@terreno/api 0.0.11-beta.1 → 0.0.12
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/biome.jsonc +1 -1
- package/dist/api.arrayOperations.test.d.ts +1 -0
- package/dist/api.arrayOperations.test.js +868 -0
- package/dist/api.errors.test.d.ts +1 -0
- package/dist/api.errors.test.js +175 -0
- package/dist/api.hooks.test.d.ts +1 -0
- package/dist/api.hooks.test.js +891 -0
- package/dist/api.query.test.d.ts +1 -0
- package/dist/api.query.test.js +805 -0
- package/dist/api.test.js +310 -3182
- package/dist/auth.test.js +135 -0
- package/dist/expressServer.test.d.ts +1 -0
- package/dist/expressServer.test.js +669 -0
- package/dist/notifiers/slackNotifier.d.ts +2 -1
- package/dist/notifiers/slackNotifier.js +20 -13
- package/dist/permissions.test.js +57 -0
- package/dist/populate.test.js +52 -0
- package/dist/tests.d.ts +9 -27
- package/dist/utils.test.js +66 -0
- package/package.json +2 -2
- package/src/api.arrayOperations.test.ts +690 -0
- package/src/api.errors.test.ts +156 -0
- package/src/api.hooks.test.ts +704 -0
- package/src/api.query.test.ts +538 -0
- package/src/api.test.ts +273 -2658
- package/src/auth.test.ts +72 -0
- package/src/expressServer.test.ts +579 -0
- package/src/notifiers/slackNotifier.ts +28 -17
- package/src/permissions.test.ts +70 -1
- package/src/populate.test.ts +58 -0
- package/src/utils.test.ts +26 -1
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
39
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
40
|
+
if (!m) return o;
|
|
41
|
+
var i = m.call(o), r, ar = [], e;
|
|
42
|
+
try {
|
|
43
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
44
|
+
}
|
|
45
|
+
catch (error) { e = { error: error }; }
|
|
46
|
+
finally {
|
|
47
|
+
try {
|
|
48
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
49
|
+
}
|
|
50
|
+
finally { if (e) throw e.error; }
|
|
51
|
+
}
|
|
52
|
+
return ar;
|
|
53
|
+
};
|
|
54
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
55
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
56
|
+
};
|
|
57
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
+
var bun_test_1 = require("bun:test");
|
|
59
|
+
var supertest_1 = __importDefault(require("supertest"));
|
|
60
|
+
var api_1 = require("./api");
|
|
61
|
+
var auth_1 = require("./auth");
|
|
62
|
+
var permissions_1 = require("./permissions");
|
|
63
|
+
var tests_1 = require("./tests");
|
|
64
|
+
var transformers_1 = require("./transformers");
|
|
65
|
+
(0, bun_test_1.describe)("model array operations", function () {
|
|
66
|
+
var _server;
|
|
67
|
+
var app;
|
|
68
|
+
var admin;
|
|
69
|
+
var spinach;
|
|
70
|
+
var apple;
|
|
71
|
+
var agent;
|
|
72
|
+
(0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
73
|
+
var _a, _b;
|
|
74
|
+
return __generator(this, function (_c) {
|
|
75
|
+
switch (_c.label) {
|
|
76
|
+
case 0:
|
|
77
|
+
process.env.REFRESH_TOKEN_SECRET = "testsecret1234";
|
|
78
|
+
return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
79
|
+
case 1:
|
|
80
|
+
_a = __read.apply(void 0, [_c.sent(), 1]), admin = _a[0];
|
|
81
|
+
return [4 /*yield*/, Promise.all([
|
|
82
|
+
tests_1.FoodModel.create({
|
|
83
|
+
calories: 1,
|
|
84
|
+
created: new Date("2021-12-03T00:00:20.000Z"),
|
|
85
|
+
hidden: false,
|
|
86
|
+
name: "Spinach",
|
|
87
|
+
ownerId: admin._id,
|
|
88
|
+
source: {
|
|
89
|
+
name: "Brand",
|
|
90
|
+
},
|
|
91
|
+
}),
|
|
92
|
+
tests_1.FoodModel.create({
|
|
93
|
+
calories: 100,
|
|
94
|
+
categories: [
|
|
95
|
+
{
|
|
96
|
+
name: "Fruit",
|
|
97
|
+
show: true,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "Popular",
|
|
101
|
+
show: false,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
created: new Date("2021-12-03T00:00:30.000Z"),
|
|
105
|
+
hidden: false,
|
|
106
|
+
name: "Apple",
|
|
107
|
+
ownerId: admin._id,
|
|
108
|
+
tags: ["healthy", "cheap"],
|
|
109
|
+
}),
|
|
110
|
+
])];
|
|
111
|
+
case 2:
|
|
112
|
+
_b = __read.apply(void 0, [_c.sent(), 2]), spinach = _b[0], apple = _b[1];
|
|
113
|
+
app = (0, tests_1.getBaseServer)();
|
|
114
|
+
(0, auth_1.setupAuth)(app, tests_1.UserModel);
|
|
115
|
+
(0, auth_1.addAuthRoutes)(app, tests_1.UserModel);
|
|
116
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
117
|
+
allowAnonymous: true,
|
|
118
|
+
permissions: {
|
|
119
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
120
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
121
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
122
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
123
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
124
|
+
},
|
|
125
|
+
queryFields: ["hidden", "calories", "created", "source.name"],
|
|
126
|
+
sort: { created: "descending" },
|
|
127
|
+
}));
|
|
128
|
+
_server = (0, supertest_1.default)(app);
|
|
129
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
130
|
+
case 3:
|
|
131
|
+
agent = _c.sent();
|
|
132
|
+
return [2 /*return*/];
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}); });
|
|
136
|
+
(0, bun_test_1.it)("add array sub-schema item", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
137
|
+
var res;
|
|
138
|
+
return __generator(this, function (_a) {
|
|
139
|
+
switch (_a.label) {
|
|
140
|
+
case 0: return [4 /*yield*/, agent
|
|
141
|
+
.post("/food/".concat(apple._id, "/categories"))
|
|
142
|
+
.send({ name: "Good Seller", show: false })
|
|
143
|
+
.expect(400)];
|
|
144
|
+
case 1:
|
|
145
|
+
res = _a.sent();
|
|
146
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Malformed body, array operations should have a single, top level key, got: name,show");
|
|
147
|
+
return [4 /*yield*/, agent
|
|
148
|
+
.post("/food/".concat(apple._id, "/categories"))
|
|
149
|
+
.send({ categories: { name: "Good Seller", show: false } })
|
|
150
|
+
.expect(200)];
|
|
151
|
+
case 2:
|
|
152
|
+
res = _a.sent();
|
|
153
|
+
(0, bun_test_1.expect)(res.body.data.categories).toHaveLength(3);
|
|
154
|
+
(0, bun_test_1.expect)(res.body.data.categories[2].name).toBe("Good Seller");
|
|
155
|
+
return [4 /*yield*/, agent
|
|
156
|
+
.post("/food/".concat(spinach._id, "/categories"))
|
|
157
|
+
.send({ categories: { name: "Good Seller", show: false } })
|
|
158
|
+
.expect(200)];
|
|
159
|
+
case 3:
|
|
160
|
+
res = _a.sent();
|
|
161
|
+
(0, bun_test_1.expect)(res.body.data.categories).toHaveLength(1);
|
|
162
|
+
return [2 /*return*/];
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}); });
|
|
166
|
+
(0, bun_test_1.it)("update array sub-schema item", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
167
|
+
var res;
|
|
168
|
+
return __generator(this, function (_a) {
|
|
169
|
+
switch (_a.label) {
|
|
170
|
+
case 0: return [4 /*yield*/, agent
|
|
171
|
+
.patch("/food/".concat(apple._id, "/categories/xyz"))
|
|
172
|
+
.send({ categories: { name: "Good Seller", show: false } })
|
|
173
|
+
.expect(404)];
|
|
174
|
+
case 1:
|
|
175
|
+
res = _a.sent();
|
|
176
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Could not find categories/xyz");
|
|
177
|
+
return [4 /*yield*/, agent
|
|
178
|
+
.patch("/food/".concat(apple._id, "/categories/").concat(apple.categories[1]._id))
|
|
179
|
+
.send({ categories: { name: "Good Seller", show: false } })
|
|
180
|
+
.expect(200)];
|
|
181
|
+
case 2:
|
|
182
|
+
res = _a.sent();
|
|
183
|
+
(0, bun_test_1.expect)(res.body.data.categories).toHaveLength(2);
|
|
184
|
+
(0, bun_test_1.expect)(res.body.data.categories[1].name).toBe("Good Seller");
|
|
185
|
+
return [2 /*return*/];
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}); });
|
|
189
|
+
(0, bun_test_1.it)("delete array sub-schema item", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
190
|
+
var res;
|
|
191
|
+
return __generator(this, function (_a) {
|
|
192
|
+
switch (_a.label) {
|
|
193
|
+
case 0: return [4 /*yield*/, agent.delete("/food/".concat(apple._id, "/categories/xyz")).expect(404)];
|
|
194
|
+
case 1:
|
|
195
|
+
res = _a.sent();
|
|
196
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Could not find categories/xyz");
|
|
197
|
+
return [4 /*yield*/, agent
|
|
198
|
+
.delete("/food/".concat(apple._id, "/categories/").concat(apple.categories[0]._id))
|
|
199
|
+
.expect(200)];
|
|
200
|
+
case 2:
|
|
201
|
+
res = _a.sent();
|
|
202
|
+
(0, bun_test_1.expect)(res.body.data.categories).toHaveLength(1);
|
|
203
|
+
(0, bun_test_1.expect)(res.body.data.categories[0].name).toBe("Popular");
|
|
204
|
+
return [2 /*return*/];
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}); });
|
|
208
|
+
(0, bun_test_1.it)("add array item", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
209
|
+
var res;
|
|
210
|
+
return __generator(this, function (_a) {
|
|
211
|
+
switch (_a.label) {
|
|
212
|
+
case 0: return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "popular" }).expect(200)];
|
|
213
|
+
case 1:
|
|
214
|
+
res = _a.sent();
|
|
215
|
+
(0, bun_test_1.expect)(res.body.data.tags).toHaveLength(3);
|
|
216
|
+
(0, bun_test_1.expect)(res.body.data.tags).toEqual(["healthy", "cheap", "popular"]);
|
|
217
|
+
return [4 /*yield*/, agent.post("/food/".concat(spinach._id, "/tags")).send({ tags: "popular" }).expect(200)];
|
|
218
|
+
case 2:
|
|
219
|
+
res = _a.sent();
|
|
220
|
+
(0, bun_test_1.expect)(res.body.data.tags).toEqual(["popular"]);
|
|
221
|
+
return [2 /*return*/];
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}); });
|
|
225
|
+
(0, bun_test_1.it)("update array item", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
226
|
+
var res;
|
|
227
|
+
return __generator(this, function (_a) {
|
|
228
|
+
switch (_a.label) {
|
|
229
|
+
case 0: return [4 /*yield*/, agent
|
|
230
|
+
.patch("/food/".concat(apple._id, "/tags/xyz"))
|
|
231
|
+
.send({ tags: "unhealthy" })
|
|
232
|
+
.expect(404)];
|
|
233
|
+
case 1:
|
|
234
|
+
res = _a.sent();
|
|
235
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Could not find tags/xyz");
|
|
236
|
+
return [4 /*yield*/, agent
|
|
237
|
+
.patch("/food/".concat(apple._id, "/tags/healthy"))
|
|
238
|
+
.send({ tags: "unhealthy" })
|
|
239
|
+
.expect(200)];
|
|
240
|
+
case 2:
|
|
241
|
+
res = _a.sent();
|
|
242
|
+
(0, bun_test_1.expect)(res.body.data.tags).toEqual(["unhealthy", "cheap"]);
|
|
243
|
+
return [2 /*return*/];
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}); });
|
|
247
|
+
(0, bun_test_1.it)("delete array item", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
248
|
+
var res;
|
|
249
|
+
return __generator(this, function (_a) {
|
|
250
|
+
switch (_a.label) {
|
|
251
|
+
case 0: return [4 /*yield*/, agent.delete("/food/".concat(apple._id, "/tags/xyz")).expect(404)];
|
|
252
|
+
case 1:
|
|
253
|
+
res = _a.sent();
|
|
254
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Could not find tags/xyz");
|
|
255
|
+
return [4 /*yield*/, agent.delete("/food/".concat(apple._id, "/tags/healthy")).expect(200)];
|
|
256
|
+
case 2:
|
|
257
|
+
res = _a.sent();
|
|
258
|
+
(0, bun_test_1.expect)(res.body.data.tags).toEqual(["cheap"]);
|
|
259
|
+
return [2 /*return*/];
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}); });
|
|
263
|
+
(0, bun_test_1.it)("updates timestamps on array subdocuments", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
264
|
+
var foodWithTimestamps, firstCategoryId, secondCategoryId, res, updatedCategory, unchangedCategory;
|
|
265
|
+
var _a, _b, _c, _d, _e, _f;
|
|
266
|
+
return __generator(this, function (_g) {
|
|
267
|
+
switch (_g.label) {
|
|
268
|
+
case 0: return [4 /*yield*/, tests_1.FoodModel.create({
|
|
269
|
+
calories: 100,
|
|
270
|
+
categories: [
|
|
271
|
+
{
|
|
272
|
+
name: "Category 1",
|
|
273
|
+
show: true,
|
|
274
|
+
updated: new Date("2024-01-01T00:00:00.000Z"),
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
name: "Category 2",
|
|
278
|
+
show: true,
|
|
279
|
+
updated: new Date("2024-01-01T00:00:00.000Z"),
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
created: new Date(),
|
|
283
|
+
name: "Food with Timestamps",
|
|
284
|
+
ownerId: admin._id,
|
|
285
|
+
})];
|
|
286
|
+
case 1:
|
|
287
|
+
foodWithTimestamps = _g.sent();
|
|
288
|
+
firstCategoryId = (_c = (_b = (_a = foodWithTimestamps.categories) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b._id) === null || _c === void 0 ? void 0 : _c.toString();
|
|
289
|
+
secondCategoryId = (_f = (_e = (_d = foodWithTimestamps.categories) === null || _d === void 0 ? void 0 : _d[1]) === null || _e === void 0 ? void 0 : _e._id) === null || _f === void 0 ? void 0 : _f.toString();
|
|
290
|
+
if (!firstCategoryId || !secondCategoryId) {
|
|
291
|
+
throw new Error("Failed to create food with categories");
|
|
292
|
+
}
|
|
293
|
+
// Wait a moment to ensure timestamp difference
|
|
294
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 100); })];
|
|
295
|
+
case 2:
|
|
296
|
+
// Wait a moment to ensure timestamp difference
|
|
297
|
+
_g.sent();
|
|
298
|
+
return [4 /*yield*/, agent
|
|
299
|
+
.patch("/food/".concat(foodWithTimestamps._id, "/categories/").concat(firstCategoryId))
|
|
300
|
+
.send({ categories: { name: "Updated Category" } })
|
|
301
|
+
.expect(200)];
|
|
302
|
+
case 3:
|
|
303
|
+
res = _g.sent();
|
|
304
|
+
updatedCategory = res.body.data.categories.find(function (c) { return c._id === firstCategoryId; });
|
|
305
|
+
unchangedCategory = res.body.data.categories.find(function (c) { return c._id === secondCategoryId; });
|
|
306
|
+
if (!updatedCategory || !unchangedCategory) {
|
|
307
|
+
throw new Error("Failed to find categories in response");
|
|
308
|
+
}
|
|
309
|
+
(0, bun_test_1.expect)(updatedCategory.updated).not.toBe(updatedCategory.created);
|
|
310
|
+
(0, bun_test_1.expect)(unchangedCategory.updated).toBe(unchangedCategory.created);
|
|
311
|
+
(0, bun_test_1.expect)(updatedCategory.name).toBe("Updated Category");
|
|
312
|
+
// Unchanged.
|
|
313
|
+
(0, bun_test_1.expect)(updatedCategory.show).toBe(true);
|
|
314
|
+
(0, bun_test_1.expect)(unchangedCategory.show).toBe(true);
|
|
315
|
+
return [2 /*return*/];
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}); });
|
|
319
|
+
(0, bun_test_1.it)("array operations call postUpdate with different copy of document", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
320
|
+
var postUpdateDoc, postUpdatePrevDoc, postUpdateCalled, categoryId, updatedCategory, prevCategory, remainingCategories, prevCategories;
|
|
321
|
+
return __generator(this, function (_a) {
|
|
322
|
+
switch (_a.label) {
|
|
323
|
+
case 0:
|
|
324
|
+
postUpdateCalled = false;
|
|
325
|
+
app = (0, tests_1.getBaseServer)();
|
|
326
|
+
(0, auth_1.setupAuth)(app, tests_1.UserModel);
|
|
327
|
+
(0, auth_1.addAuthRoutes)(app, tests_1.UserModel);
|
|
328
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
329
|
+
allowAnonymous: true,
|
|
330
|
+
permissions: {
|
|
331
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
332
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
333
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
334
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
335
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
336
|
+
},
|
|
337
|
+
postUpdate: function (doc, _cleanedBody, _request, prevValue) { return __awaiter(void 0, void 0, void 0, function () {
|
|
338
|
+
return __generator(this, function (_a) {
|
|
339
|
+
postUpdateDoc = doc;
|
|
340
|
+
postUpdatePrevDoc = prevValue;
|
|
341
|
+
postUpdateCalled = true;
|
|
342
|
+
return [2 /*return*/];
|
|
343
|
+
});
|
|
344
|
+
}); },
|
|
345
|
+
}));
|
|
346
|
+
_server = (0, supertest_1.default)(app);
|
|
347
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
348
|
+
case 1:
|
|
349
|
+
agent = _a.sent();
|
|
350
|
+
// Test POST operation (add to array)
|
|
351
|
+
return [4 /*yield*/, agent
|
|
352
|
+
.post("/food/".concat(apple._id, "/categories"))
|
|
353
|
+
.send({ categories: { name: "New Category", show: true } })
|
|
354
|
+
.expect(200)];
|
|
355
|
+
case 2:
|
|
356
|
+
// Test POST operation (add to array)
|
|
357
|
+
_a.sent();
|
|
358
|
+
(0, bun_test_1.expect)(postUpdateCalled).toBe(true);
|
|
359
|
+
(0, bun_test_1.expect)(postUpdateDoc).toBeDefined();
|
|
360
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc).toBeDefined();
|
|
361
|
+
// Verify they are different object references
|
|
362
|
+
(0, bun_test_1.expect)(postUpdateDoc).not.toBe(postUpdatePrevDoc);
|
|
363
|
+
// Verify the content is different (new category added)
|
|
364
|
+
(0, bun_test_1.expect)(postUpdateDoc.categories).toHaveLength(3);
|
|
365
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc.categories).toHaveLength(2);
|
|
366
|
+
// Reset for next test
|
|
367
|
+
postUpdateCalled = false;
|
|
368
|
+
postUpdateDoc = undefined;
|
|
369
|
+
postUpdatePrevDoc = undefined;
|
|
370
|
+
categoryId = apple.categories[0]._id;
|
|
371
|
+
if (!categoryId) {
|
|
372
|
+
throw new Error("Category ID is undefined");
|
|
373
|
+
}
|
|
374
|
+
return [4 /*yield*/, agent
|
|
375
|
+
.patch("/food/".concat(apple._id, "/categories/").concat(categoryId))
|
|
376
|
+
.send({ categories: { name: "Updated Category", show: false } })
|
|
377
|
+
.expect(200)];
|
|
378
|
+
case 3:
|
|
379
|
+
_a.sent();
|
|
380
|
+
(0, bun_test_1.expect)(postUpdateCalled).toBe(true);
|
|
381
|
+
(0, bun_test_1.expect)(postUpdateDoc).toBeDefined();
|
|
382
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc).toBeDefined();
|
|
383
|
+
// Verify they are different object references
|
|
384
|
+
(0, bun_test_1.expect)(postUpdateDoc).not.toBe(postUpdatePrevDoc);
|
|
385
|
+
updatedCategory = postUpdateDoc.categories.find(function (c) { return c._id.toString() === categoryId.toString(); });
|
|
386
|
+
prevCategory = postUpdatePrevDoc.categories.find(function (c) { return c._id.toString() === categoryId.toString(); });
|
|
387
|
+
(0, bun_test_1.expect)(updatedCategory.name).toBe("Updated Category");
|
|
388
|
+
(0, bun_test_1.expect)(prevCategory.name).toBe("Fruit");
|
|
389
|
+
// Reset for next test
|
|
390
|
+
postUpdateCalled = false;
|
|
391
|
+
postUpdateDoc = undefined;
|
|
392
|
+
postUpdatePrevDoc = undefined;
|
|
393
|
+
// Test DELETE operation (remove from array)
|
|
394
|
+
return [4 /*yield*/, agent.delete("/food/".concat(apple._id, "/categories/").concat(categoryId)).expect(200)];
|
|
395
|
+
case 4:
|
|
396
|
+
// Test DELETE operation (remove from array)
|
|
397
|
+
_a.sent();
|
|
398
|
+
(0, bun_test_1.expect)(postUpdateCalled).toBe(true);
|
|
399
|
+
(0, bun_test_1.expect)(postUpdateDoc).toBeDefined();
|
|
400
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc).toBeDefined();
|
|
401
|
+
// Verify they are different object references
|
|
402
|
+
(0, bun_test_1.expect)(postUpdateDoc).not.toBe(postUpdatePrevDoc);
|
|
403
|
+
remainingCategories = postUpdateDoc.categories.filter(function (c) { return c._id.toString() === categoryId.toString(); });
|
|
404
|
+
prevCategories = postUpdatePrevDoc.categories.filter(function (c) { return c._id.toString() === categoryId.toString(); });
|
|
405
|
+
(0, bun_test_1.expect)(remainingCategories).toHaveLength(0);
|
|
406
|
+
(0, bun_test_1.expect)(prevCategories).toHaveLength(1);
|
|
407
|
+
return [2 /*return*/];
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
}); });
|
|
411
|
+
(0, bun_test_1.it)("array operations with string arrays call postUpdate with different copy", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
412
|
+
var postUpdateDoc, postUpdatePrevDoc, postUpdateCalled;
|
|
413
|
+
return __generator(this, function (_a) {
|
|
414
|
+
switch (_a.label) {
|
|
415
|
+
case 0:
|
|
416
|
+
postUpdateCalled = false;
|
|
417
|
+
app = (0, tests_1.getBaseServer)();
|
|
418
|
+
(0, auth_1.setupAuth)(app, tests_1.UserModel);
|
|
419
|
+
(0, auth_1.addAuthRoutes)(app, tests_1.UserModel);
|
|
420
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
421
|
+
allowAnonymous: true,
|
|
422
|
+
permissions: {
|
|
423
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
424
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
425
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
426
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
427
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
428
|
+
},
|
|
429
|
+
postUpdate: function (doc, _cleanedBody, _request, prevValue) { return __awaiter(void 0, void 0, void 0, function () {
|
|
430
|
+
return __generator(this, function (_a) {
|
|
431
|
+
postUpdateDoc = doc;
|
|
432
|
+
postUpdatePrevDoc = prevValue;
|
|
433
|
+
postUpdateCalled = true;
|
|
434
|
+
return [2 /*return*/];
|
|
435
|
+
});
|
|
436
|
+
}); },
|
|
437
|
+
}));
|
|
438
|
+
_server = (0, supertest_1.default)(app);
|
|
439
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
440
|
+
case 1:
|
|
441
|
+
agent = _a.sent();
|
|
442
|
+
// Test POST operation with string array (add tag)
|
|
443
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(200)];
|
|
444
|
+
case 2:
|
|
445
|
+
// Test POST operation with string array (add tag)
|
|
446
|
+
_a.sent();
|
|
447
|
+
(0, bun_test_1.expect)(postUpdateCalled).toBe(true);
|
|
448
|
+
(0, bun_test_1.expect)(postUpdateDoc).toBeDefined();
|
|
449
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc).toBeDefined();
|
|
450
|
+
// Verify they are different object references
|
|
451
|
+
(0, bun_test_1.expect)(postUpdateDoc).not.toBe(postUpdatePrevDoc);
|
|
452
|
+
// Verify the content is different (new tag added)
|
|
453
|
+
(0, bun_test_1.expect)(postUpdateDoc.tags).toHaveLength(3);
|
|
454
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc.tags).toHaveLength(2);
|
|
455
|
+
(0, bun_test_1.expect)(postUpdateDoc.tags).toContain("organic");
|
|
456
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc.tags).not.toContain("organic");
|
|
457
|
+
// Reset for next test
|
|
458
|
+
postUpdateCalled = false;
|
|
459
|
+
postUpdateDoc = undefined;
|
|
460
|
+
postUpdatePrevDoc = undefined;
|
|
461
|
+
// Test PATCH operation with string array (update tag)
|
|
462
|
+
return [4 /*yield*/, agent.patch("/food/".concat(apple._id, "/tags/healthy")).send({ tags: "super-healthy" }).expect(200)];
|
|
463
|
+
case 3:
|
|
464
|
+
// Test PATCH operation with string array (update tag)
|
|
465
|
+
_a.sent();
|
|
466
|
+
(0, bun_test_1.expect)(postUpdateCalled).toBe(true);
|
|
467
|
+
(0, bun_test_1.expect)(postUpdateDoc).not.toBe(postUpdatePrevDoc);
|
|
468
|
+
// Verify the content is different (tag updated)
|
|
469
|
+
(0, bun_test_1.expect)(postUpdateDoc.tags).toContain("super-healthy");
|
|
470
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc.tags).toContain("healthy");
|
|
471
|
+
(0, bun_test_1.expect)(postUpdateDoc.tags).not.toContain("healthy");
|
|
472
|
+
(0, bun_test_1.expect)(postUpdatePrevDoc.tags).not.toContain("super-healthy");
|
|
473
|
+
return [2 /*return*/];
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
}); });
|
|
477
|
+
});
|
|
478
|
+
(0, bun_test_1.describe)("array operation errors", function () {
|
|
479
|
+
var _server;
|
|
480
|
+
var app;
|
|
481
|
+
var admin;
|
|
482
|
+
var apple;
|
|
483
|
+
var agent;
|
|
484
|
+
(0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
485
|
+
var _a;
|
|
486
|
+
return __generator(this, function (_b) {
|
|
487
|
+
switch (_b.label) {
|
|
488
|
+
case 0: return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
489
|
+
case 1:
|
|
490
|
+
_a = __read.apply(void 0, [_b.sent(), 1]), admin = _a[0];
|
|
491
|
+
return [4 /*yield*/, tests_1.FoodModel.create({
|
|
492
|
+
calories: 100,
|
|
493
|
+
categories: [
|
|
494
|
+
{ name: "Fruit", show: true },
|
|
495
|
+
{ name: "Popular", show: false },
|
|
496
|
+
],
|
|
497
|
+
created: new Date("2021-12-03T00:00:30.000Z"),
|
|
498
|
+
hidden: false,
|
|
499
|
+
name: "Apple",
|
|
500
|
+
ownerId: admin._id,
|
|
501
|
+
tags: ["healthy", "cheap"],
|
|
502
|
+
})];
|
|
503
|
+
case 2:
|
|
504
|
+
apple = _b.sent();
|
|
505
|
+
app = (0, tests_1.getBaseServer)();
|
|
506
|
+
(0, auth_1.setupAuth)(app, tests_1.UserModel);
|
|
507
|
+
(0, auth_1.addAuthRoutes)(app, tests_1.UserModel);
|
|
508
|
+
return [2 /*return*/];
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
}); });
|
|
512
|
+
(0, bun_test_1.it)("array operation preUpdate returning undefined throws error", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
513
|
+
var res;
|
|
514
|
+
return __generator(this, function (_a) {
|
|
515
|
+
switch (_a.label) {
|
|
516
|
+
case 0:
|
|
517
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
518
|
+
allowAnonymous: true,
|
|
519
|
+
permissions: {
|
|
520
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
521
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
522
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
523
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
524
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
525
|
+
},
|
|
526
|
+
preUpdate: function () { return undefined; },
|
|
527
|
+
}));
|
|
528
|
+
_server = (0, supertest_1.default)(app);
|
|
529
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
530
|
+
case 1:
|
|
531
|
+
agent = _a.sent();
|
|
532
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(403)];
|
|
533
|
+
case 2:
|
|
534
|
+
res = _a.sent();
|
|
535
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Update not allowed");
|
|
536
|
+
(0, bun_test_1.expect)(res.body.detail).toBe("A body must be returned from preUpdate");
|
|
537
|
+
return [2 /*return*/];
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
}); });
|
|
541
|
+
(0, bun_test_1.it)("array operation preUpdate returning null throws error", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
542
|
+
var res;
|
|
543
|
+
return __generator(this, function (_a) {
|
|
544
|
+
switch (_a.label) {
|
|
545
|
+
case 0:
|
|
546
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
547
|
+
allowAnonymous: true,
|
|
548
|
+
permissions: {
|
|
549
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
550
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
551
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
552
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
553
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
554
|
+
},
|
|
555
|
+
preUpdate: function () { return null; },
|
|
556
|
+
}));
|
|
557
|
+
_server = (0, supertest_1.default)(app);
|
|
558
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
559
|
+
case 1:
|
|
560
|
+
agent = _a.sent();
|
|
561
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(403)];
|
|
562
|
+
case 2:
|
|
563
|
+
res = _a.sent();
|
|
564
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Update not allowed");
|
|
565
|
+
return [2 /*return*/];
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
}); });
|
|
569
|
+
(0, bun_test_1.it)("array operation preUpdate error is handled", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
570
|
+
var res;
|
|
571
|
+
return __generator(this, function (_a) {
|
|
572
|
+
switch (_a.label) {
|
|
573
|
+
case 0:
|
|
574
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
575
|
+
allowAnonymous: true,
|
|
576
|
+
permissions: {
|
|
577
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
578
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
579
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
580
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
581
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
582
|
+
},
|
|
583
|
+
preUpdate: function () {
|
|
584
|
+
throw new Error("preUpdate array failed");
|
|
585
|
+
},
|
|
586
|
+
}));
|
|
587
|
+
_server = (0, supertest_1.default)(app);
|
|
588
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
589
|
+
case 1:
|
|
590
|
+
agent = _a.sent();
|
|
591
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(400)];
|
|
592
|
+
case 2:
|
|
593
|
+
res = _a.sent();
|
|
594
|
+
(0, bun_test_1.expect)(res.body.title).toContain("preUpdate hook error");
|
|
595
|
+
return [2 /*return*/];
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
}); });
|
|
599
|
+
(0, bun_test_1.it)("array operation postUpdate error is handled", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
600
|
+
var res;
|
|
601
|
+
return __generator(this, function (_a) {
|
|
602
|
+
switch (_a.label) {
|
|
603
|
+
case 0:
|
|
604
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
605
|
+
allowAnonymous: true,
|
|
606
|
+
permissions: {
|
|
607
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
608
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
609
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
610
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
611
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
612
|
+
},
|
|
613
|
+
postUpdate: function () {
|
|
614
|
+
throw new Error("postUpdate array failed");
|
|
615
|
+
},
|
|
616
|
+
}));
|
|
617
|
+
_server = (0, supertest_1.default)(app);
|
|
618
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
619
|
+
case 1:
|
|
620
|
+
agent = _a.sent();
|
|
621
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(400)];
|
|
622
|
+
case 2:
|
|
623
|
+
res = _a.sent();
|
|
624
|
+
(0, bun_test_1.expect)(res.body.title).toContain("PATCH Post Update error");
|
|
625
|
+
return [2 /*return*/];
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
}); });
|
|
629
|
+
(0, bun_test_1.it)("array operation denied without update permission", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
630
|
+
var res;
|
|
631
|
+
return __generator(this, function (_a) {
|
|
632
|
+
switch (_a.label) {
|
|
633
|
+
case 0:
|
|
634
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
635
|
+
allowAnonymous: true,
|
|
636
|
+
permissions: {
|
|
637
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
638
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
639
|
+
list: [permissions_1.Permissions.IsAny],
|
|
640
|
+
read: [permissions_1.Permissions.IsAny],
|
|
641
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
642
|
+
},
|
|
643
|
+
}));
|
|
644
|
+
_server = (0, supertest_1.default)(app);
|
|
645
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "notAdmin")];
|
|
646
|
+
case 1:
|
|
647
|
+
agent = _a.sent();
|
|
648
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(405)];
|
|
649
|
+
case 2:
|
|
650
|
+
res = _a.sent();
|
|
651
|
+
(0, bun_test_1.expect)(res.body.title).toContain("Access to PATCH");
|
|
652
|
+
return [2 /*return*/];
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
}); });
|
|
656
|
+
(0, bun_test_1.it)("array operation on non-existent document returns 404", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
657
|
+
var fakeId, res;
|
|
658
|
+
return __generator(this, function (_a) {
|
|
659
|
+
switch (_a.label) {
|
|
660
|
+
case 0:
|
|
661
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
662
|
+
allowAnonymous: true,
|
|
663
|
+
permissions: {
|
|
664
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
665
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
666
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
667
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
668
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
669
|
+
},
|
|
670
|
+
}));
|
|
671
|
+
_server = (0, supertest_1.default)(app);
|
|
672
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
673
|
+
case 1:
|
|
674
|
+
agent = _a.sent();
|
|
675
|
+
fakeId = "000000000000000000000000";
|
|
676
|
+
return [4 /*yield*/, agent.post("/food/".concat(fakeId, "/tags")).send({ tags: "organic" }).expect(404)];
|
|
677
|
+
case 2:
|
|
678
|
+
res = _a.sent();
|
|
679
|
+
(0, bun_test_1.expect)(res.body.title).toContain("Could not find document to PATCH");
|
|
680
|
+
return [2 /*return*/];
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
}); });
|
|
684
|
+
(0, bun_test_1.it)("array operation denied when user cannot update specific doc", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
685
|
+
var res;
|
|
686
|
+
return __generator(this, function (_a) {
|
|
687
|
+
switch (_a.label) {
|
|
688
|
+
case 0:
|
|
689
|
+
// Create food owned by admin, then try to update as notAdmin
|
|
690
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
691
|
+
allowAnonymous: true,
|
|
692
|
+
permissions: {
|
|
693
|
+
create: [permissions_1.Permissions.IsAuthenticated],
|
|
694
|
+
delete: [permissions_1.Permissions.IsAuthenticated],
|
|
695
|
+
list: [permissions_1.Permissions.IsAuthenticated],
|
|
696
|
+
read: [permissions_1.Permissions.IsAuthenticated],
|
|
697
|
+
update: [permissions_1.Permissions.IsOwner],
|
|
698
|
+
},
|
|
699
|
+
}));
|
|
700
|
+
_server = (0, supertest_1.default)(app);
|
|
701
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "notAdmin")];
|
|
702
|
+
case 1:
|
|
703
|
+
// Login as notAdmin and try to update admin's food (apple)
|
|
704
|
+
agent = _a.sent();
|
|
705
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(403)];
|
|
706
|
+
case 2:
|
|
707
|
+
res = _a.sent();
|
|
708
|
+
(0, bun_test_1.expect)(res.body.title).toContain("Patch not allowed");
|
|
709
|
+
return [2 /*return*/];
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
}); });
|
|
713
|
+
(0, bun_test_1.it)("array operation transform error is handled", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
714
|
+
var res;
|
|
715
|
+
return __generator(this, function (_a) {
|
|
716
|
+
switch (_a.label) {
|
|
717
|
+
case 0:
|
|
718
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
719
|
+
allowAnonymous: true,
|
|
720
|
+
permissions: {
|
|
721
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
722
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
723
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
724
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
725
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
726
|
+
},
|
|
727
|
+
transformer: (0, transformers_1.AdminOwnerTransformer)({
|
|
728
|
+
adminWriteFields: ["name"],
|
|
729
|
+
}),
|
|
730
|
+
}));
|
|
731
|
+
_server = (0, supertest_1.default)(app);
|
|
732
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
733
|
+
case 1:
|
|
734
|
+
agent = _a.sent();
|
|
735
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(403)];
|
|
736
|
+
case 2:
|
|
737
|
+
res = _a.sent();
|
|
738
|
+
(0, bun_test_1.expect)(res.body.title).toContain("cannot write fields");
|
|
739
|
+
return [2 /*return*/];
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
}); });
|
|
743
|
+
});
|
|
744
|
+
(0, bun_test_1.describe)("array operation with undefined preUpdate return", function () {
|
|
745
|
+
var _server;
|
|
746
|
+
var app;
|
|
747
|
+
var admin;
|
|
748
|
+
var apple;
|
|
749
|
+
var agent;
|
|
750
|
+
(0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
751
|
+
var _a;
|
|
752
|
+
return __generator(this, function (_b) {
|
|
753
|
+
switch (_b.label) {
|
|
754
|
+
case 0: return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
755
|
+
case 1:
|
|
756
|
+
_a = __read.apply(void 0, [_b.sent(), 1]), admin = _a[0];
|
|
757
|
+
return [4 /*yield*/, tests_1.FoodModel.create({
|
|
758
|
+
calories: 100,
|
|
759
|
+
categories: [
|
|
760
|
+
{ name: "Fruit", show: true },
|
|
761
|
+
{ name: "Popular", show: false },
|
|
762
|
+
],
|
|
763
|
+
created: new Date("2021-12-03T00:00:30.000Z"),
|
|
764
|
+
hidden: false,
|
|
765
|
+
name: "Apple",
|
|
766
|
+
ownerId: admin._id,
|
|
767
|
+
tags: ["healthy", "cheap"],
|
|
768
|
+
})];
|
|
769
|
+
case 2:
|
|
770
|
+
apple = _b.sent();
|
|
771
|
+
app = (0, tests_1.getBaseServer)();
|
|
772
|
+
(0, auth_1.setupAuth)(app, tests_1.UserModel);
|
|
773
|
+
(0, auth_1.addAuthRoutes)(app, tests_1.UserModel);
|
|
774
|
+
return [2 /*return*/];
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
}); });
|
|
778
|
+
(0, bun_test_1.it)("array operation preUpdate returning undefined for array POST throws error", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
779
|
+
var res;
|
|
780
|
+
return __generator(this, function (_a) {
|
|
781
|
+
switch (_a.label) {
|
|
782
|
+
case 0:
|
|
783
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
784
|
+
allowAnonymous: true,
|
|
785
|
+
permissions: {
|
|
786
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
787
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
788
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
789
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
790
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
791
|
+
},
|
|
792
|
+
preUpdate: function () { return undefined; },
|
|
793
|
+
}));
|
|
794
|
+
_server = (0, supertest_1.default)(app);
|
|
795
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
796
|
+
case 1:
|
|
797
|
+
agent = _a.sent();
|
|
798
|
+
return [4 /*yield*/, agent.post("/food/".concat(apple._id, "/tags")).send({ tags: "organic" }).expect(403)];
|
|
799
|
+
case 2:
|
|
800
|
+
res = _a.sent();
|
|
801
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Update not allowed");
|
|
802
|
+
(0, bun_test_1.expect)(res.body.detail).toBe("A body must be returned from preUpdate");
|
|
803
|
+
return [2 /*return*/];
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
}); });
|
|
807
|
+
(0, bun_test_1.it)("array operation preUpdate returning null for array PATCH throws error", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
808
|
+
var res;
|
|
809
|
+
return __generator(this, function (_a) {
|
|
810
|
+
switch (_a.label) {
|
|
811
|
+
case 0:
|
|
812
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
813
|
+
allowAnonymous: true,
|
|
814
|
+
permissions: {
|
|
815
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
816
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
817
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
818
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
819
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
820
|
+
},
|
|
821
|
+
preUpdate: function () { return null; },
|
|
822
|
+
}));
|
|
823
|
+
_server = (0, supertest_1.default)(app);
|
|
824
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
825
|
+
case 1:
|
|
826
|
+
agent = _a.sent();
|
|
827
|
+
return [4 /*yield*/, agent
|
|
828
|
+
.patch("/food/".concat(apple._id, "/tags/healthy"))
|
|
829
|
+
.send({ tags: "unhealthy" })
|
|
830
|
+
.expect(403)];
|
|
831
|
+
case 2:
|
|
832
|
+
res = _a.sent();
|
|
833
|
+
(0, bun_test_1.expect)(res.body.title).toBe("Update not allowed");
|
|
834
|
+
return [2 /*return*/];
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
}); });
|
|
838
|
+
(0, bun_test_1.it)("array operation preUpdate error for array DELETE is handled", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
839
|
+
var res;
|
|
840
|
+
return __generator(this, function (_a) {
|
|
841
|
+
switch (_a.label) {
|
|
842
|
+
case 0:
|
|
843
|
+
app.use("/food", (0, api_1.modelRouter)(tests_1.FoodModel, {
|
|
844
|
+
allowAnonymous: true,
|
|
845
|
+
permissions: {
|
|
846
|
+
create: [permissions_1.Permissions.IsAdmin],
|
|
847
|
+
delete: [permissions_1.Permissions.IsAdmin],
|
|
848
|
+
list: [permissions_1.Permissions.IsAdmin],
|
|
849
|
+
read: [permissions_1.Permissions.IsAdmin],
|
|
850
|
+
update: [permissions_1.Permissions.IsAdmin],
|
|
851
|
+
},
|
|
852
|
+
preUpdate: function () {
|
|
853
|
+
throw new Error("preUpdate error during delete");
|
|
854
|
+
},
|
|
855
|
+
}));
|
|
856
|
+
_server = (0, supertest_1.default)(app);
|
|
857
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
858
|
+
case 1:
|
|
859
|
+
agent = _a.sent();
|
|
860
|
+
return [4 /*yield*/, agent.delete("/food/".concat(apple._id, "/tags/healthy")).expect(400)];
|
|
861
|
+
case 2:
|
|
862
|
+
res = _a.sent();
|
|
863
|
+
(0, bun_test_1.expect)(res.body.title).toContain("preUpdate hook error");
|
|
864
|
+
return [2 /*return*/];
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
}); });
|
|
868
|
+
});
|