@platformatic/sql-graphql 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nyc_output/0681b2b7-587a-40f2-8242-257bc4c72456.json +1 -0
- package/.nyc_output/191054d4-6a1e-4a1b-87bb-f801ed78a223.json +1 -0
- package/.nyc_output/22ead0f6-e5a6-4647-a2ea-db2f42498081.json +1 -0
- package/.nyc_output/4e847e26-05cd-4063-9277-48aff86d6822.json +1 -0
- package/.nyc_output/5acfd416-02d1-497b-8dbd-69c0af167c62.json +1 -0
- package/.nyc_output/5ec04f76-9bcb-475d-b79e-f9304cc0026c.json +1 -0
- package/.nyc_output/5f3bb47a-0d2d-440a-a466-8ffa9ab3efaa.json +1 -0
- package/.nyc_output/71c2bd84-9a72-4e86-83c6-d587ce525fe4.json +1 -0
- package/.nyc_output/74cc1dab-7479-48e7-80b0-c97351d8856e.json +1 -0
- package/.nyc_output/9f5d12ba-bc3d-461c-a0e2-2a95d2020c19.json +1 -0
- package/.nyc_output/ac343b71-6f76-421c-a287-46d19bb48f89.json +1 -0
- package/.nyc_output/c1c0eecb-63a0-4258-81b6-50e7488bd67c.json +1 -0
- package/.nyc_output/c201a1cd-3105-4d18-bbbb-8d7fa674d439.json +1 -0
- package/.nyc_output/d6da0270-e9ed-41e2-bbf3-9262d1df683c.json +1 -0
- package/.nyc_output/processinfo/0681b2b7-587a-40f2-8242-257bc4c72456.json +1 -0
- package/.nyc_output/processinfo/191054d4-6a1e-4a1b-87bb-f801ed78a223.json +1 -0
- package/.nyc_output/processinfo/22ead0f6-e5a6-4647-a2ea-db2f42498081.json +1 -0
- package/.nyc_output/processinfo/4e847e26-05cd-4063-9277-48aff86d6822.json +1 -0
- package/.nyc_output/processinfo/5acfd416-02d1-497b-8dbd-69c0af167c62.json +1 -0
- package/.nyc_output/processinfo/5ec04f76-9bcb-475d-b79e-f9304cc0026c.json +1 -0
- package/.nyc_output/processinfo/5f3bb47a-0d2d-440a-a466-8ffa9ab3efaa.json +1 -0
- package/.nyc_output/processinfo/71c2bd84-9a72-4e86-83c6-d587ce525fe4.json +1 -0
- package/.nyc_output/processinfo/74cc1dab-7479-48e7-80b0-c97351d8856e.json +1 -0
- package/.nyc_output/processinfo/9f5d12ba-bc3d-461c-a0e2-2a95d2020c19.json +1 -0
- package/.nyc_output/processinfo/ac343b71-6f76-421c-a287-46d19bb48f89.json +1 -0
- package/.nyc_output/processinfo/c1c0eecb-63a0-4258-81b6-50e7488bd67c.json +1 -0
- package/.nyc_output/processinfo/c201a1cd-3105-4d18-bbbb-8d7fa674d439.json +1 -0
- package/.nyc_output/processinfo/d6da0270-e9ed-41e2-bbf3-9262d1df683c.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -0
- package/.taprc +1 -0
- package/LICENSE +201 -0
- package/NOTICE +13 -0
- package/README.md +13 -0
- package/index.d.ts +40 -0
- package/index.js +117 -0
- package/lib/entity-to-type.js +248 -0
- package/lib/relationship.js +67 -0
- package/lib/utils.js +77 -0
- package/package.json +44 -0
- package/test/datatypes.test.js +708 -0
- package/test/federation.test.js +312 -0
- package/test/helper.js +70 -0
- package/test/hooks.test.js +660 -0
- package/test/ignore.test.js +117 -0
- package/test/insert.test.js +181 -0
- package/test/inserted_updated_at.test.js +517 -0
- package/test/nested.test.js +862 -0
- package/test/no-modification-of-entity.test.js +113 -0
- package/test/order_by.test.js +397 -0
- package/test/relations.test.js +60 -0
- package/test/simple.test.js +708 -0
- package/test/sqlite.test.js +276 -0
- package/test/types/index.test-d.ts +33 -0
- package/test/where.test.js +814 -0
|
@@ -0,0 +1,862 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const sqlGraphQL = require('..')
|
|
5
|
+
const sqlMapper = require('@platformatic/sql-mapper')
|
|
6
|
+
const fastify = require('fastify')
|
|
7
|
+
const { clear, connInfo, isMysql, isSQLite } = require('./helper')
|
|
8
|
+
|
|
9
|
+
test('nested resolver', async ({ pass, teardown, same, equal }) => {
|
|
10
|
+
const app = fastify()
|
|
11
|
+
app.register(sqlMapper, {
|
|
12
|
+
...connInfo,
|
|
13
|
+
async onDatabaseLoad (db, sql) {
|
|
14
|
+
pass('onDatabaseLoad called')
|
|
15
|
+
|
|
16
|
+
await clear(db, sql)
|
|
17
|
+
|
|
18
|
+
if (isMysql) {
|
|
19
|
+
await db.query(sql`
|
|
20
|
+
CREATE TABLE categories (
|
|
21
|
+
id SERIAL PRIMARY KEY,
|
|
22
|
+
name VARCHAR(255)
|
|
23
|
+
);
|
|
24
|
+
CREATE TABLE pages (
|
|
25
|
+
id SERIAL PRIMARY KEY,
|
|
26
|
+
title VARCHAR(42),
|
|
27
|
+
category_id BIGINT UNSIGNED,
|
|
28
|
+
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
|
|
29
|
+
);
|
|
30
|
+
`)
|
|
31
|
+
} else if (isSQLite) {
|
|
32
|
+
await db.query(sql`
|
|
33
|
+
CREATE TABLE categories (
|
|
34
|
+
id INTEGER PRIMARY KEY,
|
|
35
|
+
name VARCHAR(42)
|
|
36
|
+
);
|
|
37
|
+
`)
|
|
38
|
+
await db.query(sql`
|
|
39
|
+
CREATE TABLE pages (
|
|
40
|
+
id INTEGER PRIMARY KEY,
|
|
41
|
+
title VARCHAR(42),
|
|
42
|
+
category_id INTEGER REFERENCES categories(id)
|
|
43
|
+
);
|
|
44
|
+
`)
|
|
45
|
+
} else {
|
|
46
|
+
await db.query(sql`
|
|
47
|
+
CREATE TABLE categories (
|
|
48
|
+
id SERIAL PRIMARY KEY,
|
|
49
|
+
name VARCHAR(42)
|
|
50
|
+
);
|
|
51
|
+
CREATE TABLE pages (
|
|
52
|
+
id SERIAL PRIMARY KEY,
|
|
53
|
+
title VARCHAR(42),
|
|
54
|
+
category_id INTEGER REFERENCES categories(id)
|
|
55
|
+
);
|
|
56
|
+
`)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
app.register(sqlGraphQL)
|
|
61
|
+
teardown(app.close.bind(app))
|
|
62
|
+
|
|
63
|
+
const categories = [{
|
|
64
|
+
name: 'Pets'
|
|
65
|
+
}, {
|
|
66
|
+
name: 'Food'
|
|
67
|
+
}]
|
|
68
|
+
|
|
69
|
+
await app.inject({
|
|
70
|
+
method: 'POST',
|
|
71
|
+
url: '/graphql',
|
|
72
|
+
body: {
|
|
73
|
+
query: `
|
|
74
|
+
mutation batch($inputs: [CategoryInput]!) {
|
|
75
|
+
insertCategories(inputs: $inputs) {
|
|
76
|
+
id
|
|
77
|
+
name
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
`,
|
|
81
|
+
variables: {
|
|
82
|
+
inputs: categories
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
{
|
|
88
|
+
const res = await app.inject({
|
|
89
|
+
method: 'POST',
|
|
90
|
+
url: '/graphql',
|
|
91
|
+
body: {
|
|
92
|
+
query: `
|
|
93
|
+
mutation {
|
|
94
|
+
savePage(input: { title: "Hello", categoryId: 1 }) {
|
|
95
|
+
id
|
|
96
|
+
title
|
|
97
|
+
category {
|
|
98
|
+
id
|
|
99
|
+
name
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
`
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
equal(res.statusCode, 200, 'savePage status code')
|
|
107
|
+
same(res.json(), {
|
|
108
|
+
data: {
|
|
109
|
+
savePage: {
|
|
110
|
+
id: 1,
|
|
111
|
+
title: 'Hello',
|
|
112
|
+
category: {
|
|
113
|
+
id: 1,
|
|
114
|
+
name: 'Pets'
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, 'savePage response')
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
{
|
|
122
|
+
const res = await app.inject({
|
|
123
|
+
method: 'POST',
|
|
124
|
+
url: '/graphql',
|
|
125
|
+
body: {
|
|
126
|
+
query: `
|
|
127
|
+
query {
|
|
128
|
+
getPageById(id: 1) {
|
|
129
|
+
id
|
|
130
|
+
title
|
|
131
|
+
category {
|
|
132
|
+
id
|
|
133
|
+
name
|
|
134
|
+
pages {
|
|
135
|
+
id
|
|
136
|
+
title
|
|
137
|
+
category {
|
|
138
|
+
id
|
|
139
|
+
name
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
`
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
equal(res.statusCode, 200, 'pages status code')
|
|
149
|
+
same(res.json(), {
|
|
150
|
+
data: {
|
|
151
|
+
getPageById: {
|
|
152
|
+
id: 1,
|
|
153
|
+
title: 'Hello',
|
|
154
|
+
category: {
|
|
155
|
+
id: 1,
|
|
156
|
+
name: 'Pets',
|
|
157
|
+
pages: [{
|
|
158
|
+
id: 1,
|
|
159
|
+
title: 'Hello',
|
|
160
|
+
category: {
|
|
161
|
+
id: 1,
|
|
162
|
+
name: 'Pets'
|
|
163
|
+
}
|
|
164
|
+
}]
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}, 'pages response')
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Without ids
|
|
172
|
+
{
|
|
173
|
+
const res = await app.inject({
|
|
174
|
+
method: 'POST',
|
|
175
|
+
url: '/graphql',
|
|
176
|
+
body: {
|
|
177
|
+
query: `
|
|
178
|
+
query {
|
|
179
|
+
getPageById(id: 1) {
|
|
180
|
+
title
|
|
181
|
+
category {
|
|
182
|
+
name
|
|
183
|
+
pages {
|
|
184
|
+
title
|
|
185
|
+
category {
|
|
186
|
+
name
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
`
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
equal(res.statusCode, 200, 'pages status code')
|
|
196
|
+
same(res.json(), {
|
|
197
|
+
data: {
|
|
198
|
+
getPageById: {
|
|
199
|
+
title: 'Hello',
|
|
200
|
+
category: {
|
|
201
|
+
name: 'Pets',
|
|
202
|
+
pages: [{
|
|
203
|
+
title: 'Hello',
|
|
204
|
+
category: {
|
|
205
|
+
name: 'Pets'
|
|
206
|
+
}
|
|
207
|
+
}]
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}, 'pages response')
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
{
|
|
215
|
+
const res = await app.inject({
|
|
216
|
+
method: 'POST',
|
|
217
|
+
url: '/graphql',
|
|
218
|
+
body: {
|
|
219
|
+
query: `
|
|
220
|
+
query {
|
|
221
|
+
categories {
|
|
222
|
+
id
|
|
223
|
+
name
|
|
224
|
+
pages {
|
|
225
|
+
id
|
|
226
|
+
title
|
|
227
|
+
category {
|
|
228
|
+
id
|
|
229
|
+
name
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
`
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
equal(res.statusCode, 200, 'categories.posts status code')
|
|
238
|
+
same(res.json(), {
|
|
239
|
+
data: {
|
|
240
|
+
categories: [{
|
|
241
|
+
id: 1,
|
|
242
|
+
name: 'Pets',
|
|
243
|
+
pages: [{
|
|
244
|
+
id: 1,
|
|
245
|
+
title: 'Hello',
|
|
246
|
+
category: {
|
|
247
|
+
id: 1,
|
|
248
|
+
name: 'Pets'
|
|
249
|
+
}
|
|
250
|
+
}]
|
|
251
|
+
}, {
|
|
252
|
+
id: 2,
|
|
253
|
+
name: 'Food',
|
|
254
|
+
pages: []
|
|
255
|
+
}]
|
|
256
|
+
}
|
|
257
|
+
}, 'categories.posts response')
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
test('disable one-too-many', async ({ pass, teardown, same, equal, match }) => {
|
|
262
|
+
const app = fastify()
|
|
263
|
+
app.register(sqlMapper, {
|
|
264
|
+
...connInfo,
|
|
265
|
+
async onDatabaseLoad (db, sql) {
|
|
266
|
+
pass('onDatabaseLoad called')
|
|
267
|
+
|
|
268
|
+
await clear(db, sql)
|
|
269
|
+
|
|
270
|
+
if (isMysql) {
|
|
271
|
+
await db.query(sql`
|
|
272
|
+
CREATE TABLE categories (
|
|
273
|
+
id SERIAL PRIMARY KEY,
|
|
274
|
+
name VARCHAR(255)
|
|
275
|
+
);
|
|
276
|
+
CREATE TABLE pages (
|
|
277
|
+
id SERIAL PRIMARY KEY,
|
|
278
|
+
title VARCHAR(42),
|
|
279
|
+
category_id BIGINT UNSIGNED,
|
|
280
|
+
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
|
|
281
|
+
);
|
|
282
|
+
`)
|
|
283
|
+
} else if (isSQLite) {
|
|
284
|
+
await db.query(sql`
|
|
285
|
+
CREATE TABLE categories (
|
|
286
|
+
id INTEGER PRIMARY KEY,
|
|
287
|
+
name VARCHAR(42)
|
|
288
|
+
);
|
|
289
|
+
`)
|
|
290
|
+
await db.query(sql`
|
|
291
|
+
CREATE TABLE pages (
|
|
292
|
+
id INTEGER PRIMARY KEY,
|
|
293
|
+
title VARCHAR(42),
|
|
294
|
+
category_id INTEGER REFERENCES categories(id)
|
|
295
|
+
);
|
|
296
|
+
`)
|
|
297
|
+
} else {
|
|
298
|
+
await db.query(sql`
|
|
299
|
+
CREATE TABLE categories (
|
|
300
|
+
id SERIAL PRIMARY KEY,
|
|
301
|
+
name VARCHAR(42)
|
|
302
|
+
);
|
|
303
|
+
CREATE TABLE pages (
|
|
304
|
+
id SERIAL PRIMARY KEY,
|
|
305
|
+
title VARCHAR(42),
|
|
306
|
+
category_id INTEGER REFERENCES categories(id)
|
|
307
|
+
);
|
|
308
|
+
`)
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
app.register(sqlGraphQL, {
|
|
313
|
+
resolvers: {
|
|
314
|
+
Category: {
|
|
315
|
+
pages: false
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
})
|
|
319
|
+
teardown(app.close.bind(app))
|
|
320
|
+
|
|
321
|
+
const categories = [{
|
|
322
|
+
name: 'Pets'
|
|
323
|
+
}, {
|
|
324
|
+
name: 'Food'
|
|
325
|
+
}]
|
|
326
|
+
|
|
327
|
+
await app.inject({
|
|
328
|
+
method: 'POST',
|
|
329
|
+
url: '/graphql',
|
|
330
|
+
body: {
|
|
331
|
+
query: `
|
|
332
|
+
mutation batch($inputs: [CategoryInput]!) {
|
|
333
|
+
insertCategories(inputs: $inputs) {
|
|
334
|
+
id
|
|
335
|
+
name
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
`,
|
|
339
|
+
variables: {
|
|
340
|
+
inputs: categories
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
{
|
|
346
|
+
const res = await app.inject({
|
|
347
|
+
method: 'POST',
|
|
348
|
+
url: '/graphql',
|
|
349
|
+
body: {
|
|
350
|
+
query: `
|
|
351
|
+
mutation {
|
|
352
|
+
savePage(input: { title: "Hello", categoryId: 1 }) {
|
|
353
|
+
id
|
|
354
|
+
title
|
|
355
|
+
category {
|
|
356
|
+
id
|
|
357
|
+
name
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
`
|
|
362
|
+
}
|
|
363
|
+
})
|
|
364
|
+
equal(res.statusCode, 200, 'savePage status code')
|
|
365
|
+
same(res.json(), {
|
|
366
|
+
data: {
|
|
367
|
+
savePage: {
|
|
368
|
+
id: 1,
|
|
369
|
+
title: 'Hello',
|
|
370
|
+
category: {
|
|
371
|
+
id: 1,
|
|
372
|
+
name: 'Pets'
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}, 'savePage response')
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
{
|
|
380
|
+
const res = await app.inject({
|
|
381
|
+
method: 'POST',
|
|
382
|
+
url: '/graphql',
|
|
383
|
+
body: {
|
|
384
|
+
query: `
|
|
385
|
+
query {
|
|
386
|
+
getPageById(id: 1) {
|
|
387
|
+
id
|
|
388
|
+
title
|
|
389
|
+
category {
|
|
390
|
+
id
|
|
391
|
+
name
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
`
|
|
396
|
+
}
|
|
397
|
+
})
|
|
398
|
+
equal(res.statusCode, 200, 'pages status code')
|
|
399
|
+
same(res.json(), {
|
|
400
|
+
data: {
|
|
401
|
+
getPageById: {
|
|
402
|
+
id: 1,
|
|
403
|
+
title: 'Hello',
|
|
404
|
+
category: {
|
|
405
|
+
id: 1,
|
|
406
|
+
name: 'Pets'
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}, 'pages response')
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
{
|
|
414
|
+
const res = await app.inject({
|
|
415
|
+
method: 'POST',
|
|
416
|
+
url: '/graphql',
|
|
417
|
+
body: {
|
|
418
|
+
query: `
|
|
419
|
+
query {
|
|
420
|
+
categories {
|
|
421
|
+
id
|
|
422
|
+
name
|
|
423
|
+
pages {
|
|
424
|
+
id
|
|
425
|
+
title
|
|
426
|
+
category {
|
|
427
|
+
id
|
|
428
|
+
name
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
`
|
|
434
|
+
}
|
|
435
|
+
})
|
|
436
|
+
equal(res.statusCode, 400, 'categories.posts status code')
|
|
437
|
+
match(res.json(), {
|
|
438
|
+
errors: [{
|
|
439
|
+
message: 'Cannot query field "pages" on type "Category". Did you mean "name"?'
|
|
440
|
+
}]
|
|
441
|
+
}, 'categories.posts response')
|
|
442
|
+
}
|
|
443
|
+
})
|
|
444
|
+
|
|
445
|
+
test('disable many-to-one relationship', async ({ pass, teardown, same, equal, match }) => {
|
|
446
|
+
const app = fastify()
|
|
447
|
+
app.register(sqlMapper, {
|
|
448
|
+
...connInfo,
|
|
449
|
+
async onDatabaseLoad (db, sql) {
|
|
450
|
+
pass('onDatabaseLoad called')
|
|
451
|
+
|
|
452
|
+
await clear(db, sql)
|
|
453
|
+
|
|
454
|
+
if (isMysql) {
|
|
455
|
+
await db.query(sql`
|
|
456
|
+
CREATE TABLE categories (
|
|
457
|
+
id SERIAL PRIMARY KEY,
|
|
458
|
+
name VARCHAR(255)
|
|
459
|
+
);
|
|
460
|
+
CREATE TABLE pages (
|
|
461
|
+
id SERIAL PRIMARY KEY,
|
|
462
|
+
title VARCHAR(42),
|
|
463
|
+
category_id BIGINT UNSIGNED,
|
|
464
|
+
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
|
|
465
|
+
);
|
|
466
|
+
`)
|
|
467
|
+
} else if (isSQLite) {
|
|
468
|
+
await db.query(sql`
|
|
469
|
+
CREATE TABLE categories (
|
|
470
|
+
id INTEGER PRIMARY KEY,
|
|
471
|
+
name VARCHAR(42)
|
|
472
|
+
);
|
|
473
|
+
`)
|
|
474
|
+
await db.query(sql`
|
|
475
|
+
CREATE TABLE pages (
|
|
476
|
+
id INTEGER PRIMARY KEY,
|
|
477
|
+
title VARCHAR(42),
|
|
478
|
+
category_id INTEGER REFERENCES categories(id)
|
|
479
|
+
);
|
|
480
|
+
`)
|
|
481
|
+
} else {
|
|
482
|
+
await db.query(sql`
|
|
483
|
+
CREATE TABLE categories (
|
|
484
|
+
id SERIAL PRIMARY KEY,
|
|
485
|
+
name VARCHAR(42)
|
|
486
|
+
);
|
|
487
|
+
CREATE TABLE pages (
|
|
488
|
+
id SERIAL PRIMARY KEY,
|
|
489
|
+
title VARCHAR(42),
|
|
490
|
+
category_id INTEGER REFERENCES categories(id)
|
|
491
|
+
);
|
|
492
|
+
`)
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
})
|
|
496
|
+
app.register(sqlGraphQL, {
|
|
497
|
+
resolvers: {
|
|
498
|
+
Page: {
|
|
499
|
+
category: false
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
})
|
|
503
|
+
teardown(app.close.bind(app))
|
|
504
|
+
|
|
505
|
+
const categories = [{
|
|
506
|
+
name: 'Pets'
|
|
507
|
+
}, {
|
|
508
|
+
name: 'Food'
|
|
509
|
+
}]
|
|
510
|
+
|
|
511
|
+
await app.inject({
|
|
512
|
+
method: 'POST',
|
|
513
|
+
url: '/graphql',
|
|
514
|
+
body: {
|
|
515
|
+
query: `
|
|
516
|
+
mutation batch($inputs: [CategoryInput]!) {
|
|
517
|
+
insertCategories(inputs: $inputs) {
|
|
518
|
+
id
|
|
519
|
+
name
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
`,
|
|
523
|
+
variables: {
|
|
524
|
+
inputs: categories
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
})
|
|
528
|
+
|
|
529
|
+
{
|
|
530
|
+
const res = await app.inject({
|
|
531
|
+
method: 'POST',
|
|
532
|
+
url: '/graphql',
|
|
533
|
+
body: {
|
|
534
|
+
query: `
|
|
535
|
+
mutation {
|
|
536
|
+
savePage(input: { title: "Hello", categoryId: 1 }) {
|
|
537
|
+
id
|
|
538
|
+
title
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
`
|
|
542
|
+
}
|
|
543
|
+
})
|
|
544
|
+
equal(res.statusCode, 200, 'savePage status code')
|
|
545
|
+
same(res.json(), {
|
|
546
|
+
data: {
|
|
547
|
+
savePage: {
|
|
548
|
+
id: 1,
|
|
549
|
+
title: 'Hello'
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}, 'savePage response')
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
{
|
|
556
|
+
const res = await app.inject({
|
|
557
|
+
method: 'POST',
|
|
558
|
+
url: '/graphql',
|
|
559
|
+
body: {
|
|
560
|
+
query: `
|
|
561
|
+
query {
|
|
562
|
+
getPageById(id: 1) {
|
|
563
|
+
id
|
|
564
|
+
title
|
|
565
|
+
category {
|
|
566
|
+
id
|
|
567
|
+
name
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
`
|
|
572
|
+
}
|
|
573
|
+
})
|
|
574
|
+
equal(res.statusCode, 400, 'pages status code')
|
|
575
|
+
match(res.json(), {
|
|
576
|
+
errors: [{
|
|
577
|
+
message: 'Cannot query field "category" on type "Page". Did you mean "categoryId"?'
|
|
578
|
+
}]
|
|
579
|
+
}, 'pages response')
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
{
|
|
583
|
+
const res = await app.inject({
|
|
584
|
+
method: 'POST',
|
|
585
|
+
url: '/graphql',
|
|
586
|
+
body: {
|
|
587
|
+
query: `
|
|
588
|
+
query {
|
|
589
|
+
categories {
|
|
590
|
+
id
|
|
591
|
+
name
|
|
592
|
+
pages {
|
|
593
|
+
id
|
|
594
|
+
title
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
`
|
|
599
|
+
}
|
|
600
|
+
})
|
|
601
|
+
equal(res.statusCode, 200, 'categories.posts status code')
|
|
602
|
+
same(res.json(), {
|
|
603
|
+
data: {
|
|
604
|
+
categories: [{
|
|
605
|
+
id: 1,
|
|
606
|
+
name: 'Pets',
|
|
607
|
+
pages: [{
|
|
608
|
+
id: 1,
|
|
609
|
+
title: 'Hello'
|
|
610
|
+
}]
|
|
611
|
+
}, {
|
|
612
|
+
id: 2,
|
|
613
|
+
name: 'Food',
|
|
614
|
+
pages: []
|
|
615
|
+
}]
|
|
616
|
+
}
|
|
617
|
+
}, 'categories.posts response')
|
|
618
|
+
}
|
|
619
|
+
})
|
|
620
|
+
|
|
621
|
+
test('nested update', async ({ pass, teardown, same, equal }) => {
|
|
622
|
+
const app = fastify()
|
|
623
|
+
app.register(sqlMapper, {
|
|
624
|
+
...connInfo,
|
|
625
|
+
async onDatabaseLoad (db, sql) {
|
|
626
|
+
pass('onDatabaseLoad called')
|
|
627
|
+
|
|
628
|
+
await clear(db, sql)
|
|
629
|
+
|
|
630
|
+
if (isMysql) {
|
|
631
|
+
await db.query(sql`
|
|
632
|
+
CREATE TABLE categories (
|
|
633
|
+
id SERIAL PRIMARY KEY,
|
|
634
|
+
name VARCHAR(255)
|
|
635
|
+
);
|
|
636
|
+
CREATE TABLE pages (
|
|
637
|
+
id SERIAL PRIMARY KEY,
|
|
638
|
+
title VARCHAR(42),
|
|
639
|
+
category_id BIGINT UNSIGNED,
|
|
640
|
+
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
|
|
641
|
+
);
|
|
642
|
+
`)
|
|
643
|
+
} else if (isSQLite) {
|
|
644
|
+
await db.query(sql`
|
|
645
|
+
CREATE TABLE categories (
|
|
646
|
+
id INTEGER PRIMARY KEY,
|
|
647
|
+
name VARCHAR(42)
|
|
648
|
+
);
|
|
649
|
+
`)
|
|
650
|
+
await db.query(sql`
|
|
651
|
+
CREATE TABLE pages (
|
|
652
|
+
id INTEGER PRIMARY KEY,
|
|
653
|
+
title VARCHAR(42),
|
|
654
|
+
category_id INTEGER REFERENCES categories(id)
|
|
655
|
+
);
|
|
656
|
+
`)
|
|
657
|
+
} else {
|
|
658
|
+
await db.query(sql`
|
|
659
|
+
CREATE TABLE categories (
|
|
660
|
+
id SERIAL PRIMARY KEY,
|
|
661
|
+
name VARCHAR(42)
|
|
662
|
+
);
|
|
663
|
+
CREATE TABLE pages (
|
|
664
|
+
id SERIAL PRIMARY KEY,
|
|
665
|
+
title VARCHAR(42),
|
|
666
|
+
category_id INTEGER REFERENCES categories(id)
|
|
667
|
+
);
|
|
668
|
+
`)
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
})
|
|
672
|
+
app.register(sqlGraphQL)
|
|
673
|
+
teardown(app.close.bind(app))
|
|
674
|
+
|
|
675
|
+
const categories = [{
|
|
676
|
+
name: 'Pets'
|
|
677
|
+
}, {
|
|
678
|
+
name: 'Food'
|
|
679
|
+
}]
|
|
680
|
+
|
|
681
|
+
await app.inject({
|
|
682
|
+
method: 'POST',
|
|
683
|
+
url: '/graphql',
|
|
684
|
+
body: {
|
|
685
|
+
query: `
|
|
686
|
+
mutation batch($inputs: [CategoryInput]!) {
|
|
687
|
+
insertCategories(inputs: $inputs) {
|
|
688
|
+
id
|
|
689
|
+
name
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
`,
|
|
693
|
+
variables: {
|
|
694
|
+
inputs: categories
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
})
|
|
698
|
+
|
|
699
|
+
{
|
|
700
|
+
const res = await app.inject({
|
|
701
|
+
method: 'POST',
|
|
702
|
+
url: '/graphql',
|
|
703
|
+
body: {
|
|
704
|
+
query: `
|
|
705
|
+
mutation {
|
|
706
|
+
savePage(input: { title: "Hello", categoryId: 1 }) {
|
|
707
|
+
id
|
|
708
|
+
title
|
|
709
|
+
category {
|
|
710
|
+
id
|
|
711
|
+
name
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
`
|
|
716
|
+
}
|
|
717
|
+
})
|
|
718
|
+
equal(res.statusCode, 200, 'savePage status code')
|
|
719
|
+
same(res.json(), {
|
|
720
|
+
data: {
|
|
721
|
+
savePage: {
|
|
722
|
+
id: 1,
|
|
723
|
+
title: 'Hello',
|
|
724
|
+
category: {
|
|
725
|
+
id: 1,
|
|
726
|
+
name: 'Pets'
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}, 'savePage response')
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
{
|
|
734
|
+
const res = await app.inject({
|
|
735
|
+
method: 'POST',
|
|
736
|
+
url: '/graphql',
|
|
737
|
+
body: {
|
|
738
|
+
query: `
|
|
739
|
+
query {
|
|
740
|
+
getPageById(id: 1) {
|
|
741
|
+
id
|
|
742
|
+
title
|
|
743
|
+
category {
|
|
744
|
+
id
|
|
745
|
+
name
|
|
746
|
+
pages {
|
|
747
|
+
id
|
|
748
|
+
title
|
|
749
|
+
category {
|
|
750
|
+
id
|
|
751
|
+
name
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
`
|
|
758
|
+
}
|
|
759
|
+
})
|
|
760
|
+
equal(res.statusCode, 200, 'pages status code')
|
|
761
|
+
same(res.json(), {
|
|
762
|
+
data: {
|
|
763
|
+
getPageById: {
|
|
764
|
+
id: 1,
|
|
765
|
+
title: 'Hello',
|
|
766
|
+
category: {
|
|
767
|
+
id: 1,
|
|
768
|
+
name: 'Pets',
|
|
769
|
+
pages: [{
|
|
770
|
+
id: 1,
|
|
771
|
+
title: 'Hello',
|
|
772
|
+
category: {
|
|
773
|
+
id: 1,
|
|
774
|
+
name: 'Pets'
|
|
775
|
+
}
|
|
776
|
+
}]
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}, 'pages response')
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
{
|
|
784
|
+
const res = await app.inject({
|
|
785
|
+
method: 'POST',
|
|
786
|
+
url: '/graphql',
|
|
787
|
+
body: {
|
|
788
|
+
query: `
|
|
789
|
+
query {
|
|
790
|
+
categories {
|
|
791
|
+
id
|
|
792
|
+
name
|
|
793
|
+
pages {
|
|
794
|
+
id
|
|
795
|
+
title
|
|
796
|
+
category {
|
|
797
|
+
id
|
|
798
|
+
name
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
`
|
|
804
|
+
}
|
|
805
|
+
})
|
|
806
|
+
equal(res.statusCode, 200, 'categories.posts status code')
|
|
807
|
+
same(res.json(), {
|
|
808
|
+
data: {
|
|
809
|
+
categories: [{
|
|
810
|
+
id: 1,
|
|
811
|
+
name: 'Pets',
|
|
812
|
+
pages: [{
|
|
813
|
+
id: 1,
|
|
814
|
+
title: 'Hello',
|
|
815
|
+
category: {
|
|
816
|
+
id: 1,
|
|
817
|
+
name: 'Pets'
|
|
818
|
+
}
|
|
819
|
+
}]
|
|
820
|
+
}, {
|
|
821
|
+
id: 2,
|
|
822
|
+
name: 'Food',
|
|
823
|
+
pages: []
|
|
824
|
+
}]
|
|
825
|
+
}
|
|
826
|
+
}, 'categories.posts response')
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
{
|
|
830
|
+
const res = await app.inject({
|
|
831
|
+
method: 'POST',
|
|
832
|
+
url: '/graphql',
|
|
833
|
+
body: {
|
|
834
|
+
query: `
|
|
835
|
+
mutation {
|
|
836
|
+
savePage(input: { title: "Updated", id: 1 }) {
|
|
837
|
+
id
|
|
838
|
+
title
|
|
839
|
+
category {
|
|
840
|
+
id
|
|
841
|
+
name
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
`
|
|
846
|
+
}
|
|
847
|
+
})
|
|
848
|
+
equal(res.statusCode, 200, 'savePage status code')
|
|
849
|
+
same(res.json(), {
|
|
850
|
+
data: {
|
|
851
|
+
savePage: {
|
|
852
|
+
id: 1,
|
|
853
|
+
title: 'Updated',
|
|
854
|
+
category: {
|
|
855
|
+
id: 1,
|
|
856
|
+
name: 'Pets'
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
}, 'savePage response')
|
|
861
|
+
}
|
|
862
|
+
})
|