domain-objects
Version:
A simple, convenient way to represent domain objects, leverage domain knowledge, and add runtime validation in your code base.
280 lines • 15.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const joi_1 = __importDefault(require("joi"));
const DomainEntity_1 = require("../instantiation/DomainEntity");
const DomainLiteral_1 = require("../instantiation/DomainLiteral");
const DomainEntityUniqueKeysMustBeDefinedError_1 = require("./DomainEntityUniqueKeysMustBeDefinedError");
const omitMetadataValues_1 = require("./omitMetadataValues");
describe('omitMetadataValues', () => {
describe('literal', () => {
class Tool extends DomainLiteral_1.DomainLiteral {
}
it('should correctly omit metadata values', () => {
// create an instance of it
const hammer = new Tool({
id: 821,
uuid: '__uuid__',
createdAt: 'yesterday',
name: 'Hammer',
make: 'Craftsman',
model: 'h1',
});
// check none of them are defined after omitting
const hammerWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(hammer);
expect(hammerWithoutMetadataValues.id).toEqual(undefined);
expect(hammerWithoutMetadataValues.uuid).toEqual(undefined);
expect(hammerWithoutMetadataValues.createdAt).toEqual(undefined);
// check that resulting object is still an instance of the literal
expect(hammerWithoutMetadataValues).toBeInstanceOf(Tool);
// check that the rest of the values are still accurate
expect(Object.assign(Object.assign({}, hammer), { id: undefined, uuid: undefined, createdAt: undefined })).toEqual(hammerWithoutMetadataValues);
});
it('should correctly omit metadata values, even if not all metadata values are defined - e.g., id, nothing else', () => {
// create an instance of it
const hammer = new Tool({
id: 821,
name: 'Hammer',
make: 'Craftsman',
model: 'h1',
});
// check none of them are defined after omitting
const hammerWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(hammer);
expect(hammerWithoutMetadataValues.id).toEqual(undefined);
expect(hammerWithoutMetadataValues.uuid).toEqual(undefined);
expect(hammerWithoutMetadataValues.createdAt).toEqual(undefined);
// check that resulting object is still an instance of the literal
expect(hammerWithoutMetadataValues).toBeInstanceOf(Tool);
// check that the rest of the values are still accurate
expect(Object.assign(Object.assign({}, hammer), { id: undefined })).toEqual(hammerWithoutMetadataValues);
});
it('should correctly omit metadata values, even if not all metadata values are defined - e.g., none of them are', () => {
// create an instance of it
const hammer = new Tool({
name: 'Hammer',
make: 'Craftsman',
model: 'h1',
});
// check none of them are defined after omitting
const hammerWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(hammer);
expect(hammerWithoutMetadataValues.id).toEqual(undefined);
expect(hammerWithoutMetadataValues.uuid).toEqual(undefined);
expect(hammerWithoutMetadataValues.createdAt).toEqual(undefined);
// check that resulting object is still an instance of the literal
expect(hammerWithoutMetadataValues).toBeInstanceOf(Tool);
// check that the rest of the values are still accurate
expect(hammer).toEqual(hammerWithoutMetadataValues);
});
});
describe('entity', () => {
class Booster extends DomainEntity_1.DomainEntity {
}
Booster.unique = ['name']; // for the test, we just care that its unique on anything
it('should correctly omit metadata values', () => {
// instantiate the entity
const booster = new Booster({
id: 821,
uuid: '__UUID__',
createdAt: '__last_year__',
updatedAt: '__today__',
effectiveAt: '__yesterday__',
name: 'pointy end up',
timesLaunched: 21,
engineVersion: 'v0.7.1',
status: 'preparing',
});
// check none of them are defined after omitting
const boosterWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(booster);
expect(boosterWithoutMetadataValues.id).toBeUndefined();
expect(boosterWithoutMetadataValues.uuid).toBeUndefined();
expect(boosterWithoutMetadataValues.createdAt).toBeUndefined();
expect(boosterWithoutMetadataValues.updatedAt).toBeUndefined();
expect(boosterWithoutMetadataValues.effectiveAt).toBeUndefined();
// check that resulting object is still an instance of the literal
expect(boosterWithoutMetadataValues).toBeInstanceOf(Booster);
// check that the rest of the values are still accurate
expect(Object.assign(Object.assign({}, booster), { id: undefined, uuid: undefined, createdAt: undefined, updatedAt: undefined, effectiveAt: undefined })).toEqual(boosterWithoutMetadataValues);
});
it('should correctly omit metadata values from an array of dobjs', () => {
// instantiate the entity
const booster = new Booster({
id: 821,
uuid: '__UUID__',
createdAt: '__last_year__',
updatedAt: '__today__',
effectiveAt: '__yesterday__',
name: 'pointy end up',
timesLaunched: 21,
engineVersion: 'v0.7.1',
status: 'preparing',
});
// check none of them are defined after omitting
const boosterWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)([booster]);
expect(boosterWithoutMetadataValues[0].id).toBeUndefined();
expect(boosterWithoutMetadataValues[0].uuid).toBeUndefined();
expect(boosterWithoutMetadataValues[0].createdAt).toBeUndefined();
expect(boosterWithoutMetadataValues[0].updatedAt).toBeUndefined();
expect(boosterWithoutMetadataValues[0].effectiveAt).toBeUndefined();
// check that resulting object is still an instance of the literal
expect(boosterWithoutMetadataValues[0]).toBeInstanceOf(Booster);
// check that the rest of the values are still accurate
expect(Object.assign(Object.assign({}, booster), { id: undefined, uuid: undefined, createdAt: undefined, updatedAt: undefined, effectiveAt: undefined })).toEqual(boosterWithoutMetadataValues[0]);
});
it('should correctly omit metadata values, even if not all metadata values are defined - e.g., id, nothing else', () => {
// instantiate the entity
const booster = new Booster({
id: 821,
name: 'pointy end up',
timesLaunched: 21,
engineVersion: 'v0.7.1',
status: 'preparing',
});
// check none of them are defined after omitting
const boosterWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(booster);
expect(boosterWithoutMetadataValues.id).toBeUndefined();
expect(boosterWithoutMetadataValues.uuid).toBeUndefined();
expect(boosterWithoutMetadataValues.createdAt).toBeUndefined();
expect(boosterWithoutMetadataValues.updatedAt).toBeUndefined();
expect(boosterWithoutMetadataValues.effectiveAt).toBeUndefined();
// check that resulting object is still an instance of the literal
expect(boosterWithoutMetadataValues).toBeInstanceOf(Booster);
// check that the rest of the values are still accurate
expect(Object.assign(Object.assign({}, booster), { id: undefined })).toEqual(boosterWithoutMetadataValues);
});
it('should correctly omit metadata values, even if not all metadata values are defined - e.g., none of them are', () => {
// instantiate the entity
const booster = new Booster({
name: 'pointy end up',
timesLaunched: 21,
engineVersion: 'v0.7.1',
status: 'preparing',
});
// check none of them are defined after omitting
const boosterWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(booster);
expect(boosterWithoutMetadataValues.id).toBeUndefined();
expect(boosterWithoutMetadataValues.uuid).toBeUndefined();
expect(boosterWithoutMetadataValues.createdAt).toBeUndefined();
expect(boosterWithoutMetadataValues.updatedAt).toBeUndefined();
expect(boosterWithoutMetadataValues.effectiveAt).toBeUndefined();
// check that resulting object is still an instance of the literal
expect(boosterWithoutMetadataValues).toBeInstanceOf(Booster);
// check that the rest of the values are still accurate
expect(booster).toEqual(boosterWithoutMetadataValues);
});
it('should correctly _not_ omit the uuid, if uuid is part of the unique keys', () => {
class LotOwner extends DomainEntity_1.DomainEntity {
}
LotOwner.unique = ['uuid']; // lot owner is unique on uuid, meaning its not metadata
// instantiate the entity
const owner = new LotOwner({
id: 721,
uuid: '__uuid__',
name: 'billy bob',
phone: '5555555555',
});
// check none of them are defined after omitting
const ownerWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(owner);
expect(ownerWithoutMetadataValues.id).toBeUndefined();
expect(ownerWithoutMetadataValues.uuid).toBeDefined();
// check that resulting object is still an instance of the entity
expect(owner).toBeInstanceOf(LotOwner);
// check that the rest of the values are still accurate
expect(Object.assign(Object.assign({}, owner), { id: undefined })).toEqual(ownerWithoutMetadataValues);
});
it('should correctly _not_ omit the uuid and still instantiate, if uuid is part of the unique keys and schema is defined', () => {
const schema = joi_1.default.object().keys({
id: joi_1.default.number().optional(),
uuid: joi_1.default.string().required(),
name: joi_1.default.string().required(),
phone: joi_1.default.string().required(),
});
class LotOwner extends DomainEntity_1.DomainEntity {
}
LotOwner.schema = schema;
LotOwner.unique = ['uuid']; // lot owner is unique on uuid, meaning its not metadata
// instantiate the entity
const owner = new LotOwner({
id: 721,
uuid: '__uuid__',
name: 'billy bob',
phone: '5555555555',
});
// check none of them are defined after omitting
const ownerWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(owner);
expect(ownerWithoutMetadataValues.id).toBeUndefined();
expect(ownerWithoutMetadataValues.uuid).toBeDefined();
// check that resulting object is still an instance of the entity
expect(owner).toBeInstanceOf(LotOwner);
// check that the rest of the values are still accurate
expect(Object.assign(Object.assign({}, owner), { id: undefined })).toEqual(ownerWithoutMetadataValues);
});
it('should throw an error if an entity was defined without the unique property being defined, as we cant figure out what the metadata values are otherwise', () => {
class LotDweller extends DomainEntity_1.DomainEntity {
}
// instantiate the entity
const dweller = new LotDweller({
id: 721,
uuid: '__uuid__',
name: 'billy bob',
phone: '5555555555',
});
// check that error is thrown, because we cant figure out whether uuid is metadata or not in this case
try {
(0, omitMetadataValues_1.omitMetadataValues)(dweller);
throw new Error('should not reach here');
}
catch (error) {
if (!(error instanceof Error))
throw error;
expect(error.message).toContain('`LotDweller.unique` must be defined, to be able to `omitMetadataValues`');
expect(error).toBeInstanceOf(DomainEntityUniqueKeysMustBeDefinedError_1.DomainEntityUniqueKeysMustBeDefinedError);
}
});
});
describe('nested', () => {
it('should correctly omit metadata of domain literals nested inside of domain entities', () => __awaiter(void 0, void 0, void 0, function* () {
class Address extends DomainLiteral_1.DomainLiteral {
}
class Photo extends DomainLiteral_1.DomainLiteral {
}
class SpacePort extends DomainEntity_1.DomainEntity {
}
SpacePort.unique = ['address']; // lot owner is unique on the address
SpacePort.nested = { address: Address, photos: Photo };
const starbase = new SpacePort({
id: 821,
uuid: '__uuid__',
name: 'starbase',
address: new Address({
id: 721,
uuid: '__uuid__',
city: 'Boca Chica',
state: 'Texas',
country: 'United States of America',
continent: 'America',
planet: 'Earth',
}),
photos: [new Photo({ id: 1, uuid: '__uuid__', url: 'https://...' })],
});
const starbaseWithoutMetadataValues = (0, omitMetadataValues_1.omitMetadataValues)(starbase);
expect(starbaseWithoutMetadataValues.id).toBeUndefined();
expect(starbaseWithoutMetadataValues.uuid).toBeUndefined();
expect(starbaseWithoutMetadataValues.address.id).toBeUndefined();
expect(starbaseWithoutMetadataValues.address.uuid).toBeUndefined();
expect(starbaseWithoutMetadataValues.photos[0].id).toBeUndefined();
expect(starbaseWithoutMetadataValues.photos[0].uuid).toBeUndefined();
}));
});
});
//# sourceMappingURL=omitMetadataValues.test.js.map