@sphereon/ssi-sdk.data-store 0.30.1-unstable.4 → 0.30.1

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 (136) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +77 -77
  3. package/dist/contact/ContactStore.d.ts.map +1 -1
  4. package/dist/digitalCredential/DigitalCredentialStore.d.ts.map +1 -1
  5. package/dist/eventLogger/EventLoggerStore.d.ts.map +1 -1
  6. package/dist/issuanceBranding/IssuanceBrandingStore.d.ts.map +1 -1
  7. package/dist/migrations/internal-migrations-ormconfig.d.ts.map +1 -1
  8. package/dist/migrations/postgres/1708525189001-CreateDigitalCredential.js +33 -33
  9. package/dist/migrations/postgres/1708797018115-CreateMachineStateStore.js +16 -16
  10. package/dist/migrations/postgres/1715761125001-CreateContacts.js +33 -33
  11. package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.js +12 -12
  12. package/dist/migrations/sqlite/1708525189002-CreateDigitalCredential.js +32 -32
  13. package/dist/migrations/sqlite/1708796002272-CreateMachineStateStore.js +15 -15
  14. package/dist/migrations/sqlite/1710438363002-CreateContacts.js +13 -13
  15. package/dist/migrations/sqlite/1715761125002-CreateContacts.js +32 -32
  16. package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.js +9 -9
  17. package/dist/presentationDefinition/PDStore.d.ts.map +1 -1
  18. package/dist/utils/SortingUtils.d.ts.map +1 -1
  19. package/dist/utils/contact/MappingUtils.d.ts.map +1 -1
  20. package/dist/utils/digitalCredential/MappingUtils.d.ts.map +1 -1
  21. package/dist/utils/digitalCredential/MappingUtils.js +4 -4
  22. package/dist/utils/digitalCredential/MappingUtils.js.map +1 -1
  23. package/dist/utils/presentationDefinition/MappingUtils.js +2 -2
  24. package/dist/utils/presentationDefinition/MappingUtils.js.map +1 -1
  25. package/package.json +8 -8
  26. package/src/__tests__/contact.entities.test.ts +2642 -2642
  27. package/src/__tests__/contact.store.test.ts +2649 -2649
  28. package/src/__tests__/digitalCredential.entities.test.ts +274 -274
  29. package/src/__tests__/digitalCredential.store.test.ts +330 -330
  30. package/src/__tests__/eventLogger.entities.test.ts +76 -76
  31. package/src/__tests__/eventLogger.store.test.ts +130 -130
  32. package/src/__tests__/issuanceBranding.entities.test.ts +846 -846
  33. package/src/__tests__/issuanceBranding.store.test.ts +1886 -1886
  34. package/src/__tests__/machineState.entities.test.ts +53 -53
  35. package/src/__tests__/machineState.store.test.ts +176 -176
  36. package/src/__tests__/pd-manager.entities.test.ts +73 -73
  37. package/src/__tests__/pd-manager.store.test.ts +193 -193
  38. package/src/contact/AbstractContactStore.ts +71 -71
  39. package/src/contact/ContactStore.ts +768 -768
  40. package/src/digitalCredential/AbstractDigitalCredentialStore.ts +21 -21
  41. package/src/digitalCredential/DigitalCredentialStore.ts +189 -189
  42. package/src/entities/contact/BaseContactEntity.ts +51 -51
  43. package/src/entities/contact/ConnectionEntity.ts +35 -35
  44. package/src/entities/contact/ContactMetadataItemEntity.ts +51 -51
  45. package/src/entities/contact/CorrelationIdentifierEntity.ts +43 -43
  46. package/src/entities/contact/DidAuthConfigEntity.ts +20 -20
  47. package/src/entities/contact/ElectronicAddressEntity.ts +70 -70
  48. package/src/entities/contact/IdentityEntity.ts +107 -107
  49. package/src/entities/contact/IdentityMetadataItemEntity.ts +48 -48
  50. package/src/entities/contact/NaturalPersonEntity.ts +44 -44
  51. package/src/entities/contact/OpenIdConfigEntity.ts +32 -32
  52. package/src/entities/contact/OrganizationEntity.ts +35 -35
  53. package/src/entities/contact/PartyEntity.ts +117 -117
  54. package/src/entities/contact/PartyRelationshipEntity.ts +68 -68
  55. package/src/entities/contact/PartyTypeEntity.ts +63 -63
  56. package/src/entities/contact/PhysicalAddressEntity.ts +95 -95
  57. package/src/entities/digitalCredential/DigitalCredentialEntity.ts +98 -98
  58. package/src/entities/eventLogger/AuditEventEntity.ts +92 -92
  59. package/src/entities/issuanceBranding/BackgroundAttributesEntity.ts +42 -42
  60. package/src/entities/issuanceBranding/BaseLocaleBrandingEntity.ts +87 -87
  61. package/src/entities/issuanceBranding/CredentialBrandingEntity.ts +79 -79
  62. package/src/entities/issuanceBranding/CredentialLocaleBrandingEntity.ts +33 -33
  63. package/src/entities/issuanceBranding/ImageAttributesEntity.ts +57 -57
  64. package/src/entities/issuanceBranding/ImageDimensionsEntity.ts +22 -22
  65. package/src/entities/issuanceBranding/IssuerBrandingEntity.ts +73 -73
  66. package/src/entities/issuanceBranding/IssuerLocaleBrandingEntity.ts +33 -33
  67. package/src/entities/issuanceBranding/TextAttributesEntity.ts +31 -31
  68. package/src/entities/machineState/MachineStateInfoEntity.ts +59 -59
  69. package/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts +44 -44
  70. package/src/entities/statusList2021/StatusList2021Entity.ts +96 -96
  71. package/src/entities/statusList2021/StatusList2021EntryEntity.ts +29 -29
  72. package/src/eventLogger/AbstractEventLoggerStore.ts +7 -7
  73. package/src/eventLogger/EventLoggerStore.ts +62 -62
  74. package/src/index.ts +160 -160
  75. package/src/issuanceBranding/IssuanceBrandingStore.ts +559 -559
  76. package/src/machineState/IAbstractMachineStateStore.ts +65 -65
  77. package/src/machineState/MachineStateStore.ts +149 -149
  78. package/src/migrations/generic/1-CreateContacts.ts +66 -66
  79. package/src/migrations/generic/10-CreatePresentationDefinitions.ts +66 -66
  80. package/src/migrations/generic/2-CreateIssuanceBranding.ts +64 -64
  81. package/src/migrations/generic/3-CreateContacts.ts +66 -66
  82. package/src/migrations/generic/4-CreateStatusList.ts +54 -54
  83. package/src/migrations/generic/5-CreateAuditEvents.ts +66 -66
  84. package/src/migrations/generic/6-CreateDigitalCredential.ts +66 -66
  85. package/src/migrations/generic/7-CreateMachineStateStore.ts +66 -66
  86. package/src/migrations/generic/8-CreateContacts.ts +66 -66
  87. package/src/migrations/generic/9-CreateContacts.ts +66 -66
  88. package/src/migrations/generic/index.ts +43 -43
  89. package/src/migrations/index.ts +10 -10
  90. package/src/migrations/postgres/1659463079428-CreateContacts.ts +63 -63
  91. package/src/migrations/postgres/1685628974232-CreateIssuanceBranding.ts +85 -85
  92. package/src/migrations/postgres/1690925872592-CreateContacts.ts +158 -158
  93. package/src/migrations/postgres/1693866470001-CreateStatusList.ts +24 -24
  94. package/src/migrations/postgres/1701634812183-CreateAuditEvents.ts +33 -33
  95. package/src/migrations/postgres/1708525189001-CreateDigitalCredential.ts +61 -61
  96. package/src/migrations/postgres/1708797018115-CreateMachineStateStore.ts +29 -29
  97. package/src/migrations/postgres/1710438363001-CreateContacts.ts +63 -63
  98. package/src/migrations/postgres/1715761125001-CreateContacts.ts +60 -60
  99. package/src/migrations/postgres/1716475165345-CreatePresentationDefinitions.ts +25 -25
  100. package/src/migrations/sqlite/1659463069549-CreateContacts.ts +110 -110
  101. package/src/migrations/sqlite/1685628973231-CreateIssuanceBranding.ts +119 -119
  102. package/src/migrations/sqlite/1690925872693-CreateContacts.ts +228 -228
  103. package/src/migrations/sqlite/1693866470000-CreateStatusList.ts +24 -24
  104. package/src/migrations/sqlite/1701634819487-CreateAuditEvents.ts +15 -15
  105. package/src/migrations/sqlite/1708525189002-CreateDigitalCredential.ts +46 -46
  106. package/src/migrations/sqlite/1708796002272-CreateMachineStateStore.ts +28 -28
  107. package/src/migrations/sqlite/1710438363002-CreateContacts.ts +83 -83
  108. package/src/migrations/sqlite/1715761125002-CreateContacts.ts +59 -59
  109. package/src/migrations/sqlite/1716475165344-CreatePresentationDefinitions.ts +24 -24
  110. package/src/presentationDefinition/AbstractPDStore.ts +20 -20
  111. package/src/presentationDefinition/PDStore.ts +185 -185
  112. package/src/statusList/IStatusListStore.ts +44 -44
  113. package/src/statusList/StatusListStore.ts +236 -236
  114. package/src/types/contact/IAbstractContactStore.ts +161 -161
  115. package/src/types/contact/contact.ts +295 -295
  116. package/src/types/digitalCredential/IAbstractDigitalCredentialStore.ts +42 -42
  117. package/src/types/digitalCredential/digitalCredential.ts +102 -102
  118. package/src/types/eventLogger/IAbstractEventLoggerStore.ts +12 -12
  119. package/src/types/eventLogger/eventLogger.ts +3 -3
  120. package/src/types/index.ts +14 -14
  121. package/src/types/machineState/IAbstractMachineStateStore.ts +68 -68
  122. package/src/types/presentationDefinition/IAbstractPDStore.ts +25 -25
  123. package/src/types/presentationDefinition/presentationDefinition.ts +17 -17
  124. package/src/utils/SortingUtils.ts +16 -16
  125. package/src/utils/contact/MappingUtils.ts +506 -506
  126. package/src/utils/digitalCredential/MappingUtils.ts +160 -160
  127. package/src/utils/hasher.ts +19 -19
  128. package/src/utils/presentationDefinition/MappingUtils.ts +52 -52
  129. package/dist/entities/contact/IMetadataEntity.d.ts +0 -8
  130. package/dist/entities/contact/IMetadataEntity.d.ts.map +0 -1
  131. package/dist/entities/contact/IMetadataEntity.js +0 -2
  132. package/dist/entities/contact/IMetadataEntity.js.map +0 -1
  133. package/dist/migrations/generic/8-CreatePresentationDefinitions.d.ts +0 -7
  134. package/dist/migrations/generic/8-CreatePresentationDefinitions.d.ts.map +0 -1
  135. package/dist/migrations/generic/8-CreatePresentationDefinitions.js +0 -78
  136. package/dist/migrations/generic/8-CreatePresentationDefinitions.js.map +0 -1
@@ -1,2642 +1,2642 @@
1
- import { getDID } from '@sphereon/ssi-sdk-ext.did-utils'
2
- import { DataSources } from '@sphereon/ssi-sdk.agent-config'
3
- import { DataSource, FindOptionsWhere } from 'typeorm'
4
- import { BaseContactEntity } from '../entities/contact/BaseContactEntity'
5
- import { ConnectionEntity } from '../entities/contact/ConnectionEntity'
6
- import { ContactMetadataItemEntity } from '../entities/contact/ContactMetadataItemEntity'
7
- import { CorrelationIdentifierEntity } from '../entities/contact/CorrelationIdentifierEntity'
8
- import { DidAuthConfigEntity } from '../entities/contact/DidAuthConfigEntity'
9
- import { ElectronicAddressEntity } from '../entities/contact/ElectronicAddressEntity'
10
- import { IdentityEntity } from '../entities/contact/IdentityEntity'
11
- import { IdentityMetadataItemEntity } from '../entities/contact/IdentityMetadataItemEntity'
12
- import { NaturalPersonEntity } from '../entities/contact/NaturalPersonEntity'
13
- import { OpenIdConfigEntity } from '../entities/contact/OpenIdConfigEntity'
14
- import { OrganizationEntity } from '../entities/contact/OrganizationEntity'
15
- import { PartyEntity } from '../entities/contact/PartyEntity'
16
- import { PartyRelationshipEntity } from '../entities/contact/PartyRelationshipEntity'
17
- import { PartyTypeEntity } from '../entities/contact/PartyTypeEntity'
18
- import { PhysicalAddressEntity } from '../entities/contact/PhysicalAddressEntity'
19
- import {
20
- contactMetadataItemEntityFrom,
21
- CredentialRole,
22
- DataStoreContactEntities,
23
- DataStoreMigrations,
24
- identityMetadataItemEntityFrom,
25
- IdentityOrigin,
26
- MetadataTypes,
27
- PartyOrigin,
28
- partyTypeFrom,
29
- } from '../index'
30
- import {
31
- ConnectionType,
32
- CorrelationIdentifierType,
33
- NaturalPerson,
34
- NonPersistedConnection,
35
- NonPersistedDidAuthConfig,
36
- NonPersistedElectronicAddress,
37
- NonPersistedIdentity,
38
- NonPersistedNaturalPerson,
39
- NonPersistedOpenIdConfig,
40
- NonPersistedOrganization,
41
- NonPersistedParty,
42
- NonPersistedPartyType,
43
- NonPersistedPhysicalAddress,
44
- Organization,
45
- PartyTypeType,
46
- } from '../types'
47
- import {
48
- connectionEntityFrom,
49
- didAuthConfigEntityFrom,
50
- electronicAddressEntityFrom,
51
- identityEntityFrom,
52
- naturalPersonEntityFrom,
53
- openIdConfigEntityFrom,
54
- organizationEntityFrom,
55
- partyEntityFrom,
56
- partyRelationshipEntityFrom,
57
- partyTypeEntityFrom,
58
- physicalAddressEntityFrom,
59
- } from '../utils/contact/MappingUtils'
60
-
61
- // TODO write test adding two contacts reusing the same contactType
62
-
63
- describe('Database entities tests', (): void => {
64
- let dbConnection: DataSource
65
-
66
- beforeEach(async (): Promise<void> => {
67
- DataSources.singleInstance().defaultDbType = 'sqlite'
68
- dbConnection = await new DataSource({
69
- type: 'sqlite',
70
- database: ':memory:',
71
- logging: ['info'],
72
- migrationsRun: false,
73
- migrations: DataStoreMigrations,
74
- synchronize: false,
75
- entities: DataStoreContactEntities,
76
- }).initialize()
77
- await dbConnection.runMigrations()
78
- expect(await dbConnection.showMigrations()).toBeFalsy()
79
- })
80
-
81
- afterEach(async (): Promise<void> => {
82
- await (await dbConnection).destroy()
83
- })
84
-
85
- it('Should save person party to database', async (): Promise<void> => {
86
- const party: NonPersistedParty = {
87
- uri: 'example.com',
88
- partyType: {
89
- type: PartyTypeType.NATURAL_PERSON,
90
- origin: PartyOrigin.INTERNAL,
91
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
92
- name: 'example_name',
93
- },
94
- contact: {
95
- firstName: 'example_first_name',
96
- middleName: 'example_middle_name',
97
- lastName: 'example_last_name',
98
- displayName: 'example_display_name',
99
- },
100
- }
101
-
102
- const partyEntity: PartyEntity = partyEntityFrom(party)
103
- const savedParty: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity, {
104
- transaction: true,
105
- })
106
-
107
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
108
- where: { id: savedParty.id },
109
- })
110
-
111
- expect(fromDb).toBeDefined()
112
- expect(fromDb?.identities?.length).toEqual(0)
113
- expect(fromDb?.uri).toEqual(party.uri)
114
- expect(fromDb?.partyType).toBeDefined()
115
- expect(fromDb?.partyType.type).toEqual(party.partyType.type)
116
- expect(fromDb?.partyType.origin).toEqual(party.partyType.origin)
117
- expect(fromDb?.partyType.tenantId).toEqual(party.partyType.tenantId)
118
- expect(fromDb?.partyType.name).toEqual(party.partyType.name)
119
- expect(fromDb?.contact).toBeDefined()
120
- expect((<NaturalPersonEntity>fromDb?.contact).firstName).toEqual((<NaturalPerson>party.contact).firstName)
121
- expect((<NaturalPersonEntity>fromDb?.contact).middleName).toEqual((<NaturalPerson>party.contact).middleName)
122
- expect((<NaturalPersonEntity>fromDb?.contact).lastName).toEqual((<NaturalPerson>party.contact).lastName)
123
- expect((<NaturalPersonEntity>fromDb?.contact).displayName).toEqual((<NaturalPerson>party.contact).displayName)
124
- })
125
-
126
- it('Should save organization party to database', async (): Promise<void> => {
127
- const party: NonPersistedParty = {
128
- uri: 'example.com',
129
- partyType: {
130
- type: PartyTypeType.ORGANIZATION,
131
- origin: PartyOrigin.INTERNAL,
132
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
133
- name: 'example_name',
134
- },
135
- contact: {
136
- legalName: 'example_legal_name',
137
- displayName: 'example_display_name',
138
- },
139
- }
140
-
141
- const partyEntity: PartyEntity = partyEntityFrom(party)
142
- const savedParty: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity, {
143
- transaction: true,
144
- })
145
-
146
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
147
- where: { id: savedParty.id },
148
- })
149
-
150
- expect(fromDb).toBeDefined()
151
- expect(fromDb?.identities?.length).toEqual(0)
152
- expect(fromDb?.uri).toEqual(party.uri)
153
- expect(fromDb?.partyType).toBeDefined()
154
- expect(fromDb?.partyType.type).toEqual(party.partyType.type)
155
- expect(fromDb?.partyType.origin).toEqual(party.partyType.origin)
156
- expect(fromDb?.partyType.tenantId).toEqual(party.partyType.tenantId)
157
- expect(fromDb?.partyType.name).toEqual(party.partyType.name)
158
- expect(fromDb?.contact).toBeDefined()
159
- expect((<OrganizationEntity>fromDb?.contact).legalName).toEqual((<Organization>party.contact).legalName)
160
- expect((<OrganizationEntity>fromDb?.contact).displayName).toEqual((<Organization>party.contact).displayName)
161
- })
162
-
163
- it('Should result in party relationship for the owner side only', async (): Promise<void> => {
164
- const party1: NonPersistedParty = {
165
- uri: 'example1.com',
166
- partyType: {
167
- type: PartyTypeType.NATURAL_PERSON,
168
- origin: PartyOrigin.INTERNAL,
169
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
170
- name: 'example_name1',
171
- },
172
- contact: {
173
- firstName: 'example_first_name1',
174
- middleName: 'example_middle_name1',
175
- lastName: 'example_last_name1',
176
- displayName: 'example_display_name1',
177
- },
178
- }
179
-
180
- const partyEntity1: PartyEntity = partyEntityFrom(party1)
181
- const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
182
- transaction: true,
183
- })
184
-
185
- const party2: NonPersistedParty = {
186
- uri: 'example2.com',
187
- partyType: {
188
- type: PartyTypeType.NATURAL_PERSON,
189
- origin: PartyOrigin.INTERNAL,
190
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
191
- name: 'example_name2',
192
- },
193
- contact: {
194
- firstName: 'example_first_name2',
195
- middleName: 'example_middle_name2',
196
- lastName: 'example_last_name2',
197
- displayName: 'example_display_name2',
198
- },
199
- }
200
-
201
- const partyEntity2: PartyEntity = partyEntityFrom(party2)
202
- const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
203
- transaction: true,
204
- })
205
-
206
- const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
207
- leftId: savedParty1.id,
208
- rightId: savedParty2.id,
209
- })
210
-
211
- await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
212
- transaction: true,
213
- })
214
-
215
- const fromDb1: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
216
- where: { id: savedParty1.id },
217
- })
218
-
219
- const fromDb2: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
220
- where: { id: savedParty2.id },
221
- })
222
-
223
- expect(fromDb1).toBeDefined()
224
- expect(fromDb1?.relationships.length).toEqual(1)
225
- expect(fromDb2).toBeDefined()
226
- expect(fromDb2?.relationships.length).toEqual(0)
227
- })
228
-
229
- it('should throw error when saving person party with blank first name', async (): Promise<void> => {
230
- const party: NonPersistedParty = {
231
- uri: 'example.com',
232
- partyType: {
233
- type: PartyTypeType.NATURAL_PERSON,
234
- origin: PartyOrigin.INTERNAL,
235
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
236
- name: 'example_name',
237
- },
238
- contact: {
239
- firstName: '',
240
- middleName: 'example_middle_name1',
241
- lastName: 'example_last_name1',
242
- displayName: 'example_display_name1',
243
- },
244
- }
245
-
246
- const partyEntity: PartyEntity = partyEntityFrom(party)
247
-
248
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank first names are not allowed')
249
- })
250
-
251
- it('should throw error when saving person party with blank middle name', async (): Promise<void> => {
252
- const party: NonPersistedParty = {
253
- uri: 'example.com',
254
- partyType: {
255
- type: PartyTypeType.NATURAL_PERSON,
256
- origin: PartyOrigin.EXTERNAL,
257
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
258
- name: 'example_name',
259
- },
260
- contact: {
261
- firstName: 'example_first_name',
262
- middleName: '',
263
- lastName: 'example_last_name',
264
- displayName: 'example_display_name',
265
- },
266
- }
267
-
268
- const partyEntity: PartyEntity = partyEntityFrom(party)
269
-
270
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank middle names are not allowed')
271
- })
272
-
273
- it('should throw error when saving person party with blank last name', async (): Promise<void> => {
274
- const party: NonPersistedParty = {
275
- uri: 'example.com',
276
- partyType: {
277
- type: PartyTypeType.NATURAL_PERSON,
278
- origin: PartyOrigin.EXTERNAL,
279
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
280
- name: 'example_name',
281
- },
282
- contact: {
283
- firstName: 'example_first_name',
284
- middleName: 'example_middle_name',
285
- lastName: '',
286
- displayName: 'example_display_name',
287
- },
288
- }
289
-
290
- const partyEntity: PartyEntity = partyEntityFrom(party)
291
-
292
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank last names are not allowed')
293
- })
294
-
295
- it('should throw error when saving person party with blank display name', async (): Promise<void> => {
296
- const party: NonPersistedParty = {
297
- uri: 'example.com',
298
- partyType: {
299
- type: PartyTypeType.NATURAL_PERSON,
300
- origin: PartyOrigin.EXTERNAL,
301
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
302
- name: 'example_name',
303
- },
304
- contact: {
305
- firstName: 'example_first_name',
306
- middleName: 'example_middle_name',
307
- lastName: 'example_last_name',
308
- displayName: '',
309
- },
310
- }
311
-
312
- const partyEntity: PartyEntity = partyEntityFrom(party)
313
-
314
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank display names are not allowed')
315
- })
316
-
317
- it('should throw error when saving organization party with blank legal name', async (): Promise<void> => {
318
- const party: NonPersistedParty = {
319
- uri: 'example.com',
320
- partyType: {
321
- type: PartyTypeType.ORGANIZATION,
322
- origin: PartyOrigin.INTERNAL,
323
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
324
- name: 'example_name',
325
- },
326
- contact: {
327
- legalName: '',
328
- displayName: 'example_legal_name',
329
- },
330
- }
331
-
332
- const partyEntity: PartyEntity = partyEntityFrom(party)
333
-
334
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank legal names are not allowed')
335
- })
336
-
337
- it('should throw error when saving organization party with blank display name', async (): Promise<void> => {
338
- const party: NonPersistedParty = {
339
- uri: 'example.com',
340
- partyType: {
341
- type: PartyTypeType.ORGANIZATION,
342
- origin: PartyOrigin.INTERNAL,
343
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
344
- name: 'example_name',
345
- },
346
- contact: {
347
- legalName: 'example_first_name',
348
- displayName: '',
349
- },
350
- }
351
-
352
- const partyEntity: PartyEntity = partyEntityFrom(party)
353
-
354
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank display names are not allowed')
355
- })
356
-
357
- it('should throw error when saving party with blank party type name', async (): Promise<void> => {
358
- const party: NonPersistedParty = {
359
- uri: 'example.com',
360
- partyType: {
361
- type: PartyTypeType.NATURAL_PERSON,
362
- origin: PartyOrigin.EXTERNAL,
363
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
364
- name: '',
365
- },
366
- contact: {
367
- firstName: 'example_first_name',
368
- middleName: 'example_middle_name',
369
- lastName: 'example_last_name',
370
- displayName: 'example_display_name',
371
- },
372
- }
373
-
374
- const partyEntity: PartyEntity = partyEntityFrom(party)
375
-
376
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank names are not allowed')
377
- })
378
-
379
- it('should throw error when saving party with blank party type description', async (): Promise<void> => {
380
- const party: NonPersistedParty = {
381
- uri: 'example.com',
382
- partyType: {
383
- type: PartyTypeType.NATURAL_PERSON,
384
- origin: PartyOrigin.INTERNAL,
385
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
386
- name: 'example_name',
387
- description: '',
388
- },
389
- contact: {
390
- firstName: 'example_first_name',
391
- middleName: 'example_middle_name',
392
- lastName: 'example_last_name',
393
- displayName: 'example_display_name',
394
- },
395
- }
396
-
397
- const partyEntity: PartyEntity = partyEntityFrom(party)
398
-
399
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank descriptions are not allowed')
400
- })
401
-
402
- it('should throw error when saving party with blank party type tenant id', async (): Promise<void> => {
403
- const party: NonPersistedParty = {
404
- uri: 'example.com',
405
- partyType: {
406
- type: PartyTypeType.NATURAL_PERSON,
407
- origin: PartyOrigin.EXTERNAL,
408
- tenantId: '',
409
- name: 'example_name',
410
- },
411
- contact: {
412
- firstName: 'example_first_name',
413
- middleName: 'example_middle_name',
414
- lastName: 'example_last_name',
415
- displayName: 'example_display_name',
416
- },
417
- }
418
-
419
- const partyEntity: PartyEntity = partyEntityFrom(party)
420
-
421
- await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError("Blank tenant id's are not allowed")
422
- })
423
-
424
- it('Should enforce unique alias for an identity', async (): Promise<void> => {
425
- const alias = 'non_unique_alias'
426
- const identity1: NonPersistedIdentity = {
427
- alias,
428
- origin: IdentityOrigin.EXTERNAL,
429
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
430
- identifier: {
431
- type: CorrelationIdentifierType.DID,
432
- correlationId: 'unique_correlationId1',
433
- },
434
- }
435
- const identity1Entity: IdentityEntity = identityEntityFrom(identity1)
436
- await dbConnection.getRepository(IdentityEntity).save(identity1Entity)
437
-
438
- const identity2: NonPersistedIdentity = {
439
- alias: alias,
440
- origin: IdentityOrigin.EXTERNAL,
441
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
442
- identifier: {
443
- type: CorrelationIdentifierType.DID,
444
- correlationId: 'unique_correlationId2',
445
- },
446
- }
447
- const identity2Entity: IdentityEntity = identityEntityFrom(identity2)
448
- await expect(dbConnection.getRepository(IdentityEntity).save(identity2Entity)).rejects.toThrowError(
449
- 'SQLITE_CONSTRAINT: UNIQUE constraint failed: Identity.alias',
450
- )
451
- })
452
-
453
- it('Should enforce unique correlationId for a identity', async (): Promise<void> => {
454
- const correlationId = 'non_unique_correlationId'
455
- const identity1: NonPersistedIdentity = {
456
- alias: 'unique_alias1',
457
- origin: IdentityOrigin.EXTERNAL,
458
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
459
- identifier: {
460
- type: CorrelationIdentifierType.DID,
461
- correlationId,
462
- },
463
- }
464
- const identity1Entity: IdentityEntity = identityEntityFrom(identity1)
465
- await dbConnection.getRepository(IdentityEntity).save(identity1Entity)
466
-
467
- const identity2: NonPersistedIdentity = {
468
- alias: 'unique_alias2',
469
- origin: IdentityOrigin.EXTERNAL,
470
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
471
- identifier: {
472
- type: CorrelationIdentifierType.DID,
473
- correlationId,
474
- },
475
- }
476
- const identity2Entity: IdentityEntity = identityEntityFrom(identity2)
477
- await expect(dbConnection.getRepository(IdentityEntity).save(identity2Entity)).rejects.toThrowError(
478
- 'SQLITE_CONSTRAINT: UNIQUE constraint failed: CorrelationIdentifier.correlation_id',
479
- )
480
- })
481
-
482
- it('Should save identity to database', async (): Promise<void> => {
483
- const correlationId = 'example_did'
484
- const identity: NonPersistedIdentity = {
485
- alias: correlationId,
486
- origin: IdentityOrigin.EXTERNAL,
487
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
488
- identifier: {
489
- type: CorrelationIdentifierType.DID,
490
- correlationId,
491
- },
492
- }
493
-
494
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
495
-
496
- await dbConnection.getRepository(IdentityEntity).save(identityEntity)
497
-
498
- const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
499
- where: {
500
- identifier: {
501
- correlationId,
502
- },
503
- },
504
- })
505
-
506
- expect(fromDb).toBeDefined()
507
- expect(fromDb?.connection).toBeNull()
508
- expect(fromDb?.identifier).toBeDefined()
509
- expect(fromDb?.identifier.correlationId).toEqual(identity.identifier.correlationId)
510
- expect(fromDb?.identifier.type).toEqual(identity.identifier.type)
511
- })
512
-
513
- it('should throw error when saving identity with blank alias', async (): Promise<void> => {
514
- const identity: NonPersistedIdentity = {
515
- alias: '',
516
- origin: IdentityOrigin.EXTERNAL,
517
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
518
- identifier: {
519
- type: CorrelationIdentifierType.DID,
520
- correlationId: 'example_did',
521
- },
522
- }
523
-
524
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
525
-
526
- await expect(dbConnection.getRepository(IdentityEntity).save(identityEntity)).rejects.toThrowError('Blank aliases are not allowed')
527
- })
528
-
529
- it('should throw error when saving identity with blank correlation id', async (): Promise<void> => {
530
- const identity: NonPersistedIdentity = {
531
- alias: 'example_did',
532
- origin: IdentityOrigin.EXTERNAL,
533
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
534
- identifier: {
535
- type: CorrelationIdentifierType.DID,
536
- correlationId: '',
537
- },
538
- }
539
-
540
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
541
-
542
- await expect(dbConnection.getRepository(IdentityEntity).save(identityEntity)).rejects.toThrowError('Blank correlation ids are not allowed')
543
- })
544
-
545
- it('should throw error when saving identity with blank metadata label', async (): Promise<void> => {
546
- const correlationId = 'example_did'
547
- const identity: NonPersistedIdentity = {
548
- alias: correlationId,
549
- origin: IdentityOrigin.EXTERNAL,
550
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
551
- identifier: {
552
- type: CorrelationIdentifierType.DID,
553
- correlationId,
554
- },
555
- metadata: [
556
- {
557
- label: '',
558
- value: 'example_value',
559
- },
560
- ],
561
- }
562
-
563
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
564
-
565
- await expect(dbConnection.getRepository(IdentityEntity).save(identityEntity)).rejects.toThrowError('Blank metadata labels are not allowed')
566
- })
567
-
568
- it('Should save identity with openid connection to database', async (): Promise<void> => {
569
- const correlationId = 'example.com'
570
- const identity: NonPersistedIdentity = {
571
- alias: correlationId,
572
- origin: IdentityOrigin.EXTERNAL,
573
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
574
- identifier: {
575
- type: CorrelationIdentifierType.URL,
576
- correlationId,
577
- },
578
- connection: {
579
- type: ConnectionType.OPENID_CONNECT,
580
- config: {
581
- clientId: '138d7bf8-c930-4c6e-b928-97d3a4928b01',
582
- clientSecret: '03b3955f-d020-4f2a-8a27-4e452d4e27a0',
583
- scopes: ['auth'],
584
- issuer: 'https://example.com/app-test',
585
- redirectUrl: 'app:/callback',
586
- dangerouslyAllowInsecureHttpRequests: true,
587
- clientAuthMethod: <const>'post',
588
- },
589
- },
590
- }
591
-
592
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
593
-
594
- await dbConnection.getRepository(IdentityEntity).save(identityEntity)
595
-
596
- const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
597
- where: {
598
- identifier: {
599
- correlationId,
600
- },
601
- },
602
- })
603
-
604
- expect(fromDb).toBeDefined()
605
- expect(fromDb?.connection).toBeDefined()
606
- expect(fromDb?.identifier).toBeDefined()
607
- expect(fromDb?.identifier.correlationId).toEqual(identity.identifier.correlationId)
608
- expect(fromDb?.identifier.type).toEqual(identity.identifier.type)
609
- expect(fromDb?.connection?.type).toEqual(identity.connection?.type)
610
- expect(fromDb?.connection?.config).toBeDefined()
611
- expect((<OpenIdConfigEntity>fromDb?.connection?.config).clientId).toEqual((<NonPersistedOpenIdConfig>identity.connection?.config).clientId)
612
- })
613
-
614
- it('Should save identity with didauth connection to database', async (): Promise<void> => {
615
- const correlationId = 'example.com'
616
- const identity: NonPersistedIdentity = {
617
- alias: correlationId,
618
- origin: IdentityOrigin.EXTERNAL,
619
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
620
- identifier: {
621
- type: CorrelationIdentifierType.URL,
622
- correlationId,
623
- },
624
- connection: {
625
- type: ConnectionType.SIOPv2,
626
- config: {
627
- idOpts: {
628
- identifier: {
629
- did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
630
- provider: 'test_provider',
631
- keys: [],
632
- services: [],
633
- },
634
- },
635
- redirectUrl: 'https://example.com',
636
- stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
637
- sessionId: 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
638
- },
639
- },
640
- } satisfies NonPersistedIdentity
641
-
642
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
643
-
644
- await dbConnection.getRepository(IdentityEntity).save(identityEntity)
645
-
646
- const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
647
- where: {
648
- identifier: {
649
- correlationId,
650
- },
651
- },
652
- })
653
-
654
- expect(fromDb).toBeDefined()
655
- expect(fromDb?.connection).toBeDefined()
656
- expect(fromDb?.identifier).toBeDefined()
657
- expect(fromDb?.identifier.correlationId).toEqual(identity.identifier.correlationId)
658
- expect(fromDb?.identifier.type).toEqual(identity.identifier.type)
659
- expect(fromDb?.connection?.type).toEqual(identity.connection?.type)
660
- expect(fromDb?.connection?.config).toBeDefined()
661
- expect((<DidAuthConfigEntity>fromDb?.connection?.config).identifier).toEqual(
662
- getDID({ identifier: (<NonPersistedDidAuthConfig>identity.connection?.config).idOpts.identifier as string }),
663
- )
664
- })
665
-
666
- it('Should save connection with openid config to database', async (): Promise<void> => {
667
- const connection: NonPersistedConnection = {
668
- type: ConnectionType.OPENID_CONNECT,
669
- config: {
670
- clientId: '138d7bf8-c930-4c6e-b928-97d3a4928b01',
671
- clientSecret: '03b3955f-d020-4f2a-8a27-4e452d4e27a0',
672
- scopes: ['auth'],
673
- issuer: 'https://example.com/app-test',
674
- redirectUrl: 'app:/callback',
675
- dangerouslyAllowInsecureHttpRequests: true,
676
- clientAuthMethod: <const>'post',
677
- },
678
- }
679
- const connectionEntity: ConnectionEntity = connectionEntityFrom(connection)
680
- await dbConnection.getRepository(ConnectionEntity).save(connectionEntity, {
681
- transaction: true,
682
- })
683
-
684
- const fromDb: ConnectionEntity | null = await dbConnection.getRepository(ConnectionEntity).findOne({
685
- where: { type: connection.type },
686
- })
687
-
688
- expect(fromDb).toBeDefined()
689
-
690
- const fromDbConfig: OpenIdConfigEntity | null = await dbConnection.getRepository(OpenIdConfigEntity).findOne({
691
- where: { id: fromDb?.id },
692
- })
693
-
694
- expect(fromDbConfig).toBeDefined()
695
- expect(fromDb?.type).toEqual(connection.type)
696
- expect(fromDb?.config).toBeDefined()
697
- expect((<OpenIdConfigEntity>fromDb?.config).clientId).toEqual((<NonPersistedOpenIdConfig>connection.config).clientId)
698
- })
699
-
700
- it('Should save connection with didauth config to database', async (): Promise<void> => {
701
- const connection: NonPersistedConnection = {
702
- type: ConnectionType.SIOPv2,
703
- config: {
704
- idOpts: {
705
- identifier: {
706
- did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
707
- provider: 'test_provider',
708
- keys: [],
709
- services: [],
710
- },
711
- },
712
- redirectUrl: 'https://example.com',
713
- stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
714
- sessionId: 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
715
- },
716
- }
717
- const connectionEntity: ConnectionEntity = connectionEntityFrom(connection)
718
- await dbConnection.getRepository(ConnectionEntity).save(connectionEntity, {
719
- transaction: true,
720
- })
721
-
722
- const fromDb: ConnectionEntity | null = await dbConnection.getRepository(ConnectionEntity).findOne({
723
- where: { type: connection.type },
724
- })
725
-
726
- expect(fromDb).toBeDefined()
727
-
728
- const fromDbConfig: DidAuthConfigEntity | null = await dbConnection.getRepository(DidAuthConfigEntity).findOne({
729
- where: { id: fromDb?.id },
730
- })
731
-
732
- expect(fromDbConfig).toBeDefined()
733
- expect(fromDb?.type).toEqual(connection.type)
734
- expect(fromDb?.config).toBeDefined()
735
- expect((<DidAuthConfigEntity>fromDb?.config).identifier).toEqual(
736
- getDID({ identifier: (<NonPersistedDidAuthConfig>connection?.config).idOpts.identifier as string }),
737
- )
738
- })
739
-
740
- it('Should save openid config to database', async (): Promise<void> => {
741
- const clientId = '138d7bf8-c930-4c6e-b928-97d3a4928b01'
742
- const config: NonPersistedOpenIdConfig = {
743
- clientId,
744
- clientSecret: '03b3955f-d020-4f2a-8a27-4e452d4e27a0',
745
- scopes: ['auth'],
746
- issuer: 'https://example.com/app-test',
747
- redirectUrl: 'app:/callback',
748
- dangerouslyAllowInsecureHttpRequests: true,
749
- clientAuthMethod: <const>'post',
750
- }
751
-
752
- const configEntity: OpenIdConfigEntity = openIdConfigEntityFrom(config)
753
- await dbConnection.getRepository(OpenIdConfigEntity).save(configEntity, {
754
- transaction: true,
755
- })
756
-
757
- const fromDb: OpenIdConfigEntity | null = await dbConnection.getRepository(OpenIdConfigEntity).findOne({
758
- where: { clientId: config.clientId },
759
- })
760
-
761
- expect(fromDb).toBeDefined()
762
- expect((<OpenIdConfigEntity>fromDb).clientId).toEqual(config.clientId)
763
- })
764
-
765
- it('Should save didauth config to database', async (): Promise<void> => {
766
- const sessionId = 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01'
767
- const config: NonPersistedDidAuthConfig = {
768
- idOpts: {
769
- identifier: {
770
- did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
771
- provider: 'test_provider',
772
- keys: [],
773
- services: [],
774
- },
775
- },
776
- redirectUrl: 'https://example.com',
777
- stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
778
- sessionId,
779
- }
780
-
781
- const configEntity: DidAuthConfigEntity = didAuthConfigEntityFrom(config)
782
- await dbConnection.getRepository(DidAuthConfigEntity).save(configEntity, {
783
- transaction: true,
784
- })
785
-
786
- const fromDb: DidAuthConfigEntity | null = await dbConnection.getRepository(DidAuthConfigEntity).findOne({
787
- where: { sessionId: config.sessionId },
788
- })
789
-
790
- expect(fromDb).toBeDefined()
791
- expect((<DidAuthConfigEntity>fromDb).identifier).toEqual(getDID({ identifier: (<NonPersistedDidAuthConfig>config).idOpts.identifier as string }))
792
- })
793
-
794
- it('Should delete party and all child relations', async (): Promise<void> => {
795
- const party1: NonPersistedParty = {
796
- uri: 'example.com',
797
- partyType: {
798
- type: PartyTypeType.NATURAL_PERSON,
799
- origin: PartyOrigin.INTERNAL,
800
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
801
- name: 'example_name1',
802
- },
803
- contact: {
804
- firstName: 'example_first_name1',
805
- middleName: 'example_middle_name1',
806
- lastName: 'example_last_name1',
807
- displayName: 'example_display_name1',
808
- },
809
- }
810
-
811
- const partyEntity1: PartyEntity = partyEntityFrom(party1)
812
- const savedParty1: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity1)
813
-
814
- expect(savedParty1).toBeDefined()
815
-
816
- const party2: NonPersistedParty = {
817
- uri: 'example.com',
818
- partyType: {
819
- type: PartyTypeType.NATURAL_PERSON,
820
- origin: PartyOrigin.INTERNAL,
821
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
822
- name: 'example_name2',
823
- },
824
- contact: {
825
- firstName: 'example_first_name2',
826
- middleName: 'example_middle_name2',
827
- lastName: 'example_last_name2',
828
- displayName: 'example_display_name2',
829
- },
830
- }
831
-
832
- const partyEntity2: PartyEntity = partyEntityFrom(party2)
833
- const savedParty2: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity2)
834
-
835
- expect(savedParty2).toBeDefined()
836
-
837
- const correlationId = 'relation_example.com'
838
- const identity: NonPersistedIdentity = {
839
- alias: correlationId,
840
- origin: IdentityOrigin.EXTERNAL,
841
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
842
- identifier: {
843
- type: CorrelationIdentifierType.URL,
844
- correlationId,
845
- },
846
- connection: {
847
- type: ConnectionType.OPENID_CONNECT,
848
- config: {
849
- clientId: '138d7bf8-c930-4c6e-b928-97d3a4928b01',
850
- clientSecret: '03b3955f-d020-4f2a-8a27-4e452d4e27a0',
851
- scopes: ['auth'],
852
- issuer: 'https://example.com/app-test',
853
- redirectUrl: 'app:/callback',
854
- dangerouslyAllowInsecureHttpRequests: true,
855
- clientAuthMethod: <const>'post',
856
- },
857
- },
858
- metadata: [
859
- {
860
- label: 'example_label',
861
- value: 'example_value',
862
- },
863
- ],
864
- }
865
-
866
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
867
- identityEntity.party = savedParty1
868
-
869
- const savedIdentity: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).save(identityEntity)
870
-
871
- expect(savedIdentity).toBeDefined()
872
-
873
- const electronicAddress: NonPersistedElectronicAddress = {
874
- type: 'email',
875
- electronicAddress: 'example_electronic_address',
876
- }
877
- const electronicAddressEntity: ElectronicAddressEntity = electronicAddressEntityFrom(electronicAddress)
878
- electronicAddressEntity.party = savedParty1
879
-
880
- const savedElectronicAddress: ElectronicAddressEntity | null = await dbConnection
881
- .getRepository(ElectronicAddressEntity)
882
- .save(electronicAddressEntity)
883
-
884
- expect(savedElectronicAddress).toBeDefined()
885
-
886
- const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
887
- leftId: savedParty1.id,
888
- rightId: savedParty2.id,
889
- })
890
-
891
- const savedRelationship: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
892
- transaction: true,
893
- })
894
-
895
- expect(savedRelationship).toBeDefined()
896
-
897
- expect(
898
- await dbConnection.getRepository(PartyEntity).findOne({
899
- where: { id: savedParty1.id },
900
- }),
901
- ).toBeDefined()
902
-
903
- await dbConnection.getRepository(PartyEntity).delete({ id: savedParty1.id })
904
-
905
- // check party
906
- await expect(
907
- await dbConnection.getRepository(PartyEntity).findOne({
908
- where: { id: savedParty1.id },
909
- }),
910
- ).toBeNull()
911
-
912
- // check identity
913
- expect(
914
- await dbConnection.getRepository(IdentityEntity).findOne({
915
- where: { id: savedParty1.id },
916
- }),
917
- ).toBeNull()
918
-
919
- // check identity identifier
920
- expect(
921
- await dbConnection.getRepository(CorrelationIdentifierEntity).findOne({
922
- where: { id: savedIdentity.identifier.id },
923
- }),
924
- ).toBeNull()
925
-
926
- // check identity connection
927
- expect(
928
- await dbConnection.getRepository(ConnectionEntity).findOne({
929
- where: { id: savedIdentity.connection!.id },
930
- }),
931
- ).toBeNull()
932
-
933
- // check connection config
934
- expect(
935
- await dbConnection.getRepository(OpenIdConfigEntity).findOne({
936
- where: { id: savedIdentity.connection!.config.id },
937
- }),
938
- ).toBeNull()
939
-
940
- // check identity metadata
941
- expect(
942
- await dbConnection.getRepository(IdentityMetadataItemEntity).findOne({
943
- where: { id: savedIdentity.metadata![0].id },
944
- }),
945
- ).toBeNull()
946
-
947
- // check electronic address
948
- expect(
949
- await dbConnection.getRepository(ElectronicAddressEntity).findOne({
950
- where: { id: savedParty1.id },
951
- }),
952
- ).toBeNull()
953
-
954
- // check contact
955
- expect(
956
- await dbConnection.getRepository(BaseContactEntity).findOne({
957
- where: { id: savedParty1.contact.id },
958
- }),
959
- ).toBeNull()
960
-
961
- // check party type
962
- expect(
963
- await dbConnection.getRepository(PartyTypeEntity).findOne({
964
- where: { id: savedParty1.partyType.id },
965
- }),
966
- ).toBeDefined()
967
-
968
- // check relation
969
- expect(
970
- await dbConnection.getRepository(PartyRelationshipEntity).findOne({
971
- where: { id: savedRelationship.id },
972
- }),
973
- ).toBeNull()
974
- })
975
-
976
- it('Should delete identity and all child relations', async (): Promise<void> => {
977
- const party: NonPersistedParty = {
978
- uri: 'example.com',
979
- partyType: {
980
- type: PartyTypeType.NATURAL_PERSON,
981
- origin: PartyOrigin.EXTERNAL,
982
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
983
- name: 'example_name',
984
- },
985
- contact: {
986
- firstName: 'example_first_name',
987
- middleName: 'example_middle_name',
988
- lastName: 'example_last_name',
989
- displayName: 'example_display_name',
990
- },
991
- }
992
-
993
- const partyEntity: PartyEntity = partyEntityFrom(party)
994
- const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
995
-
996
- expect(savedParty).toBeDefined()
997
-
998
- const correlationId = 'relation_example.com'
999
- const identity: NonPersistedIdentity = {
1000
- alias: correlationId,
1001
- origin: IdentityOrigin.EXTERNAL,
1002
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1003
- identifier: {
1004
- type: CorrelationIdentifierType.URL,
1005
- correlationId,
1006
- },
1007
- connection: {
1008
- type: ConnectionType.SIOPv2,
1009
- config: {
1010
- idOpts: {
1011
- identifier: {
1012
- did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
1013
- provider: 'test_provider',
1014
- keys: [],
1015
- services: [],
1016
- },
1017
- },
1018
- redirectUrl: 'https://example.com',
1019
- stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
1020
- sessionId: 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
1021
- },
1022
- },
1023
- metadata: [
1024
- {
1025
- label: 'example_label',
1026
- value: 'example_value',
1027
- },
1028
- ],
1029
- }
1030
-
1031
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
1032
- identityEntity.party = savedParty
1033
-
1034
- const savedIdentity: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1035
-
1036
- expect(
1037
- await dbConnection.getRepository(PartyEntity).findOne({
1038
- where: { id: savedParty.id },
1039
- }),
1040
- ).toBeDefined()
1041
-
1042
- await dbConnection.getRepository(IdentityEntity).delete({ id: savedIdentity.id })
1043
-
1044
- // check identity
1045
- expect(
1046
- await dbConnection.getRepository(IdentityEntity).findOne({
1047
- where: { alias: correlationId },
1048
- }),
1049
- ).toBeNull()
1050
-
1051
- // check identity identifier
1052
- expect(
1053
- await dbConnection.getRepository(CorrelationIdentifierEntity).findOne({
1054
- where: { id: savedIdentity.identifier.id },
1055
- }),
1056
- ).toBeNull()
1057
-
1058
- // check identity connection
1059
- expect(
1060
- await dbConnection.getRepository(ConnectionEntity).findOne({
1061
- where: { id: savedIdentity.connection!.id },
1062
- }),
1063
- ).toBeNull()
1064
-
1065
- // check connection config
1066
- expect(
1067
- await dbConnection.getRepository(OpenIdConfigEntity).findOne({
1068
- where: { id: savedIdentity.connection!.config.id },
1069
- }),
1070
- ).toBeNull()
1071
-
1072
- // check identity metadata
1073
- expect(
1074
- await dbConnection.getRepository(IdentityMetadataItemEntity).findOne({
1075
- where: { id: savedIdentity.metadata![0].id },
1076
- }),
1077
- ).toBeNull()
1078
- })
1079
-
1080
- it('Should not delete party when deleting identity', async (): Promise<void> => {
1081
- const party: NonPersistedParty = {
1082
- uri: 'example.com',
1083
- partyType: {
1084
- type: PartyTypeType.NATURAL_PERSON,
1085
- origin: PartyOrigin.EXTERNAL,
1086
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1087
- name: 'example_name',
1088
- },
1089
- contact: {
1090
- firstName: 'example_first_name',
1091
- middleName: 'example_middle_name',
1092
- lastName: 'example_last_name',
1093
- displayName: 'example_display_name',
1094
- },
1095
- }
1096
-
1097
- const partyEntity: PartyEntity = partyEntityFrom(party)
1098
- const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1099
-
1100
- expect(savedParty).toBeDefined()
1101
-
1102
- const correlationId = 'relation_example.com'
1103
- const identity: NonPersistedIdentity = {
1104
- alias: correlationId,
1105
- origin: IdentityOrigin.EXTERNAL,
1106
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1107
- identifier: {
1108
- type: CorrelationIdentifierType.URL,
1109
- correlationId,
1110
- },
1111
- connection: {
1112
- type: ConnectionType.SIOPv2,
1113
- config: {
1114
- idOpts: {
1115
- identifier: {
1116
- did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
1117
- provider: 'test_provider',
1118
- keys: [],
1119
- services: [],
1120
- },
1121
- },
1122
- redirectUrl: 'https://example.com',
1123
- stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
1124
- sessionId: 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
1125
- },
1126
- },
1127
- metadata: [
1128
- {
1129
- label: 'example_label',
1130
- value: 'example_value',
1131
- },
1132
- ],
1133
- }
1134
-
1135
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
1136
- identityEntity.party = savedParty
1137
-
1138
- const savedIdentity: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1139
-
1140
- expect(savedIdentity).toBeDefined()
1141
-
1142
- await dbConnection.getRepository(IdentityEntity).delete({ id: savedIdentity.id })
1143
-
1144
- // check identity
1145
- expect(
1146
- await dbConnection.getRepository(IdentityEntity).findOne({
1147
- where: { id: savedIdentity.id },
1148
- }),
1149
- ).toBeNull()
1150
-
1151
- // check party
1152
- expect(
1153
- await dbConnection.getRepository(PartyEntity).findOne({
1154
- where: { id: savedParty.id },
1155
- }),
1156
- ).toBeDefined()
1157
- })
1158
-
1159
- it('Should set creation date when saving party', async (): Promise<void> => {
1160
- const party: NonPersistedParty = {
1161
- uri: 'example.com',
1162
- partyType: {
1163
- type: PartyTypeType.NATURAL_PERSON,
1164
- origin: PartyOrigin.INTERNAL,
1165
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1166
- name: 'example_name',
1167
- },
1168
- contact: {
1169
- firstName: 'example_first_name',
1170
- middleName: 'example_middle_name',
1171
- lastName: 'example_last_name',
1172
- displayName: 'example_display_name',
1173
- },
1174
- }
1175
-
1176
- const partyEntity: PartyEntity = partyEntityFrom(party)
1177
- const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1178
-
1179
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1180
- where: { id: savedParty.id },
1181
- })
1182
-
1183
- expect(fromDb).toBeDefined()
1184
- expect(fromDb?.createdAt).toBeDefined()
1185
- })
1186
-
1187
- it('Should not update creation date when updating party', async (): Promise<void> => {
1188
- const party: NonPersistedParty = {
1189
- uri: 'example.com',
1190
- partyType: {
1191
- type: PartyTypeType.NATURAL_PERSON,
1192
- origin: PartyOrigin.INTERNAL,
1193
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1194
- name: 'example_name',
1195
- },
1196
- contact: {
1197
- firstName: 'example_first_name',
1198
- middleName: 'example_middle_name',
1199
- lastName: 'example_last_name',
1200
- displayName: 'example_display_name',
1201
- },
1202
- }
1203
-
1204
- const partyEntity: PartyEntity = partyEntityFrom(party)
1205
- const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1206
-
1207
- expect(savedParty).toBeDefined()
1208
-
1209
- const newContactFirstName = 'new_first_name'
1210
- await dbConnection.getRepository(PartyEntity).save({
1211
- ...savedParty,
1212
- contact: {
1213
- ...savedParty.contact,
1214
- firstName: newContactFirstName,
1215
- },
1216
- })
1217
-
1218
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1219
- where: { id: savedParty.id },
1220
- })
1221
-
1222
- expect(fromDb).toBeDefined()
1223
- expect((<NaturalPersonEntity>fromDb?.contact).firstName).toEqual(newContactFirstName)
1224
- expect(fromDb?.createdAt).toEqual(savedParty?.createdAt)
1225
- })
1226
-
1227
- it('Should set creation date when saving identity', async (): Promise<void> => {
1228
- const correlationId = 'example_did'
1229
- const identity: NonPersistedIdentity = {
1230
- alias: correlationId,
1231
- origin: IdentityOrigin.EXTERNAL,
1232
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1233
- identifier: {
1234
- type: CorrelationIdentifierType.DID,
1235
- correlationId,
1236
- },
1237
- }
1238
-
1239
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
1240
- await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1241
-
1242
- const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
1243
- where: {
1244
- identifier: {
1245
- correlationId,
1246
- },
1247
- },
1248
- })
1249
-
1250
- expect(fromDb).toBeDefined()
1251
- expect(fromDb?.createdAt).toBeDefined()
1252
- })
1253
-
1254
- it('Should not update creation date when saving identity', async (): Promise<void> => {
1255
- const correlationId = 'example_did'
1256
- const identity: NonPersistedIdentity = {
1257
- alias: correlationId,
1258
- origin: IdentityOrigin.EXTERNAL,
1259
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1260
- identifier: {
1261
- type: CorrelationIdentifierType.DID,
1262
- correlationId,
1263
- },
1264
- }
1265
-
1266
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
1267
- const savedIdentity: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1268
- const newCorrelationId = 'new_example_did'
1269
- await dbConnection
1270
- .getRepository(IdentityEntity)
1271
- .save({ ...savedIdentity, identifier: { ...savedIdentity.identifier, correlationId: newCorrelationId } })
1272
-
1273
- const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
1274
- where: {
1275
- identifier: {
1276
- correlationId: newCorrelationId,
1277
- },
1278
- },
1279
- })
1280
-
1281
- expect(fromDb).toBeDefined()
1282
- expect(fromDb?.createdAt).toEqual(savedIdentity?.createdAt)
1283
- })
1284
-
1285
- it('Should set last updated date when saving party', async (): Promise<void> => {
1286
- const party: NonPersistedParty = {
1287
- uri: 'example.com',
1288
- partyType: {
1289
- type: PartyTypeType.NATURAL_PERSON,
1290
- origin: PartyOrigin.INTERNAL,
1291
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1292
- name: 'example_name',
1293
- },
1294
- contact: {
1295
- firstName: 'example_first_name',
1296
- middleName: 'example_middle_name',
1297
- lastName: 'example_last_name',
1298
- displayName: 'example_display_name',
1299
- },
1300
- }
1301
-
1302
- const partyEntity: PartyEntity = partyEntityFrom(party)
1303
- const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1304
-
1305
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1306
- where: { id: savedParty.id },
1307
- })
1308
-
1309
- expect(fromDb).toBeDefined()
1310
- expect(fromDb?.lastUpdatedAt).toBeDefined()
1311
- })
1312
-
1313
- it('Should update last updated date when updating party', async (): Promise<void> => {
1314
- const party: NonPersistedParty = {
1315
- uri: 'example.com',
1316
- partyType: {
1317
- type: PartyTypeType.NATURAL_PERSON,
1318
- origin: PartyOrigin.EXTERNAL,
1319
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1320
- name: 'example_name',
1321
- },
1322
- contact: {
1323
- firstName: 'example_first_name',
1324
- middleName: 'example_middle_name',
1325
- lastName: 'example_last_name',
1326
- displayName: 'example_display_name',
1327
- },
1328
- }
1329
-
1330
- const partyEntity: PartyEntity = partyEntityFrom(party)
1331
- const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1332
- expect(savedParty).toBeDefined()
1333
-
1334
- // waiting here to get a different timestamp
1335
- await new Promise((resolve) => setTimeout(resolve, 2000))
1336
-
1337
- const newContactFirstName = 'new_first_name'
1338
- await dbConnection.getRepository(PartyEntity).save({
1339
- ...savedParty,
1340
- // FIXME there is still an issue when updating nested objects, the parent does not update
1341
- // https://github.com/typeorm/typeorm/issues/5378
1342
- uri: 'new uri', // TODO remove this to trigger the bug
1343
- contact: {
1344
- ...savedParty.contact,
1345
- firstName: newContactFirstName,
1346
- },
1347
- })
1348
-
1349
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1350
- where: { id: savedParty.id },
1351
- })
1352
-
1353
- expect(fromDb).toBeDefined()
1354
- expect((<NaturalPersonEntity>fromDb?.contact).firstName).toEqual(newContactFirstName)
1355
- expect(fromDb?.lastUpdatedAt).not.toEqual(savedParty?.lastUpdatedAt)
1356
- })
1357
-
1358
- it('Should set last updated date when saving party type', async (): Promise<void> => {
1359
- const partyType: NonPersistedPartyType = {
1360
- type: PartyTypeType.NATURAL_PERSON,
1361
- origin: PartyOrigin.EXTERNAL,
1362
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1363
- name: 'example_name',
1364
- }
1365
-
1366
- const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
1367
- const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
1368
-
1369
- const fromDb: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).findOne({
1370
- where: { id: savedPartyType.id },
1371
- })
1372
-
1373
- expect(fromDb).toBeDefined()
1374
- expect(fromDb?.lastUpdatedAt).toBeDefined()
1375
- })
1376
-
1377
- it('Should set last creation date when saving party type', async (): Promise<void> => {
1378
- const partyType: NonPersistedPartyType = {
1379
- type: PartyTypeType.NATURAL_PERSON,
1380
- origin: PartyOrigin.INTERNAL,
1381
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1382
- name: 'example_name',
1383
- }
1384
-
1385
- const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
1386
- const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
1387
-
1388
- const fromDb: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).findOne({
1389
- where: { id: savedPartyType.id },
1390
- })
1391
-
1392
- expect(fromDb).toBeDefined()
1393
- expect(fromDb?.createdAt).toBeDefined()
1394
- })
1395
-
1396
- it('Should set last updated date when saving identity', async (): Promise<void> => {
1397
- const correlationId = 'example_did'
1398
- const identity: NonPersistedIdentity = {
1399
- alias: correlationId,
1400
- origin: IdentityOrigin.EXTERNAL,
1401
- roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1402
- identifier: {
1403
- type: CorrelationIdentifierType.DID,
1404
- correlationId,
1405
- },
1406
- }
1407
-
1408
- const identityEntity: IdentityEntity = identityEntityFrom(identity)
1409
- await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1410
-
1411
- const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
1412
- where: {
1413
- identifier: {
1414
- correlationId,
1415
- },
1416
- },
1417
- })
1418
-
1419
- expect(fromDb).toBeDefined()
1420
- expect(fromDb?.lastUpdatedAt).toBeDefined()
1421
- })
1422
-
1423
- it('Should enforce unique type and tenant id combination when saving party type', async (): Promise<void> => {
1424
- const tenantId = 'non_unique_value'
1425
- const partyType1: NonPersistedPartyType = {
1426
- type: PartyTypeType.NATURAL_PERSON,
1427
- origin: PartyOrigin.EXTERNAL,
1428
- tenantId,
1429
- name: 'example_party_type_name1',
1430
- }
1431
-
1432
- const partyTypeEntity1: PartyTypeEntity = partyTypeEntityFrom(partyType1)
1433
- const savedPartyType1: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity1)
1434
-
1435
- expect(savedPartyType1).toBeDefined()
1436
-
1437
- const partyType2: NonPersistedPartyType = {
1438
- type: PartyTypeType.NATURAL_PERSON,
1439
- origin: PartyOrigin.INTERNAL,
1440
- tenantId,
1441
- name: 'example_party_type_name2',
1442
- }
1443
-
1444
- const partyTypeEntity2: PartyTypeEntity = partyTypeEntityFrom(partyType2)
1445
- await expect(dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity2)).rejects.toThrowError(
1446
- 'SQLITE_CONSTRAINT: UNIQUE constraint failed: PartyType.type, PartyType.tenant_id',
1447
- )
1448
- })
1449
-
1450
- it('Should enforce unique name when saving party type', async (): Promise<void> => {
1451
- const name = 'non_unique_value'
1452
- const partyType1: NonPersistedPartyType = {
1453
- type: PartyTypeType.NATURAL_PERSON,
1454
- origin: PartyOrigin.INTERNAL,
1455
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1456
- name,
1457
- }
1458
-
1459
- const partyTypeEntity1: PartyTypeEntity = partyTypeEntityFrom(partyType1)
1460
- const savedPartyType1: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity1)
1461
-
1462
- expect(savedPartyType1).toBeDefined()
1463
-
1464
- const partyType2: NonPersistedPartyType = {
1465
- type: PartyTypeType.NATURAL_PERSON,
1466
- origin: PartyOrigin.INTERNAL,
1467
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1468
- name,
1469
- }
1470
-
1471
- const partyTypeEntity2: PartyTypeEntity = partyTypeEntityFrom(partyType2)
1472
- await expect(dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity2)).rejects.toThrowError(
1473
- 'SQLITE_CONSTRAINT: UNIQUE constraint failed: PartyType.name',
1474
- )
1475
- })
1476
-
1477
- it('Should enforce unique legal name when saving organization', async (): Promise<void> => {
1478
- const legalName = 'non_unique_value'
1479
- const organization1: NonPersistedOrganization = {
1480
- legalName,
1481
- displayName: 'example_display_name',
1482
- }
1483
-
1484
- const organizationEntity1: OrganizationEntity = organizationEntityFrom(organization1)
1485
- const savedOrganization1: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity1, {
1486
- transaction: true,
1487
- })
1488
-
1489
- expect(savedOrganization1).toBeDefined()
1490
-
1491
- const organization2: NonPersistedOrganization = {
1492
- legalName,
1493
- displayName: 'example_display_name',
1494
- }
1495
-
1496
- const organizationEntity2: OrganizationEntity = organizationEntityFrom(organization2)
1497
- await expect(dbConnection.getRepository(OrganizationEntity).save(organizationEntity2)).rejects.toThrowError(
1498
- 'SQLITE_CONSTRAINT: UNIQUE constraint failed: BaseContact.legal_name',
1499
- )
1500
- })
1501
-
1502
- it('Should enforce unique legal name when saving organization', async (): Promise<void> => {
1503
- const legalName = 'example_legal_name'
1504
- const organization1: NonPersistedOrganization = {
1505
- legalName,
1506
- displayName: 'example_display_name',
1507
- }
1508
-
1509
- const organizationEntity1: OrganizationEntity = organizationEntityFrom(organization1)
1510
- const savedOrganization1: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity1, {
1511
- transaction: true,
1512
- })
1513
-
1514
- expect(savedOrganization1).toBeDefined()
1515
-
1516
- const organization2: NonPersistedOrganization = {
1517
- legalName,
1518
- displayName: 'example_display_name',
1519
- }
1520
-
1521
- const organizationEntity2: OrganizationEntity = organizationEntityFrom(organization2)
1522
- await expect(dbConnection.getRepository(OrganizationEntity).save(organizationEntity2)).rejects.toThrowError(
1523
- 'SQLITE_CONSTRAINT: UNIQUE constraint failed: BaseContact.legal_name',
1524
- )
1525
- })
1526
-
1527
- it('Should save party relationship to database', async (): Promise<void> => {
1528
- const party1: NonPersistedParty = {
1529
- uri: 'example1.com',
1530
- partyType: {
1531
- type: PartyTypeType.NATURAL_PERSON,
1532
- origin: PartyOrigin.INTERNAL,
1533
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1534
- name: 'example_name1',
1535
- },
1536
- contact: {
1537
- firstName: 'example_first_name1',
1538
- middleName: 'example_middle_name1',
1539
- lastName: 'example_last_name1',
1540
- displayName: 'example_display_name1',
1541
- },
1542
- }
1543
-
1544
- const partyEntity1: PartyEntity = partyEntityFrom(party1)
1545
- const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1546
- transaction: true,
1547
- })
1548
-
1549
- expect(savedParty1).toBeDefined()
1550
-
1551
- const party2: NonPersistedParty = {
1552
- uri: 'example2.com',
1553
- partyType: {
1554
- type: PartyTypeType.NATURAL_PERSON,
1555
- origin: PartyOrigin.INTERNAL,
1556
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1557
- name: 'example_name2',
1558
- },
1559
- contact: {
1560
- firstName: 'example_first_name2',
1561
- middleName: 'example_middle_name2',
1562
- lastName: 'example_last_name2',
1563
- displayName: 'example_display_name2',
1564
- },
1565
- }
1566
-
1567
- const partyEntity2: PartyEntity = partyEntityFrom(party2)
1568
- const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1569
- transaction: true,
1570
- })
1571
-
1572
- expect(savedParty2).toBeDefined()
1573
-
1574
- const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
1575
- leftId: savedParty1.id,
1576
- rightId: savedParty2.id,
1577
- })
1578
-
1579
- await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
1580
- transaction: true,
1581
- })
1582
-
1583
- // TODO check the relation field
1584
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1585
- where: { id: partyEntity1.id },
1586
- })
1587
-
1588
- expect(fromDb).toBeDefined()
1589
- })
1590
-
1591
- it('Should set last updated date when saving party relationship', async (): Promise<void> => {
1592
- const party1: NonPersistedParty = {
1593
- uri: 'example1.com',
1594
- partyType: {
1595
- type: PartyTypeType.NATURAL_PERSON,
1596
- origin: PartyOrigin.INTERNAL,
1597
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1598
- name: 'example_name1',
1599
- },
1600
- contact: {
1601
- firstName: 'example_first_name1',
1602
- middleName: 'example_middle_name1',
1603
- lastName: 'example_last_name1',
1604
- displayName: 'example_display_name1',
1605
- },
1606
- }
1607
-
1608
- const partyEntity1: PartyEntity = partyEntityFrom(party1)
1609
- const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1610
- transaction: true,
1611
- })
1612
-
1613
- const party2: NonPersistedParty = {
1614
- uri: 'example2.com',
1615
- partyType: {
1616
- type: PartyTypeType.NATURAL_PERSON,
1617
- origin: PartyOrigin.INTERNAL,
1618
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1619
- name: 'example_name2',
1620
- },
1621
- contact: {
1622
- firstName: 'example_first_name2',
1623
- middleName: 'example_middle_name2',
1624
- lastName: 'example_last_name2',
1625
- displayName: 'example_display_name2',
1626
- },
1627
- }
1628
-
1629
- const partyEntity2: PartyEntity = partyEntityFrom(party2)
1630
- const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1631
- transaction: true,
1632
- })
1633
-
1634
- const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
1635
- leftId: savedParty1.id,
1636
- rightId: savedParty2.id,
1637
- })
1638
-
1639
- await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
1640
- transaction: true,
1641
- })
1642
-
1643
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1644
- where: { id: partyEntity1.id },
1645
- })
1646
-
1647
- expect(fromDb).toBeDefined()
1648
- expect(fromDb?.lastUpdatedAt).toBeDefined()
1649
- })
1650
-
1651
- it('Should set creation date when saving party relationship', async (): Promise<void> => {
1652
- const party1: NonPersistedParty = {
1653
- uri: 'example1.com',
1654
- partyType: {
1655
- type: PartyTypeType.NATURAL_PERSON,
1656
- origin: PartyOrigin.INTERNAL,
1657
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1658
- name: 'example_name1',
1659
- },
1660
- contact: {
1661
- firstName: 'example_first_name1',
1662
- middleName: 'example_middle_name1',
1663
- lastName: 'example_last_name1',
1664
- displayName: 'example_display_name1',
1665
- },
1666
- }
1667
-
1668
- const partyEntity1: PartyEntity = partyEntityFrom(party1)
1669
- const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1670
- transaction: true,
1671
- })
1672
-
1673
- const party2: NonPersistedParty = {
1674
- uri: 'example2.com',
1675
- partyType: {
1676
- type: PartyTypeType.NATURAL_PERSON,
1677
- origin: PartyOrigin.INTERNAL,
1678
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1679
- name: 'example_name2',
1680
- },
1681
- contact: {
1682
- firstName: 'example_first_name2',
1683
- middleName: 'example_middle_name2',
1684
- lastName: 'example_last_name2',
1685
- displayName: 'example_display_name2',
1686
- },
1687
- }
1688
-
1689
- const partyEntity2: PartyEntity = partyEntityFrom(party2)
1690
- const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1691
- transaction: true,
1692
- })
1693
-
1694
- const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
1695
- leftId: savedParty1.id,
1696
- rightId: savedParty2.id,
1697
- })
1698
-
1699
- await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
1700
- transaction: true,
1701
- })
1702
-
1703
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1704
- where: { id: partyEntity1.id },
1705
- })
1706
-
1707
- expect(fromDb).toBeDefined()
1708
- expect(fromDb?.createdAt).toBeDefined()
1709
- })
1710
-
1711
- it('Should save bidirectional party relationships to database', async (): Promise<void> => {
1712
- const party1: NonPersistedParty = {
1713
- uri: 'example1.com',
1714
- partyType: {
1715
- type: PartyTypeType.NATURAL_PERSON,
1716
- origin: PartyOrigin.INTERNAL,
1717
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1718
- name: 'example_name1',
1719
- },
1720
- contact: {
1721
- firstName: 'example_first_name1',
1722
- middleName: 'example_middle_name1',
1723
- lastName: 'example_last_name1',
1724
- displayName: 'example_display_name1',
1725
- },
1726
- }
1727
-
1728
- const partyEntity1: PartyEntity = partyEntityFrom(party1)
1729
- const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1730
- transaction: true,
1731
- })
1732
-
1733
- expect(savedParty1).toBeDefined()
1734
-
1735
- const party2: NonPersistedParty = {
1736
- uri: 'example2.com',
1737
- partyType: {
1738
- type: PartyTypeType.NATURAL_PERSON,
1739
- origin: PartyOrigin.INTERNAL,
1740
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1741
- name: 'example_name2',
1742
- },
1743
- contact: {
1744
- firstName: 'example_first_name2',
1745
- middleName: 'example_middle_name2',
1746
- lastName: 'example_last_name2',
1747
- displayName: 'example_display_name2',
1748
- },
1749
- }
1750
-
1751
- const partyEntity2: PartyEntity = partyEntityFrom(party2)
1752
- const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1753
- transaction: true,
1754
- })
1755
-
1756
- expect(savedParty2).toBeDefined()
1757
-
1758
- const relationship1: PartyRelationshipEntity = partyRelationshipEntityFrom({
1759
- leftId: savedParty1.id,
1760
- rightId: savedParty2.id,
1761
- })
1762
-
1763
- const savedRelationship1: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship1, {
1764
- transaction: true,
1765
- })
1766
-
1767
- expect(savedRelationship1).toBeDefined()
1768
-
1769
- const relationship2: PartyRelationshipEntity = partyRelationshipEntityFrom({
1770
- leftId: savedParty2.id,
1771
- rightId: savedParty1.id,
1772
- })
1773
-
1774
- const savedRelationship2: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship2, {
1775
- transaction: true,
1776
- })
1777
-
1778
- expect(savedRelationship2).toBeDefined()
1779
-
1780
- const fromDb: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).findOne({
1781
- where: { id: savedRelationship2.id },
1782
- })
1783
-
1784
- expect(fromDb).toBeDefined()
1785
- })
1786
-
1787
- it('Should enforce unique owner combination for party relationship', async (): Promise<void> => {
1788
- const party1: NonPersistedParty = {
1789
- uri: 'example1.com',
1790
- partyType: {
1791
- type: PartyTypeType.NATURAL_PERSON,
1792
- origin: PartyOrigin.INTERNAL,
1793
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1794
- name: 'example_name1',
1795
- },
1796
- contact: {
1797
- firstName: 'example_first_name1',
1798
- middleName: 'example_middle_name1',
1799
- lastName: 'example_last_name1',
1800
- displayName: 'example_display_name1',
1801
- },
1802
- }
1803
-
1804
- const partyEntity1: PartyEntity = partyEntityFrom(party1)
1805
- const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1806
- transaction: true,
1807
- })
1808
-
1809
- expect(savedParty1).toBeDefined()
1810
-
1811
- const party2: NonPersistedParty = {
1812
- uri: 'example2.com',
1813
- partyType: {
1814
- type: PartyTypeType.NATURAL_PERSON,
1815
- origin: PartyOrigin.INTERNAL,
1816
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1817
- name: 'example_name2',
1818
- },
1819
- contact: {
1820
- firstName: 'example_first_name2',
1821
- middleName: 'example_middle_name2',
1822
- lastName: 'example_last_name2',
1823
- displayName: 'example_display_name2',
1824
- },
1825
- }
1826
-
1827
- const partyEntity2: PartyEntity = partyEntityFrom(party2)
1828
- const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1829
- transaction: true,
1830
- })
1831
-
1832
- expect(savedParty2).toBeDefined()
1833
-
1834
- const relationship1: PartyRelationshipEntity = partyRelationshipEntityFrom({
1835
- leftId: savedParty1.id,
1836
- rightId: savedParty2.id,
1837
- })
1838
-
1839
- const savedRelationship1: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship1, {
1840
- transaction: true,
1841
- })
1842
-
1843
- expect(savedRelationship1).toBeDefined()
1844
-
1845
- const relationship2: PartyRelationshipEntity = partyRelationshipEntityFrom({
1846
- leftId: savedParty1.id,
1847
- rightId: savedParty2.id,
1848
- })
1849
-
1850
- await expect(dbConnection.getRepository(PartyRelationshipEntity).save(relationship2)).rejects.toThrowError(
1851
- 'SQLITE_CONSTRAINT: UNIQUE constraint failed: PartyRelationship.left_id, PartyRelationship.right_id',
1852
- )
1853
- })
1854
-
1855
- it('Should save party type to database', async (): Promise<void> => {
1856
- const partyType: NonPersistedPartyType = {
1857
- type: PartyTypeType.NATURAL_PERSON,
1858
- origin: PartyOrigin.INTERNAL,
1859
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1860
- name: 'example_name',
1861
- }
1862
-
1863
- const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
1864
- const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
1865
-
1866
- const fromDb: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).findOne({
1867
- where: { id: savedPartyType.id },
1868
- })
1869
-
1870
- expect(fromDb).toBeDefined()
1871
- })
1872
-
1873
- it('Should save person to database', async (): Promise<void> => {
1874
- const person: NonPersistedNaturalPerson = {
1875
- firstName: 'example_first_name',
1876
- lastName: 'lastName2',
1877
- displayName: 'displayName',
1878
- }
1879
-
1880
- const personEntity: NaturalPersonEntity = naturalPersonEntityFrom(person)
1881
- const savedPerson: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).save(personEntity, {
1882
- transaction: true,
1883
- })
1884
-
1885
- const fromDb: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).findOne({
1886
- where: { id: savedPerson.id },
1887
- })
1888
-
1889
- expect(fromDb).toBeDefined()
1890
- })
1891
-
1892
- it('Should set last updated date when saving person', async (): Promise<void> => {
1893
- const person: NonPersistedNaturalPerson = {
1894
- firstName: 'example_first_name',
1895
- lastName: 'lastName2',
1896
- displayName: 'displayName',
1897
- }
1898
-
1899
- const personEntity: NaturalPersonEntity = naturalPersonEntityFrom(person)
1900
- const savedPerson: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).save(personEntity, {
1901
- transaction: true,
1902
- })
1903
-
1904
- const fromDb: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).findOne({
1905
- where: { id: savedPerson.id },
1906
- })
1907
-
1908
- expect(fromDb).toBeDefined()
1909
- expect(fromDb?.lastUpdatedAt).toBeDefined()
1910
- })
1911
-
1912
- it('Should set creation date when saving person', async (): Promise<void> => {
1913
- const person: NonPersistedNaturalPerson = {
1914
- firstName: 'example_first_name',
1915
- lastName: 'lastName2',
1916
- displayName: 'displayName',
1917
- }
1918
-
1919
- const personEntity: NaturalPersonEntity = naturalPersonEntityFrom(person)
1920
- const savedPerson: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).save(personEntity, {
1921
- transaction: true,
1922
- })
1923
-
1924
- const fromDb: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).findOne({
1925
- where: { id: savedPerson.id },
1926
- })
1927
-
1928
- expect(fromDb).toBeDefined()
1929
- expect(fromDb?.createdAt).toBeDefined()
1930
- })
1931
-
1932
- it('Should save organization to database', async (): Promise<void> => {
1933
- const organization: NonPersistedOrganization = {
1934
- legalName: 'example_legal_name',
1935
- displayName: 'example_display_name',
1936
- }
1937
-
1938
- const organizationEntity: OrganizationEntity = organizationEntityFrom(organization)
1939
- const savedOrganization: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity, {
1940
- transaction: true,
1941
- })
1942
-
1943
- const fromDb: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).findOne({
1944
- where: { id: savedOrganization.id },
1945
- })
1946
-
1947
- expect(fromDb).toBeDefined()
1948
- })
1949
-
1950
- it('Should set last updated date when saving organization', async (): Promise<void> => {
1951
- const organization: NonPersistedOrganization = {
1952
- legalName: 'example_legal_name',
1953
- displayName: 'example_display_name',
1954
- }
1955
-
1956
- const organizationEntity: OrganizationEntity = organizationEntityFrom(organization)
1957
- const savedOrganization: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity, {
1958
- transaction: true,
1959
- })
1960
-
1961
- const fromDb: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).findOne({
1962
- where: { id: savedOrganization.id },
1963
- })
1964
-
1965
- expect(fromDb).toBeDefined()
1966
- expect(fromDb?.lastUpdatedAt).toBeDefined()
1967
- })
1968
-
1969
- it('Should set creation date when saving organization', async (): Promise<void> => {
1970
- const organization: NonPersistedOrganization = {
1971
- legalName: 'example_legal_name',
1972
- displayName: 'example_display_name',
1973
- }
1974
-
1975
- const organizationEntity: OrganizationEntity = organizationEntityFrom(organization)
1976
- const savedOrganization: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity, {
1977
- transaction: true,
1978
- })
1979
-
1980
- const fromDb: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).findOne({
1981
- where: { id: savedOrganization.id },
1982
- })
1983
-
1984
- expect(fromDb).toBeDefined()
1985
- expect(fromDb?.createdAt).toBeDefined()
1986
- })
1987
-
1988
- it('Should get party based on person information', async (): Promise<void> => {
1989
- const firstName = 'example_first_name'
1990
- const party: NonPersistedParty = {
1991
- uri: 'example.com',
1992
- partyType: {
1993
- type: PartyTypeType.NATURAL_PERSON,
1994
- origin: PartyOrigin.INTERNAL,
1995
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1996
- name: 'example_name',
1997
- },
1998
- contact: {
1999
- firstName,
2000
- middleName: 'example_middle_name',
2001
- lastName: 'example_last_name',
2002
- displayName: 'example_display_name',
2003
- },
2004
- }
2005
-
2006
- const partyEntity: PartyEntity = partyEntityFrom(party)
2007
- await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2008
- transaction: true,
2009
- })
2010
-
2011
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
2012
- where: {
2013
- contact: {
2014
- firstName,
2015
- } as FindOptionsWhere<BaseContactEntity>, //NaturalPersonEntity | OrganizationEntity
2016
- },
2017
- })
2018
-
2019
- expect(fromDb).toBeDefined()
2020
- })
2021
-
2022
- it('Should get party based on organization information', async (): Promise<void> => {
2023
- const legalName = 'example_legal_name'
2024
- const party: NonPersistedParty = {
2025
- uri: 'example.com',
2026
- partyType: {
2027
- type: PartyTypeType.ORGANIZATION,
2028
- origin: PartyOrigin.INTERNAL,
2029
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2030
- name: 'example_name',
2031
- },
2032
- contact: {
2033
- legalName,
2034
- displayName: 'example_display_name',
2035
- },
2036
- }
2037
-
2038
- const partyEntity: PartyEntity = partyEntityFrom(party)
2039
- await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2040
- transaction: true,
2041
- })
2042
-
2043
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
2044
- where: {
2045
- contact: {
2046
- legalName,
2047
- } as FindOptionsWhere<BaseContactEntity>, //NaturalPersonEntity | OrganizationEntity
2048
- },
2049
- })
2050
-
2051
- expect(fromDb).toBeDefined()
2052
- })
2053
-
2054
- it("Should enforce unique party id's for relationship sides", async (): Promise<void> => {
2055
- const party: NonPersistedParty = {
2056
- uri: 'example.com',
2057
- partyType: {
2058
- type: PartyTypeType.NATURAL_PERSON,
2059
- origin: PartyOrigin.INTERNAL,
2060
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2061
- name: 'example_name',
2062
- },
2063
- contact: {
2064
- firstName: 'example_first_name',
2065
- middleName: 'example_middle_name',
2066
- lastName: 'example_last_name',
2067
- displayName: 'example_display_name',
2068
- },
2069
- }
2070
-
2071
- const partyEntity: PartyEntity = partyEntityFrom(party)
2072
- const savedParty: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2073
- transaction: true,
2074
- })
2075
-
2076
- expect(savedParty).toBeDefined()
2077
-
2078
- const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
2079
- leftId: savedParty.id,
2080
- rightId: savedParty.id,
2081
- })
2082
-
2083
- await expect(dbConnection.getRepository(PartyRelationshipEntity).save(relationship)).rejects.toThrowError(
2084
- 'Cannot use the same id for both sides of the relationship',
2085
- )
2086
- })
2087
-
2088
- it('Should delete party relationship', async (): Promise<void> => {
2089
- const party1: NonPersistedParty = {
2090
- uri: 'example1.com',
2091
- partyType: {
2092
- type: PartyTypeType.NATURAL_PERSON,
2093
- origin: PartyOrigin.INTERNAL,
2094
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2095
- name: 'example_name1',
2096
- },
2097
- contact: {
2098
- firstName: 'example_first_name1',
2099
- middleName: 'example_middle_name1',
2100
- lastName: 'example_last_name1',
2101
- displayName: 'example_display_name1',
2102
- },
2103
- }
2104
-
2105
- const partyEntity1: PartyEntity = partyEntityFrom(party1)
2106
- const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
2107
- transaction: true,
2108
- })
2109
-
2110
- expect(savedParty1).toBeDefined()
2111
-
2112
- const party2: NonPersistedParty = {
2113
- uri: 'example2.com',
2114
- partyType: {
2115
- type: PartyTypeType.NATURAL_PERSON,
2116
- origin: PartyOrigin.INTERNAL,
2117
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
2118
- name: 'example_name2',
2119
- },
2120
- contact: {
2121
- firstName: 'example_first_name2',
2122
- middleName: 'example_middle_name2',
2123
- lastName: 'example_last_name2',
2124
- displayName: 'example_display_name2',
2125
- },
2126
- }
2127
-
2128
- const partyEntity2: PartyEntity = partyEntityFrom(party2)
2129
- const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
2130
- transaction: true,
2131
- })
2132
-
2133
- expect(savedParty2).toBeDefined()
2134
-
2135
- const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
2136
- leftId: savedParty1.id,
2137
- rightId: savedParty2.id,
2138
- })
2139
-
2140
- const savedRelationship: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
2141
- transaction: true,
2142
- })
2143
-
2144
- expect(savedRelationship).toBeDefined()
2145
-
2146
- await dbConnection.getRepository(PartyRelationshipEntity).delete({ id: savedRelationship.id })
2147
-
2148
- await expect(
2149
- await dbConnection.getRepository(PartyRelationshipEntity).findOne({
2150
- where: { id: savedRelationship.id },
2151
- }),
2152
- ).toBeNull()
2153
- })
2154
-
2155
- it('Should delete party type', async (): Promise<void> => {
2156
- const partyType: NonPersistedPartyType = {
2157
- type: PartyTypeType.NATURAL_PERSON,
2158
- origin: PartyOrigin.INTERNAL,
2159
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2160
- name: 'example_name',
2161
- }
2162
-
2163
- const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
2164
- const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
2165
-
2166
- expect(savedPartyType).toBeDefined()
2167
-
2168
- await dbConnection.getRepository(PartyTypeEntity).delete({ id: savedPartyType.id })
2169
-
2170
- await expect(
2171
- await dbConnection.getRepository(PartyTypeEntity).findOne({
2172
- where: { id: savedPartyType.id },
2173
- }),
2174
- ).toBeNull()
2175
- })
2176
-
2177
- it('Should not be able to remove party type when used by parties', async (): Promise<void> => {
2178
- const party: NonPersistedParty = {
2179
- uri: 'example.com',
2180
- partyType: {
2181
- type: PartyTypeType.NATURAL_PERSON,
2182
- origin: PartyOrigin.INTERNAL,
2183
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2184
- name: 'example_name',
2185
- },
2186
- contact: {
2187
- firstName: 'example_first_name',
2188
- middleName: 'example_middle_name',
2189
- lastName: 'example_last_name',
2190
- displayName: 'example_display_name',
2191
- },
2192
- }
2193
-
2194
- const partyEntity: PartyEntity = partyEntityFrom(party)
2195
- const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2196
- transaction: true,
2197
- })
2198
-
2199
- expect(savedParty).toBeDefined()
2200
-
2201
- await expect(dbConnection.getRepository(PartyTypeEntity).delete({ id: savedParty.partyType.id })).rejects.toThrowError(
2202
- 'FOREIGN KEY constraint failed',
2203
- )
2204
- })
2205
-
2206
- it('Should save party with existing party type', async (): Promise<void> => {
2207
- const partyType: NonPersistedPartyType = {
2208
- type: PartyTypeType.NATURAL_PERSON,
2209
- origin: PartyOrigin.INTERNAL,
2210
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2211
- name: 'example_name',
2212
- }
2213
-
2214
- const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
2215
- const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
2216
-
2217
- const party: NonPersistedParty = {
2218
- uri: 'example.com',
2219
- partyType: partyTypeFrom(savedPartyType),
2220
- contact: {
2221
- firstName: 'example_first_name',
2222
- middleName: 'example_middle_name',
2223
- lastName: 'example_last_name',
2224
- displayName: 'example_display_name',
2225
- },
2226
- }
2227
-
2228
- const partyEntity: PartyEntity = partyEntityFrom(party)
2229
- partyEntity.partyType = savedPartyType
2230
- await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2231
- transaction: true,
2232
- })
2233
-
2234
- const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
2235
- where: { id: partyEntity.id },
2236
- })
2237
-
2238
- expect(fromDb).toBeDefined()
2239
- expect(fromDb?.partyType).toBeDefined()
2240
- expect(fromDb?.partyType.id).toEqual(savedPartyType.id)
2241
- expect(fromDb?.partyType.type).toEqual(savedPartyType.type)
2242
- expect(fromDb?.partyType.origin).toEqual(savedPartyType.origin)
2243
- expect(fromDb?.partyType.tenantId).toEqual(savedPartyType.tenantId)
2244
- expect(fromDb?.partyType.name).toEqual(savedPartyType.name)
2245
- })
2246
-
2247
- it('Should not update creation date when saving party type', async (): Promise<void> => {
2248
- const partyType: NonPersistedPartyType = {
2249
- type: PartyTypeType.NATURAL_PERSON,
2250
- origin: PartyOrigin.INTERNAL,
2251
- tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2252
- name: 'example_name',
2253
- }
2254
-
2255
- const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
2256
- const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
2257
- await dbConnection.getRepository(PartyTypeEntity).save({ ...savedPartyType, type: PartyTypeType.ORGANIZATION })
2258
-
2259
- const fromDb: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).findOne({
2260
- where: {
2261
- type: PartyTypeType.ORGANIZATION,
2262
- },
2263
- })
2264
-
2265
- expect(fromDb).toBeDefined()
2266
- expect(fromDb?.createdAt).toEqual(savedPartyType?.createdAt)
2267
- })
2268
-
2269
- it('Should save email electronic address to database', async (): Promise<void> => {
2270
- const electronicAddress: NonPersistedElectronicAddress = {
2271
- type: 'email',
2272
- electronicAddress: 'example_email_address',
2273
- }
2274
-
2275
- const electronicAddressEntity: ElectronicAddressEntity = electronicAddressEntityFrom(electronicAddress)
2276
- const savedElectronicAddress: ElectronicAddressEntity = await dbConnection.getRepository(ElectronicAddressEntity).save(electronicAddressEntity, {
2277
- transaction: true,
2278
- })
2279
-
2280
- const fromDb: ElectronicAddressEntity | null = await dbConnection.getRepository(ElectronicAddressEntity).findOne({
2281
- where: { id: savedElectronicAddress.id },
2282
- })
2283
-
2284
- expect(fromDb).toBeDefined()
2285
- expect(fromDb?.type).toEqual(electronicAddress.type)
2286
- expect(fromDb?.electronicAddress).toEqual(electronicAddress.electronicAddress)
2287
- expect(fromDb?.createdAt).toBeDefined()
2288
- expect(fromDb?.lastUpdatedAt).toBeDefined()
2289
- })
2290
-
2291
- it('Should save phone electronic address to database', async (): Promise<void> => {
2292
- const electronicAddress: NonPersistedElectronicAddress = {
2293
- type: 'phone',
2294
- electronicAddress: 'example_phone_number',
2295
- }
2296
-
2297
- const electronicAddressEntity: ElectronicAddressEntity = electronicAddressEntityFrom(electronicAddress)
2298
- const savedElectronicAddress: ElectronicAddressEntity = await dbConnection.getRepository(ElectronicAddressEntity).save(electronicAddressEntity, {
2299
- transaction: true,
2300
- })
2301
-
2302
- const fromDb: ElectronicAddressEntity | null = await dbConnection.getRepository(ElectronicAddressEntity).findOne({
2303
- where: { id: savedElectronicAddress.id },
2304
- })
2305
-
2306
- expect(fromDb).toBeDefined()
2307
- expect(fromDb?.type).toEqual(electronicAddress.type)
2308
- expect(fromDb?.electronicAddress).toEqual(electronicAddress.electronicAddress)
2309
- expect(fromDb?.createdAt).toBeDefined()
2310
- expect(fromDb?.lastUpdatedAt).toBeDefined()
2311
- })
2312
-
2313
- it('should throw error when saving electronic address with blank electronic address', async (): Promise<void> => {
2314
- const electronicAddress: NonPersistedElectronicAddress = {
2315
- type: 'email',
2316
- electronicAddress: '',
2317
- }
2318
-
2319
- const electronicAddressEntity: ElectronicAddressEntity = electronicAddressEntityFrom(electronicAddress)
2320
-
2321
- await expect(dbConnection.getRepository(ElectronicAddressEntity).save(electronicAddressEntity)).rejects.toThrowError(
2322
- 'Blank electronic addresses are not allowed',
2323
- )
2324
- })
2325
-
2326
- it('Should save home physical address to database', async (): Promise<void> => {
2327
- const physicalAddress: NonPersistedPhysicalAddress = {
2328
- type: 'home',
2329
- streetName: 'example_street_name',
2330
- streetNumber: 'example_street_number',
2331
- buildingName: 'example_building_name',
2332
- postalCode: 'example_postal_code',
2333
- cityName: 'example_city_name',
2334
- provinceName: 'example_province_name',
2335
- countryCode: 'example_country_code',
2336
- }
2337
-
2338
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2339
- const savedPhysicalAddress: PhysicalAddressEntity = await dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity, {
2340
- transaction: true,
2341
- })
2342
-
2343
- const fromDb: PhysicalAddressEntity | null = await dbConnection.getRepository(PhysicalAddressEntity).findOne({
2344
- where: { id: savedPhysicalAddress.id },
2345
- })
2346
-
2347
- expect(fromDb).toBeDefined()
2348
- expect(fromDb?.type).toEqual(physicalAddress.type)
2349
- expect(fromDb?.streetName).toEqual(physicalAddress.streetName)
2350
- expect(fromDb?.streetNumber).toEqual(physicalAddress.streetNumber)
2351
- expect(fromDb?.buildingName).toEqual(physicalAddress.buildingName)
2352
- expect(fromDb?.postalCode).toEqual(physicalAddress.postalCode)
2353
- expect(fromDb?.cityName).toEqual(physicalAddress.cityName)
2354
- expect(fromDb?.provinceName).toEqual(physicalAddress.provinceName)
2355
- expect(fromDb?.countryCode).toEqual(physicalAddress.countryCode)
2356
- expect(fromDb?.createdAt).toBeDefined()
2357
- expect(fromDb?.lastUpdatedAt).toBeDefined()
2358
- })
2359
-
2360
- it('Should save visit physical address to database', async (): Promise<void> => {
2361
- const physicalAddress: NonPersistedPhysicalAddress = {
2362
- type: 'visit',
2363
- streetName: 'example_street_name',
2364
- streetNumber: 'example_street_number',
2365
- buildingName: 'example_building_name',
2366
- postalCode: 'example_postal_code',
2367
- cityName: 'example_city_name',
2368
- provinceName: 'example_province_name',
2369
- countryCode: 'example_country_code',
2370
- }
2371
-
2372
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2373
- const savedPhysicalAddress: PhysicalAddressEntity = await dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity, {
2374
- transaction: true,
2375
- })
2376
-
2377
- const fromDb: PhysicalAddressEntity | null = await dbConnection.getRepository(PhysicalAddressEntity).findOne({
2378
- where: { id: savedPhysicalAddress.id },
2379
- })
2380
-
2381
- expect(fromDb).toBeDefined()
2382
- expect(fromDb?.type).toEqual(physicalAddress.type)
2383
- expect(fromDb?.streetName).toEqual(physicalAddress.streetName)
2384
- expect(fromDb?.streetNumber).toEqual(physicalAddress.streetNumber)
2385
- expect(fromDb?.buildingName).toEqual(physicalAddress.buildingName)
2386
- expect(fromDb?.postalCode).toEqual(physicalAddress.postalCode)
2387
- expect(fromDb?.cityName).toEqual(physicalAddress.cityName)
2388
- expect(fromDb?.provinceName).toEqual(physicalAddress.provinceName)
2389
- expect(fromDb?.countryCode).toEqual(physicalAddress.countryCode)
2390
- expect(fromDb?.createdAt).toBeDefined()
2391
- expect(fromDb?.lastUpdatedAt).toBeDefined()
2392
- })
2393
-
2394
- it('Should save postal physical address to database', async (): Promise<void> => {
2395
- const physicalAddress: NonPersistedPhysicalAddress = {
2396
- type: 'postal',
2397
- streetName: 'example_street_name',
2398
- streetNumber: 'example_street_number',
2399
- buildingName: 'example_building_name',
2400
- postalCode: 'example_postal_code',
2401
- cityName: 'example_city_name',
2402
- provinceName: 'example_province_name',
2403
- countryCode: 'example_country_code',
2404
- }
2405
-
2406
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2407
- const savedPhysicalAddress: PhysicalAddressEntity = await dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity, {
2408
- transaction: true,
2409
- })
2410
-
2411
- const fromDb: PhysicalAddressEntity | null = await dbConnection.getRepository(PhysicalAddressEntity).findOne({
2412
- where: { id: savedPhysicalAddress.id },
2413
- })
2414
-
2415
- expect(fromDb).toBeDefined()
2416
- expect(fromDb?.type).toEqual(physicalAddress.type)
2417
- expect(fromDb?.streetName).toEqual(physicalAddress.streetName)
2418
- expect(fromDb?.streetNumber).toEqual(physicalAddress.streetNumber)
2419
- expect(fromDb?.buildingName).toEqual(physicalAddress.buildingName)
2420
- expect(fromDb?.postalCode).toEqual(physicalAddress.postalCode)
2421
- expect(fromDb?.cityName).toEqual(physicalAddress.cityName)
2422
- expect(fromDb?.provinceName).toEqual(physicalAddress.provinceName)
2423
- expect(fromDb?.countryCode).toEqual(physicalAddress.countryCode)
2424
- expect(fromDb?.createdAt).toBeDefined()
2425
- expect(fromDb?.lastUpdatedAt).toBeDefined()
2426
- })
2427
-
2428
- it('should throw error when saving physical address with blank street name', async (): Promise<void> => {
2429
- const physicalAddress: NonPersistedPhysicalAddress = {
2430
- type: 'home',
2431
- streetName: '',
2432
- streetNumber: 'example_street_number',
2433
- buildingName: 'example_building_name',
2434
- postalCode: 'example_postal_code',
2435
- cityName: 'example_city_name',
2436
- provinceName: 'example_province_name',
2437
- countryCode: 'example_country_code',
2438
- }
2439
-
2440
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2441
-
2442
- await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2443
- 'Blank street names are not allowed',
2444
- )
2445
- })
2446
-
2447
- it('should throw error when saving physical address with blank street number', async (): Promise<void> => {
2448
- const physicalAddress: NonPersistedPhysicalAddress = {
2449
- type: 'home',
2450
- streetName: 'example_street_name',
2451
- streetNumber: '',
2452
- buildingName: 'example_building_name',
2453
- postalCode: 'example_postal_code',
2454
- cityName: 'example_city_name',
2455
- provinceName: 'example_province_name',
2456
- countryCode: 'example_country_code',
2457
- }
2458
-
2459
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2460
-
2461
- await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2462
- 'Blank street numbers are not allowed',
2463
- )
2464
- })
2465
-
2466
- it('should throw error when saving physical address with blank building name', async (): Promise<void> => {
2467
- const physicalAddress: NonPersistedPhysicalAddress = {
2468
- type: 'home',
2469
- streetName: 'example_street_name',
2470
- streetNumber: 'example_street_number',
2471
- buildingName: '',
2472
- postalCode: 'example_postal_code',
2473
- cityName: 'example_city_name',
2474
- provinceName: 'example_province_name',
2475
- countryCode: 'example_country_code',
2476
- }
2477
-
2478
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2479
-
2480
- await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2481
- 'Blank building names are not allowed',
2482
- )
2483
- })
2484
-
2485
- it('should throw error when saving physical address with blank postal code', async (): Promise<void> => {
2486
- const physicalAddress: NonPersistedPhysicalAddress = {
2487
- type: 'home',
2488
- streetName: 'example_street_name',
2489
- streetNumber: 'example_street_number',
2490
- buildingName: 'example_building_name',
2491
- postalCode: '',
2492
- cityName: 'example_city_name',
2493
- provinceName: 'example_province_name',
2494
- countryCode: 'example_country_code',
2495
- }
2496
-
2497
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2498
-
2499
- await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2500
- 'Blank postal codes are not allowed',
2501
- )
2502
- })
2503
-
2504
- it('should throw error when saving physical address with blank city name', async (): Promise<void> => {
2505
- const physicalAddress: NonPersistedPhysicalAddress = {
2506
- type: 'home',
2507
- streetName: 'example_street_name',
2508
- streetNumber: 'example_street_number',
2509
- buildingName: 'example_building_name',
2510
- postalCode: 'example_postal_code',
2511
- cityName: '',
2512
- provinceName: 'example_province_name',
2513
- countryCode: 'example_country_code',
2514
- }
2515
-
2516
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2517
-
2518
- await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2519
- 'Blank city names are not allowed',
2520
- )
2521
- })
2522
-
2523
- it('should throw error when saving physical address with blank province name', async (): Promise<void> => {
2524
- const physicalAddress: NonPersistedPhysicalAddress = {
2525
- type: 'home',
2526
- streetName: 'example_street_name',
2527
- streetNumber: 'example_street_number',
2528
- buildingName: 'example_building_name',
2529
- postalCode: 'example_postal_code',
2530
- cityName: 'example_city_name',
2531
- provinceName: '',
2532
- countryCode: 'example_country_code',
2533
- }
2534
-
2535
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2536
-
2537
- await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2538
- 'Blank province names are not allowed',
2539
- )
2540
- })
2541
-
2542
- it('should throw error when saving physical address with blank country code', async (): Promise<void> => {
2543
- const physicalAddress: NonPersistedPhysicalAddress = {
2544
- type: 'home',
2545
- streetName: 'example_street_name',
2546
- streetNumber: 'example_street_number',
2547
- buildingName: 'example_building_name',
2548
- postalCode: 'example_postal_code',
2549
- cityName: 'example_city_name',
2550
- provinceName: 'example_province_name',
2551
- countryCode: '',
2552
- }
2553
-
2554
- const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2555
-
2556
- await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2557
- 'Blank country codes are not allowed',
2558
- )
2559
- })
2560
-
2561
- it('Should save identity metadata item to database', async (): Promise<void> => {
2562
- const metadataItem = {
2563
- label: 'example_label',
2564
- value: 'example_value',
2565
- }
2566
-
2567
- const identityMetadataItemEntity = identityMetadataItemEntityFrom(metadataItem)
2568
-
2569
- await dbConnection.getRepository(IdentityMetadataItemEntity).save(identityMetadataItemEntity!)
2570
-
2571
- const fromDb = await dbConnection.getRepository(IdentityMetadataItemEntity).findOne({
2572
- where: { label: metadataItem.label },
2573
- })
2574
-
2575
- expect(fromDb).toBeDefined()
2576
- expect(fromDb?.label).toEqual(metadataItem.label)
2577
- expect(fromDb?.stringValue).toEqual(metadataItem.value)
2578
- })
2579
-
2580
- it('Should throw error when saving identity metadata item with blank label', async (): Promise<void> => {
2581
- const metadataItem = {
2582
- label: '',
2583
- value: 'example_value',
2584
- }
2585
-
2586
- const identityMetadataItemEntity = identityMetadataItemEntityFrom(metadataItem)
2587
-
2588
- await expect(dbConnection.getRepository(IdentityMetadataItemEntity).save(identityMetadataItemEntity!)).rejects.toThrowError(
2589
- 'Blank metadata labels are not allowed',
2590
- )
2591
- })
2592
-
2593
- it('Should throw error when saving identity metadata item with unsupported object type', async (): Promise<void> => {
2594
- const metadataItem = {
2595
- label: 'example_label',
2596
- value: { unsupported: 'object' } as unknown as MetadataTypes, // Force not to have MetadataTypes
2597
- }
2598
-
2599
- expect(() => identityMetadataItemEntityFrom(metadataItem)).toThrowError('Unsupported object type: Object for value [object Object]')
2600
- })
2601
-
2602
- it('Should save contact metadata item to database', async (): Promise<void> => {
2603
- const metadataItem = {
2604
- label: 'example_label',
2605
- value: 'example_value',
2606
- }
2607
-
2608
- const contactMetadataItemEntity = contactMetadataItemEntityFrom(metadataItem)
2609
-
2610
- await dbConnection.getRepository(ContactMetadataItemEntity).save(contactMetadataItemEntity!)
2611
-
2612
- const fromDb = await dbConnection.getRepository(ContactMetadataItemEntity).findOne({
2613
- where: { label: metadataItem.label },
2614
- })
2615
-
2616
- expect(fromDb).toBeDefined()
2617
- expect(fromDb?.label).toEqual(metadataItem.label)
2618
- expect(fromDb?.stringValue).toEqual(metadataItem.value)
2619
- })
2620
-
2621
- it('Should throw error when saving contact metadata item with blank label', async (): Promise<void> => {
2622
- const metadataItem = {
2623
- label: '',
2624
- value: 'example_value',
2625
- }
2626
-
2627
- const contactMetadataItemEntity = contactMetadataItemEntityFrom(metadataItem)
2628
-
2629
- await expect(dbConnection.getRepository(ContactMetadataItemEntity).save(contactMetadataItemEntity!)).rejects.toThrowError(
2630
- 'Blank metadata labels are not allowed',
2631
- )
2632
- })
2633
-
2634
- it('Should throw error when saving contact metadata item with unsupported object type', async (): Promise<void> => {
2635
- const metadataItem = {
2636
- label: 'example_label',
2637
- value: { unsupported: 'object' } as unknown as MetadataTypes, // Force not to have MetadataTypes
2638
- }
2639
-
2640
- expect(() => contactMetadataItemEntityFrom(metadataItem)).toThrowError('Unsupported object type: Object for value [object Object]')
2641
- })
2642
- })
1
+ import { getDID } from '@sphereon/ssi-sdk-ext.did-utils'
2
+ import { DataSources } from '@sphereon/ssi-sdk.agent-config'
3
+ import { DataSource, FindOptionsWhere } from 'typeorm'
4
+ import { BaseContactEntity } from '../entities/contact/BaseContactEntity'
5
+ import { ConnectionEntity } from '../entities/contact/ConnectionEntity'
6
+ import { ContactMetadataItemEntity } from '../entities/contact/ContactMetadataItemEntity'
7
+ import { CorrelationIdentifierEntity } from '../entities/contact/CorrelationIdentifierEntity'
8
+ import { DidAuthConfigEntity } from '../entities/contact/DidAuthConfigEntity'
9
+ import { ElectronicAddressEntity } from '../entities/contact/ElectronicAddressEntity'
10
+ import { IdentityEntity } from '../entities/contact/IdentityEntity'
11
+ import { IdentityMetadataItemEntity } from '../entities/contact/IdentityMetadataItemEntity'
12
+ import { NaturalPersonEntity } from '../entities/contact/NaturalPersonEntity'
13
+ import { OpenIdConfigEntity } from '../entities/contact/OpenIdConfigEntity'
14
+ import { OrganizationEntity } from '../entities/contact/OrganizationEntity'
15
+ import { PartyEntity } from '../entities/contact/PartyEntity'
16
+ import { PartyRelationshipEntity } from '../entities/contact/PartyRelationshipEntity'
17
+ import { PartyTypeEntity } from '../entities/contact/PartyTypeEntity'
18
+ import { PhysicalAddressEntity } from '../entities/contact/PhysicalAddressEntity'
19
+ import {
20
+ contactMetadataItemEntityFrom,
21
+ CredentialRole,
22
+ DataStoreContactEntities,
23
+ DataStoreMigrations,
24
+ identityMetadataItemEntityFrom,
25
+ IdentityOrigin,
26
+ MetadataTypes,
27
+ PartyOrigin,
28
+ partyTypeFrom,
29
+ } from '../index'
30
+ import {
31
+ ConnectionType,
32
+ CorrelationIdentifierType,
33
+ NaturalPerson,
34
+ NonPersistedConnection,
35
+ NonPersistedDidAuthConfig,
36
+ NonPersistedElectronicAddress,
37
+ NonPersistedIdentity,
38
+ NonPersistedNaturalPerson,
39
+ NonPersistedOpenIdConfig,
40
+ NonPersistedOrganization,
41
+ NonPersistedParty,
42
+ NonPersistedPartyType,
43
+ NonPersistedPhysicalAddress,
44
+ Organization,
45
+ PartyTypeType,
46
+ } from '../types'
47
+ import {
48
+ connectionEntityFrom,
49
+ didAuthConfigEntityFrom,
50
+ electronicAddressEntityFrom,
51
+ identityEntityFrom,
52
+ naturalPersonEntityFrom,
53
+ openIdConfigEntityFrom,
54
+ organizationEntityFrom,
55
+ partyEntityFrom,
56
+ partyRelationshipEntityFrom,
57
+ partyTypeEntityFrom,
58
+ physicalAddressEntityFrom,
59
+ } from '../utils/contact/MappingUtils'
60
+
61
+ // TODO write test adding two contacts reusing the same contactType
62
+
63
+ describe('Database entities tests', (): void => {
64
+ let dbConnection: DataSource
65
+
66
+ beforeEach(async (): Promise<void> => {
67
+ DataSources.singleInstance().defaultDbType = 'sqlite'
68
+ dbConnection = await new DataSource({
69
+ type: 'sqlite',
70
+ database: ':memory:',
71
+ logging: ['info'],
72
+ migrationsRun: false,
73
+ migrations: DataStoreMigrations,
74
+ synchronize: false,
75
+ entities: DataStoreContactEntities,
76
+ }).initialize()
77
+ await dbConnection.runMigrations()
78
+ expect(await dbConnection.showMigrations()).toBeFalsy()
79
+ })
80
+
81
+ afterEach(async (): Promise<void> => {
82
+ await (await dbConnection).destroy()
83
+ })
84
+
85
+ it('Should save person party to database', async (): Promise<void> => {
86
+ const party: NonPersistedParty = {
87
+ uri: 'example.com',
88
+ partyType: {
89
+ type: PartyTypeType.NATURAL_PERSON,
90
+ origin: PartyOrigin.INTERNAL,
91
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
92
+ name: 'example_name',
93
+ },
94
+ contact: {
95
+ firstName: 'example_first_name',
96
+ middleName: 'example_middle_name',
97
+ lastName: 'example_last_name',
98
+ displayName: 'example_display_name',
99
+ },
100
+ }
101
+
102
+ const partyEntity: PartyEntity = partyEntityFrom(party)
103
+ const savedParty: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity, {
104
+ transaction: true,
105
+ })
106
+
107
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
108
+ where: { id: savedParty.id },
109
+ })
110
+
111
+ expect(fromDb).toBeDefined()
112
+ expect(fromDb?.identities?.length).toEqual(0)
113
+ expect(fromDb?.uri).toEqual(party.uri)
114
+ expect(fromDb?.partyType).toBeDefined()
115
+ expect(fromDb?.partyType.type).toEqual(party.partyType.type)
116
+ expect(fromDb?.partyType.origin).toEqual(party.partyType.origin)
117
+ expect(fromDb?.partyType.tenantId).toEqual(party.partyType.tenantId)
118
+ expect(fromDb?.partyType.name).toEqual(party.partyType.name)
119
+ expect(fromDb?.contact).toBeDefined()
120
+ expect((<NaturalPersonEntity>fromDb?.contact).firstName).toEqual((<NaturalPerson>party.contact).firstName)
121
+ expect((<NaturalPersonEntity>fromDb?.contact).middleName).toEqual((<NaturalPerson>party.contact).middleName)
122
+ expect((<NaturalPersonEntity>fromDb?.contact).lastName).toEqual((<NaturalPerson>party.contact).lastName)
123
+ expect((<NaturalPersonEntity>fromDb?.contact).displayName).toEqual((<NaturalPerson>party.contact).displayName)
124
+ })
125
+
126
+ it('Should save organization party to database', async (): Promise<void> => {
127
+ const party: NonPersistedParty = {
128
+ uri: 'example.com',
129
+ partyType: {
130
+ type: PartyTypeType.ORGANIZATION,
131
+ origin: PartyOrigin.INTERNAL,
132
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
133
+ name: 'example_name',
134
+ },
135
+ contact: {
136
+ legalName: 'example_legal_name',
137
+ displayName: 'example_display_name',
138
+ },
139
+ }
140
+
141
+ const partyEntity: PartyEntity = partyEntityFrom(party)
142
+ const savedParty: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity, {
143
+ transaction: true,
144
+ })
145
+
146
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
147
+ where: { id: savedParty.id },
148
+ })
149
+
150
+ expect(fromDb).toBeDefined()
151
+ expect(fromDb?.identities?.length).toEqual(0)
152
+ expect(fromDb?.uri).toEqual(party.uri)
153
+ expect(fromDb?.partyType).toBeDefined()
154
+ expect(fromDb?.partyType.type).toEqual(party.partyType.type)
155
+ expect(fromDb?.partyType.origin).toEqual(party.partyType.origin)
156
+ expect(fromDb?.partyType.tenantId).toEqual(party.partyType.tenantId)
157
+ expect(fromDb?.partyType.name).toEqual(party.partyType.name)
158
+ expect(fromDb?.contact).toBeDefined()
159
+ expect((<OrganizationEntity>fromDb?.contact).legalName).toEqual((<Organization>party.contact).legalName)
160
+ expect((<OrganizationEntity>fromDb?.contact).displayName).toEqual((<Organization>party.contact).displayName)
161
+ })
162
+
163
+ it('Should result in party relationship for the owner side only', async (): Promise<void> => {
164
+ const party1: NonPersistedParty = {
165
+ uri: 'example1.com',
166
+ partyType: {
167
+ type: PartyTypeType.NATURAL_PERSON,
168
+ origin: PartyOrigin.INTERNAL,
169
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
170
+ name: 'example_name1',
171
+ },
172
+ contact: {
173
+ firstName: 'example_first_name1',
174
+ middleName: 'example_middle_name1',
175
+ lastName: 'example_last_name1',
176
+ displayName: 'example_display_name1',
177
+ },
178
+ }
179
+
180
+ const partyEntity1: PartyEntity = partyEntityFrom(party1)
181
+ const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
182
+ transaction: true,
183
+ })
184
+
185
+ const party2: NonPersistedParty = {
186
+ uri: 'example2.com',
187
+ partyType: {
188
+ type: PartyTypeType.NATURAL_PERSON,
189
+ origin: PartyOrigin.INTERNAL,
190
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
191
+ name: 'example_name2',
192
+ },
193
+ contact: {
194
+ firstName: 'example_first_name2',
195
+ middleName: 'example_middle_name2',
196
+ lastName: 'example_last_name2',
197
+ displayName: 'example_display_name2',
198
+ },
199
+ }
200
+
201
+ const partyEntity2: PartyEntity = partyEntityFrom(party2)
202
+ const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
203
+ transaction: true,
204
+ })
205
+
206
+ const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
207
+ leftId: savedParty1.id,
208
+ rightId: savedParty2.id,
209
+ })
210
+
211
+ await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
212
+ transaction: true,
213
+ })
214
+
215
+ const fromDb1: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
216
+ where: { id: savedParty1.id },
217
+ })
218
+
219
+ const fromDb2: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
220
+ where: { id: savedParty2.id },
221
+ })
222
+
223
+ expect(fromDb1).toBeDefined()
224
+ expect(fromDb1?.relationships.length).toEqual(1)
225
+ expect(fromDb2).toBeDefined()
226
+ expect(fromDb2?.relationships.length).toEqual(0)
227
+ })
228
+
229
+ it('should throw error when saving person party with blank first name', async (): Promise<void> => {
230
+ const party: NonPersistedParty = {
231
+ uri: 'example.com',
232
+ partyType: {
233
+ type: PartyTypeType.NATURAL_PERSON,
234
+ origin: PartyOrigin.INTERNAL,
235
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
236
+ name: 'example_name',
237
+ },
238
+ contact: {
239
+ firstName: '',
240
+ middleName: 'example_middle_name1',
241
+ lastName: 'example_last_name1',
242
+ displayName: 'example_display_name1',
243
+ },
244
+ }
245
+
246
+ const partyEntity: PartyEntity = partyEntityFrom(party)
247
+
248
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank first names are not allowed')
249
+ })
250
+
251
+ it('should throw error when saving person party with blank middle name', async (): Promise<void> => {
252
+ const party: NonPersistedParty = {
253
+ uri: 'example.com',
254
+ partyType: {
255
+ type: PartyTypeType.NATURAL_PERSON,
256
+ origin: PartyOrigin.EXTERNAL,
257
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
258
+ name: 'example_name',
259
+ },
260
+ contact: {
261
+ firstName: 'example_first_name',
262
+ middleName: '',
263
+ lastName: 'example_last_name',
264
+ displayName: 'example_display_name',
265
+ },
266
+ }
267
+
268
+ const partyEntity: PartyEntity = partyEntityFrom(party)
269
+
270
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank middle names are not allowed')
271
+ })
272
+
273
+ it('should throw error when saving person party with blank last name', async (): Promise<void> => {
274
+ const party: NonPersistedParty = {
275
+ uri: 'example.com',
276
+ partyType: {
277
+ type: PartyTypeType.NATURAL_PERSON,
278
+ origin: PartyOrigin.EXTERNAL,
279
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
280
+ name: 'example_name',
281
+ },
282
+ contact: {
283
+ firstName: 'example_first_name',
284
+ middleName: 'example_middle_name',
285
+ lastName: '',
286
+ displayName: 'example_display_name',
287
+ },
288
+ }
289
+
290
+ const partyEntity: PartyEntity = partyEntityFrom(party)
291
+
292
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank last names are not allowed')
293
+ })
294
+
295
+ it('should throw error when saving person party with blank display name', async (): Promise<void> => {
296
+ const party: NonPersistedParty = {
297
+ uri: 'example.com',
298
+ partyType: {
299
+ type: PartyTypeType.NATURAL_PERSON,
300
+ origin: PartyOrigin.EXTERNAL,
301
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
302
+ name: 'example_name',
303
+ },
304
+ contact: {
305
+ firstName: 'example_first_name',
306
+ middleName: 'example_middle_name',
307
+ lastName: 'example_last_name',
308
+ displayName: '',
309
+ },
310
+ }
311
+
312
+ const partyEntity: PartyEntity = partyEntityFrom(party)
313
+
314
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank display names are not allowed')
315
+ })
316
+
317
+ it('should throw error when saving organization party with blank legal name', async (): Promise<void> => {
318
+ const party: NonPersistedParty = {
319
+ uri: 'example.com',
320
+ partyType: {
321
+ type: PartyTypeType.ORGANIZATION,
322
+ origin: PartyOrigin.INTERNAL,
323
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
324
+ name: 'example_name',
325
+ },
326
+ contact: {
327
+ legalName: '',
328
+ displayName: 'example_legal_name',
329
+ },
330
+ }
331
+
332
+ const partyEntity: PartyEntity = partyEntityFrom(party)
333
+
334
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank legal names are not allowed')
335
+ })
336
+
337
+ it('should throw error when saving organization party with blank display name', async (): Promise<void> => {
338
+ const party: NonPersistedParty = {
339
+ uri: 'example.com',
340
+ partyType: {
341
+ type: PartyTypeType.ORGANIZATION,
342
+ origin: PartyOrigin.INTERNAL,
343
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
344
+ name: 'example_name',
345
+ },
346
+ contact: {
347
+ legalName: 'example_first_name',
348
+ displayName: '',
349
+ },
350
+ }
351
+
352
+ const partyEntity: PartyEntity = partyEntityFrom(party)
353
+
354
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank display names are not allowed')
355
+ })
356
+
357
+ it('should throw error when saving party with blank party type name', async (): Promise<void> => {
358
+ const party: NonPersistedParty = {
359
+ uri: 'example.com',
360
+ partyType: {
361
+ type: PartyTypeType.NATURAL_PERSON,
362
+ origin: PartyOrigin.EXTERNAL,
363
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
364
+ name: '',
365
+ },
366
+ contact: {
367
+ firstName: 'example_first_name',
368
+ middleName: 'example_middle_name',
369
+ lastName: 'example_last_name',
370
+ displayName: 'example_display_name',
371
+ },
372
+ }
373
+
374
+ const partyEntity: PartyEntity = partyEntityFrom(party)
375
+
376
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank names are not allowed')
377
+ })
378
+
379
+ it('should throw error when saving party with blank party type description', async (): Promise<void> => {
380
+ const party: NonPersistedParty = {
381
+ uri: 'example.com',
382
+ partyType: {
383
+ type: PartyTypeType.NATURAL_PERSON,
384
+ origin: PartyOrigin.INTERNAL,
385
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
386
+ name: 'example_name',
387
+ description: '',
388
+ },
389
+ contact: {
390
+ firstName: 'example_first_name',
391
+ middleName: 'example_middle_name',
392
+ lastName: 'example_last_name',
393
+ displayName: 'example_display_name',
394
+ },
395
+ }
396
+
397
+ const partyEntity: PartyEntity = partyEntityFrom(party)
398
+
399
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError('Blank descriptions are not allowed')
400
+ })
401
+
402
+ it('should throw error when saving party with blank party type tenant id', async (): Promise<void> => {
403
+ const party: NonPersistedParty = {
404
+ uri: 'example.com',
405
+ partyType: {
406
+ type: PartyTypeType.NATURAL_PERSON,
407
+ origin: PartyOrigin.EXTERNAL,
408
+ tenantId: '',
409
+ name: 'example_name',
410
+ },
411
+ contact: {
412
+ firstName: 'example_first_name',
413
+ middleName: 'example_middle_name',
414
+ lastName: 'example_last_name',
415
+ displayName: 'example_display_name',
416
+ },
417
+ }
418
+
419
+ const partyEntity: PartyEntity = partyEntityFrom(party)
420
+
421
+ await expect(dbConnection.getRepository(PartyEntity).save(partyEntity)).rejects.toThrowError("Blank tenant id's are not allowed")
422
+ })
423
+
424
+ it('Should enforce unique alias for an identity', async (): Promise<void> => {
425
+ const alias = 'non_unique_alias'
426
+ const identity1: NonPersistedIdentity = {
427
+ alias,
428
+ origin: IdentityOrigin.EXTERNAL,
429
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
430
+ identifier: {
431
+ type: CorrelationIdentifierType.DID,
432
+ correlationId: 'unique_correlationId1',
433
+ },
434
+ }
435
+ const identity1Entity: IdentityEntity = identityEntityFrom(identity1)
436
+ await dbConnection.getRepository(IdentityEntity).save(identity1Entity)
437
+
438
+ const identity2: NonPersistedIdentity = {
439
+ alias: alias,
440
+ origin: IdentityOrigin.EXTERNAL,
441
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
442
+ identifier: {
443
+ type: CorrelationIdentifierType.DID,
444
+ correlationId: 'unique_correlationId2',
445
+ },
446
+ }
447
+ const identity2Entity: IdentityEntity = identityEntityFrom(identity2)
448
+ await expect(dbConnection.getRepository(IdentityEntity).save(identity2Entity)).rejects.toThrowError(
449
+ 'SQLITE_CONSTRAINT: UNIQUE constraint failed: Identity.alias',
450
+ )
451
+ })
452
+
453
+ it('Should enforce unique correlationId for a identity', async (): Promise<void> => {
454
+ const correlationId = 'non_unique_correlationId'
455
+ const identity1: NonPersistedIdentity = {
456
+ alias: 'unique_alias1',
457
+ origin: IdentityOrigin.EXTERNAL,
458
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
459
+ identifier: {
460
+ type: CorrelationIdentifierType.DID,
461
+ correlationId,
462
+ },
463
+ }
464
+ const identity1Entity: IdentityEntity = identityEntityFrom(identity1)
465
+ await dbConnection.getRepository(IdentityEntity).save(identity1Entity)
466
+
467
+ const identity2: NonPersistedIdentity = {
468
+ alias: 'unique_alias2',
469
+ origin: IdentityOrigin.EXTERNAL,
470
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
471
+ identifier: {
472
+ type: CorrelationIdentifierType.DID,
473
+ correlationId,
474
+ },
475
+ }
476
+ const identity2Entity: IdentityEntity = identityEntityFrom(identity2)
477
+ await expect(dbConnection.getRepository(IdentityEntity).save(identity2Entity)).rejects.toThrowError(
478
+ 'SQLITE_CONSTRAINT: UNIQUE constraint failed: CorrelationIdentifier.correlation_id',
479
+ )
480
+ })
481
+
482
+ it('Should save identity to database', async (): Promise<void> => {
483
+ const correlationId = 'example_did'
484
+ const identity: NonPersistedIdentity = {
485
+ alias: correlationId,
486
+ origin: IdentityOrigin.EXTERNAL,
487
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
488
+ identifier: {
489
+ type: CorrelationIdentifierType.DID,
490
+ correlationId,
491
+ },
492
+ }
493
+
494
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
495
+
496
+ await dbConnection.getRepository(IdentityEntity).save(identityEntity)
497
+
498
+ const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
499
+ where: {
500
+ identifier: {
501
+ correlationId,
502
+ },
503
+ },
504
+ })
505
+
506
+ expect(fromDb).toBeDefined()
507
+ expect(fromDb?.connection).toBeNull()
508
+ expect(fromDb?.identifier).toBeDefined()
509
+ expect(fromDb?.identifier.correlationId).toEqual(identity.identifier.correlationId)
510
+ expect(fromDb?.identifier.type).toEqual(identity.identifier.type)
511
+ })
512
+
513
+ it('should throw error when saving identity with blank alias', async (): Promise<void> => {
514
+ const identity: NonPersistedIdentity = {
515
+ alias: '',
516
+ origin: IdentityOrigin.EXTERNAL,
517
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
518
+ identifier: {
519
+ type: CorrelationIdentifierType.DID,
520
+ correlationId: 'example_did',
521
+ },
522
+ }
523
+
524
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
525
+
526
+ await expect(dbConnection.getRepository(IdentityEntity).save(identityEntity)).rejects.toThrowError('Blank aliases are not allowed')
527
+ })
528
+
529
+ it('should throw error when saving identity with blank correlation id', async (): Promise<void> => {
530
+ const identity: NonPersistedIdentity = {
531
+ alias: 'example_did',
532
+ origin: IdentityOrigin.EXTERNAL,
533
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
534
+ identifier: {
535
+ type: CorrelationIdentifierType.DID,
536
+ correlationId: '',
537
+ },
538
+ }
539
+
540
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
541
+
542
+ await expect(dbConnection.getRepository(IdentityEntity).save(identityEntity)).rejects.toThrowError('Blank correlation ids are not allowed')
543
+ })
544
+
545
+ it('should throw error when saving identity with blank metadata label', async (): Promise<void> => {
546
+ const correlationId = 'example_did'
547
+ const identity: NonPersistedIdentity = {
548
+ alias: correlationId,
549
+ origin: IdentityOrigin.EXTERNAL,
550
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
551
+ identifier: {
552
+ type: CorrelationIdentifierType.DID,
553
+ correlationId,
554
+ },
555
+ metadata: [
556
+ {
557
+ label: '',
558
+ value: 'example_value',
559
+ },
560
+ ],
561
+ }
562
+
563
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
564
+
565
+ await expect(dbConnection.getRepository(IdentityEntity).save(identityEntity)).rejects.toThrowError('Blank metadata labels are not allowed')
566
+ })
567
+
568
+ it('Should save identity with openid connection to database', async (): Promise<void> => {
569
+ const correlationId = 'example.com'
570
+ const identity: NonPersistedIdentity = {
571
+ alias: correlationId,
572
+ origin: IdentityOrigin.EXTERNAL,
573
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
574
+ identifier: {
575
+ type: CorrelationIdentifierType.URL,
576
+ correlationId,
577
+ },
578
+ connection: {
579
+ type: ConnectionType.OPENID_CONNECT,
580
+ config: {
581
+ clientId: '138d7bf8-c930-4c6e-b928-97d3a4928b01',
582
+ clientSecret: '03b3955f-d020-4f2a-8a27-4e452d4e27a0',
583
+ scopes: ['auth'],
584
+ issuer: 'https://example.com/app-test',
585
+ redirectUrl: 'app:/callback',
586
+ dangerouslyAllowInsecureHttpRequests: true,
587
+ clientAuthMethod: <const>'post',
588
+ },
589
+ },
590
+ }
591
+
592
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
593
+
594
+ await dbConnection.getRepository(IdentityEntity).save(identityEntity)
595
+
596
+ const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
597
+ where: {
598
+ identifier: {
599
+ correlationId,
600
+ },
601
+ },
602
+ })
603
+
604
+ expect(fromDb).toBeDefined()
605
+ expect(fromDb?.connection).toBeDefined()
606
+ expect(fromDb?.identifier).toBeDefined()
607
+ expect(fromDb?.identifier.correlationId).toEqual(identity.identifier.correlationId)
608
+ expect(fromDb?.identifier.type).toEqual(identity.identifier.type)
609
+ expect(fromDb?.connection?.type).toEqual(identity.connection?.type)
610
+ expect(fromDb?.connection?.config).toBeDefined()
611
+ expect((<OpenIdConfigEntity>fromDb?.connection?.config).clientId).toEqual((<NonPersistedOpenIdConfig>identity.connection?.config).clientId)
612
+ })
613
+
614
+ it('Should save identity with didauth connection to database', async (): Promise<void> => {
615
+ const correlationId = 'example.com'
616
+ const identity: NonPersistedIdentity = {
617
+ alias: correlationId,
618
+ origin: IdentityOrigin.EXTERNAL,
619
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
620
+ identifier: {
621
+ type: CorrelationIdentifierType.URL,
622
+ correlationId,
623
+ },
624
+ connection: {
625
+ type: ConnectionType.SIOPv2,
626
+ config: {
627
+ idOpts: {
628
+ identifier: {
629
+ did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
630
+ provider: 'test_provider',
631
+ keys: [],
632
+ services: [],
633
+ },
634
+ },
635
+ redirectUrl: 'https://example.com',
636
+ stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
637
+ sessionId: 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
638
+ },
639
+ },
640
+ } satisfies NonPersistedIdentity
641
+
642
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
643
+
644
+ await dbConnection.getRepository(IdentityEntity).save(identityEntity)
645
+
646
+ const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
647
+ where: {
648
+ identifier: {
649
+ correlationId,
650
+ },
651
+ },
652
+ })
653
+
654
+ expect(fromDb).toBeDefined()
655
+ expect(fromDb?.connection).toBeDefined()
656
+ expect(fromDb?.identifier).toBeDefined()
657
+ expect(fromDb?.identifier.correlationId).toEqual(identity.identifier.correlationId)
658
+ expect(fromDb?.identifier.type).toEqual(identity.identifier.type)
659
+ expect(fromDb?.connection?.type).toEqual(identity.connection?.type)
660
+ expect(fromDb?.connection?.config).toBeDefined()
661
+ expect((<DidAuthConfigEntity>fromDb?.connection?.config).identifier).toEqual(
662
+ getDID({ identifier: (<NonPersistedDidAuthConfig>identity.connection?.config).idOpts.identifier as string }),
663
+ )
664
+ })
665
+
666
+ it('Should save connection with openid config to database', async (): Promise<void> => {
667
+ const connection: NonPersistedConnection = {
668
+ type: ConnectionType.OPENID_CONNECT,
669
+ config: {
670
+ clientId: '138d7bf8-c930-4c6e-b928-97d3a4928b01',
671
+ clientSecret: '03b3955f-d020-4f2a-8a27-4e452d4e27a0',
672
+ scopes: ['auth'],
673
+ issuer: 'https://example.com/app-test',
674
+ redirectUrl: 'app:/callback',
675
+ dangerouslyAllowInsecureHttpRequests: true,
676
+ clientAuthMethod: <const>'post',
677
+ },
678
+ }
679
+ const connectionEntity: ConnectionEntity = connectionEntityFrom(connection)
680
+ await dbConnection.getRepository(ConnectionEntity).save(connectionEntity, {
681
+ transaction: true,
682
+ })
683
+
684
+ const fromDb: ConnectionEntity | null = await dbConnection.getRepository(ConnectionEntity).findOne({
685
+ where: { type: connection.type },
686
+ })
687
+
688
+ expect(fromDb).toBeDefined()
689
+
690
+ const fromDbConfig: OpenIdConfigEntity | null = await dbConnection.getRepository(OpenIdConfigEntity).findOne({
691
+ where: { id: fromDb?.id },
692
+ })
693
+
694
+ expect(fromDbConfig).toBeDefined()
695
+ expect(fromDb?.type).toEqual(connection.type)
696
+ expect(fromDb?.config).toBeDefined()
697
+ expect((<OpenIdConfigEntity>fromDb?.config).clientId).toEqual((<NonPersistedOpenIdConfig>connection.config).clientId)
698
+ })
699
+
700
+ it('Should save connection with didauth config to database', async (): Promise<void> => {
701
+ const connection: NonPersistedConnection = {
702
+ type: ConnectionType.SIOPv2,
703
+ config: {
704
+ idOpts: {
705
+ identifier: {
706
+ did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
707
+ provider: 'test_provider',
708
+ keys: [],
709
+ services: [],
710
+ },
711
+ },
712
+ redirectUrl: 'https://example.com',
713
+ stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
714
+ sessionId: 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
715
+ },
716
+ }
717
+ const connectionEntity: ConnectionEntity = connectionEntityFrom(connection)
718
+ await dbConnection.getRepository(ConnectionEntity).save(connectionEntity, {
719
+ transaction: true,
720
+ })
721
+
722
+ const fromDb: ConnectionEntity | null = await dbConnection.getRepository(ConnectionEntity).findOne({
723
+ where: { type: connection.type },
724
+ })
725
+
726
+ expect(fromDb).toBeDefined()
727
+
728
+ const fromDbConfig: DidAuthConfigEntity | null = await dbConnection.getRepository(DidAuthConfigEntity).findOne({
729
+ where: { id: fromDb?.id },
730
+ })
731
+
732
+ expect(fromDbConfig).toBeDefined()
733
+ expect(fromDb?.type).toEqual(connection.type)
734
+ expect(fromDb?.config).toBeDefined()
735
+ expect((<DidAuthConfigEntity>fromDb?.config).identifier).toEqual(
736
+ getDID({ identifier: (<NonPersistedDidAuthConfig>connection?.config).idOpts.identifier as string }),
737
+ )
738
+ })
739
+
740
+ it('Should save openid config to database', async (): Promise<void> => {
741
+ const clientId = '138d7bf8-c930-4c6e-b928-97d3a4928b01'
742
+ const config: NonPersistedOpenIdConfig = {
743
+ clientId,
744
+ clientSecret: '03b3955f-d020-4f2a-8a27-4e452d4e27a0',
745
+ scopes: ['auth'],
746
+ issuer: 'https://example.com/app-test',
747
+ redirectUrl: 'app:/callback',
748
+ dangerouslyAllowInsecureHttpRequests: true,
749
+ clientAuthMethod: <const>'post',
750
+ }
751
+
752
+ const configEntity: OpenIdConfigEntity = openIdConfigEntityFrom(config)
753
+ await dbConnection.getRepository(OpenIdConfigEntity).save(configEntity, {
754
+ transaction: true,
755
+ })
756
+
757
+ const fromDb: OpenIdConfigEntity | null = await dbConnection.getRepository(OpenIdConfigEntity).findOne({
758
+ where: { clientId: config.clientId },
759
+ })
760
+
761
+ expect(fromDb).toBeDefined()
762
+ expect((<OpenIdConfigEntity>fromDb).clientId).toEqual(config.clientId)
763
+ })
764
+
765
+ it('Should save didauth config to database', async (): Promise<void> => {
766
+ const sessionId = 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01'
767
+ const config: NonPersistedDidAuthConfig = {
768
+ idOpts: {
769
+ identifier: {
770
+ did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
771
+ provider: 'test_provider',
772
+ keys: [],
773
+ services: [],
774
+ },
775
+ },
776
+ redirectUrl: 'https://example.com',
777
+ stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
778
+ sessionId,
779
+ }
780
+
781
+ const configEntity: DidAuthConfigEntity = didAuthConfigEntityFrom(config)
782
+ await dbConnection.getRepository(DidAuthConfigEntity).save(configEntity, {
783
+ transaction: true,
784
+ })
785
+
786
+ const fromDb: DidAuthConfigEntity | null = await dbConnection.getRepository(DidAuthConfigEntity).findOne({
787
+ where: { sessionId: config.sessionId },
788
+ })
789
+
790
+ expect(fromDb).toBeDefined()
791
+ expect((<DidAuthConfigEntity>fromDb).identifier).toEqual(getDID({ identifier: (<NonPersistedDidAuthConfig>config).idOpts.identifier as string }))
792
+ })
793
+
794
+ it('Should delete party and all child relations', async (): Promise<void> => {
795
+ const party1: NonPersistedParty = {
796
+ uri: 'example.com',
797
+ partyType: {
798
+ type: PartyTypeType.NATURAL_PERSON,
799
+ origin: PartyOrigin.INTERNAL,
800
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
801
+ name: 'example_name1',
802
+ },
803
+ contact: {
804
+ firstName: 'example_first_name1',
805
+ middleName: 'example_middle_name1',
806
+ lastName: 'example_last_name1',
807
+ displayName: 'example_display_name1',
808
+ },
809
+ }
810
+
811
+ const partyEntity1: PartyEntity = partyEntityFrom(party1)
812
+ const savedParty1: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity1)
813
+
814
+ expect(savedParty1).toBeDefined()
815
+
816
+ const party2: NonPersistedParty = {
817
+ uri: 'example.com',
818
+ partyType: {
819
+ type: PartyTypeType.NATURAL_PERSON,
820
+ origin: PartyOrigin.INTERNAL,
821
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
822
+ name: 'example_name2',
823
+ },
824
+ contact: {
825
+ firstName: 'example_first_name2',
826
+ middleName: 'example_middle_name2',
827
+ lastName: 'example_last_name2',
828
+ displayName: 'example_display_name2',
829
+ },
830
+ }
831
+
832
+ const partyEntity2: PartyEntity = partyEntityFrom(party2)
833
+ const savedParty2: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity2)
834
+
835
+ expect(savedParty2).toBeDefined()
836
+
837
+ const correlationId = 'relation_example.com'
838
+ const identity: NonPersistedIdentity = {
839
+ alias: correlationId,
840
+ origin: IdentityOrigin.EXTERNAL,
841
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
842
+ identifier: {
843
+ type: CorrelationIdentifierType.URL,
844
+ correlationId,
845
+ },
846
+ connection: {
847
+ type: ConnectionType.OPENID_CONNECT,
848
+ config: {
849
+ clientId: '138d7bf8-c930-4c6e-b928-97d3a4928b01',
850
+ clientSecret: '03b3955f-d020-4f2a-8a27-4e452d4e27a0',
851
+ scopes: ['auth'],
852
+ issuer: 'https://example.com/app-test',
853
+ redirectUrl: 'app:/callback',
854
+ dangerouslyAllowInsecureHttpRequests: true,
855
+ clientAuthMethod: <const>'post',
856
+ },
857
+ },
858
+ metadata: [
859
+ {
860
+ label: 'example_label',
861
+ value: 'example_value',
862
+ },
863
+ ],
864
+ }
865
+
866
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
867
+ identityEntity.party = savedParty1
868
+
869
+ const savedIdentity: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).save(identityEntity)
870
+
871
+ expect(savedIdentity).toBeDefined()
872
+
873
+ const electronicAddress: NonPersistedElectronicAddress = {
874
+ type: 'email',
875
+ electronicAddress: 'example_electronic_address',
876
+ }
877
+ const electronicAddressEntity: ElectronicAddressEntity = electronicAddressEntityFrom(electronicAddress)
878
+ electronicAddressEntity.party = savedParty1
879
+
880
+ const savedElectronicAddress: ElectronicAddressEntity | null = await dbConnection
881
+ .getRepository(ElectronicAddressEntity)
882
+ .save(electronicAddressEntity)
883
+
884
+ expect(savedElectronicAddress).toBeDefined()
885
+
886
+ const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
887
+ leftId: savedParty1.id,
888
+ rightId: savedParty2.id,
889
+ })
890
+
891
+ const savedRelationship: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
892
+ transaction: true,
893
+ })
894
+
895
+ expect(savedRelationship).toBeDefined()
896
+
897
+ expect(
898
+ await dbConnection.getRepository(PartyEntity).findOne({
899
+ where: { id: savedParty1.id },
900
+ }),
901
+ ).toBeDefined()
902
+
903
+ await dbConnection.getRepository(PartyEntity).delete({ id: savedParty1.id })
904
+
905
+ // check party
906
+ await expect(
907
+ await dbConnection.getRepository(PartyEntity).findOne({
908
+ where: { id: savedParty1.id },
909
+ }),
910
+ ).toBeNull()
911
+
912
+ // check identity
913
+ expect(
914
+ await dbConnection.getRepository(IdentityEntity).findOne({
915
+ where: { id: savedParty1.id },
916
+ }),
917
+ ).toBeNull()
918
+
919
+ // check identity identifier
920
+ expect(
921
+ await dbConnection.getRepository(CorrelationIdentifierEntity).findOne({
922
+ where: { id: savedIdentity.identifier.id },
923
+ }),
924
+ ).toBeNull()
925
+
926
+ // check identity connection
927
+ expect(
928
+ await dbConnection.getRepository(ConnectionEntity).findOne({
929
+ where: { id: savedIdentity.connection!.id },
930
+ }),
931
+ ).toBeNull()
932
+
933
+ // check connection config
934
+ expect(
935
+ await dbConnection.getRepository(OpenIdConfigEntity).findOne({
936
+ where: { id: savedIdentity.connection!.config.id },
937
+ }),
938
+ ).toBeNull()
939
+
940
+ // check identity metadata
941
+ expect(
942
+ await dbConnection.getRepository(IdentityMetadataItemEntity).findOne({
943
+ where: { id: savedIdentity.metadata![0].id },
944
+ }),
945
+ ).toBeNull()
946
+
947
+ // check electronic address
948
+ expect(
949
+ await dbConnection.getRepository(ElectronicAddressEntity).findOne({
950
+ where: { id: savedParty1.id },
951
+ }),
952
+ ).toBeNull()
953
+
954
+ // check contact
955
+ expect(
956
+ await dbConnection.getRepository(BaseContactEntity).findOne({
957
+ where: { id: savedParty1.contact.id },
958
+ }),
959
+ ).toBeNull()
960
+
961
+ // check party type
962
+ expect(
963
+ await dbConnection.getRepository(PartyTypeEntity).findOne({
964
+ where: { id: savedParty1.partyType.id },
965
+ }),
966
+ ).toBeDefined()
967
+
968
+ // check relation
969
+ expect(
970
+ await dbConnection.getRepository(PartyRelationshipEntity).findOne({
971
+ where: { id: savedRelationship.id },
972
+ }),
973
+ ).toBeNull()
974
+ })
975
+
976
+ it('Should delete identity and all child relations', async (): Promise<void> => {
977
+ const party: NonPersistedParty = {
978
+ uri: 'example.com',
979
+ partyType: {
980
+ type: PartyTypeType.NATURAL_PERSON,
981
+ origin: PartyOrigin.EXTERNAL,
982
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
983
+ name: 'example_name',
984
+ },
985
+ contact: {
986
+ firstName: 'example_first_name',
987
+ middleName: 'example_middle_name',
988
+ lastName: 'example_last_name',
989
+ displayName: 'example_display_name',
990
+ },
991
+ }
992
+
993
+ const partyEntity: PartyEntity = partyEntityFrom(party)
994
+ const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
995
+
996
+ expect(savedParty).toBeDefined()
997
+
998
+ const correlationId = 'relation_example.com'
999
+ const identity: NonPersistedIdentity = {
1000
+ alias: correlationId,
1001
+ origin: IdentityOrigin.EXTERNAL,
1002
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1003
+ identifier: {
1004
+ type: CorrelationIdentifierType.URL,
1005
+ correlationId,
1006
+ },
1007
+ connection: {
1008
+ type: ConnectionType.SIOPv2,
1009
+ config: {
1010
+ idOpts: {
1011
+ identifier: {
1012
+ did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
1013
+ provider: 'test_provider',
1014
+ keys: [],
1015
+ services: [],
1016
+ },
1017
+ },
1018
+ redirectUrl: 'https://example.com',
1019
+ stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
1020
+ sessionId: 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
1021
+ },
1022
+ },
1023
+ metadata: [
1024
+ {
1025
+ label: 'example_label',
1026
+ value: 'example_value',
1027
+ },
1028
+ ],
1029
+ }
1030
+
1031
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
1032
+ identityEntity.party = savedParty
1033
+
1034
+ const savedIdentity: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1035
+
1036
+ expect(
1037
+ await dbConnection.getRepository(PartyEntity).findOne({
1038
+ where: { id: savedParty.id },
1039
+ }),
1040
+ ).toBeDefined()
1041
+
1042
+ await dbConnection.getRepository(IdentityEntity).delete({ id: savedIdentity.id })
1043
+
1044
+ // check identity
1045
+ expect(
1046
+ await dbConnection.getRepository(IdentityEntity).findOne({
1047
+ where: { alias: correlationId },
1048
+ }),
1049
+ ).toBeNull()
1050
+
1051
+ // check identity identifier
1052
+ expect(
1053
+ await dbConnection.getRepository(CorrelationIdentifierEntity).findOne({
1054
+ where: { id: savedIdentity.identifier.id },
1055
+ }),
1056
+ ).toBeNull()
1057
+
1058
+ // check identity connection
1059
+ expect(
1060
+ await dbConnection.getRepository(ConnectionEntity).findOne({
1061
+ where: { id: savedIdentity.connection!.id },
1062
+ }),
1063
+ ).toBeNull()
1064
+
1065
+ // check connection config
1066
+ expect(
1067
+ await dbConnection.getRepository(OpenIdConfigEntity).findOne({
1068
+ where: { id: savedIdentity.connection!.config.id },
1069
+ }),
1070
+ ).toBeNull()
1071
+
1072
+ // check identity metadata
1073
+ expect(
1074
+ await dbConnection.getRepository(IdentityMetadataItemEntity).findOne({
1075
+ where: { id: savedIdentity.metadata![0].id },
1076
+ }),
1077
+ ).toBeNull()
1078
+ })
1079
+
1080
+ it('Should not delete party when deleting identity', async (): Promise<void> => {
1081
+ const party: NonPersistedParty = {
1082
+ uri: 'example.com',
1083
+ partyType: {
1084
+ type: PartyTypeType.NATURAL_PERSON,
1085
+ origin: PartyOrigin.EXTERNAL,
1086
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1087
+ name: 'example_name',
1088
+ },
1089
+ contact: {
1090
+ firstName: 'example_first_name',
1091
+ middleName: 'example_middle_name',
1092
+ lastName: 'example_last_name',
1093
+ displayName: 'example_display_name',
1094
+ },
1095
+ }
1096
+
1097
+ const partyEntity: PartyEntity = partyEntityFrom(party)
1098
+ const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1099
+
1100
+ expect(savedParty).toBeDefined()
1101
+
1102
+ const correlationId = 'relation_example.com'
1103
+ const identity: NonPersistedIdentity = {
1104
+ alias: correlationId,
1105
+ origin: IdentityOrigin.EXTERNAL,
1106
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1107
+ identifier: {
1108
+ type: CorrelationIdentifierType.URL,
1109
+ correlationId,
1110
+ },
1111
+ connection: {
1112
+ type: ConnectionType.SIOPv2,
1113
+ config: {
1114
+ idOpts: {
1115
+ identifier: {
1116
+ did: 'did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
1117
+ provider: 'test_provider',
1118
+ keys: [],
1119
+ services: [],
1120
+ },
1121
+ },
1122
+ redirectUrl: 'https://example.com',
1123
+ stateId: 'e91f3510-5ce9-42ee-83b7-fa68ff323d27',
1124
+ sessionId: 'https://example.com/did:test:138d7bf8-c930-4c6e-b928-97d3a4928b01',
1125
+ },
1126
+ },
1127
+ metadata: [
1128
+ {
1129
+ label: 'example_label',
1130
+ value: 'example_value',
1131
+ },
1132
+ ],
1133
+ }
1134
+
1135
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
1136
+ identityEntity.party = savedParty
1137
+
1138
+ const savedIdentity: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1139
+
1140
+ expect(savedIdentity).toBeDefined()
1141
+
1142
+ await dbConnection.getRepository(IdentityEntity).delete({ id: savedIdentity.id })
1143
+
1144
+ // check identity
1145
+ expect(
1146
+ await dbConnection.getRepository(IdentityEntity).findOne({
1147
+ where: { id: savedIdentity.id },
1148
+ }),
1149
+ ).toBeNull()
1150
+
1151
+ // check party
1152
+ expect(
1153
+ await dbConnection.getRepository(PartyEntity).findOne({
1154
+ where: { id: savedParty.id },
1155
+ }),
1156
+ ).toBeDefined()
1157
+ })
1158
+
1159
+ it('Should set creation date when saving party', async (): Promise<void> => {
1160
+ const party: NonPersistedParty = {
1161
+ uri: 'example.com',
1162
+ partyType: {
1163
+ type: PartyTypeType.NATURAL_PERSON,
1164
+ origin: PartyOrigin.INTERNAL,
1165
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1166
+ name: 'example_name',
1167
+ },
1168
+ contact: {
1169
+ firstName: 'example_first_name',
1170
+ middleName: 'example_middle_name',
1171
+ lastName: 'example_last_name',
1172
+ displayName: 'example_display_name',
1173
+ },
1174
+ }
1175
+
1176
+ const partyEntity: PartyEntity = partyEntityFrom(party)
1177
+ const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1178
+
1179
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1180
+ where: { id: savedParty.id },
1181
+ })
1182
+
1183
+ expect(fromDb).toBeDefined()
1184
+ expect(fromDb?.createdAt).toBeDefined()
1185
+ })
1186
+
1187
+ it('Should not update creation date when updating party', async (): Promise<void> => {
1188
+ const party: NonPersistedParty = {
1189
+ uri: 'example.com',
1190
+ partyType: {
1191
+ type: PartyTypeType.NATURAL_PERSON,
1192
+ origin: PartyOrigin.INTERNAL,
1193
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1194
+ name: 'example_name',
1195
+ },
1196
+ contact: {
1197
+ firstName: 'example_first_name',
1198
+ middleName: 'example_middle_name',
1199
+ lastName: 'example_last_name',
1200
+ displayName: 'example_display_name',
1201
+ },
1202
+ }
1203
+
1204
+ const partyEntity: PartyEntity = partyEntityFrom(party)
1205
+ const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1206
+
1207
+ expect(savedParty).toBeDefined()
1208
+
1209
+ const newContactFirstName = 'new_first_name'
1210
+ await dbConnection.getRepository(PartyEntity).save({
1211
+ ...savedParty,
1212
+ contact: {
1213
+ ...savedParty.contact,
1214
+ firstName: newContactFirstName,
1215
+ },
1216
+ })
1217
+
1218
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1219
+ where: { id: savedParty.id },
1220
+ })
1221
+
1222
+ expect(fromDb).toBeDefined()
1223
+ expect((<NaturalPersonEntity>fromDb?.contact).firstName).toEqual(newContactFirstName)
1224
+ expect(fromDb?.createdAt).toEqual(savedParty?.createdAt)
1225
+ })
1226
+
1227
+ it('Should set creation date when saving identity', async (): Promise<void> => {
1228
+ const correlationId = 'example_did'
1229
+ const identity: NonPersistedIdentity = {
1230
+ alias: correlationId,
1231
+ origin: IdentityOrigin.EXTERNAL,
1232
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1233
+ identifier: {
1234
+ type: CorrelationIdentifierType.DID,
1235
+ correlationId,
1236
+ },
1237
+ }
1238
+
1239
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
1240
+ await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1241
+
1242
+ const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
1243
+ where: {
1244
+ identifier: {
1245
+ correlationId,
1246
+ },
1247
+ },
1248
+ })
1249
+
1250
+ expect(fromDb).toBeDefined()
1251
+ expect(fromDb?.createdAt).toBeDefined()
1252
+ })
1253
+
1254
+ it('Should not update creation date when saving identity', async (): Promise<void> => {
1255
+ const correlationId = 'example_did'
1256
+ const identity: NonPersistedIdentity = {
1257
+ alias: correlationId,
1258
+ origin: IdentityOrigin.EXTERNAL,
1259
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1260
+ identifier: {
1261
+ type: CorrelationIdentifierType.DID,
1262
+ correlationId,
1263
+ },
1264
+ }
1265
+
1266
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
1267
+ const savedIdentity: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1268
+ const newCorrelationId = 'new_example_did'
1269
+ await dbConnection
1270
+ .getRepository(IdentityEntity)
1271
+ .save({ ...savedIdentity, identifier: { ...savedIdentity.identifier, correlationId: newCorrelationId } })
1272
+
1273
+ const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
1274
+ where: {
1275
+ identifier: {
1276
+ correlationId: newCorrelationId,
1277
+ },
1278
+ },
1279
+ })
1280
+
1281
+ expect(fromDb).toBeDefined()
1282
+ expect(fromDb?.createdAt).toEqual(savedIdentity?.createdAt)
1283
+ })
1284
+
1285
+ it('Should set last updated date when saving party', async (): Promise<void> => {
1286
+ const party: NonPersistedParty = {
1287
+ uri: 'example.com',
1288
+ partyType: {
1289
+ type: PartyTypeType.NATURAL_PERSON,
1290
+ origin: PartyOrigin.INTERNAL,
1291
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1292
+ name: 'example_name',
1293
+ },
1294
+ contact: {
1295
+ firstName: 'example_first_name',
1296
+ middleName: 'example_middle_name',
1297
+ lastName: 'example_last_name',
1298
+ displayName: 'example_display_name',
1299
+ },
1300
+ }
1301
+
1302
+ const partyEntity: PartyEntity = partyEntityFrom(party)
1303
+ const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1304
+
1305
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1306
+ where: { id: savedParty.id },
1307
+ })
1308
+
1309
+ expect(fromDb).toBeDefined()
1310
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
1311
+ })
1312
+
1313
+ it('Should update last updated date when updating party', async (): Promise<void> => {
1314
+ const party: NonPersistedParty = {
1315
+ uri: 'example.com',
1316
+ partyType: {
1317
+ type: PartyTypeType.NATURAL_PERSON,
1318
+ origin: PartyOrigin.EXTERNAL,
1319
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1320
+ name: 'example_name',
1321
+ },
1322
+ contact: {
1323
+ firstName: 'example_first_name',
1324
+ middleName: 'example_middle_name',
1325
+ lastName: 'example_last_name',
1326
+ displayName: 'example_display_name',
1327
+ },
1328
+ }
1329
+
1330
+ const partyEntity: PartyEntity = partyEntityFrom(party)
1331
+ const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity)
1332
+ expect(savedParty).toBeDefined()
1333
+
1334
+ // waiting here to get a different timestamp
1335
+ await new Promise((resolve) => setTimeout(resolve, 2000))
1336
+
1337
+ const newContactFirstName = 'new_first_name'
1338
+ await dbConnection.getRepository(PartyEntity).save({
1339
+ ...savedParty,
1340
+ // FIXME there is still an issue when updating nested objects, the parent does not update
1341
+ // https://github.com/typeorm/typeorm/issues/5378
1342
+ uri: 'new uri', // TODO remove this to trigger the bug
1343
+ contact: {
1344
+ ...savedParty.contact,
1345
+ firstName: newContactFirstName,
1346
+ },
1347
+ })
1348
+
1349
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1350
+ where: { id: savedParty.id },
1351
+ })
1352
+
1353
+ expect(fromDb).toBeDefined()
1354
+ expect((<NaturalPersonEntity>fromDb?.contact).firstName).toEqual(newContactFirstName)
1355
+ expect(fromDb?.lastUpdatedAt).not.toEqual(savedParty?.lastUpdatedAt)
1356
+ })
1357
+
1358
+ it('Should set last updated date when saving party type', async (): Promise<void> => {
1359
+ const partyType: NonPersistedPartyType = {
1360
+ type: PartyTypeType.NATURAL_PERSON,
1361
+ origin: PartyOrigin.EXTERNAL,
1362
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1363
+ name: 'example_name',
1364
+ }
1365
+
1366
+ const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
1367
+ const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
1368
+
1369
+ const fromDb: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).findOne({
1370
+ where: { id: savedPartyType.id },
1371
+ })
1372
+
1373
+ expect(fromDb).toBeDefined()
1374
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
1375
+ })
1376
+
1377
+ it('Should set last creation date when saving party type', async (): Promise<void> => {
1378
+ const partyType: NonPersistedPartyType = {
1379
+ type: PartyTypeType.NATURAL_PERSON,
1380
+ origin: PartyOrigin.INTERNAL,
1381
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1382
+ name: 'example_name',
1383
+ }
1384
+
1385
+ const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
1386
+ const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
1387
+
1388
+ const fromDb: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).findOne({
1389
+ where: { id: savedPartyType.id },
1390
+ })
1391
+
1392
+ expect(fromDb).toBeDefined()
1393
+ expect(fromDb?.createdAt).toBeDefined()
1394
+ })
1395
+
1396
+ it('Should set last updated date when saving identity', async (): Promise<void> => {
1397
+ const correlationId = 'example_did'
1398
+ const identity: NonPersistedIdentity = {
1399
+ alias: correlationId,
1400
+ origin: IdentityOrigin.EXTERNAL,
1401
+ roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER],
1402
+ identifier: {
1403
+ type: CorrelationIdentifierType.DID,
1404
+ correlationId,
1405
+ },
1406
+ }
1407
+
1408
+ const identityEntity: IdentityEntity = identityEntityFrom(identity)
1409
+ await dbConnection.getRepository(IdentityEntity).save(identityEntity)
1410
+
1411
+ const fromDb: IdentityEntity | null = await dbConnection.getRepository(IdentityEntity).findOne({
1412
+ where: {
1413
+ identifier: {
1414
+ correlationId,
1415
+ },
1416
+ },
1417
+ })
1418
+
1419
+ expect(fromDb).toBeDefined()
1420
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
1421
+ })
1422
+
1423
+ it('Should enforce unique type and tenant id combination when saving party type', async (): Promise<void> => {
1424
+ const tenantId = 'non_unique_value'
1425
+ const partyType1: NonPersistedPartyType = {
1426
+ type: PartyTypeType.NATURAL_PERSON,
1427
+ origin: PartyOrigin.EXTERNAL,
1428
+ tenantId,
1429
+ name: 'example_party_type_name1',
1430
+ }
1431
+
1432
+ const partyTypeEntity1: PartyTypeEntity = partyTypeEntityFrom(partyType1)
1433
+ const savedPartyType1: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity1)
1434
+
1435
+ expect(savedPartyType1).toBeDefined()
1436
+
1437
+ const partyType2: NonPersistedPartyType = {
1438
+ type: PartyTypeType.NATURAL_PERSON,
1439
+ origin: PartyOrigin.INTERNAL,
1440
+ tenantId,
1441
+ name: 'example_party_type_name2',
1442
+ }
1443
+
1444
+ const partyTypeEntity2: PartyTypeEntity = partyTypeEntityFrom(partyType2)
1445
+ await expect(dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity2)).rejects.toThrowError(
1446
+ 'SQLITE_CONSTRAINT: UNIQUE constraint failed: PartyType.type, PartyType.tenant_id',
1447
+ )
1448
+ })
1449
+
1450
+ it('Should enforce unique name when saving party type', async (): Promise<void> => {
1451
+ const name = 'non_unique_value'
1452
+ const partyType1: NonPersistedPartyType = {
1453
+ type: PartyTypeType.NATURAL_PERSON,
1454
+ origin: PartyOrigin.INTERNAL,
1455
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1456
+ name,
1457
+ }
1458
+
1459
+ const partyTypeEntity1: PartyTypeEntity = partyTypeEntityFrom(partyType1)
1460
+ const savedPartyType1: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity1)
1461
+
1462
+ expect(savedPartyType1).toBeDefined()
1463
+
1464
+ const partyType2: NonPersistedPartyType = {
1465
+ type: PartyTypeType.NATURAL_PERSON,
1466
+ origin: PartyOrigin.INTERNAL,
1467
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1468
+ name,
1469
+ }
1470
+
1471
+ const partyTypeEntity2: PartyTypeEntity = partyTypeEntityFrom(partyType2)
1472
+ await expect(dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity2)).rejects.toThrowError(
1473
+ 'SQLITE_CONSTRAINT: UNIQUE constraint failed: PartyType.name',
1474
+ )
1475
+ })
1476
+
1477
+ it('Should enforce unique legal name when saving organization', async (): Promise<void> => {
1478
+ const legalName = 'non_unique_value'
1479
+ const organization1: NonPersistedOrganization = {
1480
+ legalName,
1481
+ displayName: 'example_display_name',
1482
+ }
1483
+
1484
+ const organizationEntity1: OrganizationEntity = organizationEntityFrom(organization1)
1485
+ const savedOrganization1: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity1, {
1486
+ transaction: true,
1487
+ })
1488
+
1489
+ expect(savedOrganization1).toBeDefined()
1490
+
1491
+ const organization2: NonPersistedOrganization = {
1492
+ legalName,
1493
+ displayName: 'example_display_name',
1494
+ }
1495
+
1496
+ const organizationEntity2: OrganizationEntity = organizationEntityFrom(organization2)
1497
+ await expect(dbConnection.getRepository(OrganizationEntity).save(organizationEntity2)).rejects.toThrowError(
1498
+ 'SQLITE_CONSTRAINT: UNIQUE constraint failed: BaseContact.legal_name',
1499
+ )
1500
+ })
1501
+
1502
+ it('Should enforce unique legal name when saving organization', async (): Promise<void> => {
1503
+ const legalName = 'example_legal_name'
1504
+ const organization1: NonPersistedOrganization = {
1505
+ legalName,
1506
+ displayName: 'example_display_name',
1507
+ }
1508
+
1509
+ const organizationEntity1: OrganizationEntity = organizationEntityFrom(organization1)
1510
+ const savedOrganization1: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity1, {
1511
+ transaction: true,
1512
+ })
1513
+
1514
+ expect(savedOrganization1).toBeDefined()
1515
+
1516
+ const organization2: NonPersistedOrganization = {
1517
+ legalName,
1518
+ displayName: 'example_display_name',
1519
+ }
1520
+
1521
+ const organizationEntity2: OrganizationEntity = organizationEntityFrom(organization2)
1522
+ await expect(dbConnection.getRepository(OrganizationEntity).save(organizationEntity2)).rejects.toThrowError(
1523
+ 'SQLITE_CONSTRAINT: UNIQUE constraint failed: BaseContact.legal_name',
1524
+ )
1525
+ })
1526
+
1527
+ it('Should save party relationship to database', async (): Promise<void> => {
1528
+ const party1: NonPersistedParty = {
1529
+ uri: 'example1.com',
1530
+ partyType: {
1531
+ type: PartyTypeType.NATURAL_PERSON,
1532
+ origin: PartyOrigin.INTERNAL,
1533
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1534
+ name: 'example_name1',
1535
+ },
1536
+ contact: {
1537
+ firstName: 'example_first_name1',
1538
+ middleName: 'example_middle_name1',
1539
+ lastName: 'example_last_name1',
1540
+ displayName: 'example_display_name1',
1541
+ },
1542
+ }
1543
+
1544
+ const partyEntity1: PartyEntity = partyEntityFrom(party1)
1545
+ const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1546
+ transaction: true,
1547
+ })
1548
+
1549
+ expect(savedParty1).toBeDefined()
1550
+
1551
+ const party2: NonPersistedParty = {
1552
+ uri: 'example2.com',
1553
+ partyType: {
1554
+ type: PartyTypeType.NATURAL_PERSON,
1555
+ origin: PartyOrigin.INTERNAL,
1556
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1557
+ name: 'example_name2',
1558
+ },
1559
+ contact: {
1560
+ firstName: 'example_first_name2',
1561
+ middleName: 'example_middle_name2',
1562
+ lastName: 'example_last_name2',
1563
+ displayName: 'example_display_name2',
1564
+ },
1565
+ }
1566
+
1567
+ const partyEntity2: PartyEntity = partyEntityFrom(party2)
1568
+ const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1569
+ transaction: true,
1570
+ })
1571
+
1572
+ expect(savedParty2).toBeDefined()
1573
+
1574
+ const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
1575
+ leftId: savedParty1.id,
1576
+ rightId: savedParty2.id,
1577
+ })
1578
+
1579
+ await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
1580
+ transaction: true,
1581
+ })
1582
+
1583
+ // TODO check the relation field
1584
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1585
+ where: { id: partyEntity1.id },
1586
+ })
1587
+
1588
+ expect(fromDb).toBeDefined()
1589
+ })
1590
+
1591
+ it('Should set last updated date when saving party relationship', async (): Promise<void> => {
1592
+ const party1: NonPersistedParty = {
1593
+ uri: 'example1.com',
1594
+ partyType: {
1595
+ type: PartyTypeType.NATURAL_PERSON,
1596
+ origin: PartyOrigin.INTERNAL,
1597
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1598
+ name: 'example_name1',
1599
+ },
1600
+ contact: {
1601
+ firstName: 'example_first_name1',
1602
+ middleName: 'example_middle_name1',
1603
+ lastName: 'example_last_name1',
1604
+ displayName: 'example_display_name1',
1605
+ },
1606
+ }
1607
+
1608
+ const partyEntity1: PartyEntity = partyEntityFrom(party1)
1609
+ const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1610
+ transaction: true,
1611
+ })
1612
+
1613
+ const party2: NonPersistedParty = {
1614
+ uri: 'example2.com',
1615
+ partyType: {
1616
+ type: PartyTypeType.NATURAL_PERSON,
1617
+ origin: PartyOrigin.INTERNAL,
1618
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1619
+ name: 'example_name2',
1620
+ },
1621
+ contact: {
1622
+ firstName: 'example_first_name2',
1623
+ middleName: 'example_middle_name2',
1624
+ lastName: 'example_last_name2',
1625
+ displayName: 'example_display_name2',
1626
+ },
1627
+ }
1628
+
1629
+ const partyEntity2: PartyEntity = partyEntityFrom(party2)
1630
+ const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1631
+ transaction: true,
1632
+ })
1633
+
1634
+ const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
1635
+ leftId: savedParty1.id,
1636
+ rightId: savedParty2.id,
1637
+ })
1638
+
1639
+ await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
1640
+ transaction: true,
1641
+ })
1642
+
1643
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1644
+ where: { id: partyEntity1.id },
1645
+ })
1646
+
1647
+ expect(fromDb).toBeDefined()
1648
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
1649
+ })
1650
+
1651
+ it('Should set creation date when saving party relationship', async (): Promise<void> => {
1652
+ const party1: NonPersistedParty = {
1653
+ uri: 'example1.com',
1654
+ partyType: {
1655
+ type: PartyTypeType.NATURAL_PERSON,
1656
+ origin: PartyOrigin.INTERNAL,
1657
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1658
+ name: 'example_name1',
1659
+ },
1660
+ contact: {
1661
+ firstName: 'example_first_name1',
1662
+ middleName: 'example_middle_name1',
1663
+ lastName: 'example_last_name1',
1664
+ displayName: 'example_display_name1',
1665
+ },
1666
+ }
1667
+
1668
+ const partyEntity1: PartyEntity = partyEntityFrom(party1)
1669
+ const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1670
+ transaction: true,
1671
+ })
1672
+
1673
+ const party2: NonPersistedParty = {
1674
+ uri: 'example2.com',
1675
+ partyType: {
1676
+ type: PartyTypeType.NATURAL_PERSON,
1677
+ origin: PartyOrigin.INTERNAL,
1678
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1679
+ name: 'example_name2',
1680
+ },
1681
+ contact: {
1682
+ firstName: 'example_first_name2',
1683
+ middleName: 'example_middle_name2',
1684
+ lastName: 'example_last_name2',
1685
+ displayName: 'example_display_name2',
1686
+ },
1687
+ }
1688
+
1689
+ const partyEntity2: PartyEntity = partyEntityFrom(party2)
1690
+ const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1691
+ transaction: true,
1692
+ })
1693
+
1694
+ const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
1695
+ leftId: savedParty1.id,
1696
+ rightId: savedParty2.id,
1697
+ })
1698
+
1699
+ await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
1700
+ transaction: true,
1701
+ })
1702
+
1703
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
1704
+ where: { id: partyEntity1.id },
1705
+ })
1706
+
1707
+ expect(fromDb).toBeDefined()
1708
+ expect(fromDb?.createdAt).toBeDefined()
1709
+ })
1710
+
1711
+ it('Should save bidirectional party relationships to database', async (): Promise<void> => {
1712
+ const party1: NonPersistedParty = {
1713
+ uri: 'example1.com',
1714
+ partyType: {
1715
+ type: PartyTypeType.NATURAL_PERSON,
1716
+ origin: PartyOrigin.INTERNAL,
1717
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1718
+ name: 'example_name1',
1719
+ },
1720
+ contact: {
1721
+ firstName: 'example_first_name1',
1722
+ middleName: 'example_middle_name1',
1723
+ lastName: 'example_last_name1',
1724
+ displayName: 'example_display_name1',
1725
+ },
1726
+ }
1727
+
1728
+ const partyEntity1: PartyEntity = partyEntityFrom(party1)
1729
+ const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1730
+ transaction: true,
1731
+ })
1732
+
1733
+ expect(savedParty1).toBeDefined()
1734
+
1735
+ const party2: NonPersistedParty = {
1736
+ uri: 'example2.com',
1737
+ partyType: {
1738
+ type: PartyTypeType.NATURAL_PERSON,
1739
+ origin: PartyOrigin.INTERNAL,
1740
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1741
+ name: 'example_name2',
1742
+ },
1743
+ contact: {
1744
+ firstName: 'example_first_name2',
1745
+ middleName: 'example_middle_name2',
1746
+ lastName: 'example_last_name2',
1747
+ displayName: 'example_display_name2',
1748
+ },
1749
+ }
1750
+
1751
+ const partyEntity2: PartyEntity = partyEntityFrom(party2)
1752
+ const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1753
+ transaction: true,
1754
+ })
1755
+
1756
+ expect(savedParty2).toBeDefined()
1757
+
1758
+ const relationship1: PartyRelationshipEntity = partyRelationshipEntityFrom({
1759
+ leftId: savedParty1.id,
1760
+ rightId: savedParty2.id,
1761
+ })
1762
+
1763
+ const savedRelationship1: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship1, {
1764
+ transaction: true,
1765
+ })
1766
+
1767
+ expect(savedRelationship1).toBeDefined()
1768
+
1769
+ const relationship2: PartyRelationshipEntity = partyRelationshipEntityFrom({
1770
+ leftId: savedParty2.id,
1771
+ rightId: savedParty1.id,
1772
+ })
1773
+
1774
+ const savedRelationship2: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship2, {
1775
+ transaction: true,
1776
+ })
1777
+
1778
+ expect(savedRelationship2).toBeDefined()
1779
+
1780
+ const fromDb: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).findOne({
1781
+ where: { id: savedRelationship2.id },
1782
+ })
1783
+
1784
+ expect(fromDb).toBeDefined()
1785
+ })
1786
+
1787
+ it('Should enforce unique owner combination for party relationship', async (): Promise<void> => {
1788
+ const party1: NonPersistedParty = {
1789
+ uri: 'example1.com',
1790
+ partyType: {
1791
+ type: PartyTypeType.NATURAL_PERSON,
1792
+ origin: PartyOrigin.INTERNAL,
1793
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1794
+ name: 'example_name1',
1795
+ },
1796
+ contact: {
1797
+ firstName: 'example_first_name1',
1798
+ middleName: 'example_middle_name1',
1799
+ lastName: 'example_last_name1',
1800
+ displayName: 'example_display_name1',
1801
+ },
1802
+ }
1803
+
1804
+ const partyEntity1: PartyEntity = partyEntityFrom(party1)
1805
+ const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
1806
+ transaction: true,
1807
+ })
1808
+
1809
+ expect(savedParty1).toBeDefined()
1810
+
1811
+ const party2: NonPersistedParty = {
1812
+ uri: 'example2.com',
1813
+ partyType: {
1814
+ type: PartyTypeType.NATURAL_PERSON,
1815
+ origin: PartyOrigin.INTERNAL,
1816
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
1817
+ name: 'example_name2',
1818
+ },
1819
+ contact: {
1820
+ firstName: 'example_first_name2',
1821
+ middleName: 'example_middle_name2',
1822
+ lastName: 'example_last_name2',
1823
+ displayName: 'example_display_name2',
1824
+ },
1825
+ }
1826
+
1827
+ const partyEntity2: PartyEntity = partyEntityFrom(party2)
1828
+ const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
1829
+ transaction: true,
1830
+ })
1831
+
1832
+ expect(savedParty2).toBeDefined()
1833
+
1834
+ const relationship1: PartyRelationshipEntity = partyRelationshipEntityFrom({
1835
+ leftId: savedParty1.id,
1836
+ rightId: savedParty2.id,
1837
+ })
1838
+
1839
+ const savedRelationship1: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship1, {
1840
+ transaction: true,
1841
+ })
1842
+
1843
+ expect(savedRelationship1).toBeDefined()
1844
+
1845
+ const relationship2: PartyRelationshipEntity = partyRelationshipEntityFrom({
1846
+ leftId: savedParty1.id,
1847
+ rightId: savedParty2.id,
1848
+ })
1849
+
1850
+ await expect(dbConnection.getRepository(PartyRelationshipEntity).save(relationship2)).rejects.toThrowError(
1851
+ 'SQLITE_CONSTRAINT: UNIQUE constraint failed: PartyRelationship.left_id, PartyRelationship.right_id',
1852
+ )
1853
+ })
1854
+
1855
+ it('Should save party type to database', async (): Promise<void> => {
1856
+ const partyType: NonPersistedPartyType = {
1857
+ type: PartyTypeType.NATURAL_PERSON,
1858
+ origin: PartyOrigin.INTERNAL,
1859
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1860
+ name: 'example_name',
1861
+ }
1862
+
1863
+ const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
1864
+ const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
1865
+
1866
+ const fromDb: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).findOne({
1867
+ where: { id: savedPartyType.id },
1868
+ })
1869
+
1870
+ expect(fromDb).toBeDefined()
1871
+ })
1872
+
1873
+ it('Should save person to database', async (): Promise<void> => {
1874
+ const person: NonPersistedNaturalPerson = {
1875
+ firstName: 'example_first_name',
1876
+ lastName: 'lastName2',
1877
+ displayName: 'displayName',
1878
+ }
1879
+
1880
+ const personEntity: NaturalPersonEntity = naturalPersonEntityFrom(person)
1881
+ const savedPerson: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).save(personEntity, {
1882
+ transaction: true,
1883
+ })
1884
+
1885
+ const fromDb: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).findOne({
1886
+ where: { id: savedPerson.id },
1887
+ })
1888
+
1889
+ expect(fromDb).toBeDefined()
1890
+ })
1891
+
1892
+ it('Should set last updated date when saving person', async (): Promise<void> => {
1893
+ const person: NonPersistedNaturalPerson = {
1894
+ firstName: 'example_first_name',
1895
+ lastName: 'lastName2',
1896
+ displayName: 'displayName',
1897
+ }
1898
+
1899
+ const personEntity: NaturalPersonEntity = naturalPersonEntityFrom(person)
1900
+ const savedPerson: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).save(personEntity, {
1901
+ transaction: true,
1902
+ })
1903
+
1904
+ const fromDb: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).findOne({
1905
+ where: { id: savedPerson.id },
1906
+ })
1907
+
1908
+ expect(fromDb).toBeDefined()
1909
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
1910
+ })
1911
+
1912
+ it('Should set creation date when saving person', async (): Promise<void> => {
1913
+ const person: NonPersistedNaturalPerson = {
1914
+ firstName: 'example_first_name',
1915
+ lastName: 'lastName2',
1916
+ displayName: 'displayName',
1917
+ }
1918
+
1919
+ const personEntity: NaturalPersonEntity = naturalPersonEntityFrom(person)
1920
+ const savedPerson: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).save(personEntity, {
1921
+ transaction: true,
1922
+ })
1923
+
1924
+ const fromDb: NaturalPersonEntity | null = await dbConnection.getRepository(NaturalPersonEntity).findOne({
1925
+ where: { id: savedPerson.id },
1926
+ })
1927
+
1928
+ expect(fromDb).toBeDefined()
1929
+ expect(fromDb?.createdAt).toBeDefined()
1930
+ })
1931
+
1932
+ it('Should save organization to database', async (): Promise<void> => {
1933
+ const organization: NonPersistedOrganization = {
1934
+ legalName: 'example_legal_name',
1935
+ displayName: 'example_display_name',
1936
+ }
1937
+
1938
+ const organizationEntity: OrganizationEntity = organizationEntityFrom(organization)
1939
+ const savedOrganization: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity, {
1940
+ transaction: true,
1941
+ })
1942
+
1943
+ const fromDb: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).findOne({
1944
+ where: { id: savedOrganization.id },
1945
+ })
1946
+
1947
+ expect(fromDb).toBeDefined()
1948
+ })
1949
+
1950
+ it('Should set last updated date when saving organization', async (): Promise<void> => {
1951
+ const organization: NonPersistedOrganization = {
1952
+ legalName: 'example_legal_name',
1953
+ displayName: 'example_display_name',
1954
+ }
1955
+
1956
+ const organizationEntity: OrganizationEntity = organizationEntityFrom(organization)
1957
+ const savedOrganization: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity, {
1958
+ transaction: true,
1959
+ })
1960
+
1961
+ const fromDb: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).findOne({
1962
+ where: { id: savedOrganization.id },
1963
+ })
1964
+
1965
+ expect(fromDb).toBeDefined()
1966
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
1967
+ })
1968
+
1969
+ it('Should set creation date when saving organization', async (): Promise<void> => {
1970
+ const organization: NonPersistedOrganization = {
1971
+ legalName: 'example_legal_name',
1972
+ displayName: 'example_display_name',
1973
+ }
1974
+
1975
+ const organizationEntity: OrganizationEntity = organizationEntityFrom(organization)
1976
+ const savedOrganization: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).save(organizationEntity, {
1977
+ transaction: true,
1978
+ })
1979
+
1980
+ const fromDb: OrganizationEntity | null = await dbConnection.getRepository(OrganizationEntity).findOne({
1981
+ where: { id: savedOrganization.id },
1982
+ })
1983
+
1984
+ expect(fromDb).toBeDefined()
1985
+ expect(fromDb?.createdAt).toBeDefined()
1986
+ })
1987
+
1988
+ it('Should get party based on person information', async (): Promise<void> => {
1989
+ const firstName = 'example_first_name'
1990
+ const party: NonPersistedParty = {
1991
+ uri: 'example.com',
1992
+ partyType: {
1993
+ type: PartyTypeType.NATURAL_PERSON,
1994
+ origin: PartyOrigin.INTERNAL,
1995
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
1996
+ name: 'example_name',
1997
+ },
1998
+ contact: {
1999
+ firstName,
2000
+ middleName: 'example_middle_name',
2001
+ lastName: 'example_last_name',
2002
+ displayName: 'example_display_name',
2003
+ },
2004
+ }
2005
+
2006
+ const partyEntity: PartyEntity = partyEntityFrom(party)
2007
+ await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2008
+ transaction: true,
2009
+ })
2010
+
2011
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
2012
+ where: {
2013
+ contact: {
2014
+ firstName,
2015
+ } as FindOptionsWhere<BaseContactEntity>, //NaturalPersonEntity | OrganizationEntity
2016
+ },
2017
+ })
2018
+
2019
+ expect(fromDb).toBeDefined()
2020
+ })
2021
+
2022
+ it('Should get party based on organization information', async (): Promise<void> => {
2023
+ const legalName = 'example_legal_name'
2024
+ const party: NonPersistedParty = {
2025
+ uri: 'example.com',
2026
+ partyType: {
2027
+ type: PartyTypeType.ORGANIZATION,
2028
+ origin: PartyOrigin.INTERNAL,
2029
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2030
+ name: 'example_name',
2031
+ },
2032
+ contact: {
2033
+ legalName,
2034
+ displayName: 'example_display_name',
2035
+ },
2036
+ }
2037
+
2038
+ const partyEntity: PartyEntity = partyEntityFrom(party)
2039
+ await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2040
+ transaction: true,
2041
+ })
2042
+
2043
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
2044
+ where: {
2045
+ contact: {
2046
+ legalName,
2047
+ } as FindOptionsWhere<BaseContactEntity>, //NaturalPersonEntity | OrganizationEntity
2048
+ },
2049
+ })
2050
+
2051
+ expect(fromDb).toBeDefined()
2052
+ })
2053
+
2054
+ it("Should enforce unique party id's for relationship sides", async (): Promise<void> => {
2055
+ const party: NonPersistedParty = {
2056
+ uri: 'example.com',
2057
+ partyType: {
2058
+ type: PartyTypeType.NATURAL_PERSON,
2059
+ origin: PartyOrigin.INTERNAL,
2060
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2061
+ name: 'example_name',
2062
+ },
2063
+ contact: {
2064
+ firstName: 'example_first_name',
2065
+ middleName: 'example_middle_name',
2066
+ lastName: 'example_last_name',
2067
+ displayName: 'example_display_name',
2068
+ },
2069
+ }
2070
+
2071
+ const partyEntity: PartyEntity = partyEntityFrom(party)
2072
+ const savedParty: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2073
+ transaction: true,
2074
+ })
2075
+
2076
+ expect(savedParty).toBeDefined()
2077
+
2078
+ const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
2079
+ leftId: savedParty.id,
2080
+ rightId: savedParty.id,
2081
+ })
2082
+
2083
+ await expect(dbConnection.getRepository(PartyRelationshipEntity).save(relationship)).rejects.toThrowError(
2084
+ 'Cannot use the same id for both sides of the relationship',
2085
+ )
2086
+ })
2087
+
2088
+ it('Should delete party relationship', async (): Promise<void> => {
2089
+ const party1: NonPersistedParty = {
2090
+ uri: 'example1.com',
2091
+ partyType: {
2092
+ type: PartyTypeType.NATURAL_PERSON,
2093
+ origin: PartyOrigin.INTERNAL,
2094
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2095
+ name: 'example_name1',
2096
+ },
2097
+ contact: {
2098
+ firstName: 'example_first_name1',
2099
+ middleName: 'example_middle_name1',
2100
+ lastName: 'example_last_name1',
2101
+ displayName: 'example_display_name1',
2102
+ },
2103
+ }
2104
+
2105
+ const partyEntity1: PartyEntity = partyEntityFrom(party1)
2106
+ const savedParty1: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity1, {
2107
+ transaction: true,
2108
+ })
2109
+
2110
+ expect(savedParty1).toBeDefined()
2111
+
2112
+ const party2: NonPersistedParty = {
2113
+ uri: 'example2.com',
2114
+ partyType: {
2115
+ type: PartyTypeType.NATURAL_PERSON,
2116
+ origin: PartyOrigin.INTERNAL,
2117
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d288',
2118
+ name: 'example_name2',
2119
+ },
2120
+ contact: {
2121
+ firstName: 'example_first_name2',
2122
+ middleName: 'example_middle_name2',
2123
+ lastName: 'example_last_name2',
2124
+ displayName: 'example_display_name2',
2125
+ },
2126
+ }
2127
+
2128
+ const partyEntity2: PartyEntity = partyEntityFrom(party2)
2129
+ const savedParty2: PartyEntity = await dbConnection.getRepository(PartyEntity).save(partyEntity2, {
2130
+ transaction: true,
2131
+ })
2132
+
2133
+ expect(savedParty2).toBeDefined()
2134
+
2135
+ const relationship: PartyRelationshipEntity = partyRelationshipEntityFrom({
2136
+ leftId: savedParty1.id,
2137
+ rightId: savedParty2.id,
2138
+ })
2139
+
2140
+ const savedRelationship: PartyRelationshipEntity | null = await dbConnection.getRepository(PartyRelationshipEntity).save(relationship, {
2141
+ transaction: true,
2142
+ })
2143
+
2144
+ expect(savedRelationship).toBeDefined()
2145
+
2146
+ await dbConnection.getRepository(PartyRelationshipEntity).delete({ id: savedRelationship.id })
2147
+
2148
+ await expect(
2149
+ await dbConnection.getRepository(PartyRelationshipEntity).findOne({
2150
+ where: { id: savedRelationship.id },
2151
+ }),
2152
+ ).toBeNull()
2153
+ })
2154
+
2155
+ it('Should delete party type', async (): Promise<void> => {
2156
+ const partyType: NonPersistedPartyType = {
2157
+ type: PartyTypeType.NATURAL_PERSON,
2158
+ origin: PartyOrigin.INTERNAL,
2159
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2160
+ name: 'example_name',
2161
+ }
2162
+
2163
+ const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
2164
+ const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
2165
+
2166
+ expect(savedPartyType).toBeDefined()
2167
+
2168
+ await dbConnection.getRepository(PartyTypeEntity).delete({ id: savedPartyType.id })
2169
+
2170
+ await expect(
2171
+ await dbConnection.getRepository(PartyTypeEntity).findOne({
2172
+ where: { id: savedPartyType.id },
2173
+ }),
2174
+ ).toBeNull()
2175
+ })
2176
+
2177
+ it('Should not be able to remove party type when used by parties', async (): Promise<void> => {
2178
+ const party: NonPersistedParty = {
2179
+ uri: 'example.com',
2180
+ partyType: {
2181
+ type: PartyTypeType.NATURAL_PERSON,
2182
+ origin: PartyOrigin.INTERNAL,
2183
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2184
+ name: 'example_name',
2185
+ },
2186
+ contact: {
2187
+ firstName: 'example_first_name',
2188
+ middleName: 'example_middle_name',
2189
+ lastName: 'example_last_name',
2190
+ displayName: 'example_display_name',
2191
+ },
2192
+ }
2193
+
2194
+ const partyEntity: PartyEntity = partyEntityFrom(party)
2195
+ const savedParty: PartyEntity | null = await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2196
+ transaction: true,
2197
+ })
2198
+
2199
+ expect(savedParty).toBeDefined()
2200
+
2201
+ await expect(dbConnection.getRepository(PartyTypeEntity).delete({ id: savedParty.partyType.id })).rejects.toThrowError(
2202
+ 'FOREIGN KEY constraint failed',
2203
+ )
2204
+ })
2205
+
2206
+ it('Should save party with existing party type', async (): Promise<void> => {
2207
+ const partyType: NonPersistedPartyType = {
2208
+ type: PartyTypeType.NATURAL_PERSON,
2209
+ origin: PartyOrigin.INTERNAL,
2210
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2211
+ name: 'example_name',
2212
+ }
2213
+
2214
+ const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
2215
+ const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
2216
+
2217
+ const party: NonPersistedParty = {
2218
+ uri: 'example.com',
2219
+ partyType: partyTypeFrom(savedPartyType),
2220
+ contact: {
2221
+ firstName: 'example_first_name',
2222
+ middleName: 'example_middle_name',
2223
+ lastName: 'example_last_name',
2224
+ displayName: 'example_display_name',
2225
+ },
2226
+ }
2227
+
2228
+ const partyEntity: PartyEntity = partyEntityFrom(party)
2229
+ partyEntity.partyType = savedPartyType
2230
+ await dbConnection.getRepository(PartyEntity).save(partyEntity, {
2231
+ transaction: true,
2232
+ })
2233
+
2234
+ const fromDb: PartyEntity | null = await dbConnection.getRepository(PartyEntity).findOne({
2235
+ where: { id: partyEntity.id },
2236
+ })
2237
+
2238
+ expect(fromDb).toBeDefined()
2239
+ expect(fromDb?.partyType).toBeDefined()
2240
+ expect(fromDb?.partyType.id).toEqual(savedPartyType.id)
2241
+ expect(fromDb?.partyType.type).toEqual(savedPartyType.type)
2242
+ expect(fromDb?.partyType.origin).toEqual(savedPartyType.origin)
2243
+ expect(fromDb?.partyType.tenantId).toEqual(savedPartyType.tenantId)
2244
+ expect(fromDb?.partyType.name).toEqual(savedPartyType.name)
2245
+ })
2246
+
2247
+ it('Should not update creation date when saving party type', async (): Promise<void> => {
2248
+ const partyType: NonPersistedPartyType = {
2249
+ type: PartyTypeType.NATURAL_PERSON,
2250
+ origin: PartyOrigin.INTERNAL,
2251
+ tenantId: '0605761c-4113-4ce5-a6b2-9cbae2f9d289',
2252
+ name: 'example_name',
2253
+ }
2254
+
2255
+ const partyTypeEntity: PartyTypeEntity = partyTypeEntityFrom(partyType)
2256
+ const savedPartyType: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).save(partyTypeEntity)
2257
+ await dbConnection.getRepository(PartyTypeEntity).save({ ...savedPartyType, type: PartyTypeType.ORGANIZATION })
2258
+
2259
+ const fromDb: PartyTypeEntity | null = await dbConnection.getRepository(PartyTypeEntity).findOne({
2260
+ where: {
2261
+ type: PartyTypeType.ORGANIZATION,
2262
+ },
2263
+ })
2264
+
2265
+ expect(fromDb).toBeDefined()
2266
+ expect(fromDb?.createdAt).toEqual(savedPartyType?.createdAt)
2267
+ })
2268
+
2269
+ it('Should save email electronic address to database', async (): Promise<void> => {
2270
+ const electronicAddress: NonPersistedElectronicAddress = {
2271
+ type: 'email',
2272
+ electronicAddress: 'example_email_address',
2273
+ }
2274
+
2275
+ const electronicAddressEntity: ElectronicAddressEntity = electronicAddressEntityFrom(electronicAddress)
2276
+ const savedElectronicAddress: ElectronicAddressEntity = await dbConnection.getRepository(ElectronicAddressEntity).save(electronicAddressEntity, {
2277
+ transaction: true,
2278
+ })
2279
+
2280
+ const fromDb: ElectronicAddressEntity | null = await dbConnection.getRepository(ElectronicAddressEntity).findOne({
2281
+ where: { id: savedElectronicAddress.id },
2282
+ })
2283
+
2284
+ expect(fromDb).toBeDefined()
2285
+ expect(fromDb?.type).toEqual(electronicAddress.type)
2286
+ expect(fromDb?.electronicAddress).toEqual(electronicAddress.electronicAddress)
2287
+ expect(fromDb?.createdAt).toBeDefined()
2288
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
2289
+ })
2290
+
2291
+ it('Should save phone electronic address to database', async (): Promise<void> => {
2292
+ const electronicAddress: NonPersistedElectronicAddress = {
2293
+ type: 'phone',
2294
+ electronicAddress: 'example_phone_number',
2295
+ }
2296
+
2297
+ const electronicAddressEntity: ElectronicAddressEntity = electronicAddressEntityFrom(electronicAddress)
2298
+ const savedElectronicAddress: ElectronicAddressEntity = await dbConnection.getRepository(ElectronicAddressEntity).save(electronicAddressEntity, {
2299
+ transaction: true,
2300
+ })
2301
+
2302
+ const fromDb: ElectronicAddressEntity | null = await dbConnection.getRepository(ElectronicAddressEntity).findOne({
2303
+ where: { id: savedElectronicAddress.id },
2304
+ })
2305
+
2306
+ expect(fromDb).toBeDefined()
2307
+ expect(fromDb?.type).toEqual(electronicAddress.type)
2308
+ expect(fromDb?.electronicAddress).toEqual(electronicAddress.electronicAddress)
2309
+ expect(fromDb?.createdAt).toBeDefined()
2310
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
2311
+ })
2312
+
2313
+ it('should throw error when saving electronic address with blank electronic address', async (): Promise<void> => {
2314
+ const electronicAddress: NonPersistedElectronicAddress = {
2315
+ type: 'email',
2316
+ electronicAddress: '',
2317
+ }
2318
+
2319
+ const electronicAddressEntity: ElectronicAddressEntity = electronicAddressEntityFrom(electronicAddress)
2320
+
2321
+ await expect(dbConnection.getRepository(ElectronicAddressEntity).save(electronicAddressEntity)).rejects.toThrowError(
2322
+ 'Blank electronic addresses are not allowed',
2323
+ )
2324
+ })
2325
+
2326
+ it('Should save home physical address to database', async (): Promise<void> => {
2327
+ const physicalAddress: NonPersistedPhysicalAddress = {
2328
+ type: 'home',
2329
+ streetName: 'example_street_name',
2330
+ streetNumber: 'example_street_number',
2331
+ buildingName: 'example_building_name',
2332
+ postalCode: 'example_postal_code',
2333
+ cityName: 'example_city_name',
2334
+ provinceName: 'example_province_name',
2335
+ countryCode: 'example_country_code',
2336
+ }
2337
+
2338
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2339
+ const savedPhysicalAddress: PhysicalAddressEntity = await dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity, {
2340
+ transaction: true,
2341
+ })
2342
+
2343
+ const fromDb: PhysicalAddressEntity | null = await dbConnection.getRepository(PhysicalAddressEntity).findOne({
2344
+ where: { id: savedPhysicalAddress.id },
2345
+ })
2346
+
2347
+ expect(fromDb).toBeDefined()
2348
+ expect(fromDb?.type).toEqual(physicalAddress.type)
2349
+ expect(fromDb?.streetName).toEqual(physicalAddress.streetName)
2350
+ expect(fromDb?.streetNumber).toEqual(physicalAddress.streetNumber)
2351
+ expect(fromDb?.buildingName).toEqual(physicalAddress.buildingName)
2352
+ expect(fromDb?.postalCode).toEqual(physicalAddress.postalCode)
2353
+ expect(fromDb?.cityName).toEqual(physicalAddress.cityName)
2354
+ expect(fromDb?.provinceName).toEqual(physicalAddress.provinceName)
2355
+ expect(fromDb?.countryCode).toEqual(physicalAddress.countryCode)
2356
+ expect(fromDb?.createdAt).toBeDefined()
2357
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
2358
+ })
2359
+
2360
+ it('Should save visit physical address to database', async (): Promise<void> => {
2361
+ const physicalAddress: NonPersistedPhysicalAddress = {
2362
+ type: 'visit',
2363
+ streetName: 'example_street_name',
2364
+ streetNumber: 'example_street_number',
2365
+ buildingName: 'example_building_name',
2366
+ postalCode: 'example_postal_code',
2367
+ cityName: 'example_city_name',
2368
+ provinceName: 'example_province_name',
2369
+ countryCode: 'example_country_code',
2370
+ }
2371
+
2372
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2373
+ const savedPhysicalAddress: PhysicalAddressEntity = await dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity, {
2374
+ transaction: true,
2375
+ })
2376
+
2377
+ const fromDb: PhysicalAddressEntity | null = await dbConnection.getRepository(PhysicalAddressEntity).findOne({
2378
+ where: { id: savedPhysicalAddress.id },
2379
+ })
2380
+
2381
+ expect(fromDb).toBeDefined()
2382
+ expect(fromDb?.type).toEqual(physicalAddress.type)
2383
+ expect(fromDb?.streetName).toEqual(physicalAddress.streetName)
2384
+ expect(fromDb?.streetNumber).toEqual(physicalAddress.streetNumber)
2385
+ expect(fromDb?.buildingName).toEqual(physicalAddress.buildingName)
2386
+ expect(fromDb?.postalCode).toEqual(physicalAddress.postalCode)
2387
+ expect(fromDb?.cityName).toEqual(physicalAddress.cityName)
2388
+ expect(fromDb?.provinceName).toEqual(physicalAddress.provinceName)
2389
+ expect(fromDb?.countryCode).toEqual(physicalAddress.countryCode)
2390
+ expect(fromDb?.createdAt).toBeDefined()
2391
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
2392
+ })
2393
+
2394
+ it('Should save postal physical address to database', async (): Promise<void> => {
2395
+ const physicalAddress: NonPersistedPhysicalAddress = {
2396
+ type: 'postal',
2397
+ streetName: 'example_street_name',
2398
+ streetNumber: 'example_street_number',
2399
+ buildingName: 'example_building_name',
2400
+ postalCode: 'example_postal_code',
2401
+ cityName: 'example_city_name',
2402
+ provinceName: 'example_province_name',
2403
+ countryCode: 'example_country_code',
2404
+ }
2405
+
2406
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2407
+ const savedPhysicalAddress: PhysicalAddressEntity = await dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity, {
2408
+ transaction: true,
2409
+ })
2410
+
2411
+ const fromDb: PhysicalAddressEntity | null = await dbConnection.getRepository(PhysicalAddressEntity).findOne({
2412
+ where: { id: savedPhysicalAddress.id },
2413
+ })
2414
+
2415
+ expect(fromDb).toBeDefined()
2416
+ expect(fromDb?.type).toEqual(physicalAddress.type)
2417
+ expect(fromDb?.streetName).toEqual(physicalAddress.streetName)
2418
+ expect(fromDb?.streetNumber).toEqual(physicalAddress.streetNumber)
2419
+ expect(fromDb?.buildingName).toEqual(physicalAddress.buildingName)
2420
+ expect(fromDb?.postalCode).toEqual(physicalAddress.postalCode)
2421
+ expect(fromDb?.cityName).toEqual(physicalAddress.cityName)
2422
+ expect(fromDb?.provinceName).toEqual(physicalAddress.provinceName)
2423
+ expect(fromDb?.countryCode).toEqual(physicalAddress.countryCode)
2424
+ expect(fromDb?.createdAt).toBeDefined()
2425
+ expect(fromDb?.lastUpdatedAt).toBeDefined()
2426
+ })
2427
+
2428
+ it('should throw error when saving physical address with blank street name', async (): Promise<void> => {
2429
+ const physicalAddress: NonPersistedPhysicalAddress = {
2430
+ type: 'home',
2431
+ streetName: '',
2432
+ streetNumber: 'example_street_number',
2433
+ buildingName: 'example_building_name',
2434
+ postalCode: 'example_postal_code',
2435
+ cityName: 'example_city_name',
2436
+ provinceName: 'example_province_name',
2437
+ countryCode: 'example_country_code',
2438
+ }
2439
+
2440
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2441
+
2442
+ await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2443
+ 'Blank street names are not allowed',
2444
+ )
2445
+ })
2446
+
2447
+ it('should throw error when saving physical address with blank street number', async (): Promise<void> => {
2448
+ const physicalAddress: NonPersistedPhysicalAddress = {
2449
+ type: 'home',
2450
+ streetName: 'example_street_name',
2451
+ streetNumber: '',
2452
+ buildingName: 'example_building_name',
2453
+ postalCode: 'example_postal_code',
2454
+ cityName: 'example_city_name',
2455
+ provinceName: 'example_province_name',
2456
+ countryCode: 'example_country_code',
2457
+ }
2458
+
2459
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2460
+
2461
+ await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2462
+ 'Blank street numbers are not allowed',
2463
+ )
2464
+ })
2465
+
2466
+ it('should throw error when saving physical address with blank building name', async (): Promise<void> => {
2467
+ const physicalAddress: NonPersistedPhysicalAddress = {
2468
+ type: 'home',
2469
+ streetName: 'example_street_name',
2470
+ streetNumber: 'example_street_number',
2471
+ buildingName: '',
2472
+ postalCode: 'example_postal_code',
2473
+ cityName: 'example_city_name',
2474
+ provinceName: 'example_province_name',
2475
+ countryCode: 'example_country_code',
2476
+ }
2477
+
2478
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2479
+
2480
+ await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2481
+ 'Blank building names are not allowed',
2482
+ )
2483
+ })
2484
+
2485
+ it('should throw error when saving physical address with blank postal code', async (): Promise<void> => {
2486
+ const physicalAddress: NonPersistedPhysicalAddress = {
2487
+ type: 'home',
2488
+ streetName: 'example_street_name',
2489
+ streetNumber: 'example_street_number',
2490
+ buildingName: 'example_building_name',
2491
+ postalCode: '',
2492
+ cityName: 'example_city_name',
2493
+ provinceName: 'example_province_name',
2494
+ countryCode: 'example_country_code',
2495
+ }
2496
+
2497
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2498
+
2499
+ await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2500
+ 'Blank postal codes are not allowed',
2501
+ )
2502
+ })
2503
+
2504
+ it('should throw error when saving physical address with blank city name', async (): Promise<void> => {
2505
+ const physicalAddress: NonPersistedPhysicalAddress = {
2506
+ type: 'home',
2507
+ streetName: 'example_street_name',
2508
+ streetNumber: 'example_street_number',
2509
+ buildingName: 'example_building_name',
2510
+ postalCode: 'example_postal_code',
2511
+ cityName: '',
2512
+ provinceName: 'example_province_name',
2513
+ countryCode: 'example_country_code',
2514
+ }
2515
+
2516
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2517
+
2518
+ await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2519
+ 'Blank city names are not allowed',
2520
+ )
2521
+ })
2522
+
2523
+ it('should throw error when saving physical address with blank province name', async (): Promise<void> => {
2524
+ const physicalAddress: NonPersistedPhysicalAddress = {
2525
+ type: 'home',
2526
+ streetName: 'example_street_name',
2527
+ streetNumber: 'example_street_number',
2528
+ buildingName: 'example_building_name',
2529
+ postalCode: 'example_postal_code',
2530
+ cityName: 'example_city_name',
2531
+ provinceName: '',
2532
+ countryCode: 'example_country_code',
2533
+ }
2534
+
2535
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2536
+
2537
+ await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2538
+ 'Blank province names are not allowed',
2539
+ )
2540
+ })
2541
+
2542
+ it('should throw error when saving physical address with blank country code', async (): Promise<void> => {
2543
+ const physicalAddress: NonPersistedPhysicalAddress = {
2544
+ type: 'home',
2545
+ streetName: 'example_street_name',
2546
+ streetNumber: 'example_street_number',
2547
+ buildingName: 'example_building_name',
2548
+ postalCode: 'example_postal_code',
2549
+ cityName: 'example_city_name',
2550
+ provinceName: 'example_province_name',
2551
+ countryCode: '',
2552
+ }
2553
+
2554
+ const physicalAddressEntity: PhysicalAddressEntity = physicalAddressEntityFrom(physicalAddress)
2555
+
2556
+ await expect(dbConnection.getRepository(PhysicalAddressEntity).save(physicalAddressEntity)).rejects.toThrowError(
2557
+ 'Blank country codes are not allowed',
2558
+ )
2559
+ })
2560
+
2561
+ it('Should save identity metadata item to database', async (): Promise<void> => {
2562
+ const metadataItem = {
2563
+ label: 'example_label',
2564
+ value: 'example_value',
2565
+ }
2566
+
2567
+ const identityMetadataItemEntity = identityMetadataItemEntityFrom(metadataItem)
2568
+
2569
+ await dbConnection.getRepository(IdentityMetadataItemEntity).save(identityMetadataItemEntity!)
2570
+
2571
+ const fromDb = await dbConnection.getRepository(IdentityMetadataItemEntity).findOne({
2572
+ where: { label: metadataItem.label },
2573
+ })
2574
+
2575
+ expect(fromDb).toBeDefined()
2576
+ expect(fromDb?.label).toEqual(metadataItem.label)
2577
+ expect(fromDb?.stringValue).toEqual(metadataItem.value)
2578
+ })
2579
+
2580
+ it('Should throw error when saving identity metadata item with blank label', async (): Promise<void> => {
2581
+ const metadataItem = {
2582
+ label: '',
2583
+ value: 'example_value',
2584
+ }
2585
+
2586
+ const identityMetadataItemEntity = identityMetadataItemEntityFrom(metadataItem)
2587
+
2588
+ await expect(dbConnection.getRepository(IdentityMetadataItemEntity).save(identityMetadataItemEntity!)).rejects.toThrowError(
2589
+ 'Blank metadata labels are not allowed',
2590
+ )
2591
+ })
2592
+
2593
+ it('Should throw error when saving identity metadata item with unsupported object type', async (): Promise<void> => {
2594
+ const metadataItem = {
2595
+ label: 'example_label',
2596
+ value: { unsupported: 'object' } as unknown as MetadataTypes, // Force not to have MetadataTypes
2597
+ }
2598
+
2599
+ expect(() => identityMetadataItemEntityFrom(metadataItem)).toThrowError('Unsupported object type: Object for value [object Object]')
2600
+ })
2601
+
2602
+ it('Should save contact metadata item to database', async (): Promise<void> => {
2603
+ const metadataItem = {
2604
+ label: 'example_label',
2605
+ value: 'example_value',
2606
+ }
2607
+
2608
+ const contactMetadataItemEntity = contactMetadataItemEntityFrom(metadataItem)
2609
+
2610
+ await dbConnection.getRepository(ContactMetadataItemEntity).save(contactMetadataItemEntity!)
2611
+
2612
+ const fromDb = await dbConnection.getRepository(ContactMetadataItemEntity).findOne({
2613
+ where: { label: metadataItem.label },
2614
+ })
2615
+
2616
+ expect(fromDb).toBeDefined()
2617
+ expect(fromDb?.label).toEqual(metadataItem.label)
2618
+ expect(fromDb?.stringValue).toEqual(metadataItem.value)
2619
+ })
2620
+
2621
+ it('Should throw error when saving contact metadata item with blank label', async (): Promise<void> => {
2622
+ const metadataItem = {
2623
+ label: '',
2624
+ value: 'example_value',
2625
+ }
2626
+
2627
+ const contactMetadataItemEntity = contactMetadataItemEntityFrom(metadataItem)
2628
+
2629
+ await expect(dbConnection.getRepository(ContactMetadataItemEntity).save(contactMetadataItemEntity!)).rejects.toThrowError(
2630
+ 'Blank metadata labels are not allowed',
2631
+ )
2632
+ })
2633
+
2634
+ it('Should throw error when saving contact metadata item with unsupported object type', async (): Promise<void> => {
2635
+ const metadataItem = {
2636
+ label: 'example_label',
2637
+ value: { unsupported: 'object' } as unknown as MetadataTypes, // Force not to have MetadataTypes
2638
+ }
2639
+
2640
+ expect(() => contactMetadataItemEntityFrom(metadataItem)).toThrowError('Unsupported object type: Object for value [object Object]')
2641
+ })
2642
+ })