diff --git a/data/newArticles.yaml b/data/newArticles.yaml new file mode 100644 index 00000000..98e16dc7 --- /dev/null +++ b/data/newArticles.yaml @@ -0,0 +1,6 @@ +Calendar: + categoryEN: "Upcoming Events" + title: "#BlogName# Upcoming Events" +Picture: + categoryEN: "Picture" + title: "#BlogName# Picture" diff --git a/model/blog.js b/model/blog.js index 866f2908..fa5dcff9 100644 --- a/model/blog.js +++ b/model/blog.js @@ -379,30 +379,30 @@ function createNewBlog(user, proto, noArticle, callback) { // create an Empty blog and simualte an id != 0 const emptyBlog = exports.create(); emptyBlog.id = -1; + const newArticles = configModule.getConfig("newArticles"); - async.series([ - function createCalendar(cb) { + async.eachOf(newArticles, + function createArticle(value, key, cb) { if (noArticle) return cb(); - articleModule.createNewArticle({ blog: blog.name, categoryEN: "Upcoming Events", title: blog.name + " Upcoming Events" }, cb); + const newArticle = { blog: blog.name }; + for (const k in value) { + newArticle[k] = value[k].replaceAll("#BlogName#", blog.name); + } + articleModule.createNewArticle(newArticle, cb); }, - function createCalendar(cb) { - if (noArticle) return cb(); - articleModule.createNewArticle({ blog: blog.name, categoryEN: "Picture", title: blog.name + " Picture" }, cb); - } - ], - function finalFunction(err) { - if (err) return callback(err); - blog.save(function feedback(err, savedblog) { + function finalFunction(err) { if (err) return callback(err); - emptyBlog.id = savedblog.id; - messageCenter.global.updateBlog(user, emptyBlog, change, function(err) { - if (err) { - return callback(err); - } - return callback(null, savedblog); + blog.save(function feedback(err, savedblog) { + if (err) return callback(err); + emptyBlog.id = savedblog.id; + messageCenter.global.updateBlog(user, emptyBlog, change, function(err) { + if (err) { + return callback(err); + } + return callback(null, savedblog); + }); }); }); - }); }); } if (callback) { diff --git a/model/config.js b/model/config.js index 9a5b46ba..c166bb4c 100644 --- a/model/config.js +++ b/model/config.js @@ -124,6 +124,7 @@ Config.prototype.getJSON = function getJSON() { this.json = yaml.load(this.yaml); if (this.name === "votes") this.json = freshupVotes(this.json); if (this.name === "languageflags") this.json = freshupEmoji(this.json); + checkAndRepair[this.name](this); return this.json; } catch (err) { return { error: "YAML convert error for: " + this.name + " ", errorMessage: err }; @@ -282,69 +283,85 @@ const checkAndRepair = { let v = c.getJSON(); if (!v) v = []; c.json = v; + }, + newArticles: function(c) { + let v = c.getJSON(); + if (!v) v = {}; + for (const k in v) { + for (const k2 in v[k]) { + if (["collection", "title", "categoryEN"].indexOf(k2) >= 0) continue; + delete v[k][k2]; + } + } + c.json = v; } }; Config.prototype.setAndSave = function setAndSave(user, data, callback) { - debug("setAndSave"); - - util.requireTypes([user, data, callback], ["object", "object", "function"]); - const self = this; + function _configSetAndSave(user, data, callback) { + debug("setAndSave"); + util.requireTypes([user, data, callback], ["object", "object", "function"]); + // try to convert YAML if necessary + + delete self.json; + + + async.eachOf(data, function setAndSaveEachOf(value, key, cbEachOf) { + // There is no Value for the key, so do nothing + if (typeof (value) === "undefined") return cbEachOf(); + + // The Value to be set, is the same then in the object itself + // so do nothing + if (value === self[key]) return cbEachOf(); + if (JSON.stringify(value) === JSON.stringify(self[key])) return cbEachOf(); + if (typeof (self[key]) === "undefined" && value === "") return cbEachOf(); + + + debug("Set Key %s to value >>%s<<", key, value); + debug("Old Value Was >>%s<<", self[key]); + + + async.series([ + function calculateID(cb) { + if (self.id !== 0) return cb(); + self.save(cb); + }, + function(cb) { + // do not log validation key in logfile + const toValue = value; + + messageCenter.global.sendInfo({ oid: self.id, user: user.OSMUser, table: "config", property: key, from: self[key], to: toValue }, cb); + }, + function(cb) { + self[key] = value; + cb(); + } + ], function(err) { + cbEachOf(err); + }); + }, function setAndSaveFinalCB(err) { + debug("setAndSaveFinalCB"); + if (err) return callback(err); + checkAndRepair[self.name](self); + if (self.json && self.json.error) { + return callback(new Error(self.json.errorMessage)); + } + actualiseConfigMap(self); - // try to convert YAML if necessary - - delete self.json; - - - async.eachOf(data, function setAndSaveEachOf(value, key, cbEachOf) { - // There is no Value for the key, so do nothing - if (typeof (value) === "undefined") return cbEachOf(); - - // The Value to be set, is the same then in the object itself - // so do nothing - if (value === self[key]) return cbEachOf(); - if (JSON.stringify(value) === JSON.stringify(self[key])) return cbEachOf(); - if (typeof (self[key]) === "undefined" && value === "") return cbEachOf(); - - - debug("Set Key %s to value >>%s<<", key, value); - debug("Old Value Was >>%s<<", self[key]); - - - async.series([ - function calculateID(cb) { - if (self.id !== 0) return cb(); - self.save(cb); - }, - function(cb) { - // do not log validation key in logfile - const toValue = value; - - messageCenter.global.sendInfo({ oid: self.id, user: user.OSMUser, table: "config", property: key, from: self[key], to: toValue }, cb); - }, - function(cb) { - self[key] = value; - cb(); + if (self.name === "slacknotification") { + // Reinitialise Slack Receiver if something is changed on slack notification. + slackReceiver.initialise(); } - ], function(err) { - cbEachOf(err); + self.save(callback); }); - }, function setAndSaveFinalCB(err) { - debug("setAndSaveFinalCB"); - if (err) return callback(err); - checkAndRepair[self.name](self); - if (self.json && self.json.error) { - return callback(new Error(self.json.errorMessage)); - } - actualiseConfigMap(self); - - if (self.name === "slacknotification") { - // Reinitialise Slack Receiver if something is changed on slack notification. - slackReceiver.initialise(); - } - self.save(callback); + } + if (callback) { + return _configSetAndSave(user, data, callback); + } + return new Promise((resolve, reject) => { + _configSetAndSave(user, data, (err) => { (err) ? reject(err) : resolve(); }); }); }; @@ -408,7 +425,8 @@ function initialise(callback) { initConfigElement.bind(null, "automatictranslatetext"), initConfigElement.bind(null, "votes"), initConfigElement.bind(null, "eventsfilter"), - initConfigElement.bind(null, "ignoreforsearch") + initConfigElement.bind(null, "ignoreforsearch"), + initConfigElement.bind(null, "newArticles") ], function final(err) { debug("finalFunction initialise"); @@ -432,23 +450,31 @@ module.exports.getConfig = function(text) { }; module.exports.getConfigObject = function(text, callback) { - debug("exports.getConfigObject"); - let config = null; - assert(configMap); - if (configMap[text]) { - config = configMap[text]; - } else { - for (const key in configMap) { - const c = configMap[key]; - if (c.id === text) { - config = c; - break; + function _getConfigObject(text, callback) { + debug("exports.getConfigObject"); + let config = null; + assert(configMap); + if (configMap[text]) { + config = configMap[text]; + } else { + for (const key in configMap) { + const c = configMap[key]; + if (c.id === text) { + config = c; + break; + } } } + assert(config); + if (callback) return callback(null, config); + return config; } - assert(config); - if (callback) return callback(null, config); - return config; + if (callback) { + return _getConfigObject(text, callback); + } + return new Promise((resolve, reject) => { + _getConfigObject(text, (err, result) => (err) ? reject(err) : resolve(result)); + }); }; module.exports.initialise = initialise; diff --git a/model/logModule.js b/model/logModule.js index cc99272a..4cf69f4d 100644 --- a/model/logModule.js +++ b/model/logModule.js @@ -34,8 +34,17 @@ module.exports.log = function log(object, callback) { module.exports.find = function(obj1, obj2, callback) { - debug("find"); - pgMap.find(this, obj1, obj2, callback); + const self = this; + function _find(obj1, obj2, callback) { + debug("find"); + pgMap.find(self, obj1, obj2, callback); + } + if (callback) { + return _find(obj1, obj2, callback); + } + return new Promise((resolve, reject) => { + _find(obj1, obj2, (err, result) => (err) ? reject(err) : resolve(result)); + }); }; module.exports.findById = function(id, callback) { debug("findById"); diff --git a/notification/slackReceiver.js b/notification/slackReceiver.js index 948c24af..c45bd3f5 100644 --- a/notification/slackReceiver.js +++ b/notification/slackReceiver.js @@ -247,21 +247,24 @@ function initialise(callback) { debug("initialise"); slackhook = config.getValue("slacktool"); messageCenter.initialise(); - const channelList = configModule.getConfigObject("slacknotification").getJSON(); - - channelReceiverMap = {}; - for (let i = 0; i < channelList.length; i++) { - const channel = channelList[i]; - if (channel.channel.substring(0, 1) !== "#") continue; - channelReceiverMap["Slack Connection " + i] = new ConfigFilter(channel, new SlackReceiver(channel.slack + channel.channel, channel.slack, channel.channel)); - } - iteratorReceiver.receiverMap = channelReceiverMap; - assert(messageCenter.global); - if (!registered) { - messageCenter.global.registerReceiver(iteratorReceiver); - registered = true; - } - if (callback) return callback(); + configModule.getConfigObject("slacknotification", function(err, slackConfig) { + if (err) return callback(err); + const channelList = slackConfig.getJSON(); + + channelReceiverMap = {}; + for (let i = 0; i < channelList.length; i++) { + const channel = channelList[i]; + if (channel.channel.substring(0, 1) !== "#") continue; + channelReceiverMap["Slack Connection " + i] = new ConfigFilter(channel, new SlackReceiver(channel.slack + channel.channel, channel.slack, channel.channel)); + } + iteratorReceiver.receiverMap = channelReceiverMap; + assert(messageCenter.global); + if (!registered) { + messageCenter.global.registerReceiver(iteratorReceiver); + registered = true; + } + if (callback) return callback(); + }); } diff --git a/routes/config.js b/routes/config.js index be57bf33..23def839 100644 --- a/routes/config.js +++ b/routes/config.js @@ -60,6 +60,7 @@ function renderConfigName(req, res, next) { if (name === "languageflags") jadeFile = "calendarflags"; if (name === "calendartranslation") jadeFile = name; if (name === "editorstrings") jadeFile = name; + if (name === "newArticles") jadeFile = "config"; if (name === "categorytranslation") jadeFile = name; if (name === "automatictranslatetext") jadeFile = name; if (name === "slacknotification") jadeFile = name; diff --git a/test/index/admin_home.html b/test/index/admin_home.html index 46221043..e97aa36d 100644 --- a/test/index/admin_home.html +++ b/test/index/admin_home.html @@ -60,6 +60,7 @@

Pictures

Blog

Author Documentation

Category Translation

+

Empty Articles To Create

Article

Text for Translate Links

Not a Doublette Link

diff --git a/test/model.config.test.js b/test/model.config.test.js index 6ff73eab..e0d26569 100644 --- a/test/model.config.test.js +++ b/test/model.config.test.js @@ -28,45 +28,67 @@ describe("model/config", function() { should(c.brasil).eql("http://blog.openstreetmap.de/wp-uploads/2016/03/br.svg"); bddone(); }); - it("should have stored initialised value", function (bddone) { - testutil.findJSON("config", { name: "calendarflags" }, function(err, result) { - should.not.exist(err); - should.exist(result); - should(result.type).eql("yaml"); - bddone(); - }); + it("should have stored initialised value", async function () { + const result = await testutil.findJSON("config", { name: "calendarflags" }); + should.exist(result); + should(result.type).eql("yaml"); }); describe("setAndSave", function() { - beforeEach(function(bddone) { - async.series([ - testutil.clearDB - ], bddone); + beforeEach(async function() { + await testutil.clearDB(); }); - it("should set only the one Value in the database", function (bddone) { - let changeConfig; - configModule.getConfigObject("calendarflags", function(err, result) { - should.not.exist(err); - should.exist(result); - changeConfig = result; - const id = changeConfig.id; - changeConfig.yaml = "not logged"; - changeConfig.setAndSave({ OSMUser: "user" }, { version: 1, yaml: "not logged" }, function(err) { - should.not.exist(err); - testutil.findJSON("config", { name: "calendarflags" }, function(err, result) { - should.not.exist(err); - should(result).eql({ id: id, yaml: "not logged", version: 2, name: "calendarflags", type: "yaml" }); - logModule.find({}, { column: "property" }, function (err, result) { - should.not.exist(err); - should.exist(result); - should(result.length).equal(0); - bddone(); - }); - }); - }); - }); + it("should set only the one Value in the database", async function () { + let result = await configModule.getConfigObject("calendarflags"); + should.exist(result); + const changeConfig = result; + const id = changeConfig.id; + changeConfig.yaml = "not logged"; + await changeConfig.setAndSave({ OSMUser: "user" }, { version: 1, yaml: "not logged" }); + + result = await testutil.findJSON("config", { name: "calendarflags" }); + + should(result).eql({ id: id, yaml: "not logged", version: 2, name: "calendarflags", type: "yaml" }); + result = await logModule.find({}, { column: "property" }); + + should.exist(result); + should(result.length).equal(0); + }); + }); + const yamlData = ` + pictures: + title: "#BlogName# Pictures" + collection: sample Collection + markdownDE: sample + notUsedKey: valueOfNotUsedKey + pictures2: + title: "#BlogName# Pictures2" + `; + it("should only set allowed values for newArticles", async function() { + const newArticlesConfig = await configModule.getConfigObject("newArticles"); + should.exist(newArticlesConfig); + const id = newArticlesConfig.id; + await newArticlesConfig.setAndSave({ OSMUser: "user" }, { version: 1, yaml: yamlData }); + const result = await configModule.getConfigObject("newArticles"); + // call json to create in memory. + result.getJSON(); + should(result).eql({ + id: id, + yaml: "\n pictures: \n title: \"#BlogName# Pictures\"\n collection: sample Collection\n markdownDE: sample\n notUsedKey: valueOfNotUsedKey\n pictures2: \n title: \"#BlogName# Pictures2\"\n ", + version: 2, + name: "newArticles", + type: "yaml", + json: { + pictures: { + collection: "sample Collection", + title: "#BlogName# Pictures" + }, + pictures2: { + title: "#BlogName# Pictures2" + } + } }); }); }); diff --git a/test/testutil.js b/test/testutil.js index 9a2ee43b..51449ef3 100644 --- a/test/testutil.js +++ b/test/testutil.js @@ -63,9 +63,19 @@ exports.getJsonWithId = function getJsonWithId(table, id, cb) { // without using the model source, and is intended to used in // mocha tests. function internCreate() { return {}; } + exports.findJSON = function findJSON(table, obj, cb) { - debug("findJSON"); - pgMap.findOne({ table: table, create: internCreate }, obj, cb); + function _findJSON(table, obj, cb) { + debug("findJSON"); + pgMap.findOne({ table: table, create: internCreate }, obj, cb); + } + if (cb) { + return _findJSON(table, obj, cb); + } + + return new Promise((resolve, reject) => { + _findJSON(table, obj, (err, result) => (err) ? reject(err) : resolve(result)); + }); }; // This function is used to clean up the tables in the test module diff --git a/test/uc.access/fullAdminPage.html b/test/uc.access/fullAdminPage.html index 74db47f1..421313e8 100644 --- a/test/uc.access/fullAdminPage.html +++ b/test/uc.access/fullAdminPage.html @@ -60,6 +60,7 @@

Pictures

Blog

Author Documentation

Category Translation

+

Empty Articles To Create

Article

Text for Translate Links

Not a Doublette Link

diff --git a/views/adminindex.pug b/views/adminindex.pug index 92cd7d01..1bf1611f 100644 --- a/views/adminindex.pug +++ b/views/adminindex.pug @@ -29,6 +29,8 @@ block content a(href=layout.htmlroot+"/config/editorstrings") Author Documentation p a(href=layout.htmlroot+"/config/categorytranslation") Category Translation + p + a(href=layout.htmlroot+"/config/newArticles") Empty Articles To Create h3="Article" p a(href=layout.htmlroot+"/config/automatictranslatetext") Text for Translate Links