From ef009535316c94e49f0ceb43463419e2a1329830 Mon Sep 17 00:00:00 2001 From: BlueSlug Date: Tue, 27 Aug 2019 16:33:00 -0400 Subject: [PATCH 1/9] SJRK-268: generalized custom theme tests to work for any custom theme --- tests/ui/js/storyTellingServerUITests.js | 104 ++++++++++++++--------- 1 file changed, 66 insertions(+), 38 deletions(-) diff --git a/tests/ui/js/storyTellingServerUITests.js b/tests/ui/js/storyTellingServerUITests.js index aa7aed61..bee5bb23 100644 --- a/tests/ui/js/storyTellingServerUITests.js +++ b/tests/ui/js/storyTellingServerUITests.js @@ -69,61 +69,90 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS }); }); - var loadThemedPageTestCases = { - base: { - theme: "base", - baseTheme: "base", - authoringEnabled: true - }, - learningReflections: { - theme: "learningReflections", - baseTheme: "base", - authoringEnabled: true - } - }; - fluid.defaults("sjrk.storyTelling.storyTellingServerUiTester", { - gradeNames: ["fluid.test.testCaseHolder"], + gradeNames: ["fluid.modelComponent", "fluid.test.testCaseHolder"], + baseTestCase: { + clientConfig: { + theme: "base", + baseTheme: "base", + authoringEnabled: true + } + }, + model: { + clientConfig: { + theme: "customTheme", + baseTheme: "base", + authoringEnabled: true + } + }, modules: [{ name: "Test Storytelling Server UI code", tests: [{ name: "Test themed page loading functions", - expect: 6, + expect: 7, sequence: [{ + funcName: "sjrk.storyTelling.storyTellingServerUiTester.setupMockServer", + args: ["/clientConfig", "{that}.options.baseTestCase", "application/json"] + },{ // call the load themed page function, forcing the base theme response - task: "sjrk.storyTelling.storyTellingServerUiTester.loadThemedPageSingleTest", - args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction", loadThemedPageTestCases.base.theme], + task: "sjrk.storyTelling.loadThemedPage", + args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction"], resolve: "jqUnit.assertDeepEq", - resolveArgs: ["The themed page load resolved as expected", loadThemedPageTestCases.base, "{arguments}.0"] + resolveArgs: ["The themed page load resolved as expected", "{that}.options.baseTestCase.clientConfig", "{arguments}.0"] },{ - // call the load themed page function, forcing the Learning Reflections theme response - task: "sjrk.storyTelling.storyTellingServerUiTester.loadThemedPageSingleTest", - args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction", loadThemedPageTestCases.learningReflections.theme], + funcName: "sjrk.storyTelling.storyTellingServerUiTester.teardownMockServer" + },{ + // load clientConfig and store that value somewhere + task: "sjrk.storyTelling.storyTellingServerUiTester.loadClientConfigFromServer", + args: ["/clientConfig", "{that}", "clientConfig.theme"], resolve: "jqUnit.assertDeepEq", - resolveArgs: ["The themed page load resolved as expected", loadThemedPageTestCases.learningReflections, "{arguments}.0"] + resolveArgs: ["Custom theme was loaded successfully", "{that}.model.clientConfig", "{arguments}.0"] + },{ + // call the load themed page function, forcing the custom theme response + task: "sjrk.storyTelling.storyTellingServerUiTester.verifyCustomThemeLoading", + args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction"], + resolve: "jqUnit.assertDeepEq", + resolveArgs: ["The themed page load resolved as expected", "{that}.model.clientConfig", "{arguments}.0"] },{ funcName: "sjrk.storyTelling.storyTellingServerUiTester.assertCustomCssLoaded", - args: ["learningReflections.css", 1] + args: ["{that}.model.clientConfig.theme", 1] },{ // test the CSS/JS injection function directly funcName: "sjrk.storyTelling.loadCustomThemeFiles", - args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction", {"theme": "learningReflections"}] + args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction", "{that}.model.clientConfig"] },{ funcName: "sjrk.storyTelling.storyTellingServerUiTester.assertCustomCssLoaded", - args: ["learningReflections.css", 2] + args: ["{that}.model.clientConfig.theme", 2] }] }] }] }); - sjrk.storyTelling.storyTellingServerUiTester.loadThemedPageSingleTest = function (callback, expectedTheme) { - var loadPromise = fluid.promise(); + sjrk.storyTelling.storyTellingServerUiTester.loadClientConfigFromServer = function (url, component, clientConfigPath) { + var configPromise = fluid.promise(); + + $.get(url).then(function (data) { + if (data.theme !== data.baseTheme) { + fluid.set(component.model, clientConfigPath, data.theme); + configPromise.resolve(data); + } else { + configPromise.reject({ + isError: true, + message: "Custom theme was not set in the server configuration." + }); + } + }, function (jqXHR, textStatus, errorThrown) { + configPromise.reject({ + isError: true, + message: errorThrown + }); + }); + + return configPromise; + }; - sjrk.storyTelling.storyTellingServerUiTester.setupMockServer("/clientConfig", JSON.stringify({ - theme: expectedTheme, - baseTheme: "base", - authoringEnabled: true - })); + sjrk.storyTelling.storyTellingServerUiTester.verifyCustomThemeLoading = function (callback) { + var loadPromise = fluid.promise(); sjrk.storyTelling.loadThemedPage(callback).then(function (clientConfig) { loadPromise.resolve(clientConfig); @@ -131,23 +160,22 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS loadPromise.reject(); }); - sjrk.storyTelling.storyTellingServerUiTester.teardownMockServer(); - return loadPromise; }; - sjrk.storyTelling.storyTellingServerUiTester.setupMockServer = function (url, responseData) { + sjrk.storyTelling.storyTellingServerUiTester.setupMockServer = function (url, testCase, responseType) { mockServer = sinon.createFakeServer(); mockServer.respondImmediately = true; - - mockServer.respondWith(url, [200, { "Content-Type": "application/json" }, responseData]); + mockServer.respondWith(url, [200, { "Content-Type": responseType }, JSON.stringify(testCase.clientConfig)]); }; sjrk.storyTelling.storyTellingServerUiTester.teardownMockServer = function () { mockServer.restore(); }; - sjrk.storyTelling.storyTellingServerUiTester.assertCustomCssLoaded = function (expectedFileName, expectedInstanceCount) { + sjrk.storyTelling.storyTellingServerUiTester.assertCustomCssLoaded = function (expectedTheme, expectedInstanceCount) { + var expectedFileName = expectedTheme + ".css"; + var cssFilesLinked = fluid.transform(fluid.getMembers($("link"), "href"), function (fileUrl) { return fileUrl.split("/css/")[1]; }); From 53fc4fb6ada7f784874848aca73de78d31c6dc1f Mon Sep 17 00:00:00 2001 From: BlueSlug Date: Wed, 28 Aug 2019 15:36:51 -0400 Subject: [PATCH 2/9] SJRK-268: removed redundant callbacks from theme loading functions --- src/ui/storyTellingServerUI.js | 23 ++++------- tests/ui/js/storyTellingServerUITests.js | 40 +++++++------------- tests/ui/js/testUtils.js | 10 ----- themes/base/storyBrowse.html | 2 +- themes/base/storyEdit.html | 2 +- themes/base/storyView.html | 2 +- themes/learningReflections/introduction.html | 2 +- themes/learningReflections/resources.html | 2 +- themes/learningReflections/workshops.html | 2 +- 9 files changed, 26 insertions(+), 59 deletions(-) diff --git a/src/ui/storyTellingServerUI.js b/src/ui/storyTellingServerUI.js index bf791cdd..1ba89eda 100644 --- a/src/ui/storyTellingServerUI.js +++ b/src/ui/storyTellingServerUI.js @@ -104,19 +104,15 @@ sjrk.storyTelling.loadBrowse = function (clientConfig, options) { }; /* Gets the current theme from the server and loads associated files if and - * only if the current theme is not set to the base theme. Once complete, the - * provided callback function is called and the theme name is passed into it. - * - "callback": a function to call once everything has completed. Will be called - * regardless of whether theme information was specified or retrieved + * only if the current theme is not set to the base theme. Returns a promise. + * If the promise resolves, it will contain the clientConfig information. */ -sjrk.storyTelling.loadThemedPage = function (callback) { +sjrk.storyTelling.loadTheme = function () { var loadPromise = fluid.promise(); - var callbackFunction = typeof callback === "function" ? callback : fluid.getGlobalValue(callback); - $.get("/clientConfig").then(function (data) { if (data.theme !== data.baseTheme) { - sjrk.storyTelling.loadCustomThemeFiles(callbackFunction, data).then(function () { + sjrk.storyTelling.loadCustomThemeFiles(data).then(function () { loadPromise.resolve(data); }, function (jqXHR, textStatus, errorThrown) { loadPromise.reject({ @@ -125,7 +121,6 @@ sjrk.storyTelling.loadThemedPage = function (callback) { }); }); } else { - callbackFunction(data); loadPromise.resolve(data); } }, function (jqXHR, textStatus, errorThrown) { @@ -139,14 +134,13 @@ sjrk.storyTelling.loadThemedPage = function (callback) { }; /* Loads CSS and JavaScript files for the provided theme into the page markup. - * If JavaScript file loading is successful, the callback function is called. - * - "callback": a function to call once everything has completed + * Returns a promise. If the promise resolves, it will contain the clientConfig. * - "clientConfig": a collection of client config values consisting of * - "theme": the current theme of the site * - "baseTheme": the base theme of the site * - "authoringEnabled": indicates whether story saving and editing are enabled */ -sjrk.storyTelling.loadCustomThemeFiles = function (callback, clientConfig) { +sjrk.storyTelling.loadCustomThemeFiles = function (clientConfig) { var loadPromise = fluid.promise(); var cssUrl = fluid.stringTemplate("/css/%theme.css", {theme: clientConfig.theme}); @@ -159,10 +153,7 @@ sjrk.storyTelling.loadCustomThemeFiles = function (callback, clientConfig) { }).appendTo("head"); $.getScript(scriptUrl, function () { - if (typeof callback === "function") { - var callbackResult = callback(clientConfig); - loadPromise.resolve(callbackResult); - } + loadPromise.resolve(clientConfig); }).fail(function (jqXHR, textStatus, errorThrown) { loadPromise.reject({ isError: true, diff --git a/tests/ui/js/storyTellingServerUITests.js b/tests/ui/js/storyTellingServerUITests.js index bee5bb23..48156d4d 100644 --- a/tests/ui/js/storyTellingServerUITests.js +++ b/tests/ui/js/storyTellingServerUITests.js @@ -88,38 +88,36 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS modules: [{ name: "Test Storytelling Server UI code", tests: [{ - name: "Test themed page loading functions", - expect: 7, + name: "Test themed page loading functions with mock values", + expect: 1, sequence: [{ funcName: "sjrk.storyTelling.storyTellingServerUiTester.setupMockServer", - args: ["/clientConfig", "{that}.options.baseTestCase", "application/json"] + args: ["/clientConfig", "{that}.options.baseTestCase.clientConfig", "application/json"] },{ - // call the load themed page function, forcing the base theme response - task: "sjrk.storyTelling.loadThemedPage", - args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction"], + task: "sjrk.storyTelling.loadTheme", resolve: "jqUnit.assertDeepEq", resolveArgs: ["The themed page load resolved as expected", "{that}.options.baseTestCase.clientConfig", "{arguments}.0"] },{ funcName: "sjrk.storyTelling.storyTellingServerUiTester.teardownMockServer" - },{ - // load clientConfig and store that value somewhere + }] + },{ + name: "Test themed page loading functions with server config values", + expect: 4, + sequence: [{ task: "sjrk.storyTelling.storyTellingServerUiTester.loadClientConfigFromServer", args: ["/clientConfig", "{that}", "clientConfig.theme"], resolve: "jqUnit.assertDeepEq", resolveArgs: ["Custom theme was loaded successfully", "{that}.model.clientConfig", "{arguments}.0"] },{ - // call the load themed page function, forcing the custom theme response - task: "sjrk.storyTelling.storyTellingServerUiTester.verifyCustomThemeLoading", - args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction"], + task: "sjrk.storyTelling.loadTheme", resolve: "jqUnit.assertDeepEq", resolveArgs: ["The themed page load resolved as expected", "{that}.model.clientConfig", "{arguments}.0"] },{ funcName: "sjrk.storyTelling.storyTellingServerUiTester.assertCustomCssLoaded", args: ["{that}.model.clientConfig.theme", 1] },{ - // test the CSS/JS injection function directly funcName: "sjrk.storyTelling.loadCustomThemeFiles", - args: ["sjrk.storyTelling.testUtils.callbackVerificationFunction", "{that}.model.clientConfig"] + args: ["{that}.model.clientConfig"] },{ funcName: "sjrk.storyTelling.storyTellingServerUiTester.assertCustomCssLoaded", args: ["{that}.model.clientConfig.theme", 2] @@ -151,22 +149,10 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS return configPromise; }; - sjrk.storyTelling.storyTellingServerUiTester.verifyCustomThemeLoading = function (callback) { - var loadPromise = fluid.promise(); - - sjrk.storyTelling.loadThemedPage(callback).then(function (clientConfig) { - loadPromise.resolve(clientConfig); - }, function () { - loadPromise.reject(); - }); - - return loadPromise; - }; - - sjrk.storyTelling.storyTellingServerUiTester.setupMockServer = function (url, testCase, responseType) { + sjrk.storyTelling.storyTellingServerUiTester.setupMockServer = function (url, clientConfig, responseType) { mockServer = sinon.createFakeServer(); mockServer.respondImmediately = true; - mockServer.respondWith(url, [200, { "Content-Type": responseType }, JSON.stringify(testCase.clientConfig)]); + mockServer.respondWith(url, [200, { "Content-Type": responseType }, JSON.stringify(clientConfig)]); }; sjrk.storyTelling.storyTellingServerUiTester.teardownMockServer = function () { diff --git a/tests/ui/js/testUtils.js b/tests/ui/js/testUtils.js index b5ad0a71..1003e971 100644 --- a/tests/ui/js/testUtils.js +++ b/tests/ui/js/testUtils.js @@ -170,16 +170,6 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS jqUnit.assertEquals("Number of remaining blocks is expected #: " + expectedNumberOfBlocks, expectedNumberOfBlocks, managedComponentRegistryAsArray.length); }; - /* A simple function that asserts that it was called with a truthy value, - * intended for use as a callback - * - "value": a value (hopefully truthy) - */ - sjrk.storyTelling.testUtils.callbackVerificationFunction = function (value) { - if (value) { - jqUnit.assert("Callback was successfully called with value: " + JSON.stringify(value)); - } - }; - /* Alters URL without pageload, via code from StackOverflow * https://stackoverflow.com/questions/10970078/modifying-a-query-string-without-reloading-the-page * - "queryString": the query string to append to the current page URL diff --git a/themes/base/storyBrowse.html b/themes/base/storyBrowse.html index 6921803c..adc91e0a 100644 --- a/themes/base/storyBrowse.html +++ b/themes/base/storyBrowse.html @@ -115,7 +115,7 @@