import MysqlConnectionManager from "../src/db/MysqlConnectionManager"; import Model from "../src/db/Model"; import {MIGRATIONS} from "./_migrations"; import ModelFactory from "../src/db/ModelFactory"; import {ValidationBag, ValidationError} from "../src/db/Validator"; class FakeDummyModel extends Model { public id?: number = undefined; public name?: string = undefined; public date?: Date = undefined; public date_default?: Date = undefined; protected init(): void { this.setValidation('name').acceptUndefined().between(3, 256); } } let factory: ModelFactory; beforeAll(async () => { MysqlConnectionManager.registerMigrations(MIGRATIONS); ModelFactory.register(FakeDummyModel); await MysqlConnectionManager.prepare(); // Create FakeDummyModel table factory = ModelFactory.get(FakeDummyModel); await MysqlConnectionManager.query(`DROP TABLE IF EXISTS ${(factory.table)}`); await MysqlConnectionManager.query(`CREATE TABLE ${(factory.table)}( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(256), date DATETIME, date_default DATETIME DEFAULT NOW(), PRIMARY KEY(id) )`); }); afterAll(async () => { await MysqlConnectionManager.endPool(); }); describe('Model', () => { it('should construct properly', () => { const date = new Date(888); const model = factory.create({ name: 'a_name', date: date, non_existing_property: 'dropped_value', }); expect(model.id).toBeUndefined(); expect(model.name).toBe('a_name'); expect(model.date).toBe(date); expect(model.date_default).toBeUndefined(); expect(model.non_existing_property).toBeUndefined(); }); it('should have a proper table name', () => { expect(factory.table).toBe('fake_dummy_models'); expect(FakeDummyModel.table).toBe('fake_dummy_models'); expect(FakeDummyModel.create({}).table).toBe('fake_dummy_models'); }); it('should insert properly', async () => { const date = new Date(569985); const insertInstance: FakeDummyModel | null = factory.create({ name: 'name1', date: date, }); // Insert expect(await insertInstance.exists()).toBeFalsy(); await insertInstance.save(); expect(await insertInstance.exists()).toBeTruthy(); expect(insertInstance.id).toBe(1); // Auto id from insert expect(insertInstance.name).toBe('name1'); expect(insertInstance.date?.getTime()).toBeCloseTo(date.getTime(), -4); expect(insertInstance.date_default).toBeDefined(); // Check that row exists in DB const retrievedInstance = await FakeDummyModel.getById(1); expect(retrievedInstance).toBeDefined(); expect(retrievedInstance!.id).toBe(1); expect(retrievedInstance!.name).toBe('name1'); expect(retrievedInstance!.date?.getTime()).toBeCloseTo(date.getTime(), -4); expect(retrievedInstance!.date_default).toBeDefined(); const failingInsertModel = factory.create({ name: 'a', }); await expect(failingInsertModel.save()).rejects.toBeInstanceOf(ValidationBag); }); it('should update properly', async () => { const insertModel = factory.create({ name: 'update', }); await insertModel.save(); const preUpdatedModel = await FakeDummyModel.getById(insertModel.id); expect(preUpdatedModel).not.toBeNull(); expect(preUpdatedModel!.name).toBe(insertModel.name); // Update model preUpdatedModel!.name = 'updated_name'; await preUpdatedModel!.save(); const postUpdatedModel = await FakeDummyModel.getById(insertModel.id); expect(postUpdatedModel).not.toBeNull(); expect(postUpdatedModel!.id).toBe(insertModel.id); expect(postUpdatedModel!.name).not.toBe(insertModel.name); expect(postUpdatedModel!.name).toBe(preUpdatedModel!.name); }); it('should delete properly', async () => { const insertModel = factory.create({ name: 'delete', }); await insertModel.save(); const preDeleteModel = await FakeDummyModel.getById(insertModel.id); expect(preDeleteModel).not.toBeNull(); await preDeleteModel!.delete(); const postDeleteModel = await FakeDummyModel.getById(insertModel.id); expect(postDeleteModel).toBeNull(); }); });