acebase/spec/schema.spec.js
Ewout Stortenbeker 39389f7200 updated unit tests
2022-07-25 22:51:55 +02:00

254 lines
No EOL
9.7 KiB
JavaScript

/// <reference types='@types/jasmine' />
const { AceBase } = require('..');
const { createTempDB } = require("./tempdb");
const ok = { ok: true };
describe('schema', () => {
/** @type {AceBase} */
let db;
/** @type {{(): Promise<void>}} */
let removeDB;
beforeAll(async () => {
({ db, removeDB } = await createTempDB());
});
it('can be defined with strings and objects', async () => {
// const { db, removeDB } = await createTempDB();
// Try using string type definitions
let clientSchema = {
name: 'string',
url: 'string',
email: 'string',
"contacts?": {
'*': {
type: 'string',
name: 'string',
email: 'string',
telephone: 'string'
}
},
"addresses?": {
'*': {
type: '"postal"|"visit"',
street: 'string',
nr: 'number',
city: 'string',
"state?": 'string',
country: '"nl"|"be"|"de"|"fr"',
}
}
};
expect(() => db.schema.set('clients/*', clientSchema)).not.toThrow();
// Test if we can add client without contacts and addresses
let result = await db.schema.check('clients/client1', { name: 'Ewout', url: '', email: '' }, false);
expect(result).toEqual({ ok: true });
// Test without email
result = await db.schema.check('clients/client1', { name: 'Ewout', url: '' }, false);
expect(result.ok).toBeFalse();
// Test with wrong email data type
result = await db.schema.check('clients/client1', { name: 'Ewout', url: '', email: 35 }, false);
expect(result.ok).toBeFalse();
// Test with invalid property
result = await db.schema.check('clients/client1', { name: 'Ewout', url: '', email: '', wrong: 'not allowed' }, false);
expect(result.ok).toBeFalse();
// Test with wrong contact
result = await db.schema.check('clients/client1', { name: 'Ewout', url: '', email: '', contacts: 'none' }, false);
expect(result.ok).toBeFalse();
// Test with empty contacts
result = await db.schema.check('clients/client1', { name: 'Ewout', url: '', email: '', contacts: { } }, false);
expect(result).toEqual({ ok: true });
// Test with wrong contact item data type
result = await db.schema.check('clients/client1', { name: 'Ewout', url: '', email: '', contacts: { contact1: 'wrong contact' } }, false);
expect(result.ok).toBeFalse();
// Test with ok contact item
result = await db.schema.check('clients/client1', { name: 'Ewout', url: '', email: '', contacts: { contact1: { type: 'sales', name: 'John', email: '', telephone: '' } } }, false);
expect(result).toEqual({ ok: true });
// Test wrong contact item on target path
result = await db.schema.check('clients/client1/contacts/contact1', 'wrong contact', false);
expect(result.ok).toBeFalse();
// Test with ok contact item on target path
result = await db.schema.check('clients/client1/contacts/contact1', { type: 'sales', name: 'John', email: '', telephone: '' }, false);
expect(result).toEqual({ ok: true });
// Test updating a single property
result = await db.schema.check('clients/client1', { name: 'John' }, true);
expect(result).toEqual({ ok: true });
// Test removing a mandatory property
result = await db.schema.check('clients/client1', { name: null }, true);
expect(result.ok).toBeFalse();
// Test removing an optional property
result = await db.schema.check('clients/client1', { addresses: null }, true);
expect(result).toEqual({ ok: true });
// Test removing an unknown property
result = await db.schema.check('clients/client1', { unknown: null }, true);
expect(result).toEqual({ ok: true });
// Try using classnames & regular expressions
let emailRegex = /[a-z.\-_]+@(?:[a-z\-_]+\.){1,}[a-z]{2,}$/i;
clientSchema = {
name: String,
url: /^https:\/\//,
email: emailRegex,
"contacts?": {
"*": {
type: String,
name: String,
email: emailRegex,
telephone: /^\+[0-9\-]{10,}$/
}
},
"addresses?": {
"*": {
type: '"postal"|"visit"',
street: String,
nr: Number,
city: String,
"state?": String,
country: /^[A-Z]{2}$/,
}
}
};
// Overwrite previous schema
expect(() => db.schema.set('clients/*', clientSchema)).not.toThrow();
// Test valid input
result = await db.schema.check('clients/client1', { name: 'My client', url: 'https://client.com', email: 'info@client.com' }, false);
expect(result).toEqual({ ok: true });
// Test with empty email
result = await db.schema.check('clients/client1/email', '', false);
expect(result.ok).toBeFalse();
// Test with invalid email
result = await db.schema.check('clients/client1/email', 'not valid @address.com', false);
expect(result.ok).toBeFalse();
// Test with valid email
result = await db.schema.check('clients/client1/email', 'test@address.com', false);
expect(result).toEqual({ ok: true });
// Test valid address
result = await db.schema.check('clients/client1/addresses/address1', { type: 'visit', street: 'Main', nr: 253, city: 'Capital', country: 'NL' }, false);
expect(result).toEqual({ ok: true });
// Test invalid address type
result = await db.schema.check('clients/client1/addresses/address1', { type: 'invalid', street: 'Main', nr: 253, city: 'Capital', country: 'NL' }, false);
expect(result.ok).toBeFalse();
// Test invalid country (lowercase)
result = await db.schema.check('clients/client1/addresses/address1', { type: 'postal', street: 'Main', nr: 253, city: 'Capital', country: 'nl' }, false);
expect(result.ok).toBeFalse();
// Test updating property to valid value
result = await db.schema.check('clients/client1/addresses/address1', { country: 'NL' }, true);
expect(result).toEqual({ ok: true });
// Test updating property to invalid value
result = await db.schema.check('clients/client1/addresses/address1', { country: 'nl' }, true);
expect(result.ok).toBeFalse();
// Test updating target to valid value
result = await db.schema.check('clients/client1/addresses/address1/country', 'NL', true);
expect(result).toEqual({ ok: true });
// Test updating target to invalid value
result = await db.schema.check('clients/client1/addresses/address1/country', 'nl', true);
expect(result.ok).toBeFalse();
// Create new schema to test static values
const staticValuesSchema = {
"bool?": true,
"int?": 35,
"float?": 101.101
};
expect(() => db.schema.set('static', staticValuesSchema)).not.toThrow();
// Test valid boolean value:
result = await db.schema.check('static', { bool: true }, false);
expect(result).toEqual({ ok: true });
// Test invalid boolean value:
result = await db.schema.check('static', { bool: false }, false);
expect(result.ok).toBeFalse();
// Test valid int value:
result = await db.schema.check('static', { int: 35 }, false);
expect(result).toEqual({ ok: true });
// Test invalid int value:
result = await db.schema.check('static', { int: 2323 }, false);
expect(result.ok).toBeFalse();
// Test valid float value:
result = await db.schema.check('static', { float: 101.101 }, false);
expect(result).toEqual({ ok: true });
// Test invalid float value:
result = await db.schema.check('static', { float: 897.452 }, false);
expect(result.ok).toBeFalse();
});
it('type Object must allow any property', async() => {
const schema = 'Object';
expect(() => db.schema.set('generic-object', schema)).not.toThrow();
let result = await db.schema.check('generic-object', { custom: 'allowed' }, false);
expect(result).toEqual(ok);
result = await db.schema.check('generic-object/custom','allowed', false);
expect(result).toEqual(ok);
result = await db.schema.check('generic-object', 'NOT allowed', false);
expect(result.ok).toBeFalse();
});
// it('array of objects #127', async() => {
// // Created for #127 (https://github.com/appy-one/acebase/discussions/127)
// await db.schema.set('chats/$chatid',{
// id: 'string',
// messages:'{ message: string }[]'
// });
// const proxy = await db.ref('chats/chat1').proxy({ defaultValue: { id: 'chat1', messages: [] } });
// let promise = new Promise((resolve, reject) => {
// proxy.on('mutation', event => {
// resolve(event);
// });
// proxy.on('error', error => {
// reject(error);
// });
// });
// const chat = proxy.value;
// chat.messages.push({
// message: 'hello'
// });
// await expectAsync(promise).not.toBeRejected();
// }, 120e3);
afterAll(async () => {
await removeDB();
});
});