"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const testHelper_1 = require("../../testHelper");
const projectionTestUtils_1 = require("../../Utilities/projectionTestUtils");
const TypeAttributeParam_1 = require("./TypeAttributeParam");
const ProjectionOMTestUtil_1 = require("./ProjectionOMTestUtil");
/**
 * A test class for testing the CombineAttributes operation in a projection as well as Select 'one' in a resolution guidance
 */
describe('Cdm/Projection/ProjectionCombineTest', () => {
    /**
     * All possible combinations of the different resolution directives
     */
    const resOptsCombinations = [
        [],
        ['referenceOnly'],
        ['normalized'],
        ['structured'],
        ['referenceOnly', 'normalized'],
        ['referenceOnly', 'structured'],
        ['normalized', 'structured'],
        ['referenceOnly', 'normalized', 'structured']
    ];
    /**
     * The path between TestDataPath and TestName.
     */
    const testsSubpath = 'Cdm/Projection/ProjectionCombineTest';
    /**
     * Test Entity Extends with a Resolution Guidance that selects 'one'
     */
    it('TestExtends', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestExtends';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test Entity Extends with a Combine Attributes operation
     */
    it('TestExtendsProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestExtendsProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test Entity Attribute with a Resolution Guidance that selects 'one'
     */
    it('TestEA', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestEA';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test Entity Attribute with a Combine Attributes operation
     */
    it('TestEAProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestEAProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test Entity Attribute with a Combine Attributes operation but IsPolymorphicSource flag set to false
     */
    it('TestNonPolymorphicProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestNonPolymorphicProj';
        const entityName = 'NewPerson';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        const entity = yield corpus.fetchObjectAsync(`local:/${entityName}.cdm.json/${entityName}`);
        const resolvedEntity = yield projectionTestUtils_1.projectionTestUtils.getResolvedEntity(corpus, entity, []);
        // Original set of attributes: ['name', 'age', 'address', 'phoneNumber', 'email']
        // Combined attributes ['phoneNumber', 'email'] into 'contactAt'
        expect(resolvedEntity.attributes.length)
            .toEqual(4);
        expect(resolvedEntity.attributes.allItems[0].name)
            .toEqual('name');
        expect(resolvedEntity.attributes.allItems[1].name)
            .toEqual('age');
        expect(resolvedEntity.attributes.allItems[2].name)
            .toEqual('address');
        expect(resolvedEntity.attributes.allItems[3].name)
            .toEqual('contactAt');
    }));
    /**
     * Test a Combine Attributes operation with an empty select list
     */
    it('TestEmptyProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestEmptyProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test a collection of Combine Attributes operation
     */
    it('TestCollProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestCollProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test Nested Combine Attributes operations
     */
    it('TestNestedProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestNestedProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test Multiple Nested Operations with Combine including ArrayExpansion and Rename
     */
    it('TestMultiProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestMultiProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            if (resOpt.includes('structured')) {
                // Array expansion is not supported on an attribute group yet.
                continue;
            }
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test a Combine Attributes operation with condition set to false
     */
    it('TestCondProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestCondProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test Nested Combine with Rename Operation
     */
    it('TestRenProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestRenProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            if (resOpt.includes('structured')) {
                // Rename attributes is not supported on an attribute group yet.
                continue;
            }
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test Entity Attribute with a Combine Attributes operation that selects a common already 'merged' attribute (e.g. IsPrimary)
     */
    it('TestCommProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestCommProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test a Combine Attributes operation by selecting missing attributes
     */
    it('TestMissProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestMissProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test a Combine Attributes operation with a different sequence of selection attributes
     */
    it('TestSeqProj', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestSeqProj';
        const entityName = 'Customer';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        for (const resOpt of resOptsCombinations) {
            yield projectionTestUtils_1.projectionTestUtils.loadEntityForResolutionOptionAndSave(corpus, testName, testsSubpath, entityName, resOpt);
        }
    }));
    /**
     * Test for object model
     */
    it('TestEAProjOM', () => __awaiter(void 0, void 0, void 0, function* () {
        const className = 'TestProjectionCombine';
        const testName = 'TestEAProjOM';
        const entityName_Email = 'Email';
        const attributeParams_Email = [];
        attributeParams_Email.push(new TypeAttributeParam_1.TypeAttributeParam(`EmailID`, `string`, `identifiedBy`));
        attributeParams_Email.push(new TypeAttributeParam_1.TypeAttributeParam(`Address`, `string`, `hasA`));
        attributeParams_Email.push(new TypeAttributeParam_1.TypeAttributeParam(`IsPrimary`, `boolean`, `hasA`));
        const entityName_Phone = 'Phone';
        const attributeParams_Phone = [];
        attributeParams_Phone.push(new TypeAttributeParam_1.TypeAttributeParam(`PhoneID`, `string`, `identifiedBy`));
        attributeParams_Phone.push(new TypeAttributeParam_1.TypeAttributeParam(`Number`, `string`, `hasA`));
        attributeParams_Phone.push(new TypeAttributeParam_1.TypeAttributeParam(`IsPrimary`, `boolean`, `hasA`));
        const entityName_Social = 'Social';
        const attributeParams_Social = [];
        attributeParams_Social.push(new TypeAttributeParam_1.TypeAttributeParam(`SocialID`, `string`, `identifiedBy`));
        attributeParams_Social.push(new TypeAttributeParam_1.TypeAttributeParam(`Account`, `string`, `hasA`));
        attributeParams_Social.push(new TypeAttributeParam_1.TypeAttributeParam(`IsPrimary`, `boolean`, `hasA`));
        const entityName_Customer = 'Customer';
        const attributeParams_Customer = [];
        attributeParams_Customer.push(new TypeAttributeParam_1.TypeAttributeParam(`CustomerName`, `string`, `hasA`));
        const selectedAttributes = [`EmailID`, `PhoneID`, `SocialID`];
        const util = new ProjectionOMTestUtil_1.ProjectionOMTestUtil(className, testName);
        const entity_Email = util.CreateBasicEntity(entityName_Email, attributeParams_Email);
        util.validateBasicEntity(entity_Email, entityName_Email, attributeParams_Email);
        const entity_Phone = util.CreateBasicEntity(entityName_Phone, attributeParams_Phone);
        util.validateBasicEntity(entity_Phone, entityName_Phone, attributeParams_Phone);
        const entity_Social = util.CreateBasicEntity(entityName_Social, attributeParams_Social);
        util.validateBasicEntity(entity_Social, entityName_Social, attributeParams_Social);
        const entity_Customer = util.CreateBasicEntity(entityName_Customer, attributeParams_Customer);
        util.validateBasicEntity(entity_Customer, entityName_Customer, attributeParams_Customer);
        const projection_Customer = util.createProjection(entity_Customer.entityName);
        const typeAttribute_MergeInto = util.createTypeAttribute(`MergeInto`, `string`, `hasA`);
        const operation_CombineAttributes = util.createOperationCombineAttributes(projection_Customer, selectedAttributes, typeAttribute_MergeInto);
        const projectionEntityRef_Customer = util.createProjectionInlineEntityReference(projection_Customer);
        const entityAttribute_ContactAt = util.createEntityAttribute(`ContactAt`, projectionEntityRef_Customer);
        entity_Customer.attributes.push(entityAttribute_ContactAt);
        for (const resOpts of resOptsCombinations) {
            yield util.getAndValidateResolvedEntity(entity_Customer, resOpts);
        }
        yield util.defaultManifest.saveAsAsync(util.manifestDocName, true);
    }));
});
//# sourceMappingURL=ProjectionCombine.test.js.map