"use strict";
var yok_1 = require("../../yok");
var util_1 = require("util");
var path_1 = require("path");
var messages_service_1 = require("../../services/messages-service");
var fs_1 = require("fs");
var chai_1 = require("chai");
var Future = require("fibers/future");
function createTestInjector(jsonContents, options) {
    var testInjector = new yok_1.Yok();
    testInjector.register("fs", {
        exists: function (path) { return Future.fromResult(options && options.useRealFsExists ? fs_1.existsSync(path) : true); },
        readJson: function (filename, encoding) { return Future.fromResult(jsonContents); }
    });
    testInjector.register("messagesService", messages_service_1.MessagesService);
    return testInjector;
}
describe("messages-service", function () {
    var service;
    describe("pathsToMessageJsonFiles property", function () {
        it("initializes with the default json file", function () {
            var injector = createTestInjector({});
            service = injector.resolve("$messagesService");
            chai_1.assert.deepEqual(1, service.pathsToMessageJsonFiles.length, "Messages service should initialize with a default json file.");
        });
        it("appends the default json file when setting pathsToMessageJsonFiles", function () {
            var injector = createTestInjector({}, { useRealFsExists: false });
            service = injector.resolve("$messagesService");
            service.pathsToMessageJsonFiles = ["someHackyJsonFile.json"];
            chai_1.assert.deepEqual(2, service.pathsToMessageJsonFiles.length, "Messages service should append the default json file.");
        });
        it("should throw if non-existent json file is provided", function () {
            var injector = createTestInjector({}, { useRealFsExists: true });
            service = injector.resolve("$messagesService");
            chai_1.assert.throws(function () { service.pathsToMessageJsonFiles = ["someJsonFile.json"]; }, "someJsonFile.json does not exist");
        });
    });
    describe("getMessage", function () {
        it("returns the given message if not found as key in any json file", function () {
            var injector = createTestInjector({});
            service = injector.resolve("$messagesService");
            var stringMessage = "Some message", resultMessage = service.getMessage(stringMessage);
            chai_1.assert.deepEqual(stringMessage, resultMessage, "Messages service should return the given message if not found as key in any json file in `pathsToMessageJsonFiles` property.");
        });
        it("util.formats the given message if not found as key in any json file and contains special symbol (%s,%d, etc.)", function () {
            var injector = createTestInjector({});
            service = injector.resolve("$messagesService");
            var messageFormat = "Some %s message.", formatArg = "formatted", expectedMessage = util_1.format(messageFormat, formatArg), resultMessage = service.getMessage(messageFormat, formatArg);
            chai_1.assert.deepEqual(expectedMessage, resultMessage, "Messages service should apply util.format.");
        });
        it("should return correct value from json file if found in json message files", function () {
            var jsonContents = { KEY: "Value" }, injector = createTestInjector(jsonContents);
            service = injector.resolve("$messagesService");
            chai_1.assert.deepEqual(jsonContents.KEY, service.getMessage("KEY"), "Messages service should return correct value from json file by given key.");
        });
        it("should util.format value from json file if found in json message files and contains special symbol (%s,%d, etc.)", function () {
            var jsonContents = { KEY: "%s value" }, injector = createTestInjector(jsonContents);
            service = injector.resolve("$messagesService");
            var formatArg = "Formatted", expectedMessage = util_1.format(jsonContents.KEY, formatArg), actualMessage = service.getMessage(jsonContents.KEY, formatArg);
            chai_1.assert.deepEqual(expectedMessage, actualMessage, "Messages service should util.format value from json file by given key when value is format.");
        });
        it("should return correct value from json file if found in json message files with complex key", function () {
            var jsonContents = {
                KEY: {
                    NESTED_KEY: "Value"
                }
            }, injector = createTestInjector(jsonContents);
            service = injector.resolve("$messagesService");
            chai_1.assert.deepEqual(jsonContents.KEY.NESTED_KEY, service.getMessage("KEY.NESTED_KEY"), "Messages service should return correct value from json file by given complex key.");
        });
        it("should return correct value from json file if found in client json before common json", function () {
            var commonJsonContents = {
                KEY: "Value"
            }, clientJsonContents = {
                KEY: "Overriden value"
            }, pathToDefaultMessageJson = path_1.join(__dirname, "..", "..", "resources", "messages", "errorMessages.json"), injector = createTestInjector({});
            injector.register("fs", {
                exists: function (path) { return Future.fromResult(true); },
                readJson: function (filename, encoding) { return Future.fromResult(filename === pathToDefaultMessageJson ? commonJsonContents : clientJsonContents); }
            });
            service = injector.resolve("$messagesService");
            service.pathsToMessageJsonFiles = ["clientJsonFile.json"];
            chai_1.assert.notDeepEqual(commonJsonContents.KEY, service.getMessage("KEY"), "Messages service should return correct value from json file when value is overriden by client.");
            chai_1.assert.deepEqual(clientJsonContents.KEY, service.getMessage("KEY"), "Messages service should return correct value from json file when value is overriden by client.");
        });
    });
});
