Skip to content

Commit 38f5aad

Browse files
committed
fix/params 🧊 add tests, rework regexp, bye old node
1 parent 5b9302a commit 38f5aad

9 files changed

Lines changed: 69 additions & 30 deletions

File tree

packages/server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"dist"
3838
],
3939
"engines": {
40-
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
40+
"node": "^16.0.0 || >=17.0.0"
4141
},
4242
"scripts": {
4343
"prepublishOnly": "git diff --exit-code",

packages/server/src/core/graphql/createGraphQLRoute/helpers/calculateGraphQLRouteConfigWeight/calculateGraphQLRouteConfigWeight.test.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,28 +46,14 @@ describe('calculateGraphQLRouteConfigWeight', () => {
4646
).toBe(3);
4747
});
4848

49-
it('Should add one for variables descriptor scalar value', () => {
50-
expect(
51-
calculateGraphQLRouteConfigWeight({
52-
data: {},
53-
entities: {
54-
variables: {
55-
checkMode: 'equals',
56-
value: 'scalar'
57-
}
58-
} as any
59-
})
60-
).toBe(1);
61-
});
62-
6349
it('Should count plain object variables without descriptor', () => {
6450
expect(
6551
calculateGraphQLRouteConfigWeight({
6652
data: {},
6753
entities: {
68-
variables: { key: 'value' }
54+
variables: { a: 'value', b: 'value' }
6955
}
7056
})
71-
).toBe(1);
57+
).toBe(2);
7258
});
7359
});

packages/server/src/core/graphql/createGraphQLRoute/helpers/matchGraphQLRequestArtifacts/matchGraphQLRequestArtifacts.test.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from 'vitest';
1+
import { describe, expect, it, vi } from 'vitest';
22

33
import type { BaseUrl, GraphQLRequestArtifact } from '@/utils/types';
44

@@ -38,13 +38,15 @@ describe('matchGraphQLRequestArtifacts', () => {
3838
expect(matched).toHaveLength(0);
3939
});
4040

41-
it('Should match query string ignoring whitespace', () => {
41+
it('Should match equivalent queries with different insignificant whitespace', () => {
4242
const matched = matchGraphQLRequestArtifacts({
4343
artifacts: [makeArtifact({ query: 'query { User { name } }' })],
4444
meta: {
4545
path: '/',
4646
operationType: 'query',
47-
query: 'query { User { name } }'
47+
query: `query {
48+
User { name }
49+
}`
4850
}
4951
});
5052
expect(matched).toHaveLength(1);
@@ -123,6 +125,39 @@ describe('matchGraphQLRequestArtifacts', () => {
123125
expect(matched).toHaveLength(1);
124126
});
125127

128+
it('Should match operation name regexp with case-insensitive flag', () => {
129+
const matched = matchGraphQLRequestArtifacts({
130+
artifacts: [makeArtifact({ operationName: /^getusers$/i })],
131+
meta: {
132+
path: '/',
133+
operationType: 'query',
134+
operationName: 'GetUsers'
135+
}
136+
});
137+
expect(matched).toHaveLength(1);
138+
});
139+
140+
it('Should skip artifact with neither query nor operationName', () => {
141+
const warn = vi.spyOn(console, 'warn');
142+
const artifact = makeArtifact({});
143+
144+
const matched = matchGraphQLRequestArtifacts({
145+
artifacts: [artifact],
146+
meta: {
147+
path: '/',
148+
operationType: 'query',
149+
operationName: 'GetUsers'
150+
}
151+
});
152+
153+
expect(matched).toHaveLength(0);
154+
expect(warn).toHaveBeenCalledWith(
155+
`[mock-config] GraphQL artifact with no query or operationName was skipped: ${JSON.stringify(
156+
artifact
157+
)}`
158+
);
159+
});
160+
126161
it('Should fail operation name regexp when pattern does not match', () => {
127162
const matched = matchGraphQLRequestArtifacts({
128163
artifacts: [makeArtifact({ operationName: /^Other$/ })],

packages/server/src/core/graphql/createGraphQLRoute/helpers/matchGraphQLRequestArtifacts/matchGraphQLRequestArtifacts.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { parse, print, stripIgnoredCharacters } from 'graphql';
2+
13
import type { GraphQLRequestArtifact } from '@/utils/types';
24

35
import { normalizeUrl } from '@/utils/helpers';
@@ -25,7 +27,10 @@ export const matchGraphQLRequestArtifacts = ({
2527

2628
if (artifact.query) {
2729
if (!meta.query) return false;
28-
return artifact.query.replace(/\s+/g, '') === meta.query.replace(/\s+/g, '');
30+
return (
31+
stripIgnoredCharacters(print(parse(artifact.query))) ===
32+
stripIgnoredCharacters(print(parse(meta.query)))
33+
);
2934
}
3035

3136
if (artifact.operationName) {
@@ -35,5 +40,10 @@ export const matchGraphQLRequestArtifacts = ({
3540
: artifact.operationName === meta.operationName;
3641
}
3742

38-
throw new Error('Unmatched graphql request');
43+
console.warn(
44+
`[mock-config] GraphQL artifact with no query or operationName was skipped: ${JSON.stringify(
45+
artifact
46+
)}`
47+
);
48+
return false;
3949
});

packages/server/src/core/rest/createRestRoute/helpers/calculateRestRouteConfigWeight/calculateRestRouteConfigWeight.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ describe('calculateRestRouteConfigWeight', () => {
7474
calculateRestRouteConfigWeight({
7575
data: {},
7676
entities: {
77-
body: { key: 'value' }
77+
body: { a: 'value', b: 'value' }
7878
}
7979
})
80-
).toBe(1);
80+
).toBe(2);
8181
});
8282

8383
it('Should add one for non-plain body array', () => {

packages/server/src/core/rest/createRestRoute/helpers/matchRestRequestArtifacts/matchRestRequestArtifacts.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ describe('matchRestRequestArtifacts', () => {
7979
const matched = matchRestRequestArtifacts({
8080
artifacts: [
8181
makeArtifact({
82-
baseUrl: '/api/',
82+
baseUrl: '/api',
8383
path: '/users/:id'
8484
})
8585
],

packages/server/src/core/rest/createRestRoute/helpers/matchRestRequestArtifacts/matchRestRequestArtifacts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ export const matchRestRequestArtifacts = ({ artifacts, meta }: MatchRestRequestA
2727
if (artifact.method !== meta.method) return false;
2828

2929
if (artifact.path instanceof RegExp) {
30-
if (artifact.baseUrl === '/') return artifact.path.test(meta.path);
30+
if (artifact.baseUrl === '/') return new RegExp(artifact.path).test(meta.path);
3131
const tail = meta.path === artifact.baseUrl ? '' : meta.path.slice(artifact.baseUrl.length);
3232
if (!tail) return false;
33-
return artifact.path.test(tail);
33+
return new RegExp(artifact.path).test(tail);
3434
}
3535

3636
return generatePathRegex(urlJoin(artifact.baseUrl, artifact.path)).test(meta.path);

packages/server/src/core/rest/createRestRoute/helpers/prepareRestRequestArtifacts/prepareRestRequestArtifacts.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ describe('prepareRestRequestArtifacts', () => {
3232
expect(prepared[1].path).toBe('/users/:id');
3333
});
3434

35+
it('Should prefer more specific path over higher route weight', () => {
36+
const prepared = prepareRestRequestArtifacts([
37+
makeArtifact({ path: '/users/:id', weight: 100 }),
38+
makeArtifact({ path: '/users/me', weight: 1 })
39+
]);
40+
expect(prepared[0].path).toBe('/users/me');
41+
expect(prepared[1].path).toBe('/users/:id');
42+
});
43+
3544
it('Should not reorder two non-parameterized paths', () => {
3645
const prepared = prepareRestRequestArtifacts([
3746
makeArtifact({ path: '/first' }),

packages/server/src/core/rest/createRestRoute/helpers/prepareRestRequestArtifacts/prepareRestRequestArtifacts.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { RestRequestArtifact } from '@/utils/types';
22

33
export const prepareRestRequestArtifacts = (requestArtifacts: RestRequestArtifact[]) => {
44
const sortedByPathRequestArtifacts = requestArtifacts
5+
.toSorted((first, second) => second.weight - first.weight)
56
.toSorted(({ path: firstPath }, { path: secondPath }) => {
67
// ✅ important:
78
// do not compare RegExp paths and non-parameterized paths
@@ -31,8 +32,6 @@ export const prepareRestRequestArtifacts = (requestArtifacts: RestRequestArtifac
3132
return +isFirstPathPartParameter - +isSecondPathPartParameter;
3233
}
3334
return 0;
34-
})
35-
.toSorted((first, second) => second.weight - first.weight);
36-
35+
});
3736
return sortedByPathRequestArtifacts;
3837
};

0 commit comments

Comments
 (0)