"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 Security_1 = __importDefault(require("../../../in/security/Security"));
const RedeemFixture_1 = require("../../../../../__tests__/fixtures/redeem/RedeemFixture");
const RedeemCommand_1 = require("../../../../app/usecase/command/security/operations/redeem/RedeemCommand");
const ControllerRedeemCommand_1 = require("../../../../app/usecase/command/security/operations/redeem/ControllerRedeemCommand");
const ProtectedPartitionsFixture_1 = require("../../../../../__tests__/fixtures/protectedPartitions/ProtectedPartitionsFixture");
const ProtectedRedeemFromByPartitionCommand_1 = require("../../../../app/usecase/command/security/operations/redeem/ProtectedRedeemFromByPartitionCommand");
const BatchBurnCommand_1 = require("../../../../app/usecase/command/security/operations/batch/batchBurn/BatchBurnCommand");
const BurnCommand_1 = require("../../../../app/usecase/command/security/operations/burn/BurnCommand");
const BatchFixture_1 = require("../../../../../__tests__/fixtures/batch/BatchFixture");
const BurnFixture_1 = require("../../../../../__tests__/fixtures/burn/BurnFixture");
describe("Redeem", () => {
    let commandBusMock;
    let queryBusMock;
    let mirrorNodeMock;
    let redeemRequest;
    let burnRequest;
    let forceRedeemRequest;
    let protectedRedeemFromByPartitionRequest;
    let batchBurnRequest;
    let handleValidationSpy;
    const transactionId = DataFixture_1.TransactionIdFixture.create().id;
    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(() => { });
        Security_1.default.commandBus = commandBusMock;
        Security_1.default.queryBus = queryBusMock;
        Security_1.default.mirrorNode = mirrorNodeMock;
    });
    afterEach(() => {
        jest.resetAllMocks();
        jest.restoreAllMocks();
    });
    describe("redeem", () => {
        redeemRequest = new request_1.RedeemRequest(RedeemFixture_1.RedeemRequestFixture.create());
        const expectedResponse = {
            payload: true,
            transactionId: transactionId,
        };
        it("should redeem successfully", async () => {
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.redeem(redeemRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("RedeemRequest", redeemRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new RedeemCommand_1.RedeemCommand(redeemRequest.amount, redeemRequest.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(Security_1.default.redeem(redeemRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("RedeemRequest", redeemRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new RedeemCommand_1.RedeemCommand(redeemRequest.amount, redeemRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            redeemRequest = new request_1.RedeemRequest({
                ...RedeemFixture_1.RedeemRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Security_1.default.redeem(redeemRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if amount is invalid", async () => {
            redeemRequest = new request_1.RedeemRequest({
                ...RedeemFixture_1.RedeemRequestFixture.create({
                    amount: "invalid",
                }),
            });
            await expect(Security_1.default.redeem(redeemRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("burn", () => {
        burnRequest = new request_1.BurnRequest(BurnFixture_1.BurnRequestFixture.create());
        const expectedResponse = {
            payload: true,
            transactionId: transactionId,
        };
        it("should burn successfully", async () => {
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.burn(burnRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("BurnRequest", burnRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new BurnCommand_1.BurnCommand(burnRequest.sourceId, burnRequest.amount, burnRequest.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(Security_1.default.burn(burnRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("BurnRequest", burnRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new BurnCommand_1.BurnCommand(burnRequest.sourceId, burnRequest.amount, burnRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            burnRequest = new request_1.BurnRequest({
                ...BurnFixture_1.BurnRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Security_1.default.burn(burnRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if amount is invalid", async () => {
            burnRequest = new request_1.BurnRequest({
                ...BurnFixture_1.BurnRequestFixture.create({
                    amount: "invalid",
                }),
            });
            await expect(Security_1.default.burn(burnRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("controllerRedeem", () => {
        forceRedeemRequest = new request_1.ForceRedeemRequest(RedeemFixture_1.ForceRedeemRequestFixture.create());
        const expectedResponse = {
            payload: true,
            transactionId: transactionId,
        };
        it("should controller redeem successfully", async () => {
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.controllerRedeem(forceRedeemRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("ForceRedeemRequest", forceRedeemRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new ControllerRedeemCommand_1.ControllerRedeemCommand(forceRedeemRequest.amount, forceRedeemRequest.sourceId, forceRedeemRequest.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(Security_1.default.controllerRedeem(forceRedeemRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("ForceRedeemRequest", forceRedeemRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new ControllerRedeemCommand_1.ControllerRedeemCommand(forceRedeemRequest.amount, forceRedeemRequest.sourceId, forceRedeemRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            forceRedeemRequest = new request_1.ForceRedeemRequest({
                ...RedeemFixture_1.ForceRedeemRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Security_1.default.controllerRedeem(forceRedeemRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if sourceId is invalid", async () => {
            forceRedeemRequest = new request_1.ForceRedeemRequest({
                ...RedeemFixture_1.ForceRedeemRequestFixture.create({
                    sourceId: "invalid",
                }),
            });
            await expect(Security_1.default.controllerRedeem(forceRedeemRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if amount is invalid", async () => {
            forceRedeemRequest = new request_1.ForceRedeemRequest({
                ...RedeemFixture_1.ForceRedeemRequestFixture.create({
                    amount: "invalid",
                }),
            });
            await expect(Security_1.default.controllerRedeem(forceRedeemRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("protectedRedeemFromByPartition", () => {
        protectedRedeemFromByPartitionRequest = new request_1.ProtectedRedeemFromByPartitionRequest(ProtectedPartitionsFixture_1.ProtectedRedeemFromByPartitionRequestFixture.create());
        const expectedResponse = {
            payload: true,
            transactionId: transactionId,
        };
        it("should protected redeem from by partition successfully", async () => {
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.protectedRedeemFromByPartition(protectedRedeemFromByPartitionRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("ProtectedRedeemFromByPartitionRequest", protectedRedeemFromByPartitionRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new ProtectedRedeemFromByPartitionCommand_1.ProtectedRedeemFromByPartitionCommand(protectedRedeemFromByPartitionRequest.securityId, protectedRedeemFromByPartitionRequest.partitionId, protectedRedeemFromByPartitionRequest.sourceId, protectedRedeemFromByPartitionRequest.amount, protectedRedeemFromByPartitionRequest.deadline, protectedRedeemFromByPartitionRequest.nounce, protectedRedeemFromByPartitionRequest.signature));
            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(Security_1.default.protectedRedeemFromByPartition(protectedRedeemFromByPartitionRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("ProtectedRedeemFromByPartitionRequest", protectedRedeemFromByPartitionRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new ProtectedRedeemFromByPartitionCommand_1.ProtectedRedeemFromByPartitionCommand(protectedRedeemFromByPartitionRequest.securityId, protectedRedeemFromByPartitionRequest.partitionId, protectedRedeemFromByPartitionRequest.sourceId, protectedRedeemFromByPartitionRequest.amount, protectedRedeemFromByPartitionRequest.deadline, protectedRedeemFromByPartitionRequest.nounce, protectedRedeemFromByPartitionRequest.signature));
        });
        it("should throw error if securityId is invalid", async () => {
            protectedRedeemFromByPartitionRequest = new request_1.ProtectedRedeemFromByPartitionRequest({
                ...ProtectedPartitionsFixture_1.ProtectedRedeemFromByPartitionRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Security_1.default.protectedRedeemFromByPartition(protectedRedeemFromByPartitionRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if partitionId is invalid", async () => {
            protectedRedeemFromByPartitionRequest = new request_1.ProtectedRedeemFromByPartitionRequest({
                ...ProtectedPartitionsFixture_1.ProtectedRedeemFromByPartitionRequestFixture.create({
                    partitionId: "invalid",
                }),
            });
            await expect(Security_1.default.protectedRedeemFromByPartition(protectedRedeemFromByPartitionRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if sourceId is invalid", async () => {
            protectedRedeemFromByPartitionRequest = new request_1.ProtectedRedeemFromByPartitionRequest({
                ...ProtectedPartitionsFixture_1.ProtectedRedeemFromByPartitionRequestFixture.create({
                    sourceId: "invalid",
                }),
            });
            await expect(Security_1.default.protectedRedeemFromByPartition(protectedRedeemFromByPartitionRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if amount is invalid", async () => {
            protectedRedeemFromByPartitionRequest = new request_1.ProtectedRedeemFromByPartitionRequest({
                ...ProtectedPartitionsFixture_1.ProtectedRedeemFromByPartitionRequestFixture.create({
                    amount: "invalid",
                }),
            });
            await expect(Security_1.default.protectedRedeemFromByPartition(protectedRedeemFromByPartitionRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if deadline is invalid", async () => {
            protectedRedeemFromByPartitionRequest = new request_1.ProtectedRedeemFromByPartitionRequest({
                ...ProtectedPartitionsFixture_1.ProtectedRedeemFromByPartitionRequestFixture.create({
                    deadline: (Math.ceil(new Date().getTime() / 1000) - 100).toString(),
                }),
            });
            await expect(Security_1.default.protectedRedeemFromByPartition(protectedRedeemFromByPartitionRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("BatchBurn", () => {
        batchBurnRequest = new request_1.BatchBurnRequest(BatchFixture_1.BatchBurnRequestFixture.create());
        const expectedResponse = new BatchBurnCommand_1.BatchBurnResponse(true, transactionId);
        it("should batch burn sucessfully", async () => {
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.batchBurn(batchBurnRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("BatchBurnRequest", batchBurnRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new BatchBurnCommand_1.BatchBurnCommand(batchBurnRequest.securityId, batchBurnRequest.amountList, batchBurnRequest.targetList));
            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(Security_1.default.batchBurn(batchBurnRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith("BatchBurnRequest", batchBurnRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new BatchBurnCommand_1.BatchBurnCommand(batchBurnRequest.securityId, batchBurnRequest.amountList, batchBurnRequest.targetList));
        });
        it("should throw error if securityId is invalid", async () => {
            batchBurnRequest = new request_1.BatchBurnRequest({
                ...BatchFixture_1.BatchBurnRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Security_1.default.batchBurn(batchBurnRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if amountList is empty", async () => {
            batchBurnRequest = new request_1.BatchBurnRequest({
                ...BatchFixture_1.BatchBurnRequestFixture.create({
                    amountList: [],
                }),
            });
            await expect(Security_1.default.batchBurn(batchBurnRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if targetList is empty", async () => {
            batchBurnRequest = new request_1.BatchBurnRequest({
                ...BatchFixture_1.BatchBurnRequestFixture.create({
                    targetList: [],
                }),
            });
            await expect(Security_1.default.batchBurn(batchBurnRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if list lengths are not equal", async () => {
            batchBurnRequest = new request_1.BatchBurnRequest({
                ...BatchFixture_1.BatchBurnRequestFixture.create({
                    targetList: [DataFixture_1.HederaIdPropsFixture.create().value, DataFixture_1.HederaIdPropsFixture.create().value],
                }),
            });
            await expect(Security_1.default.batchBurn(batchBurnRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
});
