diff --git a/red/api/theme.js b/red/api/theme.js index 04f1ad36d..39b1b39d4 100644 --- a/red/api/theme.js +++ b/red/api/theme.js @@ -18,8 +18,9 @@ var express = require("express"); var util = require("util"); var path = require("path"); var fs = require("fs"); +var clone = require("clone"); -var themeContext = { +var defaultContext = { page: { title: "Node-RED", favicon: "favicon.ico" @@ -30,6 +31,7 @@ var themeContext = { } }; +var themeContext = clone(defaultContext); var themeSettings = null; function serveFile(app,baseUrl,file) { @@ -51,6 +53,9 @@ module.exports = { init: function(settings) { var i; var url; + themeContext = clone(defaultContext); + themeSettings = null; + if (settings.editorTheme) { var theme = settings.editorTheme; themeSettings = {}; diff --git a/test/red/api/info_spec.js b/test/red/api/info_spec.js index 75e4cc59b..f7124c661 100644 --- a/test/red/api/info_spec.js +++ b/test/red/api/info_spec.js @@ -1,5 +1,5 @@ /** - * Copyright 2014 IBM Corp. + * Copyright 2014, 2015 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,8 @@ var app = express(); var settings = require("../../../red/settings"); var info = require("../../../red/api/info"); +var theme = require("../../../red/api/theme"); + describe("info api", function() { describe("settings handler", function() { before(function() { @@ -34,12 +36,16 @@ describe("info api", function() { paletteCategories :["red","blue","green"] } settings.init(userSettings); + + sinon.stub(theme,"settings",function() { return { test: 456 };}); + app = express(); app.get("/settings",info.settings); }); after(function() { settings.reset(); + theme.settings.restore(); }); it('returns the filtered settings', function(done) { @@ -53,6 +59,7 @@ describe("info api", function() { res.body.should.have.property("httpNodeRoot","testHttpNodeRoot"); res.body.should.have.property("version","testVersion"); res.body.should.have.property("paletteCategories",["red","blue","green"]); + res.body.should.have.property("editorTheme",{test:456}); res.body.should.not.have.property("foo",123); done(); }); diff --git a/test/red/api/theme_spec.js b/test/red/api/theme_spec.js index e69de29bb..6421bdbdd 100644 --- a/test/red/api/theme_spec.js +++ b/test/red/api/theme_spec.js @@ -0,0 +1,103 @@ +/** + * Copyright 2015 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var sinon = require('sinon'); +var when = require('when'); +var fs = require("fs"); + +var app = express(); +var settings = require("../../../red/settings"); + +var theme = require("../../../red/api/theme"); + +describe("theme handler", function() { + beforeEach(function() { + sinon.stub(fs,"statSync",function() { return true; }); + }); + afterEach(function() { + theme.init({}); + fs.statSync.restore(); + }); + it("applies the default theme", function() { + var result = theme.init({}); + should.not.exist(result); + + var context = theme.context(); + context.should.have.a.property("page"); + context.page.should.have.a.property("title","Node-RED"); + context.page.should.have.a.property("favicon","favicon.ico"); + context.should.have.a.property("header"); + context.header.should.have.a.property("title","Node-RED"); + context.header.should.have.a.property("image","red/images/node-red.png"); + + should.not.exist(theme.settings()); + }); + + it("picks up custom theme", function() { + var result = theme.init({ + editorTheme: { + page: { + title: "Test Page Title", + favicon: "/absolute/path/to/theme/icon", + css: "/absolute/path/to/custom/css/file" + }, + header: { + title: "Test Header Title", + image: "/absolute/path/to/header/image" // or null to remove image + }, + + deployButton: { + type:"simple", + label:"Save", + icon: "/absolute/path/to/deploy/button/image" // or null to remove image + }, + + menu: { // Hide unwanted menu items by id. see editor/js/main.js:loadEditor for complete list + "menu-item-import-library": false, + "menu-item-export-library": false, + "menu-item-keyboard-shortcuts": false, + "menu-item-help": { + label: "Alternative Help Link Text", + url: "http://example.com" + } + }, + + userMenu: false, // Hide the user-menu even if adminAuth is enabled + + login: { + image: "/absolute/path/to/login/page/big/image" // a 256x256 image + } + } + }); + should.exist(result); + + var context = theme.context(); + context.should.have.a.property("page"); + context.page.should.have.a.property("title","Test Page Title"); + context.should.have.a.property("header"); + context.header.should.have.a.property("title","Test Header Title"); + + var settings = theme.settings(); + settings.should.have.a.property("deployButton"); + settings.should.have.a.property("userMenu"); + settings.should.have.a.property("menu"); + + }); + +}); \ No newline at end of file