@expo/entity-database-adapter-knex 0.35.0 → 0.36.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/build/PostgresEntityDatabaseAdapter.d.ts +1 -1
- package/build/PostgresEntityDatabaseAdapter.js.map +1 -1
- package/build/PostgresEntityDatabaseAdapterProvider.d.ts +1 -1
- package/build/PostgresEntityQueryContextProvider.js +1 -0
- package/build/PostgresEntityQueryContextProvider.js.map +1 -1
- package/build/__integration-tests__/PostgresEntityIntegration-test.js +41 -28
- package/build/__integration-tests__/PostgresEntityIntegration-test.js.map +1 -1
- package/build/__integration-tests__/PostgresEntityQueryContextProvider-test.js.map +1 -1
- package/build/errors/__tests__/wrapNativePostgresCallAsync-test.js.map +1 -1
- package/build/errors/wrapNativePostgresCallAsync.js.map +1 -1
- package/build/testfixtures/ErrorsTestEntity.js +12 -15
- package/build/testfixtures/ErrorsTestEntity.js.map +1 -1
- package/build/testfixtures/InvalidTestEntity.js +12 -15
- package/build/testfixtures/InvalidTestEntity.js.map +1 -1
- package/build/testfixtures/PostgresTestEntity.js +12 -15
- package/build/testfixtures/PostgresTestEntity.js.map +1 -1
- package/build/testfixtures/PostgresTriggerTestEntity.js +16 -15
- package/build/testfixtures/PostgresTriggerTestEntity.js.map +1 -1
- package/build/testfixtures/PostgresUniqueTestEntity.js +12 -15
- package/build/testfixtures/PostgresUniqueTestEntity.js.map +1 -1
- package/build/testfixtures/PostgresValidatorTestEntity.js +14 -15
- package/build/testfixtures/PostgresValidatorTestEntity.js.map +1 -1
- package/package.json +5 -5
- package/src/PostgresEntityDatabaseAdapter.ts +15 -13
- package/src/PostgresEntityDatabaseAdapterProvider.ts +2 -2
- package/src/PostgresEntityQueryContextProvider.ts +5 -5
- package/src/__integration-tests__/PostgresEntityIntegration-test.ts +129 -106
- package/src/__integration-tests__/PostgresInvalidSetup-test.ts +8 -8
- package/src/__integration-tests__/errors-test.ts +11 -11
- package/src/__tests__/EntityFields-test.ts +3 -3
- package/src/errors/wrapNativePostgresCallAsync.ts +2 -2
- package/src/testfixtures/ErrorsTestEntity.ts +2 -2
- package/src/testfixtures/PostgresTriggerTestEntity.ts +10 -4
- package/src/testfixtures/PostgresValidatorTestEntity.ts +2 -2
- package/src/testfixtures/createKnexIntegrationTestEntityCompanionProvider.ts +2 -2
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OrderByOrdering,
|
|
3
3
|
createUnitTestEntityCompanionProvider,
|
|
4
|
-
enforceResultsAsync,
|
|
5
4
|
ViewerContext,
|
|
6
5
|
TransactionIsolationLevel,
|
|
7
6
|
} from '@expo/entity';
|
|
8
7
|
import { enforceAsyncResult } from '@expo/results';
|
|
9
8
|
import { knex, Knex } from 'knex';
|
|
10
9
|
import nullthrows from 'nullthrows';
|
|
10
|
+
import { setTimeout } from 'timers/promises';
|
|
11
11
|
|
|
12
12
|
import PostgresTestEntity from '../testfixtures/PostgresTestEntity';
|
|
13
13
|
import PostgresTriggerTestEntity from '../testfixtures/PostgresTriggerTestEntity';
|
|
@@ -42,7 +42,7 @@ describe('postgres entity integration', () => {
|
|
|
42
42
|
it('supports parallel partial updates', async () => {
|
|
43
43
|
const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
|
|
44
44
|
const entity = await enforceAsyncResult(
|
|
45
|
-
PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync()
|
|
45
|
+
PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync(),
|
|
46
46
|
);
|
|
47
47
|
|
|
48
48
|
// update two different fields at the same time (from the same entity)
|
|
@@ -69,7 +69,7 @@ describe('postgres entity integration', () => {
|
|
|
69
69
|
it('throws knex error upon empty update', async () => {
|
|
70
70
|
const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
|
|
71
71
|
const entity = await enforceAsyncResult(
|
|
72
|
-
PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync()
|
|
72
|
+
PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync(),
|
|
73
73
|
);
|
|
74
74
|
await expect(PostgresTestEntity.updater(entity).updateAsync()).rejects.toThrow();
|
|
75
75
|
});
|
|
@@ -77,7 +77,7 @@ describe('postgres entity integration', () => {
|
|
|
77
77
|
it('throws error upon empty update for stub database adapter to match behavior', async () => {
|
|
78
78
|
const vc = new ViewerContext(createUnitTestEntityCompanionProvider());
|
|
79
79
|
const entity = await enforceAsyncResult(
|
|
80
|
-
PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync()
|
|
80
|
+
PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync(),
|
|
81
81
|
);
|
|
82
82
|
await expect(PostgresTestEntity.updater(entity).updateAsync()).rejects.toThrow();
|
|
83
83
|
});
|
|
@@ -88,66 +88,89 @@ describe('postgres entity integration', () => {
|
|
|
88
88
|
|
|
89
89
|
// put one in the DB
|
|
90
90
|
const firstEntity = await enforceAsyncResult(
|
|
91
|
-
PostgresTestEntity.creator(vc1).setField('name', 'hello').createAsync()
|
|
91
|
+
PostgresTestEntity.creator(vc1).setField('name', 'hello').createAsync(),
|
|
92
92
|
);
|
|
93
93
|
|
|
94
|
-
await
|
|
94
|
+
await PostgresTestEntity.loader(vc1).enforcing().loadByIDAsync(firstEntity.getID());
|
|
95
95
|
|
|
96
96
|
const errorToThrow = new Error('Intentional error');
|
|
97
97
|
|
|
98
98
|
await expect(
|
|
99
|
-
vc1.runInTransactionForDatabaseAdaptorFlavorAsync(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
vc1.runInTransactionForDatabaseAdaptorFlavorAsync(
|
|
100
|
+
'postgres',
|
|
101
|
+
async (queryContext) => {
|
|
102
|
+
// put another in the DB that will be rolled back due to error thrown
|
|
103
|
+
await enforceAsyncResult(
|
|
104
|
+
PostgresTestEntity.creator(vc1, queryContext).setField('name', 'hello').createAsync(),
|
|
105
|
+
);
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
throw errorToThrow;
|
|
108
|
+
},
|
|
109
|
+
{}, // test empty transaction config
|
|
110
|
+
),
|
|
107
111
|
).rejects.toEqual(errorToThrow);
|
|
108
112
|
|
|
109
|
-
const entities = await
|
|
110
|
-
|
|
111
|
-
|
|
113
|
+
const entities = await PostgresTestEntity.loader(vc1)
|
|
114
|
+
.enforcing()
|
|
115
|
+
.loadManyByFieldEqualingAsync('name', 'hello');
|
|
112
116
|
expect(entities).toHaveLength(1);
|
|
113
117
|
});
|
|
114
118
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
describe('isolation levels', () => {
|
|
120
|
+
test.each(Object.values(TransactionIsolationLevel))(
|
|
121
|
+
'isolation level: %p',
|
|
122
|
+
async (isolationLevel: TransactionIsolationLevel) => {
|
|
123
|
+
const vc1 = new ViewerContext(
|
|
124
|
+
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
|
|
125
|
+
);
|
|
121
126
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
await vc1.runInTransactionForDatabaseAdaptorFlavorAsync(
|
|
125
|
-
'postgres',
|
|
126
|
-
async (queryContext) => {
|
|
127
|
-
const entity = await PostgresTestEntity.loader(vc1, queryContext)
|
|
128
|
-
.enforcing()
|
|
129
|
-
.loadByIDAsync(firstEntity.getID());
|
|
130
|
-
await PostgresTestEntity.updater(entity, queryContext)
|
|
131
|
-
.setField('name', newName)
|
|
132
|
-
.enforceUpdateAsync();
|
|
133
|
-
},
|
|
134
|
-
{ isolationLevel: TransactionIsolationLevel.SERIALIZABLE }
|
|
127
|
+
const firstEntity = await enforceAsyncResult(
|
|
128
|
+
PostgresTestEntity.creator(vc1).setField('name', 'hello').createAsync(),
|
|
135
129
|
);
|
|
136
|
-
return {};
|
|
137
|
-
} catch (e) {
|
|
138
|
-
return { error: e as Error };
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
// do some parallel updates to trigger serializable error in at least some of them
|
|
143
|
-
const results = await Promise.all([
|
|
144
|
-
loadAndUpdateAsync('hello2'),
|
|
145
|
-
loadAndUpdateAsync('hello3'),
|
|
146
|
-
loadAndUpdateAsync('hello4'),
|
|
147
|
-
loadAndUpdateAsync('hello5'),
|
|
148
|
-
]);
|
|
149
130
|
|
|
150
|
-
|
|
131
|
+
const loadAndUpdateAsync = async (
|
|
132
|
+
newName: string,
|
|
133
|
+
delay: number,
|
|
134
|
+
): Promise<{ error?: Error }> => {
|
|
135
|
+
try {
|
|
136
|
+
await vc1.runInTransactionForDatabaseAdaptorFlavorAsync(
|
|
137
|
+
'postgres',
|
|
138
|
+
async (queryContext) => {
|
|
139
|
+
const entity = await PostgresTestEntity.loader(vc1, queryContext)
|
|
140
|
+
.enforcing()
|
|
141
|
+
.loadByIDAsync(firstEntity.getID());
|
|
142
|
+
await setTimeout(delay);
|
|
143
|
+
await PostgresTestEntity.updater(entity, queryContext)
|
|
144
|
+
.setField('name', entity.getField('name') + ',' + newName)
|
|
145
|
+
.enforceUpdateAsync();
|
|
146
|
+
},
|
|
147
|
+
{ isolationLevel },
|
|
148
|
+
);
|
|
149
|
+
return {};
|
|
150
|
+
} catch (e) {
|
|
151
|
+
return { error: e as Error };
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// do some parallel updates to trigger serializable error in at least some of them
|
|
156
|
+
const results = await Promise.all([
|
|
157
|
+
loadAndUpdateAsync('hello2', 0),
|
|
158
|
+
loadAndUpdateAsync('hello3', 100),
|
|
159
|
+
loadAndUpdateAsync('hello4', 200),
|
|
160
|
+
loadAndUpdateAsync('hello5', 300),
|
|
161
|
+
]);
|
|
162
|
+
|
|
163
|
+
if (isolationLevel === TransactionIsolationLevel.READ_COMMITTED) {
|
|
164
|
+
// read committed seems executes the transactions and doesn't produce a consistent result, but doesn't throw
|
|
165
|
+
expect(results.filter((r) => !!r.error).length > 0).toBe(false);
|
|
166
|
+
} else {
|
|
167
|
+
// all other isolation levels throw since they're doing nonrepeatable reads
|
|
168
|
+
expect(results.filter((r) => (r.error as any)?.cause?.code === '40001').length > 0).toBe(
|
|
169
|
+
true,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
);
|
|
151
174
|
});
|
|
152
175
|
|
|
153
176
|
describe('JSON fields', () => {
|
|
@@ -158,7 +181,7 @@ describe('postgres entity integration', () => {
|
|
|
158
181
|
PostgresTestEntity.creator(vc1)
|
|
159
182
|
.setField('stringArray', ['hello', 'world'])
|
|
160
183
|
.setField('jsonArrayField', ['hello', 'world'])
|
|
161
|
-
.createAsync()
|
|
184
|
+
.createAsync(),
|
|
162
185
|
);
|
|
163
186
|
|
|
164
187
|
expect(entity.getField('stringArray')).toEqual(['hello', 'world']);
|
|
@@ -171,7 +194,7 @@ describe('postgres entity integration', () => {
|
|
|
171
194
|
const entity = await enforceAsyncResult(
|
|
172
195
|
PostgresTestEntity.creator(vc1)
|
|
173
196
|
.setField('jsonObjectField', { hello: 'world' })
|
|
174
|
-
.createAsync()
|
|
197
|
+
.createAsync(),
|
|
175
198
|
);
|
|
176
199
|
|
|
177
200
|
expect(entity.getField('jsonObjectField')).toEqual({ hello: 'world' });
|
|
@@ -183,12 +206,12 @@ describe('postgres entity integration', () => {
|
|
|
183
206
|
const entity1 = await enforceAsyncResult(
|
|
184
207
|
PostgresTestEntity.creator(vc1)
|
|
185
208
|
.setField('maybeJsonArrayField', ['hello', 'world'])
|
|
186
|
-
.createAsync()
|
|
209
|
+
.createAsync(),
|
|
187
210
|
);
|
|
188
211
|
const entity2 = await enforceAsyncResult(
|
|
189
212
|
PostgresTestEntity.creator(vc1)
|
|
190
213
|
.setField('maybeJsonArrayField', { hello: 'world' })
|
|
191
|
-
.createAsync()
|
|
214
|
+
.createAsync(),
|
|
192
215
|
);
|
|
193
216
|
|
|
194
217
|
expect(entity1.getField('maybeJsonArrayField')).toEqual(['hello', 'world']);
|
|
@@ -201,17 +224,17 @@ describe('postgres entity integration', () => {
|
|
|
201
224
|
const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
|
|
202
225
|
|
|
203
226
|
let entity = await enforceAsyncResult(
|
|
204
|
-
PostgresTestEntity.creator(vc1).setField('bigintField', '72057594037928038').createAsync()
|
|
227
|
+
PostgresTestEntity.creator(vc1).setField('bigintField', '72057594037928038').createAsync(),
|
|
205
228
|
);
|
|
206
229
|
expect(entity.getField('bigintField')).toEqual('72057594037928038');
|
|
207
230
|
|
|
208
231
|
entity = await enforceAsyncResult(
|
|
209
|
-
PostgresTestEntity.updater(entity).setField('bigintField', '10').updateAsync()
|
|
232
|
+
PostgresTestEntity.updater(entity).setField('bigintField', '10').updateAsync(),
|
|
210
233
|
);
|
|
211
234
|
expect(entity.getField('bigintField')).toEqual('10');
|
|
212
235
|
|
|
213
236
|
entity = await enforceAsyncResult(
|
|
214
|
-
PostgresTestEntity.updater(entity).setField('bigintField', '-10').updateAsync()
|
|
237
|
+
PostgresTestEntity.updater(entity).setField('bigintField', '-10').updateAsync(),
|
|
215
238
|
);
|
|
216
239
|
expect(entity.getField('bigintField')).toEqual('-10');
|
|
217
240
|
});
|
|
@@ -226,7 +249,7 @@ describe('postgres entity integration', () => {
|
|
|
226
249
|
.setField('name', 'hello')
|
|
227
250
|
.setField('hasACat', false)
|
|
228
251
|
.setField('hasADog', true)
|
|
229
|
-
.createAsync()
|
|
252
|
+
.createAsync(),
|
|
230
253
|
);
|
|
231
254
|
|
|
232
255
|
await enforceAsyncResult(
|
|
@@ -234,7 +257,7 @@ describe('postgres entity integration', () => {
|
|
|
234
257
|
.setField('name', 'world')
|
|
235
258
|
.setField('hasACat', false)
|
|
236
259
|
.setField('hasADog', true)
|
|
237
|
-
.createAsync()
|
|
260
|
+
.createAsync(),
|
|
238
261
|
);
|
|
239
262
|
|
|
240
263
|
await enforceAsyncResult(
|
|
@@ -242,7 +265,7 @@ describe('postgres entity integration', () => {
|
|
|
242
265
|
.setField('name', 'wat')
|
|
243
266
|
.setField('hasACat', false)
|
|
244
267
|
.setField('hasADog', false)
|
|
245
|
-
.createAsync()
|
|
268
|
+
.createAsync(),
|
|
246
269
|
);
|
|
247
270
|
|
|
248
271
|
const results = await PostgresTestEntity.loader(vc1)
|
|
@@ -299,25 +322,25 @@ describe('postgres entity integration', () => {
|
|
|
299
322
|
PostgresTestEntity.creator(vc1)
|
|
300
323
|
.setField('name', 'a')
|
|
301
324
|
.setField('hasADog', true)
|
|
302
|
-
.createAsync()
|
|
325
|
+
.createAsync(),
|
|
303
326
|
);
|
|
304
327
|
await enforceAsyncResult(
|
|
305
328
|
PostgresTestEntity.creator(vc1)
|
|
306
329
|
.setField('name', 'b')
|
|
307
330
|
.setField('hasADog', true)
|
|
308
|
-
.createAsync()
|
|
331
|
+
.createAsync(),
|
|
309
332
|
);
|
|
310
333
|
await enforceAsyncResult(
|
|
311
334
|
PostgresTestEntity.creator(vc1)
|
|
312
335
|
.setField('name', null)
|
|
313
336
|
.setField('hasADog', true)
|
|
314
|
-
.createAsync()
|
|
337
|
+
.createAsync(),
|
|
315
338
|
);
|
|
316
339
|
await enforceAsyncResult(
|
|
317
340
|
PostgresTestEntity.creator(vc1)
|
|
318
341
|
.setField('name', null)
|
|
319
342
|
.setField('hasADog', false)
|
|
320
|
-
.createAsync()
|
|
343
|
+
.createAsync(),
|
|
321
344
|
);
|
|
322
345
|
|
|
323
346
|
const results = await PostgresTestEntity.loader(vc1)
|
|
@@ -340,7 +363,7 @@ describe('postgres entity integration', () => {
|
|
|
340
363
|
order: OrderByOrdering.DESCENDING,
|
|
341
364
|
},
|
|
342
365
|
],
|
|
343
|
-
}
|
|
366
|
+
},
|
|
344
367
|
);
|
|
345
368
|
expect(results2).toHaveLength(2);
|
|
346
369
|
expect(results2.map((e) => e.getField('name'))).toEqual([null, 'a']);
|
|
@@ -355,7 +378,7 @@ describe('postgres entity integration', () => {
|
|
|
355
378
|
.setField('name', 'hello')
|
|
356
379
|
.setField('hasACat', false)
|
|
357
380
|
.setField('hasADog', true)
|
|
358
|
-
.createAsync()
|
|
381
|
+
.createAsync(),
|
|
359
382
|
);
|
|
360
383
|
|
|
361
384
|
const results = await PostgresTestEntity.loader(vc1)
|
|
@@ -372,13 +395,13 @@ describe('postgres entity integration', () => {
|
|
|
372
395
|
.setField('name', 'hello')
|
|
373
396
|
.setField('hasACat', false)
|
|
374
397
|
.setField('hasADog', true)
|
|
375
|
-
.createAsync()
|
|
398
|
+
.createAsync(),
|
|
376
399
|
);
|
|
377
400
|
|
|
378
401
|
await expect(
|
|
379
402
|
PostgresTestEntity.loader(vc1)
|
|
380
403
|
.enforcing()
|
|
381
|
-
.loadManyByRawWhereClauseAsync('invalid_column = ?', ['hello'])
|
|
404
|
+
.loadManyByRawWhereClauseAsync('invalid_column = ?', ['hello']),
|
|
382
405
|
).rejects.toThrow();
|
|
383
406
|
});
|
|
384
407
|
|
|
@@ -389,21 +412,21 @@ describe('postgres entity integration', () => {
|
|
|
389
412
|
PostgresTestEntity.creator(vc1)
|
|
390
413
|
.setField('name', 'a')
|
|
391
414
|
.setField('hasADog', true)
|
|
392
|
-
.createAsync()
|
|
415
|
+
.createAsync(),
|
|
393
416
|
);
|
|
394
417
|
|
|
395
418
|
await enforceAsyncResult(
|
|
396
419
|
PostgresTestEntity.creator(vc1)
|
|
397
420
|
.setField('name', 'b')
|
|
398
421
|
.setField('hasADog', true)
|
|
399
|
-
.createAsync()
|
|
422
|
+
.createAsync(),
|
|
400
423
|
);
|
|
401
424
|
|
|
402
425
|
await enforceAsyncResult(
|
|
403
426
|
PostgresTestEntity.creator(vc1)
|
|
404
427
|
.setField('name', 'c')
|
|
405
428
|
.setField('hasADog', true)
|
|
406
|
-
.createAsync()
|
|
429
|
+
.createAsync(),
|
|
407
430
|
);
|
|
408
431
|
|
|
409
432
|
const results = await PostgresTestEntity.loader(vc1)
|
|
@@ -455,58 +478,58 @@ describe('postgres entity integration', () => {
|
|
|
455
478
|
describe('create', () => {
|
|
456
479
|
it('rolls back transaction when trigger throws except afterCommit', async () => {
|
|
457
480
|
const vc1 = new ViewerContext(
|
|
458
|
-
createKnexIntegrationTestEntityCompanionProvider(knexInstance)
|
|
481
|
+
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
|
|
459
482
|
);
|
|
460
483
|
|
|
461
484
|
await expect(
|
|
462
485
|
PostgresTriggerTestEntity.creator(vc1)
|
|
463
486
|
.setField('name', 'beforeCreate')
|
|
464
|
-
.enforceCreateAsync()
|
|
487
|
+
.enforceCreateAsync(),
|
|
465
488
|
).rejects.toThrowError('name cannot have value beforeCreate');
|
|
466
489
|
await expect(
|
|
467
490
|
PostgresTriggerTestEntity.loader(vc1)
|
|
468
491
|
.enforcing()
|
|
469
|
-
.loadByFieldEqualingAsync('name', 'beforeCreate')
|
|
492
|
+
.loadByFieldEqualingAsync('name', 'beforeCreate'),
|
|
470
493
|
).resolves.toBeNull();
|
|
471
494
|
|
|
472
495
|
await expect(
|
|
473
496
|
PostgresTriggerTestEntity.creator(vc1)
|
|
474
497
|
.setField('name', 'afterCreate')
|
|
475
|
-
.enforceCreateAsync()
|
|
498
|
+
.enforceCreateAsync(),
|
|
476
499
|
).rejects.toThrowError('name cannot have value afterCreate');
|
|
477
500
|
await expect(
|
|
478
501
|
PostgresTriggerTestEntity.loader(vc1)
|
|
479
502
|
.enforcing()
|
|
480
|
-
.loadByFieldEqualingAsync('name', 'afterCreate')
|
|
503
|
+
.loadByFieldEqualingAsync('name', 'afterCreate'),
|
|
481
504
|
).resolves.toBeNull();
|
|
482
505
|
|
|
483
506
|
await expect(
|
|
484
|
-
PostgresTriggerTestEntity.creator(vc1).setField('name', 'beforeAll').enforceCreateAsync()
|
|
507
|
+
PostgresTriggerTestEntity.creator(vc1).setField('name', 'beforeAll').enforceCreateAsync(),
|
|
485
508
|
).rejects.toThrowError('name cannot have value beforeAll');
|
|
486
509
|
await expect(
|
|
487
510
|
PostgresTriggerTestEntity.loader(vc1)
|
|
488
511
|
.enforcing()
|
|
489
|
-
.loadByFieldEqualingAsync('name', 'beforeAll')
|
|
512
|
+
.loadByFieldEqualingAsync('name', 'beforeAll'),
|
|
490
513
|
).resolves.toBeNull();
|
|
491
514
|
|
|
492
515
|
await expect(
|
|
493
|
-
PostgresTriggerTestEntity.creator(vc1).setField('name', 'afterAll').enforceCreateAsync()
|
|
516
|
+
PostgresTriggerTestEntity.creator(vc1).setField('name', 'afterAll').enforceCreateAsync(),
|
|
494
517
|
).rejects.toThrowError('name cannot have value afterAll');
|
|
495
518
|
await expect(
|
|
496
519
|
PostgresTriggerTestEntity.loader(vc1)
|
|
497
520
|
.enforcing()
|
|
498
|
-
.loadByFieldEqualingAsync('name', 'afterAll')
|
|
521
|
+
.loadByFieldEqualingAsync('name', 'afterAll'),
|
|
499
522
|
).resolves.toBeNull();
|
|
500
523
|
|
|
501
524
|
await expect(
|
|
502
525
|
PostgresTriggerTestEntity.creator(vc1)
|
|
503
526
|
.setField('name', 'afterCommit')
|
|
504
|
-
.enforceCreateAsync()
|
|
527
|
+
.enforceCreateAsync(),
|
|
505
528
|
).rejects.toThrowError('name cannot have value afterCommit');
|
|
506
529
|
await expect(
|
|
507
530
|
PostgresTriggerTestEntity.loader(vc1)
|
|
508
531
|
.enforcing()
|
|
509
|
-
.loadByFieldEqualingAsync('name', 'afterCommit')
|
|
532
|
+
.loadByFieldEqualingAsync('name', 'afterCommit'),
|
|
510
533
|
).resolves.not.toBeNull();
|
|
511
534
|
});
|
|
512
535
|
});
|
|
@@ -514,7 +537,7 @@ describe('postgres entity integration', () => {
|
|
|
514
537
|
describe('update', () => {
|
|
515
538
|
it('rolls back transaction when trigger throws except afterCommit', async () => {
|
|
516
539
|
const vc1 = new ViewerContext(
|
|
517
|
-
createKnexIntegrationTestEntityCompanionProvider(knexInstance)
|
|
540
|
+
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
|
|
518
541
|
);
|
|
519
542
|
|
|
520
543
|
const entity = await PostgresTriggerTestEntity.creator(vc1)
|
|
@@ -524,56 +547,56 @@ describe('postgres entity integration', () => {
|
|
|
524
547
|
await expect(
|
|
525
548
|
PostgresTriggerTestEntity.updater(entity)
|
|
526
549
|
.setField('name', 'beforeUpdate')
|
|
527
|
-
.enforceUpdateAsync()
|
|
550
|
+
.enforceUpdateAsync(),
|
|
528
551
|
).rejects.toThrowError('name cannot have value beforeUpdate');
|
|
529
552
|
await expect(
|
|
530
553
|
PostgresTriggerTestEntity.loader(vc1)
|
|
531
554
|
.enforcing()
|
|
532
|
-
.loadByFieldEqualingAsync('name', 'beforeUpdate')
|
|
555
|
+
.loadByFieldEqualingAsync('name', 'beforeUpdate'),
|
|
533
556
|
).resolves.toBeNull();
|
|
534
557
|
|
|
535
558
|
await expect(
|
|
536
559
|
PostgresTriggerTestEntity.updater(entity)
|
|
537
560
|
.setField('name', 'afterUpdate')
|
|
538
|
-
.enforceUpdateAsync()
|
|
561
|
+
.enforceUpdateAsync(),
|
|
539
562
|
).rejects.toThrowError('name cannot have value afterUpdate');
|
|
540
563
|
await expect(
|
|
541
564
|
PostgresTriggerTestEntity.loader(vc1)
|
|
542
565
|
.enforcing()
|
|
543
|
-
.loadByFieldEqualingAsync('name', 'afterUpdate')
|
|
566
|
+
.loadByFieldEqualingAsync('name', 'afterUpdate'),
|
|
544
567
|
).resolves.toBeNull();
|
|
545
568
|
|
|
546
569
|
await expect(
|
|
547
570
|
PostgresTriggerTestEntity.updater(entity)
|
|
548
571
|
.setField('name', 'beforeAll')
|
|
549
|
-
.enforceUpdateAsync()
|
|
572
|
+
.enforceUpdateAsync(),
|
|
550
573
|
).rejects.toThrowError('name cannot have value beforeAll');
|
|
551
574
|
await expect(
|
|
552
575
|
PostgresTriggerTestEntity.loader(vc1)
|
|
553
576
|
.enforcing()
|
|
554
|
-
.loadByFieldEqualingAsync('name', 'beforeAll')
|
|
577
|
+
.loadByFieldEqualingAsync('name', 'beforeAll'),
|
|
555
578
|
).resolves.toBeNull();
|
|
556
579
|
|
|
557
580
|
await expect(
|
|
558
581
|
PostgresTriggerTestEntity.updater(entity)
|
|
559
582
|
.setField('name', 'afterAll')
|
|
560
|
-
.enforceUpdateAsync()
|
|
583
|
+
.enforceUpdateAsync(),
|
|
561
584
|
).rejects.toThrowError('name cannot have value afterAll');
|
|
562
585
|
await expect(
|
|
563
586
|
PostgresTriggerTestEntity.loader(vc1)
|
|
564
587
|
.enforcing()
|
|
565
|
-
.loadByFieldEqualingAsync('name', 'afterAll')
|
|
588
|
+
.loadByFieldEqualingAsync('name', 'afterAll'),
|
|
566
589
|
).resolves.toBeNull();
|
|
567
590
|
|
|
568
591
|
await expect(
|
|
569
592
|
PostgresTriggerTestEntity.updater(entity)
|
|
570
593
|
.setField('name', 'afterCommit')
|
|
571
|
-
.enforceUpdateAsync()
|
|
594
|
+
.enforceUpdateAsync(),
|
|
572
595
|
).rejects.toThrowError('name cannot have value afterCommit');
|
|
573
596
|
await expect(
|
|
574
597
|
PostgresTriggerTestEntity.loader(vc1)
|
|
575
598
|
.enforcing()
|
|
576
|
-
.loadByFieldEqualingAsync('name', 'afterCommit')
|
|
599
|
+
.loadByFieldEqualingAsync('name', 'afterCommit'),
|
|
577
600
|
).resolves.not.toBeNull();
|
|
578
601
|
});
|
|
579
602
|
});
|
|
@@ -581,31 +604,31 @@ describe('postgres entity integration', () => {
|
|
|
581
604
|
describe('delete', () => {
|
|
582
605
|
it('rolls back transaction when trigger throws except afterCommit', async () => {
|
|
583
606
|
const vc1 = new ViewerContext(
|
|
584
|
-
createKnexIntegrationTestEntityCompanionProvider(knexInstance)
|
|
607
|
+
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
|
|
585
608
|
);
|
|
586
609
|
|
|
587
610
|
const entityBeforeDelete = await PostgresTriggerTestEntity.creator(vc1)
|
|
588
611
|
.setField('name', 'beforeDelete')
|
|
589
612
|
.enforceCreateAsync();
|
|
590
613
|
await expect(
|
|
591
|
-
PostgresTriggerTestEntity.enforceDeleteAsync(entityBeforeDelete)
|
|
614
|
+
PostgresTriggerTestEntity.enforceDeleteAsync(entityBeforeDelete),
|
|
592
615
|
).rejects.toThrowError('name cannot have value beforeDelete');
|
|
593
616
|
await expect(
|
|
594
617
|
PostgresTriggerTestEntity.loader(vc1)
|
|
595
618
|
.enforcing()
|
|
596
|
-
.loadByFieldEqualingAsync('name', 'beforeDelete')
|
|
619
|
+
.loadByFieldEqualingAsync('name', 'beforeDelete'),
|
|
597
620
|
).resolves.not.toBeNull();
|
|
598
621
|
|
|
599
622
|
const entityAfterDelete = await PostgresTriggerTestEntity.creator(vc1)
|
|
600
623
|
.setField('name', 'afterDelete')
|
|
601
624
|
.enforceCreateAsync();
|
|
602
625
|
await expect(
|
|
603
|
-
PostgresTriggerTestEntity.enforceDeleteAsync(entityAfterDelete)
|
|
626
|
+
PostgresTriggerTestEntity.enforceDeleteAsync(entityAfterDelete),
|
|
604
627
|
).rejects.toThrowError('name cannot have value afterDelete');
|
|
605
628
|
await expect(
|
|
606
629
|
PostgresTriggerTestEntity.loader(vc1)
|
|
607
630
|
.enforcing()
|
|
608
|
-
.loadByFieldEqualingAsync('name', 'afterDelete')
|
|
631
|
+
.loadByFieldEqualingAsync('name', 'afterDelete'),
|
|
609
632
|
).resolves.not.toBeNull();
|
|
610
633
|
});
|
|
611
634
|
});
|
|
@@ -613,25 +636,25 @@ describe('postgres entity integration', () => {
|
|
|
613
636
|
describe('create', () => {
|
|
614
637
|
it('rolls back transaction when trigger throws ', async () => {
|
|
615
638
|
const vc1 = new ViewerContext(
|
|
616
|
-
createKnexIntegrationTestEntityCompanionProvider(knexInstance)
|
|
639
|
+
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
|
|
617
640
|
);
|
|
618
641
|
|
|
619
642
|
await expect(
|
|
620
643
|
PostgresValidatorTestEntity.creator(vc1)
|
|
621
644
|
.setField('name', 'beforeCreateAndBeforeUpdate')
|
|
622
|
-
.enforceCreateAsync()
|
|
645
|
+
.enforceCreateAsync(),
|
|
623
646
|
).rejects.toThrowError('name cannot have value beforeCreateAndBeforeUpdate');
|
|
624
647
|
await expect(
|
|
625
648
|
PostgresValidatorTestEntity.loader(vc1)
|
|
626
649
|
.enforcing()
|
|
627
|
-
.loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate')
|
|
650
|
+
.loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate'),
|
|
628
651
|
).resolves.toBeNull();
|
|
629
652
|
});
|
|
630
653
|
});
|
|
631
654
|
describe('update', () => {
|
|
632
655
|
it('rolls back transaction when trigger throws ', async () => {
|
|
633
656
|
const vc1 = new ViewerContext(
|
|
634
|
-
createKnexIntegrationTestEntityCompanionProvider(knexInstance)
|
|
657
|
+
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
|
|
635
658
|
);
|
|
636
659
|
|
|
637
660
|
const entity = await PostgresValidatorTestEntity.creator(vc1)
|
|
@@ -641,19 +664,19 @@ describe('postgres entity integration', () => {
|
|
|
641
664
|
await expect(
|
|
642
665
|
PostgresValidatorTestEntity.updater(entity)
|
|
643
666
|
.setField('name', 'beforeCreateAndBeforeUpdate')
|
|
644
|
-
.enforceUpdateAsync()
|
|
667
|
+
.enforceUpdateAsync(),
|
|
645
668
|
).rejects.toThrowError('name cannot have value beforeCreateAndBeforeUpdate');
|
|
646
669
|
await expect(
|
|
647
670
|
PostgresValidatorTestEntity.loader(vc1)
|
|
648
671
|
.enforcing()
|
|
649
|
-
.loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate')
|
|
672
|
+
.loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate'),
|
|
650
673
|
).resolves.toBeNull();
|
|
651
674
|
});
|
|
652
675
|
});
|
|
653
676
|
describe('delete', () => {
|
|
654
677
|
it('validation should not run on a delete mutation', async () => {
|
|
655
678
|
const vc1 = new ViewerContext(
|
|
656
|
-
createKnexIntegrationTestEntityCompanionProvider(knexInstance)
|
|
679
|
+
createKnexIntegrationTestEntityCompanionProvider(knexInstance),
|
|
657
680
|
);
|
|
658
681
|
|
|
659
682
|
const entityToDelete = await PostgresValidatorTestEntity.creator(vc1)
|
|
@@ -663,7 +686,7 @@ describe('postgres entity integration', () => {
|
|
|
663
686
|
await expect(
|
|
664
687
|
PostgresValidatorTestEntity.loader(vc1)
|
|
665
688
|
.enforcing()
|
|
666
|
-
.loadByFieldEqualingAsync('name', 'shouldBeDeleted')
|
|
689
|
+
.loadByFieldEqualingAsync('name', 'shouldBeDeleted'),
|
|
667
690
|
).resolves.toBeNull();
|
|
668
691
|
});
|
|
669
692
|
});
|
|
@@ -718,7 +741,7 @@ describe('postgres entity integration', () => {
|
|
|
718
741
|
preCommitCallCount++;
|
|
719
742
|
throw Error('wat');
|
|
720
743
|
}, 0);
|
|
721
|
-
})
|
|
744
|
+
}),
|
|
722
745
|
).rejects.toThrowError('wat');
|
|
723
746
|
|
|
724
747
|
expect(preCommitCallCount).toBe(2);
|
|
@@ -35,40 +35,40 @@ describe('postgres entity integration', () => {
|
|
|
35
35
|
it('throws after deletion of multiple rows or no rows', async () => {
|
|
36
36
|
const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
|
|
37
37
|
const entity1 = await enforceAsyncResult(
|
|
38
|
-
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync()
|
|
38
|
+
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync(),
|
|
39
39
|
);
|
|
40
40
|
await enforceAsyncResult(
|
|
41
|
-
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'world').createAsync()
|
|
41
|
+
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'world').createAsync(),
|
|
42
42
|
);
|
|
43
43
|
|
|
44
44
|
await expect(InvalidTestEntity.deleteAsync(entity1)).rejects.toThrowError(
|
|
45
|
-
'Excessive deletions from database adapter delete'
|
|
45
|
+
'Excessive deletions from database adapter delete',
|
|
46
46
|
);
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
it('throws after update of multiple rows', async () => {
|
|
50
50
|
const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
|
|
51
51
|
const entity1 = await enforceAsyncResult(
|
|
52
|
-
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync()
|
|
52
|
+
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync(),
|
|
53
53
|
);
|
|
54
54
|
await enforceAsyncResult(
|
|
55
|
-
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'world').createAsync()
|
|
55
|
+
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'world').createAsync(),
|
|
56
56
|
);
|
|
57
57
|
|
|
58
58
|
await expect(
|
|
59
|
-
InvalidTestEntity.updater(entity1).setField('name', 'blah').enforceUpdateAsync()
|
|
59
|
+
InvalidTestEntity.updater(entity1).setField('name', 'blah').enforceUpdateAsync(),
|
|
60
60
|
).rejects.toThrowError('Excessive results from database adapter update');
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
it('throws after update of no rows', async () => {
|
|
64
64
|
const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
|
|
65
65
|
const entity1 = await enforceAsyncResult(
|
|
66
|
-
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync()
|
|
66
|
+
InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync(),
|
|
67
67
|
);
|
|
68
68
|
await InvalidTestEntity.deleteAsync(entity1);
|
|
69
69
|
|
|
70
70
|
await expect(
|
|
71
|
-
InvalidTestEntity.updater(entity1).setField('name', 'blah').enforceUpdateAsync()
|
|
71
|
+
InvalidTestEntity.updater(entity1).setField('name', 'blah').enforceUpdateAsync(),
|
|
72
72
|
).rejects.toThrowError('Empty results from database adapter update');
|
|
73
73
|
});
|
|
74
74
|
});
|