diff --git a/docs/guides/mocking-rest-calls.md b/docs/guides/mocking-rest-calls.md index 0c91aa9193..44298aa9b8 100644 --- a/docs/guides/mocking-rest-calls.md +++ b/docs/guides/mocking-rest-calls.md @@ -22,6 +22,15 @@ The following configuration example will mock all CMS calls. apiMockPaths: ['^cms/.*'], ``` +> [!TIP] +> With PWA version 5.2.0 a filtering for matrix parameters (e.g. `/cms;pgid=JdbSDW8rrqSRpGO4S7o0b4AK0000/includes`) was introduces. +> This way personalized REST calls can be mocked now as well with file path without the matrix parameter. +> The configuration would look like this. +> +> ``` +> apiMockPaths: ['^cms.*/.*'], +> ``` + ## Supply Mocked Data Mocked data is put in the folder _assets/mock-data/_. diff --git a/src/app/core/interceptors/mock.interceptor.spec.ts b/src/app/core/interceptors/mock.interceptor.spec.ts index 77cd9f1c7f..e740771dca 100644 --- a/src/app/core/interceptors/mock.interceptor.spec.ts +++ b/src/app/core/interceptors/mock.interceptor.spec.ts @@ -28,11 +28,15 @@ describe('Mock Interceptor', () => { describe('Request URL Modification', () => { it.each([ - [`${BASE_URL}/categories/Cameras`, './assets/mock-data/categories/Cameras/get.json'], - [`${BASE_URL};loc=en_US;cur=USD/categories/Cameras`, './assets/mock-data/categories/Cameras/get.json'], - [`${BASE_URL}/categories?view=tree`, './assets/mock-data/categories/get.json'], - [`${BASE_URL};loc=en_US;cur=USD/categories?view=tree`, './assets/mock-data/categories/get.json'], - ['./assets/picture.png', './assets/picture.png'], + [`${BASE_URL}/categories/Cameras`, '/assets/mock-data/categories/Cameras/get.json'], + [`${BASE_URL};loc=en_US;cur=USD/categories/Cameras`, '/assets/mock-data/categories/Cameras/get.json'], + [`${BASE_URL}/categories?view=tree`, '/assets/mock-data/categories/get.json'], + [`${BASE_URL};loc=en_US;cur=USD/categories?view=tree`, '/assets/mock-data/categories/get.json'], + [ + `${BASE_URL};loc=en_US;cur=USD/products;spgid=PU8jvEfUmFeE5k_3Hq1EE7DuxlIMC/1005182`, + '/assets/mock-data/products/1005182/get.json', + ], + ['/assets/picture.png', '/assets/picture.png'], ])('should replace request to "%s" with "%s"', (incoming, outgoing) => { const http = new HttpRequest('GET', incoming); @@ -48,28 +52,31 @@ describe('Mock Interceptor', () => { }); }); - describe.each` - item | within | expected - ${'categories'} | ${undefined} | ${false} - ${'categories'} | ${[]} | ${false} - ${'categories'} | ${['categories']} | ${true} - ${'catego'} | ${['categories']} | ${false} - ${'categories'} | ${['cat.*']} | ${true} - ${'product/cat'} | ${['cat.*']} | ${true} - ${'product/38201833'} | ${['2018']} | ${true} - ${'product/cat'} | ${['^cat.*']} | ${false} - ${'categories/Computers'} | ${['categories$']} | ${false} - ${'categories/Computers'} | ${['categories.*']} | ${true} - ${'categories/Computers'} | ${['categories/.*']} | ${true} - ${'categories/Computers'} | ${['categories/Computers']} | ${true} - ${'categories/Computers'} | ${['categories/Audio']} | ${false} - ${'categories/Computers'} | ${['categories/']} | ${true} - ${'categories/Computers'} | ${['categories/(Audio|Computers|HiFi)']} | ${true} - ${'categories/Computers'} | ${['categories/(Audio|Computers|HiFi)/']} | ${false} - ${'categories/Computers'} | ${['Computers']} | ${true} - `(`matchPath Method`, ({ item, within, expected }) => { - it(`should be ${expected} for URL '${item}' and mock paths [${within}]`, () => { - expect(mockInterceptor.matchPath(item, within)).toBe(expected); + describe('matchPath Method', () => { + // eslint-disable-next-line jest/valid-title + describe.each` + item | within | expected + ${'categories'} | ${undefined} | ${false} + ${'categories'} | ${[]} | ${false} + ${'categories'} | ${['categories']} | ${true} + ${'catego'} | ${['categories']} | ${false} + ${'categories'} | ${['cat.*']} | ${true} + ${'product/cat'} | ${['cat.*']} | ${true} + ${'product/38201833'} | ${['2018']} | ${true} + ${'product/cat'} | ${['^cat.*']} | ${false} + ${'categories/Computers'} | ${['categories$']} | ${false} + ${'categories/Computers'} | ${['categories.*']} | ${true} + ${'categories/Computers'} | ${['categories/.*']} | ${true} + ${'categories/Computers'} | ${['categories/Computers']} | ${true} + ${'categories/Computers'} | ${['categories/Audio']} | ${false} + ${'categories/Computers'} | ${['categories/']} | ${true} + ${'categories/Computers'} | ${['categories/(Audio|Computers|HiFi)']} | ${true} + ${'categories/Computers'} | ${['categories/(Audio|Computers|HiFi)/']} | ${false} + ${'categories/Computers'} | ${['Computers']} | ${true} + `(``, ({ item, within, expected }) => { + it(`should be ${expected} for URL '${item}' and mock paths [${within}]`, () => { + expect(mockInterceptor.matchPath(item, within)).toBe(expected); + }); }); }); }); diff --git a/src/app/core/interceptors/mock.interceptor.ts b/src/app/core/interceptors/mock.interceptor.ts index 438a90ed71..3b48638b50 100644 --- a/src/app/core/interceptors/mock.interceptor.ts +++ b/src/app/core/interceptors/mock.interceptor.ts @@ -1,5 +1,6 @@ import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Inject, Injectable } from '@angular/core'; +import { PRIMARY_OUTLET, Router } from '@angular/router'; import { Store, select } from '@ngrx/store'; import { Observable } from 'rxjs'; @@ -16,7 +17,11 @@ const MOCK_DATA_ROOT = './assets/mock-data'; export class MockInterceptor implements HttpInterceptor { private restEndpoint: string; - constructor(@Inject(API_MOCK_PATHS) private apiMockPaths: InjectSingle, store: Store) { + constructor( + @Inject(API_MOCK_PATHS) private apiMockPaths: InjectSingle, + store: Store, + private router: Router + ) { store.pipe(select(getRestEndpoint)).subscribe(data => (this.restEndpoint = data)); } @@ -28,7 +33,9 @@ export class MockInterceptor implements HttpInterceptor { return next.handle(req); } - const newUrl = `${MOCK_DATA_ROOT}/${this.getRestPath(req.url)}/${req.method.toLocaleLowerCase()}.json`; + const mockUrl = `${MOCK_DATA_ROOT}/${this.getRestPath(req.url)}/${req.method.toLocaleLowerCase()}.json`; + const commands = this.router.parseUrl(mockUrl)?.root?.children?.[PRIMARY_OUTLET]?.segments?.map(s => s.path); + const newUrl = this.router.createUrlTree(commands)?.toString(); // eslint-disable-next-line no-console console.log(`redirecting '${req.url}' to '${newUrl}'`);