Skip to content

Commit

Permalink
Merge branch 'develop-6.6.x' into feature/CXSPA-4907
Browse files Browse the repository at this point in the history
  • Loading branch information
FollowTheFlo authored Oct 6, 2023
2 parents 7616d67 + 0d36166 commit ee7983a
Show file tree
Hide file tree
Showing 10 changed files with 772 additions and 205 deletions.
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -16,10 +23,21 @@ class MockSmartEditLauncherService {
return this._cmsTicketId;
}
}
const mockPageContext = {
id: 'mockCode',
type: PageType.CATEGORY_PAGE,
};
class MockRoutingService implements Partial<RoutingService> {
getPageContext(): Observable<PageContext> {
return of(mockPageContext);
}
}

describe('CmsTicketInterceptor', () => {
let httpMock: HttpTestingController;
let service: SmartEditLauncherService;
let routingService: RoutingService;
let featureConfig: FeatureConfigService;

beforeEach(() => {
TestBed.configureTestingModule({
Expand All @@ -29,7 +47,10 @@ describe('CmsTicketInterceptor', () => {
provide: SmartEditLauncherService,
useClass: MockSmartEditLauncherService,
},

{
provide: RoutingService,
useClass: MockRoutingService,
},
{
provide: HTTP_INTERCEPTORS,
useClass: CmsTicketInterceptor,
Expand All @@ -40,6 +61,8 @@ describe('CmsTicketInterceptor', () => {

httpMock = TestBed.inject(HttpTestingController);
service = TestBed.inject(SmartEditLauncherService);
routingService = TestBed.inject(RoutingService);
featureConfig = TestBed.inject(FeatureConfigService);
});

afterEach(() => {
Expand Down Expand Up @@ -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');
}
));
});
Original file line number Diff line number Diff line change
Expand Up @@ -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<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
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<any>,
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);
})
);
}
}
31 changes: 28 additions & 3 deletions projects/core/src/cms/cms.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,32 @@
*/

import { ModuleWithProviders, NgModule } from '@angular/core';
import { provideDefaultConfig } from '../config/config-providers';
import { defaultCmsModuleConfig } from './config/default-cms-config';
import {
defaultCmsModuleConfig,
defaultUserCmsModuleConfig,
} from './config/default-cms-config';
import { CmsService } from './facade/cms.service';
import { PageMetaModule } from './page/page-meta.module';
import { CmsStoreModule } from './store/cms-store.module';
import { ConfigChunk, provideDefaultConfigFactory } from '../config';
import { USER_CMS_ENDPOINTS } from '../model';

function getDefaultCmsConfig(configChunk: any) {
let isUserCmsEndpoint = false;

configChunk.find((config: any) => {
const userCmsEndpoints = config.features?.[USER_CMS_ENDPOINTS];

if (Boolean(userCmsEndpoints)) {
isUserCmsEndpoint = userCmsEndpoints;
}
});

if (isUserCmsEndpoint) {
return defaultUserCmsModuleConfig;
}
return defaultCmsModuleConfig;
}

@NgModule({
imports: [CmsStoreModule, PageMetaModule.forRoot()],
Expand All @@ -18,7 +39,11 @@ export class CmsModule {
static forRoot(): ModuleWithProviders<CmsModule> {
return {
ngModule: CmsModule,
providers: [CmsService, provideDefaultConfig(defaultCmsModuleConfig)],
providers: [
CmsService,
// TODO: (CXSPA-4886) In the major change to provideDefaultConfig(defaultCmsModuleConfig)
provideDefaultConfigFactory(getDefaultCmsConfig, [ConfigChunk]),
],
};
}
}
15 changes: 15 additions & 0 deletions projects/core/src/cms/config/default-cms-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,18 @@ export const defaultCmsModuleConfig: CmsConfig = {
pageSize: 50,
},
};

// TODO: (CXSPA-4886) replace and remove this with defaultCmsModuleConfig in the major
export const defaultUserCmsModuleConfig: CmsConfig = {
...defaultCmsModuleConfig,
backend: {
occ: {
endpoints: {
component: 'users/${userId}/cms/components/${id}',
components: 'users/${userId}/cms/components',
pages: 'users/${userId}/cms/pages',
page: 'users/${userId}/cms/pages/${id}',
},
},
},
};
3 changes: 3 additions & 0 deletions projects/core/src/model/cms.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,6 @@ export interface CmsPickupItemDetails extends CmsComponent {
showEdit: boolean;
context: string;
}

// TODO: (CXSPA-4886) Remove this flag in the major
export const USER_CMS_ENDPOINTS = 'userCmsEndpoints';
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const pageContext: PageContext = {
type: PageType.PRODUCT_PAGE,
};

const spyOnPostEndpoint = `/cms/components?productCode=123`;
const spyOnPostEndpoint = `userId/anonymous/cms/components?productCode=123`;

describe('LegacyOccCmsComponentAdapter', () => {
let service: LegacyOccCmsComponentAdapter;
Expand Down Expand Up @@ -72,7 +72,7 @@ describe('LegacyOccCmsComponentAdapter', () => {

const testRequest = mockHttpRequest(
'POST',
'/cms/components?productCode=123'
'userId/anonymous/cms/components?productCode=123'
);

assertPostTestRequestBody(testRequest);
Expand Down
Loading

0 comments on commit ee7983a

Please sign in to comment.