"use strict";
// SPDX-License-Identifier: Apache-2.0
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ts_jest_1 = require("@golevelup/ts-jest");
const request_1 = require("../request");
const DataFixture_1 = require("../../../../__tests__/fixtures/shared/DataFixture");
const LogService_1 = __importDefault(require("../../../app/service/log/LogService"));
const ValidatedArgs_1 = __importDefault(require("../../../core/validation/ValidatedArgs"));
const ValidationError_1 = require("../../../core/validation/ValidationError");
const RoleFixture_1 = require("../../../../__tests__/fixtures/role/RoleFixture");
const Role_1 = __importDefault(require("./Role"));
const HasRoleQuery_1 = require("../../../app/usecase/query/security/roles/hasRole/HasRoleQuery");
const GrantRoleCommand_1 = require("../../../app/usecase/command/security/roles/grantRole/GrantRoleCommand");
const RevokeRoleCommand_1 = require("../../../app/usecase/command/security/roles/revokeRole/RevokeRoleCommand");
const GetRoleCountForQuery_1 = require("../../../app/usecase/query/security/roles/getRoleCountFor/GetRoleCountForQuery");
const GetRolesForQuery_1 = require("../../../app/usecase/query/security/roles/getRolesFor/GetRolesForQuery");
const GetRoleMemberCountQuery_1 = require("../../../app/usecase/query/security/roles/getRoleMemberCount/GetRoleMemberCountQuery");
const GetRoleMembersQuery_1 = require("../../../app/usecase/query/security/roles/getRoleMembers/GetRoleMembersQuery");
const Account_1 = __importDefault(require("../../../domain/context/account/Account"));
const AccountFixture_1 = require("../../../../__tests__/fixtures/account/AccountFixture");
const ApplyRolesCommand_1 = require("../../../app/usecase/command/security/roles/applyRoles/ApplyRolesCommand");
const SecurityRole_1 = require("../../../domain/context/security/SecurityRole");
describe("Role", () => {
    let commandBusMock;
    let queryBusMock;
    let mirrorNodeMock;
    let roleRequest;
    let getRoleCountForRequest;
    let getRolesForRequest;
    let getRoleMemberCountRequest;
    let getRoleMembersRequest;
    let applyRolesRequest;
    let handleValidationSpy;
    const transactionId = DataFixture_1.TransactionIdFixture.create().id;
    const account = new Account_1.default(AccountFixture_1.AccountPropsFixture.create());
    const expectedResponse = {
        payload: true,
        transactionId: transactionId,
    };
    beforeEach(() => {
        commandBusMock = (0, ts_jest_1.createMock)();
        queryBusMock = (0, ts_jest_1.createMock)();
        mirrorNodeMock = (0, ts_jest_1.createMock)();
        handleValidationSpy = jest.spyOn(ValidatedArgs_1.default, "handleValidation");
        jest.spyOn(LogService_1.default, "logError").mockImplementation(() => { });
        Role_1.default.commandBus = commandBusMock;
        Role_1.default.queryBus = queryBusMock;
        Role_1.default.mirrorNode = mirrorNodeMock;
    });
    afterEach(() => {
        jest.resetAllMocks();
        jest.restoreAllMocks();
    });
    describe("hasRole", () => {
        roleRequest = new request_1.RoleRequest(RoleFixture_1.RoleRequestFixture.create());
        const expectedResponse = {
            payload: true,
        };
        it("should get has role successfully", async () => {
            queryBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Role_1.default.hasRole(roleRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("RoleRequest", roleRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new HasRoleQuery_1.HasRoleQuery(roleRequest.role, roleRequest.targetId, roleRequest.securityId));
            expect(result).toEqual(expectedResponse.payload);
        });
        it("should throw an error if query execution fails", async () => {
            const error = new Error("Query execution failed");
            queryBusMock.execute.mockRejectedValue(error);
            await expect(Role_1.default.hasRole(roleRequest)).rejects.toThrow("Query execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("RoleRequest", roleRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new HasRoleQuery_1.HasRoleQuery(roleRequest.role, roleRequest.targetId, roleRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Role_1.default.hasRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if targetId is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    targetId: "invalid",
                }),
            });
            await expect(Role_1.default.hasRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if role is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    role: "invalid",
                }),
            });
            await expect(Role_1.default.hasRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("grantRole", () => {
        it("should grant role successfully", async () => {
            roleRequest = new request_1.RoleRequest(RoleFixture_1.RoleRequestFixture.create());
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Role_1.default.grantRole(roleRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("RoleRequest", roleRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new GrantRoleCommand_1.GrantRoleCommand(roleRequest.role, roleRequest.targetId, roleRequest.securityId));
            expect(result).toEqual(expectedResponse);
        });
        it("should throw an error if command execution fails", async () => {
            roleRequest = new request_1.RoleRequest(RoleFixture_1.RoleRequestFixture.create());
            const error = new Error("Command execution failed");
            commandBusMock.execute.mockRejectedValue(error);
            await expect(Role_1.default.grantRole(roleRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("RoleRequest", roleRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new GrantRoleCommand_1.GrantRoleCommand(roleRequest.role, roleRequest.targetId, roleRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Role_1.default.grantRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if targetId is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    targetId: "invalid",
                }),
            });
            await expect(Role_1.default.grantRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if role is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    role: "invalid",
                }),
            });
            await expect(Role_1.default.grantRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("revokeRole", () => {
        it("should revoke role successfully", async () => {
            roleRequest = new request_1.RoleRequest(RoleFixture_1.RoleRequestFixture.create());
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Role_1.default.revokeRole(roleRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("RoleRequest", roleRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new RevokeRoleCommand_1.RevokeRoleCommand(roleRequest.role, roleRequest.targetId, roleRequest.securityId));
            expect(result).toEqual(expectedResponse);
        });
        it("should throw an error if command execution fails", async () => {
            roleRequest = new request_1.RoleRequest(RoleFixture_1.RoleRequestFixture.create());
            const error = new Error("Command execution failed");
            commandBusMock.execute.mockRejectedValue(error);
            await expect(Role_1.default.revokeRole(roleRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("RoleRequest", roleRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new RevokeRoleCommand_1.RevokeRoleCommand(roleRequest.role, roleRequest.targetId, roleRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Role_1.default.revokeRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if targetId is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    targetId: "invalid",
                }),
            });
            await expect(Role_1.default.revokeRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if role is invalid", async () => {
            roleRequest = new request_1.RoleRequest({
                ...RoleFixture_1.RoleRequestFixture.create({
                    role: "invalid",
                }),
            });
            await expect(Role_1.default.revokeRole(roleRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("getRoleCountFor", () => {
        getRoleCountForRequest = new request_1.GetRoleCountForRequest(RoleFixture_1.GetRoleCountForRequestFixture.create());
        const expectedResponse = {
            payload: 1,
        };
        it("should get role count for successfully", async () => {
            queryBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Role_1.default.getRoleCountFor(getRoleCountForRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("GetRoleCountForRequest", getRoleCountForRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetRoleCountForQuery_1.GetRoleCountForQuery(getRoleCountForRequest.targetId, getRoleCountForRequest.securityId));
            expect(result).toEqual(expectedResponse.payload);
        });
        it("should throw an error if query execution fails", async () => {
            const error = new Error("Query execution failed");
            queryBusMock.execute.mockRejectedValue(error);
            await expect(Role_1.default.getRoleCountFor(getRoleCountForRequest)).rejects.toThrow("Query execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("GetRoleCountForRequest", getRoleCountForRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetRoleCountForQuery_1.GetRoleCountForQuery(getRoleCountForRequest.targetId, getRoleCountForRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            getRoleCountForRequest = new request_1.GetRoleCountForRequest({
                ...RoleFixture_1.GetRoleCountForRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Role_1.default.getRoleCountFor(getRoleCountForRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if targetId is invalid", async () => {
            getRoleCountForRequest = new request_1.GetRoleCountForRequest({
                ...RoleFixture_1.GetRoleCountForRequestFixture.create({
                    targetId: "invalid",
                }),
            });
            await expect(Role_1.default.getRoleCountFor(getRoleCountForRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("getRolesFor", () => {
        getRolesForRequest = new request_1.GetRolesForRequest(RoleFixture_1.GetRolesForRequestFixture.create());
        const expectedResponse = {
            payload: ["role"],
        };
        it("should get role for successfully", async () => {
            queryBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Role_1.default.getRolesFor(getRolesForRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("GetRolesForRequest", getRolesForRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetRolesForQuery_1.GetRolesForQuery(getRolesForRequest.targetId, getRolesForRequest.securityId, getRolesForRequest.start, getRolesForRequest.end));
            expect(result).toEqual(expectedResponse.payload);
        });
        it("should throw an error if query execution fails", async () => {
            const error = new Error("Query execution failed");
            queryBusMock.execute.mockRejectedValue(error);
            await expect(Role_1.default.getRolesFor(getRolesForRequest)).rejects.toThrow("Query execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("GetRolesForRequest", getRolesForRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetRolesForQuery_1.GetRolesForQuery(getRolesForRequest.targetId, getRolesForRequest.securityId, getRolesForRequest.start, getRolesForRequest.end));
        });
        it("should throw error if securityId is invalid", async () => {
            getRolesForRequest = new request_1.GetRolesForRequest({
                ...RoleFixture_1.GetRolesForRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Role_1.default.getRolesFor(getRolesForRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if targetId is invalid", async () => {
            getRolesForRequest = new request_1.GetRolesForRequest({
                ...RoleFixture_1.GetRolesForRequestFixture.create({
                    targetId: "invalid",
                }),
            });
            await expect(Role_1.default.getRolesFor(getRolesForRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("getRoleMemberCount", () => {
        getRoleMemberCountRequest = new request_1.GetRoleMemberCountRequest(RoleFixture_1.GetRoleMemberCountRequestFixture.create());
        const expectedResponse = {
            payload: 1,
        };
        it("should get role member count successfully", async () => {
            queryBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Role_1.default.getRoleMemberCount(getRoleMemberCountRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("GetRoleMemberCountRequest", getRoleMemberCountRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetRoleMemberCountQuery_1.GetRoleMemberCountQuery(getRoleMemberCountRequest.role, getRoleMemberCountRequest.securityId));
            expect(result).toEqual(expectedResponse.payload);
        });
        it("should throw an error if query execution fails", async () => {
            const error = new Error("Query execution failed");
            queryBusMock.execute.mockRejectedValue(error);
            await expect(Role_1.default.getRoleMemberCount(getRoleMemberCountRequest)).rejects.toThrow("Query execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("GetRoleMemberCountRequest", getRoleMemberCountRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetRoleMemberCountQuery_1.GetRoleMemberCountQuery(getRoleMemberCountRequest.role, getRoleMemberCountRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            getRoleMemberCountRequest = new request_1.GetRoleMemberCountRequest({
                ...RoleFixture_1.GetRoleMemberCountRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Role_1.default.getRoleMemberCount(getRoleMemberCountRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if role is invalid", async () => {
            getRoleMemberCountRequest = new request_1.GetRoleMemberCountRequest({
                ...RoleFixture_1.GetRoleMemberCountRequestFixture.create({
                    role: "invalid",
                }),
            });
            await expect(Role_1.default.getRoleMemberCount(getRoleMemberCountRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("getRoleMembers", () => {
        getRoleMembersRequest = new request_1.GetRoleMembersRequest(RoleFixture_1.GetRoleMembersRequestFixture.create());
        const expectedResponse = {
            payload: [account.id.toString()],
        };
        it("should get role members successfully", async () => {
            queryBusMock.execute.mockResolvedValue(expectedResponse);
            mirrorNodeMock.getAccountInfo.mockResolvedValue(account);
            const result = await Role_1.default.getRoleMembers(getRoleMembersRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("GetRoleMembersRequest", getRoleMembersRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetRoleMembersQuery_1.GetRoleMembersQuery(getRoleMembersRequest.role, getRoleMembersRequest.securityId, getRoleMembersRequest.start, getRoleMembersRequest.end));
            expect(mirrorNodeMock.getAccountInfo).toHaveBeenCalledWith(account.id.toString());
            expect(result).toEqual(expectedResponse.payload);
        });
        it("should throw an error if query execution fails", async () => {
            const error = new Error("Query execution failed");
            queryBusMock.execute.mockRejectedValue(error);
            await expect(Role_1.default.getRoleMembers(getRoleMembersRequest)).rejects.toThrow("Query execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("GetRoleMembersRequest", getRoleMembersRequest);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetRoleMembersQuery_1.GetRoleMembersQuery(getRoleMembersRequest.role, getRoleMembersRequest.securityId, getRoleMembersRequest.start, getRoleMembersRequest.end));
        });
        it("should throw error if securityId is invalid", async () => {
            getRoleMembersRequest = new request_1.GetRoleMembersRequest({
                ...RoleFixture_1.GetRoleMembersRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Role_1.default.getRoleMembers(getRoleMembersRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if role is invalid", async () => {
            getRoleMembersRequest = new request_1.GetRoleMembersRequest({
                ...RoleFixture_1.GetRoleMembersRequestFixture.create({
                    role: "invalid",
                }),
            });
            await expect(Role_1.default.getRoleMembers(getRoleMembersRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("applyRoles", () => {
        applyRolesRequest = new request_1.ApplyRolesRequest(RoleFixture_1.ApplyRolesRequestFixture.create());
        it("should apply roles successfully", async () => {
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Role_1.default.applyRoles(applyRolesRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("ApplyRolesRequest", applyRolesRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new ApplyRolesCommand_1.ApplyRolesCommand(applyRolesRequest.roles, applyRolesRequest.actives, applyRolesRequest.targetId, applyRolesRequest.securityId));
            expect(result).toEqual(expectedResponse);
        });
        it("should throw an error if command execution fails", async () => {
            const error = new Error("Command execution failed");
            commandBusMock.execute.mockRejectedValue(error);
            await expect(Role_1.default.applyRoles(applyRolesRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("ApplyRolesRequest", applyRolesRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new ApplyRolesCommand_1.ApplyRolesCommand(applyRolesRequest.roles, applyRolesRequest.actives, applyRolesRequest.targetId, applyRolesRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            applyRolesRequest = new request_1.ApplyRolesRequest({
                ...RoleFixture_1.ApplyRolesRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Role_1.default.applyRoles(applyRolesRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if targetId is invalid", async () => {
            applyRolesRequest = new request_1.ApplyRolesRequest({
                ...RoleFixture_1.ApplyRolesRequestFixture.create({
                    targetId: "invalid",
                }),
            });
            await expect(Role_1.default.applyRoles(applyRolesRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if roles is empty", async () => {
            applyRolesRequest = new request_1.ApplyRolesRequest({
                ...RoleFixture_1.ApplyRolesRequestFixture.create({
                    roles: [],
                }),
            });
            await expect(Role_1.default.applyRoles(applyRolesRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if roles not exist", async () => {
            applyRolesRequest = new request_1.ApplyRolesRequest({
                ...RoleFixture_1.ApplyRolesRequestFixture.create({
                    roles: ["invalid"],
                }),
            });
            await expect(Role_1.default.applyRoles(applyRolesRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if roles is duplicated", async () => {
            applyRolesRequest = new request_1.ApplyRolesRequest({
                ...RoleFixture_1.ApplyRolesRequestFixture.create({
                    roles: [SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE, SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE],
                }),
            });
            await expect(Role_1.default.applyRoles(applyRolesRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if roles list and active list are different", async () => {
            applyRolesRequest = new request_1.ApplyRolesRequest({
                ...RoleFixture_1.ApplyRolesRequestFixture.create({
                    roles: [SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE],
                    actives: [true, false],
                }),
            });
            await expect(Role_1.default.applyRoles(applyRolesRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
});
