"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 Storage_1 = require("../../Storage");
const testHelper_1 = require("../testHelper");
const testStorageAdapter_1 = require("../testStorageAdapter");
describe('Persistence.PersistenceLayerTest', () => {
    const testsSubpath = 'Persistence/PersistenceLayer';
    /**
     * Errors are not thrown when invalid json is loaded into the corpus
     */
    it('TestInvalidJson', (done) => __awaiter(void 0, void 0, void 0, function* () {
        const testInputPath = testHelper_1.testHelper.getInputFolderPath(testsSubpath, 'TestInvalidJson');
        const corpus = new internal_1.CdmCorpusDefinition();
        corpus.setEventCallback((level, msg) => { }, internal_1.cdmStatusLevel.error);
        corpus.storage.mount('local', new Storage_1.LocalAdapter(testInputPath));
        corpus.storage.defaultNamespace = 'local';
        let failed = false;
        let invalidManifest;
        try {
            invalidManifest = yield corpus.fetchObjectAsync('local:/invalidManifest.manifest.cdm.json');
        }
        catch (e) {
            failed = true;
        }
        expect(failed)
            .toBeFalsy();
        expect(invalidManifest)
            .toBeUndefined();
        done();
    }));
    /**
     * Test setting SaveConfigFile to false and checking if the file is not saved.
     */
    it('testNotSavingConfigFile', () => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'testNotSavingConfigFile';
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName);
        // Load manifest from input folder.
        const manifest = yield corpus.fetchObjectAsync("default.manifest.cdm.json");
        // Move manifest to output folder.
        const outputFolder = corpus.storage.fetchRootFolder("output");
        for (const entityDec of manifest.entities) {
            var entity = yield corpus.fetchObjectAsync(entityDec.entityPath, manifest);
            outputFolder.documents.push(entity.inDocument);
        }
        outputFolder.documents.push(manifest);
        // Make sure the output folder is empty.
        testHelper_1.testHelper.deleteFilesFromActualOutput(testHelper_1.testHelper.getActualOutputFolderPath(testsSubpath, testName));
        // Save manifest to output folder.
        var co = new internal_1.copyOptions();
        co.saveConfigFile = false;
        yield manifest.saveAsAsync("default.manifest.cdm.json", false, co);
        // Compare the result.
        testHelper_1.testHelper.assertFolderFilesEquality(testHelper_1.testHelper.getExpectedOutputFolderPath(testsSubpath, testName), testHelper_1.testHelper.getActualOutputFolderPath(testsSubpath, testName));
    }));
    /**
     * Test that a document is fetched and saved using the correct persistence class,
     * regardless of the case sensitivity of the file name/extension.
     */
    it('TestFetchingAndSavingDocumentsWithCaseInsensitiveCheck', (done) => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestFetchingAndSavingDocumentsWithCaseInsensitiveCheck';
        const testInputPath = testHelper_1.testHelper.getInputFolderPath(testsSubpath, testName);
        const corpus = new internal_1.CdmCorpusDefinition();
        corpus.setEventCallback(() => { }, internal_1.cdmStatusLevel.error);
        const localAdapter = new Storage_1.LocalAdapter(testInputPath);
        const remoteAdapter = new Storage_1.RemoteAdapter(new Map([['contoso', 'http://contoso.com']]));
        corpus.storage.mount('local', localAdapter);
        corpus.storage.mount('remote', remoteAdapter);
        corpus.storage.unMount('cdm');
        corpus.storage.defaultNamespace = 'local';
        const manifest = yield corpus.fetchObjectAsync('empty.Manifest.cdm.json');
        const manifestFromModelJson = yield corpus.fetchObjectAsync('Model.json');
        // Swap out the adapter for a fake one so that we aren't actually saving files.
        const allDocs = new Map();
        const testAdapter = new testStorageAdapter_1.TestStorageAdapter(allDocs);
        corpus.storage.setAdapter('local', testAdapter);
        const newManifestName = 'empty.MANIFEST.CDM.json';
        yield manifest.saveAsAsync(newManifestName, true);
        // Verify that manifest persistence was called by comparing the saved document to the original manifest.
        let serializedManifest = allDocs.get(`/${newManifestName}`);
        let expectedOutputManifest = testHelper_1.testHelper.getExpectedOutputFileContent(testsSubpath, testName, manifest.name);
        testHelper_1.testHelper.assertSameObjectWasSerialized(expectedOutputManifest, serializedManifest);
        const newManifestFromModelJsonName = 'MODEL.json';
        yield manifestFromModelJson.saveAsAsync(newManifestFromModelJsonName, true);
        // Verify that model.json persistence was called by comparing the saved document to the original model.json.
        serializedManifest = allDocs.get(`/${newManifestFromModelJsonName}`);
        expectedOutputManifest = testHelper_1.testHelper.getExpectedOutputFileContent(testsSubpath, testName, manifestFromModelJson.name);
        testHelper_1.testHelper.assertSameObjectWasSerialized(expectedOutputManifest, serializedManifest);
        done();
    }));
    /**
     * Test that saving a model.json that isn't named exactly as such fails to save.
     */
    it('TestSavingInvalidModelJsonName', (done) => __awaiter(void 0, void 0, void 0, function* () {
        const corpus = new internal_1.CdmCorpusDefinition();
        corpus.setEventCallback(() => { }, internal_1.cdmStatusLevel.error);
        corpus.storage.unMount('cdm');
        corpus.storage.defaultNamespace = 'local';
        const manifest = new internal_1.CdmManifestDefinition(corpus.ctx, 'manifest');
        corpus.storage.fetchRootFolder('local').documents
            .push(manifest);
        const allDocs = new Map();
        const testAdapter = new testStorageAdapter_1.TestStorageAdapter(allDocs);
        corpus.storage.setAdapter('local', testAdapter);
        const newManifestFromModelJsonName = 'my.model.json';
        yield manifest.saveAsAsync(newManifestFromModelJsonName, true);
        // TODO: because we can load documents properly now, SaveAsAsync returns false.
        // Will check the value returned from SaveAsAsync() when the problem is solved
        expect(allDocs.has(`/${newManifestFromModelJsonName}`))
            .toBeFalsy();
        done();
    }));
    /**
     * Test that loading a model.json that isn't named exactly as such fails to load.
     */
    it('TestLoadingInvalidModelJsonName', (done) => __awaiter(void 0, void 0, void 0, function* () {
        const testInputPath = testHelper_1.testHelper.getInputFolderPath(testsSubpath, 'TestLoadingInvalidModelJsonName');
        const corpus = new internal_1.CdmCorpusDefinition();
        corpus.setEventCallback(() => { }, internal_1.cdmStatusLevel.error);
        corpus.storage.mount('local', new Storage_1.LocalAdapter(testInputPath));
        corpus.storage.defaultNamespace = 'local';
        // We are trying to load a file with an invalid name, so fetchObjectAsync should just return null.
        const invalidModelJson = yield corpus.fetchObjectAsync('test.model.json');
        expect(invalidModelJson)
            .toBeUndefined();
        done();
    }));
    /**
     * Testing that type attribute properties (ex. IsReadOnly, isPrimaryKey) are not persisted in model.json format.
     */
    it('TestModelJsonTypeAttributePersistence', (done) => __awaiter(void 0, void 0, void 0, function* () {
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestModelJsonTypeAttributePersistence');
        // we need to create a second adapter to the output folder to fool the OM into thinking it's different
        // this is because there is a bug currently that prevents us from saving and then loading a model.json
        corpus.storage.mount('alternateOutput', new Storage_1.LocalAdapter(testHelper_1.testHelper.getActualOutputFolderPath(testsSubpath, 'TestModelJsonTypeAttributePersistence')));
        // create manifest
        const entityName = 'TestTypeAttributePersistence';
        const localRoot = corpus.storage.fetchRootFolder('local');
        const outputRoot = corpus.storage.fetchRootFolder('output');
        const manifest = corpus.MakeObject(internal_1.cdmObjectType.manifestDef, 'tempAbstract');
        manifest.imports.push('cdm:/foundations.cdm.json', undefined);
        localRoot.documents.push(manifest);
        // create entity
        const doc = corpus.MakeObject(internal_1.cdmObjectType.documentDef, `${entityName}.cdm.json`);
        doc.imports.push('cdm:/foundations.cdm.json', undefined);
        localRoot.documents.push(doc, doc.name);
        const entityDef = doc.definitions.push(internal_1.cdmObjectType.entityDef, entityName);
        // create type attribute
        const cdmTypeAttributeDefinition = corpus.MakeObject(internal_1.cdmObjectType.typeAttributeDef, entityName, false);
        cdmTypeAttributeDefinition.isReadOnly = true;
        entityDef.attributes.push(cdmTypeAttributeDefinition);
        manifest.entities.push(entityDef);
        const manifestResolved = yield manifest.createResolvedManifestAsync('default', undefined);
        outputRoot.documents.push(manifestResolved);
        manifestResolved.imports.push('cdm:/foundations.cdm.json');
        yield manifestResolved.saveAsAsync('model.json', true);
        const newManifest = yield corpus.fetchObjectAsync('alternateOutput:/model.json');
        const newEnt = yield corpus.fetchObjectAsync(newManifest.entities.allItems[0].entityPath, manifest);
        const typeAttribute = newEnt.attributes.allItems[0];
        expect(typeAttribute.isReadOnly)
            .toBeTruthy();
        done();
    }));
    /**
     * Test that the persistence layer handles the case when the persistence format cannot be found.
     */
    it('TestMissingPersistenceFormat', (done) => __awaiter(void 0, void 0, void 0, function* () {
        const expectedLogCodes = new Set([internal_1.cdmLogCode.ErrPersistClassMissing]);
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestMissingPersistenceFormat', undefined, false, expectedLogCodes);
        const folder = corpus.storage.fetchRootFolder(corpus.storage.defaultNamespace);
        const manifest = corpus.MakeObject(internal_1.cdmObjectType.manifestDef, 'someManifest');
        folder.documents.push(manifest);
        // trying to save to an unsupported format should return false and not fail
        const succeded = yield manifest.saveAsAsync('manifest.unSupportedExtension');
        expect(succeded)
            .toBeFalsy();
        done();
    }));
    /**
     * Test that the persistence layer handles the case when the document is empty.
     */
    it('TestLoadingEmptyJsonData', (done) => __awaiter(void 0, void 0, void 0, function* () {
        const testName = 'TestLoadingEmptyJsonData';
        const expectedLogCodes = new Set([internal_1.cdmLogCode.ErrPersistFileReadFailure]);
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, testName, null, false, expectedLogCodes, false);
        const manifest = yield corpus.fetchObjectAsync('empty.Manifest.cdm.json');
        expect(manifest).toBeUndefined();
        testHelper_1.testHelper.expectCdmLogCodeEquality(corpus, internal_1.cdmLogCode.ErrPersistFileReadFailure, true);
        done();
    }));
});
//# sourceMappingURL=PersistenceLayer.test.js.map