"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 internal_1 = require("../../../../internal");
const Persistence_1 = require("../../../../Persistence");
const ManifestPersistence_1 = require("../../../../Persistence/CdmFolder/ManifestPersistence");
const Storage_1 = require("../../../../Storage");
const timeUtils = require("../../../../Utilities/timeUtils");
const testHelper_1 = require("../../../testHelper");
// tslint:disable-next-line: max-func-body-length
describe('Persistence.CdmFolder.Manifest', () => {
    /// <summary>
    /// The path between TestDataPath and TestName.
    /// </summary>
    const testsSubpath = 'Persistence/CdmFolder/Manifest';
    /**
     * Testing for manifest impl instance with no entities and no submanifests.
     */
    it('TestLoadFolderWithNoEntityFolders', () => {
        const content = testHelper_1.testHelper.getInputFileContent(testsSubpath, 'TestLoadFolderWithNoEntityFolders', 'empty.manifest.cdm.json');
        const cdmManifest = Persistence_1.CdmFolder.ManifestPersistence.fromObject(new internal_1.resolveContext(new internal_1.CdmCorpusDefinition(), undefined), 'cdmTest', 'someNamespace', '/', JSON.parse(content));
        expect(cdmManifest.getName())
            .toBe('cdmTest');
        expect(cdmManifest.manifestName)
            .toBe('cdmTest');
        expect(cdmManifest.schema)
            .toBe('CdmManifestDefinition.cdm.json');
        expect(cdmManifest.jsonSchemaSemanticVersion)
            .toBe('1.0.0');
        expect(cdmManifest.lastFileModifiedTime.toUTCString())
            .toBe('Mon, 15 Sep 2008 23:53:23 GMT');
        expect(cdmManifest.explanation)
            .toBe('test cdm folder for cdm version 1.0+');
        expect(cdmManifest.imports.length)
            .toBe(1);
        expect(cdmManifest.imports.allItems[0].corpusPath)
            .toBe('/primitives.cdm.json');
        expect(cdmManifest.entities.length)
            .toBe(0);
        expect(cdmManifest.exhibitsTraits.length)
            .toBe(1);
        expect(cdmManifest.subManifests.length)
            .toBe(0);
    });
    /**
     * Tests for manifests with everything.
     */
    it('TestManifestWithEverything', () => {
        let content = testHelper_1.testHelper.getInputFileContent(testsSubpath, 'TestManifestWithEverything', 'complete.manifest.cdm.json');
        let cdmManifest = Persistence_1.CdmFolder.ManifestPersistence.fromObject(new internal_1.resolveContext(new internal_1.CdmCorpusDefinition(), undefined), 'docName', 'someNamespace', '', JSON.parse(content));
        expect(cdmManifest.subManifests.length)
            .toBe(1);
        expect(cdmManifest.entities.length)
            .toBe(2);
        expect(cdmManifest.manifestName)
            .toBe('cdmTest');
        content = testHelper_1.testHelper.getInputFileContent(testsSubpath, 'TestManifestWithEverything', 'noname.manifest.cdm.json');
        cdmManifest = Persistence_1.CdmFolder.ManifestPersistence.fromObject(new internal_1.resolveContext(new internal_1.CdmCorpusDefinition(), undefined), 'docName.manifest.cdm.json', 'someNamespace', '/', JSON.parse(content));
        expect(cdmManifest.subManifests.length)
            .toBe(1);
        expect(cdmManifest.entities.length)
            .toBe(2);
        expect(cdmManifest.manifestName)
            .toBe('docName');
    });
    /**
     * Tests for back-comp folio loading.
     */
    it('TestFolioWithEverything', () => {
        let content = testHelper_1.testHelper.getInputFileContent(testsSubpath, 'TestFolioWithEverything', 'complete.folio.cdm.json');
        let cdmManifest = Persistence_1.CdmFolder.ManifestPersistence.fromObject(new internal_1.resolveContext(new internal_1.CdmCorpusDefinition(), undefined), 'docName', 'someNamespace', '', JSON.parse(content));
        expect(cdmManifest.subManifests.length)
            .toBe(1);
        expect(cdmManifest.entities.length)
            .toBe(2);
        expect(cdmManifest.manifestName)
            .toBe('cdmTest');
        content = testHelper_1.testHelper.getInputFileContent(testsSubpath, 'TestFolioWithEverything', 'noname.folio.cdm.json');
        cdmManifest = Persistence_1.CdmFolder.ManifestPersistence.fromObject(new internal_1.resolveContext(new internal_1.CdmCorpusDefinition(), undefined), 'docName.folio.cdm.json', 'someNamespace', '/', JSON.parse(content));
        expect(cdmManifest.subManifests.length)
            .toBe(1);
        expect(cdmManifest.entities.length)
            .toBe(2);
        expect(cdmManifest.manifestName)
            .toBe('docName');
    });
    /**
     * Test for copy data.
     */
    it('TestManifestForCopyData', () => {
        const content = testHelper_1.testHelper.getInputFileContent(testsSubpath, 'TestManifestForCopyData', 'complete.manifest.cdm.json');
        const cdmManifest = Persistence_1.CdmFolder.ManifestPersistence.fromObject(new internal_1.resolveContext(new internal_1.CdmCorpusDefinition(), undefined), 'cdmTest', 'someNamespace', '/', JSON.parse(content));
        const manifestObject = ManifestPersistence_1.ManifestPersistence.toData(cdmManifest, undefined, undefined);
        expect(manifestObject.$schema)
            .toBe('CdmManifestDefinition.cdm.json');
        expect(manifestObject.jsonSchemaSemanticVersion)
            .toBe('1.0.0');
        expect(manifestObject.documentVersion)
            .toBe('2.0.0');
        expect(manifestObject.manifestName)
            .toBe('cdmTest');
        expect(manifestObject.explanation)
            .toBe('test cdm folder for cdm version 1.0+');
        expect(manifestObject.imports.length)
            .toBe(1);
        expect(manifestObject.imports[0].corpusPath)
            .toBe('/primitives.cdm.json');
        expect(manifestObject.exhibitsTraits.length)
            .toBe(1);
        expect(manifestObject.entities.length)
            .toBe(2);
        expect(manifestObject.entities[0].entityName)
            .toBe('testEntity');
        expect(manifestObject.subManifests.length)
            .toBe(1);
        expect(manifestObject.subManifests[0].definition)
            .toBe('test definition');
        expect(manifestObject.lastFileModifiedTime)
            .toBeUndefined();
    });
    /**
     * Test modified times for manifest and files beneath it
     * (loads and sets modified times correctly)
     */
    it('TestLoadsAndSetsTimesCorrectly', () => __awaiter(void 0, void 0, void 0, function* () {
        const timeBeforeLoad = new Date();
        const inputPath = testHelper_1.testHelper.getInputFolderPath(testsSubpath, 'TestLoadsAndSetsTimesCorrectly');
        const cdmCorpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestLoadsAndSetsTimesCorrectly');
        cdmCorpus.setEventCallback((level, msg) => {
            throw new Error('Unexpected log: ' + msg);
        }, internal_1.cdmStatusLevel.warning);
        cdmCorpus.storage.mount('someNamespace', new Storage_1.LocalAdapter(inputPath));
        const cdmManifest = yield cdmCorpus.fetchObjectAsync('someNamespace:/default.manifest.cdm.json');
        const statusTimeAtLoad = cdmManifest.lastFileStatusCheckTime;
        // hard coded because the time comes from inside the file
        expect(timeUtils.getFormattedDateString(statusTimeAtLoad))
            .toBe('2019-02-01T15:36:19.410Z');
        // waits 100 milliseconds
        // tslint:disable-next-line: no-string-based-set-timeout
        yield new Promise((resolve) => setTimeout(resolve, 100));
        expect(!!cdmManifest._fileSystemModifiedTime)
            .toBe(true);
        expect(cdmManifest._fileSystemModifiedTime < timeBeforeLoad)
            .toBe(true);
        yield cdmManifest.fileStatusCheckAsync();
        expect(cdmManifest.lastFileStatusCheckTime > timeBeforeLoad)
            .toBe(true);
        expect(cdmManifest.lastFileStatusCheckTime > statusTimeAtLoad)
            .toBe(true);
        expect(cdmManifest.subManifests.length)
            .toBe(1);
        expect(cdmManifest.subManifests.allItems[0].lastFileStatusCheckTime > timeBeforeLoad)
            .toBe(true);
        expect(cdmManifest.entities.length)
            .toBe(1);
        expect(cdmManifest.entities.allItems[0].dataPartitions.length)
            .toBe(1);
        const entity = cdmManifest.entities.allItems[0];
        const subManifest = cdmManifest.subManifests.allItems[0];
        const maxTime = timeUtils.maxTime(entity.lastFileModifiedTime, subManifest.lastFileModifiedTime);
        expect(timeUtils.getFormattedDateString(cdmManifest.lastChildFileModifiedTime))
            .toBe(timeUtils.getFormattedDateString(maxTime));
    }));
    /**
     * Checks Absolute corpus path can be created with valid input.
     */
    it('TestValidRootPath', () => {
        const corpus = new internal_1.CdmCorpusDefinition();
        // Set empty callback to avoid breaking tests due too many errors in logs,
        // change the event callback to console or file status report if wanted.
        // tslint:disable-next-line: no-empty
        corpus.setEventCallback(() => { }, internal_1.cdmStatusLevel.error);
        // checks with null object
        let absolutePath = corpus.storage.createAbsoluteCorpusPath('Abc/Def');
        expect(absolutePath)
            .toEqual('/Abc/Def');
        absolutePath = corpus.storage.createAbsoluteCorpusPath('/Abc/Def');
        expect(absolutePath)
            .toEqual('/Abc/Def');
        absolutePath = corpus.storage.createAbsoluteCorpusPath('cdm:/Abc/Def');
        expect(absolutePath)
            .toEqual('cdm:/Abc/Def');
        const obj = new internal_1.CdmManifestDefinition(undefined, undefined);
        obj.namespace = '';
        obj.folderPath = 'Mnp/Qrs/';
        absolutePath = corpus.storage.createAbsoluteCorpusPath('Abc/Def', obj);
        expect(absolutePath)
            .toEqual('Mnp/Qrs/Abc/Def');
        obj.namespace = 'cdm';
        obj.folderPath = 'Mnp/Qrs/';
        absolutePath = corpus.storage.createAbsoluteCorpusPath('/Abc/Def', obj);
        expect(absolutePath)
            .toEqual('cdm:/Abc/Def');
        obj.namespace = 'cdm';
        obj.folderPath = 'Mnp/Qrs/';
        absolutePath = corpus.storage.createAbsoluteCorpusPath('Abc/Def', obj);
        expect(absolutePath)
            .toEqual('cdm:Mnp/Qrs/Abc/Def');
    });
    /**
     * FolderPath should always end in a /
     * This checks the behavior if FolderPath does not end with a /
     * ( '/' should be appended and a warning be sent through callback function)
     */
    it('TestPathThatDoesNotEndInSlash', () => {
        var expectedLogCodes = new Set([internal_1.cdmLogCode.WarnStorageExpectedPathPrefix]);
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestPathThatDoesNotEndInSlash', undefined, false, expectedLogCodes, true);
        const obj = new internal_1.CdmManifestDefinition(undefined, undefined);
        obj.folderPath = 'Mnp';
        obj.namespace = 'cdm';
        const absolutePath = corpus.storage.createAbsoluteCorpusPath('Abc', obj);
        expect(absolutePath)
            .toEqual('cdm:Mnp/Abc');
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.WarnStorageExpectedPathPrefix, true);
    });
    /**
     * Tests absolute paths cannot be created with wrong parameters.
     * Checks behavior if objectPath is invalid.
     */
    it('TestPathRootInvalidObjectPath', () => {
        var expectedLogCodes = new Set([internal_1.cdmLogCode.ErrStorageInvalidPathFormat]);
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestPathRootInvalidObjectPath', undefined, false, expectedLogCodes, true);
        corpus.storage.createAbsoluteCorpusPath('./Abc');
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
        corpus.storage.createAbsoluteCorpusPath('/./Abc');
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
        corpus.storage.createAbsoluteCorpusPath('../Abc');
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
        corpus.storage.createAbsoluteCorpusPath('Abc/../Def');
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
    });
    /**
     * Tests absolute paths cannot be created with wrong parameters.
     * Checks behavior if FolderPath is invalid.
     */
    it('TestPathRootInvalidFolderPath', () => {
        var expectedLogCodes = new Set([internal_1.cdmLogCode.ErrStorageInvalidPathFormat]);
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestPathRootInvalidFolderPath', undefined, false, expectedLogCodes, true);
        let obj = new internal_1.CdmManifestDefinition(undefined, undefined);
        obj.namespace = 'cdm';
        obj.folderPath = './Mnp';
        corpus.storage.createAbsoluteCorpusPath('Abc', obj);
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
        obj = new internal_1.CdmManifestDefinition(undefined, undefined);
        obj.namespace = 'cdm';
        obj.folderPath = '/./Mnp';
        corpus.storage.createAbsoluteCorpusPath('Abc', obj);
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
        obj = new internal_1.CdmManifestDefinition(undefined, undefined);
        obj.namespace = 'cdm';
        obj.folderPath = '../Mnp';
        corpus.storage.createAbsoluteCorpusPath('Abc', obj);
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
        obj = new internal_1.CdmManifestDefinition(undefined, undefined);
        obj.namespace = 'cdm';
        obj.folderPath = 'Mnp/./Qrs';
        corpus.storage.createAbsoluteCorpusPath('Abc', obj);
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
        obj = new internal_1.CdmManifestDefinition(undefined, undefined);
        obj.namespace = 'cdm';
        obj.folderPath = 'Mnp/../Qrs';
        corpus.storage.createAbsoluteCorpusPath('Abc', obj);
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrStorageInvalidPathFormat, true);
    });
    /**
     * Testpassing blank or empty values for manifest schema, name etc.
     */
    it('TestManifestWithBlankFields', () => {
        const content = testHelper_1.testHelper.getInputFileContent(testsSubpath, 'testManifestWithBlankFields', 'blank.manifest.cdm.json');
        const cdmManifest = Persistence_1.CdmFolder.ManifestPersistence.fromObject(new internal_1.resolveContext(new internal_1.CdmCorpusDefinition(), undefined), 'cdmTest', 'someNamespace', '/', JSON.parse(content));
        expect(cdmManifest.getName())
            .toBe('cdmTest');
        expect(cdmManifest.schema)
            .toBeUndefined();
        expect(cdmManifest.documentVersion)
            .toBeUndefined();
        expect(cdmManifest.lastFileModifiedTime.toUTCString())
            .toBe('Mon, 15 Sep 2008 23:53:23 GMT');
        expect(cdmManifest.explanation)
            .toBe('test cdm folder for cdm version 1.0+');
        expect(cdmManifest.imports.length)
            .toBe(1);
        expect(cdmManifest.imports.allItems[0].corpusPath)
            .toBe('/primitives.cdm.json');
        expect(cdmManifest.entities.length)
            .toBe(0);
        expect(cdmManifest.exhibitsTraits.length)
            .toBe(1);
        expect(cdmManifest.subManifests.length)
            .toBe(0);
    });
});
//# sourceMappingURL=ManifestImpl.test.js.map