From 0d36166b26cf7146f2f19d0d380c965758761ba7 Mon Sep 17 00:00:00 2001 From: Florent Letendre Date: Fri, 6 Oct 2023 10:39:33 -0400 Subject: [PATCH] fix: component with restriction is not displayed after being changed in SmartEdit (#17893) CXSPA-3495 SmartEdit Interceptor modified to improve productList request. This fix is effective with a server enhancement described on CCMTD-46304. --- .../cms-ticket.interceptor.spec.ts | 88 ++++++++++++++++++- .../cms-ticket.interceptor.ts | 53 +++++++++-- 2 files changed, 132 insertions(+), 9 deletions(-) diff --git a/feature-libs/smartedit/root/http-interceptors/cms-ticket.interceptor.spec.ts b/feature-libs/smartedit/root/http-interceptors/cms-ticket.interceptor.spec.ts index 608685f81a2..f73e53f2636 100644 --- a/feature-libs/smartedit/root/http-interceptors/cms-ticket.interceptor.spec.ts +++ b/feature-libs/smartedit/root/http-interceptors/cms-ticket.interceptor.spec.ts @@ -1,10 +1,17 @@ -import { HttpClient, HTTP_INTERCEPTORS } from '@angular/common/http'; +import { HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http'; import { HttpClientTestingModule, HttpTestingController, } from '@angular/common/http/testing'; -import { inject, TestBed } from '@angular/core/testing'; -import { defaultOccConfig } from '@spartacus/core'; +import { TestBed, inject } from '@angular/core/testing'; +import { + FeatureConfigService, + PageContext, + PageType, + RoutingService, + defaultOccConfig, +} from '@spartacus/core'; +import { Observable, of } from 'rxjs'; import { SmartEditLauncherService } from '../services/smart-edit-launcher.service'; import { CmsTicketInterceptor } from './cms-ticket.interceptor'; @@ -16,10 +23,21 @@ class MockSmartEditLauncherService { return this._cmsTicketId; } } +const mockPageContext = { + id: 'mockCode', + type: PageType.CATEGORY_PAGE, +}; +class MockRoutingService implements Partial { + getPageContext(): Observable { + return of(mockPageContext); + } +} describe('CmsTicketInterceptor', () => { let httpMock: HttpTestingController; let service: SmartEditLauncherService; + let routingService: RoutingService; + let featureConfig: FeatureConfigService; beforeEach(() => { TestBed.configureTestingModule({ @@ -29,7 +47,10 @@ describe('CmsTicketInterceptor', () => { provide: SmartEditLauncherService, useClass: MockSmartEditLauncherService, }, - + { + provide: RoutingService, + useClass: MockRoutingService, + }, { provide: HTTP_INTERCEPTORS, useClass: CmsTicketInterceptor, @@ -40,6 +61,8 @@ describe('CmsTicketInterceptor', () => { httpMock = TestBed.inject(HttpTestingController); service = TestBed.inject(SmartEditLauncherService); + routingService = TestBed.inject(RoutingService); + featureConfig = TestBed.inject(FeatureConfigService); }); afterEach(() => { @@ -122,4 +145,61 @@ describe('CmsTicketInterceptor', () => { mockReq.flush('somedata'); } )); + + it('should add parameters for productList requests: cmsTicketId, pageType, code', inject( + [HttpClient], + (http: HttpClient) => { + spyOn(featureConfig, 'isLevel').and.returnValue(true); + spyOnProperty(service, 'cmsTicketId', 'get').and.returnValue( + 'mockCmsTicketId' + ); + + http.get(`${OccUrl}/productList`).subscribe((result) => { + expect(result).toBeTruthy(); + }); + const mockReq = httpMock.expectOne((req) => { + return req.method === 'GET'; + }); + + expect(mockReq.request.params.get('cmsTicketId')).toEqual( + 'mockCmsTicketId' + ); + expect(mockReq.request.params.get('pageType')).toEqual( + PageType.CATEGORY_PAGE + ); + expect(mockReq.request.params.get('code')).toEqual('mockCode'); + mockReq.flush('somedata'); + } + )); + + it('should add only one parameter for productList requests when pageContext is partial: cmsTicketId', inject( + [HttpClient], + (http: HttpClient) => { + spyOn(featureConfig, 'isLevel').and.returnValue(true); + spyOn(routingService, 'getPageContext').and.returnValue( + of({ + ...mockPageContext, + id: '', + }) + ); + + spyOnProperty(service, 'cmsTicketId', 'get').and.returnValue( + 'mockCmsTicketId' + ); + + http.get(`${OccUrl}/productList`).subscribe((result) => { + expect(result).toBeTruthy(); + }); + const mockReq = httpMock.expectOne((req) => { + return req.method === 'GET'; + }); + + expect(mockReq.request.params.get('cmsTicketId')).toEqual( + 'mockCmsTicketId' + ); + expect(mockReq.request.params.get('pageType')).toBeFalsy(); + expect(mockReq.request.params.get('code')).toBeFalsy(); + mockReq.flush('somedata'); + } + )); }); diff --git a/feature-libs/smartedit/root/http-interceptors/cms-ticket.interceptor.ts b/feature-libs/smartedit/root/http-interceptors/cms-ticket.interceptor.ts index 807c66f5896..a003716917d 100644 --- a/feature-libs/smartedit/root/http-interceptors/cms-ticket.interceptor.ts +++ b/feature-libs/smartedit/root/http-interceptors/cms-ticket.interceptor.ts @@ -10,29 +10,72 @@ import { HttpInterceptor, HttpRequest, } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; +import { + FeatureConfigService, + PageContext, + RoutingService, +} from '@spartacus/core'; import { Observable } from 'rxjs'; +import { switchMap, take } from 'rxjs/operators'; import { SmartEditLauncherService } from '../services/smart-edit-launcher.service'; @Injectable({ providedIn: 'root' }) export class CmsTicketInterceptor implements HttpInterceptor { - constructor(private service: SmartEditLauncherService) {} + routingService = inject(RoutingService); + featureConfig = inject(FeatureConfigService); + constructor(protected service: SmartEditLauncherService) {} intercept( request: HttpRequest, next: HttpHandler ): Observable> { + const cmsTicketId = this.service.cmsTicketId; + if (!cmsTicketId) { + return next.handle(request); + } if ( - this.service.cmsTicketId && - (request.url.includes('/cms/') || request.url.includes('/products/')) + this.featureConfig.isLevel('6.6') && + request.url.includes('/productList') ) { + return this.setRequestForProductListPage(request, next, cmsTicketId); + } + if (request.url.includes('/cms/') || request.url.includes('/products/')) { request = request.clone({ setParams: { - cmsTicketId: this.service.cmsTicketId, + cmsTicketId, }, }); } return next.handle(request); } + + protected setRequestForProductListPage( + request: HttpRequest, + next: HttpHandler, + cmsTicketId: string + ) { + return this.routingService.getPageContext().pipe( + take(1), + switchMap((pageContext: PageContext) => { + request = request.clone( + !!pageContext.id && !!pageContext.type + ? { + setParams: { + cmsTicketId, + pageType: pageContext.type, + code: pageContext.id, + }, + } + : { + setParams: { + cmsTicketId, + }, + } + ); + return next.handle(request); + }) + ); + } }