Skip to content

Commit

Permalink
Merge branch 'feature/PB-33454_Ensure-collection-v2-schema-is-validat…
Browse files Browse the repository at this point in the history
…ed-at-the-abstract-class-level' into 'develop'

PB-33454 - Ensure collection v2 schema is validated at the abstract class level

See merge request passbolt/passbolt-styleguide!1621
  • Loading branch information
cedricalfonsi committed May 14, 2024
2 parents 5543190 + 3d3a3c0 commit 6556d5a
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 14 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "passbolt-styleguide",
"version": "4.8.0-alpha.9",
"version": "4.8.0-alpha.10",
"license": "AGPL-3.0",
"copyright": "Copyright 2023 Passbolt SA",
"description": "Passbolt styleguide contains common styling assets used by the different sites, plugin, etc.",
Expand Down
21 changes: 16 additions & 5 deletions src/shared/models/entity/abstract/entityV2Collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import EntityValidationError from "./entityValidationError";
import EntityCollection from "./entityCollection";
import CollectionValidationError from "./collectionValidationError";
import EntityCollectionError from "./entityCollectionError";
import EntitySchema from "./entitySchema";

class EntityV2Collection extends EntityCollection {
/**
Expand All @@ -33,16 +34,26 @@ class EntityV2Collection extends EntityCollection {
* @throws {EntityCollectionError} If a item does not validate the collection validation build rules.
*/
constructor(dtos = [], options = {}) {
// Note: EntityCollection V1 will clone the dtos into the instance _props property. Delete it after usage.
super(dtos, options);
/*
* Push the items into the collection.
* Use the the _props property where EntityCollection V1 clone the dtos into.
* Delete it after usage.
*/
this._props = EntitySchema.validate(
this.constructor.name,
this._props,
this.constructor.getSchema()
);
this.pushMany(this._props, {...options, clone: false});
this._props = null;
}

/**
* Return the schema representing this collection.
* @return {object}
* @abstract
*/
static getSchema() {
throw new Error("The collection class should declare its schema.");
}

/**
* Build or clone entity.
* @param {object|Entity} data The data of the item to push
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
* @link https://www.passbolt.com Passbolt(tm)
* @since 4.7.0
*/
import EntitySchema from "./entitySchema";
import EntityV2Collection from "./entityV2Collection";
import {TestEntity} from "./entity.test.data";

Expand All @@ -20,11 +19,6 @@ export class TestEntityV2Collection extends EntityV2Collection {
return TestEntity;
}

constructor(dtos = [], options = {}) {
dtos = EntitySchema.validate(TestEntityV2Collection.name, dtos, TestEntityV2Collection.getSchema());
super(dtos, options);
}

/**
* Get the collection schema
* @returns {object}
Expand Down
52 changes: 52 additions & 0 deletions src/shared/models/entity/abstract/entityV2Collection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,17 @@ import CollectionValidationError from "./collectionValidationError";
import EntityValidationError from "./entityValidationError";
import {TestEntityV2Collection} from "./entityV2Collection.test.data";
import {defaultAssociatedTestEntityDto, defaultTestEntityDto, TestEntity} from "./entity.test.data";
import EntityV2Collection from "./entityV2Collection";

describe("EntityV2Collection", () => {
describe("EntityV2Collection:entityClass", () => {
// It is expected to throw an error but does not for an unexpected reason.
it.failing("should throw an exception if called to mimic its abstract nature", () => {
expect.assertions(1);
expect(() => EntityV2Collection.entityClass).toThrow();
});
});

describe("EntityV2Collection:buildOrCloneEntity", () => {
it("should throw an exception if the data parameter is not an object.", () => {
const collection = new TestEntityV2Collection([]);
Expand Down Expand Up @@ -52,6 +61,49 @@ describe("EntityV2Collection", () => {
});
});

describe("EntityV2Collection:constructor", () => {
it("should validate the collection schema.", () => {
expect.assertions(1);
expect(() => new TestEntityV2Collection({})).toThrowEntityValidationError("items");
});

it("should push the dtos given as parameter into the collection.", () => {
expect.assertions(10);
const entityDto1 = defaultTestEntityDto();
const entityDto2 = defaultTestEntityDto();
const entityDto3 = defaultTestEntityDto();
const dtos = [entityDto1, entityDto2, entityDto3];
const collection = new TestEntityV2Collection(dtos);
expect(collection.items).toHaveLength(3);
expect(collection.items[0]).toBeInstanceOf(TestEntity);
expect(collection.items[0].id).toEqual(entityDto1.id);
expect(collection.items[0].name).toEqual(entityDto1.name);
expect(collection.items[1]).toBeInstanceOf(TestEntity);
expect(collection.items[1].id).toEqual(entityDto2.id);
expect(collection.items[1].name).toEqual(entityDto2.name);
expect(collection.items[2]).toBeInstanceOf(TestEntity);
expect(collection.items[2].id).toEqual(entityDto3.id);
expect(collection.items[2].name).toEqual(entityDto3.name);
});

it("should delete the _props property.", () => {
expect.assertions(1);
const entityDto1 = defaultTestEntityDto();
const entityDto2 = defaultTestEntityDto();
const entityDto3 = defaultTestEntityDto();
const dtos = [entityDto1, entityDto2, entityDto3];
const collection = new TestEntityV2Collection(dtos);
expect(collection._props).toBeNull();
});
});

describe("EntityV2Collection:getSchema", () => {
it("should throw an exception if called to mimic its abstract nature", () => {
expect.assertions(1);
expect(() => EntityV2Collection.getSchema()).toThrow();
});
});

describe("EntityV2Collection:push", () => {
it("should throw an exception if the data parameter is not an object.", () => {
const collection = new TestEntityV2Collection([]);
Expand Down

0 comments on commit 6556d5a

Please sign in to comment.