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,1566 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import { Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
|
|
3
|
+
import { Memory } from '../../src/core/memory';
|
|
4
|
+
import { createGoogleSheetsDataSource } from '../../src/core/data-source';
|
|
5
|
+
|
|
6
|
+
describe('GoogleSheetsDataSource', () =>
|
|
7
|
+
{
|
|
8
|
+
@Entity()
|
|
9
|
+
class User
|
|
10
|
+
{
|
|
11
|
+
@PrimaryGeneratedColumn()
|
|
12
|
+
id!: number;
|
|
13
|
+
|
|
14
|
+
@Column()
|
|
15
|
+
name!: string;
|
|
16
|
+
|
|
17
|
+
@ManyToMany(
|
|
18
|
+
() => Role,
|
|
19
|
+
(role) => role.users,
|
|
20
|
+
)
|
|
21
|
+
@JoinTable({
|
|
22
|
+
name: 'user_role',
|
|
23
|
+
joinColumn: {
|
|
24
|
+
name: 'userId',
|
|
25
|
+
referencedColumnName: 'id',
|
|
26
|
+
},
|
|
27
|
+
inverseJoinColumn: {
|
|
28
|
+
name: 'roleId',
|
|
29
|
+
referencedColumnName: 'id',
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
roles?: Role[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Entity()
|
|
36
|
+
class Category
|
|
37
|
+
{
|
|
38
|
+
@PrimaryGeneratedColumn()
|
|
39
|
+
id!: number;
|
|
40
|
+
|
|
41
|
+
@Column()
|
|
42
|
+
name!: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Entity()
|
|
46
|
+
class Post
|
|
47
|
+
{
|
|
48
|
+
@PrimaryGeneratedColumn()
|
|
49
|
+
id!: number;
|
|
50
|
+
|
|
51
|
+
@Column()
|
|
52
|
+
title!: string;
|
|
53
|
+
|
|
54
|
+
@Column()
|
|
55
|
+
userId!: number;
|
|
56
|
+
|
|
57
|
+
@Column({ nullable: true })
|
|
58
|
+
categoryId!: number;
|
|
59
|
+
|
|
60
|
+
@ManyToOne(
|
|
61
|
+
() => User,
|
|
62
|
+
)
|
|
63
|
+
@JoinColumn({
|
|
64
|
+
name: 'userId',
|
|
65
|
+
})
|
|
66
|
+
user!: User;
|
|
67
|
+
|
|
68
|
+
@ManyToOne(
|
|
69
|
+
() => Category,
|
|
70
|
+
)
|
|
71
|
+
@JoinColumn({
|
|
72
|
+
name: 'categoryId',
|
|
73
|
+
})
|
|
74
|
+
category!: Category;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Entity()
|
|
78
|
+
class Role
|
|
79
|
+
{
|
|
80
|
+
@PrimaryGeneratedColumn()
|
|
81
|
+
id!: number;
|
|
82
|
+
|
|
83
|
+
@Column()
|
|
84
|
+
name!: string;
|
|
85
|
+
|
|
86
|
+
@ManyToMany(
|
|
87
|
+
() => User,
|
|
88
|
+
(user) => user.roles,
|
|
89
|
+
)
|
|
90
|
+
users!: User[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@Entity()
|
|
94
|
+
class UuidUser
|
|
95
|
+
{
|
|
96
|
+
@PrimaryGeneratedColumn('uuid')
|
|
97
|
+
id!: string;
|
|
98
|
+
|
|
99
|
+
@Column()
|
|
100
|
+
name!: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Entity()
|
|
104
|
+
class IdentityUser
|
|
105
|
+
{
|
|
106
|
+
@PrimaryGeneratedColumn('identity')
|
|
107
|
+
id!: number;
|
|
108
|
+
|
|
109
|
+
@Column()
|
|
110
|
+
name!: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@Entity()
|
|
114
|
+
class RowidUser
|
|
115
|
+
{
|
|
116
|
+
@PrimaryGeneratedColumn('rowid')
|
|
117
|
+
id!: string;
|
|
118
|
+
|
|
119
|
+
@Column()
|
|
120
|
+
name!: string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const entities = [User, Post, Category, Role, UuidUser, IdentityUser, RowidUser]
|
|
124
|
+
|
|
125
|
+
test('inserts a new entity', async () =>
|
|
126
|
+
{
|
|
127
|
+
const client = new Memory({
|
|
128
|
+
user: [
|
|
129
|
+
{ id: 1, name: 'Basuni' },
|
|
130
|
+
{ id: 2, name: 'Tan Tan' },
|
|
131
|
+
],
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
135
|
+
type: 'google-sheets',
|
|
136
|
+
client,
|
|
137
|
+
entities
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
await dataSource.initialize();
|
|
141
|
+
|
|
142
|
+
const repository = dataSource.getRepository(User);
|
|
143
|
+
|
|
144
|
+
const user = repository.create({
|
|
145
|
+
id: 3,
|
|
146
|
+
name: 'Budi',
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
await repository.save(user);
|
|
150
|
+
|
|
151
|
+
expect(user.id).toBe(3);
|
|
152
|
+
|
|
153
|
+
const users = await repository.find();
|
|
154
|
+
|
|
155
|
+
expect(users).toHaveLength(3);
|
|
156
|
+
expect(users[2]).toMatchObject({
|
|
157
|
+
id: 3,
|
|
158
|
+
name: 'Budi',
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
await dataSource.destroy();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('updates an existing entity', async () =>
|
|
165
|
+
{
|
|
166
|
+
const client = new Memory({
|
|
167
|
+
user: [
|
|
168
|
+
{ id: 1, name: 'Basuni' },
|
|
169
|
+
{ id: 2, name: 'Tan Tan' },
|
|
170
|
+
],
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
174
|
+
type: 'google-sheets',
|
|
175
|
+
client,
|
|
176
|
+
entities
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
await dataSource.initialize();
|
|
180
|
+
|
|
181
|
+
const repository = dataSource.getRepository(User);
|
|
182
|
+
|
|
183
|
+
const user = await repository.findOne({
|
|
184
|
+
where: {
|
|
185
|
+
id: 1,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
expect(user).not.toBeNull();
|
|
190
|
+
|
|
191
|
+
if (!user)
|
|
192
|
+
{
|
|
193
|
+
throw new Error('User not found.');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
user.name = 'Basuni Updated';
|
|
197
|
+
|
|
198
|
+
await repository.save(user);
|
|
199
|
+
|
|
200
|
+
const updatedUser = await repository.findOne({
|
|
201
|
+
where: {
|
|
202
|
+
id: 1,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
expect(updatedUser).toMatchObject({
|
|
207
|
+
id: 1,
|
|
208
|
+
name: 'Basuni Updated',
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
await dataSource.destroy();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test('deletes an existing entity', async () =>
|
|
215
|
+
{
|
|
216
|
+
const client = new Memory({
|
|
217
|
+
user: [
|
|
218
|
+
{ id: 1, name: 'Basuni' },
|
|
219
|
+
{ id: 2, name: 'Tan Tan' },
|
|
220
|
+
],
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
224
|
+
type: 'google-sheets',
|
|
225
|
+
client,
|
|
226
|
+
entities
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
await dataSource.initialize();
|
|
230
|
+
|
|
231
|
+
const repository = dataSource.getRepository(User);
|
|
232
|
+
|
|
233
|
+
const user = await repository.findOne({
|
|
234
|
+
where: {
|
|
235
|
+
id: 1,
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
expect(user).not.toBeNull();
|
|
240
|
+
|
|
241
|
+
if (!user)
|
|
242
|
+
{
|
|
243
|
+
throw new Error('User not found.');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
await repository.remove(user);
|
|
247
|
+
|
|
248
|
+
const deletedUser = await repository.findOne({
|
|
249
|
+
where: {
|
|
250
|
+
id: 1,
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
expect(deletedUser).toBeNull();
|
|
255
|
+
|
|
256
|
+
const users = await repository.find();
|
|
257
|
+
|
|
258
|
+
expect(users).toHaveLength(1);
|
|
259
|
+
expect(users[0]).toMatchObject({
|
|
260
|
+
id: 2,
|
|
261
|
+
name: 'Tan Tan',
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
await dataSource.destroy();
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
test('bulk inserts multiple entities', async () =>
|
|
268
|
+
{
|
|
269
|
+
const client = new Memory({
|
|
270
|
+
user: [
|
|
271
|
+
{ id: 1, name: 'Basuni' },
|
|
272
|
+
],
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
276
|
+
type: 'google-sheets',
|
|
277
|
+
client,
|
|
278
|
+
entities
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
await dataSource.initialize();
|
|
282
|
+
|
|
283
|
+
const repository = dataSource.getRepository(User);
|
|
284
|
+
|
|
285
|
+
await repository.insert([
|
|
286
|
+
{ name: 'Budi' },
|
|
287
|
+
{ name: 'Andi' },
|
|
288
|
+
]);
|
|
289
|
+
|
|
290
|
+
const users = await repository.find();
|
|
291
|
+
|
|
292
|
+
expect(users).toHaveLength(3);
|
|
293
|
+
|
|
294
|
+
expect(users).toMatchObject([
|
|
295
|
+
{ id: 1, name: 'Basuni' },
|
|
296
|
+
{ id: 2, name: 'Budi' },
|
|
297
|
+
{ id: 3, name: 'Andi' },
|
|
298
|
+
]);
|
|
299
|
+
|
|
300
|
+
await dataSource.destroy();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
test('updates multiple entities', async () =>
|
|
304
|
+
{
|
|
305
|
+
const client = new Memory({
|
|
306
|
+
user: [
|
|
307
|
+
{ id: 1, name: 'Basuni' },
|
|
308
|
+
{ id: 2, name: 'Basuni' },
|
|
309
|
+
{ id: 3, name: 'Tan Tan' },
|
|
310
|
+
],
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
314
|
+
type: 'google-sheets',
|
|
315
|
+
client,
|
|
316
|
+
entities
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
await dataSource.initialize();
|
|
320
|
+
|
|
321
|
+
const repository = dataSource.getRepository(User);
|
|
322
|
+
|
|
323
|
+
await repository.update(
|
|
324
|
+
{ name: 'Basuni' },
|
|
325
|
+
{ name: 'Basuni Updated' },
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
const users = await repository.find();
|
|
329
|
+
|
|
330
|
+
expect(users).toMatchObject([
|
|
331
|
+
{ id: 1, name: 'Basuni Updated' },
|
|
332
|
+
{ id: 2, name: 'Basuni Updated' },
|
|
333
|
+
{ id: 3, name: 'Tan Tan' },
|
|
334
|
+
]);
|
|
335
|
+
|
|
336
|
+
await dataSource.destroy();
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test('deletes multiple entities', async () =>
|
|
340
|
+
{
|
|
341
|
+
const client = new Memory({
|
|
342
|
+
user: [
|
|
343
|
+
{ id: 1, name: 'Basuni' },
|
|
344
|
+
{ id: 2, name: 'Basuni' },
|
|
345
|
+
{ id: 3, name: 'Tan Tan' },
|
|
346
|
+
],
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
350
|
+
type: 'google-sheets',
|
|
351
|
+
client,
|
|
352
|
+
entities
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
await dataSource.initialize();
|
|
356
|
+
|
|
357
|
+
const repository = dataSource.getRepository(User);
|
|
358
|
+
|
|
359
|
+
await repository.delete({
|
|
360
|
+
name: 'Basuni',
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const users = await repository.find();
|
|
364
|
+
|
|
365
|
+
expect(users).toMatchObject([
|
|
366
|
+
{ id: 3, name: 'Tan Tan' },
|
|
367
|
+
]);
|
|
368
|
+
|
|
369
|
+
await dataSource.destroy();
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
test('saves an existing entity', async () =>
|
|
373
|
+
{
|
|
374
|
+
const client = new Memory({
|
|
375
|
+
user: [
|
|
376
|
+
{ id: 1, name: 'Tan Tan' },
|
|
377
|
+
{ id: 2, name: 'Basuni' },
|
|
378
|
+
],
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
382
|
+
type: 'google-sheets',
|
|
383
|
+
client,
|
|
384
|
+
entities
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
await dataSource.initialize();
|
|
388
|
+
|
|
389
|
+
const repository = dataSource.getRepository(User);
|
|
390
|
+
|
|
391
|
+
const user = await repository.findOneBy({
|
|
392
|
+
id: 1,
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
if (!user)
|
|
396
|
+
{
|
|
397
|
+
throw new Error('User not found.');
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
user.name = 'Tan Tan Updated';
|
|
401
|
+
|
|
402
|
+
await repository.save(user);
|
|
403
|
+
|
|
404
|
+
const updated = await repository.findOneBy({
|
|
405
|
+
id: 1,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
expect(updated).toEqual({
|
|
409
|
+
id: 1,
|
|
410
|
+
name: 'Tan Tan Updated',
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
await dataSource.destroy();
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
test('removes an existing entity', async () =>
|
|
417
|
+
{
|
|
418
|
+
const client = new Memory({
|
|
419
|
+
user: [
|
|
420
|
+
{ id: 1, name: 'Tan Tan' },
|
|
421
|
+
{ id: 2, name: 'Basuni' },
|
|
422
|
+
],
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
426
|
+
type: 'google-sheets',
|
|
427
|
+
client,
|
|
428
|
+
entities
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
await dataSource.initialize();
|
|
432
|
+
|
|
433
|
+
const repository = dataSource.getRepository(User);
|
|
434
|
+
|
|
435
|
+
const user = await repository.findOneBy({
|
|
436
|
+
id: 1,
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
if (!user)
|
|
440
|
+
{
|
|
441
|
+
throw new Error('User not found.');
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
await repository.remove(user);
|
|
445
|
+
|
|
446
|
+
const removed = await repository.findOneBy({
|
|
447
|
+
id: 1,
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
expect(removed).toBeNull();
|
|
451
|
+
|
|
452
|
+
const remaining = await repository.find();
|
|
453
|
+
|
|
454
|
+
expect(remaining).toEqual([
|
|
455
|
+
{
|
|
456
|
+
id: 2,
|
|
457
|
+
name: 'Basuni',
|
|
458
|
+
},
|
|
459
|
+
]);
|
|
460
|
+
|
|
461
|
+
await dataSource.destroy();
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
test('preloads an existing entity', async () =>
|
|
465
|
+
{
|
|
466
|
+
const client = new Memory({
|
|
467
|
+
user: [
|
|
468
|
+
{ id: 1, name: 'Tan Tan' },
|
|
469
|
+
{ id: 2, name: 'Basuni' },
|
|
470
|
+
],
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
474
|
+
type: 'google-sheets',
|
|
475
|
+
client,
|
|
476
|
+
entities
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
await dataSource.initialize();
|
|
480
|
+
|
|
481
|
+
const repository = dataSource.getRepository(User);
|
|
482
|
+
|
|
483
|
+
const user = await repository.preload({
|
|
484
|
+
id: 1,
|
|
485
|
+
name: 'Tan Tan Updated',
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
expect(user).toEqual({
|
|
489
|
+
id: 1,
|
|
490
|
+
name: 'Tan Tan Updated',
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
await dataSource.destroy();
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
test('returns undefined when preloading a non-existing entity', async () =>
|
|
497
|
+
{
|
|
498
|
+
const client = new Memory({
|
|
499
|
+
user: [
|
|
500
|
+
{ id: 1, name: 'Tan Tan' },
|
|
501
|
+
{ id: 2, name: 'Basuni' },
|
|
502
|
+
],
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
506
|
+
type: 'google-sheets',
|
|
507
|
+
client,
|
|
508
|
+
entities
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
await dataSource.initialize();
|
|
512
|
+
|
|
513
|
+
const repository = dataSource.getRepository(User);
|
|
514
|
+
|
|
515
|
+
const user = await repository.preload({
|
|
516
|
+
id: 999,
|
|
517
|
+
name: 'Budi',
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
expect(user).toBeUndefined();
|
|
521
|
+
|
|
522
|
+
await dataSource.destroy();
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
test('assigns generated id when saving a new entity', async () =>
|
|
526
|
+
{
|
|
527
|
+
const client = new Memory({
|
|
528
|
+
user: [
|
|
529
|
+
{ id: 1, name: 'Tan Tan' },
|
|
530
|
+
{ id: 2, name: 'Basuni' },
|
|
531
|
+
],
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
535
|
+
type: 'google-sheets',
|
|
536
|
+
client,
|
|
537
|
+
entities
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
await dataSource.initialize();
|
|
541
|
+
|
|
542
|
+
const repository = dataSource.getRepository(User);
|
|
543
|
+
|
|
544
|
+
const user = repository.create({
|
|
545
|
+
name: 'Andi',
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
await repository.save(user);
|
|
549
|
+
|
|
550
|
+
expect(user.id).toBe(3);
|
|
551
|
+
|
|
552
|
+
const saved = await repository.findOneBy({
|
|
553
|
+
id: 3,
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
expect(saved).toEqual({
|
|
557
|
+
id: 3,
|
|
558
|
+
name: 'Andi',
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
await dataSource.destroy();
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
test('assigns generated ids when saving multiple new entities', async () =>
|
|
565
|
+
{
|
|
566
|
+
const client = new Memory({
|
|
567
|
+
user: [
|
|
568
|
+
{ id: 1, name: 'Tan Tan' },
|
|
569
|
+
{ id: 2, name: 'Basuni' },
|
|
570
|
+
],
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
574
|
+
type: 'google-sheets',
|
|
575
|
+
client,
|
|
576
|
+
entities
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
await dataSource.initialize();
|
|
580
|
+
|
|
581
|
+
const repository = dataSource.getRepository(User);
|
|
582
|
+
|
|
583
|
+
const users = repository.create([
|
|
584
|
+
{
|
|
585
|
+
name: 'Andi',
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
name: 'Budi',
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
name: 'Citra',
|
|
592
|
+
},
|
|
593
|
+
]);
|
|
594
|
+
|
|
595
|
+
await repository.save(users);
|
|
596
|
+
|
|
597
|
+
expect(users[0]!.id).toBe(3);
|
|
598
|
+
expect(users[1]!.id).toBe(4);
|
|
599
|
+
expect(users[2]!.id).toBe(5);
|
|
600
|
+
|
|
601
|
+
const saved = await repository.find({
|
|
602
|
+
order: {
|
|
603
|
+
id: 'ASC',
|
|
604
|
+
},
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
expect(saved).toEqual([
|
|
608
|
+
{
|
|
609
|
+
id: 1,
|
|
610
|
+
name: 'Tan Tan',
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
id: 2,
|
|
614
|
+
name: 'Basuni',
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
id: 3,
|
|
618
|
+
name: 'Andi',
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
id: 4,
|
|
622
|
+
name: 'Budi',
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
id: 5,
|
|
626
|
+
name: 'Citra',
|
|
627
|
+
},
|
|
628
|
+
]);
|
|
629
|
+
|
|
630
|
+
await dataSource.destroy();
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
test('assigns generated ids when saving multiple new entities to an empty sheet', async () =>
|
|
634
|
+
{
|
|
635
|
+
const client = new Memory({
|
|
636
|
+
user: [],
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
640
|
+
type: 'google-sheets',
|
|
641
|
+
client,
|
|
642
|
+
entities
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
await dataSource.initialize();
|
|
646
|
+
|
|
647
|
+
const repository = dataSource.getRepository(User);
|
|
648
|
+
|
|
649
|
+
const users = repository.create([
|
|
650
|
+
{
|
|
651
|
+
name: 'Andi',
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
name: 'Budi',
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
name: 'Citra',
|
|
658
|
+
},
|
|
659
|
+
]);
|
|
660
|
+
|
|
661
|
+
await repository.save(users);
|
|
662
|
+
|
|
663
|
+
expect(users[0]!.id).toBe(1);
|
|
664
|
+
expect(users[1]!.id).toBe(2);
|
|
665
|
+
expect(users[2]!.id).toBe(3);
|
|
666
|
+
|
|
667
|
+
const saved = await repository.find({
|
|
668
|
+
order: {
|
|
669
|
+
id: 'ASC',
|
|
670
|
+
},
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
expect(saved).toEqual([
|
|
674
|
+
{
|
|
675
|
+
id: 1,
|
|
676
|
+
name: 'Andi',
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
id: 2,
|
|
680
|
+
name: 'Budi',
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
id: 3,
|
|
684
|
+
name: 'Citra',
|
|
685
|
+
},
|
|
686
|
+
]);
|
|
687
|
+
|
|
688
|
+
await dataSource.destroy();
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
test('assigns generated id based on the maximum existing id', async () =>
|
|
692
|
+
{
|
|
693
|
+
const client = new Memory({
|
|
694
|
+
user: [
|
|
695
|
+
{ id: 1, name: 'Tan Tan' },
|
|
696
|
+
{ id: 10, name: 'Basuni' },
|
|
697
|
+
{ id: 5, name: 'Citra' },
|
|
698
|
+
],
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
702
|
+
type: 'google-sheets',
|
|
703
|
+
client,
|
|
704
|
+
entities
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
await dataSource.initialize();
|
|
708
|
+
|
|
709
|
+
const repository = dataSource.getRepository(User);
|
|
710
|
+
|
|
711
|
+
const user = repository.create({
|
|
712
|
+
name: 'Andi',
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
await repository.save(user);
|
|
716
|
+
|
|
717
|
+
expect(user.id).toBe(11);
|
|
718
|
+
|
|
719
|
+
const saved = await repository.findOneBy({
|
|
720
|
+
id: 11,
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
expect(saved).toEqual({
|
|
724
|
+
id: 11,
|
|
725
|
+
name: 'Andi',
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
await dataSource.destroy();
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
test('returns affected rows when updating entities with query builder', async () =>
|
|
732
|
+
{
|
|
733
|
+
const client = new Memory({
|
|
734
|
+
user: [
|
|
735
|
+
{ id: 1, name: 'Tan Tan' },
|
|
736
|
+
{ id: 2, name: 'Basuni' },
|
|
737
|
+
{ id: 3, name: 'Tan Tan' },
|
|
738
|
+
],
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
742
|
+
type: 'google-sheets',
|
|
743
|
+
client,
|
|
744
|
+
entities
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
await dataSource.initialize();
|
|
748
|
+
|
|
749
|
+
const result = await dataSource
|
|
750
|
+
.createQueryBuilder()
|
|
751
|
+
.update(User)
|
|
752
|
+
.set({
|
|
753
|
+
name: 'Updated',
|
|
754
|
+
})
|
|
755
|
+
.where('id = :id', {
|
|
756
|
+
id: 1,
|
|
757
|
+
})
|
|
758
|
+
.execute();
|
|
759
|
+
|
|
760
|
+
expect(result.affected).toBe(1);
|
|
761
|
+
|
|
762
|
+
await dataSource.destroy();
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
test('returns zero affected rows when updating a non-existing entity', async () =>
|
|
766
|
+
{
|
|
767
|
+
const client = new Memory({
|
|
768
|
+
user: [
|
|
769
|
+
{ id: 1, name: 'Tan Tan' },
|
|
770
|
+
],
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
774
|
+
type: 'google-sheets',
|
|
775
|
+
client,
|
|
776
|
+
entities
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
await dataSource.initialize();
|
|
780
|
+
|
|
781
|
+
const result = await dataSource
|
|
782
|
+
.createQueryBuilder()
|
|
783
|
+
.update(User)
|
|
784
|
+
.set({
|
|
785
|
+
name: 'Updated',
|
|
786
|
+
})
|
|
787
|
+
.where('id = :id', {
|
|
788
|
+
id: 999,
|
|
789
|
+
})
|
|
790
|
+
.execute();
|
|
791
|
+
|
|
792
|
+
expect(result.affected).toBe(0);
|
|
793
|
+
|
|
794
|
+
await dataSource.destroy();
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
test('returns affected rows when deleting entities with query builder', async () =>
|
|
798
|
+
{
|
|
799
|
+
const client = new Memory({
|
|
800
|
+
user: [
|
|
801
|
+
{ id: 1, name: 'Tan Tan' },
|
|
802
|
+
{ id: 2, name: 'Basuni' },
|
|
803
|
+
{ id: 3, name: 'Citra' },
|
|
804
|
+
],
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
808
|
+
type: 'google-sheets',
|
|
809
|
+
client,
|
|
810
|
+
entities
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
await dataSource.initialize();
|
|
814
|
+
|
|
815
|
+
const result = await dataSource
|
|
816
|
+
.createQueryBuilder()
|
|
817
|
+
.delete()
|
|
818
|
+
.from(User)
|
|
819
|
+
.where('id = :id', {
|
|
820
|
+
id: 2,
|
|
821
|
+
})
|
|
822
|
+
.execute();
|
|
823
|
+
|
|
824
|
+
expect(result.affected).toBe(1);
|
|
825
|
+
|
|
826
|
+
await dataSource.destroy();
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
test('returns zero affected rows when deleting a non-existing entity', async () =>
|
|
830
|
+
{
|
|
831
|
+
const client = new Memory({
|
|
832
|
+
user: [
|
|
833
|
+
{ id: 1, name: 'Tan Tan' },
|
|
834
|
+
],
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
const dataSource = createGoogleSheetsDataSource({
|
|
838
|
+
type: 'google-sheets',
|
|
839
|
+
client,
|
|
840
|
+
entities
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
await dataSource.initialize();
|
|
844
|
+
|
|
845
|
+
const result = await dataSource
|
|
846
|
+
.createQueryBuilder()
|
|
847
|
+
.delete()
|
|
848
|
+
.from(User)
|
|
849
|
+
.where('id = :id', {
|
|
850
|
+
id: 999,
|
|
851
|
+
})
|
|
852
|
+
.execute();
|
|
853
|
+
|
|
854
|
+
expect(result.affected).toBe(0);
|
|
855
|
+
|
|
856
|
+
await dataSource.destroy();
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
test('assigns generated uuid when saving a new entity', async () =>
|
|
860
|
+
{
|
|
861
|
+
const client =
|
|
862
|
+
new Memory();
|
|
863
|
+
|
|
864
|
+
const dataSource =
|
|
865
|
+
createGoogleSheetsDataSource({
|
|
866
|
+
type: 'google-sheets',
|
|
867
|
+
client,
|
|
868
|
+
entities
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
await dataSource.initialize();
|
|
872
|
+
|
|
873
|
+
const user =
|
|
874
|
+
dataSource
|
|
875
|
+
.getRepository(UuidUser)
|
|
876
|
+
.create({
|
|
877
|
+
name: 'John',
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
await dataSource
|
|
881
|
+
.getRepository(UuidUser)
|
|
882
|
+
.save(user);
|
|
883
|
+
|
|
884
|
+
expect(user.id)
|
|
885
|
+
.toBeString();
|
|
886
|
+
|
|
887
|
+
expect(user.id.length)
|
|
888
|
+
.toBe(36);
|
|
889
|
+
|
|
890
|
+
expect(
|
|
891
|
+
user.id,
|
|
892
|
+
).toMatch(
|
|
893
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,
|
|
894
|
+
);
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
test('rejects generated identity when saving a new entity', async () =>
|
|
898
|
+
{
|
|
899
|
+
const client =
|
|
900
|
+
new Memory();
|
|
901
|
+
|
|
902
|
+
const dataSource =
|
|
903
|
+
createGoogleSheetsDataSource({
|
|
904
|
+
type: 'google-sheets',
|
|
905
|
+
client,
|
|
906
|
+
entities
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
await dataSource.initialize();
|
|
910
|
+
|
|
911
|
+
const user =
|
|
912
|
+
dataSource
|
|
913
|
+
.getRepository(IdentityUser)
|
|
914
|
+
.create({
|
|
915
|
+
name: 'John',
|
|
916
|
+
});
|
|
917
|
+
|
|
918
|
+
await expect(
|
|
919
|
+
dataSource
|
|
920
|
+
.getRepository(IdentityUser)
|
|
921
|
+
.save(user),
|
|
922
|
+
).rejects.toThrow(
|
|
923
|
+
'PrimaryGeneratedColumn("identity") is not supported by Google Sheets driver.',
|
|
924
|
+
);
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
test('rejects generated rowid when saving a new entity', async () =>
|
|
928
|
+
{
|
|
929
|
+
const client =
|
|
930
|
+
new Memory();
|
|
931
|
+
|
|
932
|
+
const dataSource =
|
|
933
|
+
createGoogleSheetsDataSource({
|
|
934
|
+
type: 'google-sheets',
|
|
935
|
+
client,
|
|
936
|
+
entities
|
|
937
|
+
});
|
|
938
|
+
|
|
939
|
+
await dataSource.initialize();
|
|
940
|
+
|
|
941
|
+
const user =
|
|
942
|
+
dataSource
|
|
943
|
+
.getRepository(RowidUser)
|
|
944
|
+
.create({
|
|
945
|
+
name: 'John',
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
await expect(
|
|
949
|
+
dataSource
|
|
950
|
+
.getRepository(RowidUser)
|
|
951
|
+
.save(user),
|
|
952
|
+
).rejects.toThrow(
|
|
953
|
+
'PrimaryGeneratedColumn("rowid") is not supported by Google Sheets driver.',
|
|
954
|
+
);
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
test('saves ManyToOne relation', async () =>
|
|
958
|
+
{
|
|
959
|
+
const client =
|
|
960
|
+
new Memory({
|
|
961
|
+
user: [
|
|
962
|
+
{
|
|
963
|
+
id: 1,
|
|
964
|
+
name: 'Basuni',
|
|
965
|
+
},
|
|
966
|
+
],
|
|
967
|
+
post: [],
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
const dataSource =
|
|
971
|
+
createGoogleSheetsDataSource({
|
|
972
|
+
type: 'google-sheets',
|
|
973
|
+
client,
|
|
974
|
+
entities
|
|
975
|
+
});
|
|
976
|
+
|
|
977
|
+
await dataSource.initialize();
|
|
978
|
+
|
|
979
|
+
const userRepository =
|
|
980
|
+
dataSource.getRepository(User);
|
|
981
|
+
|
|
982
|
+
const postRepository =
|
|
983
|
+
dataSource.getRepository(Post);
|
|
984
|
+
|
|
985
|
+
const user =
|
|
986
|
+
await userRepository.findOneBy({
|
|
987
|
+
id: 1,
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
expect(user).not.toBeNull();
|
|
991
|
+
|
|
992
|
+
if (!user)
|
|
993
|
+
{
|
|
994
|
+
throw new Error(
|
|
995
|
+
'User not found.',
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
const post =
|
|
1000
|
+
postRepository.create({
|
|
1001
|
+
title: 'New Post',
|
|
1002
|
+
user,
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
await postRepository.save(post);
|
|
1006
|
+
|
|
1007
|
+
expect(post.id).toBeDefined();
|
|
1008
|
+
expect(post.title).toBe('New Post');
|
|
1009
|
+
expect(post.userId).toBe(1);
|
|
1010
|
+
|
|
1011
|
+
const saved =
|
|
1012
|
+
await postRepository.findOneBy({
|
|
1013
|
+
id: post.id,
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1016
|
+
expect(saved).toMatchObject({
|
|
1017
|
+
id: post.id,
|
|
1018
|
+
title: 'New Post',
|
|
1019
|
+
userId: 1,
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
await dataSource.destroy();
|
|
1023
|
+
});
|
|
1024
|
+
|
|
1025
|
+
test('saves multiple ManyToOne relations', async () =>
|
|
1026
|
+
{
|
|
1027
|
+
const client =
|
|
1028
|
+
new Memory({
|
|
1029
|
+
user: [
|
|
1030
|
+
{
|
|
1031
|
+
id: 1,
|
|
1032
|
+
name: 'Basuni',
|
|
1033
|
+
},
|
|
1034
|
+
],
|
|
1035
|
+
category: [
|
|
1036
|
+
{
|
|
1037
|
+
id: 1,
|
|
1038
|
+
name: 'Technology',
|
|
1039
|
+
},
|
|
1040
|
+
],
|
|
1041
|
+
post: [],
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1044
|
+
const dataSource =
|
|
1045
|
+
createGoogleSheetsDataSource({
|
|
1046
|
+
type: 'google-sheets',
|
|
1047
|
+
client,
|
|
1048
|
+
entities,
|
|
1049
|
+
});
|
|
1050
|
+
|
|
1051
|
+
await dataSource.initialize();
|
|
1052
|
+
|
|
1053
|
+
const userRepository =
|
|
1054
|
+
dataSource.getRepository(User);
|
|
1055
|
+
|
|
1056
|
+
const categoryRepository =
|
|
1057
|
+
dataSource.getRepository(Category);
|
|
1058
|
+
|
|
1059
|
+
const postRepository =
|
|
1060
|
+
dataSource.getRepository(Post);
|
|
1061
|
+
|
|
1062
|
+
const user =
|
|
1063
|
+
await userRepository.findOneBy({
|
|
1064
|
+
id: 1,
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
const category =
|
|
1068
|
+
await categoryRepository.findOneBy({
|
|
1069
|
+
id: 1,
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
expect(user).not.toBeNull();
|
|
1073
|
+
expect(category).not.toBeNull();
|
|
1074
|
+
|
|
1075
|
+
if (!user || !category)
|
|
1076
|
+
{
|
|
1077
|
+
throw new Error(
|
|
1078
|
+
'Relation entity not found.',
|
|
1079
|
+
);
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
const post =
|
|
1083
|
+
postRepository.create({
|
|
1084
|
+
title: 'New Post',
|
|
1085
|
+
user,
|
|
1086
|
+
category,
|
|
1087
|
+
});
|
|
1088
|
+
|
|
1089
|
+
await postRepository.save(post);
|
|
1090
|
+
|
|
1091
|
+
expect(post.id).toBeDefined();
|
|
1092
|
+
expect(post.title).toBe('New Post');
|
|
1093
|
+
expect(post.userId).toBe(1);
|
|
1094
|
+
expect(post.categoryId).toBe(1);
|
|
1095
|
+
|
|
1096
|
+
const saved =
|
|
1097
|
+
await postRepository.findOneBy({
|
|
1098
|
+
id: post.id,
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1101
|
+
expect(saved).toMatchObject({
|
|
1102
|
+
id: post.id,
|
|
1103
|
+
title: 'New Post',
|
|
1104
|
+
userId: 1,
|
|
1105
|
+
categoryId: 1,
|
|
1106
|
+
});
|
|
1107
|
+
|
|
1108
|
+
await dataSource.destroy();
|
|
1109
|
+
});
|
|
1110
|
+
|
|
1111
|
+
test('saves ManyToMany relation', async () =>
|
|
1112
|
+
{
|
|
1113
|
+
const client =
|
|
1114
|
+
new Memory({
|
|
1115
|
+
user: [],
|
|
1116
|
+
role: [
|
|
1117
|
+
{
|
|
1118
|
+
id: 1,
|
|
1119
|
+
name: 'Admin',
|
|
1120
|
+
},
|
|
1121
|
+
{
|
|
1122
|
+
id: 2,
|
|
1123
|
+
name: 'Developer',
|
|
1124
|
+
},
|
|
1125
|
+
],
|
|
1126
|
+
user_role: [],
|
|
1127
|
+
});
|
|
1128
|
+
|
|
1129
|
+
const dataSource =
|
|
1130
|
+
createGoogleSheetsDataSource({
|
|
1131
|
+
type: 'google-sheets',
|
|
1132
|
+
client,
|
|
1133
|
+
entities: [
|
|
1134
|
+
User,
|
|
1135
|
+
Role,
|
|
1136
|
+
],
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
await dataSource.initialize();
|
|
1140
|
+
|
|
1141
|
+
const userRepository =
|
|
1142
|
+
dataSource.getRepository(User);
|
|
1143
|
+
|
|
1144
|
+
const roleRepository =
|
|
1145
|
+
dataSource.getRepository(Role);
|
|
1146
|
+
|
|
1147
|
+
const admin =
|
|
1148
|
+
await roleRepository.findOneBy({
|
|
1149
|
+
id: 1,
|
|
1150
|
+
});
|
|
1151
|
+
|
|
1152
|
+
const developer =
|
|
1153
|
+
await roleRepository.findOneBy({
|
|
1154
|
+
id: 2,
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
expect(admin).not.toBeNull();
|
|
1158
|
+
expect(developer).not.toBeNull();
|
|
1159
|
+
|
|
1160
|
+
if (!admin || !developer)
|
|
1161
|
+
{
|
|
1162
|
+
throw new Error(
|
|
1163
|
+
'Role not found.',
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
const user =
|
|
1168
|
+
userRepository.create({
|
|
1169
|
+
name: 'Basuni',
|
|
1170
|
+
roles: [
|
|
1171
|
+
admin,
|
|
1172
|
+
developer,
|
|
1173
|
+
],
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
await userRepository.save(user);
|
|
1177
|
+
|
|
1178
|
+
expect(user.id).toBeDefined();
|
|
1179
|
+
expect(user.name).toBe('Basuni');
|
|
1180
|
+
|
|
1181
|
+
const saved =
|
|
1182
|
+
await userRepository
|
|
1183
|
+
.createQueryBuilder('user')
|
|
1184
|
+
.leftJoinAndSelect(
|
|
1185
|
+
'user.roles',
|
|
1186
|
+
'role',
|
|
1187
|
+
)
|
|
1188
|
+
.where(
|
|
1189
|
+
'user.id = :id',
|
|
1190
|
+
{
|
|
1191
|
+
id: user.id,
|
|
1192
|
+
},
|
|
1193
|
+
)
|
|
1194
|
+
.getOne();
|
|
1195
|
+
|
|
1196
|
+
expect(saved).toMatchObject({
|
|
1197
|
+
id: user.id,
|
|
1198
|
+
name: 'Basuni',
|
|
1199
|
+
roles: [
|
|
1200
|
+
{
|
|
1201
|
+
id: 1,
|
|
1202
|
+
name: 'Admin',
|
|
1203
|
+
},
|
|
1204
|
+
{
|
|
1205
|
+
id: 2,
|
|
1206
|
+
name: 'Developer',
|
|
1207
|
+
},
|
|
1208
|
+
],
|
|
1209
|
+
});
|
|
1210
|
+
|
|
1211
|
+
await dataSource.destroy();
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1214
|
+
test('updates ManyToMany relation', async () =>
|
|
1215
|
+
{
|
|
1216
|
+
const client =
|
|
1217
|
+
new Memory({
|
|
1218
|
+
user: [
|
|
1219
|
+
{
|
|
1220
|
+
id: 1,
|
|
1221
|
+
name: 'Basuni',
|
|
1222
|
+
},
|
|
1223
|
+
],
|
|
1224
|
+
role: [
|
|
1225
|
+
{
|
|
1226
|
+
id: 1,
|
|
1227
|
+
name: 'Admin',
|
|
1228
|
+
},
|
|
1229
|
+
{
|
|
1230
|
+
id: 2,
|
|
1231
|
+
name: 'Developer',
|
|
1232
|
+
},
|
|
1233
|
+
],
|
|
1234
|
+
user_role: [
|
|
1235
|
+
{
|
|
1236
|
+
userId: 1,
|
|
1237
|
+
roleId: 1,
|
|
1238
|
+
},
|
|
1239
|
+
{
|
|
1240
|
+
userId: 1,
|
|
1241
|
+
roleId: 2,
|
|
1242
|
+
},
|
|
1243
|
+
],
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
const dataSource =
|
|
1247
|
+
createGoogleSheetsDataSource({
|
|
1248
|
+
type: 'google-sheets',
|
|
1249
|
+
client,
|
|
1250
|
+
entities: [
|
|
1251
|
+
User,
|
|
1252
|
+
Role,
|
|
1253
|
+
],
|
|
1254
|
+
});
|
|
1255
|
+
|
|
1256
|
+
await dataSource.initialize();
|
|
1257
|
+
|
|
1258
|
+
const userRepository =
|
|
1259
|
+
dataSource.getRepository(User);
|
|
1260
|
+
|
|
1261
|
+
const roleRepository =
|
|
1262
|
+
dataSource.getRepository(Role);
|
|
1263
|
+
|
|
1264
|
+
const user =
|
|
1265
|
+
await userRepository.findOne({
|
|
1266
|
+
where: {
|
|
1267
|
+
id: 1,
|
|
1268
|
+
},
|
|
1269
|
+
relations: {
|
|
1270
|
+
roles: true,
|
|
1271
|
+
},
|
|
1272
|
+
});
|
|
1273
|
+
|
|
1274
|
+
const developer =
|
|
1275
|
+
await roleRepository.findOneBy({
|
|
1276
|
+
id: 2,
|
|
1277
|
+
});
|
|
1278
|
+
|
|
1279
|
+
expect(user).not.toBeNull();
|
|
1280
|
+
expect(developer).not.toBeNull();
|
|
1281
|
+
|
|
1282
|
+
if (!user || !developer)
|
|
1283
|
+
{
|
|
1284
|
+
throw new Error(
|
|
1285
|
+
'User or role not found.',
|
|
1286
|
+
);
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
user.roles = [
|
|
1290
|
+
developer,
|
|
1291
|
+
];
|
|
1292
|
+
|
|
1293
|
+
await userRepository.save(user);
|
|
1294
|
+
|
|
1295
|
+
const saved =
|
|
1296
|
+
await userRepository.findOne({
|
|
1297
|
+
where: {
|
|
1298
|
+
id: 1,
|
|
1299
|
+
},
|
|
1300
|
+
relations: {
|
|
1301
|
+
roles: true,
|
|
1302
|
+
},
|
|
1303
|
+
});
|
|
1304
|
+
|
|
1305
|
+
expect(saved).toMatchObject({
|
|
1306
|
+
id: 1,
|
|
1307
|
+
name: 'Basuni',
|
|
1308
|
+
roles: [
|
|
1309
|
+
{
|
|
1310
|
+
id: 2,
|
|
1311
|
+
name: 'Developer',
|
|
1312
|
+
},
|
|
1313
|
+
],
|
|
1314
|
+
});
|
|
1315
|
+
|
|
1316
|
+
const junctionRows =
|
|
1317
|
+
await client.getRows(
|
|
1318
|
+
'user_role',
|
|
1319
|
+
);
|
|
1320
|
+
|
|
1321
|
+
expect(junctionRows).toEqual([
|
|
1322
|
+
{
|
|
1323
|
+
userId: 1,
|
|
1324
|
+
roleId: 2,
|
|
1325
|
+
},
|
|
1326
|
+
]);
|
|
1327
|
+
|
|
1328
|
+
await dataSource.destroy();
|
|
1329
|
+
});
|
|
1330
|
+
|
|
1331
|
+
test('removes ManyToMany relations', async () =>
|
|
1332
|
+
{
|
|
1333
|
+
const client =
|
|
1334
|
+
new Memory({
|
|
1335
|
+
user: [
|
|
1336
|
+
{
|
|
1337
|
+
id: 1,
|
|
1338
|
+
name: 'Basuni',
|
|
1339
|
+
},
|
|
1340
|
+
],
|
|
1341
|
+
role: [
|
|
1342
|
+
{
|
|
1343
|
+
id: 1,
|
|
1344
|
+
name: 'Admin',
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
id: 2,
|
|
1348
|
+
name: 'Developer',
|
|
1349
|
+
},
|
|
1350
|
+
],
|
|
1351
|
+
user_role: [
|
|
1352
|
+
{
|
|
1353
|
+
userId: 1,
|
|
1354
|
+
roleId: 1,
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
userId: 1,
|
|
1358
|
+
roleId: 2,
|
|
1359
|
+
},
|
|
1360
|
+
],
|
|
1361
|
+
});
|
|
1362
|
+
|
|
1363
|
+
const dataSource =
|
|
1364
|
+
createGoogleSheetsDataSource({
|
|
1365
|
+
type: 'google-sheets',
|
|
1366
|
+
client,
|
|
1367
|
+
entities: [
|
|
1368
|
+
User,
|
|
1369
|
+
Role,
|
|
1370
|
+
],
|
|
1371
|
+
});
|
|
1372
|
+
|
|
1373
|
+
await dataSource.initialize();
|
|
1374
|
+
|
|
1375
|
+
const userRepository =
|
|
1376
|
+
dataSource.getRepository(User);
|
|
1377
|
+
|
|
1378
|
+
const user =
|
|
1379
|
+
await userRepository.findOne({
|
|
1380
|
+
where: {
|
|
1381
|
+
id: 1,
|
|
1382
|
+
},
|
|
1383
|
+
relations: {
|
|
1384
|
+
roles: true,
|
|
1385
|
+
},
|
|
1386
|
+
});
|
|
1387
|
+
|
|
1388
|
+
expect(user).not.toBeNull();
|
|
1389
|
+
|
|
1390
|
+
if (!user)
|
|
1391
|
+
{
|
|
1392
|
+
throw new Error(
|
|
1393
|
+
'User not found.',
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
expect(user.roles).toHaveLength(2);
|
|
1398
|
+
|
|
1399
|
+
user.roles = [];
|
|
1400
|
+
|
|
1401
|
+
await userRepository.save(user);
|
|
1402
|
+
|
|
1403
|
+
const saved =
|
|
1404
|
+
await userRepository.findOne({
|
|
1405
|
+
where: {
|
|
1406
|
+
id: 1,
|
|
1407
|
+
},
|
|
1408
|
+
relations: {
|
|
1409
|
+
roles: true,
|
|
1410
|
+
},
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
expect(saved).toMatchObject({
|
|
1414
|
+
id: 1,
|
|
1415
|
+
name: 'Basuni',
|
|
1416
|
+
roles: [],
|
|
1417
|
+
});
|
|
1418
|
+
|
|
1419
|
+
const junctionRows =
|
|
1420
|
+
await client.getRows(
|
|
1421
|
+
'user_role',
|
|
1422
|
+
);
|
|
1423
|
+
|
|
1424
|
+
expect(junctionRows).toEqual([]);
|
|
1425
|
+
|
|
1426
|
+
await dataSource.destroy();
|
|
1427
|
+
});
|
|
1428
|
+
|
|
1429
|
+
test('replaces ManyToMany relations', async () =>
|
|
1430
|
+
{
|
|
1431
|
+
const client =
|
|
1432
|
+
new Memory({
|
|
1433
|
+
user: [
|
|
1434
|
+
{
|
|
1435
|
+
id: 1,
|
|
1436
|
+
name: 'Basuni',
|
|
1437
|
+
},
|
|
1438
|
+
],
|
|
1439
|
+
role: [
|
|
1440
|
+
{
|
|
1441
|
+
id: 1,
|
|
1442
|
+
name: 'Admin',
|
|
1443
|
+
},
|
|
1444
|
+
{
|
|
1445
|
+
id: 2,
|
|
1446
|
+
name: 'Developer',
|
|
1447
|
+
},
|
|
1448
|
+
{
|
|
1449
|
+
id: 3,
|
|
1450
|
+
name: 'Manager',
|
|
1451
|
+
},
|
|
1452
|
+
],
|
|
1453
|
+
user_role: [
|
|
1454
|
+
{
|
|
1455
|
+
userId: 1,
|
|
1456
|
+
roleId: 1,
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
userId: 1,
|
|
1460
|
+
roleId: 2,
|
|
1461
|
+
},
|
|
1462
|
+
],
|
|
1463
|
+
});
|
|
1464
|
+
|
|
1465
|
+
const dataSource =
|
|
1466
|
+
createGoogleSheetsDataSource({
|
|
1467
|
+
type: 'google-sheets',
|
|
1468
|
+
client,
|
|
1469
|
+
entities: [
|
|
1470
|
+
User,
|
|
1471
|
+
Role,
|
|
1472
|
+
],
|
|
1473
|
+
});
|
|
1474
|
+
|
|
1475
|
+
await dataSource.initialize();
|
|
1476
|
+
|
|
1477
|
+
const userRepository =
|
|
1478
|
+
dataSource.getRepository(User);
|
|
1479
|
+
|
|
1480
|
+
const roleRepository =
|
|
1481
|
+
dataSource.getRepository(Role);
|
|
1482
|
+
|
|
1483
|
+
const user =
|
|
1484
|
+
await userRepository.findOne({
|
|
1485
|
+
where: {
|
|
1486
|
+
id: 1,
|
|
1487
|
+
},
|
|
1488
|
+
relations: {
|
|
1489
|
+
roles: true,
|
|
1490
|
+
},
|
|
1491
|
+
});
|
|
1492
|
+
|
|
1493
|
+
const developer =
|
|
1494
|
+
await roleRepository.findOneBy({
|
|
1495
|
+
id: 2,
|
|
1496
|
+
});
|
|
1497
|
+
|
|
1498
|
+
const manager =
|
|
1499
|
+
await roleRepository.findOneBy({
|
|
1500
|
+
id: 3,
|
|
1501
|
+
});
|
|
1502
|
+
|
|
1503
|
+
expect(user).not.toBeNull();
|
|
1504
|
+
expect(developer).not.toBeNull();
|
|
1505
|
+
expect(manager).not.toBeNull();
|
|
1506
|
+
|
|
1507
|
+
if (!user || !developer || !manager)
|
|
1508
|
+
{
|
|
1509
|
+
throw new Error(
|
|
1510
|
+
'User or role not found.',
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
expect(user.roles).toHaveLength(2);
|
|
1515
|
+
|
|
1516
|
+
user.roles = [
|
|
1517
|
+
developer,
|
|
1518
|
+
manager,
|
|
1519
|
+
];
|
|
1520
|
+
|
|
1521
|
+
await userRepository.save(user);
|
|
1522
|
+
|
|
1523
|
+
const saved =
|
|
1524
|
+
await userRepository.findOne({
|
|
1525
|
+
where: {
|
|
1526
|
+
id: 1,
|
|
1527
|
+
},
|
|
1528
|
+
relations: {
|
|
1529
|
+
roles: true,
|
|
1530
|
+
},
|
|
1531
|
+
});
|
|
1532
|
+
|
|
1533
|
+
expect(saved).toMatchObject({
|
|
1534
|
+
id: 1,
|
|
1535
|
+
name: 'Basuni',
|
|
1536
|
+
roles: [
|
|
1537
|
+
{
|
|
1538
|
+
id: 2,
|
|
1539
|
+
name: 'Developer',
|
|
1540
|
+
},
|
|
1541
|
+
{
|
|
1542
|
+
id: 3,
|
|
1543
|
+
name: 'Manager',
|
|
1544
|
+
},
|
|
1545
|
+
],
|
|
1546
|
+
});
|
|
1547
|
+
|
|
1548
|
+
const junctionRows =
|
|
1549
|
+
await client.getRows(
|
|
1550
|
+
'user_role',
|
|
1551
|
+
);
|
|
1552
|
+
|
|
1553
|
+
expect(junctionRows).toEqual([
|
|
1554
|
+
{
|
|
1555
|
+
userId: 1,
|
|
1556
|
+
roleId: 2,
|
|
1557
|
+
},
|
|
1558
|
+
{
|
|
1559
|
+
userId: 1,
|
|
1560
|
+
roleId: 3,
|
|
1561
|
+
},
|
|
1562
|
+
]);
|
|
1563
|
+
|
|
1564
|
+
await dataSource.destroy();
|
|
1565
|
+
});
|
|
1566
|
+
});
|