@travetto/model-query
Version:
Datastore abstraction for advanced query support.
156 lines (110 loc) • 4.73 kB
text/typescript
import assert from 'node:assert';
import { Suite, Test } from '@travetto/test';
import { ModelCrudSupport, NotFoundError } from '@travetto/model';
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
import { Address, Person, Todo } from './model.ts';
import { ModelQueryCrudSupport } from '../../src/types/crud.ts';
@Suite()
export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudSupport & ModelCrudSupport> {
@Test()
async testUpdateOneWithQuery() {
const svc = await this.service;
const todo1 = await svc.create(Todo, Todo.from({ text: 'bob' }));
assert(todo1.id);
assert(todo1.version === 0);
const todo1v2 = await svc.updateByQuery(Todo, Todo.from({
id: todo1.id,
text: `${todo1.text}!!`,
version: todo1.version + 1
}), { where: { id: todo1.id, version: todo1.version } },);
assert(todo1v2.id === todo1.id);
assert(todo1v2.version > todo1.version);
await assert.rejects(
() => svc.updateByQuery(Todo, Todo.from({
id: todo1.id,
text: `${todo1.text}!!`,
version: todo1.version + 1
}), { where: { id: todo1.id, version: todo1.version } }),
NotFoundError
);
const todo2 = await svc.create(Todo, Todo.from({ text: 'bob2' }));
const result = await svc.updateByQuery(Todo, Todo.from({
id: todo2.id,
text: `${todo1.text}!!`,
version: todo1.version + 1
}), { where: { id: todo2.id, text: 'bob2' } });
assert(result.id === todo2.id);
}
@Test()
async testUpdateOneWithQueryMultiple() {
const svc = await this.service;
const todo1 = await svc.create(Todo, Todo.from({ text: 'bob', version: 1 }));
assert(todo1.id);
assert(todo1.version === 1);
const todo1v = ['a', 'b', 'c', 'd', 'e'].map(x => Todo.from({ ...todo1, text: `${todo1.text}-${x}`, version: todo1.version + 1 }));
const promises = todo1v.map(x => svc.updateByQuery(Todo, x, { where: { version: todo1.version } }));
const results = await Promise.allSettled(promises);
const rejected = results.filter(x => x.status === 'rejected');
const fulfilled = results.filter(x => x.status === 'fulfilled');
for (const el of rejected) {
assert(el.reason instanceof NotFoundError);
}
assert(fulfilled.length === 1);
assert(rejected.length === todo1v.length - 1);
const succeeded = fulfilled[0];
assert(succeeded.value.id === todo1.id);
assert(succeeded.value.version === todo1.version + 1);
assert(succeeded.value.text !== todo1.text);
const todo2 = await svc.get(Todo, todo1.id);
assert.deepStrictEqual(todo2, succeeded.value);
const promises2 = ['a', 'b', 'c', 'd', 'e'].map(x => Todo.from({ ...todo2, text: `${todo2.text}-${x}`, version: todo2.version + 2 }));
const results2 = await Promise.allSettled(promises2.map(x => svc.updateByQuery(Todo, x, { where: { version: todo2.version + 1 } })));
for (const el of results2) {
assert(el.status === 'rejected');
assert(el.reason instanceof NotFoundError);
}
}
@Test()
async testDeleteByQuery() {
const svc = await this.service;
const count = await this.saveAll(Person, [1, 2, 3, 4, 5].map(d => Person.from({
age: d,
gender: 'm',
name: `Test ${d}`,
address: Address.from({
street1: 'street1',
street2: 'street2'
})
})));
assert(count === 5);
const c = await svc.deleteByQuery(Person, { where: { age: { $gt: 3 } } });
assert(c === 2);
assert(await svc.queryCount(Person, {}) === 3);
const c2 = await svc.deleteByQuery(Person, { where: { age: { $lte: 3 } } });
assert(c2 === 3);
assert(await svc.queryCount(Person, {}) === 0);
}
@Test()
async testUpdateByQuery() {
const svc = await this.service;
const count = await this.saveAll(Person, [1, 2, 3, 4, 5].map(d => Person.from({
age: d,
gender: 'm',
name: `Test ${d}`,
address: Address.from({
street1: 'street1',
street2: 'street2'
})
})));
assert(count === 5);
assert(await svc.queryCount(Person, { where: { gender: 'm' } }) === 5);
const c = await svc.updatePartialByQuery(Person, { where: { age: { $gt: 3 } } }, { gender: 'f' });
assert((await svc.query(Person, {}))[0].address.street1 === 'street1');
assert(c === 2);
assert(await svc.queryCount(Person, { where: { gender: 'm' } }) === 3);
const c2 = await svc.updatePartialByQuery(Person, { where: { gender: 'm' } }, { gender: 'f' });
assert(c2 === 3);
assert(await svc.queryCount(Person, { where: { gender: 'f' } }) === 5);
assert(await svc.queryCount(Person, { where: { gender: 'm' } }) === 0);
}
}