@formio/appserver 2.0.0-rc.8 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/actions/index.d.ts +3 -156
- package/lib/actions/login/LoginAction.d.ts +2 -109
- package/lib/actions/login/LoginAction.js +124 -213
- package/lib/actions/role/RoleAction.d.ts +2 -61
- package/lib/actions/role/RoleAction.js +13 -20
- package/lib/actions/save/SaveAction.d.ts +2 -28
- package/lib/actions/save/SaveAction.js +27 -45
- package/lib/modules/index.d.ts +1 -3
- package/lib/modules/index.js +2 -4
- package/lib/modules/mongodb/db.d.ts +31 -32
- package/lib/modules/mongodb/db.js +220 -94
- package/lib/server.d.ts +5 -171
- package/lib/server.js +59 -66
- package/package.json +19 -21
- package/lib/actions/login/LoginAction.spec.d.ts +0 -1
- package/lib/actions/login/LoginAction.spec.js +0 -15
- package/lib/actions/role/RoleAction.spec.d.ts +0 -1
- package/lib/actions/role/RoleAction.spec.js +0 -15
- package/lib/actions/save/SaveAction.spec.d.ts +0 -1
- package/lib/actions/save/SaveAction.spec.js +0 -15
- package/lib/modules/auth/auth.d.ts +0 -5
- package/lib/modules/auth/auth.js +0 -70
- package/lib/modules/auth/auth.spec.d.ts +0 -1
- package/lib/modules/auth/auth.spec.js +0 -93
- package/lib/modules/mongodb/db.spec.d.ts +0 -1
- package/lib/modules/mongodb/db.spec.js +0 -714
- package/server.js +0 -1
|
@@ -1,714 +0,0 @@
|
|
|
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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const chai_1 = require("chai");
|
|
13
|
-
const db_1 = require("./db");
|
|
14
|
-
const mongodb_memory_server_1 = require("mongodb-memory-server");
|
|
15
|
-
describe('Database', () => {
|
|
16
|
-
let mongod;
|
|
17
|
-
let database;
|
|
18
|
-
let config;
|
|
19
|
-
before(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
-
mongod = yield mongodb_memory_server_1.MongoMemoryServer.create();
|
|
21
|
-
const uri = mongod.getUri();
|
|
22
|
-
config = {
|
|
23
|
-
url: uri,
|
|
24
|
-
config: {}
|
|
25
|
-
};
|
|
26
|
-
database = new db_1.Database(config);
|
|
27
|
-
}));
|
|
28
|
-
after(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
-
// Close the database connection
|
|
30
|
-
if (database) {
|
|
31
|
-
yield database.close();
|
|
32
|
-
}
|
|
33
|
-
// Then stop the MongoDB memory server
|
|
34
|
-
if (mongod) {
|
|
35
|
-
yield mongod.stop();
|
|
36
|
-
}
|
|
37
|
-
}));
|
|
38
|
-
describe('constructor', () => {
|
|
39
|
-
it('should initialize with default values', () => {
|
|
40
|
-
const db = new db_1.Database(config);
|
|
41
|
-
(0, chai_1.expect)(db.db).to.be.null;
|
|
42
|
-
(0, chai_1.expect)(db.currentCollectionName).to.equal('submissions');
|
|
43
|
-
(0, chai_1.expect)(db.currentCollection).to.be.null;
|
|
44
|
-
(0, chai_1.expect)(db.defaultCollection).to.be.null;
|
|
45
|
-
(0, chai_1.expect)(db.prefix).to.equal('');
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
describe('ObjectId', () => {
|
|
49
|
-
it('should handle null/undefined input', () => {
|
|
50
|
-
(0, chai_1.expect)(database.ObjectId(null)).to.be.null;
|
|
51
|
-
(0, chai_1.expect)(database.ObjectId(undefined)).to.be.null;
|
|
52
|
-
});
|
|
53
|
-
it('should handle $in queries', () => {
|
|
54
|
-
const input = { $in: ['507f1f77bcf86cd799439011', '507f1f77bcf86cd799439012'] };
|
|
55
|
-
const result = database.ObjectId(input);
|
|
56
|
-
(0, chai_1.expect)(result).to.have.property('$in');
|
|
57
|
-
(0, chai_1.expect)(result.$in).to.be.an('array');
|
|
58
|
-
});
|
|
59
|
-
it('should return original value for invalid ObjectId strings', () => {
|
|
60
|
-
const invalidId = 'invalid-id';
|
|
61
|
-
const result = database.ObjectId(invalidId);
|
|
62
|
-
(0, chai_1.expect)(result).to.equal(invalidId);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
describe('collectionName', () => {
|
|
66
|
-
it('should return collection name without prefix', () => {
|
|
67
|
-
database.prefix = '';
|
|
68
|
-
(0, chai_1.expect)(database.collectionName('test')).to.equal('test');
|
|
69
|
-
});
|
|
70
|
-
it('should return collection name with prefix', () => {
|
|
71
|
-
database.prefix = 'myapp.';
|
|
72
|
-
(0, chai_1.expect)(database.collectionName('test')).to.equal('myapp.test');
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
describe('connect', () => {
|
|
76
|
-
it('should connect to database', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
-
yield database.connect();
|
|
78
|
-
(0, chai_1.expect)(database.db).to.not.be.null;
|
|
79
|
-
(0, chai_1.expect)(database.defaultCollection).to.not.be.null;
|
|
80
|
-
}));
|
|
81
|
-
it('should set prefix when provided', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
|
-
const db = new db_1.Database(config);
|
|
83
|
-
yield db.connect('testapp');
|
|
84
|
-
(0, chai_1.expect)(db.prefix).to.equal('testapp.');
|
|
85
|
-
}));
|
|
86
|
-
});
|
|
87
|
-
describe('collection', () => {
|
|
88
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
89
|
-
if (!database.db) {
|
|
90
|
-
yield database.connect();
|
|
91
|
-
}
|
|
92
|
-
}));
|
|
93
|
-
it('should return collection when db is connected', () => {
|
|
94
|
-
const collection = database.collection('test');
|
|
95
|
-
(0, chai_1.expect)(collection).to.not.be.null;
|
|
96
|
-
});
|
|
97
|
-
it('should return null when db is not connected', () => {
|
|
98
|
-
const db = new db_1.Database(config);
|
|
99
|
-
const collection = db.collection('test');
|
|
100
|
-
(0, chai_1.expect)(collection).to.be.null;
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
describe('CRUD Operations', () => {
|
|
104
|
-
let scope;
|
|
105
|
-
let testCollection;
|
|
106
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
107
|
-
if (!database.db) {
|
|
108
|
-
yield database.connect();
|
|
109
|
-
}
|
|
110
|
-
// Setup a basic scope for testing
|
|
111
|
-
scope = {
|
|
112
|
-
form: {
|
|
113
|
-
_id: '507f1f77bcf86cd799439011',
|
|
114
|
-
components: []
|
|
115
|
-
},
|
|
116
|
-
project: {
|
|
117
|
-
_id: '507f1f77bcf86cd799439012'
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
testCollection = yield database.formCollection(scope);
|
|
121
|
-
}));
|
|
122
|
-
afterEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
123
|
-
// Clean up test data after each test
|
|
124
|
-
if (testCollection) {
|
|
125
|
-
yield testCollection.deleteMany({});
|
|
126
|
-
}
|
|
127
|
-
}));
|
|
128
|
-
describe('create', () => {
|
|
129
|
-
it('should create a new record with basic data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
130
|
-
const recordData = {
|
|
131
|
-
data: { name: 'Test User', email: 'test@example.com' },
|
|
132
|
-
metadata: { source: 'test' }
|
|
133
|
-
};
|
|
134
|
-
const result = yield database.create(scope, recordData);
|
|
135
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
136
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result._id).to.exist;
|
|
137
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.data.name).to.equal('Test User');
|
|
138
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.data.email).to.equal('test@example.com');
|
|
139
|
-
// Verify using raw MongoDB find
|
|
140
|
-
const rawRecord = yield testCollection.findOne({ _id: result === null || result === void 0 ? void 0 : result._id });
|
|
141
|
-
(0, chai_1.expect)(rawRecord).to.not.be.null;
|
|
142
|
-
(0, chai_1.expect)(rawRecord.data.name).to.equal('Test User');
|
|
143
|
-
(0, chai_1.expect)(rawRecord.data.email).to.equal('test@example.com');
|
|
144
|
-
(0, chai_1.expect)(rawRecord.metadata.source).to.equal('test');
|
|
145
|
-
}));
|
|
146
|
-
it('should set timestamps and system fields', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
147
|
-
const beforeCreate = new Date();
|
|
148
|
-
const recordData = {
|
|
149
|
-
data: { content: 'Test content' }
|
|
150
|
-
};
|
|
151
|
-
const result = yield database.create(scope, recordData);
|
|
152
|
-
const afterCreate = new Date();
|
|
153
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
154
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.created).to.be.a('date');
|
|
155
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.modified).to.be.a('date');
|
|
156
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.deleted).to.be.null;
|
|
157
|
-
// Verify using raw MongoDB find
|
|
158
|
-
const rawRecord = yield testCollection.findOne({ _id: result === null || result === void 0 ? void 0 : result._id });
|
|
159
|
-
(0, chai_1.expect)(rawRecord.created.getTime()).to.be.at.least(beforeCreate.getTime());
|
|
160
|
-
(0, chai_1.expect)(rawRecord.created.getTime()).to.be.at.most(afterCreate.getTime());
|
|
161
|
-
(0, chai_1.expect)(rawRecord.form.toString()).to.equal(scope.form._id);
|
|
162
|
-
(0, chai_1.expect)(rawRecord.project.toString()).to.equal(scope.project._id);
|
|
163
|
-
(0, chai_1.expect)(rawRecord.deleted).to.be.null;
|
|
164
|
-
}));
|
|
165
|
-
it('should create multiple records', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
166
|
-
const records = [
|
|
167
|
-
{ data: { name: 'User 1', type: 'first' } },
|
|
168
|
-
{ data: { name: 'User 2', type: 'second' } },
|
|
169
|
-
{ data: { name: 'User 3', type: 'third' } }
|
|
170
|
-
];
|
|
171
|
-
const results = [];
|
|
172
|
-
for (const recordData of records) {
|
|
173
|
-
const result = yield database.create(scope, recordData);
|
|
174
|
-
results.push(result);
|
|
175
|
-
}
|
|
176
|
-
(0, chai_1.expect)(results).to.have.length(3);
|
|
177
|
-
// Verify all records exist using raw MongoDB find
|
|
178
|
-
const allRecords = yield testCollection.find({}).toArray();
|
|
179
|
-
(0, chai_1.expect)(allRecords).to.have.length(3);
|
|
180
|
-
const names = allRecords.map((record) => record.data.name).sort();
|
|
181
|
-
(0, chai_1.expect)(names).to.deep.equal(['User 1', 'User 2', 'User 3']);
|
|
182
|
-
}));
|
|
183
|
-
});
|
|
184
|
-
describe('read', () => {
|
|
185
|
-
let createdRecords;
|
|
186
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
187
|
-
// Create test data
|
|
188
|
-
const testData = [
|
|
189
|
-
{ data: { name: 'John Doe', age: 30, active: 1 } },
|
|
190
|
-
{ data: { name: 'Jane Smith', age: 25, active: 0 } },
|
|
191
|
-
{ data: { name: 'Bob Johnson', age: 35, active: 1 } }
|
|
192
|
-
];
|
|
193
|
-
createdRecords = [];
|
|
194
|
-
for (const recordData of testData) {
|
|
195
|
-
const result = yield database.create(scope, recordData);
|
|
196
|
-
createdRecords.push(result);
|
|
197
|
-
}
|
|
198
|
-
}));
|
|
199
|
-
it('should find single record by id string', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
200
|
-
const targetId = createdRecords[0]._id.toString();
|
|
201
|
-
const result = yield database.read(scope, targetId);
|
|
202
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
203
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result._id.toString()).to.equal(targetId);
|
|
204
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.data.name).to.equal('John Doe');
|
|
205
|
-
// Verify against raw MongoDB find
|
|
206
|
-
const rawRecord = yield testCollection.findOne({ _id: createdRecords[0]._id });
|
|
207
|
-
(0, chai_1.expect)(rawRecord).to.not.be.null;
|
|
208
|
-
(0, chai_1.expect)(rawRecord.data.name).to.equal(result === null || result === void 0 ? void 0 : result.data.name);
|
|
209
|
-
}));
|
|
210
|
-
it('should return null for non-existent id', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
211
|
-
const nonExistentId = '507f1f77bcf86cd799439999';
|
|
212
|
-
const result = yield database.read(scope, nonExistentId);
|
|
213
|
-
(0, chai_1.expect)(result).to.be.null;
|
|
214
|
-
// Verify against raw MongoDB find
|
|
215
|
-
const rawRecord = yield testCollection.findOne({ _id: database.ObjectId(nonExistentId) });
|
|
216
|
-
(0, chai_1.expect)(rawRecord).to.be.null;
|
|
217
|
-
}));
|
|
218
|
-
it('should return null for invalid id format', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
219
|
-
const invalidId = 'invalid-id-format';
|
|
220
|
-
const result = yield database.read(scope, invalidId);
|
|
221
|
-
(0, chai_1.expect)(result).to.be.null;
|
|
222
|
-
// Verify against raw MongoDB find - should not find anything
|
|
223
|
-
const rawRecord = yield testCollection.findOne({ _id: invalidId });
|
|
224
|
-
(0, chai_1.expect)(rawRecord).to.be.null;
|
|
225
|
-
}));
|
|
226
|
-
it('should handle ObjectId conversion correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
227
|
-
const targetRecord = createdRecords[1];
|
|
228
|
-
const idString = targetRecord._id.toString();
|
|
229
|
-
const result = yield database.read(scope, idString);
|
|
230
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
231
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result._id.toString()).to.equal(idString);
|
|
232
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.data.name).to.equal('Jane Smith');
|
|
233
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.data.age).to.equal(25);
|
|
234
|
-
// Verify against raw MongoDB find
|
|
235
|
-
const rawRecord = yield testCollection.findOne({ _id: targetRecord._id });
|
|
236
|
-
(0, chai_1.expect)(rawRecord.data.name).to.equal('Jane Smith');
|
|
237
|
-
(0, chai_1.expect)(rawRecord.data.age).to.equal(25);
|
|
238
|
-
}));
|
|
239
|
-
it('should return null when database is not connected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
240
|
-
const db = new db_1.Database(config);
|
|
241
|
-
const result = yield db.read(scope, createdRecords[0]._id.toString());
|
|
242
|
-
(0, chai_1.expect)(result).to.be.null;
|
|
243
|
-
}));
|
|
244
|
-
});
|
|
245
|
-
describe('update', () => {
|
|
246
|
-
let testRecord;
|
|
247
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
248
|
-
// Create a test record
|
|
249
|
-
const recordData = {
|
|
250
|
-
data: { name: 'Original Name', status: 'draft', version: 1 }
|
|
251
|
-
};
|
|
252
|
-
testRecord = yield database.create(scope, recordData);
|
|
253
|
-
}));
|
|
254
|
-
it('should update a single record by id string', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
255
|
-
const updateData = {
|
|
256
|
-
data: { name: 'Updated Name', status: 'published', version: 2 }
|
|
257
|
-
};
|
|
258
|
-
yield new Promise(resolve => setTimeout(resolve, 10)); // Ensure timestamp difference
|
|
259
|
-
const result = yield database.update(scope, testRecord._id.toString(), updateData);
|
|
260
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
261
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.data.name).to.equal('Updated Name');
|
|
262
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.data.status).to.equal('published');
|
|
263
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.data.version).to.equal(2);
|
|
264
|
-
// Verify against raw MongoDB find
|
|
265
|
-
const rawRecord = yield testCollection.findOne({ _id: testRecord._id });
|
|
266
|
-
(0, chai_1.expect)(rawRecord.data.name).to.equal('Updated Name');
|
|
267
|
-
(0, chai_1.expect)(rawRecord.data.status).to.equal('published');
|
|
268
|
-
(0, chai_1.expect)(rawRecord.data.version).to.equal(2);
|
|
269
|
-
(0, chai_1.expect)(rawRecord.modified.getTime()).to.be.greaterThan(rawRecord.created.getTime());
|
|
270
|
-
}));
|
|
271
|
-
it('should return null for non-existent id', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
272
|
-
const updateData = { data: { status: 'updated' } };
|
|
273
|
-
const nonExistentId = '507f1f77bcf86cd799439999';
|
|
274
|
-
const result = yield database.update(scope, nonExistentId, updateData);
|
|
275
|
-
(0, chai_1.expect)(result).to.be.null;
|
|
276
|
-
// Verify original record unchanged
|
|
277
|
-
const rawRecord = yield testCollection.findOne({ _id: testRecord._id });
|
|
278
|
-
(0, chai_1.expect)(rawRecord.data.name).to.equal('Original Name');
|
|
279
|
-
(0, chai_1.expect)(rawRecord.data.status).to.equal('draft');
|
|
280
|
-
}));
|
|
281
|
-
it('should return null for invalid id format', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
282
|
-
const updateData = { data: { status: 'updated' } };
|
|
283
|
-
const invalidId = 'invalid-id-format';
|
|
284
|
-
const result = yield database.update(scope, invalidId, updateData);
|
|
285
|
-
(0, chai_1.expect)(result).to.be.null;
|
|
286
|
-
// Verify original record unchanged
|
|
287
|
-
const rawRecord = yield testCollection.findOne({ _id: testRecord._id });
|
|
288
|
-
(0, chai_1.expect)(rawRecord.data.name).to.equal('Original Name');
|
|
289
|
-
}));
|
|
290
|
-
it('should update timestamps correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
291
|
-
const originalModified = testRecord.modified;
|
|
292
|
-
const updateData = {
|
|
293
|
-
data: { status: 'updated' }
|
|
294
|
-
};
|
|
295
|
-
// Wait a moment to ensure timestamp difference
|
|
296
|
-
yield new Promise(resolve => setTimeout(resolve, 10));
|
|
297
|
-
const result = yield database.update(scope, testRecord._id.toString(), updateData);
|
|
298
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.modified.getTime()).to.be.greaterThan(originalModified.getTime());
|
|
299
|
-
// Verify against raw MongoDB find
|
|
300
|
-
const rawRecord = yield testCollection.findOne({ _id: testRecord._id });
|
|
301
|
-
(0, chai_1.expect)(rawRecord.modified.getTime()).to.be.greaterThan(originalModified.getTime());
|
|
302
|
-
}));
|
|
303
|
-
it('should return null when database is not connected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
304
|
-
const db = new db_1.Database(config);
|
|
305
|
-
const updateData = { data: { status: 'updated' } };
|
|
306
|
-
const result = yield db.update(scope, testRecord._id.toString(), updateData);
|
|
307
|
-
(0, chai_1.expect)(result).to.be.null;
|
|
308
|
-
}));
|
|
309
|
-
});
|
|
310
|
-
describe('delete', () => {
|
|
311
|
-
let testRecords;
|
|
312
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
313
|
-
// Create test records
|
|
314
|
-
const testData = [
|
|
315
|
-
{ data: { name: 'Record 1', category: 'temp' } },
|
|
316
|
-
{ data: { name: 'Record 2', category: 'temp' } },
|
|
317
|
-
{ data: { name: 'Record 3', category: 'permanent' } }
|
|
318
|
-
];
|
|
319
|
-
testRecords = [];
|
|
320
|
-
for (const recordData of testData) {
|
|
321
|
-
const result = yield database.create(scope, recordData);
|
|
322
|
-
testRecords.push(result);
|
|
323
|
-
}
|
|
324
|
-
}));
|
|
325
|
-
it('should soft delete a single record by id string', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
326
|
-
const targetRecord = testRecords[0];
|
|
327
|
-
const result = yield database.delete(scope, targetRecord._id.toString());
|
|
328
|
-
(0, chai_1.expect)(result).to.be.true;
|
|
329
|
-
// Verify against raw MongoDB find
|
|
330
|
-
const rawRecord = yield testCollection.findOne({ _id: targetRecord._id });
|
|
331
|
-
(0, chai_1.expect)(rawRecord.deleted).to.not.be.null;
|
|
332
|
-
(0, chai_1.expect)(rawRecord.deleted).to.be.a('date');
|
|
333
|
-
// Verify record still exists in database (soft delete)
|
|
334
|
-
const allRecords = yield testCollection.find({}).toArray();
|
|
335
|
-
(0, chai_1.expect)(allRecords).to.have.length(3);
|
|
336
|
-
}));
|
|
337
|
-
it('should hard delete a single record when specified', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
338
|
-
const targetRecord = testRecords[0];
|
|
339
|
-
const result = yield database.delete(scope, targetRecord._id.toString(), true);
|
|
340
|
-
(0, chai_1.expect)(result).to.be.true;
|
|
341
|
-
// Verify record is completely removed from database
|
|
342
|
-
const rawRecord = yield testCollection.findOne({ _id: targetRecord._id });
|
|
343
|
-
(0, chai_1.expect)(rawRecord).to.be.null;
|
|
344
|
-
// Verify total count decreased
|
|
345
|
-
const allRecords = yield testCollection.find({}).toArray();
|
|
346
|
-
(0, chai_1.expect)(allRecords).to.have.length(2);
|
|
347
|
-
}));
|
|
348
|
-
it('should return false for non-existent id', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
349
|
-
const nonExistentId = '507f1f77bcf86cd799439999';
|
|
350
|
-
const result = yield database.delete(scope, nonExistentId);
|
|
351
|
-
(0, chai_1.expect)(result).to.be.false;
|
|
352
|
-
// Verify no records were affected
|
|
353
|
-
const allRecords = yield testCollection.find({}).toArray();
|
|
354
|
-
(0, chai_1.expect)(allRecords).to.have.length(3);
|
|
355
|
-
allRecords.forEach((record) => {
|
|
356
|
-
(0, chai_1.expect)(record.deleted).to.be.null;
|
|
357
|
-
});
|
|
358
|
-
}));
|
|
359
|
-
it('should return false for invalid id format', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
360
|
-
const invalidId = 'invalid-id-format';
|
|
361
|
-
const result = yield database.delete(scope, invalidId);
|
|
362
|
-
(0, chai_1.expect)(result).to.be.false;
|
|
363
|
-
// Verify no records were affected
|
|
364
|
-
const allRecords = yield testCollection.find({}).toArray();
|
|
365
|
-
(0, chai_1.expect)(allRecords).to.have.length(3);
|
|
366
|
-
}));
|
|
367
|
-
it('should handle deletion of already deleted record', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
368
|
-
// First, soft delete a record
|
|
369
|
-
const targetRecord = testRecords[0];
|
|
370
|
-
const firstDelete = yield database.delete(scope, targetRecord._id.toString());
|
|
371
|
-
(0, chai_1.expect)(firstDelete).to.be.true;
|
|
372
|
-
// Try to delete it again
|
|
373
|
-
const secondDelete = yield database.delete(scope, targetRecord._id.toString());
|
|
374
|
-
(0, chai_1.expect)(secondDelete).to.be.false; // Should be false
|
|
375
|
-
// Verify it's still soft deleted (not hard deleted)
|
|
376
|
-
const rawRecord = yield testCollection.findOne({ _id: targetRecord._id });
|
|
377
|
-
(0, chai_1.expect)(rawRecord).to.not.be.null;
|
|
378
|
-
(0, chai_1.expect)(rawRecord.deleted).to.not.be.null;
|
|
379
|
-
}));
|
|
380
|
-
it('should hard delete an already soft deleted record', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
381
|
-
const targetRecord = testRecords[0];
|
|
382
|
-
// First, soft delete the record
|
|
383
|
-
const softDelete = yield database.delete(scope, targetRecord._id.toString());
|
|
384
|
-
(0, chai_1.expect)(softDelete).to.be.true;
|
|
385
|
-
// Then hard delete it
|
|
386
|
-
const hardDelete = yield database.delete(scope, targetRecord._id.toString(), true);
|
|
387
|
-
(0, chai_1.expect)(hardDelete).to.be.true;
|
|
388
|
-
// Verify record is completely removed from database
|
|
389
|
-
const rawRecord = yield testCollection.findOne({ _id: targetRecord._id });
|
|
390
|
-
(0, chai_1.expect)(rawRecord).to.be.null;
|
|
391
|
-
// Verify total count decreased
|
|
392
|
-
const allRecords = yield testCollection.find({}).toArray();
|
|
393
|
-
(0, chai_1.expect)(allRecords).to.have.length(2);
|
|
394
|
-
}));
|
|
395
|
-
it('should update modified timestamp on soft delete', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
396
|
-
const targetRecord = testRecords[0];
|
|
397
|
-
const originalModified = targetRecord.modified;
|
|
398
|
-
// Wait a moment to ensure timestamp difference
|
|
399
|
-
yield new Promise(resolve => setTimeout(resolve, 10));
|
|
400
|
-
const result = yield database.delete(scope, targetRecord._id.toString());
|
|
401
|
-
(0, chai_1.expect)(result).to.be.true;
|
|
402
|
-
// Verify against raw MongoDB find
|
|
403
|
-
const rawRecord = yield testCollection.findOne({ _id: targetRecord._id });
|
|
404
|
-
(0, chai_1.expect)(rawRecord.modified.getTime()).to.be.greaterThan(originalModified.getTime());
|
|
405
|
-
}));
|
|
406
|
-
it('should return false when database is not connected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
407
|
-
const db = new db_1.Database(config);
|
|
408
|
-
const result = yield db.delete(scope, testRecords[0]._id.toString());
|
|
409
|
-
(0, chai_1.expect)(result).to.be.false;
|
|
410
|
-
}));
|
|
411
|
-
});
|
|
412
|
-
describe('CRUD Integration Tests', () => {
|
|
413
|
-
it('should perform complete CRUD lifecycle', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
414
|
-
// CREATE
|
|
415
|
-
const createData = {
|
|
416
|
-
data: { name: 'CRUD Test User', email: 'crud@test.com', status: 'new' }
|
|
417
|
-
};
|
|
418
|
-
const created = yield database.create(scope, createData);
|
|
419
|
-
(0, chai_1.expect)(created).to.not.be.null;
|
|
420
|
-
// Verify creation with raw MongoDB
|
|
421
|
-
let rawRecord = yield testCollection.findOne({ _id: created === null || created === void 0 ? void 0 : created._id });
|
|
422
|
-
(0, chai_1.expect)(rawRecord.data.name).to.equal('CRUD Test User');
|
|
423
|
-
// READ
|
|
424
|
-
const readResult = yield database.read(scope, created === null || created === void 0 ? void 0 : created._id.toString());
|
|
425
|
-
(0, chai_1.expect)(readResult).to.not.be.null;
|
|
426
|
-
(0, chai_1.expect)(readResult === null || readResult === void 0 ? void 0 : readResult.data.name).to.equal('CRUD Test User');
|
|
427
|
-
// UPDATE
|
|
428
|
-
const updateData = {
|
|
429
|
-
data: { name: 'Updated CRUD User', status: 'modified' }
|
|
430
|
-
};
|
|
431
|
-
const updated = yield database.update(scope, created === null || created === void 0 ? void 0 : created._id.toString(), updateData);
|
|
432
|
-
(0, chai_1.expect)(updated).to.not.be.null;
|
|
433
|
-
(0, chai_1.expect)(updated === null || updated === void 0 ? void 0 : updated.data.name).to.equal('Updated CRUD User');
|
|
434
|
-
// Verify update with raw MongoDB
|
|
435
|
-
rawRecord = yield testCollection.findOne({ _id: created === null || created === void 0 ? void 0 : created._id });
|
|
436
|
-
(0, chai_1.expect)(rawRecord.data.name).to.equal('Updated CRUD User');
|
|
437
|
-
(0, chai_1.expect)(rawRecord.data.status).to.equal('modified');
|
|
438
|
-
// DELETE (soft)
|
|
439
|
-
const deleted = yield database.delete(scope, created === null || created === void 0 ? void 0 : created._id.toString());
|
|
440
|
-
(0, chai_1.expect)(deleted).to.be.true;
|
|
441
|
-
// Verify soft delete with raw MongoDB
|
|
442
|
-
rawRecord = yield testCollection.findOne({ _id: created === null || created === void 0 ? void 0 : created._id });
|
|
443
|
-
(0, chai_1.expect)(rawRecord).to.not.be.null;
|
|
444
|
-
(0, chai_1.expect)(rawRecord.deleted).to.not.be.null;
|
|
445
|
-
// HARD DELETE
|
|
446
|
-
const hardDeleted = yield database.delete(scope, created === null || created === void 0 ? void 0 : created._id.toString(), true);
|
|
447
|
-
(0, chai_1.expect)(hardDeleted).to.be.true;
|
|
448
|
-
// Verify hard delete with raw MongoDB
|
|
449
|
-
rawRecord = yield testCollection.findOne({ _id: created === null || created === void 0 ? void 0 : created._id });
|
|
450
|
-
(0, chai_1.expect)(rawRecord).to.be.null;
|
|
451
|
-
}));
|
|
452
|
-
});
|
|
453
|
-
describe('index', () => {
|
|
454
|
-
let testRecords;
|
|
455
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
456
|
-
// Create a comprehensive dataset for testing
|
|
457
|
-
const testData = [
|
|
458
|
-
{ data: { name: 'Alice Johnson', age: 28, department: 'Engineering', active: true, salary: 75000 } },
|
|
459
|
-
{ data: { name: 'Bob Smith', age: 35, department: 'Marketing', active: true, salary: 65000 } },
|
|
460
|
-
{ data: { name: 'Carol Davis', age: 42, department: 'Engineering', active: false, salary: 85000 } },
|
|
461
|
-
{ data: { name: 'David Wilson', age: 29, department: 'Sales', active: true, salary: 55000 } },
|
|
462
|
-
{ data: { name: 'Eve Brown', age: 31, department: 'Engineering', active: true, salary: 78000 } },
|
|
463
|
-
{ data: { name: 'Frank Miller', age: 45, department: 'Marketing', active: false, salary: 70000 } },
|
|
464
|
-
{ data: { name: 'Grace Lee', age: 26, department: 'Sales', active: true, salary: 52000 } },
|
|
465
|
-
{ data: { name: 'Henry Taylor', age: 38, department: 'Engineering', active: true, salary: 82000 } },
|
|
466
|
-
{ data: { name: 'Ivy Chen', age: 33, department: 'Marketing', active: true, salary: 68000 } },
|
|
467
|
-
{ data: { name: 'Jack White', age: 27, department: 'Sales', active: false, salary: 49000 } }
|
|
468
|
-
];
|
|
469
|
-
testRecords = [];
|
|
470
|
-
for (const recordData of testData) {
|
|
471
|
-
const result = yield database.create(scope, recordData);
|
|
472
|
-
testRecords.push(result);
|
|
473
|
-
}
|
|
474
|
-
// Wait a moment to ensure all records are created with different timestamps
|
|
475
|
-
yield new Promise(resolve => setTimeout(resolve, 10));
|
|
476
|
-
}));
|
|
477
|
-
it('should return all records with default parameters', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
478
|
-
var _a, _b;
|
|
479
|
-
const result = yield database.index(scope);
|
|
480
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
481
|
-
(0, chai_1.expect)((_a = result === null || result === void 0 ? void 0 : result.items) === null || _a === void 0 ? void 0 : _a.length).to.be.at.most(10); // Default limit might be 10
|
|
482
|
-
// Verify against raw MongoDB find (matching the filters applied by the query method)
|
|
483
|
-
const rawQuery = {
|
|
484
|
-
deleted: null,
|
|
485
|
-
form: database.ObjectId(scope.form._id),
|
|
486
|
-
project: database.ObjectId(scope.project._id)
|
|
487
|
-
};
|
|
488
|
-
// Apply the same default limit and sort as the index method
|
|
489
|
-
const rawRecords = yield testCollection.find(rawQuery).sort({ created: -1 }).limit(10).toArray();
|
|
490
|
-
(0, chai_1.expect)(rawRecords).to.have.length(10);
|
|
491
|
-
// Compare first few records (accounting for potential default limit)
|
|
492
|
-
const compareLength = Math.min((_b = result === null || result === void 0 ? void 0 : result.items) === null || _b === void 0 ? void 0 : _b.length, rawRecords.length);
|
|
493
|
-
(0, chai_1.expect)(result.items.length).to.equal(compareLength);
|
|
494
|
-
// Verify that the returned records match the raw query results in content and order
|
|
495
|
-
for (let i = 0; i < compareLength; i++) {
|
|
496
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.items[i].data.name).to.equal(rawRecords[i].data.name);
|
|
497
|
-
(0, chai_1.expect)(result === null || result === void 0 ? void 0 : result.items[i].data.department).to.equal(rawRecords[i].data.department);
|
|
498
|
-
}
|
|
499
|
-
}));
|
|
500
|
-
it('should handle query filtering', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
501
|
-
const query = { 'data.department': 'Engineering' };
|
|
502
|
-
const result = yield database.index(scope, query);
|
|
503
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
504
|
-
(0, chai_1.expect)(result.items.length).to.equal(4); // Should match 4 engineering records
|
|
505
|
-
// Verify all returned records match the query
|
|
506
|
-
result.items.forEach((record) => {
|
|
507
|
-
(0, chai_1.expect)(record.data.department).to.equal('Engineering');
|
|
508
|
-
});
|
|
509
|
-
// Verify against raw MongoDB find
|
|
510
|
-
const rawRecords = yield testCollection.find(query).sort({ created: -1 }).toArray();
|
|
511
|
-
(0, chai_1.expect)(rawRecords).to.have.length(4);
|
|
512
|
-
(0, chai_1.expect)(result.items.length).to.equal(rawRecords.length);
|
|
513
|
-
// Compare records
|
|
514
|
-
for (let i = 0; i < result.items.length; i++) {
|
|
515
|
-
(0, chai_1.expect)(result.items[i]._id.toString()).to.equal(rawRecords[i]._id.toString());
|
|
516
|
-
(0, chai_1.expect)(result.items[i].data.department).to.equal('Engineering');
|
|
517
|
-
}
|
|
518
|
-
}));
|
|
519
|
-
it('should handle complex query filtering', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
520
|
-
const query = {
|
|
521
|
-
'data.active': true,
|
|
522
|
-
'data.salary': { $gte: 70000 }
|
|
523
|
-
};
|
|
524
|
-
const result = yield database.index(scope, query);
|
|
525
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
526
|
-
// Verify all returned records match the complex query
|
|
527
|
-
result.items.forEach((record) => {
|
|
528
|
-
(0, chai_1.expect)(record.data.active).to.be.true;
|
|
529
|
-
(0, chai_1.expect)(record.data.salary).to.be.at.least(70000);
|
|
530
|
-
});
|
|
531
|
-
// Verify against raw MongoDB find
|
|
532
|
-
const rawRecords = yield testCollection.find(query).sort({ created: -1 }).toArray();
|
|
533
|
-
(0, chai_1.expect)(result.items.length).to.equal(rawRecords.length);
|
|
534
|
-
// Compare records
|
|
535
|
-
for (let i = 0; i < result.items.length; i++) {
|
|
536
|
-
(0, chai_1.expect)(result.items[i]._id.toString()).to.equal(rawRecords[i]._id.toString());
|
|
537
|
-
(0, chai_1.expect)(result.items[i].data.active).to.be.true;
|
|
538
|
-
(0, chai_1.expect)(result.items[i].data.salary).to.be.at.least(70000);
|
|
539
|
-
}
|
|
540
|
-
}));
|
|
541
|
-
it('should handle limit parameter', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
542
|
-
const limit = 3;
|
|
543
|
-
const result = yield database.index(scope, { limit });
|
|
544
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
545
|
-
(0, chai_1.expect)(result.items.length).to.equal(limit);
|
|
546
|
-
// Verify against raw MongoDB find with limit
|
|
547
|
-
const rawRecords = yield testCollection.find({}).sort({ created: -1 }).limit(limit).toArray();
|
|
548
|
-
(0, chai_1.expect)(rawRecords).to.have.length(limit);
|
|
549
|
-
(0, chai_1.expect)(result.items.length).to.equal(rawRecords.length);
|
|
550
|
-
// Compare records
|
|
551
|
-
for (let i = 0; i < result.items.length; i++) {
|
|
552
|
-
(0, chai_1.expect)(result.items[i]._id.toString()).to.equal(rawRecords[i]._id.toString());
|
|
553
|
-
}
|
|
554
|
-
}));
|
|
555
|
-
it('should handle skip parameter for pagination', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
556
|
-
const limit = 3;
|
|
557
|
-
const skip = 2;
|
|
558
|
-
const result = yield database.index(scope, { limit, skip });
|
|
559
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
560
|
-
(0, chai_1.expect)(result.items.length).to.equal(limit);
|
|
561
|
-
// Verify against raw MongoDB find with skip and limit
|
|
562
|
-
const rawRecords = yield testCollection.find({}).sort({ created: -1 }).skip(skip).limit(limit).toArray();
|
|
563
|
-
(0, chai_1.expect)(rawRecords).to.have.length(limit);
|
|
564
|
-
(0, chai_1.expect)(result.items.length).to.equal(rawRecords.length);
|
|
565
|
-
// Compare records
|
|
566
|
-
for (let i = 0; i < result.items.length; i++) {
|
|
567
|
-
(0, chai_1.expect)(result.items[i]._id.toString()).to.equal(rawRecords[i]._id.toString());
|
|
568
|
-
}
|
|
569
|
-
}));
|
|
570
|
-
it('should handle custom sort parameter', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
571
|
-
const sort = { 'data.age': 1 }; // Sort by age ascending
|
|
572
|
-
const result = yield database.index(scope, { sort, limit: 10, skip: 0 });
|
|
573
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
574
|
-
// Verify sorting
|
|
575
|
-
for (let i = 1; i < result.items.length; i++) {
|
|
576
|
-
(0, chai_1.expect)(result.items[i].data.age).to.be.at.least(result.items[i - 1].data.age);
|
|
577
|
-
}
|
|
578
|
-
// Verify against raw MongoDB find with custom sort
|
|
579
|
-
const rawRecords = yield testCollection.find({}).sort(sort).toArray();
|
|
580
|
-
(0, chai_1.expect)(result.items.length).to.be.at.most(rawRecords.length);
|
|
581
|
-
// Compare first records (accounting for potential limit)
|
|
582
|
-
const compareLength = Math.min(result.items.length, rawRecords.length);
|
|
583
|
-
for (let i = 0; i < compareLength; i++) {
|
|
584
|
-
(0, chai_1.expect)(result.items[i]._id.toString()).to.equal(rawRecords[i]._id.toString());
|
|
585
|
-
(0, chai_1.expect)(result.items[i].data.age).to.equal(rawRecords[i].data.age);
|
|
586
|
-
}
|
|
587
|
-
}));
|
|
588
|
-
it('should handle select parameter for field projection', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
589
|
-
const select = { 'data.name': 1, 'data.department': 1 };
|
|
590
|
-
const result = yield database.index(scope, { limit: 10, skip: 0, sort: { created: -1 }, select });
|
|
591
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
592
|
-
// Verify field projection (only selected fields should be present in data)
|
|
593
|
-
result.items.forEach((record) => {
|
|
594
|
-
(0, chai_1.expect)(record.data.name).to.exist;
|
|
595
|
-
(0, chai_1.expect)(record.data.department).to.exist;
|
|
596
|
-
// Other fields should not be present (depending on implementation)
|
|
597
|
-
// Note: MongoDB projection behavior may vary based on implementation
|
|
598
|
-
});
|
|
599
|
-
// Verify against raw MongoDB find with projection
|
|
600
|
-
const rawRecords = yield testCollection.find({}, { projection: select }).sort({ created: -1 }).toArray();
|
|
601
|
-
(0, chai_1.expect)(result.items.length).to.be.at.most(rawRecords.length);
|
|
602
|
-
}));
|
|
603
|
-
it('should handle empty query results', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
604
|
-
const query = { 'data.department': 'NonExistentDepartment' };
|
|
605
|
-
const result = yield database.index(scope, query);
|
|
606
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
607
|
-
(0, chai_1.expect)(result.items.length).to.equal(0);
|
|
608
|
-
// Verify against raw MongoDB find
|
|
609
|
-
const rawRecords = yield testCollection.find(query).toArray();
|
|
610
|
-
(0, chai_1.expect)(rawRecords).to.have.length(0);
|
|
611
|
-
(0, chai_1.expect)(result.items.length).to.equal(rawRecords.length);
|
|
612
|
-
}));
|
|
613
|
-
it('should exclude soft deleted records by default', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
614
|
-
// Soft delete one record
|
|
615
|
-
yield database.delete(scope, testRecords[0]._id.toString());
|
|
616
|
-
const result = yield database.index(scope);
|
|
617
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
618
|
-
(0, chai_1.expect)(result.items.length).to.equal(9); // Should be one less
|
|
619
|
-
// Verify deleted record is not included
|
|
620
|
-
const deletedRecordInResult = result.items.find((record) => record._id.toString() === testRecords[0]._id.toString());
|
|
621
|
-
(0, chai_1.expect)(deletedRecordInResult).to.be.undefined;
|
|
622
|
-
// Verify against raw MongoDB find (excluding deleted)
|
|
623
|
-
const rawRecords = yield testCollection.find({ deleted: null }).sort({ created: -1 }).toArray();
|
|
624
|
-
(0, chai_1.expect)(rawRecords).to.have.length(9);
|
|
625
|
-
(0, chai_1.expect)(result.items.length).to.be.at.most(rawRecords.length);
|
|
626
|
-
}));
|
|
627
|
-
it('should handle includeDeleted parameter if available', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
628
|
-
// Soft delete one record
|
|
629
|
-
yield database.delete(scope, testRecords[0]._id.toString());
|
|
630
|
-
// This test assumes the index method has an includeDeleted parameter
|
|
631
|
-
// Adjust based on actual implementation
|
|
632
|
-
const result = yield database.index(scope, { limit: 10, skip: 0, sort: { created: -1 }, select: {}, includeDeleted: true });
|
|
633
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
634
|
-
(0, chai_1.expect)(result.items.length).to.equal(10); // Should include deleted record
|
|
635
|
-
// Verify against raw MongoDB find (including deleted)
|
|
636
|
-
const rawRecords = yield testCollection.find({}).sort({ created: -1 }).toArray();
|
|
637
|
-
(0, chai_1.expect)(rawRecords).to.have.length(10);
|
|
638
|
-
(0, chai_1.expect)(result.items.length).to.be.at.most(rawRecords.length);
|
|
639
|
-
}));
|
|
640
|
-
it('should handle pagination correctly across multiple pages', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
641
|
-
const pageSize = 3;
|
|
642
|
-
const pages = [];
|
|
643
|
-
// Get first 3 pages
|
|
644
|
-
for (let page = 0; page < 3; page++) {
|
|
645
|
-
const skip = page * pageSize;
|
|
646
|
-
const result = yield database.index(scope, { limit: pageSize, skip });
|
|
647
|
-
pages.push(result);
|
|
648
|
-
}
|
|
649
|
-
// Verify no duplicate records across pages
|
|
650
|
-
const allIds = pages.flatMap(page => page.items).map((record) => record._id.toString());
|
|
651
|
-
const uniqueIds = [...new Set(allIds)];
|
|
652
|
-
(0, chai_1.expect)(allIds.length).to.equal(uniqueIds.length);
|
|
653
|
-
// Verify against raw MongoDB pagination
|
|
654
|
-
const rawPage1 = yield testCollection.find({}).sort({ created: -1 }).limit(pageSize).toArray();
|
|
655
|
-
const rawPage2 = yield testCollection.find({}).sort({ created: -1 }).skip(pageSize).limit(pageSize).toArray();
|
|
656
|
-
const rawPage3 = yield testCollection.find({}).sort({ created: -1 }).skip(pageSize * 2).limit(pageSize).toArray();
|
|
657
|
-
// Compare first page
|
|
658
|
-
(0, chai_1.expect)(pages[0].items.length).to.equal(rawPage1.length);
|
|
659
|
-
for (let i = 0; i < pages[0].items.length; i++) {
|
|
660
|
-
(0, chai_1.expect)(pages[0].items[i]._id.toString()).to.equal(rawPage1[i]._id.toString());
|
|
661
|
-
}
|
|
662
|
-
// Compare second page
|
|
663
|
-
(0, chai_1.expect)(pages[1].items.length).to.equal(rawPage2.length);
|
|
664
|
-
for (let i = 0; i < pages[1].items.length; i++) {
|
|
665
|
-
(0, chai_1.expect)(pages[1].items[i]._id.toString()).to.equal(rawPage2[i]._id.toString());
|
|
666
|
-
}
|
|
667
|
-
}));
|
|
668
|
-
it('should return empty array when database is not connected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
669
|
-
const db = new db_1.Database(config);
|
|
670
|
-
const result = yield db.index(scope);
|
|
671
|
-
(0, chai_1.expect)(result.items).to.be.an('array');
|
|
672
|
-
(0, chai_1.expect)(result.items.length).to.equal(0);
|
|
673
|
-
}));
|
|
674
|
-
it('should handle ObjectId queries correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
675
|
-
const targetRecord = testRecords[0];
|
|
676
|
-
const query = { _id: targetRecord._id };
|
|
677
|
-
const result = yield database.index(scope, query);
|
|
678
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
679
|
-
(0, chai_1.expect)(result.items.length).to.equal(1);
|
|
680
|
-
(0, chai_1.expect)(result.items[0]._id.toString()).to.equal(targetRecord._id.toString());
|
|
681
|
-
// Verify against raw MongoDB find
|
|
682
|
-
const rawRecord = yield testCollection.findOne({ _id: targetRecord._id });
|
|
683
|
-
(0, chai_1.expect)(rawRecord).to.not.be.null;
|
|
684
|
-
(0, chai_1.expect)(result.items[0].data.name).to.equal(rawRecord.data.name);
|
|
685
|
-
}));
|
|
686
|
-
it('should handle regex queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
687
|
-
const query = { 'data.name': { $regex: /^A/, $options: 'i' } }; // Names starting with 'A'
|
|
688
|
-
const result = yield database.index(scope, query);
|
|
689
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
690
|
-
(0, chai_1.expect)(result.items.length).to.equal(1); // Should match 'Alice Johnson'
|
|
691
|
-
(0, chai_1.expect)(result.items[0].data.name).to.equal('Alice Johnson');
|
|
692
|
-
// Verify against raw MongoDB find
|
|
693
|
-
const rawRecords = yield testCollection.find(query).sort({ created: -1 }).toArray();
|
|
694
|
-
(0, chai_1.expect)(rawRecords).to.have.length(1);
|
|
695
|
-
(0, chai_1.expect)(result.items.length).to.equal(rawRecords.length);
|
|
696
|
-
(0, chai_1.expect)(result.items[0].data.name).to.equal(rawRecords[0].data.name);
|
|
697
|
-
}));
|
|
698
|
-
it('should handle $in queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
699
|
-
const query = { 'data.department': { $in: ['Engineering', 'Sales'] } };
|
|
700
|
-
const result = yield database.index(scope, query);
|
|
701
|
-
(0, chai_1.expect)(result).to.not.be.null;
|
|
702
|
-
(0, chai_1.expect)(result.items.length).to.equal(7); // 4 Engineering + 3 Sales
|
|
703
|
-
// Verify all returned records match the query
|
|
704
|
-
result.items.forEach((record) => {
|
|
705
|
-
(0, chai_1.expect)(['Engineering', 'Sales']).to.include(record.data.department);
|
|
706
|
-
});
|
|
707
|
-
// Verify against raw MongoDB find
|
|
708
|
-
const rawRecords = yield testCollection.find(query).sort({ created: -1 }).toArray();
|
|
709
|
-
(0, chai_1.expect)(rawRecords).to.have.length(7);
|
|
710
|
-
(0, chai_1.expect)(result.items.length).to.equal(rawRecords.length);
|
|
711
|
-
}));
|
|
712
|
-
});
|
|
713
|
-
});
|
|
714
|
-
});
|