@platformatic/sql-graphql 0.46.1 → 0.47.0
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/package.json +4 -4
- package/test/array.test.js +0 -372
- package/test/camelcase.test.js +0 -312
- package/test/composite.test.js +0 -474
- package/test/count.test.js +0 -126
- package/test/created_updated_at.test.js +0 -517
- package/test/datatypes.test.js +0 -803
- package/test/enum.test.js +0 -225
- package/test/federation.test.js +0 -312
- package/test/fix-428.test.js +0 -172
- package/test/helper.js +0 -169
- package/test/hooks.test.js +0 -660
- package/test/ignore.test.js +0 -289
- package/test/insert.test.js +0 -181
- package/test/inserted_updated_at.test.js +0 -533
- package/test/nested.test.js +0 -1269
- package/test/no-modification-of-entity.test.js +0 -113
- package/test/or.test.js +0 -302
- package/test/order_by.test.js +0 -397
- package/test/relations.test.js +0 -785
- package/test/schema.test.js +0 -277
- package/test/simple.test.js +0 -959
- package/test/special-chars.test.js +0 -47
- package/test/sqlite.test.js +0 -274
- package/test/subscription.test.js +0 -336
- package/test/types/errors.test-d.ts +0 -15
- package/test/types/index.test-d.ts +0 -32
- package/test/where.test.js +0 -1102
package/test/simple.test.js
DELETED
|
@@ -1,959 +0,0 @@
|
|
|
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, isSQLite, isMysql, isMariaDB, isPg } = require('./helper')
|
|
8
|
-
|
|
9
|
-
async function createBasicPages (db, sql) {
|
|
10
|
-
if (isSQLite) {
|
|
11
|
-
await db.query(sql`CREATE TABLE pages (
|
|
12
|
-
id INTEGER PRIMARY KEY,
|
|
13
|
-
title VARCHAR(42)
|
|
14
|
-
);`)
|
|
15
|
-
} else {
|
|
16
|
-
await db.query(sql`CREATE TABLE pages (
|
|
17
|
-
id SERIAL PRIMARY KEY,
|
|
18
|
-
title VARCHAR(42)
|
|
19
|
-
);`)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
test('simple db simple graphql schema', async ({ pass, teardown, same, equal }) => {
|
|
24
|
-
const app = fastify()
|
|
25
|
-
app.register(sqlMapper, {
|
|
26
|
-
...connInfo,
|
|
27
|
-
async onDatabaseLoad (db, sql) {
|
|
28
|
-
pass('onDatabaseLoad called')
|
|
29
|
-
|
|
30
|
-
await clear(db, sql)
|
|
31
|
-
await createBasicPages(db, sql)
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
app.register(sqlGraphQL)
|
|
35
|
-
teardown(app.close.bind(app))
|
|
36
|
-
|
|
37
|
-
await app.ready()
|
|
38
|
-
|
|
39
|
-
{
|
|
40
|
-
const res = await app.inject({
|
|
41
|
-
method: 'POST',
|
|
42
|
-
url: '/graphql',
|
|
43
|
-
body: {
|
|
44
|
-
query: `
|
|
45
|
-
mutation {
|
|
46
|
-
savePage(input: { title: "Hello" }) {
|
|
47
|
-
id
|
|
48
|
-
title
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
`
|
|
52
|
-
}
|
|
53
|
-
})
|
|
54
|
-
equal(res.statusCode, 200, 'savePage status code')
|
|
55
|
-
same(res.json(), {
|
|
56
|
-
data: {
|
|
57
|
-
savePage: {
|
|
58
|
-
id: 1,
|
|
59
|
-
title: 'Hello'
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}, 'savePage response')
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
{
|
|
66
|
-
const res = await app.inject({
|
|
67
|
-
method: 'POST',
|
|
68
|
-
url: '/graphql',
|
|
69
|
-
body: {
|
|
70
|
-
query: `
|
|
71
|
-
query {
|
|
72
|
-
getPageById(id: 1) {
|
|
73
|
-
id
|
|
74
|
-
title
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
`
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
equal(res.statusCode, 200, 'pages status code')
|
|
81
|
-
same(res.json(), {
|
|
82
|
-
data: {
|
|
83
|
-
getPageById: {
|
|
84
|
-
id: 1,
|
|
85
|
-
title: 'Hello'
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}, 'pages response')
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
{
|
|
92
|
-
const res = await app.inject({
|
|
93
|
-
method: 'POST',
|
|
94
|
-
url: '/graphql',
|
|
95
|
-
body: {
|
|
96
|
-
query: `
|
|
97
|
-
mutation {
|
|
98
|
-
savePage(input: { id: 1, title: "Hello World" }) {
|
|
99
|
-
id
|
|
100
|
-
title
|
|
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 World'
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}, 'savePage response')
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
{
|
|
118
|
-
const res = await app.inject({
|
|
119
|
-
method: 'POST',
|
|
120
|
-
url: '/graphql',
|
|
121
|
-
body: {
|
|
122
|
-
query: `
|
|
123
|
-
query {
|
|
124
|
-
getPageById(id: 1) {
|
|
125
|
-
id
|
|
126
|
-
title
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
`
|
|
130
|
-
}
|
|
131
|
-
})
|
|
132
|
-
equal(res.statusCode, 200, 'pages status code')
|
|
133
|
-
same(res.json(), {
|
|
134
|
-
data: {
|
|
135
|
-
getPageById: {
|
|
136
|
-
id: 1,
|
|
137
|
-
title: 'Hello World'
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}, 'pages response')
|
|
141
|
-
}
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
test('with federationMetadata', async ({ pass, teardown, same, equal }) => {
|
|
145
|
-
const app = fastify()
|
|
146
|
-
app.register(sqlMapper, {
|
|
147
|
-
...connInfo,
|
|
148
|
-
federationMetadata: true,
|
|
149
|
-
async onDatabaseLoad (db, sql) {
|
|
150
|
-
pass('onDatabaseLoad called')
|
|
151
|
-
|
|
152
|
-
await clear(db, sql)
|
|
153
|
-
await createBasicPages(db, sql)
|
|
154
|
-
}
|
|
155
|
-
})
|
|
156
|
-
app.register(sqlGraphQL)
|
|
157
|
-
teardown(app.close.bind(app))
|
|
158
|
-
|
|
159
|
-
await app.ready()
|
|
160
|
-
|
|
161
|
-
{
|
|
162
|
-
const res = await app.inject({
|
|
163
|
-
method: 'POST',
|
|
164
|
-
url: '/graphql',
|
|
165
|
-
body: {
|
|
166
|
-
query: `
|
|
167
|
-
mutation {
|
|
168
|
-
savePage(input: { title: "Hello" }) {
|
|
169
|
-
id
|
|
170
|
-
title
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
`
|
|
174
|
-
}
|
|
175
|
-
})
|
|
176
|
-
equal(res.statusCode, 200, 'savePage status code')
|
|
177
|
-
same(res.json(), {
|
|
178
|
-
data: {
|
|
179
|
-
savePage: {
|
|
180
|
-
id: 1,
|
|
181
|
-
title: 'Hello'
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}, 'savePage response')
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
const res = await app.inject({
|
|
189
|
-
method: 'POST',
|
|
190
|
-
url: '/graphql',
|
|
191
|
-
body: {
|
|
192
|
-
query: `
|
|
193
|
-
query {
|
|
194
|
-
getPageById(id: 1) {
|
|
195
|
-
id
|
|
196
|
-
title
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
`
|
|
200
|
-
}
|
|
201
|
-
})
|
|
202
|
-
equal(res.statusCode, 200, 'pages status code')
|
|
203
|
-
same(res.json(), {
|
|
204
|
-
data: {
|
|
205
|
-
getPageById: {
|
|
206
|
-
id: 1,
|
|
207
|
-
title: 'Hello'
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}, 'pages response')
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
{
|
|
214
|
-
const res = await app.inject({
|
|
215
|
-
method: 'POST',
|
|
216
|
-
url: '/graphql',
|
|
217
|
-
body: {
|
|
218
|
-
query: `
|
|
219
|
-
mutation {
|
|
220
|
-
savePage(input: { id: 1, title: "Hello World" }) {
|
|
221
|
-
id
|
|
222
|
-
title
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
`
|
|
226
|
-
}
|
|
227
|
-
})
|
|
228
|
-
equal(res.statusCode, 200, 'savePage status code')
|
|
229
|
-
same(res.json(), {
|
|
230
|
-
data: {
|
|
231
|
-
savePage: {
|
|
232
|
-
id: 1,
|
|
233
|
-
title: 'Hello World'
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}, 'savePage response')
|
|
237
|
-
}
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
test('add resolver', async ({ pass, teardown, same, equal }) => {
|
|
241
|
-
const app = fastify()
|
|
242
|
-
|
|
243
|
-
const schema = `
|
|
244
|
-
extend type Query {
|
|
245
|
-
search(title: String!): [Page]
|
|
246
|
-
}
|
|
247
|
-
`
|
|
248
|
-
const resolvers = {
|
|
249
|
-
Query: {
|
|
250
|
-
async search (root, args, context, info) {
|
|
251
|
-
pass('search resolver called')
|
|
252
|
-
const { db, sql } = context.app.platformatic
|
|
253
|
-
const res = await db.query(sql`SELECT * FROM pages WHERE title LIKE ${'%' + args.title + '%'}`)
|
|
254
|
-
|
|
255
|
-
return res
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
app.register(sqlMapper, {
|
|
261
|
-
...connInfo,
|
|
262
|
-
async onDatabaseLoad (db, sql) {
|
|
263
|
-
pass('onDatabaseLoad called')
|
|
264
|
-
|
|
265
|
-
await clear(db, sql)
|
|
266
|
-
await createBasicPages(db, sql)
|
|
267
|
-
}
|
|
268
|
-
})
|
|
269
|
-
app.register(sqlGraphQL, {
|
|
270
|
-
schema,
|
|
271
|
-
resolvers
|
|
272
|
-
})
|
|
273
|
-
teardown(app.close.bind(app))
|
|
274
|
-
|
|
275
|
-
await app.ready()
|
|
276
|
-
|
|
277
|
-
{
|
|
278
|
-
const res = await app.inject({
|
|
279
|
-
method: 'POST',
|
|
280
|
-
url: '/graphql',
|
|
281
|
-
body: {
|
|
282
|
-
query: `
|
|
283
|
-
mutation {
|
|
284
|
-
savePage(input: { title: "Hello World" }) {
|
|
285
|
-
id
|
|
286
|
-
title
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
`
|
|
290
|
-
}
|
|
291
|
-
})
|
|
292
|
-
equal(res.statusCode, 200, 'savePage status code')
|
|
293
|
-
same(res.json(), {
|
|
294
|
-
data: {
|
|
295
|
-
savePage: {
|
|
296
|
-
id: 1,
|
|
297
|
-
title: 'Hello World'
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}, 'savePage response')
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
{
|
|
304
|
-
const res = await app.inject({
|
|
305
|
-
method: 'POST',
|
|
306
|
-
url: '/graphql',
|
|
307
|
-
body: {
|
|
308
|
-
query: `
|
|
309
|
-
mutation {
|
|
310
|
-
savePage(input: { title: "ABC" }) {
|
|
311
|
-
id
|
|
312
|
-
title
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
`
|
|
316
|
-
}
|
|
317
|
-
})
|
|
318
|
-
equal(res.statusCode, 200, 'savePage status code')
|
|
319
|
-
same(res.json(), {
|
|
320
|
-
data: {
|
|
321
|
-
savePage: {
|
|
322
|
-
id: 2,
|
|
323
|
-
title: 'ABC'
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}, 'savePage response')
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
{
|
|
330
|
-
const res = await app.inject({
|
|
331
|
-
method: 'POST',
|
|
332
|
-
url: '/graphql',
|
|
333
|
-
body: {
|
|
334
|
-
query: `
|
|
335
|
-
query {
|
|
336
|
-
search(title: "Hello") {
|
|
337
|
-
id
|
|
338
|
-
title
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
`
|
|
342
|
-
}
|
|
343
|
-
})
|
|
344
|
-
equal(res.statusCode, 200, 'pages status code')
|
|
345
|
-
same(res.json(), {
|
|
346
|
-
data: {
|
|
347
|
-
search: [{
|
|
348
|
-
id: 1,
|
|
349
|
-
title: 'Hello World'
|
|
350
|
-
}]
|
|
351
|
-
}
|
|
352
|
-
}, 'pages response')
|
|
353
|
-
}
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
test('override resolver', async ({ pass, teardown, same, equal, plan }) => {
|
|
357
|
-
plan(3)
|
|
358
|
-
|
|
359
|
-
const app = fastify()
|
|
360
|
-
app.register(sqlMapper, {
|
|
361
|
-
...connInfo,
|
|
362
|
-
async onDatabaseLoad (db, sql) {
|
|
363
|
-
await clear(db, sql)
|
|
364
|
-
await createBasicPages(db, sql)
|
|
365
|
-
}
|
|
366
|
-
})
|
|
367
|
-
app.register(sqlGraphQL, {
|
|
368
|
-
resolvers: {
|
|
369
|
-
Mutation: {
|
|
370
|
-
async savePage (root, args, context, info) {
|
|
371
|
-
pass('savePage resolver called')
|
|
372
|
-
const { db, sql } = context.app.platformatic
|
|
373
|
-
if (isSQLite) {
|
|
374
|
-
const insert = sql`
|
|
375
|
-
INSERT INTO pages (title)
|
|
376
|
-
VALUES (${args.input.title})
|
|
377
|
-
`
|
|
378
|
-
|
|
379
|
-
await db.query(insert)
|
|
380
|
-
|
|
381
|
-
const res2 = await db.query(sql`
|
|
382
|
-
SELECT last_insert_rowid()
|
|
383
|
-
`)
|
|
384
|
-
|
|
385
|
-
const id = res2[0]['last_insert_rowid()']
|
|
386
|
-
return {
|
|
387
|
-
...args.input,
|
|
388
|
-
id
|
|
389
|
-
}
|
|
390
|
-
} else if (isMysql && !db.isMariaDB) {
|
|
391
|
-
const insert = sql`
|
|
392
|
-
INSERT INTO pages (title)
|
|
393
|
-
VALUES (${args.input.title})
|
|
394
|
-
`
|
|
395
|
-
|
|
396
|
-
await db.query(insert)
|
|
397
|
-
|
|
398
|
-
const res2 = await db.query(sql`
|
|
399
|
-
SELECT last_insert_id()
|
|
400
|
-
`)
|
|
401
|
-
|
|
402
|
-
const id = res2[0]['last_insert_id()']
|
|
403
|
-
return {
|
|
404
|
-
...args.input,
|
|
405
|
-
id
|
|
406
|
-
}
|
|
407
|
-
} else {
|
|
408
|
-
const insert = sql`
|
|
409
|
-
INSERT INTO pages (title)
|
|
410
|
-
VALUES (${args.input.title})
|
|
411
|
-
RETURNING *
|
|
412
|
-
`
|
|
413
|
-
const res = await db.query(insert)
|
|
414
|
-
return res[0]
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
})
|
|
420
|
-
teardown(app.close.bind(app))
|
|
421
|
-
|
|
422
|
-
const res = await app.inject({
|
|
423
|
-
method: 'POST',
|
|
424
|
-
url: '/graphql',
|
|
425
|
-
body: {
|
|
426
|
-
query: `
|
|
427
|
-
mutation {
|
|
428
|
-
savePage(input: { title: "Hello" }) {
|
|
429
|
-
id
|
|
430
|
-
title
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
`
|
|
434
|
-
}
|
|
435
|
-
})
|
|
436
|
-
equal(res.statusCode, 200, 'savePage status code')
|
|
437
|
-
same(res.json(), {
|
|
438
|
-
data: {
|
|
439
|
-
savePage: {
|
|
440
|
-
id: 1,
|
|
441
|
-
title: 'Hello'
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}, 'savePage response')
|
|
445
|
-
})
|
|
446
|
-
|
|
447
|
-
test('add totally new type and resolver', async ({ pass, teardown, same, equal, plan }) => {
|
|
448
|
-
plan(4)
|
|
449
|
-
|
|
450
|
-
const app = fastify()
|
|
451
|
-
app.register(sqlMapper, {
|
|
452
|
-
...connInfo,
|
|
453
|
-
async onDatabaseLoad (db, sql) {
|
|
454
|
-
await clear(db, sql)
|
|
455
|
-
await createBasicPages(db, sql)
|
|
456
|
-
}
|
|
457
|
-
})
|
|
458
|
-
app.register(sqlGraphQL, {
|
|
459
|
-
schema: `
|
|
460
|
-
type Category {
|
|
461
|
-
id: ID!
|
|
462
|
-
name: String
|
|
463
|
-
upper: String
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
extend type Query {
|
|
467
|
-
getCategory: Category
|
|
468
|
-
}
|
|
469
|
-
`,
|
|
470
|
-
resolvers: {
|
|
471
|
-
Query: {
|
|
472
|
-
async getCategory (root, args, context, info) {
|
|
473
|
-
pass('getCategory resolver called')
|
|
474
|
-
return {
|
|
475
|
-
id: 1,
|
|
476
|
-
name: 'Hello'
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
},
|
|
480
|
-
Category: {
|
|
481
|
-
upper (root, args, context, info) {
|
|
482
|
-
pass('name resolver called')
|
|
483
|
-
return root.name.toUpperCase()
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
})
|
|
488
|
-
teardown(app.close.bind(app))
|
|
489
|
-
|
|
490
|
-
const res = await app.inject({
|
|
491
|
-
method: 'POST',
|
|
492
|
-
url: '/graphql',
|
|
493
|
-
body: {
|
|
494
|
-
query: `
|
|
495
|
-
query {
|
|
496
|
-
getCategory {
|
|
497
|
-
id
|
|
498
|
-
name
|
|
499
|
-
upper
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
`
|
|
503
|
-
}
|
|
504
|
-
})
|
|
505
|
-
equal(res.statusCode, 200, 'getCategory status code')
|
|
506
|
-
same(res.json(), {
|
|
507
|
-
data: {
|
|
508
|
-
getCategory: {
|
|
509
|
-
id: 1,
|
|
510
|
-
name: 'Hello',
|
|
511
|
-
upper: 'HELLO'
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}, 'getCategory response')
|
|
515
|
-
})
|
|
516
|
-
|
|
517
|
-
test('list', async ({ pass, teardown, same, equal }) => {
|
|
518
|
-
const app = fastify()
|
|
519
|
-
app.register(sqlMapper, {
|
|
520
|
-
...connInfo,
|
|
521
|
-
async onDatabaseLoad (db, sql) {
|
|
522
|
-
pass('onDatabaseLoad called')
|
|
523
|
-
|
|
524
|
-
await clear(db, sql)
|
|
525
|
-
|
|
526
|
-
if (isSQLite) {
|
|
527
|
-
await db.query(sql`CREATE TABLE posts (
|
|
528
|
-
id INTEGER PRIMARY KEY,
|
|
529
|
-
title VARCHAR(42),
|
|
530
|
-
long_text TEXT
|
|
531
|
-
);`)
|
|
532
|
-
} else {
|
|
533
|
-
await db.query(sql`CREATE TABLE posts (
|
|
534
|
-
id SERIAL PRIMARY KEY,
|
|
535
|
-
title VARCHAR(42),
|
|
536
|
-
long_text TEXT
|
|
537
|
-
);`)
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
})
|
|
541
|
-
app.register(sqlGraphQL)
|
|
542
|
-
teardown(app.close.bind(app))
|
|
543
|
-
|
|
544
|
-
await app.ready()
|
|
545
|
-
|
|
546
|
-
const posts = [{
|
|
547
|
-
title: 'Post 1',
|
|
548
|
-
longText: 'This is a long text 1'
|
|
549
|
-
}, {
|
|
550
|
-
title: 'Post 2',
|
|
551
|
-
longText: 'This is a long text 2'
|
|
552
|
-
}, {
|
|
553
|
-
title: 'Post 3',
|
|
554
|
-
longText: 'This is a long text 3'
|
|
555
|
-
}, {
|
|
556
|
-
title: 'Post 4',
|
|
557
|
-
longText: 'This is a long text 4'
|
|
558
|
-
}]
|
|
559
|
-
|
|
560
|
-
for (const post of posts) {
|
|
561
|
-
await app.inject({
|
|
562
|
-
method: 'POST',
|
|
563
|
-
url: '/graphql',
|
|
564
|
-
body: {
|
|
565
|
-
query: `
|
|
566
|
-
mutation {
|
|
567
|
-
savePost(input: { title: "${post.title}", longText: "${post.longText}" }) {
|
|
568
|
-
id
|
|
569
|
-
title,
|
|
570
|
-
longText
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
`
|
|
574
|
-
}
|
|
575
|
-
})
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
{
|
|
579
|
-
const res = await app.inject({
|
|
580
|
-
method: 'POST',
|
|
581
|
-
url: '/graphql',
|
|
582
|
-
body: {
|
|
583
|
-
query: `
|
|
584
|
-
query {
|
|
585
|
-
posts {
|
|
586
|
-
id
|
|
587
|
-
title
|
|
588
|
-
longText
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
`
|
|
592
|
-
}
|
|
593
|
-
})
|
|
594
|
-
equal(res.statusCode, 200, 'posts status code')
|
|
595
|
-
same(res.json(), {
|
|
596
|
-
data: {
|
|
597
|
-
posts: posts.map((p, i) => {
|
|
598
|
-
return { ...p, id: i + 1 + '' }
|
|
599
|
-
})
|
|
600
|
-
}
|
|
601
|
-
}, 'posts response')
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
{
|
|
605
|
-
const res = await app.inject({
|
|
606
|
-
method: 'POST',
|
|
607
|
-
url: '/graphql',
|
|
608
|
-
body: {
|
|
609
|
-
query: `
|
|
610
|
-
query {
|
|
611
|
-
posts (limit: 2, offset: 1) {
|
|
612
|
-
id
|
|
613
|
-
title
|
|
614
|
-
longText
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
`
|
|
618
|
-
}
|
|
619
|
-
})
|
|
620
|
-
equal(res.statusCode, 200, 'posts status code')
|
|
621
|
-
same(res.json(), {
|
|
622
|
-
data: {
|
|
623
|
-
posts: posts.map((p, i) => {
|
|
624
|
-
return { ...p, id: i + 1 + '' }
|
|
625
|
-
}).slice(1, 3)
|
|
626
|
-
}
|
|
627
|
-
}, 'posts response')
|
|
628
|
-
}
|
|
629
|
-
})
|
|
630
|
-
|
|
631
|
-
test('not found', async ({ pass, teardown, same, equal }) => {
|
|
632
|
-
const app = fastify()
|
|
633
|
-
app.register(sqlMapper, {
|
|
634
|
-
...connInfo,
|
|
635
|
-
async onDatabaseLoad (db, sql) {
|
|
636
|
-
pass('onDatabaseLoad called')
|
|
637
|
-
|
|
638
|
-
await clear(db, sql)
|
|
639
|
-
|
|
640
|
-
await createBasicPages(db, sql)
|
|
641
|
-
}
|
|
642
|
-
})
|
|
643
|
-
app.register(sqlGraphQL)
|
|
644
|
-
teardown(app.close.bind(app))
|
|
645
|
-
|
|
646
|
-
await app.ready()
|
|
647
|
-
|
|
648
|
-
{
|
|
649
|
-
const res = await app.inject({
|
|
650
|
-
method: 'POST',
|
|
651
|
-
url: '/graphql',
|
|
652
|
-
body: {
|
|
653
|
-
query: `
|
|
654
|
-
query {
|
|
655
|
-
getPageById(id: 1) {
|
|
656
|
-
id
|
|
657
|
-
title
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
`
|
|
661
|
-
}
|
|
662
|
-
})
|
|
663
|
-
equal(res.statusCode, 200, 'getPageById status code')
|
|
664
|
-
same(res.json(), {
|
|
665
|
-
data: {
|
|
666
|
-
getPageById: null
|
|
667
|
-
}
|
|
668
|
-
}, 'getPageById response')
|
|
669
|
-
}
|
|
670
|
-
})
|
|
671
|
-
|
|
672
|
-
test('graphiql is enabled by default', async ({ pass, teardown, same, equal }) => {
|
|
673
|
-
const app = fastify()
|
|
674
|
-
app.register(sqlMapper, {
|
|
675
|
-
...connInfo,
|
|
676
|
-
async onDatabaseLoad (db, sql) {
|
|
677
|
-
pass('onDatabaseLoad called')
|
|
678
|
-
|
|
679
|
-
await clear(db, sql)
|
|
680
|
-
await createBasicPages(db, sql)
|
|
681
|
-
}
|
|
682
|
-
})
|
|
683
|
-
app.register(sqlGraphQL)
|
|
684
|
-
teardown(app.close.bind(app))
|
|
685
|
-
|
|
686
|
-
const res = await app.inject('/graphiql')
|
|
687
|
-
equal(res.statusCode, 200)
|
|
688
|
-
})
|
|
689
|
-
|
|
690
|
-
test('graphiql can be disabled', async ({ pass, teardown, same, equal }) => {
|
|
691
|
-
const app = fastify()
|
|
692
|
-
app.register(sqlMapper, {
|
|
693
|
-
...connInfo,
|
|
694
|
-
async onDatabaseLoad (db, sql) {
|
|
695
|
-
pass('onDatabaseLoad called')
|
|
696
|
-
|
|
697
|
-
await clear(db, sql)
|
|
698
|
-
await createBasicPages(db, sql)
|
|
699
|
-
}
|
|
700
|
-
})
|
|
701
|
-
app.register(sqlGraphQL, {
|
|
702
|
-
graphiql: false
|
|
703
|
-
})
|
|
704
|
-
teardown(app.close.bind(app))
|
|
705
|
-
|
|
706
|
-
const res = await app.inject('/graphiql')
|
|
707
|
-
equal(res.statusCode, 404)
|
|
708
|
-
})
|
|
709
|
-
|
|
710
|
-
test('default query hello should be created when no entities are found', async ({ pass, teardown, same, equal }) => {
|
|
711
|
-
const app = fastify()
|
|
712
|
-
app.register(sqlMapper, {
|
|
713
|
-
...connInfo,
|
|
714
|
-
async onDatabaseLoad (db, sql) {
|
|
715
|
-
pass('onDatabaseLoad called')
|
|
716
|
-
await clear(db, sql)
|
|
717
|
-
}
|
|
718
|
-
})
|
|
719
|
-
app.register(sqlGraphQL)
|
|
720
|
-
teardown(app.close.bind(app))
|
|
721
|
-
|
|
722
|
-
const res = await app.inject({
|
|
723
|
-
method: 'POST',
|
|
724
|
-
url: '/graphql',
|
|
725
|
-
body: {
|
|
726
|
-
query: 'query { hello }'
|
|
727
|
-
}
|
|
728
|
-
})
|
|
729
|
-
equal(res.statusCode, 200)
|
|
730
|
-
same(res.json(), {
|
|
731
|
-
data: {
|
|
732
|
-
hello: 'Hello Platformatic!'
|
|
733
|
-
}
|
|
734
|
-
})
|
|
735
|
-
})
|
|
736
|
-
|
|
737
|
-
test('default query hello should not be created when entities are found', async ({ pass, teardown, same, equal }) => {
|
|
738
|
-
const app = fastify()
|
|
739
|
-
app.register(sqlMapper, {
|
|
740
|
-
...connInfo,
|
|
741
|
-
async onDatabaseLoad (db, sql) {
|
|
742
|
-
pass('onDatabaseLoad called')
|
|
743
|
-
await clear(db, sql)
|
|
744
|
-
await createBasicPages(db, sql)
|
|
745
|
-
}
|
|
746
|
-
})
|
|
747
|
-
app.register(sqlGraphQL)
|
|
748
|
-
teardown(app.close.bind(app))
|
|
749
|
-
|
|
750
|
-
const res = await app.inject({
|
|
751
|
-
method: 'POST',
|
|
752
|
-
url: '/graphql',
|
|
753
|
-
body: {
|
|
754
|
-
query: 'query { hello }'
|
|
755
|
-
}
|
|
756
|
-
})
|
|
757
|
-
equal(res.statusCode, 400)
|
|
758
|
-
const json = res.json()
|
|
759
|
-
same(json.data, null)
|
|
760
|
-
same(json.errors[0].message, 'Cannot query field "hello" on type "Query".')
|
|
761
|
-
})
|
|
762
|
-
|
|
763
|
-
test('primary key snake_case', async ({ pass, teardown, same, equal }) => {
|
|
764
|
-
async function createBasicPagesWithSnakeCasePK (db, sql) {
|
|
765
|
-
if (isSQLite) {
|
|
766
|
-
await db.query(sql`CREATE TABLE pages (
|
|
767
|
-
page_id INTEGER PRIMARY KEY,
|
|
768
|
-
title VARCHAR(42)
|
|
769
|
-
);`)
|
|
770
|
-
} else {
|
|
771
|
-
await db.query(sql`CREATE TABLE pages (
|
|
772
|
-
page_id SERIAL PRIMARY KEY,
|
|
773
|
-
title VARCHAR(42)
|
|
774
|
-
);`)
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
const app = fastify()
|
|
779
|
-
app.register(sqlMapper, {
|
|
780
|
-
...connInfo,
|
|
781
|
-
async onDatabaseLoad (db, sql) {
|
|
782
|
-
pass('onDatabaseLoad called')
|
|
783
|
-
|
|
784
|
-
await clear(db, sql)
|
|
785
|
-
await createBasicPagesWithSnakeCasePK(db, sql)
|
|
786
|
-
}
|
|
787
|
-
})
|
|
788
|
-
app.register(sqlGraphQL, {
|
|
789
|
-
graphiql: false
|
|
790
|
-
})
|
|
791
|
-
teardown(app.close.bind(app))
|
|
792
|
-
|
|
793
|
-
const res = await app.inject('/graphiql')
|
|
794
|
-
equal(res.statusCode, 404)
|
|
795
|
-
|
|
796
|
-
{
|
|
797
|
-
const res = await app.inject({
|
|
798
|
-
method: 'POST',
|
|
799
|
-
url: '/graphql',
|
|
800
|
-
body: {
|
|
801
|
-
query: `
|
|
802
|
-
mutation {
|
|
803
|
-
savePage(input: { title: "Hello" }) {
|
|
804
|
-
pageId
|
|
805
|
-
title
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
`
|
|
809
|
-
}
|
|
810
|
-
})
|
|
811
|
-
equal(res.statusCode, 200, 'savePage status code')
|
|
812
|
-
same(res.json(), {
|
|
813
|
-
data: {
|
|
814
|
-
savePage: {
|
|
815
|
-
pageId: 1,
|
|
816
|
-
title: 'Hello'
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
}, 'savePage response')
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
{
|
|
823
|
-
const res = await app.inject({
|
|
824
|
-
method: 'POST',
|
|
825
|
-
url: '/graphql',
|
|
826
|
-
body: {
|
|
827
|
-
query: `
|
|
828
|
-
query {
|
|
829
|
-
getPageByPageId(pageId: 1) {
|
|
830
|
-
pageId
|
|
831
|
-
title
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
`
|
|
835
|
-
}
|
|
836
|
-
})
|
|
837
|
-
equal(res.statusCode, 200, 'pages status code')
|
|
838
|
-
same(res.json(), {
|
|
839
|
-
data: {
|
|
840
|
-
getPageByPageId: {
|
|
841
|
-
pageId: 1,
|
|
842
|
-
title: 'Hello'
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
}, 'pages response')
|
|
846
|
-
}
|
|
847
|
-
})
|
|
848
|
-
|
|
849
|
-
test('deserialize JSON columns', { skip: isSQLite }, async (t) => {
|
|
850
|
-
const { pass, teardown, same } = t
|
|
851
|
-
const app = fastify()
|
|
852
|
-
const jsonData = {
|
|
853
|
-
foo: 'bar',
|
|
854
|
-
baz: 42,
|
|
855
|
-
items: ['foo', 'bar'],
|
|
856
|
-
nested: {
|
|
857
|
-
hello: 'world'
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
app.register(sqlMapper, {
|
|
861
|
-
...connInfo,
|
|
862
|
-
async onDatabaseLoad (db, sql) {
|
|
863
|
-
pass('onDatabaseLoad called')
|
|
864
|
-
|
|
865
|
-
await clear(db, sql)
|
|
866
|
-
|
|
867
|
-
await db.query(sql`CREATE TABLE pages (
|
|
868
|
-
id SERIAL PRIMARY KEY,
|
|
869
|
-
title VARCHAR(255) NOT NULL,
|
|
870
|
-
metadata JSON NOT NULL
|
|
871
|
-
);`)
|
|
872
|
-
|
|
873
|
-
await db.query(sql`INSERT INTO pages (id, title, metadata) VALUES (1, 'Hello World', ${JSON.stringify(jsonData)})`)
|
|
874
|
-
}
|
|
875
|
-
})
|
|
876
|
-
app.register(sqlGraphQL, {
|
|
877
|
-
graphiql: false
|
|
878
|
-
})
|
|
879
|
-
teardown(app.close.bind(app))
|
|
880
|
-
|
|
881
|
-
await app.ready()
|
|
882
|
-
const res = await app.inject({
|
|
883
|
-
method: 'POST',
|
|
884
|
-
url: '/graphql',
|
|
885
|
-
body: {
|
|
886
|
-
query: `
|
|
887
|
-
query {
|
|
888
|
-
getPageById(id: 1) {
|
|
889
|
-
id
|
|
890
|
-
title
|
|
891
|
-
metadata
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
`
|
|
895
|
-
}
|
|
896
|
-
})
|
|
897
|
-
const json = res.json()
|
|
898
|
-
if (isMariaDB) {
|
|
899
|
-
same(json.data.getPageById.metadata, JSON.stringify(jsonData))
|
|
900
|
-
} else {
|
|
901
|
-
same(json.data.getPageById.metadata, jsonData)
|
|
902
|
-
}
|
|
903
|
-
})
|
|
904
|
-
|
|
905
|
-
test('deserialize JSONB columns', { skip: !isPg }, async (t) => {
|
|
906
|
-
const { pass, teardown, same } = t
|
|
907
|
-
const app = fastify()
|
|
908
|
-
const jsonData = {
|
|
909
|
-
foo: 'bar',
|
|
910
|
-
baz: 42,
|
|
911
|
-
items: ['foo', 'bar'],
|
|
912
|
-
nested: {
|
|
913
|
-
hello: 'world'
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
app.register(sqlMapper, {
|
|
917
|
-
...connInfo,
|
|
918
|
-
async onDatabaseLoad (db, sql) {
|
|
919
|
-
pass('onDatabaseLoad called')
|
|
920
|
-
|
|
921
|
-
await clear(db, sql)
|
|
922
|
-
|
|
923
|
-
await db.query(sql`CREATE TABLE pages (
|
|
924
|
-
id SERIAL PRIMARY KEY,
|
|
925
|
-
title VARCHAR(255) NOT NULL,
|
|
926
|
-
metadata JSONB NOT NULL
|
|
927
|
-
);`)
|
|
928
|
-
|
|
929
|
-
await db.query(sql`INSERT INTO pages (id, title, metadata) VALUES (1, 'Hello World', ${JSON.stringify(jsonData)})`)
|
|
930
|
-
}
|
|
931
|
-
})
|
|
932
|
-
app.register(sqlGraphQL, {
|
|
933
|
-
graphiql: false
|
|
934
|
-
})
|
|
935
|
-
teardown(app.close.bind(app))
|
|
936
|
-
|
|
937
|
-
await app.ready()
|
|
938
|
-
const res = await app.inject({
|
|
939
|
-
method: 'POST',
|
|
940
|
-
url: '/graphql',
|
|
941
|
-
body: {
|
|
942
|
-
query: `
|
|
943
|
-
query {
|
|
944
|
-
getPageById(id: 1) {
|
|
945
|
-
id
|
|
946
|
-
title
|
|
947
|
-
metadata
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
`
|
|
951
|
-
}
|
|
952
|
-
})
|
|
953
|
-
const json = res.json()
|
|
954
|
-
if (isMariaDB) {
|
|
955
|
-
same(json.data.getPageById.metadata, JSON.stringify(jsonData))
|
|
956
|
-
} else {
|
|
957
|
-
same(json.data.getPageById.metadata, jsonData)
|
|
958
|
-
}
|
|
959
|
-
})
|