text: /**
   * Passbolt ~ Open source password manager for teams
   * Copyright (c) Passbolt SA (https://www.passbolt.com)
   *
   * Licensed under GNU Affero General Public License version 3 of the or any later version.
   * For full copyright and license information, please see the LICENSE.txt
   * Redistributions of files must retain the above copyright notice.
   *
   * @copyright     Copyright (c) Passbolt SA (https://www.passbolt.com)
   * @license       https://opensource.org/licenses/AGPL-3.0 AGPL License
   * @link          https://www.passbolt.com Passbolt(tm)
   * @since         2.13.0
   */
  import {PermissionChangesCollection} from "./permissionChangesCollection";
  import {EntitySchema} from "../abstract/entitySchema";
  import Validator from 'validator';
  import {PermissionEntity} from "./permissionEntity";
  import {PermissionsCollection} from "./permissionsCollection";
  
  // Reset the modules before each test.
  beforeEach(() => {
    window.Validator = Validator;
    jest.resetModules();
  });
  
  describe("PermissionChangesCollection", () => {
    it("schema must validate", () => {
      EntitySchema.validateSchema(PermissionChangesCollection.ENTITY_NAME, PermissionChangesCollection.getSchema());
    });
  
    it("allow filter by aco foreign key", () => {
      const changesDto = [{
        aco: "Folder",
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: "User",
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d994",
        is_new: true,
        type: 1
      }, {
        aco: "Folder",
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: "User",
        aro_foreign_key: "640ebc06-5ec1-5322-a1ae-6120ed2f3a74",
        created: "2020-05-02T22:50:42+00:00",
        delete: true,
        id: "f639e57e-6aaa-4bd8-bb3a-7ea21a2ac44e",
        modified: "2020-05-02T22:50:42+00:00",
        type: 1
      }, {
        aco: "Folder",
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: "User",
        aro_foreign_key: "f848277c-5398-58f8-a82a-72397af2d450",
        created: "2020-05-02T22:48:37+00:00",
        id: "cd899aee-5431-45a9-a6ea-8483bf342146",
        modified: "2020-05-02T22:48:37+00:00",
        type: 7
      }];
      const changeEntity = new PermissionChangesCollection(changesDto);
      expect(changeEntity.filterByAcoForeignKey("c2c7f658-c7ac-4d73-9020-9d2c296d91ff").length).toBe(3);
      expect(changeEntity.toDto().length).toBe(3);
    });
  
    it("calculateChanges basics", () => {
      const originalSet = new PermissionsCollection([{
        id: "c2c7f658-c7ac-4d73-9020-9d2c296d9100",
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d990",
        type: PermissionEntity.PERMISSION_OWNER
      }, {
        id: "c2c7f658-c7ac-4d73-9020-9d2c296d9101",
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d991",
        type: PermissionEntity.PERMISSION_UPDATE
      }, {
        id: "c2c7f658-c7ac-4d73-9020-9d2c296d9102",
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d992",
        type: PermissionEntity.PERMISSION_READ
      },{
        id: "c2c7f658-c7ac-4d73-9020-9d2c296d9103",
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d993",
        type: PermissionEntity.PERMISSION_READ
      }]);
  
      // Delete first one
      // Downgrade second one
      // Upgrade third one
      // Let fourth one
      // Add five one
      const expectedSet = new PermissionsCollection([{
        id: "c2c7f658-c7ac-4d73-9020-9d2c296d9101",
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d991",
        type: PermissionEntity.PERMISSION_READ
      }, {
        id: "c2c7f658-c7ac-4d73-9020-9d2c296d9102",
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d992",
        type: PermissionEntity.PERMISSION_UPDATE
      }, {
        id: "c2c7f658-c7ac-4d73-9020-9d2c296d9103",
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d993",
        type: PermissionEntity.PERMISSION_READ
      },{
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: "c2c7f658-c7ac-4d73-9020-9d2c296d91ff",
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: "54c6278e-f824-5fda-91ff-3e946b18d994",
        type: PermissionEntity.PERMISSION_OWNER
      }]);
  
      const changes = PermissionChangesCollection.calculateChanges(originalSet, expectedSet);
      expect(changes.toDto()).toEqual([{
          id: 'c2c7f658-c7ac-4d73-9020-9d2c296d9101',
          aco: 'Folder',
          aro: 'User',
          aco_foreign_key: 'c2c7f658-c7ac-4d73-9020-9d2c296d91ff',
          aro_foreign_key: '54c6278e-f824-5fda-91ff-3e946b18d991',
          type: 1
        }, {
          id: 'c2c7f658-c7ac-4d73-9020-9d2c296d9102',
          aco: 'Folder',
          aro: 'User',
          aco_foreign_key: 'c2c7f658-c7ac-4d73-9020-9d2c296d91ff',
          aro_foreign_key: '54c6278e-f824-5fda-91ff-3e946b18d992',
          type: 7
        }, {
          aco: 'Folder',
          aro: 'User',
          aco_foreign_key: 'c2c7f658-c7ac-4d73-9020-9d2c296d91ff',
          aro_foreign_key: '54c6278e-f824-5fda-91ff-3e946b18d994',
          type: 15
        }, {
          id: 'c2c7f658-c7ac-4d73-9020-9d2c296d9100',
          delete: true,
          aco: 'Folder',
          aro: 'User',
          aco_foreign_key: 'c2c7f658-c7ac-4d73-9020-9d2c296d91ff',
          aro_foreign_key: '54c6278e-f824-5fda-91ff-3e946b18d990',
          type: 15
        }
      ]);
    });
  
    it("reuse changes works - part1 deletion", () => {
      let permissions;
      let changes;
      let original;
      let result;
      let resource1 = "c2c7f658-c7ac-4d73-9020-9d2c296d91ff";
      let user1 = "54c6278e-f824-5fda-91ff-3e946b18d990";
      let user2 = "54c6278e-f824-5fda-91ff-3e946b18d991";
      let folder1 = "640ebc06-5ec1-5322-a1ae-6120ed2f3a74";
      let permission1 = "c2c7f658-c7ac-4d73-9020-9d2c296d9100";
      let permission2 = "c2c7f658-c7ac-4d73-9020-9d2c296d9101";
      let permission3 = "c2c7f658-c7ac-4d73-9020-9d2c296d9102";
  
      // permission is not present and change is a delete
      permissions = new PermissionsCollection([{
        id: permission1,
        aco: PermissionEntity.ACO_RESOURCE,
        aco_foreign_key: resource1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user1,
        type: PermissionEntity.PERMISSION_OWNER
      }]);
      changes = new PermissionChangesCollection([{
        id: permission2,
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user1,
        delete: true,
        type: PermissionEntity.PERMISSION_READ
      },{
        id: permission3,
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user2,
        delete: true,
        type: PermissionEntity.PERMISSION_OWNER
      }]);
      original = new PermissionsCollection([], false);
      result = PermissionChangesCollection.reuseChanges(
        PermissionEntity.ACO_RESOURCE, resource1, permissions, changes, original
      );
      expect(result.length).toBe(0);
  
      // permission is present and change is a delete
      changes = new PermissionChangesCollection([{
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user1,
        delete: true,
        type: PermissionEntity.PERMISSION_OWNER
      }]);
      result = PermissionChangesCollection.reuseChanges(
        PermissionEntity.ACO_RESOURCE, resource1, permissions, changes, original
      );
      expect(result.length).toBe(1);
      expect(result.items[0].acoForeignKey).toBe(resource1);
      expect(result.items[0].aroForeignKey).toBe(user1);
    });
  
    it("reuse changes works - part2 create", () => {
      let permissions;
      let changes;
      let original;
      let result;
      let resource1 = "c2c7f658-c7ac-4d73-9020-9d2c296d91ff";
      let user1 = "54c6278e-f824-5fda-91ff-3e946b18d990";
      let user2 = "54c6278e-f824-5fda-91ff-3e946b18d991";
      let folder1 = "640ebc06-5ec1-5322-a1ae-6120ed2f3a74";
      let permission1 = "c2c7f658-c7ac-4d73-9020-9d2c296d9100";
  
      permissions = new PermissionsCollection([{
        id: permission1,
        aco: PermissionEntity.ACO_RESOURCE,
        aco_foreign_key: resource1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user1,
        type: PermissionEntity.PERMISSION_OWNER
      }]);
      changes = new PermissionChangesCollection([{
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user1,
        type: PermissionEntity.PERMISSION_UPDATE
      },{
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user2,
        type: PermissionEntity.PERMISSION_OWNER
      }]);
      original = new PermissionsCollection([], false);
      result = PermissionChangesCollection.reuseChanges(
        PermissionEntity.ACO_RESOURCE, resource1, permissions, changes, original
      );
      expect(result.length).toBe(1);
      expect(result.items[0].acoForeignKey).toBe(resource1);
      expect(result.items[0].aroForeignKey).toBe(user2);
    });
  
    it("reuse changes works - part3 update", () => {
      let permissions;
      let changes;
      let original;
      let result;
      let resource1 = "c2c7f658-c7ac-4d73-9020-9d2c296d91ff";
      let user1 = "54c6278e-f824-5fda-91ff-3e946b18d990";
      let user2 = "54c6278e-f824-5fda-91ff-3e946b18d991";
      let user3 = "54c6278e-f824-5fda-91ff-3e946b18d992";
      let user4 = "54c6278e-f824-5fda-91ff-3e946b18d993";
  
      let folder1 = "640ebc06-5ec1-5322-a1ae-6120ed2f3a74";
      let permission1 = "c2c7f658-c7ac-4d73-9020-9d2c296d9100";
      let permission2 = "c2c7f658-c7ac-4d73-9020-9d2c296d9101";
      let permission3 = "c2c7f658-c7ac-4d73-9020-9d2c296d9102";
      let permission4 = "c2c7f658-c7ac-4d73-9020-9d2c296d9103";
      let permission5 = "c2c7f658-c7ac-4d73-9020-9d2c296d9104";
      let permission6 = "c2c7f658-c7ac-4d73-9020-9d2c296d9105";
      let permission7 = "c2c7f658-c7ac-4d73-9020-9d2c296d9106";
  
      permissions = new PermissionsCollection([{
        // permission is not in the original
        id: permission1,
        aco: PermissionEntity.ACO_RESOURCE,
        aco_foreign_key: resource1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user1,
        type: PermissionEntity.PERMISSION_OWNER
      },{
        // permission is same than original
        id: permission2,
        aco: PermissionEntity.ACO_RESOURCE,
        aco_foreign_key: resource1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user2,
        type: PermissionEntity.PERMISSION_READ
      },{
        // permission is more than original
        id: permission3,
        aco: PermissionEntity.ACO_RESOURCE,
        aco_foreign_key: resource1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user3,
        type: PermissionEntity.PERMISSION_OWNER
      },{
        // permission is less than original
        id: permission4,
        aco: PermissionEntity.ACO_RESOURCE,
        aco_foreign_key: resource1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user4,
        type: PermissionEntity.PERMISSION_READ
      }]);
  
      changes = new PermissionChangesCollection([{
        id: permission5,
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user2,
        type: PermissionEntity.PERMISSION_OWNER
      },{
        id: permission6,
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user3,
        type: PermissionEntity.PERMISSION_UPDATE
      },{
        id: permission7,
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user4,
        type: PermissionEntity.PERMISSION_UPDATE
      }]);
  
      original = new PermissionsCollection([{
        id: permission5,
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user2,
        type: PermissionEntity.PERMISSION_READ
      },{
        id: permission6,
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user3,
        type: PermissionEntity.PERMISSION_READ
      },{
        id: permission7,
        aco: PermissionEntity.ACO_FOLDER,
        aco_foreign_key: folder1,
        aro: PermissionEntity.ARO_USER,
        aro_foreign_key: user4,
        type: PermissionEntity.PERMISSION_OWNER
      }], false);
  
      result = PermissionChangesCollection.reuseChanges(
        PermissionEntity.ACO_RESOURCE, resource1, permissions, changes, original
      );
      expect(result.length).toBe(1);
    });
  
  });
  