domain-objects
Version:
A simple, convenient way to represent domain objects, leverage domain knowledge, and add runtime validation in your code base.
171 lines • 7.26 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const uuid_1 = require("uuid");
const assertDomainObjectIsSafeToManipulate_1 = require("../constraints/assertDomainObjectIsSafeToManipulate");
const DomainEntity_1 = require("../instantiation/DomainEntity");
const DomainLiteral_1 = require("../instantiation/DomainLiteral");
const DomainEntityUniqueKeysMustBeDefinedError_1 = require("./DomainEntityUniqueKeysMustBeDefinedError");
const getUniqueIdentifier_1 = require("./getUniqueIdentifier");
describe('getUniqueIdentifier', () => {
describe('literal', () => {
it('should be able to get unique identifier accurately', () => {
class Address extends DomainLiteral_1.DomainLiteral {
}
const address = new Address({
street: '123 Elm Street',
city: 'Austin',
state: 'TX',
postal: '78704',
});
const unique = (0, getUniqueIdentifier_1.getUniqueIdentifier)(address);
expect(unique).toEqual({
street: '123 Elm Street',
city: 'Austin',
state: 'TX',
postal: '78704',
});
});
it('should exclude uuid and id, if present, and custom metadata keys are not specified', () => {
class Address extends DomainLiteral_1.DomainLiteral {
}
const address = new Address({
id: 821,
uuid: '__UUID__',
street: '123 Elm Street',
city: 'Austin',
state: 'TX',
postal: '78704',
});
const unique = (0, getUniqueIdentifier_1.getUniqueIdentifier)(address);
expect(unique).toEqual({
street: '123 Elm Street',
city: 'Austin',
state: 'TX',
postal: '78704',
});
});
it('should exclude uuid and createdAt, if present, and custom metadata keys are specified', () => {
class Address extends DomainLiteral_1.DomainLiteral {
}
Address.metadata = ['uuid', 'createdAt'];
const address = new Address({
uuid: '__UUID__',
createdAt: '__NOW__',
street: '123 Elm Street',
city: 'Austin',
state: 'TX',
postal: '78704',
});
const unique = (0, getUniqueIdentifier_1.getUniqueIdentifier)(address);
expect(unique).toEqual({
street: '123 Elm Street',
city: 'Austin',
state: 'TX',
postal: '78704',
});
});
});
describe('entity', () => {
it('should be able to get unique identifier accurately', () => {
class RocketShip extends DomainEntity_1.DomainEntity {
}
RocketShip.unique = ['serialNumber'];
RocketShip.updatable = ['fuelQuantity', 'passengers'];
const ship = new RocketShip({
serialNumber: 'SN5',
fuelQuantity: 9001,
passengers: 21,
});
const uniqueIdentifier = (0, getUniqueIdentifier_1.getUniqueIdentifier)(ship);
expect(uniqueIdentifier).toEqual({ serialNumber: 'SN5' });
});
it('should throw an error if .unique is not defined on the entity', () => {
class RocketShip extends DomainEntity_1.DomainEntity {
}
const ship = new RocketShip({
serialNumber: 'SN5',
fuelQuantity: 9001,
passengers: 21,
});
try {
(0, getUniqueIdentifier_1.getUniqueIdentifier)(ship);
throw new Error('should not reach here');
}
catch (error) {
if (!(error instanceof Error))
throw error;
expect(error.message).toContain('`RocketShip.unique` must be defined, to be able to `getUniqueIdentifier`');
expect(error).toBeInstanceOf(DomainEntityUniqueKeysMustBeDefinedError_1.DomainEntityUniqueKeysMustBeDefinedError);
}
});
it('should be able to get unique identifier accurately', () => {
class SmartPhone extends DomainEntity_1.DomainEntity {
}
SmartPhone.unique = ['manufacturer', 'brand', 'model'];
SmartPhone.updatable = ['os', 'carrier'];
const phone = new SmartPhone({
uuid: '__UUID__',
manufacturer: 'Google',
brand: 'Pixel',
model: 'Pixel 3a',
os: 'Android',
carrier: 'Verizon',
});
const uniqueIdentifier = (0, getUniqueIdentifier_1.getUniqueIdentifier)(phone);
expect(uniqueIdentifier).toEqual({
manufacturer: 'Google',
brand: 'Pixel',
model: 'Pixel 3a',
});
});
// todo: restore this functionality when we decide how to specify it better
// it('should be able to get unique identifier accurately when it has more than one set of properties it is unique on', () => {
// interface RocketShip {
// serialNumber: string;
// federation: string;
// federationShipId: string; // e.g., the id of this ship inside of a third party system
// fuelQuantity: number;
// passengers: number;
// }
// class RocketShip extends DomainEntity<RocketShip> implements RocketShip {
// public static unique = [
// ['serialNumber'],
// ['federation', 'federationShipId'],
// ];
// public static updatable = ['fuelQuantity', 'passengers'];
// }
// const ship = new RocketShip({
// serialNumber: 'SN5',
// federation: 'Sol',
// federationShipId: 'earth:spacex:5',
// fuelQuantity: 9001,
// passengers: 21,
// });
// const uniqueIdentifier = getUniqueIdentifier(ship);
// expect(uniqueIdentifier).toEqual({
// serialNumber: 'SN5',
// federation: 'Sol',
// federationShipId: 'earth:spacex:5',
// }); // properties from all unique key sets should be included
// });
});
describe('safety', () => {
it('should throw an error if domain object is not safe to manipulate', () => {
class Plane extends DomainEntity_1.DomainEntity {
}
Plane.unique = ['uuid'];
const phone = new Plane({
uuid: (0, uuid_1.v4)(),
manufacturer: { name: 'boeing' },
passengerLimit: 821,
});
try {
(0, getUniqueIdentifier_1.getUniqueIdentifier)(phone);
}
catch (error) {
expect(error).toBeInstanceOf(assertDomainObjectIsSafeToManipulate_1.DomainObjectNotSafeToManipulateError);
}
});
});
});
//# sourceMappingURL=getUniqueIdentifier.test.js.map