diff --git a/package-lock.json b/package-lock.json index 9f19b17f..095c35e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -376,6 +376,41 @@ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "optional": true }, + "@sinonjs/commons": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", + "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, "@stylelint/postcss-css-in-js": { "version": "0.37.2", "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz", @@ -3943,6 +3978,12 @@ "verror": "1.10.0" } }, + "just-extend": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz", + "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", + "dev": true + }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -4021,6 +4062,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -4527,6 +4574,36 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "nise": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", + "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, "node-ical": { "version": "0.12.7", "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.12.7.tgz", @@ -6149,6 +6226,37 @@ } } }, + "sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/package.json b/package.json index 56910da6..5473d04d 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "nyc": "^15.1.0", "prettier": "^2.2.1", "pretty-quick": "^3.1.0", + "sinon": "^9.2.4", "spectron": "^10.0.1", "stylelint": "^13.8.0", "stylelint-config-prettier": "^8.0.2", diff --git a/tests/e2e/translations_spec.js b/tests/e2e/translations_spec.js index a66d0ea4..639f8f12 100644 --- a/tests/e2e/translations_spec.js +++ b/tests/e2e/translations_spec.js @@ -7,6 +7,7 @@ const translations = require("../../translations/translations.js"); const helmet = require("helmet"); const { JSDOM } = require("jsdom"); const express = require("express"); +const sinon = require("sinon"); describe("Translations", function () { let server; @@ -34,6 +35,79 @@ describe("Translations", function () { } }); + describe("loadTranslations", () => { + let dom; + + beforeEach(() => { + dom = new JSDOM( + `\ + \ + `, + { runScripts: "dangerously", resources: "usable" } + ); + }); + + it("should load translation file", (done) => { + dom.window.onload = async function () { + const { Translator, Module, config } = dom.window; + config.language = "en"; + Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + + Module.register("name", { getTranslations: () => translations }); + const MMM = Module.create("name"); + + const loaded = sinon.stub(); + MMM.loadTranslations(loaded); + + expect(loaded.callCount).to.equal(1); + expect(Translator.load.args.length).to.equal(1); + expect(Translator.load.calledWith(MMM, "translations/en.json", false, sinon.match.func)).to.be.true; + + done(); + }; + }); + + it("should load translation + fallback file", (done) => { + dom.window.onload = async function () { + const { Translator, Module } = dom.window; + Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + + Module.register("name", { getTranslations: () => translations }); + const MMM = Module.create("name"); + + const loaded = sinon.stub(); + MMM.loadTranslations(loaded); + + expect(loaded.callCount).to.equal(1); + expect(Translator.load.args.length).to.equal(2); + expect(Translator.load.calledWith(MMM, "translations/de.json", false, sinon.match.func)).to.be.true; + expect(Translator.load.calledWith(MMM, "translations/en.json", true, sinon.match.func)).to.be.true; + + done(); + }; + }); + + it("should load translation fallback file", (done) => { + dom.window.onload = async function () { + const { Translator, Module, config } = dom.window; + config.language = "--"; + Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + + Module.register("name", { getTranslations: () => translations }); + const MMM = Module.create("name"); + + const loaded = sinon.stub(); + MMM.loadTranslations(loaded); + + expect(loaded.callCount).to.equal(1); + expect(Translator.load.args.length).to.equal(1); + expect(Translator.load.calledWith(MMM, "translations/en.json", true, sinon.match.func)).to.be.true; + + done(); + }; + }); + }); + const mmm = { name: "TranslationTest", file(file) {