"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sinon_1 = __importDefault(require("sinon"));
const internal_1 = require("../../../../../internal");
const mocks_1 = require("../../../../../testUtils/mocks");
const types_1 = require("../../../../../types");
const utilsConversionModule = __importStar(require("../../../../../utils/conversion"));
const Requirements_1 = require("../Requirements");
jest.mock('~/api/entities/Identity', require("../../../../../testUtils/mocks/entities").mockIdentityModule('~/api/entities/Identity'));
jest.mock('~/base/Procedure', require("../../../../../testUtils/mocks/procedure").mockProcedureModule('~/base/Procedure'));
describe('Requirements class', () => {
    beforeAll(() => {
        mocks_1.entityMockUtils.initMocks();
        mocks_1.dsMockUtils.initMocks();
        mocks_1.procedureMockUtils.initMocks();
    });
    afterEach(() => {
        mocks_1.entityMockUtils.reset();
        mocks_1.dsMockUtils.reset();
        mocks_1.procedureMockUtils.reset();
    });
    afterAll(() => {
        mocks_1.entityMockUtils.cleanup();
        mocks_1.dsMockUtils.cleanup();
        mocks_1.procedureMockUtils.cleanup();
    });
    test('should extend namespace', () => {
        expect(Requirements_1.Requirements.prototype instanceof internal_1.Namespace).toBe(true);
    });
    describe('method: set', () => {
        afterAll(() => {
            sinon_1.default.restore();
        });
        test('should prepare the procedure with the correct arguments and context, and return the resulting transaction queue', () => __awaiter(void 0, void 0, void 0, function* () {
            const context = mocks_1.dsMockUtils.getContextInstance();
            const token = mocks_1.entityMockUtils.getSecurityTokenInstance();
            const requirements = new Requirements_1.Requirements(token, context);
            const args = {
                requirements: [
                    [
                        {
                            type: types_1.ConditionType.IsPresent,
                            claim: {
                                type: types_1.ClaimType.Exempted,
                                scope: { type: types_1.ScopeType.Ticker, value: 'someTicker' },
                            },
                            target: types_1.ConditionTarget.Both,
                        },
                        {
                            type: types_1.ConditionType.IsAbsent,
                            claim: {
                                type: types_1.ClaimType.Blocked,
                                scope: { type: types_1.ScopeType.Ticker, value: 'someTicker' },
                            },
                            target: types_1.ConditionTarget.Both,
                        },
                    ],
                ],
            };
            const expectedQueue = 'someQueue';
            mocks_1.procedureMockUtils
                .getPrepareStub()
                .withArgs({ args: Object.assign({ ticker: token.ticker }, args), transformer: undefined }, context)
                .resolves(expectedQueue);
            const queue = yield requirements.set(args);
            expect(queue).toBe(expectedQueue);
        }));
    });
    describe('method: reset', () => {
        afterAll(() => {
            sinon_1.default.restore();
        });
        test('should prepare the procedure with the correct arguments and context, and return the resulting transaction queue', () => __awaiter(void 0, void 0, void 0, function* () {
            const context = mocks_1.dsMockUtils.getContextInstance();
            const token = mocks_1.entityMockUtils.getSecurityTokenInstance();
            const requirements = new Requirements_1.Requirements(token, context);
            const expectedQueue = 'someQueue';
            mocks_1.procedureMockUtils
                .getPrepareStub()
                .withArgs({ args: { ticker: token.ticker, requirements: [] }, transformer: undefined }, context)
                .resolves(expectedQueue);
            const queue = yield requirements.reset();
            expect(queue).toBe(expectedQueue);
        }));
    });
    describe('method: get', () => {
        let ticker;
        let context;
        let token;
        let requirements;
        let defaultClaimIssuers;
        let notDefaultClaimIssuer;
        let tokenDid;
        let cddId;
        let trustedIssuerToTrustedClaimIssuerStub;
        let expected;
        let queryMultiStub;
        let queryMultiResult;
        beforeAll(() => {
            trustedIssuerToTrustedClaimIssuerStub = sinon_1.default.stub(utilsConversionModule, 'trustedIssuerToTrustedClaimIssuer');
        });
        beforeEach(() => {
            ticker = 'FAKETICKER';
            context = mocks_1.dsMockUtils.getContextInstance();
            token = mocks_1.entityMockUtils.getSecurityTokenInstance({ ticker });
            requirements = new Requirements_1.Requirements(token, context);
            defaultClaimIssuers = [
                { identity: mocks_1.entityMockUtils.getIdentityInstance({ did: 'defaultissuer' }) },
            ];
            notDefaultClaimIssuer = {
                identity: mocks_1.entityMockUtils.getIdentityInstance({ did: 'notDefaultClaimIssuer' }),
                trustedFor: undefined,
            };
            tokenDid = 'someTokenDid';
            cddId = 'someCddId';
            mocks_1.dsMockUtils.createQueryStub('complianceManager', 'assetCompliances');
            mocks_1.dsMockUtils.createQueryStub('complianceManager', 'trustedClaimIssuer');
            queryMultiStub = mocks_1.dsMockUtils.getQueryMultiStub();
            trustedIssuerToTrustedClaimIssuerStub.returns({
                identity: defaultClaimIssuers[0].identity,
            });
            const scope = mocks_1.dsMockUtils.createMockScope({
                Identity: mocks_1.dsMockUtils.createMockIdentityId(tokenDid),
            });
            const conditionForBoth = mocks_1.dsMockUtils.createMockCondition({
                // eslint-disable-next-line @typescript-eslint/naming-convention
                condition_type: mocks_1.dsMockUtils.createMockConditionType({
                    IsAnyOf: [
                        mocks_1.dsMockUtils.createMockClaim({
                            KnowYourCustomer: scope,
                        }),
                        mocks_1.dsMockUtils.createMockClaim({
                            CustomerDueDiligence: mocks_1.dsMockUtils.createMockCddId(cddId),
                        }),
                    ],
                }),
                issuers: [],
            });
            queryMultiResult = [
                {
                    requirements: [
                        mocks_1.dsMockUtils.createMockComplianceRequirement({
                            /* eslint-disable @typescript-eslint/naming-convention */
                            sender_conditions: [
                                mocks_1.dsMockUtils.createMockCondition({
                                    condition_type: mocks_1.dsMockUtils.createMockConditionType({
                                        IsPresent: mocks_1.dsMockUtils.createMockClaim({
                                            Exempted: scope,
                                        }),
                                    }),
                                    issuers: [
                                        mocks_1.dsMockUtils.createMockTrustedIssuer({
                                            issuer: mocks_1.dsMockUtils.createMockIdentityId(notDefaultClaimIssuer.identity.did),
                                            trusted_for: mocks_1.dsMockUtils.createMockTrustedFor('Any'),
                                        }),
                                    ],
                                }),
                            ],
                            receiver_conditions: [],
                            id: mocks_1.dsMockUtils.createMockU32(1),
                        }),
                        mocks_1.dsMockUtils.createMockComplianceRequirement({
                            sender_conditions: [conditionForBoth],
                            receiver_conditions: [
                                conditionForBoth,
                                mocks_1.dsMockUtils.createMockCondition({
                                    condition_type: mocks_1.dsMockUtils.createMockConditionType({
                                        IsAbsent: mocks_1.dsMockUtils.createMockClaim({
                                            Blocked: scope,
                                        }),
                                    }),
                                    issuers: [],
                                }),
                            ],
                            id: mocks_1.dsMockUtils.createMockU32(2),
                            /* eslint-enable @typescript-eslint/naming-convention */
                        }),
                    ],
                },
                defaultClaimIssuers,
            ];
            expected = [
                {
                    id: 1,
                    conditions: [
                        {
                            target: types_1.ConditionTarget.Sender,
                            type: types_1.ConditionType.IsPresent,
                            claim: {
                                type: types_1.ClaimType.Exempted,
                                scope: { type: types_1.ScopeType.Identity, value: tokenDid },
                            },
                            trustedClaimIssuers: [notDefaultClaimIssuer],
                        },
                    ],
                },
                {
                    id: 2,
                    conditions: [
                        {
                            target: types_1.ConditionTarget.Both,
                            type: types_1.ConditionType.IsAnyOf,
                            claims: [
                                {
                                    type: types_1.ClaimType.KnowYourCustomer,
                                    scope: { type: types_1.ScopeType.Identity, value: tokenDid },
                                },
                                { type: types_1.ClaimType.CustomerDueDiligence, id: cddId },
                            ],
                            trustedClaimIssuers: defaultClaimIssuers,
                        },
                        {
                            target: types_1.ConditionTarget.Receiver,
                            type: types_1.ConditionType.IsAbsent,
                            claim: {
                                type: types_1.ClaimType.Blocked,
                                scope: { type: types_1.ScopeType.Identity, value: tokenDid },
                            },
                            trustedClaimIssuers: defaultClaimIssuers,
                        },
                    ],
                },
            ];
        });
        afterAll(() => {
            sinon_1.default.restore();
        });
        test('should return all requirements attached to the Security Token, using the default trusted claim issuers where none are set', () => __awaiter(void 0, void 0, void 0, function* () {
            queryMultiStub.resolves(queryMultiResult);
            const result = yield requirements.get();
            expect(result).toEqual(expected);
        }));
        test('should allow subscription', () => __awaiter(void 0, void 0, void 0, function* () {
            const unsubCallback = 'unsubCallback';
            queryMultiStub.callsFake((_, cbFunc) => {
                cbFunc(queryMultiResult);
                return unsubCallback;
            });
            const callback = sinon_1.default.stub();
            const result = yield requirements.get(callback);
            expect(result).toBe(unsubCallback);
            sinon_1.default.assert.calledWithExactly(callback, expected);
        }));
    });
    describe('method: pause', () => {
        afterAll(() => {
            sinon_1.default.restore();
        });
        test('should prepare the procedure with the correct arguments and context, and return the resulting transaction queue', () => __awaiter(void 0, void 0, void 0, function* () {
            const context = mocks_1.dsMockUtils.getContextInstance();
            const token = mocks_1.entityMockUtils.getSecurityTokenInstance();
            const requirements = new Requirements_1.Requirements(token, context);
            const expectedQueue = 'someQueue';
            mocks_1.procedureMockUtils
                .getPrepareStub()
                .withArgs({ args: { ticker: token.ticker, pause: true }, transformer: undefined }, context)
                .resolves(expectedQueue);
            const queue = yield requirements.pause();
            expect(queue).toBe(expectedQueue);
        }));
    });
    describe('method: unpause', () => {
        afterAll(() => {
            sinon_1.default.restore();
        });
        test('should prepare the procedure with the correct arguments and context, and return the resulting transaction queue', () => __awaiter(void 0, void 0, void 0, function* () {
            const context = mocks_1.dsMockUtils.getContextInstance();
            const token = mocks_1.entityMockUtils.getSecurityTokenInstance();
            const requirements = new Requirements_1.Requirements(token, context);
            const expectedQueue = 'someQueue';
            mocks_1.procedureMockUtils
                .getPrepareStub()
                .withArgs({ args: { ticker: token.ticker, pause: false }, transformer: undefined }, context)
                .resolves(expectedQueue);
            const queue = yield requirements.unpause();
            expect(queue).toBe(expectedQueue);
        }));
    });
    describe('method: arePaused', () => {
        afterAll(() => {
            sinon_1.default.restore();
        });
        test('should return whether compliance conditions are paused or not', () => __awaiter(void 0, void 0, void 0, function* () {
            const fakeResult = false;
            const context = mocks_1.dsMockUtils.getContextInstance();
            const token = mocks_1.entityMockUtils.getSecurityTokenInstance();
            const rawTicker = mocks_1.dsMockUtils.createMockTicker(token.ticker);
            const mockBool = mocks_1.dsMockUtils.createMockBool(fakeResult);
            const requeriments = new Requirements_1.Requirements(token, context);
            sinon_1.default
                .stub(utilsConversionModule, 'stringToTicker')
                .withArgs(token.ticker, context)
                .returns(rawTicker);
            sinon_1.default.stub(utilsConversionModule, 'boolToBoolean').withArgs(mockBool).returns(fakeResult);
            mocks_1.dsMockUtils
                .createQueryStub('complianceManager', 'assetCompliances')
                .withArgs(rawTicker)
                // eslint-disable-next-line @typescript-eslint/naming-convention
                .resolves({ paused: mockBool });
            const result = yield requeriments.arePaused();
            expect(result).toEqual(fakeResult);
        }));
    });
    describe('method: checkSettle', () => {
        let context;
        let token;
        let requirements;
        let currentDid;
        let fromDid;
        let toDid;
        let rawFromDid;
        let rawToDid;
        let rawCurrentDid;
        let rawTicker;
        let stringToIdentityIdStub;
        let assetComplianceResultToRequirementComplianceStub;
        let stringToTickerStub;
        beforeAll(() => {
            fromDid = 'fromDid';
            toDid = 'toDid';
            stringToIdentityIdStub = sinon_1.default.stub(utilsConversionModule, 'stringToIdentityId');
            assetComplianceResultToRequirementComplianceStub = sinon_1.default.stub(utilsConversionModule, 'assetComplianceResultToCompliance');
            stringToTickerStub = sinon_1.default.stub(utilsConversionModule, 'stringToTicker');
        });
        beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
            context = mocks_1.dsMockUtils.getContextInstance();
            token = mocks_1.entityMockUtils.getSecurityTokenInstance();
            requirements = new Requirements_1.Requirements(token, context);
            ({ did: currentDid } = yield context.getCurrentIdentity());
            rawFromDid = mocks_1.dsMockUtils.createMockIdentityId(fromDid);
            rawToDid = mocks_1.dsMockUtils.createMockIdentityId(toDid);
            rawCurrentDid = mocks_1.dsMockUtils.createMockIdentityId(currentDid);
            rawTicker = mocks_1.dsMockUtils.createMockTicker(token.ticker);
            stringToIdentityIdStub.withArgs(currentDid, context).returns(rawCurrentDid);
            stringToIdentityIdStub.withArgs(fromDid, context).returns(rawFromDid);
            stringToIdentityIdStub.withArgs(toDid, context).returns(rawToDid);
            stringToTickerStub.withArgs(token.ticker, context).returns(rawTicker);
        }));
        afterAll(() => {
            sinon_1.default.restore();
        });
        test('checkSettle should return the current requirement compliance and whether the transfer complies', () => __awaiter(void 0, void 0, void 0, function* () {
            const rawResponse = 'response';
            mocks_1.dsMockUtils
                .createRpcStub('compliance', 'canTransfer')
                .withArgs(rawTicker, rawCurrentDid, rawToDid)
                .resolves(rawResponse);
            const fakeResult = 'result';
            assetComplianceResultToRequirementComplianceStub.withArgs(rawResponse).returns(fakeResult);
            const result = yield requirements.checkSettle({ to: toDid });
            expect(result).toEqual(fakeResult);
        }));
        test('checkSettle should return the current requirement compliance and whether the transfer complies with another Identity', () => __awaiter(void 0, void 0, void 0, function* () {
            const rawResponse = 'response';
            mocks_1.dsMockUtils
                .createRpcStub('compliance', 'canTransfer')
                .withArgs(rawTicker, rawFromDid, rawToDid)
                .resolves(rawResponse);
            const fakeResult = 'result';
            assetComplianceResultToRequirementComplianceStub.withArgs(rawResponse).returns(fakeResult);
            const result = yield requirements.checkSettle({ from: fromDid, to: toDid });
            expect(result).toBe(fakeResult);
        }));
    });
});
//# sourceMappingURL=Requirements.js.map