Merge branch 'develop' into add-code-error-cliente-failstart

This commit is contained in:
Rodrigo Ramírez Norambuena 2017-08-05 17:47:36 -04:00
commit 7e42dcf0b5
10 changed files with 143 additions and 54 deletions

View File

@ -1,5 +1,6 @@
language: node_js language: node_js
node_js: node_js:
- "8"
- "7" - "7"
- "6" - "6"
- "5.1" - "5.1"
@ -12,6 +13,8 @@ script:
- grunt - grunt
- npm run test:unit - npm run test:unit
- npm run test:e2e - npm run test:e2e
after_script:
- npm list
cache: cache:
directories: directories:
- node_modules - node_modules

View File

@ -9,15 +9,20 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added ### Added
- Add `clientonly` script to start only the electron client for a remote server. - Add `clientonly` script to start only the electron client for a remote server.
- Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module. - Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module.
- Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git - Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git.
- Add unit test the capitalizeFirstLetter function of newfeed module.
- Add new unit tests for function `shorten` in calendar module.
### Updated ### Updated
- Changed 'default.js' - listen on all attached interfaces by default - Changed 'default.js' - listen on all attached interfaces by default.
- Add execution of `npm list` after the test are ran in Travis CI.
- Change hooks for the vendors e2e tests.
### Fixed ### Fixed
- Fixed issue with incorrect allignment of analog clock when displayed in the center column of the MM.
- Fixed issue with incorrect allignment of analog clock when displayed in the center column of the MM - Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM.
- Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM - Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'.
- Fixed issue with calendar module where global configuration of maximumEntries was not overridden by calendar specific config (see module doc).
## [2.1.2] - 2017-07-01 ## [2.1.2] - 2017-07-01
@ -47,7 +52,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Updated ### Updated
- Added missing keys to Polish translation. - Added missing keys to Polish translation.
- Added missing key to German translation. - Added missing key to German translation.
- Added better translation with flexible word order to Finnish translation - Added better translation with flexible word order to Finnish translation.
### Fixed ### Fixed
- Fix instruction in README for using automatically installer script. - Fix instruction in README for using automatically installer script.
@ -55,8 +60,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fix double message about port when server is starting - Fix double message about port when server is starting
- Corrected Swedish translations for TODAY/TOMORROW/DAYAFTERTOMORROW. - Corrected Swedish translations for TODAY/TOMORROW/DAYAFTERTOMORROW.
- Removed unused import from js/electron.js - Removed unused import from js/electron.js
- Made calendar.js respect config.timeFormat irrespecive of locale setting - Made calendar.js respect config.timeFormat irrespecive of locale setting.
- Fixed alignment of analog clock when a large calendar is displayed in the same side bar - Fixed alignment of analog clock when a large calendar is displayed in the same side bar.
## [2.1.1] - 2017-04-01 ## [2.1.1] - 2017-04-01
@ -64,18 +69,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed ### Changed
- Add `anytime` group for Compliments module. - Add `anytime` group for Compliments module.
- Compliments module can use remoteFile without default daytime arrays defined - Compliments module can use remoteFile without default daytime arrays defined.
- Installer: Use init config.js from config.js.sample. - Installer: Use init config.js from config.js.sample.
- Switched out `rrule` package for `rrule-alt` and fixes in `ical.js` in order to fix calendar issues. ([#565](https://github.com/MichMich/MagicMirror/issues/565)) - Switched out `rrule` package for `rrule-alt` and fixes in `ical.js` in order to fix calendar issues. ([#565](https://github.com/MichMich/MagicMirror/issues/565))
- Make mouse events pass through the region fullscreen_above to modules below. - Make mouse events pass through the region fullscreen_above to modules below.
- Scaled the splash screen down to make it a bit more subtle. - Scaled the splash screen down to make it a bit more subtle.
- Replace HTML tables with markdown tables in README files. - Replace HTML tables with markdown tables in README files.
- Added `DAYAFTERTOMORROW`, `UPDATE_NOTIFICATION` and `UPDATE_NOTIFICATION_MODULE` to Finnish translations. - Added `DAYAFTERTOMORROW`, `UPDATE_NOTIFICATION` and `UPDATE_NOTIFICATION_MODULE` to Finnish translations.
- Run `npm test` on Travis automatically - Run `npm test` on Travis automatically.
- Show the splash screen image even when is reboot or halted. - Show the splash screen image even when is reboot or halted.
- Added some missing translaton strings in the sv.json file. - Added some missing translaton strings in the sv.json file.
- Run task jsonlint to check translation files. - Run task jsonlint to check translation files.
- Restructured Test Suite - Restructured Test Suite.
### Added ### Added
- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)). - Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)).

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Magic Mirror</title> <title>MagicMirror²</title>
<meta name="google" content="notranslate" /> <meta name="google" content="notranslate" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" />

View File

@ -153,20 +153,6 @@ Module.register("calendar", {
for (var e in events) { for (var e in events) {
var event = events[e]; var event = events[e];
var excluded = false;
for (var f in this.config.excludedEvents) {
var filter = this.config.excludedEvents[f];
if (event.title.toLowerCase().includes(filter.toLowerCase())) {
excluded = true;
break;
}
}
if (excluded) {
continue;
}
var eventWrapper = document.createElement("tr"); var eventWrapper = document.createElement("tr");
if (this.config.colored) { if (this.config.colored) {
@ -366,7 +352,7 @@ Module.register("calendar", {
return a.startDate - b.startDate; return a.startDate - b.startDate;
}); });
return events.slice(0, this.config.maximumEntries); return events;
}, },
/* createEventList(url) /* createEventList(url)
@ -377,6 +363,7 @@ Module.register("calendar", {
addCalendar: function (url, auth, calendarConfig) { addCalendar: function (url, auth, calendarConfig) {
this.sendSocketNotification("ADD_CALENDAR", { this.sendSocketNotification("ADD_CALENDAR", {
url: url, url: url,
excludedEvents: calendarConfig.excludedEvents || this.config.excludedEvents,
maximumEntries: calendarConfig.maximumEntries || this.config.maximumEntries, maximumEntries: calendarConfig.maximumEntries || this.config.maximumEntries,
maximumNumberOfDays: calendarConfig.maximumNumberOfDays || this.config.maximumNumberOfDays, maximumNumberOfDays: calendarConfig.maximumNumberOfDays || this.config.maximumNumberOfDays,
fetchInterval: this.config.fetchInterval, fetchInterval: this.config.fetchInterval,
@ -437,25 +424,27 @@ Module.register("calendar", {
return defaultValue; return defaultValue;
}, },
/* shorten(string, maxLength) /**
* Shortens a string if it's longer than maxLength. * Shortens a string if it's longer than maxLength and add a ellipsis to the end
* Adds an ellipsis to the end. *
* * @param {string} string Text string to shorten
* argument string string - The string to shorten. * @param {number} maxLength The max length of the string
* argument maxLength number - The max length of the string. * @param {boolean} wrapEvents Wrap the text after the line has reached maxLength
* argument wrapEvents - Wrap the text after the line has reached maxLength * @returns {string} The shortened string
*
* return string - The shortened string.
*/ */
shorten: function (string, maxLength, wrapEvents) { shorten: function (string, maxLength, wrapEvents) {
if (wrapEvents) { if (typeof string !== "string") {
return "";
}
if (wrapEvents === true) {
var temp = ""; var temp = "";
var currentLine = ""; var currentLine = "";
var words = string.split(" "); var words = string.split(" ");
for (var i = 0; i < words.length; i++) { for (var i = 0; i < words.length; i++) {
var word = words[i]; var word = words[i];
if (currentLine.length + word.length < 25 - 1) { // max - 1 to account for a space if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) { // max - 1 to account for a space
currentLine += (word + " "); currentLine += (word + " ");
} else { } else {
if (currentLine.length > 0) { if (currentLine.length > 0) {
@ -467,12 +456,12 @@ Module.register("calendar", {
} }
} }
return temp + currentLine; return (temp + currentLine).trim();
} else { } else {
if (string.length > maxLength) { if (maxLength && typeof maxLength === "number" && string.length > maxLength) {
return string.slice(0, maxLength) + "&hellip;"; return string.trim().slice(0, maxLength) + "&hellip;";
} else { } else {
return string; return string.trim();
} }
} }
}, },

View File

@ -8,7 +8,7 @@
var ical = require("./vendor/ical.js"); var ical = require("./vendor/ical.js");
var moment = require("moment"); var moment = require("moment");
var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumberOfDays, auth) { var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth) {
var self = this; var self = this;
var reloadTimer = null; var reloadTimer = null;
@ -113,6 +113,19 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
title = event.description; title = event.description;
} }
var excluded = false;
for (var f in excludedEvents) {
var filter = excludedEvents[f];
if (title.toLowerCase().includes(filter.toLowerCase())) {
excluded = true;
break;
}
}
if (excluded) {
continue;
}
var location = event.location || false; var location = event.location || false;
var geo = event.geo || false; var geo = event.geo || false;
var description = event.description || false; var description = event.description || false;

View File

@ -24,7 +24,7 @@ module.exports = NodeHelper.create({
socketNotificationReceived: function(notification, payload) { socketNotificationReceived: function(notification, payload) {
if (notification === "ADD_CALENDAR") { if (notification === "ADD_CALENDAR") {
//console.log('ADD_CALENDAR: '); //console.log('ADD_CALENDAR: ');
this.createFetcher(payload.url, payload.fetchInterval, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth); this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth);
} }
}, },
@ -36,7 +36,7 @@ module.exports = NodeHelper.create({
* attribute reloadInterval number - Reload interval in milliseconds. * attribute reloadInterval number - Reload interval in milliseconds.
*/ */
createFetcher: function(url, fetchInterval, maximumEntries, maximumNumberOfDays, auth) { createFetcher: function(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth) {
var self = this; var self = this;
if (!validUrl.isUri(url)) { if (!validUrl.isUri(url)) {
@ -47,7 +47,7 @@ module.exports = NodeHelper.create({
var fetcher; var fetcher;
if (typeof self.fetchers[url] === "undefined") { if (typeof self.fetchers[url] === "undefined") {
console.log("Create new calendar fetcher for url: " + url + " - Interval: " + fetchInterval); console.log("Create new calendar fetcher for url: " + url + " - Interval: " + fetchInterval);
fetcher = new CalendarFetcher(url, fetchInterval, maximumEntries, maximumNumberOfDays, auth); fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth);
fetcher.onReceive(function(fetcher) { fetcher.onReceive(function(fetcher) {
//console.log('Broadcast events.'); //console.log('Broadcast events.');

View File

@ -50,7 +50,7 @@ describe("Electron app environment", function() {
.should.eventually.have.property("height") .should.eventually.have.property("height")
.and.be.above(0) .and.be.above(0)
.browserWindow.getTitle() .browserWindow.getTitle()
.should.eventually.equal("Magic Mirror"); .should.eventually.equal("MagicMirror²");
}); });
it("get request from http://localhost:8080 should return 200", function(done) { it("get request from http://localhost:8080 should return 200", function(done) {

View File

@ -6,21 +6,24 @@ const expect = require("chai").expect;
const describe = global.describe; const describe = global.describe;
const it = global.it; const it = global.it;
const beforeEach = global.beforeEach; const before = global.before;
const afterEach = global.afterEach; const after = global.after;
describe("Vendors", function () { describe("Vendors", function () {
return; // Test still getting failed in Travis
helpers.setupTimeout(this); helpers.setupTimeout(this);
var app = null; var app = null;
beforeEach(function () { before(function () {
return helpers.startApplication({ return helpers.startApplication({
args: ["js/electron.js"] args: ["js/electron.js"]
}).then(function (startedApp) { app = startedApp; }) }).then(function (startedApp) { app = startedApp; })
}); });
afterEach(function () { after(function () {
return helpers.stopApplication(app); return helpers.stopApplication(app);
}); });

View File

@ -14,8 +14,10 @@ describe("Functions into modules/default/calendar/calendar.js", function() {
Module.definitions[name] = moduleDefinition; Module.definitions[name] = moduleDefinition;
}; };
// load calendar.js before(function() {
require("../../../modules/default/calendar/calendar.js"); // load calendar.js
require("../../../modules/default/calendar/calendar.js");
});
describe("capFirst", function() { describe("capFirst", function() {
words = { words = {
@ -27,10 +29,47 @@ describe("Functions into modules/default/calendar/calendar.js", function() {
}; };
Object.keys(words).forEach(word => { Object.keys(words).forEach(word => {
it(`for ${word} should return ${words[word]}`, function() { it(`for '${word}' should return '${words[word]}'`, function() {
expect(Module.definitions.calendar.capFirst(word)).to.equal(words[word]); expect(Module.definitions.calendar.capFirst(word)).to.equal(words[word]);
}); });
}); });
}); });
describe("shorten", function() {
strings = {
" String with whitespace at the beginning that needs trimming" : { length: 16, return: "String with whit&hellip;" },
"long string that needs shortening": { length: 16, return: "long string that&hellip;" },
"short string": { length: 16, return: "short string" },
"long string with no maxLength defined": { return: "long string with no maxLength defined" },
};
Object.keys(strings).forEach(string => {
it(`for '${string}' should return '${strings[string].return}'`, function() {
expect(Module.definitions.calendar.shorten(string, strings[string].length)).to.equal(strings[string].return);
});
});
it("should return an empty string if shorten is called with a non-string", function () {
expect(Module.definitions.calendar.shorten(100)).to.equal("");
});
it("should not shorten the string if shorten is called with a non-number maxLength", function () {
expect(Module.definitions.calendar.shorten("This is a test string", "This is not a number")).to.equal("This is a test string");
});
it("should wrap the string instead of shorten it if shorten is called with wrapEvents = true (with maxLength defined as 20)", function () {
expect(Module.definitions.calendar.shorten(
"This is a wrapEvent test. Should wrap the string instead of shorten it if called with wrapEvent = true",
20,
true)).to.equal("This is a <br>wrapEvent test. Should wrap <br>the string instead of <br>shorten it if called with <br>wrapEvent = true");
});
it("should wrap the string instead of shorten it if shorten is called with wrapEvents = true (without maxLength defined, default 25)", function () {
expect(Module.definitions.calendar.shorten(
"This is a wrapEvent test. Should wrap the string instead of shorten it if called with wrapEvent = true",
undefined,
true)).to.equal("This is a wrapEvent <br>test. Should wrap the string <br>instead of shorten it if called <br>with wrapEvent = true");
});
});
}); });

View File

@ -0,0 +1,37 @@
var fs = require("fs");
var path = require("path");
var chai = require("chai");
var expect = chai.expect;
var vm = require("vm");
describe("Functions into modules/default/newsfeed/newsfeed.js", function() {
Module = {}
Module.definitions = {};
Module.register = function (name, moduleDefinition) {
Module.definitions[name] = moduleDefinition;
};
// load newsfeed.js
require("../../../modules/default/newsfeed/newsfeed.js");
describe("capitalizeFirstLetter", function() {
words = {
"rodrigo": "Rodrigo",
"123m": "123m",
"magic mirror": "Magic mirror",
",a": ",a",
"ñandú": "Ñandú",
".!": ".!"
};
Object.keys(words).forEach(word => {
it(`for ${word} should return ${words[word]}`, function() {
expect(Module.definitions.newsfeed.capitalizeFirstLetter(word)).to.equal(words[word]);
});
});
});
});