diff --git a/.eslintignore b/.eslintignore
index 2e1f92d3..ee60c2ea 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,6 +1,6 @@
-vendor/
+vendor/*
!/vendor/vendor.js
!/modules/default/**
!/modules/node_helper
!/modules/node_helper/**
-!/modules/default/defaultmodules.js
\ No newline at end of file
+!/modules/default/defaultmodules.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 53b534f6..eb328821 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,13 +23,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Restructured Test Suite
### Added
-- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673))
-- Calendar-specific support for `maximumEntries`, and ` maximumNumberOfDays`
+- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)).
+- Calendar-specific support for `maximumEntries`, and ` maximumNumberOfDays`.
- Add loaded function to modules, providing an async callback.
- Made default newsfeed module aware of gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures)
-- Add use pm2 for manager process into Installer RaspberryPi script
-- Russian Translation
-- Afrikaans Translation
+- Add use pm2 for manager process into Installer RaspberryPi script.
+- Russian Translation.
+- Afrikaans Translation.
- Add postinstall script to notify user that MagicMirror installed successfully despite warnings from NPM.
- Init tests using mocha.
- Option to use RegExp in Calendar's titleReplace.
@@ -37,25 +37,26 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Icelandic Translation.
- Add use a script to prevent when is run by SSH session set DISPLAY enviroment.
- Enable ability to set configuration file by the enviroment variable called MM_CONFIG_FILE.
-- Option to give each calendar a different color
-- Option for colored min-temp and max-temp
-- Add test e2e helloworld
-- Add test e2e enviroment
-- Add `chai-as-promised` npm module to devDependencies
-- Basic set of tests for clock module
-- Run e2e test in Travis
+- Option to give each calendar a different color.
+- Option for colored min-temp and max-temp.
+- Add test e2e helloworld.
+- Add test e2e enviroment.
+- Add `chai-as-promised` npm module to devDependencies.
+- Basic set of tests for clock module.
+- Run e2e test in Travis.
- Estonian Translation.
-- Add test for compliments module for parts of day
+- Add test for compliments module for parts of day.
- Korean Translation.
-- Added console warning on startup when deprecated config options are used
-- Add option to display temperature unit label to the current weather module
-- Added ability to disable wrapping of news items
+- Added console warning on startup when deprecated config options are used.
+- Add option to display temperature unit label to the current weather module.
+- Added ability to disable wrapping of news items.
- Added in the ability to hide events in the calendar module based on simple string filters.
- Updated Norwegian translation.
-- Added hideLoading option for News Feed module
+- Added hideLoading option for News Feed module.
- Added configurable dateFormat to clock module.
- Added multiple calendar icon support.
- Added meta tags to support fullscreen mode on iOS (for server mode)
+- Added `ignoreOldItems` and `ignoreOlderThan` options to the News Feed module
### Fixed
- Update .gitignore to not ignore default modules folder.
@@ -64,7 +65,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fix an issue where the analog clock looked scrambled. ([#611](https://github.com/MichMich/MagicMirror/issues/611))
- If units is set to imperial, the showRainAmount option of weatherforecast will show the correct unit.
- Module currentWeather: check if temperature received from api is defined.
-- Fix an issue with module hidden status changing to `true` although lock string prevented showing it
+- Fix an issue with module hidden status changing to `true` although lock string prevented showing it.
- Fix newsfeed module bug (removeStartTags)
- Fixed missing animation on `this.show(speed)` when module is alone in a region.
diff --git a/Gruntfile.js b/Gruntfile.js
index 73836ba4..06fed2d5 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -10,7 +10,7 @@ module.exports = function(grunt) {
"serveronly/*.js", "*.js", "tests/*/*.js", "!modules/default/alert/notificationFx.js",
"!modules/default/alert/modernizr.custom.js", "!modules/default/alert/classie.js",
"config/*",
- "translations/translations.js"
+ "translations/translations.js", "vendor/vendor.js"
]
},
diff --git a/js/app.js b/js/app.js
index f8825f7e..138fec70 100644
--- a/js/app.js
+++ b/js/app.js
@@ -68,11 +68,11 @@ var App = function() {
callback(config);
} catch (e) {
if (e.code == "ENOENT") {
- console.error("WARNING! Could not find config file. Please create one. Starting with default configuration.");
+ console.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration."));
} else if (e instanceof ReferenceError || e instanceof SyntaxError) {
- console.error("WARNING! Could not validate config file. Please correct syntax errors. Starting with default configuration.");
+ console.error(Utils.colors.error("WARNING! Could not validate config file. Please correct syntax errors. Starting with default configuration."));
} else {
- console.error("WARNING! Could not load config file. Starting with default configuration. Error found: " + e);
+ console.error(Utils.colors.error("WARNING! Could not load config file. Starting with default configuration. Error found: " + e));
}
callback(defaults);
}
diff --git a/js/main.js b/js/main.js
index 8c64d880..5c8a6737 100644
--- a/js/main.js
+++ b/js/main.js
@@ -66,7 +66,7 @@ var MM = (function() {
var classes = position.replace("_"," ");
var parentWrapper = document.getElementsByClassName(classes);
if (parentWrapper.length > 0) {
- var wrapper = parentWrapper[0].getElementsByClassName("container");
+ var wrapper = parentWrapper[0].getElementsByClassName("container");
if (wrapper.length > 0) {
return wrapper[0];
}
diff --git a/js/utils.js b/js/utils.js
index 7f548afa..76eb2703 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -10,7 +10,8 @@ var colors = require("colors/safe");
var Utils = {
colors: {
- warn: colors.yellow
+ warn: colors.yellow,
+ error: colors.red
}
};
diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md
index 9f7b2e7d..7c4ad48d 100644
--- a/modules/default/newsfeed/README.md
+++ b/modules/default/newsfeed/README.md
@@ -70,6 +70,8 @@ The following properties can be configured:
| `updateInterval` | How often do you want to display a new headline? (Milliseconds)
**Possible values:**`1000` - `60000`
**Default value:** `10000` (10 seconds)
| `animationSpeed` | Speed of the update animation. (Milliseconds)
**Possible values:**`0` - `5000`
**Default value:** `2500` (2.5 seconds)
| `maxNewsItems` | Total amount of news items to cycle through. (0 for unlimited)
**Possible values:**`0` - `...`
**Default value:** `0`
+| `ignoreOldItems` | Ignore news items that are outdated.
**Possible values:**`true` or `false
**Default value:** `false`
+| `ignoreOlderThan` | How old should news items be before they are considered outdated? (Milliseconds)
**Possible values:**`1` - `...`
**Default value:** `86400000` (1 day)
| `removeStartTags` | Some newsfeeds feature tags at the **beginning** of their titles or descriptions, such as _[VIDEO]_. This setting allows for the removal of specified tags from the beginning of an item's description and/or title.
**Possible values:**`'title'`, `'description'`, `'both'`
| `startTags` | List the tags you would like to have removed at the beginning of the feed item
**Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
| `removeEndTags` | Remove specified tags from the **end** of an item's description and/or title.
**Possible values:**`'title'`, `'description'`, `'both'`
diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js
index 5094355e..b7ec2f58 100644
--- a/modules/default/newsfeed/newsfeed.js
+++ b/modules/default/newsfeed/newsfeed.js
@@ -28,6 +28,8 @@ Module.register("newsfeed",{
updateInterval: 10 * 1000,
animationSpeed: 2.5 * 1000,
maxNewsItems: 0, // 0 for unlimited
+ ignoreOldItems: false,
+ ignoreOlderThan: 24 * 60 * 60 * 1000, // 1 day
removeStartTags: "",
removeEndTags: "",
startTags: [],
@@ -226,7 +228,9 @@ Module.register("newsfeed",{
for (var i in feedItems) {
var item = feedItems[i];
item.sourceTitle = this.titleForFeed(feed);
- newsItems.push(item);
+ if (!(this.config.ignoreOldItems && ((Date.now() - new Date(item.pubdate)) > this.config.ignoreOlderThan))) {
+ newsItems.push(item);
+ }
}
}
}
diff --git a/package.json b/package.json
index 7a1e7641..a190f12d 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "magicmirror",
"version": "2.1.1",
- "description": "A modular interface for smart mirrors.",
+ "description": "The open source modular smart mirror platform.",
"main": "js/electron.js",
"scripts": {
"start": "sh run-start.sh",
diff --git a/tests/configs/modules/calendar/fail-basic-auth.js b/tests/configs/modules/calendar/fail-basic-auth.js
new file mode 100644
index 00000000..ad22046a
--- /dev/null
+++ b/tests/configs/modules/calendar/fail-basic-auth.js
@@ -0,0 +1,44 @@
+/* Magic Mirror Test calendar calendar
+ *
+ * This configuration is a wrong authentication
+ *
+ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
+ * MIT Licensed.
+ */
+
+var config = {
+ port: 8080,
+ ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
+
+ language: "en",
+ timeFormat: 12,
+ units: "metric",
+ electronOptions: {
+ webPreferences: {
+ nodeIntegration: true,
+ },
+ },
+
+ modules: [
+ {
+ module: "calendar",
+ position: "bottom_bar",
+ config: {
+ calendars: [
+ {
+ maximumNumberOfDays: 10000,
+ url: "http://localhost:8020/tests/configs/data/calendar_test.ics",
+ auth: {
+ user: "MagicMirror",
+ pass: "StairwayToHeaven",
+ method: "basic"
+ }
+ }
+ ]
+ }
+ }
+ ]
+};
+
+/*************** DO NOT EDIT THE LINE BELOW ***************/
+if (typeof module !== "undefined") {module.exports = config;}
diff --git a/tests/configs/modules/positions.js b/tests/configs/modules/positions.js
new file mode 100644
index 00000000..7d0188c2
--- /dev/null
+++ b/tests/configs/modules/positions.js
@@ -0,0 +1,43 @@
+/* Magic Mirror Test config for position setters module
+ *
+ * For this case is using helloworld module
+ *
+ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
+ * MIT Licensed.
+ */
+
+
+var config = {
+ port: 8080,
+ ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
+ ipWhitelist: [],
+
+ language: "en",
+ timeFormat: 24,
+ units: "metric",
+ electronOptions: {
+ webPreferences: {
+ nodeIntegration: true,
+ },
+ },
+ modules:
+ // Using exotic content. This is why dont accept go to JSON configuration file
+ (function() {
+ var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third",
+ "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right",
+ "bottom_bar", "fullscreen_above", "fullscreen_below"];
+ var modules = Array();
+ for (idx in positions) {
+ modules.push({
+ module: "helloworld",
+ position: positions[idx],
+ config: {
+ text: "Text in " + positions[idx]
+ }
+ });
+ }
+ return modules;
+ })(),
+};
+/*************** DO NOT EDIT THE LINE BELOW ***************/
+if (typeof module !== "undefined") {module.exports = config;}
diff --git a/tests/configs/port_8090.js b/tests/configs/port_8090.js
new file mode 100644
index 00000000..6646dff7
--- /dev/null
+++ b/tests/configs/port_8090.js
@@ -0,0 +1,25 @@
+/* Magic Mirror Test config sample enviroment set por 8090
+ *
+ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
+ * MIT Licensed.
+ */
+
+var config = {
+ port: 8090,
+ ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
+
+ language: "en",
+ timeFormat: 24,
+ units: "metric",
+ electronOptions: {
+ webPreferences: {
+ nodeIntegration: true,
+ },
+ },
+
+ modules: [
+ ]
+};
+
+/*************** DO NOT EDIT THE LINE BELOW ***************/
+if (typeof module !== "undefined") {module.exports = config;}
diff --git a/tests/e2e/env_spec.js b/tests/e2e/env_spec.js
index 99a7f657..202bd5e4 100644
--- a/tests/e2e/env_spec.js
+++ b/tests/e2e/env_spec.js
@@ -1,5 +1,8 @@
const globalSetup = require("./global-setup");
const app = globalSetup.app;
+const request = require("request");
+const chai = require("chai");
+const expect = chai.expect;
describe("Electron app environment", function () {
this.timeout(20000);
@@ -17,7 +20,6 @@ describe("Electron app environment", function () {
app.stop().then(function() { done(); });
});
-
it("is set to open new app window", function () {
return app.client.waitUntilWindowLoaded()
.getWindowCount().should.eventually.equal(1);
@@ -28,4 +30,18 @@ describe("Electron app environment", function () {
.getTitle().should.eventually.equal("Magic Mirror");
});
+ it("get request from http://localhost:8080 should return 200", function (done) {
+ request.get("http://localhost:8080", function (err, res, body) {
+ expect(res.statusCode).to.equal(200);
+ done();
+ });
+ });
+
+ it("get request from http://localhost:8080/nothing should return 404", function (done) {
+ request.get("http://localhost:8080/nothing", function (err, res, body) {
+ expect(res.statusCode).to.equal(404);
+ done();
+ });
+ });
+
});
diff --git a/tests/e2e/modules/calendar_spec.js b/tests/e2e/modules/calendar_spec.js
index 21939f06..c701ed3c 100644
--- a/tests/e2e/modules/calendar_spec.js
+++ b/tests/e2e/modules/calendar_spec.js
@@ -65,6 +65,17 @@ describe("Calendar module", function () {
});
});
+ describe("Fail Basic auth", function() {
+ before(function() {
+ serverBasicAuth.listen(8020);
+ // Set config sample for use in test
+ process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/fail-basic-auth.js";
+ });
+
+ it("Should return No upcoming events", function () {
+ return app.client.waitUntilTextExists(".calendar", "No upcoming events.", 10000);
+ });
+ });
});
diff --git a/tests/e2e/modules_position_spec.js b/tests/e2e/modules_position_spec.js
new file mode 100644
index 00000000..a781388a
--- /dev/null
+++ b/tests/e2e/modules_position_spec.js
@@ -0,0 +1,42 @@
+const globalSetup = require("./global-setup");
+const app = globalSetup.app;
+const chai = require("chai");
+const expect = chai.expect;
+
+describe("Position of modules", function () {
+ this.timeout(20000);
+
+
+ beforeEach(function (done) {
+ app.start().then(function() { done(); } );
+ });
+
+ afterEach(function (done) {
+ app.stop().then(function() { done(); });
+ });
+
+
+ describe("Using helloworld", function() {
+
+ before(function() {
+ // Set config sample for use in test
+ process.env.MM_CONFIG_FILE = "tests/configs/modules/positions.js";
+ });
+
+ var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third",
+ "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right",
+ "bottom_bar", "fullscreen_above", "fullscreen_below"];
+
+ var position;
+ var className;
+ for (idx in positions) {
+ position = positions[idx];
+ className = position.replace("_", ".");
+ it("show text in " + position , function () {
+ return app.client.waitUntilWindowLoaded()
+ .getText("." + className).should.eventually.equal("Text in " + position);
+ });
+ }
+ });
+
+});
diff --git a/tests/e2e/port_config.js b/tests/e2e/port_config.js
new file mode 100644
index 00000000..c0806e85
--- /dev/null
+++ b/tests/e2e/port_config.js
@@ -0,0 +1,32 @@
+const globalSetup = require("./global-setup");
+const app = globalSetup.app;
+const request = require("request");
+const chai = require("chai");
+const expect = chai.expect;
+
+
+describe("port directive configuration", function () {
+
+ this.timeout(20000);
+
+ beforeEach(function (done) {
+ app.start().then(function() { done(); } );
+ });
+
+ afterEach(function (done) {
+ app.stop().then(function() { done(); });
+ });
+
+ describe("Set port 8090", function () {
+ before(function() {
+ // Set config sample for use in this test
+ process.env.MM_CONFIG_FILE = "tests/configs/port_8090.js";
+ });
+ it("should return 200", function (done) {
+ request.get("http://localhost:8090", function (err, res, body) {
+ expect(res.statusCode).to.equal(200);
+ done();
+ });
+ });
+ });
+});
diff --git a/vendor/vendor.js b/vendor/vendor.js
index 32eab950..7076cc45 100644
--- a/vendor/vendor.js
+++ b/vendor/vendor.js
@@ -8,9 +8,9 @@
*/
var vendor = {
- 'moment.js' : 'node_modules/moment/min/moment-with-locales.js',
- 'moment-timezone.js' : 'node_modules/moment-timezone/moment-timezone.js',
- 'weather-icons.css': 'node_modules/weathericons/css/weather-icons.css',
- 'weather-icons-wind.css': 'node_modules/weathericons/css/weather-icons-wind.css',
- 'font-awesome.css': 'node_modules/font-awesome/css/font-awesome.min.css'
+ "moment.js" : "node_modules/moment/min/moment-with-locales.js",
+ "moment-timezone.js" : "node_modules/moment-timezone/moment-timezone.js",
+ "weather-icons.css": "node_modules/weathericons/css/weather-icons.css",
+ "weather-icons-wind.css": "node_modules/weathericons/css/weather-icons-wind.css",
+ "font-awesome.css": "node_modules/font-awesome/css/font-awesome.min.css"
};