Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions app/src/__tests__/network-response-preview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,14 @@ describe('NetworkInspector response preview', () => {
expect(inspector.methodOptions().map((o) => o.value)).toContain('HEAD');
expect(status()).toContain('not complete JSON');
});

it('keeps a relative URL without a leading slash, so the rule matches the request', async () => {
const { button, inspector } = await open({ url: 'api/heroes?page=2' });
button('Mock this request')!.click();
await fixture.whenStable();
// Rules match a pattern without `*` as a substring of the request URL.
const pattern = inspector.draft().pattern;
expect(pattern).toBe('api/heroes?page=2');
expect('api/heroes?page=2'.includes(pattern)).toBe(true);
});
});
8 changes: 5 additions & 3 deletions app/src/pages/network-inspector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,13 @@ const REDACTED_IN_URL = /\[redacted\]|%5Bredacted%5D/gi;

/**
* A rule pattern for a recorded call: its path and query, without the origin, so it
* matches the relative client URL and the absolute SSR URL. A redacted value becomes
* `*`, because the real request carries the secret.
* matches the relative client URL and the absolute SSR URL. A relative URL stays as
* recorded, since `api/x` never contains `/api/x`. A redacted value becomes `*`,
* because the real request carries the secret.
*/
function mockPattern(url: string): string {
return pathOf(url).replace(REDACTED_IN_URL, '*');
const absolute = /^([a-z][a-z\d+.-]*:|\/\/)/i.test(url);
return (absolute ? pathOf(url) : url).replace(REDACTED_IN_URL, '*');
}

/** The preview as a mock body, when it is complete JSON (the rule form takes JSON only). */
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/content/inspectors/ssr-http.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Add a rule with these fields:

A status of 400 or more fails the request with an `HttpErrorResponse`. A lower status returns the body as a mocked response. A body with the status on **None** returns it with status 200. A stored rule with a status outside the list loses that status, and is dropped when nothing else is left to change. A rule with only a delay passes the request through, later. A rule needs a status, a delay or a body, so **Add rule** stays off until it has one. The form clears after each added rule. The first enabled rule that matches wins. After **Remove**, focus moves to the next rule's **Remove** button, the previous one when the last rule went, or the **Rules** heading when none are left. **SSR overrides** work the same way.

To start from a call you already made, open it in the timeline and click **Mock this request**. The form gets the call's method and its path and query as the URL pattern, without the origin, so the rule matches the client and SSR URLs. A redacted value in the URL becomes `*`. When the preview is complete JSON, it becomes the body, with redacted values still masked. Focus moves to **URL pattern**. Nothing is saved until you click **Add rule**, so check the body and pick a status first.
To start from a call you already made, open it in the timeline and click **Mock this request**. The form gets the call's method and its path and query as the URL pattern, without the origin, so the rule matches the client and SSR URLs. A relative URL such as `api/heroes` stays as the app wrote it. A redacted value in the URL becomes `*`. When the preview is complete JSON, it becomes the body, with redacted values still masked. Focus moves to **URL pattern**. Nothing is saved until you click **Add rule**, so check the body and pick a status first.

The body follows the request's `responseType`. A `json` request gets the parsed JSON (or the raw string when it does not parse) with `content-type: application/json`. A `text` request gets the string with `text/plain`. A `blob` request gets a `Blob`, and an `arraybuffer` request an `ArrayBuffer`, both with `application/octet-stream`. The same value is the `error` of an injected failure.

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion extension/ui/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading