tantan-typeorm-gs 1.0.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/LICENSE +21 -0
- package/README.md +31 -0
- package/bun.lock +300 -0
- package/docs/authentication.md +118 -0
- package/docs/configuration.md +680 -0
- package/docs/contributing.md +177 -0
- package/docs/crud.md +351 -0
- package/docs/custom-client.md +165 -0
- package/docs/development.md +243 -0
- package/docs/entities.md +502 -0
- package/docs/find-options.md +296 -0
- package/docs/google-cloud.md +101 -0
- package/docs/installation.md +51 -0
- package/docs/integration-testing.md +178 -0
- package/docs/limitations.md +223 -0
- package/docs/pagination.md +384 -0
- package/docs/performance.md +171 -0
- package/docs/security.md +153 -0
- package/docs/sorting.md +0 -0
- package/docs/supported-features.md +310 -0
- package/docs/synchronization.md +203 -0
- package/package.json +43 -0
- package/src/client/index.ts +589 -0
- package/src/core/data-source.ts +47 -0
- package/src/core/driver.ts +290 -0
- package/src/core/error.ts +144 -0
- package/src/core/memory.ts +152 -0
- package/src/core/query/interpreter.ts +949 -0
- package/src/core/query/runner.ts +1297 -0
- package/src/core/query/types.ts +155 -0
- package/src/core/schema-builder.ts +64 -0
- package/src/core/types.ts +113 -0
- package/src/core/utils.ts +13 -0
- package/src/index.ts +3 -0
- package/tantan-typeorm-gs.code-workspace +8 -0
- package/test/base/0001-data-source.test.ts +252 -0
- package/test/base/0002-operator.test.ts +616 -0
- package/test/base/0003-select.test.ts +281 -0
- package/test/base/0004-aggregate.test.ts +213 -0
- package/test/base/0005-transcation.test.ts +1566 -0
- package/test/base/0006-relation.test.ts +1611 -0
- package/test/base/0007-logging.test.ts +182 -0
- package/test/base/0008-soft-delete.test.ts +649 -0
- package/test/google-sheets/0001-client.test.ts +1705 -0
- package/test/google-sheets/0002-worksheet-management.test.ts +408 -0
- package/test/google-sheets/0003-data-source.test.ts +1935 -0
- package/test/google-sheets/0004-transactions.test.ts +952 -0
- package/test/google-sheets/0005-operator.test.ts +1124 -0
- package/test/google-sheets/0006-object-criteria.test.ts +283 -0
- package/test/google-sheets/0007-performance.test.ts +532 -0
- package/test/public-api.test.ts +34 -0
- package/tsconfig.build.json +21 -0
- package/tsconfig.json +34 -0
|
@@ -0,0 +1,1935 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import
|
|
3
|
+
{
|
|
4
|
+
AfterInsert,
|
|
5
|
+
AfterLoad,
|
|
6
|
+
AfterRemove,
|
|
7
|
+
AfterUpdate,
|
|
8
|
+
BeforeInsert,
|
|
9
|
+
BeforeRemove,
|
|
10
|
+
BeforeUpdate,
|
|
11
|
+
Column,
|
|
12
|
+
DefaultNamingStrategy,
|
|
13
|
+
Entity,
|
|
14
|
+
EventSubscriber,
|
|
15
|
+
ManyToOne,
|
|
16
|
+
PrimaryColumn,
|
|
17
|
+
PrimaryGeneratedColumn,
|
|
18
|
+
type EntitySubscriberInterface,
|
|
19
|
+
type InsertEvent,
|
|
20
|
+
} from 'typeorm';
|
|
21
|
+
import type { GoogleSheetsDriver } from '../../src/core/driver';
|
|
22
|
+
import { Memory } from '../../src/core/memory';
|
|
23
|
+
import { GoogleSheetsConsume, createGoogleSheetsDataSource, type GoogleSheetsDataSourceOptions } from '../../src';
|
|
24
|
+
|
|
25
|
+
describe(
|
|
26
|
+
'GoogleSheetsDataSource',
|
|
27
|
+
() =>
|
|
28
|
+
{
|
|
29
|
+
class TestNamingStrategy
|
|
30
|
+
extends DefaultNamingStrategy
|
|
31
|
+
{
|
|
32
|
+
override tableName(
|
|
33
|
+
className: string,
|
|
34
|
+
customName: string | undefined,
|
|
35
|
+
): string
|
|
36
|
+
{
|
|
37
|
+
return `sheet_${customName ?? className}`.toLowerCase();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override columnName(
|
|
41
|
+
propertyName: string,
|
|
42
|
+
customName: string | undefined,
|
|
43
|
+
embeddedPrefixes: string[],
|
|
44
|
+
): string
|
|
45
|
+
{
|
|
46
|
+
return `col_${propertyName}`.toLowerCase();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@EventSubscriber()
|
|
51
|
+
class LifecycleUserSubscriber
|
|
52
|
+
implements EntitySubscriberInterface<LifecycleUser>
|
|
53
|
+
{
|
|
54
|
+
beforeInsert(event: InsertEvent<LifecycleUser>)
|
|
55
|
+
{
|
|
56
|
+
event.entity.name =
|
|
57
|
+
`${event.entity.name}-subscriber-before`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
afterInsert(event: InsertEvent<LifecycleUser>)
|
|
61
|
+
{
|
|
62
|
+
event.entity.name =
|
|
63
|
+
`${event.entity.name}-subscriber-after`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@Entity()
|
|
68
|
+
class NamingStrategyUser
|
|
69
|
+
{
|
|
70
|
+
@PrimaryGeneratedColumn()
|
|
71
|
+
id!: number;
|
|
72
|
+
|
|
73
|
+
@Column()
|
|
74
|
+
displayName!: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Entity('custom_users')
|
|
78
|
+
class CustomUser
|
|
79
|
+
{
|
|
80
|
+
@PrimaryGeneratedColumn()
|
|
81
|
+
id!: number;
|
|
82
|
+
|
|
83
|
+
@Column()
|
|
84
|
+
name!: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Entity('mapped_users')
|
|
88
|
+
class MappedUser
|
|
89
|
+
{
|
|
90
|
+
@PrimaryGeneratedColumn()
|
|
91
|
+
id!: number;
|
|
92
|
+
|
|
93
|
+
@Column({
|
|
94
|
+
name: 'user_name',
|
|
95
|
+
})
|
|
96
|
+
name!: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@Entity('typed_users')
|
|
100
|
+
class TypedUser
|
|
101
|
+
{
|
|
102
|
+
@PrimaryGeneratedColumn()
|
|
103
|
+
id!: number;
|
|
104
|
+
|
|
105
|
+
@Column({
|
|
106
|
+
type: 'number',
|
|
107
|
+
})
|
|
108
|
+
age!: number;
|
|
109
|
+
|
|
110
|
+
@Column({
|
|
111
|
+
type: 'boolean',
|
|
112
|
+
})
|
|
113
|
+
active!: boolean;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@Entity('nullable_users')
|
|
117
|
+
class NullableUser
|
|
118
|
+
{
|
|
119
|
+
@PrimaryGeneratedColumn()
|
|
120
|
+
id!: number;
|
|
121
|
+
|
|
122
|
+
@Column({
|
|
123
|
+
nullable: true,
|
|
124
|
+
})
|
|
125
|
+
nickname!: string | null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@Entity('generated_users')
|
|
129
|
+
class GeneratedUser
|
|
130
|
+
{
|
|
131
|
+
@PrimaryGeneratedColumn()
|
|
132
|
+
id!: number;
|
|
133
|
+
|
|
134
|
+
@Column()
|
|
135
|
+
name!: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@Entity('default_users')
|
|
139
|
+
class DefaultUser
|
|
140
|
+
{
|
|
141
|
+
@PrimaryGeneratedColumn()
|
|
142
|
+
id!: number;
|
|
143
|
+
|
|
144
|
+
@Column({
|
|
145
|
+
default: 'active',
|
|
146
|
+
})
|
|
147
|
+
status!: string;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@Entity('uuid_users')
|
|
151
|
+
class UuidUser
|
|
152
|
+
{
|
|
153
|
+
@PrimaryGeneratedColumn('uuid')
|
|
154
|
+
id!: string;
|
|
155
|
+
|
|
156
|
+
@Column()
|
|
157
|
+
name!: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@Entity('sync_users')
|
|
161
|
+
class SyncUser
|
|
162
|
+
{
|
|
163
|
+
@PrimaryGeneratedColumn()
|
|
164
|
+
id!: number;
|
|
165
|
+
|
|
166
|
+
@Column()
|
|
167
|
+
name!: string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@Entity('sync_missing_headers')
|
|
171
|
+
class SyncMissingHeaderUser
|
|
172
|
+
{
|
|
173
|
+
@PrimaryGeneratedColumn()
|
|
174
|
+
id!: number;
|
|
175
|
+
|
|
176
|
+
@Column()
|
|
177
|
+
name!: string;
|
|
178
|
+
|
|
179
|
+
@Column()
|
|
180
|
+
email!: string;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@Entity('required_users')
|
|
184
|
+
class RequiredUser
|
|
185
|
+
{
|
|
186
|
+
@PrimaryColumn()
|
|
187
|
+
id!: number;
|
|
188
|
+
|
|
189
|
+
@Column()
|
|
190
|
+
name!: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@Entity('lifecycle_users')
|
|
194
|
+
class LifecycleUser
|
|
195
|
+
{
|
|
196
|
+
@PrimaryGeneratedColumn()
|
|
197
|
+
id!: number;
|
|
198
|
+
|
|
199
|
+
@Column()
|
|
200
|
+
name!: string;
|
|
201
|
+
|
|
202
|
+
@BeforeInsert()
|
|
203
|
+
beforeInsert()
|
|
204
|
+
{
|
|
205
|
+
this.name =
|
|
206
|
+
this.name.toUpperCase();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@BeforeUpdate()
|
|
210
|
+
beforeUpdate()
|
|
211
|
+
{
|
|
212
|
+
this.name =
|
|
213
|
+
this.name.toUpperCase();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
@BeforeRemove()
|
|
217
|
+
beforeRemove()
|
|
218
|
+
{
|
|
219
|
+
this.name =
|
|
220
|
+
`${this.name}-before`;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@AfterLoad()
|
|
224
|
+
afterLoad()
|
|
225
|
+
{
|
|
226
|
+
this.name =
|
|
227
|
+
`${this.name}-loaded`;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
@Entity('lifecycle_users2')
|
|
232
|
+
class LifecycleUser2
|
|
233
|
+
{
|
|
234
|
+
@PrimaryGeneratedColumn()
|
|
235
|
+
id!: number;
|
|
236
|
+
|
|
237
|
+
@Column()
|
|
238
|
+
name!: string;
|
|
239
|
+
|
|
240
|
+
@AfterInsert()
|
|
241
|
+
afterInsert()
|
|
242
|
+
{
|
|
243
|
+
this.name =
|
|
244
|
+
`${this.name}-after`;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
@AfterUpdate()
|
|
248
|
+
afterUpdate()
|
|
249
|
+
{
|
|
250
|
+
this.name =
|
|
251
|
+
`${this.name}-after`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@AfterRemove()
|
|
255
|
+
afterRemove()
|
|
256
|
+
{
|
|
257
|
+
this.name =
|
|
258
|
+
`${this.name}-after`;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
@Entity('relation_users')
|
|
263
|
+
class RelationUser
|
|
264
|
+
{
|
|
265
|
+
@PrimaryGeneratedColumn()
|
|
266
|
+
id!: number;
|
|
267
|
+
|
|
268
|
+
@Column()
|
|
269
|
+
name!: string;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
@Entity('relation_posts')
|
|
273
|
+
class RelationPost
|
|
274
|
+
{
|
|
275
|
+
@PrimaryGeneratedColumn()
|
|
276
|
+
id!: number;
|
|
277
|
+
|
|
278
|
+
@Column()
|
|
279
|
+
title!: string;
|
|
280
|
+
|
|
281
|
+
@ManyToOne(
|
|
282
|
+
() => RelationUser,
|
|
283
|
+
{
|
|
284
|
+
nullable: false,
|
|
285
|
+
},
|
|
286
|
+
)
|
|
287
|
+
author!: RelationUser;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
test(
|
|
291
|
+
'should use default GoogleSheetsConsume when client is not provided',
|
|
292
|
+
() =>
|
|
293
|
+
{
|
|
294
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
295
|
+
type: 'google-sheets',
|
|
296
|
+
|
|
297
|
+
spreadsheetId:
|
|
298
|
+
'test-spreadsheet-id',
|
|
299
|
+
|
|
300
|
+
credentials: {
|
|
301
|
+
clientEmail:
|
|
302
|
+
'test@example.com',
|
|
303
|
+
|
|
304
|
+
privateKey:
|
|
305
|
+
'test-private-key',
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const driver =
|
|
310
|
+
dataSource.driver as GoogleSheetsDriver;
|
|
311
|
+
|
|
312
|
+
expect(driver.client)
|
|
313
|
+
.toBeInstanceOf(
|
|
314
|
+
GoogleSheetsConsume,
|
|
315
|
+
);
|
|
316
|
+
},
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
test(
|
|
320
|
+
'should use custom client when provided',
|
|
321
|
+
() =>
|
|
322
|
+
{
|
|
323
|
+
const client =
|
|
324
|
+
new Memory();
|
|
325
|
+
|
|
326
|
+
const dataSource =
|
|
327
|
+
createGoogleSheetsDataSource({
|
|
328
|
+
type: 'google-sheets',
|
|
329
|
+
|
|
330
|
+
spreadsheetId:
|
|
331
|
+
'test-spreadsheet-id',
|
|
332
|
+
|
|
333
|
+
credentials: {
|
|
334
|
+
clientEmail:
|
|
335
|
+
'test@example.com',
|
|
336
|
+
|
|
337
|
+
privateKey:
|
|
338
|
+
'test-private-key',
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
client,
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
const driver =
|
|
345
|
+
dataSource.driver as GoogleSheetsDriver;
|
|
346
|
+
|
|
347
|
+
expect(driver.client)
|
|
348
|
+
.toBe(client);
|
|
349
|
+
},
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
test(
|
|
353
|
+
'should resolve custom entity table name',
|
|
354
|
+
async () =>
|
|
355
|
+
{
|
|
356
|
+
const dataSource =
|
|
357
|
+
createGoogleSheetsDataSource({
|
|
358
|
+
type: 'google-sheets',
|
|
359
|
+
|
|
360
|
+
client:
|
|
361
|
+
new Memory(),
|
|
362
|
+
|
|
363
|
+
entities: [
|
|
364
|
+
CustomUser,
|
|
365
|
+
],
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
await dataSource.initialize();
|
|
369
|
+
|
|
370
|
+
try
|
|
371
|
+
{
|
|
372
|
+
const metadata =
|
|
373
|
+
dataSource.entityMetadatas.find(
|
|
374
|
+
(item) =>
|
|
375
|
+
item.target === CustomUser,
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
expect(metadata)
|
|
379
|
+
.toBeDefined();
|
|
380
|
+
|
|
381
|
+
expect(metadata?.tableName)
|
|
382
|
+
.toBe('custom_users');
|
|
383
|
+
}
|
|
384
|
+
finally
|
|
385
|
+
{
|
|
386
|
+
await dataSource.destroy();
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
test(
|
|
392
|
+
'should use resolved entity table name as worksheet',
|
|
393
|
+
async () =>
|
|
394
|
+
{
|
|
395
|
+
const client =
|
|
396
|
+
new Memory({
|
|
397
|
+
custom_users: [
|
|
398
|
+
{
|
|
399
|
+
id: 1,
|
|
400
|
+
name: 'Basuni',
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
const dataSource =
|
|
406
|
+
createGoogleSheetsDataSource({
|
|
407
|
+
type: 'google-sheets',
|
|
408
|
+
|
|
409
|
+
client,
|
|
410
|
+
|
|
411
|
+
entities: [
|
|
412
|
+
CustomUser,
|
|
413
|
+
],
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
await dataSource.initialize();
|
|
417
|
+
|
|
418
|
+
try
|
|
419
|
+
{
|
|
420
|
+
const repository =
|
|
421
|
+
dataSource.getRepository(CustomUser);
|
|
422
|
+
|
|
423
|
+
const users =
|
|
424
|
+
await repository.find();
|
|
425
|
+
|
|
426
|
+
expect(users)
|
|
427
|
+
.toHaveLength(1);
|
|
428
|
+
|
|
429
|
+
expect(users[0]?.id)
|
|
430
|
+
.toBe(1);
|
|
431
|
+
|
|
432
|
+
expect(users[0]?.name)
|
|
433
|
+
.toBe('Basuni');
|
|
434
|
+
}
|
|
435
|
+
finally
|
|
436
|
+
{
|
|
437
|
+
await dataSource.destroy();
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
test(
|
|
443
|
+
'should resolve custom column name',
|
|
444
|
+
async () =>
|
|
445
|
+
{
|
|
446
|
+
const dataSource =
|
|
447
|
+
createGoogleSheetsDataSource({
|
|
448
|
+
type: 'google-sheets',
|
|
449
|
+
|
|
450
|
+
client:
|
|
451
|
+
new Memory(),
|
|
452
|
+
|
|
453
|
+
entities: [
|
|
454
|
+
MappedUser,
|
|
455
|
+
],
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
await dataSource.initialize();
|
|
459
|
+
|
|
460
|
+
try
|
|
461
|
+
{
|
|
462
|
+
const metadata =
|
|
463
|
+
dataSource.entityMetadatas.find(
|
|
464
|
+
(item) =>
|
|
465
|
+
item.target === MappedUser,
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
const column =
|
|
469
|
+
metadata?.findColumnWithPropertyName(
|
|
470
|
+
'name',
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
expect(column)
|
|
474
|
+
.toBeDefined();
|
|
475
|
+
|
|
476
|
+
expect(column?.propertyName)
|
|
477
|
+
.toBe('name');
|
|
478
|
+
|
|
479
|
+
expect(column?.databaseName)
|
|
480
|
+
.toBe('user_name');
|
|
481
|
+
}
|
|
482
|
+
finally
|
|
483
|
+
{
|
|
484
|
+
await dataSource.destroy();
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
test(
|
|
490
|
+
'should resolve column type',
|
|
491
|
+
async () =>
|
|
492
|
+
{
|
|
493
|
+
const dataSource =
|
|
494
|
+
createGoogleSheetsDataSource({
|
|
495
|
+
type: 'google-sheets',
|
|
496
|
+
|
|
497
|
+
client:
|
|
498
|
+
new Memory(),
|
|
499
|
+
|
|
500
|
+
entities: [
|
|
501
|
+
TypedUser,
|
|
502
|
+
],
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
await dataSource.initialize();
|
|
506
|
+
|
|
507
|
+
try
|
|
508
|
+
{
|
|
509
|
+
const metadata =
|
|
510
|
+
dataSource.entityMetadatas.find(
|
|
511
|
+
(item) =>
|
|
512
|
+
item.target === TypedUser,
|
|
513
|
+
);
|
|
514
|
+
|
|
515
|
+
const ageColumn =
|
|
516
|
+
metadata?.findColumnWithPropertyName(
|
|
517
|
+
'age',
|
|
518
|
+
);
|
|
519
|
+
|
|
520
|
+
const activeColumn =
|
|
521
|
+
metadata?.findColumnWithPropertyName(
|
|
522
|
+
'active',
|
|
523
|
+
);
|
|
524
|
+
|
|
525
|
+
expect(ageColumn?.type)
|
|
526
|
+
.toBe('number');
|
|
527
|
+
|
|
528
|
+
expect(activeColumn?.type)
|
|
529
|
+
.toBe('boolean');
|
|
530
|
+
}
|
|
531
|
+
finally
|
|
532
|
+
{
|
|
533
|
+
await dataSource.destroy();
|
|
534
|
+
}
|
|
535
|
+
},
|
|
536
|
+
);
|
|
537
|
+
|
|
538
|
+
test(
|
|
539
|
+
'should resolve nullable column',
|
|
540
|
+
async () =>
|
|
541
|
+
{
|
|
542
|
+
const dataSource =
|
|
543
|
+
createGoogleSheetsDataSource({
|
|
544
|
+
type: 'google-sheets',
|
|
545
|
+
|
|
546
|
+
client:
|
|
547
|
+
new Memory(),
|
|
548
|
+
|
|
549
|
+
entities: [
|
|
550
|
+
NullableUser,
|
|
551
|
+
],
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
await dataSource.initialize();
|
|
555
|
+
|
|
556
|
+
try
|
|
557
|
+
{
|
|
558
|
+
const metadata =
|
|
559
|
+
dataSource.entityMetadatas.find(
|
|
560
|
+
(item) =>
|
|
561
|
+
item.target === NullableUser,
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
const column =
|
|
565
|
+
metadata?.findColumnWithPropertyName(
|
|
566
|
+
'nickname',
|
|
567
|
+
);
|
|
568
|
+
|
|
569
|
+
expect(column)
|
|
570
|
+
.toBeDefined();
|
|
571
|
+
|
|
572
|
+
expect(column?.isNullable)
|
|
573
|
+
.toBe(true);
|
|
574
|
+
}
|
|
575
|
+
finally
|
|
576
|
+
{
|
|
577
|
+
await dataSource.destroy();
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
test(
|
|
583
|
+
'should resolve generated column',
|
|
584
|
+
async () =>
|
|
585
|
+
{
|
|
586
|
+
const dataSource =
|
|
587
|
+
createGoogleSheetsDataSource({
|
|
588
|
+
type: 'google-sheets',
|
|
589
|
+
|
|
590
|
+
client:
|
|
591
|
+
new Memory(),
|
|
592
|
+
|
|
593
|
+
entities: [
|
|
594
|
+
GeneratedUser,
|
|
595
|
+
],
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
await dataSource.initialize();
|
|
599
|
+
|
|
600
|
+
try
|
|
601
|
+
{
|
|
602
|
+
const metadata =
|
|
603
|
+
dataSource.entityMetadatas.find(
|
|
604
|
+
(item) =>
|
|
605
|
+
item.target === GeneratedUser,
|
|
606
|
+
);
|
|
607
|
+
|
|
608
|
+
const column =
|
|
609
|
+
metadata?.findColumnWithPropertyName(
|
|
610
|
+
'id',
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
expect(column)
|
|
614
|
+
.toBeDefined();
|
|
615
|
+
|
|
616
|
+
expect(column?.isGenerated)
|
|
617
|
+
.toBe(true);
|
|
618
|
+
|
|
619
|
+
expect(column?.isPrimary)
|
|
620
|
+
.toBe(true);
|
|
621
|
+
}
|
|
622
|
+
finally
|
|
623
|
+
{
|
|
624
|
+
await dataSource.destroy();
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
);
|
|
628
|
+
|
|
629
|
+
test(
|
|
630
|
+
'should resolve increment generation strategy',
|
|
631
|
+
async () =>
|
|
632
|
+
{
|
|
633
|
+
const dataSource =
|
|
634
|
+
createGoogleSheetsDataSource({
|
|
635
|
+
type: 'google-sheets',
|
|
636
|
+
|
|
637
|
+
client:
|
|
638
|
+
new Memory(),
|
|
639
|
+
|
|
640
|
+
entities: [
|
|
641
|
+
GeneratedUser,
|
|
642
|
+
],
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
await dataSource.initialize();
|
|
646
|
+
|
|
647
|
+
try
|
|
648
|
+
{
|
|
649
|
+
const metadata =
|
|
650
|
+
dataSource.entityMetadatas.find(
|
|
651
|
+
(item) =>
|
|
652
|
+
item.target === GeneratedUser,
|
|
653
|
+
);
|
|
654
|
+
|
|
655
|
+
const column =
|
|
656
|
+
metadata?.findColumnWithPropertyName(
|
|
657
|
+
'id',
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
expect(column?.generationStrategy)
|
|
661
|
+
.toBe('increment');
|
|
662
|
+
}
|
|
663
|
+
finally
|
|
664
|
+
{
|
|
665
|
+
await dataSource.destroy();
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
);
|
|
669
|
+
|
|
670
|
+
test(
|
|
671
|
+
'should resolve default value',
|
|
672
|
+
async () =>
|
|
673
|
+
{
|
|
674
|
+
const dataSource =
|
|
675
|
+
createGoogleSheetsDataSource({
|
|
676
|
+
type: 'google-sheets',
|
|
677
|
+
|
|
678
|
+
client:
|
|
679
|
+
new Memory(),
|
|
680
|
+
|
|
681
|
+
entities: [
|
|
682
|
+
DefaultUser,
|
|
683
|
+
],
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
await dataSource.initialize();
|
|
687
|
+
|
|
688
|
+
try
|
|
689
|
+
{
|
|
690
|
+
const metadata =
|
|
691
|
+
dataSource.entityMetadatas.find(
|
|
692
|
+
(item) =>
|
|
693
|
+
item.target === DefaultUser,
|
|
694
|
+
);
|
|
695
|
+
|
|
696
|
+
const column =
|
|
697
|
+
metadata?.findColumnWithPropertyName(
|
|
698
|
+
'status',
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
expect(column)
|
|
702
|
+
.toBeDefined();
|
|
703
|
+
|
|
704
|
+
expect(column?.default)
|
|
705
|
+
.toBe('active');
|
|
706
|
+
}
|
|
707
|
+
finally
|
|
708
|
+
{
|
|
709
|
+
await dataSource.destroy();
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
);
|
|
713
|
+
|
|
714
|
+
test(
|
|
715
|
+
'should resolve uuid generation strategy',
|
|
716
|
+
async () =>
|
|
717
|
+
{
|
|
718
|
+
const dataSource =
|
|
719
|
+
createGoogleSheetsDataSource({
|
|
720
|
+
type: 'google-sheets',
|
|
721
|
+
|
|
722
|
+
client:
|
|
723
|
+
new Memory(),
|
|
724
|
+
|
|
725
|
+
entities: [
|
|
726
|
+
UuidUser,
|
|
727
|
+
],
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
await dataSource.initialize();
|
|
731
|
+
|
|
732
|
+
try
|
|
733
|
+
{
|
|
734
|
+
const metadata =
|
|
735
|
+
dataSource.entityMetadatas.find(
|
|
736
|
+
(item) =>
|
|
737
|
+
item.target === UuidUser,
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
const column =
|
|
741
|
+
metadata?.findColumnWithPropertyName(
|
|
742
|
+
'id',
|
|
743
|
+
);
|
|
744
|
+
|
|
745
|
+
expect(column)
|
|
746
|
+
.toBeDefined();
|
|
747
|
+
|
|
748
|
+
expect(column?.isPrimary)
|
|
749
|
+
.toBe(true);
|
|
750
|
+
|
|
751
|
+
expect(column?.isGenerated)
|
|
752
|
+
.toBe(true);
|
|
753
|
+
|
|
754
|
+
expect(column?.generationStrategy)
|
|
755
|
+
.toBe('uuid');
|
|
756
|
+
}
|
|
757
|
+
finally
|
|
758
|
+
{
|
|
759
|
+
await dataSource.destroy();
|
|
760
|
+
}
|
|
761
|
+
},
|
|
762
|
+
);
|
|
763
|
+
|
|
764
|
+
test(
|
|
765
|
+
'should initialize with synchronize enabled',
|
|
766
|
+
async () =>
|
|
767
|
+
{
|
|
768
|
+
const dataSource =
|
|
769
|
+
createGoogleSheetsDataSource({
|
|
770
|
+
type: 'google-sheets',
|
|
771
|
+
|
|
772
|
+
client:
|
|
773
|
+
new Memory(),
|
|
774
|
+
|
|
775
|
+
entities: [
|
|
776
|
+
SyncUser,
|
|
777
|
+
],
|
|
778
|
+
|
|
779
|
+
synchronize: true,
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
try
|
|
783
|
+
{
|
|
784
|
+
await dataSource.initialize();
|
|
785
|
+
|
|
786
|
+
expect(dataSource.isInitialized)
|
|
787
|
+
.toBe(true);
|
|
788
|
+
}
|
|
789
|
+
finally
|
|
790
|
+
{
|
|
791
|
+
if (dataSource.isInitialized)
|
|
792
|
+
{
|
|
793
|
+
await dataSource.destroy();
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
);
|
|
798
|
+
|
|
799
|
+
test(
|
|
800
|
+
'should detect existing worksheet',
|
|
801
|
+
async () =>
|
|
802
|
+
{
|
|
803
|
+
const client =
|
|
804
|
+
new Memory({
|
|
805
|
+
sync_users: [],
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
const dataSource =
|
|
809
|
+
createGoogleSheetsDataSource({
|
|
810
|
+
type: 'google-sheets',
|
|
811
|
+
|
|
812
|
+
client,
|
|
813
|
+
|
|
814
|
+
entities: [
|
|
815
|
+
SyncUser,
|
|
816
|
+
],
|
|
817
|
+
|
|
818
|
+
synchronize: true,
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
try
|
|
822
|
+
{
|
|
823
|
+
await dataSource.initialize();
|
|
824
|
+
|
|
825
|
+
expect(
|
|
826
|
+
await client.hasSheet('sync_users'),
|
|
827
|
+
).toBe(true);
|
|
828
|
+
}
|
|
829
|
+
finally
|
|
830
|
+
{
|
|
831
|
+
if (dataSource.isInitialized)
|
|
832
|
+
{
|
|
833
|
+
await dataSource.destroy();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
},
|
|
837
|
+
);
|
|
838
|
+
|
|
839
|
+
test(
|
|
840
|
+
'should create worksheet with headers',
|
|
841
|
+
async () =>
|
|
842
|
+
{
|
|
843
|
+
const client =
|
|
844
|
+
new Memory();
|
|
845
|
+
|
|
846
|
+
const dataSource =
|
|
847
|
+
createGoogleSheetsDataSource({
|
|
848
|
+
type: 'google-sheets',
|
|
849
|
+
|
|
850
|
+
client,
|
|
851
|
+
|
|
852
|
+
entities: [
|
|
853
|
+
SyncUser,
|
|
854
|
+
],
|
|
855
|
+
|
|
856
|
+
synchronize: true,
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
try
|
|
860
|
+
{
|
|
861
|
+
await dataSource.initialize();
|
|
862
|
+
|
|
863
|
+
expect(
|
|
864
|
+
await client.hasSheet('sync_users'),
|
|
865
|
+
).toBe(true);
|
|
866
|
+
|
|
867
|
+
expect(
|
|
868
|
+
await client.getHeaders('sync_users'),
|
|
869
|
+
).toEqual([
|
|
870
|
+
'id',
|
|
871
|
+
'name',
|
|
872
|
+
]);
|
|
873
|
+
}
|
|
874
|
+
finally
|
|
875
|
+
{
|
|
876
|
+
if (dataSource.isInitialized)
|
|
877
|
+
{
|
|
878
|
+
await dataSource.destroy();
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
},
|
|
882
|
+
);
|
|
883
|
+
|
|
884
|
+
test(
|
|
885
|
+
'should add missing headers to existing worksheet',
|
|
886
|
+
async () =>
|
|
887
|
+
{
|
|
888
|
+
const client =
|
|
889
|
+
new Memory();
|
|
890
|
+
|
|
891
|
+
await client.createSheet(
|
|
892
|
+
'sync_missing_headers',
|
|
893
|
+
);
|
|
894
|
+
|
|
895
|
+
await client.insertHeaders(
|
|
896
|
+
'sync_missing_headers',
|
|
897
|
+
[
|
|
898
|
+
'id',
|
|
899
|
+
'name',
|
|
900
|
+
],
|
|
901
|
+
);
|
|
902
|
+
|
|
903
|
+
const dataSource =
|
|
904
|
+
createGoogleSheetsDataSource({
|
|
905
|
+
type: 'google-sheets',
|
|
906
|
+
|
|
907
|
+
client,
|
|
908
|
+
|
|
909
|
+
entities: [
|
|
910
|
+
SyncMissingHeaderUser,
|
|
911
|
+
],
|
|
912
|
+
|
|
913
|
+
synchronize: true,
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
try
|
|
917
|
+
{
|
|
918
|
+
await dataSource.initialize();
|
|
919
|
+
|
|
920
|
+
expect(
|
|
921
|
+
await client.getHeaders(
|
|
922
|
+
'sync_missing_headers',
|
|
923
|
+
),
|
|
924
|
+
).toEqual([
|
|
925
|
+
'id',
|
|
926
|
+
'name',
|
|
927
|
+
'email',
|
|
928
|
+
]);
|
|
929
|
+
}
|
|
930
|
+
finally
|
|
931
|
+
{
|
|
932
|
+
if (dataSource.isInitialized)
|
|
933
|
+
{
|
|
934
|
+
await dataSource.destroy();
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
},
|
|
938
|
+
);
|
|
939
|
+
|
|
940
|
+
test(
|
|
941
|
+
'should add headers to empty worksheet',
|
|
942
|
+
async () =>
|
|
943
|
+
{
|
|
944
|
+
const client =
|
|
945
|
+
new Memory();
|
|
946
|
+
|
|
947
|
+
await client.createSheet(
|
|
948
|
+
'sync_missing_headers',
|
|
949
|
+
);
|
|
950
|
+
|
|
951
|
+
const dataSource =
|
|
952
|
+
createGoogleSheetsDataSource({
|
|
953
|
+
type: 'google-sheets',
|
|
954
|
+
|
|
955
|
+
client,
|
|
956
|
+
|
|
957
|
+
entities: [
|
|
958
|
+
SyncMissingHeaderUser,
|
|
959
|
+
],
|
|
960
|
+
|
|
961
|
+
synchronize: true,
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
try
|
|
965
|
+
{
|
|
966
|
+
await dataSource.initialize();
|
|
967
|
+
|
|
968
|
+
expect(
|
|
969
|
+
await client.getHeaders(
|
|
970
|
+
'sync_missing_headers',
|
|
971
|
+
),
|
|
972
|
+
).toEqual([
|
|
973
|
+
'id',
|
|
974
|
+
'name',
|
|
975
|
+
'email',
|
|
976
|
+
]);
|
|
977
|
+
}
|
|
978
|
+
finally
|
|
979
|
+
{
|
|
980
|
+
if (dataSource.isInitialized)
|
|
981
|
+
{
|
|
982
|
+
await dataSource.destroy();
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
},
|
|
986
|
+
);
|
|
987
|
+
|
|
988
|
+
test(
|
|
989
|
+
'should preserve existing data in worksheet',
|
|
990
|
+
async () =>
|
|
991
|
+
{
|
|
992
|
+
const client =
|
|
993
|
+
new Memory({
|
|
994
|
+
sync_missing_headers: [
|
|
995
|
+
{
|
|
996
|
+
id: 1,
|
|
997
|
+
name: 'John',
|
|
998
|
+
email: 'john@example.com',
|
|
999
|
+
},
|
|
1000
|
+
{
|
|
1001
|
+
id: 2,
|
|
1002
|
+
name: 'Jane',
|
|
1003
|
+
email: 'jane@example.com',
|
|
1004
|
+
},
|
|
1005
|
+
],
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
await client.insertHeaders(
|
|
1009
|
+
'sync_missing_headers',
|
|
1010
|
+
[
|
|
1011
|
+
'id',
|
|
1012
|
+
'name',
|
|
1013
|
+
'email',
|
|
1014
|
+
],
|
|
1015
|
+
);
|
|
1016
|
+
|
|
1017
|
+
const dataSource =
|
|
1018
|
+
createGoogleSheetsDataSource({
|
|
1019
|
+
type: 'google-sheets',
|
|
1020
|
+
|
|
1021
|
+
client,
|
|
1022
|
+
|
|
1023
|
+
entities: [
|
|
1024
|
+
SyncMissingHeaderUser,
|
|
1025
|
+
],
|
|
1026
|
+
|
|
1027
|
+
synchronize: true,
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
try
|
|
1031
|
+
{
|
|
1032
|
+
await dataSource.initialize();
|
|
1033
|
+
|
|
1034
|
+
expect(
|
|
1035
|
+
await client.getRows(
|
|
1036
|
+
'sync_missing_headers',
|
|
1037
|
+
),
|
|
1038
|
+
).toEqual([
|
|
1039
|
+
{
|
|
1040
|
+
id: 1,
|
|
1041
|
+
name: 'John',
|
|
1042
|
+
email: 'john@example.com',
|
|
1043
|
+
},
|
|
1044
|
+
{
|
|
1045
|
+
id: 2,
|
|
1046
|
+
name: 'Jane',
|
|
1047
|
+
email: 'jane@example.com',
|
|
1048
|
+
},
|
|
1049
|
+
]);
|
|
1050
|
+
}
|
|
1051
|
+
finally
|
|
1052
|
+
{
|
|
1053
|
+
if (dataSource.isInitialized)
|
|
1054
|
+
{
|
|
1055
|
+
await dataSource.destroy();
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
},
|
|
1059
|
+
);
|
|
1060
|
+
|
|
1061
|
+
test(
|
|
1062
|
+
'should apply non-destructive schema changes',
|
|
1063
|
+
async () =>
|
|
1064
|
+
{
|
|
1065
|
+
const client =
|
|
1066
|
+
new Memory({
|
|
1067
|
+
sync_missing_headers: [
|
|
1068
|
+
{
|
|
1069
|
+
id: 1,
|
|
1070
|
+
name: 'John',
|
|
1071
|
+
},
|
|
1072
|
+
],
|
|
1073
|
+
});
|
|
1074
|
+
|
|
1075
|
+
await client.insertHeaders(
|
|
1076
|
+
'sync_missing_headers',
|
|
1077
|
+
[
|
|
1078
|
+
'id',
|
|
1079
|
+
'name',
|
|
1080
|
+
],
|
|
1081
|
+
);
|
|
1082
|
+
|
|
1083
|
+
const dataSource =
|
|
1084
|
+
createGoogleSheetsDataSource({
|
|
1085
|
+
type: 'google-sheets',
|
|
1086
|
+
|
|
1087
|
+
client,
|
|
1088
|
+
|
|
1089
|
+
entities: [
|
|
1090
|
+
SyncMissingHeaderUser,
|
|
1091
|
+
],
|
|
1092
|
+
|
|
1093
|
+
synchronize: true,
|
|
1094
|
+
});
|
|
1095
|
+
|
|
1096
|
+
try
|
|
1097
|
+
{
|
|
1098
|
+
await dataSource.initialize();
|
|
1099
|
+
|
|
1100
|
+
expect(
|
|
1101
|
+
await client.getHeaders(
|
|
1102
|
+
'sync_missing_headers',
|
|
1103
|
+
),
|
|
1104
|
+
).toEqual([
|
|
1105
|
+
'id',
|
|
1106
|
+
'name',
|
|
1107
|
+
'email',
|
|
1108
|
+
]);
|
|
1109
|
+
|
|
1110
|
+
expect(
|
|
1111
|
+
await client.getRows(
|
|
1112
|
+
'sync_missing_headers',
|
|
1113
|
+
),
|
|
1114
|
+
).toEqual([
|
|
1115
|
+
{
|
|
1116
|
+
id: 1,
|
|
1117
|
+
name: 'John',
|
|
1118
|
+
},
|
|
1119
|
+
]);
|
|
1120
|
+
}
|
|
1121
|
+
finally
|
|
1122
|
+
{
|
|
1123
|
+
if (dataSource.isInitialized)
|
|
1124
|
+
{
|
|
1125
|
+
await dataSource.destroy();
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
},
|
|
1129
|
+
);
|
|
1130
|
+
|
|
1131
|
+
test(
|
|
1132
|
+
'should synchronize worksheet schema end-to-end',
|
|
1133
|
+
async () =>
|
|
1134
|
+
{
|
|
1135
|
+
const client =
|
|
1136
|
+
new Memory();
|
|
1137
|
+
|
|
1138
|
+
const dataSource =
|
|
1139
|
+
createGoogleSheetsDataSource({
|
|
1140
|
+
type: 'google-sheets',
|
|
1141
|
+
|
|
1142
|
+
client,
|
|
1143
|
+
|
|
1144
|
+
entities: [
|
|
1145
|
+
SyncMissingHeaderUser,
|
|
1146
|
+
],
|
|
1147
|
+
|
|
1148
|
+
synchronize: true,
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1151
|
+
try
|
|
1152
|
+
{
|
|
1153
|
+
await dataSource.initialize();
|
|
1154
|
+
|
|
1155
|
+
expect(
|
|
1156
|
+
await client.hasSheet(
|
|
1157
|
+
'sync_missing_headers',
|
|
1158
|
+
),
|
|
1159
|
+
).toBe(true);
|
|
1160
|
+
|
|
1161
|
+
expect(
|
|
1162
|
+
await client.getHeaders(
|
|
1163
|
+
'sync_missing_headers',
|
|
1164
|
+
),
|
|
1165
|
+
).toEqual([
|
|
1166
|
+
'id',
|
|
1167
|
+
'name',
|
|
1168
|
+
'email',
|
|
1169
|
+
]);
|
|
1170
|
+
|
|
1171
|
+
expect(
|
|
1172
|
+
await client.getRows(
|
|
1173
|
+
'sync_missing_headers',
|
|
1174
|
+
),
|
|
1175
|
+
).toEqual([]);
|
|
1176
|
+
}
|
|
1177
|
+
finally
|
|
1178
|
+
{
|
|
1179
|
+
if (dataSource.isInitialized)
|
|
1180
|
+
{
|
|
1181
|
+
await dataSource.destroy();
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
},
|
|
1185
|
+
);
|
|
1186
|
+
|
|
1187
|
+
test(
|
|
1188
|
+
'rejects duplicate primary key',
|
|
1189
|
+
async () =>
|
|
1190
|
+
{
|
|
1191
|
+
const client =
|
|
1192
|
+
new Memory({
|
|
1193
|
+
generated_users: [
|
|
1194
|
+
{
|
|
1195
|
+
id: 1,
|
|
1196
|
+
name: 'Basuni',
|
|
1197
|
+
},
|
|
1198
|
+
],
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
const dataSource =
|
|
1202
|
+
createGoogleSheetsDataSource({
|
|
1203
|
+
type: 'google-sheets',
|
|
1204
|
+
|
|
1205
|
+
client,
|
|
1206
|
+
|
|
1207
|
+
entities: [
|
|
1208
|
+
GeneratedUser,
|
|
1209
|
+
],
|
|
1210
|
+
});
|
|
1211
|
+
|
|
1212
|
+
await dataSource.initialize();
|
|
1213
|
+
|
|
1214
|
+
try
|
|
1215
|
+
{
|
|
1216
|
+
const queryRunner =
|
|
1217
|
+
dataSource.createQueryRunner();
|
|
1218
|
+
|
|
1219
|
+
await queryRunner.connect();
|
|
1220
|
+
|
|
1221
|
+
try
|
|
1222
|
+
{
|
|
1223
|
+
await expect(
|
|
1224
|
+
queryRunner.query(
|
|
1225
|
+
'INSERT INTO "generated_users"("id","name") VALUES (:orm_param_0,:orm_param_1)',
|
|
1226
|
+
[
|
|
1227
|
+
1,
|
|
1228
|
+
'Budi',
|
|
1229
|
+
],
|
|
1230
|
+
),
|
|
1231
|
+
).rejects.toThrow(
|
|
1232
|
+
'Duplicate primary key',
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
finally
|
|
1236
|
+
{
|
|
1237
|
+
await queryRunner.release();
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
finally
|
|
1241
|
+
{
|
|
1242
|
+
await dataSource.destroy();
|
|
1243
|
+
}
|
|
1244
|
+
},
|
|
1245
|
+
);
|
|
1246
|
+
|
|
1247
|
+
test(
|
|
1248
|
+
'rejects missing primary key',
|
|
1249
|
+
async () =>
|
|
1250
|
+
{
|
|
1251
|
+
const client =
|
|
1252
|
+
new Memory({
|
|
1253
|
+
required_users: [],
|
|
1254
|
+
});
|
|
1255
|
+
|
|
1256
|
+
const dataSource =
|
|
1257
|
+
createGoogleSheetsDataSource({
|
|
1258
|
+
type: 'google-sheets',
|
|
1259
|
+
client,
|
|
1260
|
+
entities: [
|
|
1261
|
+
RequiredUser,
|
|
1262
|
+
],
|
|
1263
|
+
});
|
|
1264
|
+
|
|
1265
|
+
await dataSource.initialize();
|
|
1266
|
+
|
|
1267
|
+
try
|
|
1268
|
+
{
|
|
1269
|
+
const queryRunner =
|
|
1270
|
+
dataSource.createQueryRunner();
|
|
1271
|
+
|
|
1272
|
+
await queryRunner.connect();
|
|
1273
|
+
|
|
1274
|
+
try
|
|
1275
|
+
{
|
|
1276
|
+
await expect(
|
|
1277
|
+
queryRunner.query(
|
|
1278
|
+
'INSERT INTO "required_users"("name") VALUES (:orm_param_0)',
|
|
1279
|
+
[
|
|
1280
|
+
'Budi',
|
|
1281
|
+
],
|
|
1282
|
+
),
|
|
1283
|
+
).rejects.toThrow(
|
|
1284
|
+
'Missing primary key',
|
|
1285
|
+
);
|
|
1286
|
+
}
|
|
1287
|
+
finally
|
|
1288
|
+
{
|
|
1289
|
+
await queryRunner.release();
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
finally
|
|
1293
|
+
{
|
|
1294
|
+
await dataSource.destroy();
|
|
1295
|
+
}
|
|
1296
|
+
},
|
|
1297
|
+
);
|
|
1298
|
+
|
|
1299
|
+
test(
|
|
1300
|
+
'rejects unsupported operation',
|
|
1301
|
+
async () =>
|
|
1302
|
+
{
|
|
1303
|
+
const client =
|
|
1304
|
+
new Memory({
|
|
1305
|
+
generated_users: [],
|
|
1306
|
+
});
|
|
1307
|
+
|
|
1308
|
+
const dataSource =
|
|
1309
|
+
createGoogleSheetsDataSource({
|
|
1310
|
+
type: 'google-sheets',
|
|
1311
|
+
client,
|
|
1312
|
+
entities: [
|
|
1313
|
+
GeneratedUser,
|
|
1314
|
+
],
|
|
1315
|
+
});
|
|
1316
|
+
|
|
1317
|
+
await dataSource.initialize();
|
|
1318
|
+
|
|
1319
|
+
try
|
|
1320
|
+
{
|
|
1321
|
+
const queryRunner =
|
|
1322
|
+
dataSource.createQueryRunner();
|
|
1323
|
+
|
|
1324
|
+
await queryRunner.connect();
|
|
1325
|
+
|
|
1326
|
+
try
|
|
1327
|
+
{
|
|
1328
|
+
await expect(
|
|
1329
|
+
queryRunner.query(
|
|
1330
|
+
'TRUNCATE TABLE "generated_users"',
|
|
1331
|
+
),
|
|
1332
|
+
).rejects.toThrow();
|
|
1333
|
+
}
|
|
1334
|
+
finally
|
|
1335
|
+
{
|
|
1336
|
+
await queryRunner.release();
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
finally
|
|
1340
|
+
{
|
|
1341
|
+
await dataSource.destroy();
|
|
1342
|
+
}
|
|
1343
|
+
},
|
|
1344
|
+
);
|
|
1345
|
+
|
|
1346
|
+
test(
|
|
1347
|
+
'should execute BeforeInsert lifecycle hook',
|
|
1348
|
+
async () =>
|
|
1349
|
+
{
|
|
1350
|
+
const client =
|
|
1351
|
+
new Memory({
|
|
1352
|
+
lifecycle_users: [],
|
|
1353
|
+
});
|
|
1354
|
+
|
|
1355
|
+
const dataSource =
|
|
1356
|
+
createGoogleSheetsDataSource({
|
|
1357
|
+
type: 'google-sheets',
|
|
1358
|
+
client,
|
|
1359
|
+
entities: [
|
|
1360
|
+
LifecycleUser,
|
|
1361
|
+
],
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
await dataSource.initialize();
|
|
1365
|
+
|
|
1366
|
+
try
|
|
1367
|
+
{
|
|
1368
|
+
const repository =
|
|
1369
|
+
dataSource.getRepository(
|
|
1370
|
+
LifecycleUser,
|
|
1371
|
+
);
|
|
1372
|
+
|
|
1373
|
+
const entity =
|
|
1374
|
+
repository.create({
|
|
1375
|
+
name: 'Budi',
|
|
1376
|
+
});
|
|
1377
|
+
|
|
1378
|
+
await repository.save(entity);
|
|
1379
|
+
|
|
1380
|
+
expect(
|
|
1381
|
+
entity.name,
|
|
1382
|
+
).toBe('BUDI');
|
|
1383
|
+
|
|
1384
|
+
expect(
|
|
1385
|
+
await repository.find(),
|
|
1386
|
+
).toEqual([
|
|
1387
|
+
expect.objectContaining({
|
|
1388
|
+
name: 'BUDI-loaded',
|
|
1389
|
+
}),
|
|
1390
|
+
]);
|
|
1391
|
+
}
|
|
1392
|
+
finally
|
|
1393
|
+
{
|
|
1394
|
+
await dataSource.destroy();
|
|
1395
|
+
}
|
|
1396
|
+
},
|
|
1397
|
+
);
|
|
1398
|
+
|
|
1399
|
+
test(
|
|
1400
|
+
'should execute AfterInsert lifecycle hook',
|
|
1401
|
+
async () =>
|
|
1402
|
+
{
|
|
1403
|
+
const client =
|
|
1404
|
+
new Memory({
|
|
1405
|
+
lifecycle_users: [],
|
|
1406
|
+
});
|
|
1407
|
+
|
|
1408
|
+
const dataSource =
|
|
1409
|
+
createGoogleSheetsDataSource({
|
|
1410
|
+
type: 'google-sheets',
|
|
1411
|
+
client,
|
|
1412
|
+
entities: [
|
|
1413
|
+
LifecycleUser2,
|
|
1414
|
+
],
|
|
1415
|
+
});
|
|
1416
|
+
|
|
1417
|
+
await dataSource.initialize();
|
|
1418
|
+
|
|
1419
|
+
try
|
|
1420
|
+
{
|
|
1421
|
+
const repository =
|
|
1422
|
+
dataSource.getRepository(
|
|
1423
|
+
LifecycleUser2,
|
|
1424
|
+
);
|
|
1425
|
+
|
|
1426
|
+
const entity =
|
|
1427
|
+
repository.create({
|
|
1428
|
+
name: 'Budi',
|
|
1429
|
+
});
|
|
1430
|
+
|
|
1431
|
+
await repository.save(entity);
|
|
1432
|
+
|
|
1433
|
+
expect(
|
|
1434
|
+
entity.name,
|
|
1435
|
+
).toBe('Budi-after');
|
|
1436
|
+
}
|
|
1437
|
+
finally
|
|
1438
|
+
{
|
|
1439
|
+
await dataSource.destroy();
|
|
1440
|
+
}
|
|
1441
|
+
},
|
|
1442
|
+
);
|
|
1443
|
+
|
|
1444
|
+
test(
|
|
1445
|
+
'should execute BeforeUpdate lifecycle hook',
|
|
1446
|
+
async () =>
|
|
1447
|
+
{
|
|
1448
|
+
const client =
|
|
1449
|
+
new Memory({
|
|
1450
|
+
lifecycle_users: [
|
|
1451
|
+
{
|
|
1452
|
+
id: 1,
|
|
1453
|
+
name: 'Budi',
|
|
1454
|
+
},
|
|
1455
|
+
],
|
|
1456
|
+
});
|
|
1457
|
+
|
|
1458
|
+
const dataSource =
|
|
1459
|
+
createGoogleSheetsDataSource({
|
|
1460
|
+
type: 'google-sheets',
|
|
1461
|
+
client,
|
|
1462
|
+
entities: [
|
|
1463
|
+
LifecycleUser,
|
|
1464
|
+
],
|
|
1465
|
+
});
|
|
1466
|
+
|
|
1467
|
+
await dataSource.initialize();
|
|
1468
|
+
|
|
1469
|
+
try
|
|
1470
|
+
{
|
|
1471
|
+
const repository =
|
|
1472
|
+
dataSource.getRepository(
|
|
1473
|
+
LifecycleUser,
|
|
1474
|
+
);
|
|
1475
|
+
|
|
1476
|
+
const entity =
|
|
1477
|
+
await repository.findOneBy({
|
|
1478
|
+
id: 1,
|
|
1479
|
+
});
|
|
1480
|
+
|
|
1481
|
+
expect(entity).toBeDefined();
|
|
1482
|
+
|
|
1483
|
+
entity!.name = 'andi';
|
|
1484
|
+
|
|
1485
|
+
await repository.save(entity!);
|
|
1486
|
+
|
|
1487
|
+
expect(entity!.name).toBe('ANDI');
|
|
1488
|
+
|
|
1489
|
+
expect(
|
|
1490
|
+
await repository.find(),
|
|
1491
|
+
).toEqual([
|
|
1492
|
+
expect.objectContaining({
|
|
1493
|
+
name: 'ANDI-loaded',
|
|
1494
|
+
}),
|
|
1495
|
+
]);
|
|
1496
|
+
}
|
|
1497
|
+
finally
|
|
1498
|
+
{
|
|
1499
|
+
await dataSource.destroy();
|
|
1500
|
+
}
|
|
1501
|
+
},
|
|
1502
|
+
);
|
|
1503
|
+
|
|
1504
|
+
test(
|
|
1505
|
+
'should execute AfterUpdate lifecycle hook',
|
|
1506
|
+
async () =>
|
|
1507
|
+
{
|
|
1508
|
+
const client =
|
|
1509
|
+
new Memory({
|
|
1510
|
+
lifecycle_users: [
|
|
1511
|
+
{
|
|
1512
|
+
id: 1,
|
|
1513
|
+
name: 'Budi',
|
|
1514
|
+
},
|
|
1515
|
+
],
|
|
1516
|
+
});
|
|
1517
|
+
|
|
1518
|
+
const dataSource =
|
|
1519
|
+
createGoogleSheetsDataSource({
|
|
1520
|
+
type: 'google-sheets',
|
|
1521
|
+
client,
|
|
1522
|
+
entities: [
|
|
1523
|
+
LifecycleUser2,
|
|
1524
|
+
],
|
|
1525
|
+
});
|
|
1526
|
+
|
|
1527
|
+
await dataSource.initialize();
|
|
1528
|
+
|
|
1529
|
+
try
|
|
1530
|
+
{
|
|
1531
|
+
const repository =
|
|
1532
|
+
dataSource.getRepository(
|
|
1533
|
+
LifecycleUser2,
|
|
1534
|
+
);
|
|
1535
|
+
|
|
1536
|
+
const entity =
|
|
1537
|
+
repository.create({
|
|
1538
|
+
id: 1,
|
|
1539
|
+
name: 'andi',
|
|
1540
|
+
});
|
|
1541
|
+
|
|
1542
|
+
await repository.save(entity);
|
|
1543
|
+
|
|
1544
|
+
expect(entity.name).toBe('andi-after');
|
|
1545
|
+
}
|
|
1546
|
+
finally
|
|
1547
|
+
{
|
|
1548
|
+
await dataSource.destroy();
|
|
1549
|
+
}
|
|
1550
|
+
},
|
|
1551
|
+
);
|
|
1552
|
+
|
|
1553
|
+
test(
|
|
1554
|
+
'should execute BeforeRemove lifecycle hook',
|
|
1555
|
+
async () =>
|
|
1556
|
+
{
|
|
1557
|
+
const client =
|
|
1558
|
+
new Memory({
|
|
1559
|
+
lifecycle_users: [
|
|
1560
|
+
{
|
|
1561
|
+
id: 1,
|
|
1562
|
+
name: 'Budi',
|
|
1563
|
+
},
|
|
1564
|
+
],
|
|
1565
|
+
});
|
|
1566
|
+
|
|
1567
|
+
const dataSource =
|
|
1568
|
+
createGoogleSheetsDataSource({
|
|
1569
|
+
type: 'google-sheets',
|
|
1570
|
+
client,
|
|
1571
|
+
entities: [
|
|
1572
|
+
LifecycleUser,
|
|
1573
|
+
],
|
|
1574
|
+
});
|
|
1575
|
+
|
|
1576
|
+
await dataSource.initialize();
|
|
1577
|
+
|
|
1578
|
+
try
|
|
1579
|
+
{
|
|
1580
|
+
const repository =
|
|
1581
|
+
dataSource.getRepository(
|
|
1582
|
+
LifecycleUser,
|
|
1583
|
+
);
|
|
1584
|
+
|
|
1585
|
+
const entity =
|
|
1586
|
+
repository.create({
|
|
1587
|
+
id: 1,
|
|
1588
|
+
name: 'Budi',
|
|
1589
|
+
});
|
|
1590
|
+
|
|
1591
|
+
await repository.remove(entity);
|
|
1592
|
+
|
|
1593
|
+
expect(
|
|
1594
|
+
entity.name,
|
|
1595
|
+
).toBe('Budi-before');
|
|
1596
|
+
}
|
|
1597
|
+
finally
|
|
1598
|
+
{
|
|
1599
|
+
await dataSource.destroy();
|
|
1600
|
+
}
|
|
1601
|
+
},
|
|
1602
|
+
);
|
|
1603
|
+
|
|
1604
|
+
test(
|
|
1605
|
+
'should execute AfterRemove lifecycle hook',
|
|
1606
|
+
async () =>
|
|
1607
|
+
{
|
|
1608
|
+
const client =
|
|
1609
|
+
new Memory({
|
|
1610
|
+
lifecycle_users: [
|
|
1611
|
+
{
|
|
1612
|
+
id: 1,
|
|
1613
|
+
name: 'Budi',
|
|
1614
|
+
},
|
|
1615
|
+
],
|
|
1616
|
+
});
|
|
1617
|
+
|
|
1618
|
+
const dataSource =
|
|
1619
|
+
createGoogleSheetsDataSource({
|
|
1620
|
+
type: 'google-sheets',
|
|
1621
|
+
client,
|
|
1622
|
+
entities: [
|
|
1623
|
+
LifecycleUser2,
|
|
1624
|
+
],
|
|
1625
|
+
});
|
|
1626
|
+
|
|
1627
|
+
await dataSource.initialize();
|
|
1628
|
+
|
|
1629
|
+
try
|
|
1630
|
+
{
|
|
1631
|
+
const repository =
|
|
1632
|
+
dataSource.getRepository(
|
|
1633
|
+
LifecycleUser2,
|
|
1634
|
+
);
|
|
1635
|
+
|
|
1636
|
+
const entity =
|
|
1637
|
+
repository.create({
|
|
1638
|
+
id: 1,
|
|
1639
|
+
name: 'Budi',
|
|
1640
|
+
});
|
|
1641
|
+
|
|
1642
|
+
await repository.remove(entity);
|
|
1643
|
+
|
|
1644
|
+
expect(
|
|
1645
|
+
entity.name,
|
|
1646
|
+
).toBe('Budi-after');
|
|
1647
|
+
}
|
|
1648
|
+
finally
|
|
1649
|
+
{
|
|
1650
|
+
await dataSource.destroy();
|
|
1651
|
+
}
|
|
1652
|
+
},
|
|
1653
|
+
);
|
|
1654
|
+
|
|
1655
|
+
test(
|
|
1656
|
+
'should execute subscriber beforeInsert hook',
|
|
1657
|
+
async () =>
|
|
1658
|
+
{
|
|
1659
|
+
const client =
|
|
1660
|
+
new Memory({
|
|
1661
|
+
lifecycle_users: [],
|
|
1662
|
+
});
|
|
1663
|
+
|
|
1664
|
+
const dataSource =
|
|
1665
|
+
createGoogleSheetsDataSource({
|
|
1666
|
+
type: 'google-sheets',
|
|
1667
|
+
client,
|
|
1668
|
+
entities: [
|
|
1669
|
+
LifecycleUser,
|
|
1670
|
+
],
|
|
1671
|
+
subscribers: [
|
|
1672
|
+
LifecycleUserSubscriber,
|
|
1673
|
+
],
|
|
1674
|
+
});
|
|
1675
|
+
|
|
1676
|
+
await dataSource.initialize();
|
|
1677
|
+
|
|
1678
|
+
try
|
|
1679
|
+
{
|
|
1680
|
+
const repository =
|
|
1681
|
+
dataSource.getRepository(
|
|
1682
|
+
LifecycleUser,
|
|
1683
|
+
);
|
|
1684
|
+
|
|
1685
|
+
const entity =
|
|
1686
|
+
repository.create({
|
|
1687
|
+
name: 'Budi',
|
|
1688
|
+
});
|
|
1689
|
+
|
|
1690
|
+
await repository.save(entity);
|
|
1691
|
+
|
|
1692
|
+
expect(entity.name).toBe(
|
|
1693
|
+
'BUDI-subscriber-before-subscriber-after',
|
|
1694
|
+
);
|
|
1695
|
+
}
|
|
1696
|
+
finally
|
|
1697
|
+
{
|
|
1698
|
+
await dataSource.destroy();
|
|
1699
|
+
}
|
|
1700
|
+
},
|
|
1701
|
+
);
|
|
1702
|
+
|
|
1703
|
+
test(
|
|
1704
|
+
'should execute subscriber afterInsert hook',
|
|
1705
|
+
async () =>
|
|
1706
|
+
{
|
|
1707
|
+
const client =
|
|
1708
|
+
new Memory({
|
|
1709
|
+
lifecycle_users: [],
|
|
1710
|
+
});
|
|
1711
|
+
|
|
1712
|
+
const dataSource =
|
|
1713
|
+
createGoogleSheetsDataSource({
|
|
1714
|
+
type: 'google-sheets',
|
|
1715
|
+
client,
|
|
1716
|
+
entities: [
|
|
1717
|
+
LifecycleUser,
|
|
1718
|
+
],
|
|
1719
|
+
subscribers: [
|
|
1720
|
+
LifecycleUserSubscriber,
|
|
1721
|
+
],
|
|
1722
|
+
});
|
|
1723
|
+
|
|
1724
|
+
await dataSource.initialize();
|
|
1725
|
+
|
|
1726
|
+
try
|
|
1727
|
+
{
|
|
1728
|
+
const repository =
|
|
1729
|
+
dataSource.getRepository(
|
|
1730
|
+
LifecycleUser,
|
|
1731
|
+
);
|
|
1732
|
+
|
|
1733
|
+
const entity =
|
|
1734
|
+
repository.create({
|
|
1735
|
+
name: 'Budi',
|
|
1736
|
+
});
|
|
1737
|
+
|
|
1738
|
+
await repository.save(entity);
|
|
1739
|
+
|
|
1740
|
+
expect(entity.name).toBe(
|
|
1741
|
+
'BUDI-subscriber-before-subscriber-after',
|
|
1742
|
+
);
|
|
1743
|
+
}
|
|
1744
|
+
finally
|
|
1745
|
+
{
|
|
1746
|
+
await dataSource.destroy();
|
|
1747
|
+
}
|
|
1748
|
+
},
|
|
1749
|
+
);
|
|
1750
|
+
|
|
1751
|
+
test(
|
|
1752
|
+
'should apply naming strategy to worksheet and columns',
|
|
1753
|
+
async () =>
|
|
1754
|
+
{
|
|
1755
|
+
const client =
|
|
1756
|
+
new Memory();
|
|
1757
|
+
|
|
1758
|
+
const dataSource =
|
|
1759
|
+
createGoogleSheetsDataSource({
|
|
1760
|
+
type: 'google-sheets',
|
|
1761
|
+
client,
|
|
1762
|
+
entities: [
|
|
1763
|
+
NamingStrategyUser,
|
|
1764
|
+
],
|
|
1765
|
+
synchronize: true,
|
|
1766
|
+
namingStrategy:
|
|
1767
|
+
new TestNamingStrategy(),
|
|
1768
|
+
} as GoogleSheetsDataSourceOptions & {
|
|
1769
|
+
namingStrategy: TestNamingStrategy;
|
|
1770
|
+
});
|
|
1771
|
+
|
|
1772
|
+
await dataSource.initialize();
|
|
1773
|
+
|
|
1774
|
+
try
|
|
1775
|
+
{
|
|
1776
|
+
const metadata =
|
|
1777
|
+
dataSource.getMetadata(
|
|
1778
|
+
NamingStrategyUser,
|
|
1779
|
+
);
|
|
1780
|
+
|
|
1781
|
+
expect(metadata.tableName).toBe(
|
|
1782
|
+
'sheet_namingstrategyuser',
|
|
1783
|
+
);
|
|
1784
|
+
|
|
1785
|
+
expect(
|
|
1786
|
+
metadata.findColumnWithPropertyName(
|
|
1787
|
+
'displayName',
|
|
1788
|
+
)?.databaseName,
|
|
1789
|
+
).toBe(
|
|
1790
|
+
'col_displayname',
|
|
1791
|
+
);
|
|
1792
|
+
|
|
1793
|
+
expect(
|
|
1794
|
+
await client.hasSheet(
|
|
1795
|
+
'sheet_namingstrategyuser',
|
|
1796
|
+
),
|
|
1797
|
+
).toBe(true);
|
|
1798
|
+
|
|
1799
|
+
expect(
|
|
1800
|
+
await client.getHeaders(
|
|
1801
|
+
'sheet_namingstrategyuser',
|
|
1802
|
+
),
|
|
1803
|
+
).toEqual([
|
|
1804
|
+
'col_id',
|
|
1805
|
+
'col_displayname',
|
|
1806
|
+
]);
|
|
1807
|
+
}
|
|
1808
|
+
finally
|
|
1809
|
+
{
|
|
1810
|
+
await dataSource.destroy();
|
|
1811
|
+
}
|
|
1812
|
+
},
|
|
1813
|
+
);
|
|
1814
|
+
|
|
1815
|
+
test(
|
|
1816
|
+
'should resolve relation metadata',
|
|
1817
|
+
async () =>
|
|
1818
|
+
{
|
|
1819
|
+
const client =
|
|
1820
|
+
new Memory({
|
|
1821
|
+
relation_users: [],
|
|
1822
|
+
relation_posts: [],
|
|
1823
|
+
});
|
|
1824
|
+
|
|
1825
|
+
const dataSource =
|
|
1826
|
+
createGoogleSheetsDataSource({
|
|
1827
|
+
type: 'google-sheets',
|
|
1828
|
+
client,
|
|
1829
|
+
entities: [
|
|
1830
|
+
RelationUser,
|
|
1831
|
+
RelationPost,
|
|
1832
|
+
],
|
|
1833
|
+
synchronize: true,
|
|
1834
|
+
});
|
|
1835
|
+
|
|
1836
|
+
await dataSource.initialize();
|
|
1837
|
+
|
|
1838
|
+
try
|
|
1839
|
+
{
|
|
1840
|
+
const metadata =
|
|
1841
|
+
dataSource.getMetadata(
|
|
1842
|
+
RelationPost,
|
|
1843
|
+
);
|
|
1844
|
+
|
|
1845
|
+
const relation =
|
|
1846
|
+
metadata.relations.find(
|
|
1847
|
+
(item) =>
|
|
1848
|
+
item.propertyName === 'author',
|
|
1849
|
+
);
|
|
1850
|
+
|
|
1851
|
+
expect(relation).toBeDefined();
|
|
1852
|
+
|
|
1853
|
+
expect(
|
|
1854
|
+
relation!.isManyToOne,
|
|
1855
|
+
).toBe(true);
|
|
1856
|
+
|
|
1857
|
+
expect(
|
|
1858
|
+
relation!.inverseEntityMetadata.target,
|
|
1859
|
+
).toBe(RelationUser);
|
|
1860
|
+
|
|
1861
|
+
expect(
|
|
1862
|
+
relation!.inverseRelation,
|
|
1863
|
+
).toBeUndefined();
|
|
1864
|
+
}
|
|
1865
|
+
finally
|
|
1866
|
+
{
|
|
1867
|
+
await dataSource.destroy();
|
|
1868
|
+
}
|
|
1869
|
+
},
|
|
1870
|
+
);
|
|
1871
|
+
|
|
1872
|
+
test(
|
|
1873
|
+
'should load many-to-one relation',
|
|
1874
|
+
async () =>
|
|
1875
|
+
{
|
|
1876
|
+
const client =
|
|
1877
|
+
new Memory({
|
|
1878
|
+
relation_users: [
|
|
1879
|
+
{
|
|
1880
|
+
id: 1,
|
|
1881
|
+
name: 'Budi',
|
|
1882
|
+
},
|
|
1883
|
+
],
|
|
1884
|
+
relation_posts: [
|
|
1885
|
+
{
|
|
1886
|
+
id: 1,
|
|
1887
|
+
title: 'Post Budi',
|
|
1888
|
+
authorId: 1,
|
|
1889
|
+
},
|
|
1890
|
+
],
|
|
1891
|
+
});
|
|
1892
|
+
|
|
1893
|
+
const dataSource =
|
|
1894
|
+
createGoogleSheetsDataSource({
|
|
1895
|
+
type: 'google-sheets',
|
|
1896
|
+
client,
|
|
1897
|
+
entities: [
|
|
1898
|
+
RelationUser,
|
|
1899
|
+
RelationPost,
|
|
1900
|
+
],
|
|
1901
|
+
});
|
|
1902
|
+
|
|
1903
|
+
await dataSource.initialize();
|
|
1904
|
+
|
|
1905
|
+
try
|
|
1906
|
+
{
|
|
1907
|
+
const repository =
|
|
1908
|
+
dataSource.getRepository(
|
|
1909
|
+
RelationPost,
|
|
1910
|
+
);
|
|
1911
|
+
|
|
1912
|
+
const post =
|
|
1913
|
+
await repository.findOne({
|
|
1914
|
+
where: {
|
|
1915
|
+
id: 1,
|
|
1916
|
+
},
|
|
1917
|
+
relations: {
|
|
1918
|
+
author: true,
|
|
1919
|
+
},
|
|
1920
|
+
});
|
|
1921
|
+
|
|
1922
|
+
expect(post).toBeDefined();
|
|
1923
|
+
expect(post!.title).toBe('Post Budi');
|
|
1924
|
+
expect(post!.author).toBeDefined();
|
|
1925
|
+
expect(post!.author.id).toBe(1);
|
|
1926
|
+
expect(post!.author.name).toBe('Budi');
|
|
1927
|
+
}
|
|
1928
|
+
finally
|
|
1929
|
+
{
|
|
1930
|
+
await dataSource.destroy();
|
|
1931
|
+
}
|
|
1932
|
+
},
|
|
1933
|
+
);
|
|
1934
|
+
},
|
|
1935
|
+
);
|