UNPKG

@herbsjs/gotu

Version:

Domain entities javascript library.

371 lines (334 loc) 15.7 kB
const { entity } = require('../../src/entity') const { field } = require('../../src/field') const assert = require('assert') const { BaseEntity } = require('../../src/baseEntity') describe('An entity', () => { const givenAnEntityToBeUsedAsType = entity('An entity type', { f1: field(Boolean), f2: field(String) }) describe('should deserialize', () => { const givenAnEntityToReceiveObject = () => { const EntityType = givenAnEntityToBeUsedAsType const AnEntity = entity('An entity', { field1: field(Number), field2: field(String), field3: field(Date), field4: field(Boolean), field5: field(EntityType), field6: field([EntityType]), field7: field(Number), method1() { return 10 } }) return AnEntity } it('valid data from an object', () => { //given const AnEntity = givenAnEntityToReceiveObject() //when const instance = AnEntity.fromJSON({ field1: 1, field2: "1", field3: new Date('2019-09-30T23:45:34.324Z'), field4: true, field5: { f1: true, f2: "2" }, field6: [{ f1: true, f2: "2" }], field7: null, field8: "Nothing", method1() { return "Nada" }, method2() { return "Niente" } }) //then assert.strictEqual(instance['field1'], 1) assert.strictEqual(instance['field2'], "1") assert.deepStrictEqual(instance['field3'], new Date('2019-09-30T23:45:34.324Z')) assert.strictEqual(instance['field4'], true) assert(instance['field5'] instanceof BaseEntity) assert.strictEqual(instance['field5']['f1'], true) assert.strictEqual(instance['field5']['f2'], "2") assert.strictEqual(instance['field6'][0]['f1'], true) assert.strictEqual(instance['field6'][0]['f2'], "2") assert.strictEqual(instance['field7'], null) assert.strictEqual(instance['field8'], undefined) assert(instance['method1'] instanceof Function) assert.strictEqual(instance.method1(), 10) assert.strictEqual(instance['method2'], undefined) assert.strictEqual(instance.isValid(), true) assert.deepStrictEqual(instance.errors, {}) }) it('valid data from a JSON string', () => { //given const AnEntity = givenAnEntityToReceiveObject() //when const instance = AnEntity.fromJSON(`{ "field1": 1, "field2": "1", "field3": "${new Date('2019-09-30T23:45:00.000Z')}", "field4": true, "field5": {"f1": true, "f2": "2"}, "field6": [{"f1": true, "f2": "2"}], "field7": null, "field8": "Nothing" }`) //then assert.strictEqual(instance['field1'], 1) assert.strictEqual(instance['field2'], "1") assert.deepStrictEqual(instance['field3'], new Date('2019-09-30T23:45:00.000Z')) assert.strictEqual(instance['field4'], true) assert(instance['field5'] instanceof BaseEntity) assert.strictEqual(instance['field5']['f1'], true) assert.strictEqual(instance['field5']['f2'], "2") assert.strictEqual(instance['field6'][0]['f1'], true) assert.strictEqual(instance['field6'][0]['f2'], "2") assert.strictEqual(instance['field7'], null) assert.strictEqual(instance['field8'], undefined) assert(instance['method1'] instanceof Function) assert.strictEqual(instance['method2'], undefined) assert.strictEqual(instance.isValid(), true) assert.deepStrictEqual(instance.errors, {}) }) it('invalid data from an object', () => { //given const AnEntity = givenAnEntityToReceiveObject() //when const instance = AnEntity.fromJSON({ field1: "1", field2: 1, field3: true, field4: new Date('2019-09-30T23:45:34.324Z'), field5: { f1: 2, f2: false }, field6: [{ f1: 2, f2: false }], field7: null, field8: undefined, method2() { return "Nada" } }) //then assert.strictEqual(instance['field1'], "1") assert.strictEqual(instance['field2'], 1) assert.deepStrictEqual(instance['field3'], new Date('1970-01-01T00:00:00.001Z')) // true parsed as Date assert.deepStrictEqual(instance['field4'], new Date('2019-09-30T23:45:34.324Z')) assert(instance['field5'] instanceof BaseEntity) assert.strictEqual(instance['field5']['f1'], 2) assert.strictEqual(instance['field5']['f2'], false) assert.strictEqual(instance['field6'][0]['f1'], 2) assert.strictEqual(instance['field6'][0]['f2'], false) assert.strictEqual(instance['field7'], null) assert.strictEqual(instance['field8'], undefined) assert(instance['method1'] instanceof Function) assert.strictEqual(instance['method2'], undefined) assert.strictEqual(instance.isValid(), false) assert.strictEqual(Object.keys(instance.errors).length, 5) }) it('valid data from empty JSON string', () => { //given const AnEntity = givenAnEntityToReceiveObject() //when const instance = AnEntity.fromJSON(`{}`) //then assert.strictEqual(instance['field1'], undefined) assert.strictEqual(instance['field2'], undefined) assert.deepStrictEqual(instance['field3'], undefined) assert.strictEqual(instance['field4'], undefined) assert.strictEqual(instance['field5'], undefined) assert.strictEqual(instance['field6'], undefined) assert(instance['method1'] instanceof Function) assert.strictEqual(instance.isValid(), true) assert.deepStrictEqual(instance.errors, {}) }) it('should allow extra fields from JSON', () => { //given const AnEntity = givenAnEntityToReceiveObject() //when const instance = AnEntity.fromJSON({ field1: 1, field2: "1", field3: new Date('2019-09-30T23:45:34.324Z'), field4: true, field5: { f1: true, f2: "2" }, field6: [{ f1: true, f2: "2" }], field7: null, field1x: 1, field2x: "1", field3x: new Date('2019-09-30T23:45:34.324Z'), field4x: true, field5x: { f1: true, f2: "2" }, field6x: [{ f1: true, f2: "2" }], field7x: null, method1() { return "Nada" }, method2() { return "Niente" } }, { allowExtraKeys: true }) //then assert.strictEqual(instance['field1'], 1) assert.strictEqual(instance['field2'], "1") assert.deepStrictEqual(instance['field3'], new Date('2019-09-30T23:45:34.324Z')) assert.strictEqual(instance['field4'], true) assert(instance['field5'] instanceof BaseEntity) assert.strictEqual(instance['field5']['f1'], true) assert.strictEqual(instance['field5']['f2'], "2") assert.strictEqual(instance['field6'][0]['f1'], true) assert.strictEqual(instance['field6'][0]['f2'], "2") assert.strictEqual(instance['field7'], null) assert.strictEqual(instance['field8'], undefined) assert.strictEqual(instance['field1x'], 1) assert.strictEqual(instance['field2x'], "1") assert.deepStrictEqual(instance['field3x'], new Date('2019-09-30T23:45:34.324Z')) assert.strictEqual(instance['field4x'], true) assert.deepStrictEqual(instance['field5x'], { f1: true, f2: "2" }) assert.deepStrictEqual(instance['field6x'], [{ f1: true, f2: "2" }]) assert.strictEqual(instance['field7x'], null) assert.strictEqual(instance['field8x'], undefined) assert(instance['method1'] instanceof Function) assert.strictEqual(instance.method1(), 10) assert(instance['method2'] instanceof Function) assert.strictEqual(instance.method2(), 'Niente') assert.strictEqual(instance.isValid(), true) assert.deepStrictEqual(instance.errors, {}) }) }) describe('should serialize', () => { const givenAnEntityToBuildAJSON = () => { const EntityType = givenAnEntityToBeUsedAsType const AnEntity = entity('A entity', { field1: field(Number), field2: field(String), field3: field(Date), field4: field(Boolean), field5: field(EntityType), field6: field([EntityType]), method1() { return 10 } }) return AnEntity } const givenAnEntityToBuildAJSONWithArraysOfPrimitiveType = () => { const EntityType = givenAnEntityToBeUsedAsType const AnEntity = entity('A entity', { field1: field([Number]), field2: field([String]), field3: field([Object]), field4: field([Date]), field5: field([Boolean]), field6: field([EntityType]), }) return AnEntity } it('valid data to JSON', () => { //given const AnEntity = givenAnEntityToBuildAJSON() const AnTypeEntity = givenAnEntityToBeUsedAsType const instance = new AnEntity() instance.field1 = 1 instance.field2 = "1" instance.field3 = new Date('2019-09-30T23:45:34.324Z') instance.field4 = true instance.field5 = new AnTypeEntity() instance.field5.f1 = true instance.field5.f2 = "2" instance.field6 = [] instance.field6.push({ f1: true, f2: "2" }) //when instance.validate() const json = JSON.stringify(instance) //then assert.deepStrictEqual(json, '{"field1":1,"field2":"1","field3":"2019-09-30T23:45:34.324Z","field4":true,"field5":{"f1":true,"f2":"2"},"field6":[{"f1":true,"f2":"2"}]}') }) it('valid data to JSON - allow extra keys', () => { //given const AnEntity = givenAnEntityToBuildAJSON() const AnTypeEntity = givenAnEntityToBeUsedAsType const instance = new AnEntity() instance.field1 = 1 instance.field2 = "1" instance.field3 = new Date('2019-09-30T23:45:34.324Z') instance.field4 = true instance.field5 = new AnTypeEntity() instance.field5.f1 = true instance.field5.f2 = "2" instance.field6 = [AnTypeEntity.fromJSON({ f1: true, f2: "2" }), AnTypeEntity.fromJSON({ f1: false, f2: "3" })] instance.field1x = 1 instance.field2x = "1" instance.field3x = new Date('2019-09-30T23:45:34.324Z') instance.field4x = true instance.field5x = { f1: true, f2: "2" } instance.field6x = [{ f1: true, f2: "2" }] //when instance.validate() const json = JSON.stringify(instance.toJSON({ allowExtraKeys: true })) //then assert.deepStrictEqual(json, '{"field1":1,"field2":"1","field3":"2019-09-30T23:45:34.324Z","field4":true,"field5":{"f1":true,"f2":"2","errors":{}},"field6":[{"f1":true,"f2":"2","errors":{}},{"f1":false,"f2":"3","errors":{}}],"field1x":1,"field2x":"1","field3x":"2019-09-30T23:45:34.324Z","field4x":true,"field5x":{"f1":true,"f2":"2"},"field6x":[{"f1":true,"f2":"2"}],"errors":{}}') }) it('valid data to JSON - primitive type arrays', () => { //given const AnEntity = givenAnEntityToBuildAJSONWithArraysOfPrimitiveType() const instance = new AnEntity() const AnTypeEntity = givenAnEntityToBeUsedAsType instance.field1 = [1, 2] instance.field2 = ["testing", "primitive"] instance.field3 = [{ f1: true, f2: "2" }] instance.field4 = [new Date('2019-09-30T23:45:34.324Z'), new Date('2019-09-30T23:45:34.324Z')], instance.field5 = [true, false], instance.field6 = [new AnTypeEntity(), new AnTypeEntity()] //when instance.validate() const json = JSON.stringify(instance.toJSON({ allowExtraKeys: true })) //then assert.deepStrictEqual( json, '{"field1":[1,2],"field2":["testing","primitive"],"field3":[{"f1":true,"f2":"2"}],"field4":["2019-09-30T23:45:34.324Z","2019-09-30T23:45:34.324Z"],"field5":[true,false],"field6":[{"errors":{}},{"errors":{}}],"errors":{}}' ) }) it('invalid data to JSON', () => { //given const AnEntity = givenAnEntityToBuildAJSON() const AnTypeEntity = givenAnEntityToBeUsedAsType const instance = new AnEntity() instance.field1 = "1" instance.field2 = 1 instance.field3 = 1 instance.field4 = 1 instance.field5 = new AnTypeEntity() instance.field5.f1 = 2 instance.field5.f2 = true instance.field6 = [] instance.field6.push({ f1: 2, f2: true }) //when instance.validate() const json = JSON.stringify(instance) //then assert.deepStrictEqual(json, '{"field1":"1","field2":1,"field3":1,"field4":1,"field5":{"f1":2,"f2":true},"field6":[{"f1":2,"f2":true}]}') }) it('invalid data to JSON - allow extra keys', () => { //given const AnEntity = givenAnEntityToBuildAJSON() const instance = new AnEntity() instance.field2 = 1 //when instance.validate() const json = JSON.stringify(instance.toJSON({ allowExtraKeys: true })) //then assert.deepStrictEqual(json, '{"field2":1,"errors":{"field2":[{"wrongType":"String"}]}}') }) it('invalid data to JSON - primitive type arrays', () => { //given const AnEntity = givenAnEntityToBuildAJSONWithArraysOfPrimitiveType() const instance = new AnEntity() instance.field1 = [1,2] instance.field2 = [1] //when instance.validate() const json = JSON.stringify(instance.toJSON()) //then assert.deepStrictEqual( json, '{"field1":[1,2],"field2":[1]}' ) assert.deepStrictEqual(instance.errors, { field2: [ { wrongType: ["String"], }, ], }) }) }) })