src/Model/propertiesModel.test.js
import {PropertiesModel} from "./propertiesModel";
import {Model} from "./index";
import {default as deepEqual} from "deep-equal";
import {
basicModel, nestedModel, nestedModelDefault, nestedPatternModel, patternModel
} from "../../fixtures/PropertiesModel.schemas";
describe("PropertiesModel Class Suite", function () {
let _owner;
describe("Simple PropertiesModel Tests", () => {
beforeEach(() => {
_owner = new Model({schemas: [basicModel]});
});
describe("LifeCycle: Instantiation", () => {
it("should initialize a schema and a schema object", () => {
expect(_owner.model.$model).toBeDefined();
expect(_owner.model.$model instanceof PropertiesModel).toBe(true);
expect(_owner.model.$model).toBeDefined();
expect(_owner.model.$model instanceof PropertiesModel).toBe(true);
});
it("should not initialize a invalid schema and schema object", () => {
let badSchema = Object.assign({}, basicModel, {
properties: {
"bad thing": {
type: "INVALID",
},
},
});
expect(() => new Model({schemas: [badSchema]})).toThrow();
});
});
describe("LifeCycle: Creation", () => {
let _d;
it("should populate with valid data and make that data accessible", () => {
_d = {
name: "Ed Testy",
age: 99,
active: true,
};
_owner.model = _d;
expect(deepEqual(_owner.model, _d)).toBe(true);
});
it("should reject invalid data and leave model pristine", () => {
_d = {
name: "Ed Testy",
age: 99,
active: "123",
};
_owner.model = _d;
expect(deepEqual(_owner.model, {})).toBe(true);
});
});
describe("LifeCycle: Update", () => {
const _d = {
name: "Ed Testy",
age: 99,
active: true,
};
beforeEach(() => {
_owner.model = _d;
});
it("should update with valid data", () => {
_owner.model.active = false;
expect(deepEqual(_owner.model, _d)).toBe(false);
});
it("should reject invalid data update", () => {
_owner.model.active = "false";
expect(deepEqual(_owner.model, _d)).toBe(true);
});
});
});
describe("Nested PropertiesModel Tests", () => {
let _owner;
beforeEach(() => {
_owner = new Model({schemas: [nestedModel]});
});
describe("LifeCycle: Instantiation", () => {
it("should initialize a valid schema and a schema object", () => {
expect(_owner.model.$model).toBeDefined();
expect(_owner.model.$model instanceof PropertiesModel).toBe(true);
expect(_owner.model.$model).toBeDefined();
expect(_owner.model.$model instanceof PropertiesModel).toBe(true);
});
});
describe("LifeCycle: Create", () => {
let _d;
it("should populate with valid data and make that data accessible", () => {
_d = {
aObject: {
bObject: {
bValue: 1234,
},
},
};
_owner.model = _d;
expect(deepEqual(_owner.model, _d)).toBe(true);
expect(_owner.model.aObject.bObject.$model).toBeDefined();
expect(_owner.model.aObject.bObject.$model instanceof PropertiesModel).toBe(true)
});
it("should reject invalid data and leave model pristine", () => {
_d = {
aObject: {
bObject: {
bValue: "1234",
},
},
};
_owner.model = _d;
expect(deepEqual(_owner.model, {})).toBe(true);
});
});
describe("LifeCycle: Update", () => {
let _d;
it("should updated nested property models with valid data and pass validation", () => {
_d = {
aObject: {
bObject: {
bValue: 1234,
},
},
};
_owner.model = _d;
_d = {
bValue: 4321,
};
_owner.model.aObject.bObject = _d;
expect(_owner.errors).toBe(null);
expect(deepEqual(_owner.model.aObject.bObject, _d)).toBe(true);
});
});
describe("LifeCycle: Delete", () => {
let _d = {
aObject: {
bObject: {
bValue: 1234,
},
},
extraObject: {
someValue: "test",
},
};
it("should allow deletion of nested properties that are not required", () => {
_owner.model = _d;
expect(_owner.model.extraObject.someValue).toBe("test");
delete _owner.model.extraObject.someValue;
expect(_owner.errors).toBe(null);
expect(_owner.model.extraObject.someValue).toBe(void(0));
});
it("should prevent deletion of nested properties that are required", () => {
_owner.model = _d;
expect(_owner.model.aObject.bObject.bValue).toBe(1234);
delete _owner.model.aObject.bObject.bValue;
expect(typeof _owner.errors).toBe("object");
expect(_owner.model.aObject.bObject.bValue).toBe(1234);
});
});
});
describe("Nested Defaults PropertiesModel Tests", () => {
let _owner;
beforeEach(() => {
_owner = new Model({schemas: [nestedModelDefault]}, {ajvOptions: {useDefaults: true}});
});
it("should populate default values", () => {
const _d = {
aObject: {
bObject: {},
},
};
_owner.model = _d;
expect(_owner.model.aObject.bObject.bValue).toBe(123);
});
});
describe("Pattern Properties", () => {
let _owner;
beforeEach(() => {
_owner = new Model({schemas: [patternModel]}, {ajvOptions: {useDefaults: true}});
});
it("should allow pattern properties", () => {
_owner.model["test"] = "foo";
expect(`${_owner}`).toEqual("{}");
_owner.model["name"] = "foo";
expect(`${_owner}`).toEqual("{\"name\":\"foo\"}");
});
it("should accept multiple uses of patternProperty", () => {
_owner.model["name"] = "foo";
expect(`${_owner}`).toEqual("{\"name\":\"foo\"}");
_owner.model["name"] = "bar";
expect(`${_owner}`).toEqual("{\"name\":\"bar\"}");
});
});
describe("Nested Pattern Properties", () => {
let _owner;
beforeEach(() => {
_owner = new Model({schemas: [nestedPatternModel]}, {ajvOptions: {useDefaults: true}});
});
it("should allow nested pattern properties", () => {
_owner.model = {name: "test", nested: {test1: {foo: "bar"}}};
expect(`${_owner.model.nested.$model}`).toEqual("{\"test1\":{\"foo\":\"bar\"}}");
});
it("should accept multiple uses of patternProperty", () => {
_owner.model = {name: "test", nested: {test1: {foo1: "bar1"}}};
expect(`${_owner.model.nested.$model}`).toEqual("{\"test1\":{\"foo1\":\"bar1\"}}");
_owner.model.nested["test2"] = {foo2: "bar2"};
expect(`${_owner.model.nested.$model}`).toEqual("{\"test1\":{\"foo1\":\"bar1\"},\"test2\":{\"foo2\":\"bar2\"}}");
});
it("should reject subsequent invalid uses of patternProperty", () => {
_owner.model = {name: "test", nested: {test1: {foo1: "bar1"}}};
_owner.model.nested["test1"] = false;
expect(_owner.errors === null).toBe(false);
expect(`${_owner.errors[0].instancePath}`).toEqual("/test1");
expect(`${_owner.errors[0].message}`).toEqual("must be object");
});
});
});