diff --git a/platform/src/EducationPlatformApp.js b/platform/src/EducationPlatformApp.js index 5684337..293074f 100644 --- a/platform/src/EducationPlatformApp.js +++ b/platform/src/EducationPlatformApp.js @@ -54,7 +54,7 @@ class EducationPlatformApp { constructor() { this.outputType = "text"; this.outputLanguage = "text"; - this.errorHandler = new ErrorHandler(this.errorNotification.bind(this)); + this.errorHandler = new ErrorHandler(); this.preloader = new Preloader(); this.panels = []; } @@ -459,7 +459,7 @@ class EducationPlatformApp { if (response.editorUrl) { // Language workbench - this.longNotification("Building editor"); + PlaygroundUtility.longNotification("Building editor"); this.checkEditorReady( response.editorStatusUrl, response.editorUrl, action.source.editorPanel, action.source.editorActivity, outputConsole); @@ -601,7 +601,7 @@ class EducationPlatformApp { this.handleResponseActionFunction(action , actionResultPromise); - this.longNotification("Executing program"); + PlaygroundUtility.longNotification("Executing program"); } } @@ -613,26 +613,7 @@ class EducationPlatformApp { this.toggle(parentElement.id); } } - - - notification(title, message, cls="light"){ - const crossIcon = "
" - Metro.notify.create(crossIcon + "" + title + "" + "
" + message + "
", null, {keepOpen: true, cls: cls, width: 300}); - } - - longNotification(title, cls="light") { - this.notification(title + "...", "This may take a few seconds to complete if the back end is not warmed up.", cls); - } - - successNotification(message, cls="light") { - this.notification("Success:", message, cls); - } - - errorNotification(message) { - console.log("ERROR: " + message); - this.notification("Error:", message, "bg-red fg-white"); - } - + toggle(elementId, onEmpty) { var element = document.getElementById(elementId); @@ -711,7 +692,7 @@ class EducationPlatformApp { } Promise.all(fileStorePromises).then( () => { - this.successNotification("The activity panel contents have been saved."); + PlaygroundUtility.successNotification("The activity panel contents have been saved."); }).catch( (err) => { this.errorHandler.notify("An error occurred while trying to save the panel contents.", err); @@ -743,7 +724,7 @@ class EducationPlatformApp { sessionStorage.removeItem(editorPanelId); this.activityManager.setActivityVisibility(editorActivityId, false); Metro.notify.killAll(); - this.notification("Build Failed", result.error, "ribbed-lightAmber"); + PlaygroundUtility.notification("Build Failed", result.error, "ribbed-lightAmber"); } else if (!result.editorReady){ await new Promise(resolve => setTimeout(resolve, 2000)); @@ -755,12 +736,12 @@ class EducationPlatformApp { sessionStorage.setItem( editorPanelId , editorInstanceUrl ); this.activityManager.setActivityVisibility(editorActivityId, true); Metro.notify.killAll(); - this.successNotification("Building complete."); + PlaygroundUtility.successNotification("Building complete."); } } else { console.log("ERROR: The editor response could not be checked: " + statusUrl); - this.errorNotification("Failed to start the editor."); + PlaygroundUtility.errorNotification("Failed to start the editor."); } } } diff --git a/platform/src/ErrorHandler.js b/platform/src/ErrorHandler.js index ae7b89b..ee947f9 100644 --- a/platform/src/ErrorHandler.js +++ b/platform/src/ErrorHandler.js @@ -1,15 +1,8 @@ import { EducationPlatformError } from "./EducationPlatformError"; - +import { PlaygroundUtility } from "./PlaygroundUtility"; class ErrorHandler { - displayError; - - /** - * @param {Function} notifier - The function to use for displaying error messages. - */ - constructor(notifier){ - - this.displayError = notifier; + constructor(){ window.onerror = (event, source, lineno, colno, err) => { @@ -47,7 +40,7 @@ class ErrorHandler { } } - this.displayError(displayMessage); + PlaygroundUtility.errorNotification(displayMessage); } } diff --git a/platform/src/PlaygroundUtility.js b/platform/src/PlaygroundUtility.js index 3bc2a69..4cdaf1f 100644 --- a/platform/src/PlaygroundUtility.js +++ b/platform/src/PlaygroundUtility.js @@ -1,4 +1,4 @@ - +/*global Metro -- Metro is externally imported*/ class PlaygroundUtility { @@ -23,6 +23,24 @@ class PlaygroundUtility { document.getElementById("feedback-url").href = url; } + static notification(title, message, cls="light"){ + const crossIcon = "
" + Metro.notify.create(crossIcon + "" + title + "" + "
" + message + "
", null, {keepOpen: true, cls: cls, width: 300}); + } + + static longNotification(title, cls="light") { + this.notification(title + "...", "This may take a few seconds to complete if the back end is not warmed up.", cls); + } + + static successNotification(message, cls="light") { + this.notification("Success:", message, cls); + } + + static errorNotification(message) { + console.log("ERROR: " + message); + this.notification("Error:", message, "bg-red fg-white"); + } + } export { PlaygroundUtility }; \ No newline at end of file diff --git a/platform/src/index.js b/platform/src/index.js index 13dd928..162235c 100644 --- a/platform/src/index.js +++ b/platform/src/index.js @@ -1,6 +1,7 @@ /*global TOKEN_SERVER_URL -- is set by environment variable*/ import { EducationPlatformApp } from "./EducationPlatformApp.js"; +import { PlaygroundUtility } from "./PlaygroundUtility.js"; const TOKEN_HANDLER_URL = TOKEN_SERVER_URL || "http://127.0.0.1:10000"; let urlParameters = new URLSearchParams(window.location.search); @@ -19,5 +20,5 @@ window.savePanelContents = platform.savePanelContents.bind(platform); window.toggle = platform.toggle.bind(platform); window.togglePanelById = platform.togglePanelById.bind(platform); //window.renderDiagram = renderDiagram; -window.longNotification = platform.longNotification.bind(platform); +window.longNotification = PlaygroundUtility.longNotification; window.getPanelTitle = platform.getPanelTitle.bind(platform); \ No newline at end of file diff --git a/platform/test/spec/testEducationPlatformAppSpec.js b/platform/test/spec/testEducationPlatformAppSpec.js index 1ef88c5..923a1ac 100644 --- a/platform/test/spec/testEducationPlatformAppSpec.js +++ b/platform/test/spec/testEducationPlatformAppSpec.js @@ -1,6 +1,5 @@ -/*global describe, it, expect, spyOn, beforeEach, afterEach, expectAsync -- functions provided by Jasmine */ +/*global describe, it, expect, spyOn, beforeEach, expectAsync -- functions provided by Jasmine */ /*global jasmine -- object provided by Jasmine */ -/*global $ -- jquery is externally imported*/ export var TOKEN_SERVER_URL = "test://ts.url"; import {EducationPlatformApp} from "../../src/EducationPlatformApp.js"; @@ -8,6 +7,7 @@ import { ActionFunction } from "../../src/ActionFunction.js"; import { Panel } from "../../src/Panel.js"; import { ErrorHandler } from "../../src/ErrorHandler.js"; import "jasmine-ajax"; +import { PlaygroundUtility } from "../../src/PlaygroundUtility.js"; describe("EducationPlatformApp", () => { @@ -77,8 +77,8 @@ describe("EducationPlatformApp", () => { spyOn(EducationPlatformApp.prototype, "handleResponseActionFunction"); // platform - notifications - spyOn(EducationPlatformApp.prototype, "longNotification"); - spyOn(EducationPlatformApp.prototype, "errorNotification"); + spyOn(PlaygroundUtility, "longNotification"); + spyOn(PlaygroundUtility, "errorNotification"); spyOn(ErrorHandler.prototype, "notify"); }) @@ -120,8 +120,8 @@ describe("EducationPlatformApp", () => { platform.runAction(PANEL_ID, BUTTON_ID); // Check the expected results - expect(platform.longNotification).toHaveBeenCalledWith(jasmine.stringMatching('(E|e)xecuting')); - expect(platform.errorNotification).not.toHaveBeenCalled(); + expect(PlaygroundUtility.longNotification).toHaveBeenCalledWith(jasmine.stringMatching('(E|e)xecuting')); + expect(PlaygroundUtility.errorNotification).not.toHaveBeenCalled(); }) it("raises an error when an action does not exist for a given panel using ErrorHandler notify", () => { @@ -169,91 +169,4 @@ describe("EducationPlatformApp", () => { }) }) }) - - - describe("notification()", () => { - let platform; - - const NOTIFICATION_TITLE = "ABC123"; - const NOTIFICATION_MESSAGE = "DEF456"; - - beforeEach(()=>{ - // Setup - platform = new EducationPlatformApp(); - - }) - - it("displays a message with given title and text", () => { - - // Call the target object - platform.notification(NOTIFICATION_TITLE, NOTIFICATION_MESSAGE); - - // Check the expected results - const documentMessages = $(".notify-message"); - - expect(documentMessages).toHaveSize(1); - - expect(documentMessages.text()).toContain(NOTIFICATION_TITLE); - expect(documentMessages.text()).toContain(NOTIFICATION_MESSAGE); - }) - - afterEach( () => { - $(".notify-message").remove(); - }) - }) - - describe("longNotification()", () => { - - const NOTIFICATION_TEXT = "ABC123"; - const NOTIFICATION_MESSAGE = "may take a few seconds to complete"; - - it("calls notification() with the given text", () => { - // Setup - spyOn(EducationPlatformApp.prototype, "notification"); - const platform = new EducationPlatformApp(); - - // Call the target object - platform.longNotification(NOTIFICATION_TEXT); - - // Check the expected results - expect(platform.notification).toHaveBeenCalledWith(jasmine.stringMatching(NOTIFICATION_TEXT), jasmine.stringMatching(NOTIFICATION_MESSAGE), jasmine.anything()); - }) - }) - - describe("successNotification()", () => { - - const NOTIFICATION_TEXT = "ABC123"; - const NOTIFICATION_TITLE = "Success"; - - it("calls notification with the given text", () => { - // Setup - spyOn(EducationPlatformApp.prototype, "notification"); - const platform = new EducationPlatformApp(); - - // Call the target object - platform.successNotification(NOTIFICATION_TEXT); - - // Check the expected results - expect(platform.notification).toHaveBeenCalledWith(jasmine.stringMatching(NOTIFICATION_TITLE), jasmine.stringMatching(NOTIFICATION_TEXT), jasmine.anything()); - }) - }) - - describe("errorNotification()", () => { - - const NOTIFICATION_TEXT = "ABC123"; - const NOTIFICATION_TITLE = "Error"; - - it("calls notification with the given text", () => { - // Setup - spyOn(EducationPlatformApp.prototype, "notification"); - const platform = new EducationPlatformApp(); - - // Call the target object - platform.errorNotification(NOTIFICATION_TEXT); - - // Check the expected results - expect(platform.notification).toHaveBeenCalledWith(jasmine.stringMatching(NOTIFICATION_TITLE), jasmine.stringMatching(NOTIFICATION_TEXT), jasmine.anything()); - }) - }) - }) \ No newline at end of file diff --git a/platform/test/spec/testErrorHandlerSpec.js b/platform/test/spec/testErrorHandlerSpec.js index be7bd43..e41a7bd 100644 --- a/platform/test/spec/testErrorHandlerSpec.js +++ b/platform/test/spec/testErrorHandlerSpec.js @@ -1,8 +1,9 @@ -/*global describe, it, beforeEach, expect -- functions provided by Jasmine */ +/*global describe, it, beforeEach, expect, spyOn -- functions provided by Jasmine */ /*global jasmine -- object provided by Jasmine */ import { EducationPlatformError } from "../../src/EducationPlatformError.js"; import {ErrorHandler} from "../../src/ErrorHandler.js" +import { PlaygroundUtility } from "../../src/PlaygroundUtility.js"; describe("ErrorHandler", () => { @@ -10,18 +11,10 @@ describe("ErrorHandler", () => { let notifierSpy; beforeEach(()=>{ - notifierSpy = jasmine.createSpy("notifier"); + notifierSpy = spyOn(PlaygroundUtility,"errorNotification"); }) describe("constructor()", () => { - it("initialises displayError with the given notifier function", () =>{ - // Call the target object - const eh = new ErrorHandler(notifierSpy); - - // Check the expected results - expect(eh.displayError).toBe(notifierSpy); - }); - it("initialises window.onError with function that calls notify", () =>{ const error = new EducationPlatformError("Error Information"); @@ -35,7 +28,7 @@ describe("ErrorHandler", () => { }) describe("notify()", () => { - it("calls notifier function with error information", () =>{ + it("calls errorNotification() with error information", () =>{ const MESSAGE = "Test Message"; const error = new EducationPlatformError("Error Information");