Skip to content

Commit

Permalink
fix: improve mock data redirection for URLs with matrix parameters (#…
Browse files Browse the repository at this point in the history
…1324)

* matrix parameters will be removed from the redirect URL
  • Loading branch information
kepek authored May 13, 2024
1 parent 1699b79 commit db448ae
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 29 deletions.
9 changes: 9 additions & 0 deletions docs/guides/mocking-rest-calls.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<path>_.
Expand Down
61 changes: 34 additions & 27 deletions src/app/core/interceptors/mock.interceptor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
});
});
});
});
11 changes: 9 additions & 2 deletions src/app/core/interceptors/mock.interceptor.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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<typeof API_MOCK_PATHS>, store: Store) {
constructor(
@Inject(API_MOCK_PATHS) private apiMockPaths: InjectSingle<typeof API_MOCK_PATHS>,
store: Store,
private router: Router
) {
store.pipe(select(getRestEndpoint)).subscribe(data => (this.restEndpoint = data));
}

Expand All @@ -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}'`);
Expand Down

0 comments on commit db448ae

Please sign in to comment.