@loopback/repository-tests 0.20.2 → 0.21.2

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 (187) hide show
  1. package/LICENSE +2 -2
  2. package/dist/crud/create-retrieve.suite.js +1 -1
  3. package/dist/crud/create-retrieve.suite.js.map +1 -1
  4. package/dist/crud/freeform-properties.suite.js +2 -2
  5. package/dist/crud/freeform-properties.suite.js.map +1 -1
  6. package/dist/crud/nested-model-properties.suite.js +1 -1
  7. package/dist/crud/nested-model-properties.suite.js.map +1 -1
  8. package/dist/crud/relations/acceptance/belongs-to.inclusion-resolver.polymorphic.relation.acceptance.d.ts +2 -0
  9. package/dist/crud/relations/acceptance/belongs-to.inclusion-resolver.polymorphic.relation.acceptance.js +170 -0
  10. package/dist/crud/relations/acceptance/belongs-to.inclusion-resolver.polymorphic.relation.acceptance.js.map +1 -0
  11. package/dist/crud/relations/acceptance/belongs-to.inclusion-resolver.relation.acceptance.js +1 -1
  12. package/dist/crud/relations/acceptance/belongs-to.inclusion-resolver.relation.acceptance.js.map +1 -1
  13. package/dist/crud/relations/acceptance/belongs-to.polymorphic.relation.acceptance.d.ts +2 -0
  14. package/dist/crud/relations/acceptance/belongs-to.polymorphic.relation.acceptance.js +55 -0
  15. package/dist/crud/relations/acceptance/belongs-to.polymorphic.relation.acceptance.js.map +1 -0
  16. package/dist/crud/relations/acceptance/belongs-to.relation.acceptance.js +1 -1
  17. package/dist/crud/relations/acceptance/belongs-to.relation.acceptance.js.map +1 -1
  18. package/dist/crud/relations/acceptance/has-many-inclusion-resolver.relation.acceptance.js +1 -1
  19. package/dist/crud/relations/acceptance/has-many-inclusion-resolver.relation.acceptance.js.map +1 -1
  20. package/dist/crud/relations/acceptance/has-many-through-inclusion-resolver.acceptance.js +1 -1
  21. package/dist/crud/relations/acceptance/has-many-through-inclusion-resolver.acceptance.js.map +1 -1
  22. package/dist/crud/relations/acceptance/has-many-through-inclusion-resolver.polymorphic.acceptance.d.ts +2 -0
  23. package/dist/crud/relations/acceptance/has-many-through-inclusion-resolver.polymorphic.acceptance.js +170 -0
  24. package/dist/crud/relations/acceptance/has-many-through-inclusion-resolver.polymorphic.acceptance.js.map +1 -0
  25. package/dist/crud/relations/acceptance/has-many-through.relation.acceptance.js +1 -1
  26. package/dist/crud/relations/acceptance/has-many-through.relation.acceptance.js.map +1 -1
  27. package/dist/crud/relations/acceptance/has-many-through.relation.polymorphic.acceptance.d.ts +2 -0
  28. package/dist/crud/relations/acceptance/has-many-through.relation.polymorphic.acceptance.js +361 -0
  29. package/dist/crud/relations/acceptance/has-many-through.relation.polymorphic.acceptance.js.map +1 -0
  30. package/dist/crud/relations/acceptance/has-many.relation.acceptance.js +1 -1
  31. package/dist/crud/relations/acceptance/has-many.relation.acceptance.js.map +1 -1
  32. package/dist/crud/relations/acceptance/has-one.inclusion-resolver.acceptance.js +1 -1
  33. package/dist/crud/relations/acceptance/has-one.inclusion-resolver.acceptance.js.map +1 -1
  34. package/dist/crud/relations/acceptance/has-one.inclusion-resolver.polymorphic.acceptance.d.ts +2 -0
  35. package/dist/crud/relations/acceptance/has-one.inclusion-resolver.polymorphic.acceptance.js +161 -0
  36. package/dist/crud/relations/acceptance/has-one.inclusion-resolver.polymorphic.acceptance.js.map +1 -0
  37. package/dist/crud/relations/acceptance/has-one.relation.acceptance.js +1 -1
  38. package/dist/crud/relations/acceptance/has-one.relation.acceptance.js.map +1 -1
  39. package/dist/crud/relations/acceptance/has-one.relation.polymorphic.acceptance.d.ts +2 -0
  40. package/dist/crud/relations/acceptance/has-one.relation.polymorphic.acceptance.js +190 -0
  41. package/dist/crud/relations/acceptance/has-one.relation.polymorphic.acceptance.js.map +1 -0
  42. package/dist/crud/relations/acceptance/multi-relations-inclusion-resolver.relation.acceptance.js +1 -1
  43. package/dist/crud/relations/acceptance/multi-relations-inclusion-resolver.relation.acceptance.js.map +1 -1
  44. package/dist/crud/relations/fixtures/models/address.model.js +1 -1
  45. package/dist/crud/relations/fixtures/models/address.model.js.map +1 -1
  46. package/dist/crud/relations/fixtures/models/cart-item.model.js +1 -1
  47. package/dist/crud/relations/fixtures/models/cart-item.model.js.map +1 -1
  48. package/dist/crud/relations/fixtures/models/contact.model.d.ts +18 -0
  49. package/dist/crud/relations/fixtures/models/contact.model.js +49 -0
  50. package/dist/crud/relations/fixtures/models/contact.model.js.map +1 -0
  51. package/dist/crud/relations/fixtures/models/customer-cart-item-link.model.js +1 -1
  52. package/dist/crud/relations/fixtures/models/customer-cart-item-link.model.js.map +1 -1
  53. package/dist/crud/relations/fixtures/models/customer-promotion-link.model.d.ts +14 -0
  54. package/dist/crud/relations/fixtures/models/customer-promotion-link.model.js +46 -0
  55. package/dist/crud/relations/fixtures/models/customer-promotion-link.model.js.map +1 -0
  56. package/dist/crud/relations/fixtures/models/customer.model.d.ts +16 -3
  57. package/dist/crud/relations/fixtures/models/customer.model.js +28 -10
  58. package/dist/crud/relations/fixtures/models/customer.model.js.map +1 -1
  59. package/dist/crud/relations/fixtures/models/index.d.ts +6 -0
  60. package/dist/crud/relations/fixtures/models/index.js +7 -1
  61. package/dist/crud/relations/fixtures/models/index.js.map +1 -1
  62. package/dist/crud/relations/fixtures/models/order.model.js +1 -1
  63. package/dist/crud/relations/fixtures/models/order.model.js.map +1 -1
  64. package/dist/crud/relations/fixtures/models/payment-method.model.d.ts +47 -0
  65. package/dist/crud/relations/fixtures/models/payment-method.model.js +87 -0
  66. package/dist/crud/relations/fixtures/models/payment-method.model.js.map +1 -0
  67. package/dist/crud/relations/fixtures/models/promotion.model.d.ts +27 -0
  68. package/dist/crud/relations/fixtures/models/promotion.model.js +54 -0
  69. package/dist/crud/relations/fixtures/models/promotion.model.js.map +1 -0
  70. package/dist/crud/relations/fixtures/models/shipment.model.js +1 -1
  71. package/dist/crud/relations/fixtures/models/shipment.model.js.map +1 -1
  72. package/dist/crud/relations/fixtures/models/stakeholder.model.d.ts +7 -0
  73. package/dist/crud/relations/fixtures/models/stakeholder.model.js +38 -0
  74. package/dist/crud/relations/fixtures/models/stakeholder.model.js.map +1 -0
  75. package/dist/crud/relations/fixtures/models/supplier.model.d.ts +15 -0
  76. package/dist/crud/relations/fixtures/models/supplier.model.js +23 -0
  77. package/dist/crud/relations/fixtures/models/supplier.model.js.map +1 -0
  78. package/dist/crud/relations/fixtures/models/user-link.model.js +1 -1
  79. package/dist/crud/relations/fixtures/models/user-link.model.js.map +1 -1
  80. package/dist/crud/relations/fixtures/models/user.model.js +1 -1
  81. package/dist/crud/relations/fixtures/models/user.model.js.map +1 -1
  82. package/dist/crud/relations/fixtures/repositories/address.repository.js +1 -1
  83. package/dist/crud/relations/fixtures/repositories/address.repository.js.map +1 -1
  84. package/dist/crud/relations/fixtures/repositories/cart-item.repository.js +1 -1
  85. package/dist/crud/relations/fixtures/repositories/cart-item.repository.js.map +1 -1
  86. package/dist/crud/relations/fixtures/repositories/contact.repository.d.ts +30 -0
  87. package/dist/crud/relations/fixtures/repositories/contact.repository.js +21 -0
  88. package/dist/crud/relations/fixtures/repositories/contact.repository.js.map +1 -0
  89. package/dist/crud/relations/fixtures/repositories/customer-cart-item-link.repository.js +1 -1
  90. package/dist/crud/relations/fixtures/repositories/customer-cart-item-link.repository.js.map +1 -1
  91. package/dist/crud/relations/fixtures/repositories/customer-promotion-link.repository.d.ts +26 -0
  92. package/dist/crud/relations/fixtures/repositories/customer-promotion-link.repository.js +18 -0
  93. package/dist/crud/relations/fixtures/repositories/customer-promotion-link.repository.js.map +1 -0
  94. package/dist/crud/relations/fixtures/repositories/customer.repository.d.ts +9 -2
  95. package/dist/crud/relations/fixtures/repositories/customer.repository.js +8 -2
  96. package/dist/crud/relations/fixtures/repositories/customer.repository.js.map +1 -1
  97. package/dist/crud/relations/fixtures/repositories/index.d.ts +6 -1
  98. package/dist/crud/relations/fixtures/repositories/index.js +7 -2
  99. package/dist/crud/relations/fixtures/repositories/index.js.map +1 -1
  100. package/dist/crud/relations/fixtures/repositories/order.repository.js +1 -1
  101. package/dist/crud/relations/fixtures/repositories/order.repository.js.map +1 -1
  102. package/dist/crud/relations/fixtures/repositories/payment-method.repository.d.ts +77 -0
  103. package/dist/crud/relations/fixtures/repositories/payment-method.repository.js +45 -0
  104. package/dist/crud/relations/fixtures/repositories/payment-method.repository.js.map +1 -0
  105. package/dist/crud/relations/fixtures/repositories/promotion.repository.d.ts +49 -0
  106. package/dist/crud/relations/fixtures/repositories/promotion.repository.js +25 -0
  107. package/dist/crud/relations/fixtures/repositories/promotion.repository.js.map +1 -0
  108. package/dist/crud/relations/fixtures/repositories/shipment.repository.js +1 -1
  109. package/dist/crud/relations/fixtures/repositories/shipment.repository.js.map +1 -1
  110. package/dist/crud/relations/fixtures/repositories/supplier.repository.d.ts +28 -0
  111. package/dist/crud/relations/fixtures/repositories/supplier.repository.js +21 -0
  112. package/dist/crud/relations/fixtures/repositories/supplier.repository.js.map +1 -0
  113. package/dist/crud/relations/fixtures/repositories/user-link.repository.js +1 -1
  114. package/dist/crud/relations/fixtures/repositories/user-link.repository.js.map +1 -1
  115. package/dist/crud/relations/fixtures/repositories/user.repository.js +1 -1
  116. package/dist/crud/relations/fixtures/repositories/user.repository.js.map +1 -1
  117. package/dist/crud/relations/helpers.d.ts +9 -1
  118. package/dist/crud/relations/helpers.js +86 -11
  119. package/dist/crud/relations/helpers.js.map +1 -1
  120. package/dist/crud/replace-by-id.suite.js +1 -1
  121. package/dist/crud/replace-by-id.suite.js.map +1 -1
  122. package/dist/crud/transactions.suite.js +1 -1
  123. package/dist/crud/transactions.suite.js.map +1 -1
  124. package/dist/crud-test-suite.js +1 -1
  125. package/dist/crud-test-suite.js.map +1 -1
  126. package/dist/helpers.repository-tests.d.ts +1 -1
  127. package/dist/helpers.repository-tests.js +1 -1
  128. package/dist/helpers.repository-tests.js.map +1 -1
  129. package/dist/index.js +1 -1
  130. package/dist/index.js.map +1 -1
  131. package/dist/types.repository-tests.js +1 -1
  132. package/dist/types.repository-tests.js.map +1 -1
  133. package/package.json +14 -14
  134. package/src/crud/create-retrieve.suite.ts +1 -1
  135. package/src/crud/freeform-properties.suite.ts +10 -6
  136. package/src/crud/nested-model-properties.suite.ts +1 -1
  137. package/src/crud/relations/acceptance/belongs-to.inclusion-resolver.polymorphic.relation.acceptance.ts +221 -0
  138. package/src/crud/relations/acceptance/belongs-to.inclusion-resolver.relation.acceptance.ts +1 -1
  139. package/src/crud/relations/acceptance/belongs-to.polymorphic.relation.acceptance.ts +88 -0
  140. package/src/crud/relations/acceptance/belongs-to.relation.acceptance.ts +1 -1
  141. package/src/crud/relations/acceptance/has-many-inclusion-resolver.relation.acceptance.ts +1 -1
  142. package/src/crud/relations/acceptance/has-many-through-inclusion-resolver.acceptance.ts +1 -1
  143. package/src/crud/relations/acceptance/has-many-through-inclusion-resolver.polymorphic.acceptance.ts +255 -0
  144. package/src/crud/relations/acceptance/has-many-through.relation.acceptance.ts +2 -2
  145. package/src/crud/relations/acceptance/has-many-through.relation.polymorphic.acceptance.ts +494 -0
  146. package/src/crud/relations/acceptance/has-many.relation.acceptance.ts +1 -1
  147. package/src/crud/relations/acceptance/has-one.inclusion-resolver.acceptance.ts +1 -1
  148. package/src/crud/relations/acceptance/has-one.inclusion-resolver.polymorphic.acceptance.ts +208 -0
  149. package/src/crud/relations/acceptance/has-one.relation.acceptance.ts +1 -1
  150. package/src/crud/relations/acceptance/has-one.relation.polymorphic.acceptance.ts +328 -0
  151. package/src/crud/relations/acceptance/multi-relations-inclusion-resolver.relation.acceptance.ts +1 -1
  152. package/src/crud/relations/fixtures/models/address.model.ts +1 -1
  153. package/src/crud/relations/fixtures/models/cart-item.model.ts +1 -1
  154. package/src/crud/relations/fixtures/models/contact.model.ts +56 -0
  155. package/src/crud/relations/fixtures/models/customer-cart-item-link.model.ts +1 -1
  156. package/src/crud/relations/fixtures/models/customer-promotion-link.model.ts +52 -0
  157. package/src/crud/relations/fixtures/models/customer.model.ts +40 -10
  158. package/src/crud/relations/fixtures/models/index.ts +7 -1
  159. package/src/crud/relations/fixtures/models/order.model.ts +1 -1
  160. package/src/crud/relations/fixtures/models/payment-method.model.ts +118 -0
  161. package/src/crud/relations/fixtures/models/promotion.model.ts +67 -0
  162. package/src/crud/relations/fixtures/models/shipment.model.ts +1 -1
  163. package/src/crud/relations/fixtures/models/stakeholder.model.ts +33 -0
  164. package/src/crud/relations/fixtures/models/supplier.model.ts +35 -0
  165. package/src/crud/relations/fixtures/models/user-link.model.ts +1 -1
  166. package/src/crud/relations/fixtures/models/user.model.ts +1 -1
  167. package/src/crud/relations/fixtures/repositories/address.repository.ts +1 -1
  168. package/src/crud/relations/fixtures/repositories/cart-item.repository.ts +1 -1
  169. package/src/crud/relations/fixtures/repositories/contact.repository.ts +44 -0
  170. package/src/crud/relations/fixtures/repositories/customer-cart-item-link.repository.ts +1 -1
  171. package/src/crud/relations/fixtures/repositories/customer-promotion-link.repository.ts +20 -0
  172. package/src/crud/relations/fixtures/repositories/customer.repository.ts +48 -1
  173. package/src/crud/relations/fixtures/repositories/index.ts +7 -2
  174. package/src/crud/relations/fixtures/repositories/order.repository.ts +1 -1
  175. package/src/crud/relations/fixtures/repositories/payment-method.repository.ts +118 -0
  176. package/src/crud/relations/fixtures/repositories/promotion.repository.ts +37 -0
  177. package/src/crud/relations/fixtures/repositories/shipment.repository.ts +1 -1
  178. package/src/crud/relations/fixtures/repositories/supplier.repository.ts +40 -0
  179. package/src/crud/relations/fixtures/repositories/user-link.repository.ts +1 -1
  180. package/src/crud/relations/fixtures/repositories/user.repository.ts +1 -1
  181. package/src/crud/relations/helpers.ts +201 -31
  182. package/src/crud/replace-by-id.suite.ts +1 -1
  183. package/src/crud/transactions.suite.ts +1 -1
  184. package/src/crud-test-suite.ts +1 -1
  185. package/src/helpers.repository-tests.ts +2 -2
  186. package/src/index.ts +1 -1
  187. package/src/types.repository-tests.ts +1 -1
@@ -0,0 +1,208 @@
1
+ // Copyright IBM Corp. and LoopBack contributors 2019,2020. All Rights Reserved.
2
+ // Node module: @loopback/repository-tests
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ import {expect, skipIf, toJSON} from '@loopback/testlab';
7
+ import {Suite} from 'mocha';
8
+ import {
9
+ CrudFeatures,
10
+ CrudRepositoryCtor,
11
+ CrudTestContext,
12
+ DataSourceOptions,
13
+ } from '../../..';
14
+ import {
15
+ deleteAllModelsInDefaultDataSource,
16
+ withCrudCtx,
17
+ } from '../../../helpers.repository-tests';
18
+ import {
19
+ CardInfoRepository,
20
+ Cash,
21
+ CashRepository,
22
+ CreditCard,
23
+ CreditCardRepository,
24
+ Customer,
25
+ CustomerRepository,
26
+ } from '../fixtures/models';
27
+ import {givenBoundCrudRepositories} from '../helpers';
28
+
29
+ export function hasOneInclusionResolverPolymorphicAcceptance(
30
+ dataSourceOptions: DataSourceOptions,
31
+ repositoryClass: CrudRepositoryCtor,
32
+ features: CrudFeatures,
33
+ ) {
34
+ skipIf<[(this: Suite) => void], void>(
35
+ !features.supportsInclusionResolvers,
36
+ describe,
37
+ 'HasOne inclusion resolvers - polymorphic - acceptance',
38
+ suite,
39
+ );
40
+ function suite() {
41
+ before(deleteAllModelsInDefaultDataSource);
42
+ let customerRepo: CustomerRepository;
43
+ let creditCardRepo: CreditCardRepository;
44
+ let cashRepo: CashRepository;
45
+ let cardInfoRepo: CardInfoRepository;
46
+
47
+ before(
48
+ withCrudCtx(async function setupRepository(ctx: CrudTestContext) {
49
+ // this helper should create the inclusion resolvers and also
50
+ // register inclusion resolvers for us
51
+ ({customerRepo, creditCardRepo, cashRepo, cardInfoRepo} =
52
+ givenBoundCrudRepositories(
53
+ ctx.dataSource,
54
+ repositoryClass,
55
+ features,
56
+ ));
57
+ expect(customerRepo.paymentMethod.inclusionResolver).to.be.Function();
58
+
59
+ await ctx.dataSource.automigrate([
60
+ Customer.name,
61
+ CreditCard.name,
62
+ Cash.name,
63
+ ]);
64
+ }),
65
+ );
66
+
67
+ beforeEach(async () => {
68
+ await customerRepo.deleteAll();
69
+ await creditCardRepo.deleteAll();
70
+ await cashRepo.deleteAll();
71
+ await cardInfoRepo.deleteAll();
72
+ });
73
+
74
+ it('throws an error if it tries to query nonexistent relation names', async () => {
75
+ const customer = await customerRepo.create({
76
+ name: 'customer',
77
+ paymentMethodType: 'CreditCard',
78
+ });
79
+ await creditCardRepo.create({
80
+ customerId: customer.id,
81
+ });
82
+ await expect(customerRepo.find({include: ['home']})).to.be.rejectedWith(
83
+ `Invalid "filter.include" entries: "home"`,
84
+ );
85
+ });
86
+
87
+ it('returns single model instance including single related instance', async () => {
88
+ const thor = await customerRepo.create({
89
+ name: 'Thor',
90
+ paymentMethodType: 'CreditCard',
91
+ });
92
+ const thorCreditCard = await creditCardRepo.create({
93
+ customerId: thor.id,
94
+ });
95
+ const result = await customerRepo.find({
96
+ include: ['paymentMethod'],
97
+ });
98
+
99
+ const expected = {
100
+ ...thor,
101
+ parentId: features.emptyValue,
102
+ paymentMethod: thorCreditCard,
103
+ };
104
+ expect(toJSON(result)).to.deepEqual([toJSON(expected)]);
105
+ });
106
+
107
+ it('returns multiple model instances including related instances', async () => {
108
+ const thor = await customerRepo.create({
109
+ name: 'Thor',
110
+ paymentMethodType: 'Cash',
111
+ });
112
+ const odin = await customerRepo.create({
113
+ name: 'Odin',
114
+ paymentMethodType: 'CreditCard',
115
+ });
116
+ const thorCash = await cashRepo.create({
117
+ customerId: thor.id,
118
+ });
119
+ const odinCreditCard = await creditCardRepo.create({
120
+ customerId: odin.id,
121
+ });
122
+
123
+ const result = await customerRepo.find({
124
+ include: ['paymentMethod'],
125
+ });
126
+
127
+ const expected = [
128
+ {
129
+ ...thor,
130
+ parentId: features.emptyValue,
131
+ paymentMethod: thorCash,
132
+ },
133
+ {
134
+ ...odin,
135
+ parentId: features.emptyValue,
136
+ paymentMethod: odinCreditCard,
137
+ },
138
+ ];
139
+ expect(toJSON(result)).to.deepEqual(toJSON(expected));
140
+ });
141
+
142
+ it('returns a specified instance including its related model instance', async () => {
143
+ const thor = await customerRepo.create({
144
+ name: 'Thor',
145
+ paymentMethodType: 'Cash',
146
+ });
147
+ const odin = await customerRepo.create({
148
+ name: 'Odin',
149
+ paymentMethodType: 'CreditCard',
150
+ });
151
+ const bella = await customerRepo.create({
152
+ name: 'Bella',
153
+ paymentMethodType: 'CreditCard',
154
+ });
155
+ await cashRepo.create({
156
+ customerId: thor.id,
157
+ });
158
+ await creditCardRepo.create({
159
+ customerId: odin.id,
160
+ });
161
+ const bellaPaymentMethod = await creditCardRepo.create({
162
+ customerId: bella.id,
163
+ });
164
+ const bellaCardInfo = await creditCardRepo
165
+ .cardInfo(bellaPaymentMethod.id)
166
+ .create({cardHolder: 'bella!'});
167
+ bellaPaymentMethod.cardInfo = bellaCardInfo;
168
+ const result = await customerRepo.findById(bella.id, {
169
+ include: [
170
+ {
171
+ relation: 'paymentMethod',
172
+ scope: {
173
+ include: [
174
+ {
175
+ relation: 'cardInfo',
176
+ targetType: 'CreditCard',
177
+ },
178
+ ],
179
+ },
180
+ },
181
+ ],
182
+ });
183
+
184
+ const expected = {
185
+ ...bella,
186
+ parentId: features.emptyValue,
187
+ paymentMethod: bellaPaymentMethod,
188
+ };
189
+ expect(toJSON(result)).to.deepEqual(toJSON(expected));
190
+ });
191
+
192
+ it('throws error if the target repository does not have the registered resolver', async () => {
193
+ const customer = await customerRepo.create({
194
+ name: 'customer',
195
+ paymentMethodType: 'CreditCard',
196
+ });
197
+ await creditCardRepo.create({
198
+ customerId: customer.id,
199
+ });
200
+ // unregister the resolver
201
+ customerRepo.inclusionResolvers.delete('paymentMethod');
202
+
203
+ await expect(
204
+ customerRepo.find({include: ['paymentMethod']}),
205
+ ).to.be.rejectedWith(`Invalid "filter.include" entries: "paymentMethod"`);
206
+ });
207
+ }
208
+ }
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2019,2020. All Rights Reserved.
1
+ // Copyright IBM Corp. and LoopBack contributors 2019,2020. All Rights Reserved.
2
2
  // Node module: @loopback/repository-tests
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -0,0 +1,328 @@
1
+ // Copyright IBM Corp. and LoopBack contributors 2019,2020. All Rights Reserved.
2
+ // Node module: @loopback/repository-tests
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ import {DataObject, EntityNotFoundError} from '@loopback/repository';
7
+ import {expect, toJSON} from '@loopback/testlab';
8
+ import {
9
+ CrudFeatures,
10
+ CrudRepositoryCtor,
11
+ CrudTestContext,
12
+ DataSourceOptions,
13
+ } from '../../..';
14
+ import {
15
+ deleteAllModelsInDefaultDataSource,
16
+ MixedIdType,
17
+ withCrudCtx,
18
+ } from '../../../helpers.repository-tests';
19
+ import {
20
+ Cash,
21
+ CashRepository,
22
+ CreditCard,
23
+ CreditCardRepository,
24
+ Customer,
25
+ CustomerRepository,
26
+ PaymentMethod,
27
+ } from '../fixtures/models';
28
+ import {givenBoundCrudRepositories} from '../helpers';
29
+
30
+ export function hasOneRelationPolymorphicAcceptance(
31
+ dataSourceOptions: DataSourceOptions,
32
+ repositoryClass: CrudRepositoryCtor,
33
+ features: CrudFeatures,
34
+ ) {
35
+ describe('hasOne relation polymorphic (acceptance)', () => {
36
+ let customerRepo: CustomerRepository;
37
+ let creditCardRepo: CreditCardRepository;
38
+ let cashRepo: CashRepository;
39
+ let existingCustomerId: MixedIdType;
40
+
41
+ before(deleteAllModelsInDefaultDataSource);
42
+
43
+ before(
44
+ withCrudCtx(async function setupRepository(ctx: CrudTestContext) {
45
+ ({customerRepo, creditCardRepo, cashRepo} = givenBoundCrudRepositories(
46
+ ctx.dataSource,
47
+ repositoryClass,
48
+ features,
49
+ ));
50
+ const models = [Customer, CreditCard, Cash];
51
+ await ctx.dataSource.automigrate(models.map(m => m.name));
52
+ }),
53
+ );
54
+
55
+ beforeEach(async () => {
56
+ await customerRepo.deleteAll();
57
+ await creditCardRepo.deleteAll();
58
+ await cashRepo.deleteAll();
59
+ existingCustomerId = (await givenPersistedCustomerInstance()).id;
60
+ });
61
+
62
+ it('can create an instance of the related model', async () => {
63
+ const address = await createCustomerPaymentMethod(
64
+ existingCustomerId,
65
+ {},
66
+ 'CreditCard',
67
+ );
68
+ expect(toJSON(address)).to.containDeep(
69
+ toJSON({
70
+ customerId: existingCustomerId,
71
+ }),
72
+ );
73
+
74
+ const persisted = await creditCardRepo.findById(address.id);
75
+ expect(toJSON(persisted)).to.deepEqual(
76
+ toJSON({
77
+ ...address,
78
+ zipcode: features.emptyValue,
79
+ city: features.emptyValue,
80
+ province: features.emptyValue,
81
+ }),
82
+ );
83
+ });
84
+
85
+ // We do not enforce referential integrity at the moment. It is up to
86
+ // our users to set up unique constraint(s) between related models at the
87
+ // database level
88
+ it.skip('refuses to create related model instance twice', async () => {
89
+ const creditCard = await createCustomerPaymentMethod(
90
+ existingCustomerId,
91
+ {},
92
+ 'CreditCard',
93
+ );
94
+ await expect(
95
+ createCustomerPaymentMethod(existingCustomerId, {}, 'Cash'),
96
+ ).to.be.rejectedWith(/Duplicate entry for PaymentMethod.customerId/);
97
+ expect(creditCard.toObject()).to.containDeep({
98
+ customerId: existingCustomerId,
99
+ });
100
+
101
+ const persisted = await creditCardRepo.findById(creditCard.id);
102
+ expect(persisted.toObject()).to.deepEqual(creditCard.toObject());
103
+ });
104
+
105
+ it('can find instance of the related model', async () => {
106
+ const creditCard = await createCustomerPaymentMethod(
107
+ existingCustomerId,
108
+ {},
109
+ 'CreditCard',
110
+ );
111
+ const foundCreditCard = await findCustomerPaymentMethod(
112
+ existingCustomerId,
113
+ 'CreditCard',
114
+ );
115
+ expect(toJSON(foundCreditCard)).to.containEql(toJSON(creditCard));
116
+ expect(toJSON(foundCreditCard)).to.deepEqual(
117
+ toJSON({
118
+ ...creditCard,
119
+ }),
120
+ );
121
+
122
+ const persisted = await creditCardRepo.find({
123
+ where: {customerId: existingCustomerId},
124
+ });
125
+ expect(persisted[0]).to.deepEqual(foundCreditCard);
126
+ });
127
+
128
+ it('reports EntityNotFound error when related model is deleted', async () => {
129
+ const paymentMethod = await createCustomerPaymentMethod(
130
+ existingCustomerId,
131
+ {},
132
+ 'CreditCard',
133
+ );
134
+ await creditCardRepo.deleteById(paymentMethod.id);
135
+
136
+ await expect(
137
+ findCustomerPaymentMethod(existingCustomerId, 'CreditCard'),
138
+ ).to.be.rejectedWith(EntityNotFoundError);
139
+ });
140
+
141
+ it('can PATCH hasOne instances', async () => {
142
+ const paymentMethod = await createCustomerPaymentMethod(
143
+ existingCustomerId,
144
+ {},
145
+ 'CreditCard',
146
+ );
147
+
148
+ const patchObject = {cardNumber: 46458921} as DataObject<PaymentMethod>;
149
+ const arePatched = await patchCustomerPaymentMethod(
150
+ existingCustomerId,
151
+ {CreditCard: patchObject as DataObject<CreditCard>} as {
152
+ [polymorphicType: string]: DataObject<CreditCard>;
153
+ },
154
+ true,
155
+ );
156
+
157
+ expect(arePatched).to.deepEqual({count: 1});
158
+ const patchedData = await creditCardRepo.findById(paymentMethod.id);
159
+
160
+ expect(toJSON(patchedData)).to.deepEqual(
161
+ toJSON({
162
+ id: paymentMethod.id,
163
+ customerId: existingCustomerId,
164
+ cardNumber: 46458921,
165
+ }),
166
+ );
167
+ });
168
+
169
+ it('patches the related instance only', async () => {
170
+ const bob = await customerRepo.create({name: 'Bob'});
171
+ await customerRepo
172
+ .paymentMethod(bob.id)
173
+ .create({cardNumber: 12345} as DataObject<PaymentMethod>, {
174
+ polymorphicType: 'CreditCard',
175
+ });
176
+
177
+ const alice = await customerRepo.create({name: 'Alice'});
178
+ await customerRepo
179
+ .paymentMethod(alice.id)
180
+ .create({cardNumber: 67890} as DataObject<PaymentMethod>, {
181
+ polymorphicType: 'CreditCard',
182
+ });
183
+
184
+ const result = await patchCustomerPaymentMethod(
185
+ alice.id,
186
+ {
187
+ CreditCard: {
188
+ cardNumber: 7894512,
189
+ } as DataObject<CreditCard>,
190
+ } as {[polymorphicType: string]: DataObject<CreditCard>},
191
+ true,
192
+ );
193
+
194
+ expect(result).to.deepEqual({count: 1});
195
+
196
+ const foundBob = await customerRepo
197
+ .paymentMethod(bob.id)
198
+ .get(undefined, {polymorphicType: 'CreditCard'});
199
+ expect(toJSON(foundBob)).to.containDeep({cardNumber: 12345});
200
+
201
+ const foundAlice = await customerRepo
202
+ .paymentMethod(bob.id)
203
+ .get(undefined, {polymorphicType: 'CreditCard'});
204
+ expect(toJSON(foundAlice)).to.containDeep({cardNumber: 12345});
205
+ });
206
+
207
+ it('throws an error when PATCH tries to change the foreignKey', async () => {
208
+ const anotherId = (await givenPersistedCustomerInstance()).id;
209
+ await expect(
210
+ patchCustomerPaymentMethod(
211
+ existingCustomerId,
212
+ {
213
+ CreditCard: {
214
+ customerId: anotherId,
215
+ } as DataObject<CreditCard>,
216
+ } as {[polymorphicType: string]: DataObject<CreditCard>},
217
+ true,
218
+ ),
219
+ ).to.be.rejectedWith(/Property "customerId" cannot be changed!/);
220
+ });
221
+
222
+ it('can DELETE hasOne relation instances', async () => {
223
+ await createCustomerPaymentMethod(existingCustomerId, {}, 'CreditCard');
224
+
225
+ const areDeleted = await deleteCustomerPaymentMethod(
226
+ existingCustomerId,
227
+ 'CreditCard',
228
+ );
229
+ expect(areDeleted).to.deepEqual({count: 1});
230
+
231
+ await expect(
232
+ findCustomerPaymentMethod(existingCustomerId, 'CreditCard'),
233
+ ).to.be.rejectedWith(EntityNotFoundError);
234
+ });
235
+
236
+ it('deletes the related model instance only', async () => {
237
+ const bob = await customerRepo.create({name: 'Bob'});
238
+ await customerRepo
239
+ .paymentMethod(bob.id)
240
+ .create({}, {polymorphicType: 'CreditCard'});
241
+
242
+ const alice = await customerRepo.create({name: 'Alice'});
243
+ await customerRepo
244
+ .paymentMethod(alice.id)
245
+ .create({}, {polymorphicType: 'Cash'});
246
+
247
+ const brown = await customerRepo.create({name: 'Brown'});
248
+ await customerRepo
249
+ .paymentMethod(brown.id)
250
+ .create({}, {polymorphicType: 'Cash'});
251
+
252
+ const result = await deleteCustomerPaymentMethod(alice.id, 'Cash');
253
+
254
+ expect(result).to.deepEqual({count: 1});
255
+
256
+ const found = await cashRepo.find();
257
+ expect(found).to.have.length(1);
258
+ });
259
+
260
+ it('deletes the related model instance with wrong type', async () => {
261
+ const bob = await customerRepo.create({name: 'Bob'});
262
+ await customerRepo
263
+ .paymentMethod(bob.id)
264
+ .create({}, {polymorphicType: 'CreditCard'});
265
+
266
+ const alice = await customerRepo.create({name: 'Alice'});
267
+ await customerRepo
268
+ .paymentMethod(alice.id)
269
+ .create({}, {polymorphicType: 'Cash'});
270
+
271
+ const brown = await customerRepo.create({name: 'Brown'});
272
+ await customerRepo
273
+ .paymentMethod(brown.id)
274
+ .create({}, {polymorphicType: 'Cash'});
275
+
276
+ const result = await deleteCustomerPaymentMethod(alice.id, 'CreditCard');
277
+
278
+ expect(result).to.deepEqual({count: 0});
279
+
280
+ const found = await cashRepo.find();
281
+ expect(found).to.have.length(2);
282
+ });
283
+
284
+ /*---------------- HELPERS -----------------*/
285
+
286
+ async function createCustomerPaymentMethod(
287
+ customerId: MixedIdType,
288
+ paymentMethodData: DataObject<PaymentMethod>,
289
+ polymorphicTypeName: string,
290
+ ): Promise<PaymentMethod> {
291
+ return customerRepo
292
+ .paymentMethod(customerId)
293
+ .create(paymentMethodData, {polymorphicType: polymorphicTypeName});
294
+ }
295
+
296
+ async function findCustomerPaymentMethod(
297
+ customerId: MixedIdType,
298
+ polymorphicType: string,
299
+ ) {
300
+ return customerRepo
301
+ .paymentMethod(customerId)
302
+ .get(undefined, {polymorphicType: polymorphicType});
303
+ }
304
+
305
+ async function patchCustomerPaymentMethod(
306
+ customerId: MixedIdType,
307
+ paymentMethodData: DataObject<PaymentMethod>,
308
+ isMultipleTypes: boolean,
309
+ ) {
310
+ return customerRepo
311
+ .paymentMethod(customerId)
312
+ .patch(paymentMethodData, {isPolymorphic: isMultipleTypes});
313
+ }
314
+
315
+ async function deleteCustomerPaymentMethod(
316
+ customerId: MixedIdType,
317
+ polymorphicType: string,
318
+ ) {
319
+ return customerRepo
320
+ .paymentMethod(customerId)
321
+ .delete({polymorphicType: polymorphicType});
322
+ }
323
+
324
+ async function givenPersistedCustomerInstance() {
325
+ return customerRepo.create({name: 'a customer'});
326
+ }
327
+ });
328
+ }
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2019,2020. All Rights Reserved.
1
+ // Copyright IBM Corp. and LoopBack contributors 2019,2020. All Rights Reserved.
2
2
  // Node module: @loopback/repository-tests
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2019. All Rights Reserved.
1
+ // Copyright IBM Corp. and LoopBack contributors 2019. All Rights Reserved.
2
2
  // Node module: @loopback/repository-tests
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2020. All Rights Reserved.
1
+ // Copyright IBM Corp. and LoopBack contributors 2020. All Rights Reserved.
2
2
  // Node module: @loopback/repository-tests
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -0,0 +1,56 @@
1
+ // Copyright IBM Corp. and LoopBack contributors 2019. All Rights Reserved.
2
+ // Node module: @loopback/repository-tests
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ import {
7
+ belongsTo,
8
+ BelongsToAccessor,
9
+ Entity,
10
+ EntityCrudRepository,
11
+ model,
12
+ property,
13
+ } from '@loopback/repository';
14
+ import {MixedIdType} from '../../../../helpers.repository-tests';
15
+ import {CustomerWithRelations} from './customer.model';
16
+ import {Stakeholder} from './stakeholder.model';
17
+
18
+ @model()
19
+ export class Contact extends Entity {
20
+ @property({
21
+ id: true,
22
+ generated: true,
23
+ useDefaultIdType: true,
24
+ })
25
+ id: MixedIdType;
26
+ @property({
27
+ type: 'string',
28
+ })
29
+ name: string;
30
+ @property({
31
+ type: 'string',
32
+ })
33
+ email: string;
34
+
35
+ @belongsTo(() => Stakeholder, {polymorphic: true})
36
+ stakeholderId: MixedIdType;
37
+
38
+ @property({
39
+ type: 'string',
40
+ required: true,
41
+ default: 'Customer',
42
+ })
43
+ stakeholderType: string;
44
+ }
45
+
46
+ export interface ContactRelations {
47
+ stakeholder?: CustomerWithRelations;
48
+ }
49
+
50
+ export type ContactWithRelations = Contact & ContactRelations;
51
+
52
+ export interface ContactRepository
53
+ extends EntityCrudRepository<Contact, typeof Contact.prototype.id> {
54
+ // define additional members like relation methods here
55
+ stakeholder: BelongsToAccessor<Stakeholder, MixedIdType>;
56
+ }
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2020. All Rights Reserved.
1
+ // Copyright IBM Corp. and LoopBack contributors 2020. All Rights Reserved.
2
2
  // Node module: @loopback/repository-tests
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -0,0 +1,52 @@
1
+ // Copyright IBM Corp. and LoopBack contributors 2020. All Rights Reserved.
2
+ // Node module: @loopback/repository-tests
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ import {
7
+ Entity,
8
+ EntityCrudRepository,
9
+ model,
10
+ property,
11
+ } from '@loopback/repository';
12
+ import {MixedIdType} from '../../../../helpers.repository-tests';
13
+
14
+ @model()
15
+ export class CustomerPromotionLink extends Entity {
16
+ @property({
17
+ id: true,
18
+ generated: true,
19
+ useDefaultIdType: true,
20
+ })
21
+ id: MixedIdType;
22
+
23
+ @property()
24
+ customerId: MixedIdType;
25
+
26
+ @property()
27
+ // eslint-disable-next-line @typescript-eslint/naming-convention
28
+ promotion_id: MixedIdType;
29
+
30
+ @property({
31
+ type: 'string',
32
+ default: 'HalfPrice',
33
+ required: true,
34
+ })
35
+ promotiontype: string;
36
+
37
+ @property({
38
+ type: 'string',
39
+ })
40
+ description?: string;
41
+ }
42
+
43
+ export interface CustomerPromotionLinkRelations {}
44
+
45
+ export type CustomerPromotionLinkWithRelations = CustomerPromotionLink &
46
+ CustomerPromotionLinkRelations;
47
+
48
+ export interface CustomerPromotionLinkRepository
49
+ extends EntityCrudRepository<
50
+ CustomerPromotionLink,
51
+ typeof CustomerPromotionLink.prototype.id
52
+ > {}