Skip to content

Commit

Permalink
PB-33454 - Ensure collection v2 schema is validated at the abstract c…
Browse files Browse the repository at this point in the history
…lass level

Signed-off-by: Cedric Alfonsi <cedric@passbolt.com>
  • Loading branch information
cedricalfonsi committed May 14, 2024
1 parent 5543190 commit c37c2e8
Show file tree
Hide file tree
Showing 5 changed files with 55 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() {
return {};
}

/**
* 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
36 changes: 36 additions & 0 deletions src/shared/models/entity/abstract/entityV2Collection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,42 @@ 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:push", () => {
it("should throw an exception if the data parameter is not an object.", () => {
const collection = new TestEntityV2Collection([]);
Expand Down

0 comments on commit c37c2e8

Please sign in to comment.