@aneuhold/be-ts-db-lib 1.0.114 → 2.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.
Files changed (150) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +46 -10
  3. package/lib/index.d.ts +8 -8
  4. package/lib/index.d.ts.map +1 -1
  5. package/lib/index.js +10 -20
  6. package/lib/index.js.map +1 -0
  7. package/lib/index.ts +21 -0
  8. package/lib/repositories/BaseRepository.d.ts +84 -11
  9. package/lib/repositories/BaseRepository.d.ts.map +1 -1
  10. package/lib/repositories/BaseRepository.js +89 -21
  11. package/lib/repositories/BaseRepository.js.map +1 -0
  12. package/lib/repositories/BaseRepository.ts +339 -0
  13. package/lib/repositories/common/ApiKeyRepository.d.ts +2 -2
  14. package/lib/repositories/common/ApiKeyRepository.d.ts.map +1 -1
  15. package/lib/repositories/common/ApiKeyRepository.js +8 -13
  16. package/lib/repositories/common/ApiKeyRepository.js.map +1 -0
  17. package/lib/repositories/common/ApiKeyRepository.ts +55 -0
  18. package/lib/repositories/common/UserRepository.d.ts +1 -1
  19. package/lib/repositories/common/UserRepository.d.ts.map +1 -1
  20. package/lib/repositories/common/UserRepository.js +15 -20
  21. package/lib/repositories/common/UserRepository.js.map +1 -0
  22. package/lib/repositories/common/UserRepository.ts +65 -0
  23. package/lib/repositories/dashboard/DashboardBaseRepository.d.ts +2 -2
  24. package/lib/repositories/dashboard/DashboardBaseRepository.d.ts.map +1 -1
  25. package/lib/repositories/dashboard/DashboardBaseRepository.js +6 -11
  26. package/lib/repositories/dashboard/DashboardBaseRepository.js.map +1 -0
  27. package/lib/repositories/dashboard/DashboardBaseRepository.ts +31 -0
  28. package/lib/repositories/dashboard/DashboardNonogramKatanaItemRepository.d.ts +2 -2
  29. package/lib/repositories/dashboard/DashboardNonogramKatanaItemRepository.d.ts.map +1 -1
  30. package/lib/repositories/dashboard/DashboardNonogramKatanaItemRepository.js +7 -12
  31. package/lib/repositories/dashboard/DashboardNonogramKatanaItemRepository.js.map +1 -0
  32. package/lib/repositories/dashboard/DashboardNonogramKatanaItemRepository.ts +64 -0
  33. package/lib/repositories/dashboard/DashboardNonogramKatanaUpgradeRepository.d.ts +2 -2
  34. package/lib/repositories/dashboard/DashboardNonogramKatanaUpgradeRepository.d.ts.map +1 -1
  35. package/lib/repositories/dashboard/DashboardNonogramKatanaUpgradeRepository.js +7 -12
  36. package/lib/repositories/dashboard/DashboardNonogramKatanaUpgradeRepository.js.map +1 -0
  37. package/lib/repositories/dashboard/DashboardNonogramKatanaUpgradeRepository.ts +66 -0
  38. package/lib/repositories/dashboard/DashboardTaskRepository.d.ts +17 -4
  39. package/lib/repositories/dashboard/DashboardTaskRepository.d.ts.map +1 -1
  40. package/lib/repositories/dashboard/DashboardTaskRepository.js +26 -18
  41. package/lib/repositories/dashboard/DashboardTaskRepository.js.map +1 -0
  42. package/lib/repositories/dashboard/DashboardTaskRepository.ts +166 -0
  43. package/lib/repositories/dashboard/DashboardUserConfigRepository.d.ts +29 -5
  44. package/lib/repositories/dashboard/DashboardUserConfigRepository.d.ts.map +1 -1
  45. package/lib/repositories/dashboard/DashboardUserConfigRepository.js +38 -19
  46. package/lib/repositories/dashboard/DashboardUserConfigRepository.js.map +1 -0
  47. package/lib/repositories/dashboard/DashboardUserConfigRepository.ts +254 -0
  48. package/lib/services/MigrationService.d.ts.map +1 -1
  49. package/lib/services/MigrationService.js +10 -15
  50. package/lib/services/MigrationService.js.map +1 -0
  51. package/lib/services/MigrationService.ts +52 -0
  52. package/lib/services/RepoSubscriptionService.d.ts.map +1 -1
  53. package/lib/services/RepoSubscriptionService.js +2 -4
  54. package/lib/services/RepoSubscriptionService.js.map +1 -0
  55. package/lib/services/RepoSubscriptionService.ts +63 -0
  56. package/lib/tests/globalTestVariables.d.ts +5 -0
  57. package/lib/tests/globalTestVariables.d.ts.map +1 -0
  58. package/lib/tests/globalTestVariables.js +5 -0
  59. package/lib/tests/globalTestVariables.js.map +1 -0
  60. package/lib/tests/globalTestVariables.ts +4 -0
  61. package/lib/tests/repositories/BaseRepository.spec.ts +61 -0
  62. package/lib/tests/repositories/common/UserRepository.spec.ts +113 -0
  63. package/lib/tests/repositories/dashboard/NonogramKatanaItemRepository.spec.ts +55 -0
  64. package/lib/tests/repositories/dashboard/NonogramKatanaUpgradeRepository.spec.ts +14 -0
  65. package/lib/tests/repositories/dashboard/TaskRepository.spec.ts +101 -0
  66. package/lib/tests/repositories/dashboard/UserConfigRepository.spec.ts +155 -0
  67. package/lib/tests/testsUtil.d.ts +20 -4
  68. package/lib/tests/testsUtil.d.ts.map +1 -1
  69. package/lib/tests/testsUtil.js +29 -20
  70. package/lib/tests/testsUtil.js.map +1 -0
  71. package/lib/tests/testsUtil.ts +68 -0
  72. package/lib/util/DbSchemaUpdater.d.ts.map +1 -1
  73. package/lib/util/DbSchemaUpdater.js +10 -15
  74. package/lib/util/DbSchemaUpdater.js.map +1 -0
  75. package/lib/util/DbSchemaUpdater.ts +16 -0
  76. package/lib/util/DocumentCleaner.d.ts.map +1 -1
  77. package/lib/util/DocumentCleaner.js +2 -4
  78. package/lib/util/DocumentCleaner.js.map +1 -0
  79. package/lib/util/DocumentCleaner.ts +31 -0
  80. package/lib/util/DocumentDb.d.ts +4 -1
  81. package/lib/util/DocumentDb.d.ts.map +1 -1
  82. package/lib/util/DocumentDb.js +11 -10
  83. package/lib/util/DocumentDb.js.map +1 -0
  84. package/lib/util/DocumentDb.ts +47 -0
  85. package/lib/validators/BaseValidator.d.ts +11 -0
  86. package/lib/validators/BaseValidator.d.ts.map +1 -1
  87. package/lib/validators/BaseValidator.js +26 -18
  88. package/lib/validators/BaseValidator.js.map +1 -0
  89. package/lib/validators/BaseValidator.ts +150 -0
  90. package/lib/validators/common/ApiKeyValidator.d.ts +1 -1
  91. package/lib/validators/common/ApiKeyValidator.d.ts.map +1 -1
  92. package/lib/validators/common/ApiKeyValidator.js +16 -21
  93. package/lib/validators/common/ApiKeyValidator.js.map +1 -0
  94. package/lib/validators/common/ApiKeyValidator.ts +67 -0
  95. package/lib/validators/common/UserValidator.d.ts +14 -1
  96. package/lib/validators/common/UserValidator.d.ts.map +1 -1
  97. package/lib/validators/common/UserValidator.js +29 -21
  98. package/lib/validators/common/UserValidator.js.map +1 -0
  99. package/lib/validators/common/UserValidator.ts +98 -0
  100. package/lib/validators/dashboard/NonogramKatanaItemValidator.d.ts +1 -1
  101. package/lib/validators/dashboard/NonogramKatanaItemValidator.d.ts.map +1 -1
  102. package/lib/validators/dashboard/NonogramKatanaItemValidator.js +16 -21
  103. package/lib/validators/dashboard/NonogramKatanaItemValidator.js.map +1 -0
  104. package/lib/validators/dashboard/NonogramKatanaItemValidator.ts +78 -0
  105. package/lib/validators/dashboard/NonogramKatanaUpgradeValidator.d.ts +1 -1
  106. package/lib/validators/dashboard/NonogramKatanaUpgradeValidator.d.ts.map +1 -1
  107. package/lib/validators/dashboard/NonogramKatanaUpgradeValidator.js +16 -21
  108. package/lib/validators/dashboard/NonogramKatanaUpgradeValidator.js.map +1 -0
  109. package/lib/validators/dashboard/NonogramKatanaUpgradeValidator.ts +78 -0
  110. package/lib/validators/dashboard/TaskValidator.d.ts +1 -1
  111. package/lib/validators/dashboard/TaskValidator.d.ts.map +1 -1
  112. package/lib/validators/dashboard/TaskValidator.js +15 -20
  113. package/lib/validators/dashboard/TaskValidator.js.map +1 -0
  114. package/lib/validators/dashboard/TaskValidator.ts +105 -0
  115. package/lib/validators/dashboard/UserConfigValidator.d.ts +1 -1
  116. package/lib/validators/dashboard/UserConfigValidator.d.ts.map +1 -1
  117. package/lib/validators/dashboard/UserConfigValidator.js +19 -24
  118. package/lib/validators/dashboard/UserConfigValidator.js.map +1 -0
  119. package/lib/validators/dashboard/UserConfigValidator.ts +112 -0
  120. package/package.json +44 -38
  121. package/lib/scripts/migrate.d.ts +0 -2
  122. package/lib/scripts/migrate.d.ts.map +0 -1
  123. package/lib/scripts/migrate.js +0 -7
  124. package/lib/scripts/migrateDry.d.ts +0 -2
  125. package/lib/scripts/migrateDry.d.ts.map +0 -1
  126. package/lib/scripts/migrateDry.js +0 -7
  127. package/lib/scripts/validateSchema.d.ts +0 -2
  128. package/lib/scripts/validateSchema.d.ts.map +0 -1
  129. package/lib/scripts/validateSchema.js +0 -9
  130. package/lib/scripts/validateSchemaDryRun.d.ts +0 -2
  131. package/lib/scripts/validateSchemaDryRun.d.ts.map +0 -1
  132. package/lib/scripts/validateSchemaDryRun.js +0 -9
  133. package/lib/tests/repositories/BaseRepository.spec.d.ts +0 -2
  134. package/lib/tests/repositories/BaseRepository.spec.d.ts.map +0 -1
  135. package/lib/tests/repositories/BaseRepository.spec.js +0 -52
  136. package/lib/tests/repositories/common/UserRepository.spec.d.ts +0 -2
  137. package/lib/tests/repositories/common/UserRepository.spec.d.ts.map +0 -1
  138. package/lib/tests/repositories/common/UserRepository.spec.js +0 -108
  139. package/lib/tests/repositories/dashboard/NonogramKatanaItemRepository.spec.d.ts +0 -2
  140. package/lib/tests/repositories/dashboard/NonogramKatanaItemRepository.spec.d.ts.map +0 -1
  141. package/lib/tests/repositories/dashboard/NonogramKatanaItemRepository.spec.js +0 -39
  142. package/lib/tests/repositories/dashboard/NonogramKatanaUpgradeRepository.spec.d.ts +0 -2
  143. package/lib/tests/repositories/dashboard/NonogramKatanaUpgradeRepository.spec.d.ts.map +0 -1
  144. package/lib/tests/repositories/dashboard/NonogramKatanaUpgradeRepository.spec.js +0 -16
  145. package/lib/tests/repositories/dashboard/TaskRepository.spec.d.ts +0 -2
  146. package/lib/tests/repositories/dashboard/TaskRepository.spec.d.ts.map +0 -1
  147. package/lib/tests/repositories/dashboard/TaskRepository.spec.js +0 -84
  148. package/lib/tests/repositories/dashboard/UserConfigRepository.spec.d.ts +0 -2
  149. package/lib/tests/repositories/dashboard/UserConfigRepository.spec.d.ts.map +0 -1
  150. package/lib/tests/repositories/dashboard/UserConfigRepository.spec.js +0 -115
@@ -0,0 +1,63 @@
1
+ import { BaseDocument } from '@aneuhold/core-ts-db-lib';
2
+ import { ObjectId } from 'bson';
3
+
4
+ export type RepoSubscribers<TDocType extends BaseDocument> = {
5
+ insertNew: InsertNewSubscriber<TDocType>[];
6
+ insertMany: InsertManySubscriber<TDocType>[];
7
+ updateOne: UpdateOneSubscriber<TDocType>[];
8
+ updateMany: UpdateManySubscriber<TDocType>[];
9
+ deleteOne: DeleteOneSubscriber[];
10
+ deleteList: DeleteListSubscriber[];
11
+ };
12
+
13
+ export type RepoListeners<TDocType extends BaseDocument> = {
14
+ insertNew?: InsertNewSubscriber<TDocType>;
15
+ insertMany?: InsertManySubscriber<TDocType>;
16
+ updateOne?: UpdateOneSubscriber<TDocType>;
17
+ updateMany?: UpdateManySubscriber<TDocType>;
18
+ deleteOne?: DeleteOneSubscriber;
19
+ deleteList?: DeleteListSubscriber;
20
+ };
21
+
22
+ export type InsertNewSubscriber<TDocType extends BaseDocument> = (
23
+ doc: TDocType
24
+ ) => Promise<void>;
25
+
26
+ export type InsertManySubscriber<TDocType extends BaseDocument> = (
27
+ docs: TDocType[]
28
+ ) => Promise<void>;
29
+
30
+ export type UpdateOneSubscriber<TDocType extends BaseDocument> = (
31
+ doc: Partial<TDocType>
32
+ ) => Promise<void>;
33
+
34
+ export type UpdateManySubscriber<TDocType extends BaseDocument> = (
35
+ docs: Partial<TDocType>[]
36
+ ) => Promise<void>;
37
+
38
+ export type DeleteOneSubscriber = (docId: ObjectId) => Promise<void>;
39
+
40
+ export type DeleteListSubscriber = (docIds: ObjectId[]) => Promise<void>;
41
+
42
+ /**
43
+ * A subscription service that allows repositories to subscribe to events
44
+ * that happen in other repositories.
45
+ */
46
+ export default class RepoSubscriptionService {
47
+ /**
48
+ * A utility method to get a default empty set of subscribers for a
49
+ * repository.
50
+ */
51
+ static getDefaultSubscribers<
52
+ TDocType extends BaseDocument
53
+ >(): RepoSubscribers<TDocType> {
54
+ return {
55
+ insertNew: [],
56
+ insertMany: [],
57
+ updateOne: [],
58
+ updateMany: [],
59
+ deleteOne: [],
60
+ deleteList: []
61
+ };
62
+ }
63
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * A random series of characters for tests to help identify test users.
3
+ */
4
+ export declare const TEST_USER_NAME_PREFIX = "lkahwsetpiohweat";
5
+ //# sourceMappingURL=globalTestVariables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globalTestVariables.d.ts","sourceRoot":"./src/","sources":["tests/globalTestVariables.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * A random series of characters for tests to help identify test users.
3
+ */
4
+ export const TEST_USER_NAME_PREFIX = 'lkahwsetpiohweat';
5
+ //# sourceMappingURL=globalTestVariables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globalTestVariables.js","sourceRoot":"./src/","sources":["tests/globalTestVariables.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * A random series of characters for tests to help identify test users.
3
+ */
4
+ export const TEST_USER_NAME_PREFIX = 'lkahwsetpiohweat';
@@ -0,0 +1,61 @@
1
+ import {
2
+ DashboardTask,
3
+ DashboardUserConfig,
4
+ User
5
+ } from '@aneuhold/core-ts-db-lib';
6
+ import crypto from 'crypto';
7
+ import { afterAll, expect, it } from 'vitest';
8
+ import UserRepository from '../../repositories/common/UserRepository.js';
9
+ import DashboardTaskRepository from '../../repositories/dashboard/DashboardTaskRepository.js';
10
+ import DashboardUserConfigRepository from '../../repositories/dashboard/DashboardUserConfigRepository.js';
11
+ import DocumentDb from '../../util/DocumentDb.js';
12
+ import { cleanupDoc, getTestUserName } from '../testsUtil.js';
13
+
14
+ it('can create a new document and delete it', async () => {
15
+ const userRepository = UserRepository.getRepo();
16
+ const newUser = new User(getTestUserName());
17
+ const createResult = await userRepository.insertNew(newUser);
18
+ expect(createResult).toBeTruthy();
19
+
20
+ await cleanupDoc(userRepository, newUser);
21
+ }, 10000);
22
+
23
+ // -- Manual Database Operations Section -- //
24
+
25
+ it.skip('can add a new test user', async () => {
26
+ const userRepository = UserRepository.getRepo();
27
+ const newUser = new User('someUser');
28
+ newUser.auth.password = crypto.randomUUID();
29
+ const createResult = await userRepository.insertNew(newUser);
30
+ expect(createResult).toBeTruthy();
31
+ });
32
+
33
+ it.skip('can create a dashboard config for a user', async () => {
34
+ const userRepo = UserRepository.getRepo();
35
+ const user = await userRepo.get({ userName: 'usernameHere' });
36
+ expect(user).toBeTruthy();
37
+
38
+ if (user) {
39
+ const configRepo = DashboardUserConfigRepository.getRepo();
40
+ const newConfig = new DashboardUserConfig(user._id);
41
+ newConfig.enableDevMode = true;
42
+ await configRepo.insertNew(newConfig);
43
+ }
44
+ });
45
+
46
+ it.skip(`can create a new task for a user`, async () => {
47
+ const userRepo = UserRepository.getRepo();
48
+ const user = await userRepo.get({ userName: 'usernameHere' });
49
+ expect(user).toBeTruthy();
50
+
51
+ if (user) {
52
+ const taskRepo = DashboardTaskRepository.getRepo();
53
+ const newTask = new DashboardTask(user._id);
54
+ newTask.title = 'Test Task';
55
+ await taskRepo.insertNew(newTask);
56
+ }
57
+ });
58
+
59
+ afterAll(async () => {
60
+ return DocumentDb.closeDbConnection();
61
+ });
@@ -0,0 +1,113 @@
1
+ import { User } from '@aneuhold/core-ts-db-lib';
2
+ import { afterAll, describe, expect, it } from 'vitest';
3
+ import ApiKeyRepository from '../../../repositories/common/ApiKeyRepository.js';
4
+ import UserRepository from '../../../repositories/common/UserRepository.js';
5
+ import DocumentDb from '../../../util/DocumentDb.js';
6
+ import { cleanupDoc, expectToThrow, getTestUserName } from '../../testsUtil.js';
7
+
8
+ const userRepo = UserRepository.getRepo();
9
+
10
+ describe('Create operations', () => {
11
+ it('can create a new user', async () => {
12
+ const newUser = new User(getTestUserName());
13
+ const insertResult = await userRepo.insertNew(newUser);
14
+ expect(insertResult).toBeTruthy();
15
+
16
+ await cleanupDoc(userRepo, newUser);
17
+ });
18
+
19
+ it('can create a new user and the new user gets an API key', async () => {
20
+ const newUser = new User(getTestUserName());
21
+ const insertResult = await userRepo.insertNew(newUser);
22
+ expect(insertResult).toBeTruthy();
23
+ const apiKey = await ApiKeyRepository.getRepo().get({
24
+ userId: newUser._id
25
+ });
26
+ expect(apiKey).toBeTruthy();
27
+
28
+ await cleanupDoc(userRepo, newUser);
29
+ const apiKeyThatShouldNotExist = await ApiKeyRepository.getRepo().get({
30
+ userId: newUser._id
31
+ });
32
+ expect(apiKeyThatShouldNotExist).toBeFalsy();
33
+ });
34
+
35
+ it('throws if the username is a duplicate username', async () => {
36
+ const duplicateUserName = getTestUserName();
37
+ const newUser1 = new User(duplicateUserName);
38
+ const newUser2 = new User(duplicateUserName);
39
+
40
+ const insertResult = await userRepo.insertNew(newUser1);
41
+ expect(insertResult).toBeTruthy();
42
+
43
+ await expectToThrow(async () => {
44
+ await userRepo.insertNew(newUser2);
45
+ });
46
+
47
+ await cleanupDoc(userRepo, newUser1);
48
+ });
49
+ });
50
+
51
+ describe('Update operations', () => {
52
+ it('succeeds in updating the username if the username doesnt already exist', async () => {
53
+ const userName1 = getTestUserName();
54
+ const userName2 = getTestUserName();
55
+ const newUser = new User(userName1);
56
+
57
+ // Insert the user
58
+ const insertResult = await userRepo.insertNew(newUser);
59
+ expect(insertResult).toBeTruthy();
60
+
61
+ // Try to update the user
62
+ newUser.userName = userName2;
63
+ const updateResult = await userRepo.update(newUser);
64
+ expect(updateResult.acknowledged).toBeTruthy();
65
+
66
+ await cleanupDoc(userRepo, newUser);
67
+ });
68
+
69
+ it('throws if no id is defined', async () => {
70
+ const newUser = new User(getTestUserName()) as Partial<User>;
71
+ delete newUser._id;
72
+ await expectToThrow(async () => {
73
+ await userRepo.update(newUser);
74
+ });
75
+ });
76
+
77
+ it('throws if the username is updated and already exists', async () => {
78
+ const userName1 = getTestUserName();
79
+ const userName2 = getTestUserName();
80
+ const newUser = new User(userName1);
81
+ const userWithOtherUserName = new User(userName2);
82
+
83
+ // Insert the users
84
+ const insertResult1 = await userRepo.insertNew(newUser);
85
+ expect(insertResult1).toBeTruthy();
86
+ const insertResult2 = await userRepo.insertNew(userWithOtherUserName);
87
+ expect(insertResult2).toBeTruthy();
88
+
89
+ // Try to update the first user
90
+ newUser.userName = userName2;
91
+ await expectToThrow(async () => {
92
+ await userRepo.update(newUser);
93
+ });
94
+
95
+ await Promise.all([
96
+ cleanupDoc(userRepo, newUser),
97
+ cleanupDoc(userRepo, userWithOtherUserName)
98
+ ]);
99
+ });
100
+
101
+ it('throws if the user doesnt exist', async () => {
102
+ const newUser = new User(getTestUserName());
103
+
104
+ // Try to update the user
105
+ await expectToThrow(async () => {
106
+ await userRepo.update(newUser);
107
+ });
108
+ });
109
+ });
110
+
111
+ afterAll(async () => {
112
+ await DocumentDb.closeDbConnection();
113
+ });
@@ -0,0 +1,55 @@
1
+ import {
2
+ NonogramKatanaItem,
3
+ NonogramKatanaItemName,
4
+ User
5
+ } from '@aneuhold/core-ts-db-lib';
6
+ import crypto from 'crypto';
7
+ import { describe, expect, it } from 'vitest';
8
+ import UserRepository from '../../../repositories/common/UserRepository.js';
9
+ import DashboardNonogramKatanaItemRepository from '../../../repositories/dashboard/DashboardNonogramKatanaItemRepository.js';
10
+ import { cleanupDoc, getTestUserName } from '../../testsUtil.js';
11
+
12
+ const userRepo = UserRepository.getRepo();
13
+ const itemRepo = DashboardNonogramKatanaItemRepository.getRepo();
14
+
15
+ describe('Create operations', () => {
16
+ it('can create a new nonogram katana item', async () => {
17
+ const newUser = await createNewTestUser();
18
+ const newItem = new NonogramKatanaItem(
19
+ newUser._id,
20
+ NonogramKatanaItemName.Anchor
21
+ );
22
+ const insertResult = await itemRepo.insertNew(newItem);
23
+ expect(insertResult).toBeTruthy();
24
+
25
+ const newItemFromDb = await itemRepo.get({ _id: newItem._id });
26
+ expect(newItemFromDb).toBeTruthy();
27
+
28
+ await cleanupDoc(userRepo, newUser);
29
+ });
30
+ });
31
+
32
+ /**
33
+ * Deletes all Nonogram Katana Items!
34
+ *
35
+ * To just do a cleanup, put `only` after `it`. So `it.only('can delete all items'`
36
+ */
37
+ it.skip('can delete all items', async () => {
38
+ const result = await itemRepo.deleteAll();
39
+ expect(result.acknowledged).toBeTruthy();
40
+ });
41
+
42
+ /**
43
+ * Create a new test user
44
+ *
45
+ * @returns The new user
46
+ */
47
+ async function createNewTestUser() {
48
+ const newUser = new User(
49
+ getTestUserName(`${crypto.randomUUID()}nonogramKatanaItemTest`)
50
+ );
51
+ newUser.projectAccess.dashboard = true;
52
+ const insertResult = await userRepo.insertNew(newUser);
53
+ expect(insertResult).toBeTruthy();
54
+ return newUser;
55
+ }
@@ -0,0 +1,14 @@
1
+ import { expect, it } from 'vitest';
2
+ import DashboardNonogramKatanaUpgradeRepository from '../../../repositories/dashboard/DashboardNonogramKatanaUpgradeRepository.js';
3
+
4
+ const upgradeRepo = DashboardNonogramKatanaUpgradeRepository.getRepo();
5
+
6
+ /**
7
+ * Deletes all Nonogram Katana Upgrades!
8
+ *
9
+ * To just do a cleanup, put `only` after `it`. So `it.only('can delete all upgrades'`
10
+ */
11
+ it.skip('can delete all upgrades', async () => {
12
+ const result = await upgradeRepo.deleteAll();
13
+ expect(result.acknowledged).toBeTruthy();
14
+ });
@@ -0,0 +1,101 @@
1
+ import { DashboardTask, User } from '@aneuhold/core-ts-db-lib';
2
+ import crypto from 'crypto';
3
+ import { afterAll, describe, expect, it } from 'vitest';
4
+ import UserRepository from '../../../repositories/common/UserRepository.js';
5
+ import DashboardTaskRepository from '../../../repositories/dashboard/DashboardTaskRepository.js';
6
+ import DashboardUserConfigRepository from '../../../repositories/dashboard/DashboardUserConfigRepository.js';
7
+ import DocumentDb from '../../../util/DocumentDb.js';
8
+ import { cleanupDoc, getTestUserName } from '../../testsUtil.js';
9
+
10
+ const userRepo = UserRepository.getRepo();
11
+ const taskRepo = DashboardTaskRepository.getRepo();
12
+
13
+ describe('Create operations', () => {
14
+ it('can create a new task', async () => {
15
+ const newUser = await createNewTestUser();
16
+ const newTask = new DashboardTask(newUser._id);
17
+ const insertResult = await taskRepo.insertNew(newTask);
18
+ expect(insertResult).toBeTruthy();
19
+ const insertedTask = await taskRepo.get({ _id: newTask._id });
20
+ expect(insertedTask).toBeTruthy();
21
+ expect(typeof insertedTask?.createdDate).toBe('object');
22
+ if (!insertedTask) {
23
+ return;
24
+ }
25
+
26
+ await cleanupDoc(userRepo, newUser);
27
+ // Task should be deleted
28
+ const deletedTask = await taskRepo.get({ _id: newTask._id });
29
+ expect(deletedTask).toBeFalsy();
30
+ });
31
+ });
32
+
33
+ describe('Get operations', () => {
34
+ it('can get a set of tasks for a user, without any tasks from other users', async () => {
35
+ const newUser = await createNewTestUser();
36
+ const newTask = new DashboardTask(newUser._id);
37
+ const insertResult = await taskRepo.insertNew(newTask);
38
+ expect(insertResult).toBeTruthy();
39
+
40
+ const otherUser = await createNewTestUser();
41
+ const otherUserTask = new DashboardTask(otherUser._id);
42
+ const insertResult2 = await taskRepo.insertNew(otherUserTask);
43
+ expect(insertResult2).toBeTruthy();
44
+
45
+ const tasks = await taskRepo.getAllForUser(newUser._id);
46
+ expect(tasks.length).toBe(1);
47
+ expect(tasks[0]._id.toString()).toEqual(newTask._id.toString());
48
+
49
+ await cleanupDoc(userRepo, newUser);
50
+ await cleanupDoc(userRepo, otherUser);
51
+ });
52
+
53
+ it('can get a set of tasks for a user, including tasks shared with that user', async () => {
54
+ const configRepo = DashboardUserConfigRepository.getRepo();
55
+ const newUser = await createNewTestUser();
56
+ const newTask = new DashboardTask(newUser._id);
57
+ const insertResult = await taskRepo.insertNew(newTask);
58
+ expect(insertResult).toBeTruthy();
59
+
60
+ const otherUser = await createNewTestUser();
61
+ const otherUserTask = new DashboardTask(otherUser._id);
62
+
63
+ // Add other user as collaborator
64
+ const otherUserConfig = await configRepo.get({ userId: otherUser._id });
65
+ expect(otherUserConfig).toBeTruthy();
66
+ if (!otherUserConfig) {
67
+ return;
68
+ }
69
+ otherUserConfig.collaborators.push(newUser._id);
70
+ await configRepo.update(otherUserConfig);
71
+ otherUserTask.sharedWith.push(newUser._id);
72
+ const insertResult2 = await taskRepo.insertNew(otherUserTask);
73
+ expect(insertResult2).toBeTruthy();
74
+
75
+ const tasks = await taskRepo.getAllForUser(newUser._id);
76
+ expect(tasks.length).toBe(2);
77
+ expect(tasks[0]._id.toString()).toEqual(newTask._id.toString());
78
+ expect(tasks[1]._id.toString()).toEqual(otherUserTask._id.toString());
79
+
80
+ await cleanupDoc(userRepo, newUser);
81
+ await cleanupDoc(userRepo, otherUser);
82
+ });
83
+ });
84
+
85
+ afterAll(async () => {
86
+ return DocumentDb.closeDbConnection();
87
+ });
88
+
89
+ /**
90
+ * Create a new test user
91
+ *
92
+ * @returns The new user
93
+ */
94
+ async function createNewTestUser(): Promise<User> {
95
+ const newUser = new User(
96
+ getTestUserName(`${crypto.randomUUID()}dashboardTaskTest`)
97
+ );
98
+ const insertResult = await userRepo.insertNew(newUser);
99
+ expect(insertResult).toBeTruthy();
100
+ return newUser;
101
+ }
@@ -0,0 +1,155 @@
1
+ import { User } from '@aneuhold/core-ts-db-lib';
2
+ import crypto from 'crypto';
3
+ import { afterAll, describe, expect, it } from 'vitest';
4
+ import UserRepository from '../../../repositories/common/UserRepository.js';
5
+ import DashboardUserConfigRepository from '../../../repositories/dashboard/DashboardUserConfigRepository.js';
6
+ import DocumentDb from '../../../util/DocumentDb.js';
7
+ import { cleanupDoc, getTestUserName } from '../../testsUtil.js';
8
+
9
+ const userRepo = UserRepository.getRepo();
10
+ const configRepo = DashboardUserConfigRepository.getRepo();
11
+
12
+ describe('Create operations', () => {
13
+ it('can create a new user config', async () => {
14
+ // User configs are created automatically when a new user is created
15
+ const newUser = await createNewTestUser();
16
+ const newConfig = await configRepo.get({ userId: newUser._id });
17
+ expect(newConfig).toBeTruthy();
18
+ if (!newConfig) {
19
+ return;
20
+ }
21
+
22
+ await cleanupDoc(userRepo, newUser);
23
+ });
24
+ });
25
+
26
+ describe('Update operations', () => {
27
+ it('can update an existing user config', async () => {
28
+ const newUser = await createNewTestUser();
29
+ const newConfig = await configRepo.get({ userId: newUser._id });
30
+ expect(newConfig).toBeTruthy();
31
+ if (!newConfig) {
32
+ return;
33
+ }
34
+
35
+ newConfig.enableDevMode = true;
36
+ await configRepo.update(newConfig);
37
+ const updatedConfig = await configRepo.get({ _id: newConfig._id });
38
+ expect(updatedConfig?.enableDevMode).toBe(true);
39
+
40
+ await cleanupDoc(userRepo, newUser);
41
+ });
42
+
43
+ it('can add collaborators to an existing user config', async () => {
44
+ const newUser = await createNewTestUser();
45
+ const newConfig = await configRepo.get({ userId: newUser._id });
46
+ expect(newConfig).toBeTruthy();
47
+ if (!newConfig) {
48
+ return;
49
+ }
50
+
51
+ const newCollaborator = await createNewTestUser();
52
+ newConfig.collaborators.push(newCollaborator._id);
53
+ await configRepo.update(newConfig);
54
+ let updatedConfig = await configRepo.get({ _id: newConfig._id });
55
+ expect(updatedConfig?.collaborators.map((x) => x.toString())).toContain(
56
+ newCollaborator._id.toString()
57
+ );
58
+
59
+ await cleanupDoc(userRepo, newCollaborator);
60
+ // Ensure the collaborator is deleted automatically when the user is deleted
61
+ updatedConfig = await configRepo.get({ _id: newConfig._id });
62
+ expect(updatedConfig?.collaborators.map((x) => x.toString())).not.toContain(
63
+ newCollaborator._id.toString()
64
+ );
65
+
66
+ await cleanupDoc(userRepo, newUser);
67
+ });
68
+
69
+ /**
70
+ * Pretty huge test that ensures the full range of functionality is there
71
+ * for collaborators.
72
+ */
73
+ it('correctly updates the collaborators for groups of users', async () => {
74
+ const newUser1 = await createNewTestUser();
75
+ const newConfig1 = await configRepo.get({ userId: newUser1._id });
76
+ expect(newConfig1).toBeTruthy();
77
+ if (!newConfig1) {
78
+ return;
79
+ }
80
+
81
+ const newUser2 = await createNewTestUser();
82
+ const newConfig2 = await configRepo.get({ userId: newUser2._id });
83
+ expect(newConfig2).toBeTruthy();
84
+ if (!newConfig2) {
85
+ return;
86
+ }
87
+
88
+ const newUser3 = await createNewTestUser();
89
+ const newConfig3 = await configRepo.get({ userId: newUser3._id });
90
+ expect(newConfig3).toBeTruthy();
91
+ if (!newConfig3) {
92
+ return;
93
+ }
94
+
95
+ newConfig1.collaborators.push(newUser2._id);
96
+ const updateResult1 = await configRepo.update(newConfig1);
97
+ expect(updateResult1).toBeTruthy();
98
+ let updatedConfig2 = await configRepo.get({ _id: newConfig2._id });
99
+ expect(updatedConfig2?.collaborators.map((x) => x.toString())).toContain(
100
+ newUser1._id.toString()
101
+ );
102
+
103
+ newConfig3.collaborators.push(newUser1._id, newUser2._id);
104
+ let updateResult3 = await configRepo.update(newConfig3);
105
+ expect(updateResult3).toBeTruthy();
106
+ let updatedConfig1 = await configRepo.get({ _id: newConfig1._id });
107
+ expect(updatedConfig1?.collaborators.map((x) => x.toString())).toContain(
108
+ newUser3._id.toString()
109
+ );
110
+ expect(updatedConfig1?.collaborators.map((x) => x.toString())).toContain(
111
+ newUser2._id.toString()
112
+ );
113
+
114
+ newConfig3.collaborators = [];
115
+ updateResult3 = await configRepo.update(newConfig3);
116
+ expect(updateResult3).toBeTruthy();
117
+ updatedConfig1 = await configRepo.get({ _id: newConfig1._id });
118
+ expect(
119
+ updatedConfig1?.collaborators.map((x) => x.toString())
120
+ ).toContainEqual(newUser2._id.toString());
121
+ expect(
122
+ updatedConfig1?.collaborators.map((x) => x.toString())
123
+ ).not.toContain(newUser3._id.toString());
124
+ updatedConfig2 = await configRepo.get({ _id: newConfig2._id });
125
+ expect(
126
+ updatedConfig2?.collaborators.map((x) => x.toString())
127
+ ).toContainEqual(newUser1._id.toString());
128
+ expect(
129
+ updatedConfig2?.collaborators.map((x) => x.toString())
130
+ ).not.toContain(newUser3._id.toString());
131
+
132
+ await cleanupDoc(userRepo, newUser1);
133
+ await cleanupDoc(userRepo, newUser2);
134
+ await cleanupDoc(userRepo, newUser3);
135
+ }, 10000);
136
+ });
137
+
138
+ afterAll(async () => {
139
+ return DocumentDb.closeDbConnection();
140
+ });
141
+
142
+ /**
143
+ * Create a new test user
144
+ *
145
+ * @returns The new user
146
+ */
147
+ async function createNewTestUser() {
148
+ const newUser = new User(
149
+ getTestUserName(`${crypto.randomUUID()}userconfigtest`)
150
+ );
151
+ newUser.projectAccess.dashboard = true;
152
+ const insertResult = await userRepo.insertNew(newUser);
153
+ expect(insertResult).toBeTruthy();
154
+ return newUser;
155
+ }
@@ -1,18 +1,34 @@
1
1
  import { BaseDocument } from '@aneuhold/core-ts-db-lib';
2
- import BaseRepository from '../repositories/BaseRepository';
2
+ import BaseRepository from '../repositories/BaseRepository.js';
3
3
  /**
4
- * A random series of characters for tests to help identify test users.
4
+ * Asserts that the provided asynchronous function throws an error.
5
+ *
6
+ * @param func - The asynchronous function expected to throw an error.
5
7
  */
6
- export declare const TEST_USER_NAME_PREFIX = "lkahwsetpiohweat";
7
8
  export declare function expectToThrow(func: () => Promise<void>): Promise<void>;
8
9
  /**
9
10
  * Gets a test user name with a standardized prefix so that they can all be
10
11
  * identified and deleted if anything goes wrong in the tests.
12
+ *
13
+ * @param username - The username to use as a base for the test user name.
14
+ * @returns The test user name.
11
15
  */
12
16
  export declare function getTestUserName(username?: string): string;
13
17
  /**
14
- * Removes the provided doc from the DB
18
+ * Cleans up a document by deleting it from the repository and verifying its deletion.
19
+ *
20
+ * @template TDocType - The type of the document extending {@link BaseDocument}.
21
+ * @param repo - The repository from which the document will be deleted.
22
+ * @param doc - The document to be deleted.
15
23
  */
16
24
  export declare function cleanupDoc<TDocType extends BaseDocument>(repo: BaseRepository<TDocType>, doc: TDocType): Promise<void>;
25
+ /**
26
+ * Cleans up the specified documents from the repository.
27
+ *
28
+ * @template TDocType - The type of the documents.
29
+ * @param repo - The repository from which to delete the documents.
30
+ * @param docs - The documents to be deleted.
31
+ * @returns A promise that resolves when the cleanup is complete.
32
+ */
17
33
  export declare function cleanupDocs<TDocType extends BaseDocument>(repo: BaseRepository<TDocType>, docs: TDocType[]): Promise<void>;
18
34
  //# sourceMappingURL=testsUtil.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testsUtil.d.ts","sourceRoot":"","sources":["../../src/tests/testsUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,iBAQ5D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,UAGhD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,SAAS,YAAY,EAC5D,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,GAAG,EAAE,QAAQ,iBAMd;AAED,wBAAsB,WAAW,CAAC,QAAQ,SAAS,YAAY,EAC7D,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,IAAI,EAAE,QAAQ,EAAE,iBAOjB"}
1
+ {"version":3,"file":"testsUtil.d.ts","sourceRoot":"./src/","sources":["tests/testsUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,OAAO,cAAc,MAAM,mCAAmC,CAAC;AAG/D;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,iBAQ5D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,QAAQ,SAAS,YAAY,EAC5D,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,GAAG,EAAE,QAAQ,iBAMd;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,QAAQ,SAAS,YAAY,EAC7D,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,IAAI,EAAE,QAAQ,EAAE,iBAOjB"}