Skip to content

Commit b086391

Browse files
authored
Merge pull request #267 from siberiacancode/prototype/queue-as-handler
prototype/queue-as-handler 💎 resolve 'queue' variant as data handler internally
2 parents 24212a6 + 190b694 commit b086391

27 files changed

Lines changed: 515 additions & 643 deletions

File tree

packages/server/README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ Every route must be configured to handle response content in one of three ways:
9999
- `data?` `any` mock data of request
100100
- `queue?` `Array<{ time?: number; data: any}>` queue for polling with opportunity to set time for each response
101101
- `file?` `string` path to file for return in response
102-
- `settings?` `Settings` settings for route (polling on/off, etc.)
102+
- `settings?` `Settings` settings for route (status, delay)
103103
- `entities?` `Object<headers | cookies | query | params | body>` object that helps in data retrieval
104104
- `interceptors?` `Interceptors` functions to change request or response parameters, [read](#interceptors)
105105
- `interceptors?` `Interceptors` functions to change request or response parameters, [read](#interceptors)
@@ -539,7 +539,7 @@ export default flatMockServerConfig;
539539

540540
#### Polling
541541

542-
Routes support polling for data. To add polling for data, you must specify the `polling setting` and use `queue` property instead of `data` or `file`.
542+
Routes support polling for data. To add polling for data, use `queue` property instead of `data` or `file`.
543543

544544
`queue` is an array containing `data` or `file` that should be returned in order.
545545

@@ -558,7 +558,6 @@ const flatMockServerConfig = [
558558
method: "get",
559559
routes: [
560560
{
561-
settings: { polling: true },
562561
queue: [
563562
{ data: { emoji: "🦁", name: "Nursultan" } },
564563
{ data: { emoji: "", name: "Dmitriy" } },
@@ -589,7 +588,6 @@ const flatMockServerConfig = [
589588
method: "get",
590589
routes: [
591590
{
592-
settings: { polling: true },
593591
queue: [
594592
{ time: 5000, data: { emoji: "🦁", name: "Nursultan" } },
595593
{ data: { emoji: "", name: "Dmitriy" } },

packages/server/src/core/functions/graphql/graphql.test.ts

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ import { graphql } from './graphql';
44

55
describe('graphql', () => {
66
it('Should build config for inline response', () => {
7-
const result = graphql.query(
8-
'GetUsers',
9-
{ ok: true },
10-
{ delay: 25, polling: true, status: 201 }
11-
);
7+
const result = graphql.query('GetUsers', { ok: true }, { delay: 25, status: 201 });
128

139
expect(result).toStrictEqual({
1410
operationName: 'GetUsers',
@@ -17,7 +13,7 @@ describe('graphql', () => {
1713
{
1814
data: { ok: true },
1915
entities: {},
20-
settings: { delay: 25, polling: false, status: 201 }
16+
settings: { delay: 25, status: 201 }
2117
}
2218
]
2319
});
@@ -34,7 +30,7 @@ describe('graphql', () => {
3430
},
3531
response: { ok: true }
3632
},
37-
{ delay: 20, polling: true, status: 205 }
33+
{ delay: 20, status: 205 }
3834
);
3935

4036
expect(result).toStrictEqual({
@@ -48,7 +44,7 @@ describe('graphql', () => {
4844
key: 'value'
4945
}
5046
},
51-
settings: { delay: 20, polling: false, status: 205 }
47+
settings: { delay: 20, status: 205 }
5248
}
5349
]
5450
});
@@ -64,18 +60,15 @@ describe('graphql', () => {
6460
{
6561
data: { ok: true },
6662
entities: {},
67-
settings: { polling: false }
63+
settings: {}
6864
}
6965
]
7066
});
7167
});
7268

7369
it('Should build config for inline handler', () => {
7470
const handler = vi.fn().mockResolvedValue({ ok: true });
75-
const result = graphql.query('GetUsers', handler, {
76-
delay: 30,
77-
polling: true
78-
});
71+
const result = graphql.query('GetUsers', handler, { delay: 30 });
7972

8073
expect(result).toStrictEqual({
8174
operationName: 'GetUsers',
@@ -84,7 +77,7 @@ describe('graphql', () => {
8477
{
8578
data: handler,
8679
entities: {},
87-
settings: { delay: 30, polling: false }
80+
settings: { delay: 30 }
8881
}
8982
]
9083
});
@@ -102,7 +95,7 @@ describe('graphql', () => {
10295
}
10396
}
10497
},
105-
{ delay: 40, polling: true, status: 206 }
98+
{ delay: 40, status: 206 }
10699
);
107100

108101
expect(result).toStrictEqual({
@@ -116,13 +109,13 @@ describe('graphql', () => {
116109
key: 'value'
117110
}
118111
},
119-
settings: { delay: 40, polling: false, status: 206 }
112+
settings: { delay: 40, status: 206 }
120113
}
121114
]
122115
});
123116
});
124117

125-
it('Should build config for queue object and normalize queue items', () => {
118+
it('Should build config for queue object as data handler', () => {
126119
const queueHandler = vi.fn().mockResolvedValue({ ok: 'handler' });
127120
const result = graphql.query(
128121
'GetUsers',
@@ -137,24 +130,21 @@ describe('graphql', () => {
137130
{ response: { ok: 'response' }, time: 200 }
138131
]
139132
},
140-
{ delay: 50, polling: false, status: 207 }
133+
{ delay: 50, status: 207 }
141134
);
142135

143136
expect(result).toStrictEqual({
144137
operationName: 'GetUsers',
145138
operationType: 'query',
146139
routes: [
147140
{
148-
queue: [
149-
{ data: queueHandler, time: 100 },
150-
{ data: { ok: 'response' }, time: 200 }
151-
],
141+
data: expect.any(Function),
152142
entities: {
153143
headers: {
154144
key: 'value'
155145
}
156146
},
157-
settings: { delay: 50, polling: true, status: 207 }
147+
settings: { delay: 50, status: 207 }
158148
}
159149
]
160150
});
@@ -170,7 +160,7 @@ describe('graphql', () => {
170160
{
171161
data: { ok: true },
172162
entities: {},
173-
settings: { polling: false }
163+
settings: {}
174164
}
175165
]
176166
});
@@ -186,7 +176,7 @@ describe('graphql', () => {
186176
{
187177
data: { ok: true },
188178
entities: {},
189-
settings: { polling: false }
179+
settings: {}
190180
}
191181
]
192182
});
@@ -207,7 +197,7 @@ describe('graphql', () => {
207197
{
208198
data: { ok: true },
209199
entities: {},
210-
settings: { polling: false }
200+
settings: {}
211201
}
212202
]
213203
});
@@ -217,7 +207,7 @@ describe('graphql', () => {
217207
const result = graphql.query(
218208
'GetUsers',
219209
{ response: { ok: true } },
220-
{ delay: 150, polling: false, status: 200 }
210+
{ delay: 150, status: 200 }
221211
);
222212

223213
expect(result).toStrictEqual({
@@ -227,7 +217,7 @@ describe('graphql', () => {
227217
{
228218
data: { ok: true },
229219
entities: {},
230-
settings: { delay: 150, polling: false, status: 200 }
220+
settings: { delay: 150, status: 200 }
231221
}
232222
]
233223
});
@@ -255,7 +245,7 @@ describe('graphql', () => {
255245
{
256246
data: expect.any(Function),
257247
entities: {},
258-
settings: { polling: false }
248+
settings: {}
259249
}
260250
]
261251
});

packages/server/src/core/functions/graphql/graphql.ts

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type {
2+
Data,
23
GraphQLEntitiesByEntityName,
34
GraphQLOperationName,
45
GraphQLOperationType,
@@ -8,11 +9,13 @@ import type {
89
GraphQLSettings
910
} from '@/utils/types';
1011

12+
import { createQueueHandler } from './helpers';
13+
1114
interface GraphQLRequestInput {
1215
body?: unknown;
1316
params?: unknown;
1417
query?: unknown;
15-
response?: unknown;
18+
response?: Data;
1619
}
1720

1821
type ReservedGraphQLConfigKeys = {
@@ -63,52 +66,58 @@ const resolveConfigType = <Options extends GraphQLRequestInput>(config: GraphQLC
6366

6467
const createConfigResolver = <Options extends GraphQLRequestInput>(
6568
config: GraphQLConfig<Options>,
66-
settings?: GraphQLSettings
67-
) => {
69+
settings: GraphQLSettings = {}
70+
): GraphQLRouteConfig => {
6871
const resolvedConfig = resolveConfigType(config);
6972

7073
switch (resolvedConfig.type) {
7174
case 'inlineResponse':
7275
return {
7376
data: resolvedConfig.config,
7477
entities: {},
75-
settings: { ...settings, polling: false }
78+
settings
7679
};
7780

7881
case 'data': {
7982
return {
8083
data: resolvedConfig.config.response,
8184
entities: resolvedConfig.config.match ?? {},
82-
settings: { ...settings, polling: false }
85+
settings
8386
};
8487
}
8588

8689
case 'queue': {
87-
return {
88-
queue: resolvedConfig.config.queue.map((item) => {
89-
if ('handler' in item) {
90-
return { data: item.handler, time: item.time };
91-
}
90+
const normalizedQueue = resolvedConfig.config.queue.map((item) => {
91+
if ('handler' in item) {
92+
return { data: item.handler, time: item.time };
93+
}
9294

95+
if ('response' in item) {
9396
return { data: item.response, time: item.time };
94-
}),
97+
}
98+
99+
throw new Error(`Unexpected queue item kind: ${JSON.stringify(item, null, 2)}`);
100+
});
101+
102+
return {
103+
data: createQueueHandler(normalizedQueue),
95104
entities: resolvedConfig.config.match ?? {},
96-
settings: { ...settings, polling: true }
105+
settings
97106
};
98107
}
99108

100109
case 'inlineHandler':
101110
return {
102111
data: resolvedConfig.config,
103112
entities: {},
104-
settings: { ...settings, polling: false }
113+
settings
105114
};
106115

107116
case 'handlerObj': {
108117
return {
109118
data: resolvedConfig.config.handler,
110119
entities: resolvedConfig.config.match ?? {},
111-
settings: { ...settings, polling: false }
120+
settings
112121
};
113122
}
114123

@@ -171,17 +180,15 @@ const createGraphQLFactory = <Mode extends GraphQLFactoryMode>(mode: Mode) => {
171180
if (mode === 'raw') {
172181
return {
173182
query: identifier as string,
174-
operationType: (operationType ?? 'query') as GraphQLOperationType,
175-
routes: [
176-
createConfigResolver(config as GraphQLConfig<Options>, settings) as GraphQLRouteConfig
177-
]
183+
operationType: operationType ?? 'query',
184+
routes: [createConfigResolver(config, settings)]
178185
};
179186
}
180187

181188
return {
182-
operationName: identifier as GraphQLOperationName,
189+
operationName: identifier,
183190
operationType: mode,
184-
routes: [createConfigResolver(config, settings) as GraphQLRouteConfig]
191+
routes: [createConfigResolver(config, settings)]
185192
};
186193
}
187194

0 commit comments

Comments
 (0)