"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 SnapshotFixture_1 = require("../../../../../__tests__/fixtures/snapshot/SnapshotFixture");
const TakeSnapshotCommand_1 = require("../../../../app/usecase/command/security/operations/snapshot/takeSnapshot/TakeSnapshotCommand");
const GetTokenHoldersAtSnapshotQuery_1 = require("../../../../app/usecase/query/security/snapshot/getTokenHoldersAtSnapshot/GetTokenHoldersAtSnapshotQuery");
const GetTotalTokenHoldersAtSnapshotQuery_1 = require("../../../../app/usecase/query/security/snapshot/getTotalTokenHoldersAtSnapshot/GetTotalTokenHoldersAtSnapshotQuery");
const BalancesOfAtSnapshotQuery_1 = require("../../../../app/usecase/query/security/snapshot/balancesOfAtSnapshot/BalancesOfAtSnapshotQuery");
describe("Snapshot", () => {
    let commandBusMock;
    let queryBusMock;
    let mirrorNodeMock;
    let takeSnapshotRequest;
    let getTokenHoldersAtSnapshotRequest;
    let getTotalTokenHoldersAtSnapshotRequest;
    let balancesOfAtSnapshotRequest;
    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("takeSnapshot", () => {
        takeSnapshotRequest = new request_1.TakeSnapshotRequest(SnapshotFixture_1.TakeSnapshotRequestFixture.create());
        const expectedResponse = {
            payload: true,
            transactionId: transactionId,
        };
        it("should take snapshot successfully", async () => {
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.takeSnapshot(takeSnapshotRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith(request_1.TakeSnapshotRequest.name, takeSnapshotRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new TakeSnapshotCommand_1.TakeSnapshotCommand(takeSnapshotRequest.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.takeSnapshot(takeSnapshotRequest)).rejects.toThrow("Command execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith(request_1.TakeSnapshotRequest.name, takeSnapshotRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new TakeSnapshotCommand_1.TakeSnapshotCommand(takeSnapshotRequest.securityId));
        });
        it("should throw error if securityId is invalid", async () => {
            takeSnapshotRequest = new request_1.TakeSnapshotRequest({
                ...SnapshotFixture_1.TakeSnapshotRequestFixture.create({
                    securityId: "invalid",
                }),
            });
            await expect(Security_1.default.takeSnapshot(takeSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("getTokenHoldersAtSnapshot", () => {
        getTokenHoldersAtSnapshotRequest = new request_1.GetTokenHoldersAtSnapshotRequest(SnapshotFixture_1.GetTokenHoldersAtSnapshotRequestFixture.create());
        it("should get token holders at snapshot successfully", async () => {
            const expectedResponse = {
                payload: [transactionId],
            };
            queryBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.getTokenHoldersAtSnapshot(getTokenHoldersAtSnapshotRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith(request_1.GetTokenHoldersAtSnapshotRequest.name, getTokenHoldersAtSnapshotRequest);
            expect(queryBusMock.execute).toHaveBeenCalledTimes(1);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetTokenHoldersAtSnapshotQuery_1.GetTokenHoldersAtSnapshotQuery(getTokenHoldersAtSnapshotRequest.securityId, getTokenHoldersAtSnapshotRequest.snapshotId, getTokenHoldersAtSnapshotRequest.start, getTokenHoldersAtSnapshotRequest.end));
            expect(result).toStrictEqual(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(Security_1.default.getTokenHoldersAtSnapshot(getTokenHoldersAtSnapshotRequest)).rejects.toThrow("Query execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith(request_1.GetTokenHoldersAtSnapshotRequest.name, getTokenHoldersAtSnapshotRequest);
            expect(queryBusMock.execute).toHaveBeenCalledTimes(1);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetTokenHoldersAtSnapshotQuery_1.GetTokenHoldersAtSnapshotQuery(getTokenHoldersAtSnapshotRequest.securityId, getTokenHoldersAtSnapshotRequest.snapshotId, getTokenHoldersAtSnapshotRequest.start, getTokenHoldersAtSnapshotRequest.end));
        });
        it("should throw error if securityId is invalid", async () => {
            getTokenHoldersAtSnapshotRequest = new request_1.GetTokenHoldersAtSnapshotRequest({
                ...SnapshotFixture_1.GetTokenHoldersAtSnapshotRequestFixture.create(),
                securityId: "invalid",
            });
            await expect(Security_1.default.getTokenHoldersAtSnapshot(getTokenHoldersAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if snapshotId is invalid", async () => {
            getTokenHoldersAtSnapshotRequest = new request_1.GetTokenHoldersAtSnapshotRequest({
                ...SnapshotFixture_1.GetTokenHoldersAtSnapshotRequestFixture.create(),
                snapshotId: -1,
            });
            await expect(Security_1.default.getTokenHoldersAtSnapshot(getTokenHoldersAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if start is invalid", async () => {
            getTokenHoldersAtSnapshotRequest = new request_1.GetTokenHoldersAtSnapshotRequest({
                ...SnapshotFixture_1.GetTokenHoldersAtSnapshotRequestFixture.create(),
                start: -1,
            });
            await expect(Security_1.default.getTokenHoldersAtSnapshot(getTokenHoldersAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if end is invalid", async () => {
            getTokenHoldersAtSnapshotRequest = new request_1.GetTokenHoldersAtSnapshotRequest({
                ...SnapshotFixture_1.GetTokenHoldersAtSnapshotRequestFixture.create(),
                end: -1,
            });
            await expect(Security_1.default.getTokenHoldersAtSnapshot(getTokenHoldersAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("getTotalTokenHoldersAtSnapshot", () => {
        getTotalTokenHoldersAtSnapshotRequest = new request_1.GetTotalTokenHoldersAtSnapshotRequest(SnapshotFixture_1.GetTotalTokenHoldersAtSnapshotRequestFixture.create());
        it("should get total token holders successfully", async () => {
            const expectedResponse = {
                payload: 1,
            };
            queryBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.getTotalTokenHoldersAtSnapshot(getTotalTokenHoldersAtSnapshotRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith(request_1.GetTotalTokenHoldersAtSnapshotRequest.name, getTotalTokenHoldersAtSnapshotRequest);
            expect(queryBusMock.execute).toHaveBeenCalledTimes(1);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetTotalTokenHoldersAtSnapshotQuery_1.GetTotalTokenHoldersAtSnapshotQuery(getTotalTokenHoldersAtSnapshotRequest.securityId, getTotalTokenHoldersAtSnapshotRequest.snapshotId));
            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(Security_1.default.getTotalTokenHoldersAtSnapshot(getTotalTokenHoldersAtSnapshotRequest)).rejects.toThrow("Query execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith(request_1.GetTotalTokenHoldersAtSnapshotRequest.name, getTotalTokenHoldersAtSnapshotRequest);
            expect(queryBusMock.execute).toHaveBeenCalledTimes(1);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new GetTotalTokenHoldersAtSnapshotQuery_1.GetTotalTokenHoldersAtSnapshotQuery(getTotalTokenHoldersAtSnapshotRequest.securityId, getTotalTokenHoldersAtSnapshotRequest.snapshotId));
        });
        it("should throw error if securityId is invalid", async () => {
            getTotalTokenHoldersAtSnapshotRequest = new request_1.GetTotalTokenHoldersAtSnapshotRequest({
                ...SnapshotFixture_1.GetTotalTokenHoldersAtSnapshotRequestFixture.create(),
                securityId: "invalid",
            });
            await expect(Security_1.default.getTotalTokenHoldersAtSnapshot(getTotalTokenHoldersAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if snapshotId is invalid", async () => {
            getTotalTokenHoldersAtSnapshotRequest = new request_1.GetTotalTokenHoldersAtSnapshotRequest({
                ...SnapshotFixture_1.GetTotalTokenHoldersAtSnapshotRequestFixture.create(),
                snapshotId: -1,
            });
            await expect(Security_1.default.getTotalTokenHoldersAtSnapshot(getTotalTokenHoldersAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
    describe("balancesOfAtSnapshot", () => {
        balancesOfAtSnapshotRequest = new request_1.BalancesOfAtSnapshotRequest(SnapshotFixture_1.BalancesOfAtSnapshotRequestFixture.create());
        const mockBalances = [
            { holder: "0x1234567890123456789012345678901234567890", balance: BigInt(1000) },
            { holder: "0x0987654321098765432109876543210987654321", balance: BigInt(2000) },
        ];
        it("should get balances at snapshot successfully", async () => {
            const expectedResponse = {
                payload: mockBalances,
            };
            queryBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Security_1.default.balancesOfAtSnapshot(balancesOfAtSnapshotRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith(request_1.BalancesOfAtSnapshotRequest.name, balancesOfAtSnapshotRequest);
            expect(queryBusMock.execute).toHaveBeenCalledTimes(1);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new BalancesOfAtSnapshotQuery_1.BalancesOfAtSnapshotQuery(balancesOfAtSnapshotRequest.securityId, balancesOfAtSnapshotRequest.snapshotId, balancesOfAtSnapshotRequest.pageIndex, balancesOfAtSnapshotRequest.pageLength));
            expect(result).toStrictEqual(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(Security_1.default.balancesOfAtSnapshot(balancesOfAtSnapshotRequest)).rejects.toThrow("Query execution failed");
            expect(handleValidationSpy).toHaveBeenCalledWith(request_1.BalancesOfAtSnapshotRequest.name, balancesOfAtSnapshotRequest);
            expect(queryBusMock.execute).toHaveBeenCalledTimes(1);
            expect(queryBusMock.execute).toHaveBeenCalledWith(new BalancesOfAtSnapshotQuery_1.BalancesOfAtSnapshotQuery(balancesOfAtSnapshotRequest.securityId, balancesOfAtSnapshotRequest.snapshotId, balancesOfAtSnapshotRequest.pageIndex, balancesOfAtSnapshotRequest.pageLength));
        });
        it("should throw error if securityId is invalid", async () => {
            balancesOfAtSnapshotRequest = new request_1.BalancesOfAtSnapshotRequest({
                ...SnapshotFixture_1.BalancesOfAtSnapshotRequestFixture.create(),
                securityId: "invalid",
            });
            await expect(Security_1.default.balancesOfAtSnapshot(balancesOfAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if snapshotId is invalid", async () => {
            balancesOfAtSnapshotRequest = new request_1.BalancesOfAtSnapshotRequest({
                ...SnapshotFixture_1.BalancesOfAtSnapshotRequestFixture.create(),
                snapshotId: -1,
            });
            await expect(Security_1.default.balancesOfAtSnapshot(balancesOfAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if pageIndex is invalid", async () => {
            balancesOfAtSnapshotRequest = new request_1.BalancesOfAtSnapshotRequest({
                ...SnapshotFixture_1.BalancesOfAtSnapshotRequestFixture.create(),
                pageIndex: -1,
            });
            await expect(Security_1.default.balancesOfAtSnapshot(balancesOfAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
        it("should throw error if pageLength is invalid", async () => {
            balancesOfAtSnapshotRequest = new request_1.BalancesOfAtSnapshotRequest({
                ...SnapshotFixture_1.BalancesOfAtSnapshotRequestFixture.create(),
                pageLength: 0,
            });
            await expect(Security_1.default.balancesOfAtSnapshot(balancesOfAtSnapshotRequest)).rejects.toThrow(ValidationError_1.ValidationError);
        });
    });
});
