@antelopejs/interface-data-api 0.0.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.
- package/LICENSE +190 -0
- package/README.md +45 -0
- package/dist/antelope.test.d.ts +2 -0
- package/dist/antelope.test.js +59 -0
- package/dist/antelope.test.js.map +1 -0
- package/dist/components.d.ts +72 -0
- package/dist/components.js +344 -0
- package/dist/components.js.map +1 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.js +217 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata.d.ts +290 -0
- package/dist/metadata.js +444 -0
- package/dist/metadata.js.map +1 -0
- package/dist/tests/components/access_control.test.d.ts +1 -0
- package/dist/tests/components/access_control.test.js +138 -0
- package/dist/tests/components/access_control.test.js.map +1 -0
- package/dist/tests/components/listable.test.d.ts +1 -0
- package/dist/tests/components/listable.test.js +361 -0
- package/dist/tests/components/listable.test.js.map +1 -0
- package/dist/tests/components/mandatory.test.d.ts +1 -0
- package/dist/tests/components/mandatory.test.js +193 -0
- package/dist/tests/components/mandatory.test.js.map +1 -0
- package/dist/tests/components/per_action_access.test.d.ts +1 -0
- package/dist/tests/components/per_action_access.test.js +115 -0
- package/dist/tests/components/per_action_access.test.js.map +1 -0
- package/dist/tests/components/validator.test.d.ts +1 -0
- package/dist/tests/components/validator.test.js +178 -0
- package/dist/tests/components/validator.test.js.map +1 -0
- package/dist/tests/constants.d.ts +3 -0
- package/dist/tests/constants.js +7 -0
- package/dist/tests/constants.js.map +1 -0
- package/dist/tests/index/routes.test.d.ts +1 -0
- package/dist/tests/index/routes.test.js +210 -0
- package/dist/tests/index/routes.test.js.map +1 -0
- package/dist/tests/integration.test.d.ts +1 -0
- package/dist/tests/integration.test.js +838 -0
- package/dist/tests/integration.test.js.map +1 -0
- package/dist/tests/utils.d.ts +12 -0
- package/dist/tests/utils.js +70 -0
- package/dist/tests/utils.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
+
const interface_api_1 = require("@antelopejs/interface-api");
|
|
17
|
+
const interface_data_api_1 = require("@antelopejs/interface-data-api");
|
|
18
|
+
const metadata_1 = require("@antelopejs/interface-data-api/metadata");
|
|
19
|
+
const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
|
|
20
|
+
const chai_1 = require("chai");
|
|
21
|
+
const utils_1 = require("./utils");
|
|
22
|
+
const currentTestName = node_path_1.default
|
|
23
|
+
.basename(__filename)
|
|
24
|
+
.replace(/\.test\.(ts|js)$/, "");
|
|
25
|
+
const customerTableName = `customers-${currentTestName}`;
|
|
26
|
+
const productTableName = `products-${currentTestName}`;
|
|
27
|
+
const orderTableName = `orders-${currentTestName}`;
|
|
28
|
+
const orderItemTableName = `order_items-${currentTestName}`;
|
|
29
|
+
const schemaName = "default";
|
|
30
|
+
let Customer = class Customer extends interface_database_decorators_1.Table {
|
|
31
|
+
};
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, interface_database_decorators_1.Index)(),
|
|
34
|
+
__metadata("design:type", String)
|
|
35
|
+
], Customer.prototype, "email", void 0);
|
|
36
|
+
Customer = __decorate([
|
|
37
|
+
(0, interface_database_decorators_1.RegisterTable)(customerTableName, schemaName)
|
|
38
|
+
], Customer);
|
|
39
|
+
let Product = class Product extends interface_database_decorators_1.Table {
|
|
40
|
+
};
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, interface_database_decorators_1.Index)(),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], Product.prototype, "sku", void 0);
|
|
45
|
+
Product = __decorate([
|
|
46
|
+
(0, interface_database_decorators_1.RegisterTable)(productTableName, schemaName)
|
|
47
|
+
], Product);
|
|
48
|
+
let Order = class Order extends interface_database_decorators_1.Table {
|
|
49
|
+
};
|
|
50
|
+
__decorate([
|
|
51
|
+
(0, interface_database_decorators_1.Index)(),
|
|
52
|
+
__metadata("design:type", String)
|
|
53
|
+
], Order.prototype, "orderNumber", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
(0, interface_database_decorators_1.Index)(),
|
|
56
|
+
__metadata("design:type", String)
|
|
57
|
+
], Order.prototype, "customerId", void 0);
|
|
58
|
+
Order = __decorate([
|
|
59
|
+
(0, interface_database_decorators_1.RegisterTable)(orderTableName, schemaName)
|
|
60
|
+
], Order);
|
|
61
|
+
let OrderItem = class OrderItem extends interface_database_decorators_1.Table {
|
|
62
|
+
};
|
|
63
|
+
__decorate([
|
|
64
|
+
(0, interface_database_decorators_1.Index)(),
|
|
65
|
+
__metadata("design:type", String)
|
|
66
|
+
], OrderItem.prototype, "orderId", void 0);
|
|
67
|
+
__decorate([
|
|
68
|
+
(0, interface_database_decorators_1.Index)(),
|
|
69
|
+
__metadata("design:type", String)
|
|
70
|
+
], OrderItem.prototype, "productId", void 0);
|
|
71
|
+
OrderItem = __decorate([
|
|
72
|
+
(0, interface_database_decorators_1.RegisterTable)(orderItemTableName, schemaName)
|
|
73
|
+
], OrderItem);
|
|
74
|
+
class CustomerModel extends (0, interface_database_decorators_1.BasicDataModel)(Customer, customerTableName) {
|
|
75
|
+
}
|
|
76
|
+
class ProductModel extends (0, interface_database_decorators_1.BasicDataModel)(Product, productTableName) {
|
|
77
|
+
}
|
|
78
|
+
class OrderModel extends (0, interface_database_decorators_1.BasicDataModel)(Order, orderTableName) {
|
|
79
|
+
}
|
|
80
|
+
class OrderItemModel extends (0, interface_database_decorators_1.BasicDataModel)(OrderItem, orderItemTableName) {
|
|
81
|
+
}
|
|
82
|
+
const testCustomers = [
|
|
83
|
+
{
|
|
84
|
+
firstName: "Bob",
|
|
85
|
+
lastName: "Bobberson",
|
|
86
|
+
email: "bob.bobberson@email.com",
|
|
87
|
+
phone: "+1234567890",
|
|
88
|
+
address: "123 Poutine Square",
|
|
89
|
+
city: "Quebec City",
|
|
90
|
+
postalCode: "G1K 1K1",
|
|
91
|
+
country: "Canada",
|
|
92
|
+
registrationDate: new Date("2023-01-15"),
|
|
93
|
+
isActive: true,
|
|
94
|
+
loyaltyPoints: 150,
|
|
95
|
+
preferences: ["electronics", "books"],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
firstName: "Alice",
|
|
99
|
+
lastName: "Alison",
|
|
100
|
+
email: "alice.alison@email.com",
|
|
101
|
+
phone: "+33123456789",
|
|
102
|
+
address: "456 Baguette Street",
|
|
103
|
+
city: "Lyon",
|
|
104
|
+
postalCode: "69001",
|
|
105
|
+
country: "France",
|
|
106
|
+
registrationDate: new Date("2023-03-20"),
|
|
107
|
+
isActive: true,
|
|
108
|
+
loyaltyPoints: 75,
|
|
109
|
+
preferences: ["fashion", "home"],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
firstName: "John",
|
|
113
|
+
lastName: "Doe",
|
|
114
|
+
email: "john.doe@email.com",
|
|
115
|
+
phone: "+32123456789",
|
|
116
|
+
address: "789 Fries Avenue",
|
|
117
|
+
city: "Brussels",
|
|
118
|
+
postalCode: "1000",
|
|
119
|
+
country: "Belgium",
|
|
120
|
+
registrationDate: new Date("2023-06-10"),
|
|
121
|
+
isActive: false,
|
|
122
|
+
loyaltyPoints: 0,
|
|
123
|
+
preferences: ["sports"],
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
const testProducts = [
|
|
127
|
+
{
|
|
128
|
+
sku: "LAPTOP-001",
|
|
129
|
+
name: "Gaming Laptop",
|
|
130
|
+
description: "High performance gaming laptop",
|
|
131
|
+
price: 1299.99,
|
|
132
|
+
costPrice: 899.99,
|
|
133
|
+
stockQuantity: 15,
|
|
134
|
+
category: "electronics",
|
|
135
|
+
brand: "TechCorp",
|
|
136
|
+
tags: ["gaming", "laptop", "high-performance"],
|
|
137
|
+
images: ["laptop1.jpg", "laptop2.jpg"],
|
|
138
|
+
isActive: true,
|
|
139
|
+
createdAt: new Date("2023-01-01"),
|
|
140
|
+
updatedAt: new Date("2023-12-01"),
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
sku: "PHONE-002",
|
|
144
|
+
name: "Premium Smartphone",
|
|
145
|
+
description: "Professional camera smartphone",
|
|
146
|
+
price: 899.99,
|
|
147
|
+
costPrice: 599.99,
|
|
148
|
+
stockQuantity: 25,
|
|
149
|
+
category: "electronics",
|
|
150
|
+
brand: "MobileTech",
|
|
151
|
+
tags: ["smartphone", "camera", "premium"],
|
|
152
|
+
images: ["phone1.jpg", "phone2.jpg"],
|
|
153
|
+
isActive: true,
|
|
154
|
+
createdAt: new Date("2023-02-15"),
|
|
155
|
+
updatedAt: new Date("2023-11-15"),
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
sku: "BOOK-003",
|
|
159
|
+
name: "The Soldering Bible",
|
|
160
|
+
description: "Complete guide to soldering components",
|
|
161
|
+
price: 49.99,
|
|
162
|
+
costPrice: 25.99,
|
|
163
|
+
stockQuantity: 50,
|
|
164
|
+
category: "books",
|
|
165
|
+
brand: "TechBooks",
|
|
166
|
+
tags: ["soldering", "electronics", "education"],
|
|
167
|
+
images: ["book1.jpg"],
|
|
168
|
+
isActive: true,
|
|
169
|
+
createdAt: new Date("2023-03-01"),
|
|
170
|
+
updatedAt: new Date("2023-10-01"),
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
sku: "SHIRT-004",
|
|
174
|
+
name: "Organic Cotton T-shirt",
|
|
175
|
+
description: "Comfortable organic cotton t-shirt",
|
|
176
|
+
price: 29.99,
|
|
177
|
+
costPrice: 15.99,
|
|
178
|
+
stockQuantity: 100,
|
|
179
|
+
category: "fashion",
|
|
180
|
+
brand: "EcoFashion",
|
|
181
|
+
tags: ["cotton", "organic", "comfortable"],
|
|
182
|
+
images: ["shirt1.jpg", "shirt2.jpg"],
|
|
183
|
+
isActive: true,
|
|
184
|
+
createdAt: new Date("2023-04-10"),
|
|
185
|
+
updatedAt: new Date("2023-09-10"),
|
|
186
|
+
},
|
|
187
|
+
];
|
|
188
|
+
describe("Integration tests", () => {
|
|
189
|
+
before(async () => {
|
|
190
|
+
await initializeDatabase();
|
|
191
|
+
});
|
|
192
|
+
beforeEach(async () => {
|
|
193
|
+
await cleanTables();
|
|
194
|
+
});
|
|
195
|
+
it("workflow complete of customer management", async () => await workflowCustomerManagement());
|
|
196
|
+
it("workflow complete of product management", async () => await workflowProductManagement());
|
|
197
|
+
it("workflow complete of order management", async () => await workflowOrderManagement());
|
|
198
|
+
it("stock management and automatic update", async () => await stockManagementAndAutomaticUpdate());
|
|
199
|
+
it("advanced search and filtering", async () => await advancedSearchAndFiltering());
|
|
200
|
+
it("client preferences management and recommendations", async () => await clientPreferencesManagement());
|
|
201
|
+
it("error management and complex validation", async () => await errorManagementAndComplexValidation());
|
|
202
|
+
after(async () => { });
|
|
203
|
+
});
|
|
204
|
+
let _CustomerAPI = class _CustomerAPI extends (0, interface_data_api_1.DataController)(Customer, interface_data_api_1.DefaultRoutes.All, (0, interface_api_1.Controller)("/customers")) {
|
|
205
|
+
};
|
|
206
|
+
__decorate([
|
|
207
|
+
(0, metadata_1.ModelReference)(),
|
|
208
|
+
(0, interface_database_decorators_1.Model)(CustomerModel),
|
|
209
|
+
__metadata("design:type", CustomerModel)
|
|
210
|
+
], _CustomerAPI.prototype, "customerModel", void 0);
|
|
211
|
+
__decorate([
|
|
212
|
+
(0, metadata_1.Listable)(),
|
|
213
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
214
|
+
__metadata("design:type", String)
|
|
215
|
+
], _CustomerAPI.prototype, "_id", void 0);
|
|
216
|
+
__decorate([
|
|
217
|
+
(0, metadata_1.Listable)(),
|
|
218
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
219
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
220
|
+
(0, metadata_1.Validator)((value) => typeof value === "string" && value.length >= 2),
|
|
221
|
+
__metadata("design:type", String)
|
|
222
|
+
], _CustomerAPI.prototype, "firstName", void 0);
|
|
223
|
+
__decorate([
|
|
224
|
+
(0, metadata_1.Listable)(),
|
|
225
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
226
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
227
|
+
(0, metadata_1.Validator)((value) => typeof value === "string" && value.length >= 2),
|
|
228
|
+
__metadata("design:type", String)
|
|
229
|
+
], _CustomerAPI.prototype, "lastName", void 0);
|
|
230
|
+
__decorate([
|
|
231
|
+
(0, metadata_1.Listable)(),
|
|
232
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
233
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
234
|
+
(0, metadata_1.Validator)((value) => {
|
|
235
|
+
if (typeof value !== "string")
|
|
236
|
+
return false;
|
|
237
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
238
|
+
return emailRegex.test(value);
|
|
239
|
+
}),
|
|
240
|
+
__metadata("design:type", String)
|
|
241
|
+
], _CustomerAPI.prototype, "email", void 0);
|
|
242
|
+
__decorate([
|
|
243
|
+
(0, metadata_1.Listable)(),
|
|
244
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
245
|
+
(0, metadata_1.Validator)((value) => typeof value === "string" && value.length >= 10),
|
|
246
|
+
__metadata("design:type", String)
|
|
247
|
+
], _CustomerAPI.prototype, "phone", void 0);
|
|
248
|
+
__decorate([
|
|
249
|
+
(0, metadata_1.Listable)(),
|
|
250
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
251
|
+
__metadata("design:type", String)
|
|
252
|
+
], _CustomerAPI.prototype, "address", void 0);
|
|
253
|
+
__decorate([
|
|
254
|
+
(0, metadata_1.Listable)(),
|
|
255
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
256
|
+
__metadata("design:type", String)
|
|
257
|
+
], _CustomerAPI.prototype, "city", void 0);
|
|
258
|
+
__decorate([
|
|
259
|
+
(0, metadata_1.Listable)(),
|
|
260
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
261
|
+
__metadata("design:type", String)
|
|
262
|
+
], _CustomerAPI.prototype, "postalCode", void 0);
|
|
263
|
+
__decorate([
|
|
264
|
+
(0, metadata_1.Listable)(),
|
|
265
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
266
|
+
__metadata("design:type", String)
|
|
267
|
+
], _CustomerAPI.prototype, "country", void 0);
|
|
268
|
+
__decorate([
|
|
269
|
+
(0, metadata_1.Listable)(),
|
|
270
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
271
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
272
|
+
__metadata("design:type", Date)
|
|
273
|
+
], _CustomerAPI.prototype, "registrationDate", void 0);
|
|
274
|
+
__decorate([
|
|
275
|
+
(0, metadata_1.Listable)(),
|
|
276
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
277
|
+
__metadata("design:type", Boolean)
|
|
278
|
+
], _CustomerAPI.prototype, "isActive", void 0);
|
|
279
|
+
__decorate([
|
|
280
|
+
(0, metadata_1.Listable)(),
|
|
281
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
282
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
283
|
+
__metadata("design:type", Number)
|
|
284
|
+
], _CustomerAPI.prototype, "loyaltyPoints", void 0);
|
|
285
|
+
__decorate([
|
|
286
|
+
(0, metadata_1.Listable)(),
|
|
287
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
288
|
+
__metadata("design:type", Array)
|
|
289
|
+
], _CustomerAPI.prototype, "preferences", void 0);
|
|
290
|
+
_CustomerAPI = __decorate([
|
|
291
|
+
(0, interface_data_api_1.RegisterDataController)()
|
|
292
|
+
], _CustomerAPI);
|
|
293
|
+
let _ProductAPI = class _ProductAPI extends (0, interface_data_api_1.DataController)(Product, interface_data_api_1.DefaultRoutes.All, (0, interface_api_1.Controller)("/products")) {
|
|
294
|
+
};
|
|
295
|
+
__decorate([
|
|
296
|
+
(0, metadata_1.ModelReference)(),
|
|
297
|
+
(0, interface_database_decorators_1.Model)(ProductModel),
|
|
298
|
+
__metadata("design:type", ProductModel)
|
|
299
|
+
], _ProductAPI.prototype, "productModel", void 0);
|
|
300
|
+
__decorate([
|
|
301
|
+
(0, metadata_1.Listable)(),
|
|
302
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
303
|
+
__metadata("design:type", String)
|
|
304
|
+
], _ProductAPI.prototype, "_id", void 0);
|
|
305
|
+
__decorate([
|
|
306
|
+
(0, metadata_1.Listable)(),
|
|
307
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
308
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
309
|
+
(0, metadata_1.Validator)((value) => typeof value === "string" && value.length >= 3),
|
|
310
|
+
__metadata("design:type", String)
|
|
311
|
+
], _ProductAPI.prototype, "sku", void 0);
|
|
312
|
+
__decorate([
|
|
313
|
+
(0, metadata_1.Listable)(),
|
|
314
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
315
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
316
|
+
(0, metadata_1.Validator)((value) => typeof value === "string" && value.length >= 3),
|
|
317
|
+
__metadata("design:type", String)
|
|
318
|
+
], _ProductAPI.prototype, "name", void 0);
|
|
319
|
+
__decorate([
|
|
320
|
+
(0, metadata_1.Listable)(),
|
|
321
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
322
|
+
__metadata("design:type", String)
|
|
323
|
+
], _ProductAPI.prototype, "description", void 0);
|
|
324
|
+
__decorate([
|
|
325
|
+
(0, metadata_1.Listable)(),
|
|
326
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
327
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
328
|
+
(0, metadata_1.Validator)((value) => typeof value === "number" && value >= 0),
|
|
329
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
330
|
+
__metadata("design:type", Number)
|
|
331
|
+
], _ProductAPI.prototype, "price", void 0);
|
|
332
|
+
__decorate([
|
|
333
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.WriteOnly),
|
|
334
|
+
(0, metadata_1.Validator)((value) => typeof value === "number" && value >= 0),
|
|
335
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
336
|
+
__metadata("design:type", Number)
|
|
337
|
+
], _ProductAPI.prototype, "costPrice", void 0);
|
|
338
|
+
__decorate([
|
|
339
|
+
(0, metadata_1.Listable)(),
|
|
340
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
341
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
342
|
+
(0, metadata_1.Validator)((value) => typeof value === "number" && value >= 0),
|
|
343
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
344
|
+
__metadata("design:type", Number)
|
|
345
|
+
], _ProductAPI.prototype, "stockQuantity", void 0);
|
|
346
|
+
__decorate([
|
|
347
|
+
(0, metadata_1.Listable)(),
|
|
348
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
349
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
350
|
+
__metadata("design:type", String)
|
|
351
|
+
], _ProductAPI.prototype, "category", void 0);
|
|
352
|
+
__decorate([
|
|
353
|
+
(0, metadata_1.Listable)(),
|
|
354
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
355
|
+
__metadata("design:type", String)
|
|
356
|
+
], _ProductAPI.prototype, "brand", void 0);
|
|
357
|
+
__decorate([
|
|
358
|
+
(0, metadata_1.Listable)(),
|
|
359
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
360
|
+
__metadata("design:type", Array)
|
|
361
|
+
], _ProductAPI.prototype, "tags", void 0);
|
|
362
|
+
__decorate([
|
|
363
|
+
(0, metadata_1.Listable)(),
|
|
364
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
365
|
+
__metadata("design:type", Array)
|
|
366
|
+
], _ProductAPI.prototype, "images", void 0);
|
|
367
|
+
__decorate([
|
|
368
|
+
(0, metadata_1.Listable)(),
|
|
369
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
370
|
+
__metadata("design:type", Boolean)
|
|
371
|
+
], _ProductAPI.prototype, "isActive", void 0);
|
|
372
|
+
__decorate([
|
|
373
|
+
(0, metadata_1.Listable)(),
|
|
374
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
375
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
376
|
+
__metadata("design:type", Date)
|
|
377
|
+
], _ProductAPI.prototype, "createdAt", void 0);
|
|
378
|
+
__decorate([
|
|
379
|
+
(0, metadata_1.Listable)(),
|
|
380
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
381
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
382
|
+
__metadata("design:type", Date)
|
|
383
|
+
], _ProductAPI.prototype, "updatedAt", void 0);
|
|
384
|
+
_ProductAPI = __decorate([
|
|
385
|
+
(0, interface_data_api_1.RegisterDataController)()
|
|
386
|
+
], _ProductAPI);
|
|
387
|
+
let _OrderAPI = class _OrderAPI extends (0, interface_data_api_1.DataController)(Order, interface_data_api_1.DefaultRoutes.All, (0, interface_api_1.Controller)("/orders")) {
|
|
388
|
+
};
|
|
389
|
+
__decorate([
|
|
390
|
+
(0, metadata_1.ModelReference)(),
|
|
391
|
+
(0, interface_database_decorators_1.Model)(OrderModel),
|
|
392
|
+
__metadata("design:type", OrderModel)
|
|
393
|
+
], _OrderAPI.prototype, "orderModel", void 0);
|
|
394
|
+
__decorate([
|
|
395
|
+
(0, metadata_1.Listable)(),
|
|
396
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
397
|
+
__metadata("design:type", String)
|
|
398
|
+
], _OrderAPI.prototype, "_id", void 0);
|
|
399
|
+
__decorate([
|
|
400
|
+
(0, metadata_1.Listable)(),
|
|
401
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
402
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
403
|
+
__metadata("design:type", String)
|
|
404
|
+
], _OrderAPI.prototype, "orderNumber", void 0);
|
|
405
|
+
__decorate([
|
|
406
|
+
(0, metadata_1.Listable)(),
|
|
407
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
408
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
409
|
+
__metadata("design:type", String)
|
|
410
|
+
], _OrderAPI.prototype, "customerId", void 0);
|
|
411
|
+
__decorate([
|
|
412
|
+
(0, metadata_1.Listable)(),
|
|
413
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
414
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
415
|
+
(0, metadata_1.Validator)((value) => ["pending", "processing", "shipped", "delivered", "cancelled"].includes(value)),
|
|
416
|
+
__metadata("design:type", String)
|
|
417
|
+
], _OrderAPI.prototype, "status", void 0);
|
|
418
|
+
__decorate([
|
|
419
|
+
(0, metadata_1.Listable)(),
|
|
420
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
421
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
422
|
+
__metadata("design:type", Number)
|
|
423
|
+
], _OrderAPI.prototype, "totalAmount", void 0);
|
|
424
|
+
__decorate([
|
|
425
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
426
|
+
__metadata("design:type", Number)
|
|
427
|
+
], _OrderAPI.prototype, "shippingCost", void 0);
|
|
428
|
+
__decorate([
|
|
429
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
430
|
+
__metadata("design:type", Number)
|
|
431
|
+
], _OrderAPI.prototype, "taxAmount", void 0);
|
|
432
|
+
__decorate([
|
|
433
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
434
|
+
__metadata("design:type", Number)
|
|
435
|
+
], _OrderAPI.prototype, "discountAmount", void 0);
|
|
436
|
+
__decorate([
|
|
437
|
+
(0, metadata_1.Listable)(),
|
|
438
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
439
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
440
|
+
__metadata("design:type", Number)
|
|
441
|
+
], _OrderAPI.prototype, "finalAmount", void 0);
|
|
442
|
+
__decorate([
|
|
443
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
444
|
+
__metadata("design:type", String)
|
|
445
|
+
], _OrderAPI.prototype, "shippingAddress", void 0);
|
|
446
|
+
__decorate([
|
|
447
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
448
|
+
__metadata("design:type", String)
|
|
449
|
+
], _OrderAPI.prototype, "billingAddress", void 0);
|
|
450
|
+
__decorate([
|
|
451
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
452
|
+
__metadata("design:type", String)
|
|
453
|
+
], _OrderAPI.prototype, "paymentMethod", void 0);
|
|
454
|
+
__decorate([
|
|
455
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
456
|
+
__metadata("design:type", String)
|
|
457
|
+
], _OrderAPI.prototype, "notes", void 0);
|
|
458
|
+
__decorate([
|
|
459
|
+
(0, metadata_1.Listable)(),
|
|
460
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
461
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
462
|
+
__metadata("design:type", Date)
|
|
463
|
+
], _OrderAPI.prototype, "createdAt", void 0);
|
|
464
|
+
__decorate([
|
|
465
|
+
(0, metadata_1.Listable)(),
|
|
466
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
467
|
+
(0, metadata_1.Sortable)({ noIndex: true }),
|
|
468
|
+
__metadata("design:type", Date)
|
|
469
|
+
], _OrderAPI.prototype, "updatedAt", void 0);
|
|
470
|
+
_OrderAPI = __decorate([
|
|
471
|
+
(0, interface_data_api_1.RegisterDataController)()
|
|
472
|
+
], _OrderAPI);
|
|
473
|
+
let _OrderItemAPI = class _OrderItemAPI extends (0, interface_data_api_1.DataController)(OrderItem, interface_data_api_1.DefaultRoutes.All, (0, interface_api_1.Controller)("/order-items")) {
|
|
474
|
+
};
|
|
475
|
+
__decorate([
|
|
476
|
+
(0, metadata_1.ModelReference)(),
|
|
477
|
+
(0, interface_database_decorators_1.Model)(OrderItemModel),
|
|
478
|
+
__metadata("design:type", OrderItemModel)
|
|
479
|
+
], _OrderItemAPI.prototype, "orderItemModel", void 0);
|
|
480
|
+
__decorate([
|
|
481
|
+
(0, metadata_1.Listable)(),
|
|
482
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
483
|
+
__metadata("design:type", String)
|
|
484
|
+
], _OrderItemAPI.prototype, "_id", void 0);
|
|
485
|
+
__decorate([
|
|
486
|
+
(0, metadata_1.Listable)(),
|
|
487
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
488
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
489
|
+
__metadata("design:type", String)
|
|
490
|
+
], _OrderItemAPI.prototype, "orderId", void 0);
|
|
491
|
+
__decorate([
|
|
492
|
+
(0, metadata_1.Listable)(),
|
|
493
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
494
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
495
|
+
__metadata("design:type", String)
|
|
496
|
+
], _OrderItemAPI.prototype, "productId", void 0);
|
|
497
|
+
__decorate([
|
|
498
|
+
(0, metadata_1.Listable)(),
|
|
499
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
500
|
+
(0, metadata_1.Mandatory)("new", "edit"),
|
|
501
|
+
(0, metadata_1.Validator)((value) => typeof value === "number" && value > 0),
|
|
502
|
+
__metadata("design:type", Number)
|
|
503
|
+
], _OrderItemAPI.prototype, "quantity", void 0);
|
|
504
|
+
__decorate([
|
|
505
|
+
(0, metadata_1.Listable)(),
|
|
506
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadOnly),
|
|
507
|
+
__metadata("design:type", Number)
|
|
508
|
+
], _OrderItemAPI.prototype, "unitPrice", void 0);
|
|
509
|
+
__decorate([
|
|
510
|
+
(0, metadata_1.Access)(metadata_1.AccessMode.ReadWrite),
|
|
511
|
+
__metadata("design:type", Number)
|
|
512
|
+
], _OrderItemAPI.prototype, "discount", void 0);
|
|
513
|
+
_OrderItemAPI = __decorate([
|
|
514
|
+
(0, interface_data_api_1.RegisterDataController)()
|
|
515
|
+
], _OrderItemAPI);
|
|
516
|
+
async function initializeDatabase() {
|
|
517
|
+
await (0, interface_database_decorators_1.CreateDatabaseSchemaInstance)(schemaName);
|
|
518
|
+
}
|
|
519
|
+
async function cleanTables() {
|
|
520
|
+
const db = (0, utils_1.getSchemaInstance)(schemaName);
|
|
521
|
+
await Promise.all([
|
|
522
|
+
db.table(customerTableName).delete(),
|
|
523
|
+
db.table(productTableName).delete(),
|
|
524
|
+
db.table(orderTableName).delete(),
|
|
525
|
+
db.table(orderItemTableName).delete(),
|
|
526
|
+
]);
|
|
527
|
+
}
|
|
528
|
+
async function createTestData() {
|
|
529
|
+
const db = (0, utils_1.getSchemaInstance)(schemaName);
|
|
530
|
+
const customerModel = new CustomerModel(db);
|
|
531
|
+
const productModel = new ProductModel(db);
|
|
532
|
+
const orderModel = new OrderModel(db);
|
|
533
|
+
const customerResults = await customerModel.insert(testCustomers);
|
|
534
|
+
const productResults = await productModel.insert(testProducts);
|
|
535
|
+
return {
|
|
536
|
+
customerIds: customerResults,
|
|
537
|
+
productIds: productResults,
|
|
538
|
+
customerModel,
|
|
539
|
+
productModel,
|
|
540
|
+
orderModel,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
async function workflowCustomerManagement() {
|
|
544
|
+
const { customerModel } = await createTestData();
|
|
545
|
+
const newCustomer = {
|
|
546
|
+
firstName: "Sophie",
|
|
547
|
+
lastName: "Marrone",
|
|
548
|
+
email: "sophie.marrone@email.com",
|
|
549
|
+
phone: "+393334445556",
|
|
550
|
+
address: "Via Pasta 10",
|
|
551
|
+
city: "Naples",
|
|
552
|
+
postalCode: "80100",
|
|
553
|
+
country: "Italy",
|
|
554
|
+
isActive: true,
|
|
555
|
+
loyaltyPoints: 0,
|
|
556
|
+
preferences: ["art", "music"],
|
|
557
|
+
};
|
|
558
|
+
const createResponse = await (0, utils_1.newRequest)("customers", newCustomer);
|
|
559
|
+
(0, chai_1.expect)(createResponse.status).to.equal(200);
|
|
560
|
+
const createdIds = (await createResponse.json());
|
|
561
|
+
(0, chai_1.expect)(createdIds).to.have.length(1);
|
|
562
|
+
(0, chai_1.expect)(createdIds[0]).to.be.a("string");
|
|
563
|
+
const getResponse = await (0, utils_1.getRequest)("customers", { id: createdIds[0] });
|
|
564
|
+
(0, chai_1.expect)(getResponse.status).to.equal(200);
|
|
565
|
+
const customer = (await getResponse.json());
|
|
566
|
+
await (0, utils_1.validateObject)(customer, newCustomer, [
|
|
567
|
+
"firstName",
|
|
568
|
+
"lastName",
|
|
569
|
+
"email",
|
|
570
|
+
"city",
|
|
571
|
+
]);
|
|
572
|
+
const updateData = {
|
|
573
|
+
...newCustomer,
|
|
574
|
+
loyaltyPoints: 50,
|
|
575
|
+
preferences: ["art", "music", "travel"],
|
|
576
|
+
};
|
|
577
|
+
const updateResponse = await (0, utils_1.editRequest)("customers", updateData, {
|
|
578
|
+
id: createdIds[0],
|
|
579
|
+
});
|
|
580
|
+
(0, chai_1.expect)(updateResponse.status).to.equal(200);
|
|
581
|
+
const updatedCustomer = await customerModel.get(createdIds[0]);
|
|
582
|
+
(0, chai_1.expect)(updatedCustomer?.loyaltyPoints).to.equal(50);
|
|
583
|
+
(0, chai_1.expect)(updatedCustomer?.preferences).to.include("travel");
|
|
584
|
+
const listResponse = await (0, utils_1.listRequest)("customers", {
|
|
585
|
+
sortKey: "registrationDate",
|
|
586
|
+
sortDirection: "desc",
|
|
587
|
+
limit: "2",
|
|
588
|
+
});
|
|
589
|
+
(0, chai_1.expect)(listResponse.status).to.equal(200);
|
|
590
|
+
const listData = (await listResponse.json());
|
|
591
|
+
(0, chai_1.expect)(listData.results).to.have.length(2);
|
|
592
|
+
}
|
|
593
|
+
async function workflowProductManagement() {
|
|
594
|
+
const { productModel } = await createTestData();
|
|
595
|
+
const newProduct = {
|
|
596
|
+
sku: "HEADPHONES-005",
|
|
597
|
+
name: "Casque audio sans fil",
|
|
598
|
+
description: "Casque audio haute qualité avec réduction de bruit",
|
|
599
|
+
price: 199.99,
|
|
600
|
+
costPrice: 120.0,
|
|
601
|
+
stockQuantity: 30,
|
|
602
|
+
category: "electronics",
|
|
603
|
+
brand: "AudioTech",
|
|
604
|
+
tags: ["wireless", "noise-cancelling", "premium"],
|
|
605
|
+
images: ["headphones1.jpg", "headphones2.jpg"],
|
|
606
|
+
isActive: true,
|
|
607
|
+
};
|
|
608
|
+
const createResponse = await (0, utils_1.newRequest)("products", newProduct);
|
|
609
|
+
(0, chai_1.expect)(createResponse.status).to.equal(200);
|
|
610
|
+
const createdIds = (await createResponse.json());
|
|
611
|
+
(0, chai_1.expect)(createdIds).to.have.length(1);
|
|
612
|
+
const stockUpdate = { ...newProduct, stockQuantity: 25 };
|
|
613
|
+
const updateResponse = await (0, utils_1.editRequest)("products", stockUpdate, {
|
|
614
|
+
id: createdIds[0],
|
|
615
|
+
});
|
|
616
|
+
(0, chai_1.expect)(updateResponse.status).to.equal(200);
|
|
617
|
+
const updatedProduct = await productModel.get(createdIds[0]);
|
|
618
|
+
(0, chai_1.expect)(updatedProduct?.stockQuantity).to.equal(25);
|
|
619
|
+
const listResponse = await (0, utils_1.listRequest)("products", {
|
|
620
|
+
sortKey: "price",
|
|
621
|
+
sortDirection: "asc",
|
|
622
|
+
limit: "3",
|
|
623
|
+
});
|
|
624
|
+
(0, chai_1.expect)(listResponse.status).to.equal(200);
|
|
625
|
+
const listData = (await listResponse.json());
|
|
626
|
+
(0, chai_1.expect)(listData.results).to.have.length(3);
|
|
627
|
+
const categoryResponse = await (0, utils_1.listRequest)("products", {
|
|
628
|
+
category: "electronics",
|
|
629
|
+
});
|
|
630
|
+
(0, chai_1.expect)(categoryResponse.status).to.equal(200);
|
|
631
|
+
const categoryData = (await categoryResponse.json());
|
|
632
|
+
(0, chai_1.expect)(categoryData.results.length).to.be.greaterThan(0);
|
|
633
|
+
}
|
|
634
|
+
async function workflowOrderManagement() {
|
|
635
|
+
const { customerIds, productIds, orderModel } = await createTestData();
|
|
636
|
+
const orderData = {
|
|
637
|
+
orderNumber: "ORD-2024-001",
|
|
638
|
+
customerId: customerIds[0],
|
|
639
|
+
status: "pending",
|
|
640
|
+
totalAmount: 0,
|
|
641
|
+
shippingCost: 9.99,
|
|
642
|
+
taxAmount: 0,
|
|
643
|
+
discountAmount: 0,
|
|
644
|
+
finalAmount: 0,
|
|
645
|
+
shippingAddress: "Via Pasta 10, Naples, 80100",
|
|
646
|
+
billingAddress: "Via Pasta 10, Naples, 80100",
|
|
647
|
+
paymentMethod: "credit_card",
|
|
648
|
+
notes: "Express delivery requested",
|
|
649
|
+
};
|
|
650
|
+
const orderResponse = await (0, utils_1.newRequest)("orders", orderData);
|
|
651
|
+
(0, chai_1.expect)(orderResponse.status).to.equal(200);
|
|
652
|
+
const orderIds = (await orderResponse.json());
|
|
653
|
+
(0, chai_1.expect)(orderIds).to.have.length(1);
|
|
654
|
+
const orderItem1 = {
|
|
655
|
+
orderId: orderIds[0],
|
|
656
|
+
productId: productIds[0],
|
|
657
|
+
quantity: 2,
|
|
658
|
+
unitPrice: 1299.99,
|
|
659
|
+
totalPrice: 2599.98,
|
|
660
|
+
discount: 0,
|
|
661
|
+
};
|
|
662
|
+
const orderItem2 = {
|
|
663
|
+
orderId: orderIds[0],
|
|
664
|
+
productId: productIds[1],
|
|
665
|
+
quantity: 1,
|
|
666
|
+
unitPrice: 899.99,
|
|
667
|
+
totalPrice: 899.99,
|
|
668
|
+
discount: 50.0,
|
|
669
|
+
};
|
|
670
|
+
const item1Response = await (0, utils_1.newRequest)("order-items", orderItem1);
|
|
671
|
+
const item2Response = await (0, utils_1.newRequest)("order-items", orderItem2);
|
|
672
|
+
(0, chai_1.expect)(item1Response.status).to.equal(200);
|
|
673
|
+
(0, chai_1.expect)(item2Response.status).to.equal(200);
|
|
674
|
+
const totalAmount = 2599.98 + (899.99 - 50.0);
|
|
675
|
+
const taxAmount = totalAmount * 0.2;
|
|
676
|
+
const finalAmount = totalAmount + taxAmount + 9.99;
|
|
677
|
+
const orderUpdate = {
|
|
678
|
+
...orderData,
|
|
679
|
+
totalAmount,
|
|
680
|
+
taxAmount,
|
|
681
|
+
finalAmount,
|
|
682
|
+
};
|
|
683
|
+
const updateResponse = await (0, utils_1.editRequest)("orders", orderUpdate, {
|
|
684
|
+
id: orderIds[0],
|
|
685
|
+
});
|
|
686
|
+
(0, chai_1.expect)(updateResponse.status).to.equal(200);
|
|
687
|
+
const updatedOrder = await orderModel.get(orderIds[0]);
|
|
688
|
+
(0, chai_1.expect)(updatedOrder?.totalAmount).to.equal(totalAmount);
|
|
689
|
+
(0, chai_1.expect)(updatedOrder?.finalAmount).to.equal(finalAmount);
|
|
690
|
+
const statusUpdate = { ...orderData, status: "processing" };
|
|
691
|
+
const statusResponse = await (0, utils_1.editRequest)("orders", statusUpdate, {
|
|
692
|
+
id: orderIds[0],
|
|
693
|
+
});
|
|
694
|
+
(0, chai_1.expect)(statusResponse.status).to.equal(200);
|
|
695
|
+
const finalOrder = await orderModel.get(orderIds[0]);
|
|
696
|
+
(0, chai_1.expect)(finalOrder?.status).to.equal("processing");
|
|
697
|
+
}
|
|
698
|
+
async function stockManagementAndAutomaticUpdate() {
|
|
699
|
+
const { productIds, productModel } = await createTestData();
|
|
700
|
+
const initialProduct = await productModel.get(productIds[0]);
|
|
701
|
+
const initialStock = initialProduct?.stockQuantity || 0;
|
|
702
|
+
const stockReduction = { ...initialProduct, stockQuantity: initialStock - 3 };
|
|
703
|
+
const updateResponse = await (0, utils_1.editRequest)("products", stockReduction, {
|
|
704
|
+
id: productIds[0],
|
|
705
|
+
});
|
|
706
|
+
(0, chai_1.expect)(updateResponse.status).to.equal(200);
|
|
707
|
+
const updatedProduct = await productModel.get(productIds[0]);
|
|
708
|
+
(0, chai_1.expect)(updatedProduct?.stockQuantity).to.equal(initialStock - 3);
|
|
709
|
+
const invalidStock = { stockQuantity: -5 };
|
|
710
|
+
const invalidResponse = await (0, utils_1.editRequest)("products", invalidStock, {
|
|
711
|
+
id: productIds[0],
|
|
712
|
+
});
|
|
713
|
+
(0, chai_1.expect)(invalidResponse.status).to.equal(400);
|
|
714
|
+
const restock = { ...initialProduct, stockQuantity: initialStock + 10 };
|
|
715
|
+
const restockResponse = await (0, utils_1.editRequest)("products", restock, {
|
|
716
|
+
id: productIds[0],
|
|
717
|
+
});
|
|
718
|
+
(0, chai_1.expect)(restockResponse.status).to.equal(200);
|
|
719
|
+
const restockedProduct = await productModel.get(productIds[0]);
|
|
720
|
+
(0, chai_1.expect)(restockedProduct?.stockQuantity).to.equal(initialStock + 10);
|
|
721
|
+
}
|
|
722
|
+
async function advancedSearchAndFiltering() {
|
|
723
|
+
await createTestData();
|
|
724
|
+
const categoryResponse = await (0, utils_1.listRequest)("products", {
|
|
725
|
+
category: "electronics",
|
|
726
|
+
sortKey: "price",
|
|
727
|
+
sortDirection: "desc",
|
|
728
|
+
});
|
|
729
|
+
(0, chai_1.expect)(categoryResponse.status).to.equal(200);
|
|
730
|
+
const categoryData = (await categoryResponse.json());
|
|
731
|
+
(0, chai_1.expect)(categoryData.results.length).to.be.greaterThan(0);
|
|
732
|
+
const activeCustomersResponse = await (0, utils_1.listRequest)("customers", {
|
|
733
|
+
isActive: "true",
|
|
734
|
+
sortKey: "loyaltyPoints",
|
|
735
|
+
sortDirection: "desc",
|
|
736
|
+
});
|
|
737
|
+
(0, chai_1.expect)(activeCustomersResponse.status).to.equal(200);
|
|
738
|
+
const activeCustomersData = (await activeCustomersResponse.json());
|
|
739
|
+
(0, chai_1.expect)(activeCustomersData.results.length).to.be.greaterThan(0);
|
|
740
|
+
const paginatedResponse = await (0, utils_1.listRequest)("products", {
|
|
741
|
+
limit: "2",
|
|
742
|
+
offset: "1",
|
|
743
|
+
});
|
|
744
|
+
(0, chai_1.expect)(paginatedResponse.status).to.equal(200);
|
|
745
|
+
const paginatedData = (await paginatedResponse.json());
|
|
746
|
+
(0, chai_1.expect)(paginatedData.results).to.have.length(2);
|
|
747
|
+
(0, chai_1.expect)(paginatedData.total).to.be.greaterThan(2);
|
|
748
|
+
const pendingOrdersResponse = await (0, utils_1.listRequest)("orders", {
|
|
749
|
+
status: "pending",
|
|
750
|
+
sortKey: "createdAt",
|
|
751
|
+
sortDirection: "desc",
|
|
752
|
+
});
|
|
753
|
+
(0, chai_1.expect)(pendingOrdersResponse.status).to.equal(200);
|
|
754
|
+
}
|
|
755
|
+
async function clientPreferencesManagement() {
|
|
756
|
+
const { customerIds, customerModel } = await createTestData();
|
|
757
|
+
const customer = await customerModel.get(customerIds[0]);
|
|
758
|
+
const newPreferences = ["electronics", "gaming", "tech"];
|
|
759
|
+
const preferenceUpdate = { ...customer, preferences: newPreferences };
|
|
760
|
+
const updateResponse = await (0, utils_1.editRequest)("customers", preferenceUpdate, {
|
|
761
|
+
id: customerIds[0],
|
|
762
|
+
});
|
|
763
|
+
(0, chai_1.expect)(updateResponse.status).to.equal(200);
|
|
764
|
+
const updatedCustomer = await customerModel.get(customerIds[0]);
|
|
765
|
+
(0, chai_1.expect)(updatedCustomer?.preferences).to.deep.equal(newPreferences);
|
|
766
|
+
const electronicsResponse = await (0, utils_1.listRequest)("products", {
|
|
767
|
+
category: "electronics",
|
|
768
|
+
sortKey: "price",
|
|
769
|
+
sortDirection: "asc",
|
|
770
|
+
});
|
|
771
|
+
(0, chai_1.expect)(electronicsResponse.status).to.equal(200);
|
|
772
|
+
const electronicsData = (await electronicsResponse.json());
|
|
773
|
+
(0, chai_1.expect)(electronicsData.results.length).to.be.greaterThan(0);
|
|
774
|
+
const loyaltyUpdate = { ...updatedCustomer, loyaltyPoints: 200 };
|
|
775
|
+
const loyaltyResponse = await (0, utils_1.editRequest)("customers", loyaltyUpdate, {
|
|
776
|
+
id: customerIds[0],
|
|
777
|
+
});
|
|
778
|
+
(0, chai_1.expect)(loyaltyResponse.status).to.equal(200);
|
|
779
|
+
const customerWithLoyalty = await customerModel.get(customerIds[0]);
|
|
780
|
+
(0, chai_1.expect)(customerWithLoyalty?.loyaltyPoints).to.equal(200);
|
|
781
|
+
}
|
|
782
|
+
async function errorManagementAndComplexValidation() {
|
|
783
|
+
const invalidCustomer = {
|
|
784
|
+
firstName: "Test",
|
|
785
|
+
lastName: "User",
|
|
786
|
+
email: "invalid-email",
|
|
787
|
+
phone: "123",
|
|
788
|
+
isActive: true,
|
|
789
|
+
loyaltyPoints: 0,
|
|
790
|
+
preferences: ["test"],
|
|
791
|
+
};
|
|
792
|
+
const invalidEmailResponse = await (0, utils_1.newRequest)("customers", invalidCustomer);
|
|
793
|
+
(0, chai_1.expect)(invalidEmailResponse.status).to.equal(400);
|
|
794
|
+
const emailError = await invalidEmailResponse.text();
|
|
795
|
+
(0, chai_1.expect)(emailError).to.include("email");
|
|
796
|
+
const invalidProduct = {
|
|
797
|
+
sku: "TEST-001",
|
|
798
|
+
name: "Test Product",
|
|
799
|
+
price: -50.0,
|
|
800
|
+
stockQuantity: 10,
|
|
801
|
+
category: "test",
|
|
802
|
+
isActive: true,
|
|
803
|
+
};
|
|
804
|
+
const invalidPriceResponse = await (0, utils_1.newRequest)("products", invalidProduct);
|
|
805
|
+
(0, chai_1.expect)(invalidPriceResponse.status).to.equal(400);
|
|
806
|
+
const priceError = await invalidPriceResponse.text();
|
|
807
|
+
(0, chai_1.expect)(priceError).to.include("price");
|
|
808
|
+
const invalidOrderItem = {
|
|
809
|
+
orderId: "fake-order-id",
|
|
810
|
+
productId: "fake-product-id",
|
|
811
|
+
quantity: 0,
|
|
812
|
+
unitPrice: 10.0,
|
|
813
|
+
totalPrice: 0,
|
|
814
|
+
discount: 0,
|
|
815
|
+
};
|
|
816
|
+
const invalidQuantityResponse = await (0, utils_1.newRequest)("order-items", invalidOrderItem);
|
|
817
|
+
(0, chai_1.expect)(invalidQuantityResponse.status).to.equal(400);
|
|
818
|
+
const quantityError = await invalidQuantityResponse.text();
|
|
819
|
+
(0, chai_1.expect)(quantityError).to.include("quantity");
|
|
820
|
+
const { customerIds } = await createTestData();
|
|
821
|
+
const invalidStatusUpdate = { status: "invalid_status" };
|
|
822
|
+
const invalidStatusResponse = await (0, utils_1.editRequest)("orders", invalidStatusUpdate, { id: customerIds[0] });
|
|
823
|
+
(0, chai_1.expect)(invalidStatusResponse.status).to.equal(400);
|
|
824
|
+
const invalidRouteResponse = await (0, utils_1.request)("customers", "nonexistent", "GET");
|
|
825
|
+
(0, chai_1.expect)(invalidRouteResponse.status).to.equal(404);
|
|
826
|
+
const missingFieldsCustomer = {
|
|
827
|
+
firstName: "Test",
|
|
828
|
+
email: "test@example.com",
|
|
829
|
+
isActive: true,
|
|
830
|
+
loyaltyPoints: 0,
|
|
831
|
+
preferences: ["test"],
|
|
832
|
+
};
|
|
833
|
+
const missingFieldsResponse = await (0, utils_1.newRequest)("customers", missingFieldsCustomer);
|
|
834
|
+
(0, chai_1.expect)(missingFieldsResponse.status).to.equal(400);
|
|
835
|
+
const missingFieldsError = await missingFieldsResponse.text();
|
|
836
|
+
(0, chai_1.expect)(missingFieldsError).to.include("lastName");
|
|
837
|
+
}
|
|
838
|
+
//# sourceMappingURL=integration.test.js.map
|