From f47c4e31e824a8df1ab9439c77b3f72bbf60dce7 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 31 May 2024 04:14:58 +0000 Subject: [PATCH 1/2] style: format code with clang-format --- client/helpers/submitOnEnter.js | 9 +- .../helpers/tabFilterDatabaseOperations.js | 24 +- imports/ldap/getLDAPUsers.js | 106 ++- imports/ldap/import.js | 48 +- imports/ldap/loadLDAPSettings.js | 52 +- imports/ldap/saveUsers.js | 67 +- imports/priority.js | 28 +- .../exportimport/expImpFilesAttachments.js | 94 ++- .../exportimport/expImpFilesDocuments.js | 104 ++- .../exportimport/expImpMeetingseries.js | 97 ++- imports/server/exportimport/expImpMinutes.js | 144 ++-- imports/server/exportimport/expImpSchema.js | 149 ++-- imports/server/exportimport/expImpTopics.js | 85 +-- imports/server/exportimport/expImpUsers.js | 222 +++--- private/createTestUsers.js | 46 +- private/exportMeetingSeries.js | 72 +- private/importMeetingSeries.js | 108 +-- programs/generateLicenseList.js | 255 +++---- .../unit/client/helpers/submitOnEnter.test.js | 83 ++- tests/unit/imports/ActionItem.test.js | 97 ++- tests/unit/imports/GlobalSettings.test.js | 191 ++--- tests/unit/imports/InfoItem.test.js | 108 +-- tests/unit/imports/InfoItemFactory.test.js | 93 +-- tests/unit/imports/MeetingSeries.test.js | 168 +++-- tests/unit/imports/Minutes.test.js | 444 ++++++------ tests/unit/imports/Topic.test.js | 429 ++++++----- .../client/ResponsiblePreparer.test.js | 155 ++-- tests/unit/imports/ldap/getLDAPUsers.test.js | 671 +++++++++--------- tests/unit/imports/priority.test.js | 40 +- tests/unit/imports/search/ItemsFilter.test.js | 150 ++-- tests/unit/imports/search/QueryParser.test.js | 186 ++--- tests/unit/test-helper/rewiremock.js | 6 +- 32 files changed, 2233 insertions(+), 2298 deletions(-) diff --git a/client/helpers/submitOnEnter.js b/client/helpers/submitOnEnter.js index 4f2526fed..582a308b9 100644 --- a/client/helpers/submitOnEnter.js +++ b/client/helpers/submitOnEnter.js @@ -1,8 +1,6 @@ import jQuery from 'jquery'; window.$ = window.jQuery = jQuery; - - /** * Creates a handler function that prevents the default behavior of the event * and executes the provided action when the Enter key is pressed while the Ctrl @@ -35,8 +33,7 @@ function createHandler(action) { * @param {Array} textareas - An array of textarea elements. * @param {Function} action - The action to be triggered on keyup event. */ -export default function (textareas, action) { - textareas.forEach((input) => { - window.$(input).on("keyup", createHandler(action)); - }); +export default function(textareas, action) { + textareas.forEach( + (input) => { window.$(input).on("keyup", createHandler(action)); }); } diff --git a/client/templates/meetingseries/helpers/tabFilterDatabaseOperations.js b/client/templates/meetingseries/helpers/tabFilterDatabaseOperations.js index 35d978aa7..edac1768b 100644 --- a/client/templates/meetingseries/helpers/tabFilterDatabaseOperations.js +++ b/client/templates/meetingseries/helpers/tabFilterDatabaseOperations.js @@ -1,18 +1,16 @@ -import { Meteor } from "meteor/meteor"; +import {Meteor} from "meteor/meteor"; -import { Label } from "../imports/label"; +import {Label} from "../imports/label"; export function createLabelIdsReceiver(parentMeetingSeriesId) { return function getLabelIdsByName(labelName, caseSensitive) { const label = Label.findLabelsContainingSubstring( - parentMeetingSeriesId, - labelName, - caseSensitive, + parentMeetingSeriesId, + labelName, + caseSensitive, ); if (label !== null) { - return label.map((label) => { - return label._id; - }); + return label.map((label) => { return label._id; }); } return null; }; @@ -20,13 +18,11 @@ export function createLabelIdsReceiver(parentMeetingSeriesId) { export function createUserIdsReceiver(userName) { const users = - userName === "me" - ? [Meteor.user()] - : Meteor.users.find({ username: { $regex: userName } }).fetch(); + userName === "me" + ? [ Meteor.user() ] + : Meteor.users.find({username : {$regex : userName}}).fetch(); if (users) { - return users.map((user) => { - return user._id; - }); + return users.map((user) => { return user._id; }); } return []; diff --git a/imports/ldap/getLDAPUsers.js b/imports/ldap/getLDAPUsers.js index 1b58d1c5c..3831b0384 100644 --- a/imports/ldap/getLDAPUsers.js +++ b/imports/ldap/getLDAPUsers.js @@ -1,46 +1,44 @@ import ldap from "ldapjs"; import _ from "lodash"; -const _createLDAPClient = (settings) => - new Promise((resolve, reject) => { - try { - const client = ldap.createClient({ - url: settings.serverUrl, - }); +const _createLDAPClient = (settings) => new Promise((resolve, reject) => { + try { + const client = ldap.createClient({ + url : settings.serverUrl, + }); - resolve({ - client, - settings, - }); - } catch (error) { - reject(`Error creating client: ${error}`); - } - }); + resolve({ + client, + settings, + }); + } catch (error) { + reject(`Error creating client: ${error}`); + } +}); -const _bind = (connection) => - new Promise((resolve, reject) => { - const client = connection.client; - const settings = connection.settings; - const auth = settings.authentication; - const userDn = auth?.userDn; - const password = auth?.password; - - // no authentication details provided - // => the ldap server probably allows anonymous access - if (!userDn || !password) { - resolve(connection); +const _bind = (connection) => new Promise((resolve, reject) => { + const client = connection.client; + const settings = connection.settings; + const auth = settings.authentication; + const userDn = auth?.userDn; + const password = auth?.password; + + // no authentication details provided + // => the ldap server probably allows anonymous access + if (!userDn || !password) { + resolve(connection); + return; + } + + client.bind(userDn, password, (error) => { + if (error) { + reject(error); return; } - client.bind(userDn, password, (error) => { - if (error) { - reject(error); - return; - } - - resolve(connection); - }); + resolve(connection); }); +}); const inactivityStrategies = { userAccountControl(inactivitySettings, entry) { @@ -56,15 +54,13 @@ const inactivityStrategies = { return result || entry.object[key] === inactiveProperties[key]; }, false); }, - none() { - return false; - }, + none() { return false; }, }; function isInactive(inactivitySettings, entry) { const strategy = inactivitySettings?.strategy || "none"; const strategyFunction = - inactivityStrategies[strategy] || inactivityStrategies.none; + inactivityStrategies[strategy] || inactivityStrategies.none; return strategyFunction(inactivitySettings, entry); } @@ -75,9 +71,9 @@ const _fetchLDAPUsers = (connection) => { const base = settings.serverDn; const searchDn = _.get(settings, "propertyMap.username", "cn"); const userLongNameAttribute = _.get( - settings, - "propertyMap.longname", - searchDn, + settings, + "propertyMap.longname", + searchDn, ); const emailAttribute = _.get(settings, "propertyMap.email", searchDn); const filter = `(&(${searchDn}=*)${settings.searchFilter})`; @@ -89,35 +85,32 @@ const _fetchLDAPUsers = (connection) => { userLongNameAttribute, emailAttribute, ]); - const options = { filter, scope, attributes, paged: true }; + const options = {filter, scope, attributes, paged : true}; if (settings.isInactivePredicate && !settings.inactiveUsers) { settings.inactiveUsers = { - strategy: "property", - properties: settings.isInactivePredicate, + strategy : "property", + properties : settings.isInactivePredicate, }; } return new Promise((resolve, reject) => { try { client.search(base, options, (error, response) => { - if (error) reject(`Search failed: ${error}`); + if (error) + reject(`Search failed: ${error}`); const entries = []; response.on("searchEntry", (entry) => { const userIsInactive = isInactive(settings.inactiveUsers, entry); const userData = Object.assign({}, entry.object, { - isInactive: userIsInactive, + isInactive : userIsInactive, }); entries.push(userData); }); - response.on("error", (error) => { - reject(error); - }); - response.on("end", () => { - resolve({ client, settings, entries }); - }); + response.on("error", (error) => { reject(error); }); + response.on("end", () => { resolve({client, settings, entries}); }); }); } catch (error) { reject(error); @@ -134,19 +127,18 @@ const _closeLDAPClient = (connection) => { client.unbind(() => { // even if disconnect fails: we still have the users // ignore the error and return the users - resolve({ settings, users }); + resolve({settings, users}); }); }); }; -const getLDAPUsers = (settings) => - new Promise((resolve, reject) => { - _createLDAPClient(settings) +const getLDAPUsers = (settings) => new Promise((resolve, reject) => { + _createLDAPClient(settings) .then(_bind) .then(_fetchLDAPUsers) .then(_closeLDAPClient) .then(resolve) .catch(reject); - }); +}); export default getLDAPUsers; diff --git a/imports/ldap/import.js b/imports/ldap/import.js index f8b2e9d06..c0ea35155 100644 --- a/imports/ldap/import.js +++ b/imports/ldap/import.js @@ -2,34 +2,32 @@ import getLDAPUsers from "./getLDAPUsers"; import saveUsers from "./saveUsers"; const report = (bulkResult) => { - let inserted = bulkResult.nUpserted, - updated = bulkResult.nModified; + let inserted = bulkResult.nUpserted, updated = bulkResult.nModified; console.log( - `Successfully inserted ${inserted} users and updated ${updated} users.`, + `Successfully inserted ${inserted} users and updated ${updated} users.`, ); }; let selfSignedTLSAllowed = process.env.NODE_TLS_REJECT_UNAUTHORIZED; let importLock = false; -const setSelfSigned = (ldapSettings) => - new Promise((resolve, reject) => { - if (importLock) { - reject("There already is a user import running."); - return; - } +const setSelfSigned = (ldapSettings) => new Promise((resolve, reject) => { + if (importLock) { + reject("There already is a user import running."); + return; + } - importLock = true; + importLock = true; - const allowSelfSignedTLS = ldapSettings.allowSelfSignedTLS; - selfSignedTLSAllowed = process.env.NODE_TLS_REJECT_UNAUTHORIZED; + const allowSelfSignedTLS = ldapSettings.allowSelfSignedTLS; + selfSignedTLSAllowed = process.env.NODE_TLS_REJECT_UNAUTHORIZED; - if (allowSelfSignedTLS) { - process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; - } + if (allowSelfSignedTLS) { + process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; + } - resolve(ldapSettings); - }); + resolve(ldapSettings); +}); const resetSelfSigned = () => { process.env.NODE_TLS_REJECT_UNAUTHORIZED = selfSignedTLSAllowed; @@ -46,13 +44,13 @@ const handleRejection = (error) => { }; const importUsers = (ldapSettings, mongoUrl) => - setSelfSigned(ldapSettings) - .then(getLDAPUsers) - .then((data) => { - return saveUsers(data.settings, mongoUrl, data.users); - }) - .then(report) - .then(resetSelfSigned) - .catch(handleRejection); + setSelfSigned(ldapSettings) + .then(getLDAPUsers) + .then((data) => { + return saveUsers(data.settings, mongoUrl, data.users); + }) + .then(report) + .then(resetSelfSigned) + .catch(handleRejection); export default importUsers; diff --git a/imports/ldap/loadLDAPSettings.js b/imports/ldap/loadLDAPSettings.js index f69384fd9..9bfd4613c 100644 --- a/imports/ldap/loadLDAPSettings.js +++ b/imports/ldap/loadLDAPSettings.js @@ -1,41 +1,35 @@ import fs from "fs"; -const _readSettingsFile = (filename) => - new Promise((resolve, reject) => { - fs.readFile(filename, "utf8", (error, data) => { - if (error) { - reject(`Could not read settings file "${filename}"`); - } else { - resolve(data); - } - }); - }); - -const _parseJSON = (json) => - new Promise((resolve, reject) => { - try { - const data = JSON.parse(json); +const _readSettingsFile = (filename) => new Promise((resolve, reject) => { + fs.readFile(filename, "utf8", (error, data) => { + if (error) { + reject(`Could not read settings file "${filename}"`); + } else { resolve(data); - } catch (error) { - reject("Could not parse json."); } }); +}); -const _property = (property, object) => - new Promise((resolve, reject) => { - const sub = object[property]; - return sub ? resolve(sub) : reject(`Property "${property}" not found.`); - }); +const _parseJSON = (json) => new Promise((resolve, reject) => { + try { + const data = JSON.parse(json); + resolve(data); + } catch (error) { + reject("Could not parse json."); + } +}); -const loadLDAPSettings = (filename) => - new Promise((resolve, reject) => { - _readSettingsFile(filename) +const _property = (property, object) => new Promise((resolve, reject) => { + const sub = object[property]; + return sub ? resolve(sub) : reject(`Property "${property}" not found.`); +}); + +const loadLDAPSettings = (filename) => new Promise((resolve, reject) => { + _readSettingsFile(filename) .then(_parseJSON) - .then((settings) => { - return _property("ldap", settings); - }) + .then((settings) => { return _property("ldap", settings); }) .then(resolve) .catch(reject); - }); +}); export default loadLDAPSettings; diff --git a/imports/ldap/saveUsers.js b/imports/ldap/saveUsers.js index 45059fec0..009f804c8 100644 --- a/imports/ldap/saveUsers.js +++ b/imports/ldap/saveUsers.js @@ -1,13 +1,13 @@ -import { _ } from "lodash"; +import {_} from "lodash"; import mongoUriParser from "mongo-uri"; -import { MongoClient as mongo } from "mongodb"; +import {MongoClient as mongo} from "mongodb"; -import { Random } from "../../tests/performance/fixtures/lib/random"; +import {Random} from "../../tests/performance/fixtures/lib/random"; import transformUser from "./transformUser"; const _transformUsers = (settings, users) => - _.map(users, (user) => transformUser(settings, user)); + _.map(users, (user) => transformUser(settings, user)); const _connectMongo = (mongoUrl) => mongo.connect(mongoUrl); @@ -20,49 +20,46 @@ const _insertUsers = (client, mongoUri, users) => { // string length: // https://github.com/meteor/meteor/blob/release/METEOR%401.4.0.1/packages/random/random.js#L197 const randomStringConfig = { - length: 17, - charset: "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", + length : 17, + charset : "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", }; return new Promise((resolve, reject) => { try { const mongoConnection = mongoUriParser.parse(mongoUri); - const bulk = client - .db(mongoConnection.database) - .collection("users") - .initializeUnorderedBulkOp(); + const bulk = client.db(mongoConnection.database) + .collection("users") + .initializeUnorderedBulkOp(); _.forEach(users, (user) => { if (user?.username && user.emails[0] && user.emails[0].address) { user.isLDAPuser = true; const usrRegExp = new RegExp( - `^${RegExp.escape(user.username)}$`, - "i", + `^${RegExp.escape(user.username)}$`, + "i", ); - bulk - .find({ username: usrRegExp }) - .upsert() - .updateOne({ - $setOnInsert: { - _id: Random.generateId(), - // by setting this only on insert we won't log out everyone - // everytime we sync the users - services: { - password: { bcrypt: "" }, - resume: { loginTokens: [] }, - }, + bulk.find({username : usrRegExp}).upsert().updateOne({ + $setOnInsert : { + _id : Random.generateId(), + // by setting this only on insert we won't log out everyone + // everytime we sync the users + services : { + password : {bcrypt : ""}, + resume : {loginTokens : []}, }, - $set: user, - }); + }, + $set : user, + }); } else { const stringifiedUser = JSON.stringify(user, null, 2); console.log( - `SKIPPED INVALID USER (no username or no valid emails[0].address): ${stringifiedUser}`, + `SKIPPED INVALID USER (no username or no valid emails[0].address): ${ + stringifiedUser}`, ); } }); const bulkResult = bulk.execute(); - resolve({ client, bulkResult }); + resolve({client, bulkResult}); } catch (error) { reject(error); } @@ -70,9 +67,7 @@ const _insertUsers = (client, mongoUri, users) => { }; const _closeMongo = (data) => { - let force = false, - client = data.client, - result = data.bulkResult; + let force = false, client = data.client, result = data.bulkResult; return new Promise((resolve) => { client.close(force); @@ -85,12 +80,10 @@ const saveUsers = (settings, mongoUrl, users) => { return new Promise((resolve, reject) => { _connectMongo(mongoUrl) - .then((client) => { - return _insertUsers(client, mongoUrl, dbUsers); - }) - .then(_closeMongo) - .then(resolve) - .catch(reject); + .then((client) => { return _insertUsers(client, mongoUrl, dbUsers); }) + .then(_closeMongo) + .then(resolve) + .catch(reject); }); }; diff --git a/imports/priority.js b/imports/priority.js index 46add4e15..6d0335b87 100644 --- a/imports/priority.js +++ b/imports/priority.js @@ -1,15 +1,15 @@ import assert from "assert"; -import { i18n } from "meteor/universe:i18n"; +import {i18n} from "meteor/universe:i18n"; // #I18N - Attention: the below strings with longer texts will be never be used // in UI! Instead they will be pulled from translation language files via // toString() method below const PRIORITY_MAP = { - 1: "1 - High", - 2: "2", - 3: "3 - Medium", - 4: "4", - 5: "5 - Low", + 1 : "1 - High", + 2 : "2", + 3 : "3 - Medium", + 4 : "4", + 5 : "5 - Low", }; /** @@ -23,9 +23,7 @@ const PRIORITY_MAP = { * the highest priority and 5 is the lowest priority. */ export class Priority { - static GET_DEFAULT_PRIORITY() { - return new Priority(3); - } + static GET_DEFAULT_PRIORITY() { return new Priority(3); } static GET_PRIORITIES() { return Object.keys(PRIORITY_MAP).map((value) => new Priority(value)); @@ -48,12 +46,12 @@ export class Priority { toString() { if (Object.prototype.hasOwnProperty.call(PRIORITY_MAP, this.value)) { switch (this.value) { - case 1: - return i18n.__("Item.Priorities.high"); - case 3: - return i18n.__("Item.Priorities.medium"); - case 5: - return i18n.__("Item.Priorities.low"); + case 1: + return i18n.__("Item.Priorities.high"); + case 3: + return i18n.__("Item.Priorities.medium"); + case 5: + return i18n.__("Item.Priorities.low"); } return PRIORITY_MAP[this.value]; } diff --git a/imports/server/exportimport/expImpFilesAttachments.js b/imports/server/exportimport/expImpFilesAttachments.js index f8b49737f..12546fc79 100644 --- a/imports/server/exportimport/expImpFilesAttachments.js +++ b/imports/server/exportimport/expImpFilesAttachments.js @@ -1,34 +1,32 @@ -import { EJSON } from "bson"; +import {EJSON} from "bson"; import fs from "fs"; class ExpImpFilesAttachments { - static get FILENAME_POSTFIX() { - return "_filesAttachments.json"; - } + static get FILENAME_POSTFIX() { return "_filesAttachments.json"; } static doExport(db, msID, userIDs) { return new Promise((resolve, reject) => { db.collection("AttachmentsCollection") - .find({ "meta.parentseries_id": msID }) - .toArray() - .then((doc) => { - if (doc) { - const attFile = msID + ExpImpFilesAttachments.FILENAME_POSTFIX; - fs.writeFileSync(attFile, EJSON.stringify(doc, null, 2)); - console.log( - `Saved: ${attFile} with ${doc.length} file attachments`, - ); - if (doc[0]) { + .find({"meta.parentseries_id" : msID}) + .toArray() + .then((doc) => { + if (doc) { + const attFile = msID + ExpImpFilesAttachments.FILENAME_POSTFIX; + fs.writeFileSync(attFile, EJSON.stringify(doc, null, 2)); console.log( - " *** Hint *** Please manually copy all files below:", + `Saved: ${attFile} with ${doc.length} file attachments`, ); - console.log(` ${doc[0]._storagePath}`); + if (doc[0]) { + console.log( + " *** Hint *** Please manually copy all files below:", + ); + console.log(` ${doc[0]._storagePath}`); + } + resolve({db, userIDs}); + return; } - resolve({ db, userIDs }); - return; - } - return reject(`Unknown meeting series ID: ${msID}`); - }); + return reject(`Unknown meeting series ID: ${msID}`); + }); }); } @@ -38,7 +36,7 @@ class ExpImpFilesAttachments { let AllAttachmentsDoc = undefined; try { AllAttachmentsDoc = EJSON.parse( - fs.readFileSync(attachmentFile, "utf8"), + fs.readFileSync(attachmentFile, "utf8"), ); if (!AllAttachmentsDoc) { return reject(`Could not read attachment file ${attachmentFile}`); @@ -52,37 +50,33 @@ class ExpImpFilesAttachments { for (let a = 0; a < AllAttachmentsDoc.length; a++) { attachmentIDs.push(AllAttachmentsDoc[a]._id); AllAttachmentsDoc[a] = ExpImpFilesAttachments.patchUsers( - AllAttachmentsDoc[a], - usrMap, + AllAttachmentsDoc[a], + usrMap, ); } - return db - .collection("AttachmentsCollection") - .deleteMany({ - _id: { $in: attachmentIDs }, - }) // delete existing attachments with same IDs - .then((res) => { - if (res.result && !res.result.ok) { - console.log(res); - } - return db - .collection("AttachmentsCollection") - .insertMany(AllAttachmentsDoc) // insert imported minutes - .then((res) => { - if ( - res.result.ok === 1 && - res.result.n === AllAttachmentsDoc.length - ) { - console.log( - `OK, inserted ${res.result.n} attachments meta data.`, - ); - resolve({ db, usrMap }); - } else { - reject("Could not insert attachment meta data"); - } - }); - }); + return db.collection("AttachmentsCollection") + .deleteMany({ + _id : {$in : attachmentIDs}, + }) // delete existing attachments with same IDs + .then((res) => { + if (res.result && !res.result.ok) { + console.log(res); + } + return db.collection("AttachmentsCollection") + .insertMany(AllAttachmentsDoc) // insert imported minutes + .then((res) => { + if (res.result.ok === 1 && + res.result.n === AllAttachmentsDoc.length) { + console.log( + `OK, inserted ${res.result.n} attachments meta data.`, + ); + resolve({db, usrMap}); + } else { + reject("Could not insert attachment meta data"); + } + }); + }); }); } diff --git a/imports/server/exportimport/expImpFilesDocuments.js b/imports/server/exportimport/expImpFilesDocuments.js index 75cd7f260..e1f791554 100644 --- a/imports/server/exportimport/expImpFilesDocuments.js +++ b/imports/server/exportimport/expImpFilesDocuments.js @@ -1,39 +1,38 @@ -import { EJSON } from "bson"; +import {EJSON} from "bson"; import fs from "fs"; class ExpImpFilesDocuments { - static get FILENAME_POSTFIX() { - return "_filesDocuments.json"; - } + static get FILENAME_POSTFIX() { return "_filesDocuments.json"; } static doExport(db, msID, userIDs) { return new Promise((resolve, reject) => { db.collection("DocumentsCollection") - .find({ "meta.meetingSeriesId": msID }) - .toArray() - .then((doc) => { - if (doc) { - const protFile = msID + ExpImpFilesDocuments.FILENAME_POSTFIX; - fs.writeFileSync(protFile, EJSON.stringify(doc, null, 2)); - console.log( - `Saved: ${protFile} with ${doc.length} protocol documents`, - ); - if (doc[0]) { - console.log( - " *** Hint *** Please manually copy all files below:", - ); + .find({"meta.meetingSeriesId" : msID}) + .toArray() + .then((doc) => { + if (doc) { + const protFile = msID + ExpImpFilesDocuments.FILENAME_POSTFIX; + fs.writeFileSync(protFile, EJSON.stringify(doc, null, 2)); console.log( - ` ${doc[0]._storagePath.substring( - 0, - doc[0]._storagePath.lastIndexOf("/"), - )}`, + `Saved: ${protFile} with ${doc.length} protocol documents`, ); + if (doc[0]) { + console.log( + " *** Hint *** Please manually copy all files below:", + ); + console.log( + ` ${ + doc[0]._storagePath.substring( + 0, + doc[0]._storagePath.lastIndexOf("/"), + )}`, + ); + } + resolve({db, userIDs}); + return; } - resolve({ db, userIDs }); - return; - } - return reject(`Unknown meeting series ID: ${msID}`); - }); + return reject(`Unknown meeting series ID: ${msID}`); + }); }); } @@ -55,37 +54,34 @@ class ExpImpFilesDocuments { for (let p = 0; p < AllProtocolsDoc.length; p++) { protcolsIDs.push(AllProtocolsDoc[p]._id); AllProtocolsDoc[p] = ExpImpFilesDocuments.patchUsers( - AllProtocolsDoc[p], - usrMap, + AllProtocolsDoc[p], + usrMap, ); } - return db - .collection("DocumentsCollection") - .deleteMany({ - _id: { $in: protcolsIDs }, - }) // delete existing attachments with same IDs - .then((res) => { - if (res.result && !res.result.ok) { - console.log(res); - } - return db - .collection("DocumentsCollection") - .insertMany(AllProtocolsDoc) // insert imported minutes - .then((res) => { - if ( - res.result.ok === 1 && - res.result.n === AllProtocolsDoc.length - ) { - console.log( - `OK, inserted ${res.result.n} protocol files meta data.`, - ); - resolve({ db, usrMap }); - } else { - reject("Could not insert protocol files meta data"); - } - }); - }); + return db.collection("DocumentsCollection") + .deleteMany({ + _id : {$in : protcolsIDs}, + }) // delete existing attachments with same IDs + .then((res) => { + if (res.result && !res.result.ok) { + console.log(res); + } + return db.collection("DocumentsCollection") + .insertMany(AllProtocolsDoc) // insert imported minutes + .then((res) => { + if (res.result.ok === 1 && + res.result.n === AllProtocolsDoc.length) { + console.log( + `OK, inserted ${ + res.result.n} protocol files meta data.`, + ); + resolve({db, usrMap}); + } else { + reject("Could not insert protocol files meta data"); + } + }); + }); }); } diff --git a/imports/server/exportimport/expImpMeetingseries.js b/imports/server/exportimport/expImpMeetingseries.js index cf94c46e4..c2f6fa9c9 100644 --- a/imports/server/exportimport/expImpMeetingseries.js +++ b/imports/server/exportimport/expImpMeetingseries.js @@ -1,76 +1,63 @@ -import { EJSON } from "bson"; +import {EJSON} from "bson"; import fs from "fs"; class ExpImpMeetingSeries { - static get FILENAME_POSTFIX() { - return "_meetingSeries.json"; - } + static get FILENAME_POSTFIX() { return "_meetingSeries.json"; } static doExport(db, msID) { return new Promise((resolve, reject) => { const userIDs = {}; - db.collection("meetingSeries") - .findOne({ _id: msID }) - .then((doc) => { - if (doc) { - const msFile = msID + ExpImpMeetingSeries.FILENAME_POSTFIX; - fs.writeFileSync(msFile, EJSON.stringify(doc, null, 2)); - console.log(`Saved: ${msFile}`); - doc.visibleFor?.map((userID) => { - userIDs[userID] = 1; - }); - doc.informedUsers?.map((userID) => { - userIDs[userID] = 1; - }); - resolve({ db, userIDs }); - return; - } - return reject(`Unknown meeting series ID: ${msID}`); - }); + db.collection("meetingSeries").findOne({_id : msID}).then((doc) => { + if (doc) { + const msFile = msID + ExpImpMeetingSeries.FILENAME_POSTFIX; + fs.writeFileSync(msFile, EJSON.stringify(doc, null, 2)); + console.log(`Saved: ${msFile}`); + doc.visibleFor?.map((userID) => { userIDs[userID] = 1; }); + doc.informedUsers?.map((userID) => { userIDs[userID] = 1; }); + resolve({db, userIDs}); + return; + } + return reject(`Unknown meeting series ID: ${msID}`); + }); }); } static doImport(db, msID, usrMap) { return new Promise((resolve, reject) => { - db.collection("meetingSeries") - .findOne({ _id: msID }) - .then((doc) => { - if (doc) { - return reject( + db.collection("meetingSeries").findOne({_id : msID}).then((doc) => { + if (doc) { + return reject( `Meeting series with ID: ${msID} already exists. Cannot import.`, - ); - } - const msFile = msID + ExpImpMeetingSeries.FILENAME_POSTFIX; - let msDoc = undefined; - try { - msDoc = EJSON.parse(fs.readFileSync(msFile, "utf8")); - if (!msDoc) { - return reject(`Could not read meeting series file ${msFile}`); - } - } catch (e) { + ); + } + const msFile = msID + ExpImpMeetingSeries.FILENAME_POSTFIX; + let msDoc = undefined; + try { + msDoc = EJSON.parse(fs.readFileSync(msFile, "utf8")); + if (!msDoc) { return reject(`Could not read meeting series file ${msFile}`); } + } catch (e) { + return reject(`Could not read meeting series file ${msFile}`); + } - // Replace old user IDs with new users IDs - for (let i = 0; i < msDoc.visibleFor.length; i++) { - msDoc.visibleFor[i] = usrMap[msDoc.visibleFor[i]]; - } - for (let i = 0; i < msDoc.informedUsers.length; i++) { - msDoc.informedUsers[i] = usrMap[msDoc.informedUsers[i]]; - } + // Replace old user IDs with new users IDs + for (let i = 0; i < msDoc.visibleFor.length; i++) { + msDoc.visibleFor[i] = usrMap[msDoc.visibleFor[i]]; + } + for (let i = 0; i < msDoc.informedUsers.length; i++) { + msDoc.informedUsers[i] = usrMap[msDoc.informedUsers[i]]; + } - return db - .collection("meetingSeries") - .insert(msDoc) - .then((res) => { - if (res.result.ok === 1) { - console.log(`OK, inserted meeting series with ID: ${msID}`); - resolve({ db, usrMap }); - } else { - reject(`Could not insert meeting series with ID: ${msID}`); - } - }); + return db.collection("meetingSeries").insert(msDoc).then((res) => { + if (res.result.ok === 1) { + console.log(`OK, inserted meeting series with ID: ${msID}`); + resolve({db, usrMap}); + } else { + reject(`Could not insert meeting series with ID: ${msID}`); + } }); + }); }); } } diff --git a/imports/server/exportimport/expImpMinutes.js b/imports/server/exportimport/expImpMinutes.js index 64372afca..5674e03f4 100644 --- a/imports/server/exportimport/expImpMinutes.js +++ b/imports/server/exportimport/expImpMinutes.js @@ -1,12 +1,10 @@ -import { EJSON } from "bson"; +import {EJSON} from "bson"; import fs from "fs"; import ExpImpTopics from "./expImpTopics"; class ExpImpMinutes { - static get FILENAME_POSTFIX() { - return "_minutes.json"; - } + static get FILENAME_POSTFIX() { return "_minutes.json"; } /** * Export minutes of a meeting series to a file and collect additional user * IDs. @@ -21,50 +19,49 @@ class ExpImpMinutes { static doExport(db, msID, userIDs) { return new Promise((resolve, reject) => { db.collection("minutes") - .find({ meetingSeries_id: msID }) - .toArray() - .then((allMinutesDoc) => { - if (allMinutesDoc) { - const minFile = msID + ExpImpMinutes.FILENAME_POSTFIX; - fs.writeFileSync(minFile, EJSON.stringify(allMinutesDoc, null, 2)); - console.log( - `Saved: ${minFile} with ${allMinutesDoc.length} minutes`, - ); + .find({meetingSeries_id : msID}) + .toArray() + .then((allMinutesDoc) => { + if (allMinutesDoc) { + const minFile = msID + ExpImpMinutes.FILENAME_POSTFIX; + fs.writeFileSync(minFile, + EJSON.stringify(allMinutesDoc, null, 2)); + console.log( + `Saved: ${minFile} with ${allMinutesDoc.length} minutes`, + ); - // Collect additional invited / informed users from older minutes - allMinutesDoc.map((min) => { - min.visibleFor?.map((userID) => { - // should be identical to meeting series - userIDs[userID] = 1; - }); - min.informedUsers?.map((userID) => { - // should be identical to meeting series - userIDs[userID] = 1; - }); - min.participants?.map((part) => { - // might differ from meeting series users! - userIDs[part.userId] = 1; - }); - min.topics?.map((top) => { - // iterate topics - top.responsibles?.map((resp) => { - // topic-responsibles - userIDs[resp] = 1; + // Collect additional invited / informed users from older minutes + allMinutesDoc.map((min) => { + min.visibleFor?.map((userID) => { + // should be identical to meeting series + userIDs[userID] = 1; }); - top.infoItems?.map((item) => { - // topic-actionitem-responsibles - item.responsibles?.map((resp) => { + min.informedUsers?.map((userID) => { + // should be identical to meeting series + userIDs[userID] = 1; + }); + min.participants?.map((part) => { + // might differ from meeting series users! + userIDs[part.userId] = 1; + }); + min.topics?.map((top) => { + // iterate topics + top.responsibles?.map((resp) => { + // topic-responsibles userIDs[resp] = 1; }); + top.infoItems?.map((item) => { + // topic-actionitem-responsibles + item.responsibles?.map((resp) => { userIDs[resp] = 1; }); + }); }); }); - }); - resolve({ db, userIDs }); - return; - } - return reject(new Error(`Unknown meeting series ID: ${msID}`)); - }); + resolve({db, userIDs}); + return; + } + return reject(new Error(`Unknown meeting series ID: ${msID}`)); + }); }); } // TODO big function. consider refactoring. @@ -79,33 +76,33 @@ class ExpImpMinutes { } } catch (e) { return reject( - new Error(`Could not read minutes file ${minFile}\n${e}`), + new Error(`Could not read minutes file ${minFile}\n${e}`), ); } // Replace old user IDs with new users IDs let minIDs; - ({ minIDs, minDoc } = ExpImpMinutes.patchUsers(minDoc, usrMap)); + ({minIDs, minDoc} = ExpImpMinutes.patchUsers(minDoc, usrMap)); - return db - .collection("minutes") - .deleteMany({ _id: { $in: minIDs } }) // delete existing minutes with same IDs - .then((res) => { - if (res.result && !res.result.ok) { - console.log(res); - } - return db - .collection("minutes") - .insertMany(minDoc) // insert imported minutes - .then((res) => { - if (res.result.ok === 1 && res.result.n === minDoc.length) { - console.log(`OK, inserted ${res.result.n} meeting minutes.`); - resolve({ db, usrMap }); - } else { - reject(new Error("Could not insert meeting minutes")); - } - }); - }); + return db.collection("minutes") + .deleteMany( + {_id : {$in : minIDs}}) // delete existing minutes with same IDs + .then((res) => { + if (res.result && !res.result.ok) { + console.log(res); + } + return db.collection("minutes") + .insertMany(minDoc) // insert imported minutes + .then((res) => { + if (res.result.ok === 1 && res.result.n === minDoc.length) { + console.log( + `OK, inserted ${res.result.n} meeting minutes.`); + resolve({db, usrMap}); + } else { + reject(new Error("Could not insert meeting minutes")); + } + }); + }); }); } // TODO big function. consider refactoring. @@ -114,25 +111,16 @@ class ExpImpMinutes { for (const element of minDoc) { // iterate all minutes minIDs.push(element._id); - for ( - let i = 0; - element.visibleFor && i < element.visibleFor.length; - i++ - ) { + for (let i = 0; element.visibleFor && i < element.visibleFor.length; + i++) { element.visibleFor[i] = usrMap[element.visibleFor[i]]; } - for ( - let i = 0; - element.informedUsers && i < element.informedUsers.length; - i++ - ) { + for (let i = 0; element.informedUsers && i < element.informedUsers.length; + i++) { element.informedUsers[i] = usrMap[element.informedUsers[i]]; } - for ( - let i = 0; - element.participants && i < element.participants.length; - i++ - ) { + for (let i = 0; element.participants && i < element.participants.length; + i++) { element.participants[i].userId = usrMap[element.participants[i].userId]; } @@ -142,7 +130,7 @@ class ExpImpMinutes { } } - return { minIDs, minDoc }; + return {minIDs, minDoc}; } } diff --git a/imports/server/exportimport/expImpSchema.js b/imports/server/exportimport/expImpSchema.js index d3a00ea9a..02e2d1bca 100644 --- a/imports/server/exportimport/expImpSchema.js +++ b/imports/server/exportimport/expImpSchema.js @@ -1,108 +1,103 @@ -import { EJSON } from "bson"; +import {EJSON} from "bson"; import fs from "fs"; class ExpImpSchema { - static get MADE_FOR_SCHEMA() { - return 21; - } + static get MADE_FOR_SCHEMA() { return 21; } - static get FILENAME_POSTFIX() { - return "_schema.json"; - } + static get FILENAME_POSTFIX() { return "_schema.json"; } static exportCheck(db, msID) { return new Promise((resolve, reject) => { - db.collection("migrations") - .findOne() - .then((doc) => { - if (doc) { - console.log(`DB Schema Version: ${doc.version}`); - if (ExpImpSchema.MADE_FOR_SCHEMA !== doc.version) { - console.log("*** WARNING *** Schema mismatch!"); - console.log( - ` This exporter is made for database schema version: ${ExpImpSchema.MADE_FOR_SCHEMA}`, - ); - console.log( - ` But your database has schema version : ${doc.version}`, - ); - console.log( + db.collection("migrations").findOne().then((doc) => { + if (doc) { + console.log(`DB Schema Version: ${doc.version}`); + if (ExpImpSchema.MADE_FOR_SCHEMA !== doc.version) { + console.log("*** WARNING *** Schema mismatch!"); + console.log( + ` This exporter is made for database schema version: ${ + ExpImpSchema.MADE_FOR_SCHEMA}`, + ); + console.log( + ` But your database has schema version : ${ + doc.version}`, + ); + console.log( " Alyways migrate to the most recent DB schema before export!", - ); - console.log(" Alyways use matching exporter!"); - console.log( + ); + console.log(" Alyways use matching exporter!"); + console.log( " Exported data may be corrupt. Continue at your own risk.", - ); - } - const schemaFile = msID + ExpImpSchema.FILENAME_POSTFIX; - fs.writeFileSync(schemaFile, EJSON.stringify(doc, null, 2)); - console.log(`Saved: ${schemaFile}`); - resolve(db); - return; + ); } - return reject( + const schemaFile = msID + ExpImpSchema.FILENAME_POSTFIX; + fs.writeFileSync(schemaFile, EJSON.stringify(doc, null, 2)); + console.log(`Saved: ${schemaFile}`); + resolve(db); + return; + } + return reject( "No migrations schema version found in your DB! Unable to export.", - ); - }); + ); + }); }); } static preImportCheck(db, msID, force = false) { return new Promise((resolve, reject) => { - db.collection("migrations") - .findOne() - .then((doc) => { - if (doc) { - console.log(`DB Schema Version: ${doc.version}`); + db.collection("migrations").findOne().then((doc) => { + if (doc) { + console.log(`DB Schema Version: ${doc.version}`); - const schemaFile = msID + ExpImpSchema.FILENAME_POSTFIX; - let exportedSchema = undefined; - try { - exportedSchema = EJSON.parse(fs.readFileSync(schemaFile, "utf8")); - if (!exportedSchema) { - return reject(`Could not read schema file ${schemaFile}`); - } - } catch (e) { + const schemaFile = msID + ExpImpSchema.FILENAME_POSTFIX; + let exportedSchema = undefined; + try { + exportedSchema = EJSON.parse(fs.readFileSync(schemaFile, "utf8")); + if (!exportedSchema) { return reject(`Could not read schema file ${schemaFile}`); } + } catch (e) { + return reject(`Could not read schema file ${schemaFile}`); + } - if ( - ExpImpSchema.MADE_FOR_SCHEMA !== doc.version || + if (ExpImpSchema.MADE_FOR_SCHEMA !== doc.version || ExpImpSchema.MADE_FOR_SCHEMA !== exportedSchema.version || - doc.version !== exportedSchema.version - ) { - console.log("*** WARNING *** Schema mismatch!"); - console.log( - ` This importer is made for database schema version: ${ExpImpSchema.MADE_FOR_SCHEMA}`, - ); - console.log( - ` Your database has schema version : ${doc.version}`, - ); + doc.version !== exportedSchema.version) { + console.log("*** WARNING *** Schema mismatch!"); + console.log( + ` This importer is made for database schema version: ${ + ExpImpSchema.MADE_FOR_SCHEMA}`, + ); + console.log( + ` Your database has schema version : ${ + doc.version}`, + ); + console.log( + ` Your exported data has schema version : ${ + exportedSchema.version}`, + ); + console.log( + " Alyways migrate to the most recent DB schema before export/import!", + ); + console.log(" Alyways use matching exporter!"); + if (force) { console.log( - ` Your exported data has schema version : ${exportedSchema.version}`, + " --force switch detected. Continueing...", ); + } else { + console.log(" Import will stop."); console.log( - " Alyways migrate to the most recent DB schema before export/import!", - ); - console.log(" Alyways use matching exporter!"); - if (force) { - console.log( - " --force switch detected. Continueing...", - ); - } else { - console.log(" Import will stop."); - console.log( " Use --force switch to enforce import at your own risk.", - ); - return reject("Schema mismatch"); - } + ); + return reject("Schema mismatch"); } - resolve(db); - return; } - return reject( + resolve(db); + return; + } + return reject( "No migrations schema version found in your DB! Unable to import.", - ); - }); + ); + }); }); } } diff --git a/imports/server/exportimport/expImpTopics.js b/imports/server/exportimport/expImpTopics.js index 4c8f38e2d..b5ea5b534 100644 --- a/imports/server/exportimport/expImpTopics.js +++ b/imports/server/exportimport/expImpTopics.js @@ -1,26 +1,21 @@ -import { EJSON } from "bson"; +import {EJSON} from "bson"; import fs from "fs"; class ExpImpTopics { - static get FILENAME_POSTFIX() { - return "_topics.json"; - } + static get FILENAME_POSTFIX() { return "_topics.json"; } static doExport(db, msID, userIDs) { return new Promise((resolve, reject) => { - db.collection("topics") - .find({ parentId: msID }) - .toArray() - .then((doc) => { - if (doc) { - const topFile = msID + ExpImpTopics.FILENAME_POSTFIX; - fs.writeFileSync(topFile, EJSON.stringify(doc, null, 2)); - console.log(`Saved: ${topFile} with ${doc.length} topics`); - resolve({ db, userIDs }); - return; - } - return reject(`Unknown meeting series ID: ${msID}`); - }); + db.collection("topics").find({parentId : msID}).toArray().then((doc) => { + if (doc) { + const topFile = msID + ExpImpTopics.FILENAME_POSTFIX; + fs.writeFileSync(topFile, EJSON.stringify(doc, null, 2)); + console.log(`Saved: ${topFile} with ${doc.length} topics`); + resolve({db, userIDs}); + return; + } + return reject(`Unknown meeting series ID: ${msID}`); + }); }); } @@ -44,35 +39,32 @@ class ExpImpTopics { AllTopicsDoc[t] = ExpImpTopics.patchUsers(AllTopicsDoc[t], usrMap); } - return db - .collection("topics") - .deleteMany({ _id: { $in: topicIDs } }) // delete existing topics with same IDs - .then((res) => { - if (res.result && !res.result.ok) { - console.log(res); - } - return db - .collection("topics") - .insertMany(AllTopicsDoc) // insert imported minutes - .then((res) => { - if (res.result.ok === 1 && res.result.n === AllTopicsDoc.length) { - console.log(`OK, inserted ${res.result.n} topics.`); - resolve({ db, usrMap }); - } else { - reject("Could not insert topics"); - } - }); - }); + return db.collection("topics") + .deleteMany( + {_id : {$in : topicIDs}}) // delete existing topics with same IDs + .then((res) => { + if (res.result && !res.result.ok) { + console.log(res); + } + return db.collection("topics") + .insertMany(AllTopicsDoc) // insert imported minutes + .then((res) => { + if (res.result.ok === 1 && + res.result.n === AllTopicsDoc.length) { + console.log(`OK, inserted ${res.result.n} topics.`); + resolve({db, usrMap}); + } else { + reject("Could not insert topics"); + } + }); + }); }); } static patchUsers(topicDoc, usrMap) { // patch topic-responsibles - for ( - let i = 0; - topicDoc.responsibles && i < topicDoc.responsibles.length; - i++ - ) { + for (let i = 0; topicDoc.responsibles && i < topicDoc.responsibles.length; + i++) { if (usrMap[topicDoc.responsibles[i]]) { // may be "free text" user topicDoc.responsibles[i] = usrMap[topicDoc.responsibles[i]]; @@ -80,16 +72,13 @@ class ExpImpTopics { } // patch topic-actionitem-responsibles for (let i = 0; topicDoc.infoItems && i < topicDoc.infoItems.length; i++) { - for ( - let j = 0; - topicDoc.infoItems[i].responsibles && - j < topicDoc.infoItems[i].responsibles.length; - j++ - ) { + for (let j = 0; topicDoc.infoItems[i].responsibles && + j < topicDoc.infoItems[i].responsibles.length; + j++) { if (usrMap[topicDoc.infoItems[i].responsibles[j]]) { // may be "free text" user topicDoc.infoItems[i].responsibles[j] = - usrMap[topicDoc.infoItems[i].responsibles[j]]; + usrMap[topicDoc.infoItems[i].responsibles[j]]; } } } diff --git a/imports/server/exportimport/expImpUsers.js b/imports/server/exportimport/expImpUsers.js index b13636099..8d6cbf033 100644 --- a/imports/server/exportimport/expImpUsers.js +++ b/imports/server/exportimport/expImpUsers.js @@ -1,13 +1,9 @@ -import { EJSON } from "bson"; +import {EJSON} from "bson"; import fs from "fs"; class ExpImpUsers { - static get FILENAME_POSTFIX() { - return "_users.json"; - } - static get MAPNAME_POSTFIX() { - return "_userMap.json"; - } + static get FILENAME_POSTFIX() { return "_users.json"; } + static get MAPNAME_POSTFIX() { return "_userMap.json"; } static searchUser(allUserDoc, searchID) { for (let i = 0; i < allUserDoc.length; i++) { @@ -24,48 +20,47 @@ class ExpImpUsers { const userIDsOuputMap = {}; db.collection("users") - .find({ _id: { $in: userIDsFlat } }) - .toArray() - .then((allUsersDoc) => { - if (allUsersDoc) { - // userIDsFlat may contain "free text" users that are not in DB - // We create a dict to look up which collected userIDs are really - // from DB - const userIDsFromDB = {}; - allUsersDoc.map((usr) => { - userIDsFromDB[usr._id] = 1; - }); - const usrFile = msID + ExpImpUsers.FILENAME_POSTFIX; - fs.writeFileSync(usrFile, EJSON.stringify(allUsersDoc, null, 2)); - console.log(`Saved: ${usrFile} with ${allUsersDoc.length} users`); + .find({_id : {$in : userIDsFlat}}) + .toArray() + .then((allUsersDoc) => { + if (allUsersDoc) { + // userIDsFlat may contain "free text" users that are not in DB + // We create a dict to look up which collected userIDs are really + // from DB + const userIDsFromDB = {}; + allUsersDoc.map((usr) => { userIDsFromDB[usr._id] = 1; }); + const usrFile = msID + ExpImpUsers.FILENAME_POSTFIX; + fs.writeFileSync(usrFile, EJSON.stringify(allUsersDoc, null, 2)); + console.log(`Saved: ${usrFile} with ${allUsersDoc.length} users`); - // Save mapping file old => new user ID - // But only with REAL DB users (skip free text users) - userIDsFlat.map((usrID) => { - if (userIDsFromDB[usrID]) { - // default: newID === oldID - // This means, users are copied(!) from source DB to - // destination DB If newID is changed to an existing id from - // destination ID, this target user is used - const thisUser = ExpImpUsers.searchUser(allUsersDoc, usrID); - userIDsOuputMap[usrID] = { - newID: usrID, - hint: `${thisUser.username} ${thisUser.profile.name}`, - }; - } - }); - const mapFile = msID + ExpImpUsers.MAPNAME_POSTFIX; - fs.writeFileSync(mapFile, JSON.stringify(userIDsOuputMap, null, 2)); - console.log(`Saved: ${mapFile}`); - console.log( - " *** IMPORTANT!!! EDIT USER MAP FILE BEFORE IMPORT!!!", - ); + // Save mapping file old => new user ID + // But only with REAL DB users (skip free text users) + userIDsFlat.map((usrID) => { + if (userIDsFromDB[usrID]) { + // default: newID === oldID + // This means, users are copied(!) from source DB to + // destination DB If newID is changed to an existing id from + // destination ID, this target user is used + const thisUser = ExpImpUsers.searchUser(allUsersDoc, usrID); + userIDsOuputMap[usrID] = { + newID : usrID, + hint : `${thisUser.username} ${thisUser.profile.name}`, + }; + } + }); + const mapFile = msID + ExpImpUsers.MAPNAME_POSTFIX; + fs.writeFileSync(mapFile, + JSON.stringify(userIDsOuputMap, null, 2)); + console.log(`Saved: ${mapFile}`); + console.log( + " *** IMPORTANT!!! EDIT USER MAP FILE BEFORE IMPORT!!!", + ); - resolve(db); - return; - } - return reject("Could not find users: ", userIDsFlat); - }); + resolve(db); + return; + } + return reject("Could not find users: ", userIDsFlat); + }); }); } @@ -82,9 +77,8 @@ class ExpImpUsers { return reject(`Could not read user map file ${mapFile}\n${e}`); } const usrMapSimple = {}; // make flat map: oldID => newID - usrMap = Object.keys(usrMap).map((key) => { - usrMapSimple[key] = usrMap[key].newID; - }); + usrMap = Object.keys(usrMap).map( + (key) => { usrMapSimple[key] = usrMap[key].newID; }); usrMap = usrMapSimple; const usrMapCount = Object.keys(usrMap).length; @@ -102,42 +96,46 @@ class ExpImpUsers { // Check#1: All "link targets" should exist db.collection("users") - .find({ _id: { $in: usrMapTargetIDs } }) - .toArray() - .then((doc) => { - if (doc) { - console.log(`Found ${doc.length} target users in current user DB.`); - console.log( - `Will copy over ${usrCopyIDs.length} export users to current user DB.`, - ); - if (doc.length !== usrMapTargetIDs.length) { - return reject( - `Not all to-be patched target users found in current user DB: ${usrMapTargetIDs}`, + .find({_id : {$in : usrMapTargetIDs}}) + .toArray() + .then((doc) => { + if (doc) { + console.log( + `Found ${doc.length} target users in current user DB.`); + console.log( + `Will copy over ${ + usrCopyIDs.length} export users to current user DB.`, ); - } - // Check#2: All copy-users MUST NOT exist! - db.collection("users") - .find({ _id: { $in: usrCopyIDs } }) - .toArray() - .then((shouldBeEmpty) => { - if (shouldBeEmpty && shouldBeEmpty.length > 0) { - const errorUsers = shouldBeEmpty.map((usr) => { - return { _id: usr._id, username: usr.username }; + if (doc.length !== usrMapTargetIDs.length) { + return reject( + `Not all to-be patched target users found in current user DB: ${ + usrMapTargetIDs}`, + ); + } + // Check#2: All copy-users MUST NOT exist! + db.collection("users") + .find({_id : {$in : usrCopyIDs}}) + .toArray() + .then((shouldBeEmpty) => { + if (shouldBeEmpty && shouldBeEmpty.length > 0) { + const errorUsers = shouldBeEmpty.map((usr) => { + return {_id : usr._id, username : usr.username}; + }); + return reject( + `${ + shouldBeEmpty + .length} to-be copied user(s) already exists:\n${ + JSON.stringify( + errorUsers, + )}`, + ); + } + resolve({db, usrMap}); }); - return reject( - `${ - shouldBeEmpty.length - } to-be copied user(s) already exists:\n${JSON.stringify( - errorUsers, - )}`, - ); - } - resolve({ db, usrMap }); - }); - return; - } - return reject("Could not find users: ", usrMapTargetIDs); - }); + return; + } + return reject("Could not find users: ", usrMapTargetIDs); + }); }); } @@ -160,47 +158,45 @@ class ExpImpUsers { for (let u = 0; u < allUsersDoc.length; u++) { if (allUsersDoc[u]._id === usrMap[allUsersDoc[u]._id]) { // before/after ID are same in mapping file! - const roleValueForMS = allUsersDoc[u].roles[msID]; // Case#1: clone this user from source + const roleValueForMS = + allUsersDoc[u].roles[msID]; // Case#1: clone this user from source // DB => target DB! allUsersDoc[u].roles = { - msID: roleValueForMS, + msID : roleValueForMS, }; // Kill all other roles, just keep the one for this MS promiseChain.push(db.collection("users").insert(allUsersDoc[u])); } else { promiseChain.push( - // Case#2: only update user role for existing user in target DB - db - .collection("users") - .findOne({ - _id: usrMap[allUsersDoc[u]._id], - }) // find the user in target DB - .then((usr) => { - const roleValueForMS = allUsersDoc[u].roles[msID]; - if (!(roleValueForMS && roleValueForMS.length > 0)) { - return; - } - // user needs role for import meeting series? - const roles = usr.roles ? usr.roles : {}; - roles[msID] = roleValueForMS; - return db - .collection("users") // upsert role field - .update({ _id: usr._id }, { $set: { roles } }); - }), + // Case#2: only update user role for existing user in target DB + db.collection("users") + .findOne({ + _id : usrMap[allUsersDoc[u]._id], + }) // find the user in target DB + .then((usr) => { + const roleValueForMS = allUsersDoc[u].roles[msID]; + if (!(roleValueForMS && roleValueForMS.length > 0)) { + return; + } + // user needs role for import meeting series? + const roles = usr.roles ? usr.roles : {}; + roles[msID] = roleValueForMS; + return db + .collection("users") // upsert role field + .update({_id : usr._id}, {$set : {roles}}); + }), ); } } // Now execute the chain. Promise.all(promiseChain) - .then((res) => { - if (res?.[0] && res[0].result && !res[0].result.ok) { - console.log("Promisechain result: ", res); - } - resolve(db); - }) - .catch((err) => { - reject(err); - }); + .then((res) => { + if (res?.[0] && res[0].result && !res[0].result.ok) { + console.log("Promisechain result: ", res); + } + resolve(db); + }) + .catch((err) => { reject(err); }); }); } } diff --git a/private/createTestUsers.js b/private/createTestUsers.js index 106ae02e0..94b558224 100644 --- a/private/createTestUsers.js +++ b/private/createTestUsers.js @@ -7,8 +7,8 @@ * users: node createTestUsers.js -m mongodb://localhost:3101/meteor -n 5000 */ -import { faker } from "@faker-js/faker"; -import { MongoClient as mongo } from "mongodb"; +import {faker} from "@faker-js/faker"; +import {MongoClient as mongo} from "mongodb"; import random from "randomstring"; class UserFactory { @@ -16,22 +16,22 @@ class UserFactory { UserFactory.counter++; const username = `user_${UserFactory.postfix}_${UserFactory.counter}`; return { - _id: random.generate({ - length: 17, - charset: "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", + _id : random.generate({ + length : 17, + charset : "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", }), username, - createdAt: new Date(), - isInactive: false, - services: { - password: { + createdAt : new Date(), + isInactive : false, + services : { + password : { // PwdPwd1 - bcrypt: - "$2a$10$mtPbwEoJmaAO01fxI/WnZepoUz4D.U6f/yYl6KG1oojxNI7JZmn.S", + bcrypt : + "$2a$10$mtPbwEoJmaAO01fxI/WnZepoUz4D.U6f/yYl6KG1oojxNI7JZmn.S", }, }, - profile: { name: faker.person.fullName() }, - emails: [{ address: `${username}@4minitz.com`, verified: false }], + profile : {name : faker.person.fullName()}, + emails : [ {address : `${username}@4minitz.com`, verified : false} ], }; } @@ -48,11 +48,11 @@ class UserFactory { } UserFactory.counter = 0; UserFactory.postfix = random.generate({ - length: 3, - charset: "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", + length : 3, + charset : "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", }); -const _connectMongo = function (mongoUrl) { +const _connectMongo = function(mongoUrl) { return new Promise((resolve, reject) => { mongo.connect(mongoUrl, (error, db) => { if (error) { @@ -64,9 +64,9 @@ const _connectMongo = function (mongoUrl) { }; const optionParser = require("node-getopt").create([ - ["n", "number=[ARG]", "Number of users to be created"], - ["m", "mongourl=[ARG]", "Mongo DB url"], - ["h", "help", "Display this help"], + [ "n", "number=[ARG]", "Number of users to be created" ], + [ "m", "mongourl=[ARG]", "Mongo DB url" ], + [ "h", "help", "Display this help" ], ]); const arg = optionParser.bindHelp().parseSystem(); const mongoUrl = arg.options.mongourl || process.env.MONGO_URL; @@ -82,8 +82,6 @@ if (!mongoUrl) { } _connectMongo(mongoUrl) - .then((db) => UserFactory.saveUsers(db, numberOfUsers)) - .then((db) => db.close()) - .catch((error) => { - console.log(`Error: ${error}`); - }); + .then((db) => UserFactory.saveUsers(db, numberOfUsers)) + .then((db) => db.close()) + .catch((error) => { console.log(`Error: ${error}`); }); diff --git a/private/exportMeetingSeries.js b/private/exportMeetingSeries.js index 939f23ed1..8aa7657dc 100644 --- a/private/exportMeetingSeries.js +++ b/private/exportMeetingSeries.js @@ -4,20 +4,25 @@ mongodb://localhost:3101/meteor --id icwrCdJjqWpoH9ugQ */ -import { MongoClient as mongo } from "mongodb"; +import {MongoClient as mongo} from "mongodb"; -import ExpImpFileAttachments from "../imports/server/exportimport/expImpFilesAttachments"; -import ExpImpFileDocuments from "../imports/server/exportimport/expImpFilesDocuments"; -import ExpImpMeetingSeries from "../imports/server/exportimport/expImpMeetingseries"; +import ExpImpFileAttachments from + "../imports/server/exportimport/expImpFilesAttachments"; +import ExpImpFileDocuments from + "../imports/server/exportimport/expImpFilesDocuments"; +import ExpImpMeetingSeries from + "../imports/server/exportimport/expImpMeetingseries"; import ExpImpMinutes from "../imports/server/exportimport/expImpMinutes"; import ExpImpSchema from "../imports/server/exportimport/expImpSchema"; import ExpImpTopics from "../imports/server/exportimport/expImpTopics"; import ExpImpUsers from "../imports/server/exportimport/expImpUsers"; const optionParser = require("node-getopt").create([ - ["i", "id=[ARG]", "ID of meeting series, e.g. icwrCdJjqWpoH9ugQ"], - ["m", "mongourl=[ARG]", "Mongo DB url, e.g. mongodb://localhost:3101/meteor"], - ["h", "help", "Display this help"], + [ "i", "id=[ARG]", "ID of meeting series, e.g. icwrCdJjqWpoH9ugQ" ], + [ + "m", "mongourl=[ARG]", "Mongo DB url, e.g. mongodb://localhost:3101/meteor" + ], + [ "h", "help", "Display this help" ], ]); const arg = optionParser.bindHelp().parseSystem(); const mongoUrl = arg.options.mongourl || process.env.MONGO_URL; @@ -30,7 +35,7 @@ if (!mongoUrl) { optionParser.showHelp(); throw new Error("No --mongourl parameter or MONGO_URL in env"); } -const _connectMongo = function (mongoUrl) { +const _connectMongo = function(mongoUrl) { return new Promise((resolve, reject) => { mongo.connect(mongoUrl, (error, db) => { if (error) { @@ -43,32 +48,29 @@ const _connectMongo = function (mongoUrl) { console.log(""); console.log( - `*** 4Minitz MeetingSeries Export Tool *** (made for schema version: ${ExpImpSchema.MADE_FOR_SCHEMA})`, + `*** 4Minitz MeetingSeries Export Tool *** (made for schema version: ${ + ExpImpSchema.MADE_FOR_SCHEMA})`, ); _connectMongo(mongoUrl) - .then((db) => { - return ExpImpSchema.exportCheck(db, meetingseriesID); - }) - .then((db) => { - return ExpImpMeetingSeries.doExport(db, meetingseriesID); - }) - .then(({ db, userIDs }) => { - return ExpImpMinutes.doExport(db, meetingseriesID, userIDs); - }) - .then(({ db, userIDs }) => { - return ExpImpTopics.doExport(db, meetingseriesID, userIDs); - }) - .then(({ db, userIDs }) => { - return ExpImpFileAttachments.doExport(db, meetingseriesID, userIDs); - }) - .then(({ db, userIDs }) => { - return ExpImpFileDocuments.doExport(db, meetingseriesID, userIDs); - }) - .then(({ db, userIDs }) => { - return ExpImpUsers.doExport(db, meetingseriesID, userIDs); - }) - .then((db) => db.close()) - .catch((error) => { - console.log(`Error: ${error}`); - console.log("Press Ctrl+C to stop."); - }); + .then((db) => { return ExpImpSchema.exportCheck(db, meetingseriesID); }) + .then((db) => { return ExpImpMeetingSeries.doExport(db, meetingseriesID); }) + .then(({db, userIDs}) => { + return ExpImpMinutes.doExport(db, meetingseriesID, userIDs); + }) + .then(({db, userIDs}) => { + return ExpImpTopics.doExport(db, meetingseriesID, userIDs); + }) + .then(({db, userIDs}) => { + return ExpImpFileAttachments.doExport(db, meetingseriesID, userIDs); + }) + .then(({db, userIDs}) => { + return ExpImpFileDocuments.doExport(db, meetingseriesID, userIDs); + }) + .then(({db, userIDs}) => { + return ExpImpUsers.doExport(db, meetingseriesID, userIDs); + }) + .then((db) => db.close()) + .catch((error) => { + console.log(`Error: ${error}`); + console.log("Press Ctrl+C to stop."); + }); diff --git a/private/importMeetingSeries.js b/private/importMeetingSeries.js index faaf90d86..57ca41bad 100644 --- a/private/importMeetingSeries.js +++ b/private/importMeetingSeries.js @@ -4,21 +4,26 @@ mongodb://localhost:3101/meteor --id icwrCdJjqWpoH9ugQ */ -import { MongoClient as mongo } from "mongodb"; +import {MongoClient as mongo} from "mongodb"; -import ExpImpFileAttachments from "../imports/server/exportimport/expImpFilesAttachments"; -import ExpImpFileDocuments from "../imports/server/exportimport/expImpFilesDocuments"; -import ExpImpMeetingSeries from "../imports/server/exportimport/expImpMeetingseries"; +import ExpImpFileAttachments from + "../imports/server/exportimport/expImpFilesAttachments"; +import ExpImpFileDocuments from + "../imports/server/exportimport/expImpFilesDocuments"; +import ExpImpMeetingSeries from + "../imports/server/exportimport/expImpMeetingseries"; import ExpImpMinutes from "../imports/server/exportimport/expImpMinutes"; import ExpImpSchema from "../imports/server/exportimport/expImpSchema"; import ExpImpTopics from "../imports/server/exportimport/expImpTopics"; import ExpImpUsers from "../imports/server/exportimport/expImpUsers"; const optionParser = require("node-getopt").create([ - ["i", "id=[ARG]", "ID of meeting series, e.g. icwrCdJjqWpoH9ugQ"], - ["m", "mongourl=[ARG]", "Mongo DB url, e.g. mongodb://localhost:3101/meteor"], - ["f", "force", "Force import even if schema mismatch"], - ["h", "help", "Display this help"], + [ "i", "id=[ARG]", "ID of meeting series, e.g. icwrCdJjqWpoH9ugQ" ], + [ + "m", "mongourl=[ARG]", "Mongo DB url, e.g. mongodb://localhost:3101/meteor" + ], + [ "f", "force", "Force import even if schema mismatch" ], + [ "h", "help", "Display this help" ], ]); const arg = optionParser.bindHelp().parseSystem(); const mongoUrl = arg.options.mongourl || process.env.MONGO_URL; @@ -33,30 +38,30 @@ if (!mongoUrl) { throw new Error("No --mongourl parameter or MONGO_URL in env"); throw new Error("No --mongourl parameter or MONGO_URL in env"); } -const _connectMongo = (mongoUrl) => - new Promise((resolve, reject) => { - mongo.connect(mongoUrl, (error, db) => { - if (error) { - reject(error); - } - closeDB = db; - resolve(db); - }); +const _connectMongo = (mongoUrl) => new Promise((resolve, reject) => { + mongo.connect(mongoUrl, (error, db) => { + if (error) { + reject(error); + } + closeDB = db; + resolve(db); }); +}); console.log(""); console.log( - `*** 4Minitz MeetingSeries Import Tool *** (made for schema version: ${ExpImpSchema.MADE_FOR_SCHEMA})`, + `*** 4Minitz MeetingSeries Import Tool *** (made for schema version: ${ + ExpImpSchema.MADE_FOR_SCHEMA})`, ); console.log("*** ATTENTION ***"); console.log( - "- This script will import a meeting series and all dependecies to your DB.", + "- This script will import a meeting series and all dependecies to your DB.", ); console.log( - "- This script has to change existing user roles, so users can access the new data.", + "- This script has to change existing user roles, so users can access the new data.", ); console.log( - "- This script may overwrite edited data if you import the same data multiple times.", + "- This script may overwrite edited data if you import the same data multiple times.", ); console.log("So, this script is DANGEROUS!!!"); console.log("Experts only!"); @@ -67,38 +72,37 @@ console.log(" e.g.: mongodump -h 127.0.0.1 --port 3101 -d meteor"); console.log(""); console.log("Press ENTER to continue - or Ctrl+C to quit..."); require("child_process").spawnSync("read _ ", { - shell: true, - stdio: [0, 1, 2], + shell : true, + stdio : [ 0, 1, 2 ], }); var closeDB = undefined; _connectMongo(mongoUrl) - .then((db) => { - return ExpImpSchema.preImportCheck(db, meetingseriesID, arg.options.force); - }) - .then((db) => { - return ExpImpUsers.preImportCheck(db, meetingseriesID); - }) - .then(({ db, usrMap }) => { - return ExpImpMeetingSeries.doImport(db, meetingseriesID, usrMap); - }) - .then(({ db, usrMap }) => { - return ExpImpMinutes.doImport(db, meetingseriesID, usrMap); - }) - .then(({ db, usrMap }) => { - return ExpImpTopics.doImport(db, meetingseriesID, usrMap); - }) - .then(({ db, usrMap }) => { - return ExpImpFileAttachments.doImport(db, meetingseriesID, usrMap); - }) - .then(({ db, usrMap }) => { - return ExpImpFileDocuments.doImport(db, meetingseriesID, usrMap); - }) - .then(({ db, usrMap }) => { - return ExpImpUsers.doImport(db, meetingseriesID, usrMap); - }) - .then((db) => closeDB.close()) - .catch((error) => { - console.log(`Error: ${error}`); - console.log("Press Ctrl+C to stop."); - }); + .then((db) => { + return ExpImpSchema.preImportCheck(db, meetingseriesID, + arg.options.force); + }) + .then((db) => { return ExpImpUsers.preImportCheck(db, meetingseriesID); }) + .then(({db, usrMap}) => { + return ExpImpMeetingSeries.doImport(db, meetingseriesID, usrMap); + }) + .then(({db, usrMap}) => { + return ExpImpMinutes.doImport(db, meetingseriesID, usrMap); + }) + .then(({db, usrMap}) => { + return ExpImpTopics.doImport(db, meetingseriesID, usrMap); + }) + .then(({db, usrMap}) => { + return ExpImpFileAttachments.doImport(db, meetingseriesID, usrMap); + }) + .then(({db, usrMap}) => { + return ExpImpFileDocuments.doImport(db, meetingseriesID, usrMap); + }) + .then(({db, usrMap}) => { + return ExpImpUsers.doImport(db, meetingseriesID, usrMap); + }) + .then((db) => closeDB.close()) + .catch((error) => { + console.log(`Error: ${error}`); + console.log("Press Ctrl+C to stop."); + }); diff --git a/programs/generateLicenseList.js b/programs/generateLicenseList.js index 832790eb6..0d6658c70 100644 --- a/programs/generateLicenseList.js +++ b/programs/generateLicenseList.js @@ -4,104 +4,105 @@ import https from "https"; import crawler from "npm-license-crawler"; const meteorPackages = { - meteor: { - licenses: "MIT", - licenseUrl: "https://raw.githubusercontent.com/meteor/meteor/devel/LICENSE", - }, - "alanning:roles": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/alanning/meteor-roles/master/LICENSE", - }, - "babrahams:accounts-ldap": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/JackAdams/meteor-accounts-ldap/master/LICENSE", - }, - "felixble:server-templates": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/felixble/meteor-server-templates/master/LICENSE.md", - }, - "fourseven:scss": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/fourseven/meteor-scss/master/LICENSE.txt", - }, - "jagi:astronomy": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/jagi/meteor-astronomy/v2/LICENSE", - }, - "kadira:blaze-layout": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/kadirahq/blaze-layout/master/LICENSE", - }, - "ostrio:flow-router-extra": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/VeliovGroup/flow-router/master/LICENSE", - }, - "meteorhacks:subs-manager": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/kadirahq/subs-manager/master/LICENSE", - }, - "mouse0270:bootstrap-notify": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/mouse0270/bootstrap-notify/master/LICENSE", + meteor : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/meteor/meteor/devel/LICENSE", + }, + "alanning:roles" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/alanning/meteor-roles/master/LICENSE", + }, + "babrahams:accounts-ldap" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/JackAdams/meteor-accounts-ldap/master/LICENSE", + }, + "felixble:server-templates" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/felixble/meteor-server-templates/master/LICENSE.md", + }, + "fourseven:scss" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/fourseven/meteor-scss/master/LICENSE.txt", + }, + "jagi:astronomy" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/jagi/meteor-astronomy/v2/LICENSE", + }, + "kadira:blaze-layout" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/kadirahq/blaze-layout/master/LICENSE", + }, + "ostrio:flow-router-extra" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/VeliovGroup/flow-router/master/LICENSE", + }, + "meteorhacks:subs-manager" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/kadirahq/subs-manager/master/LICENSE", + }, + "mouse0270:bootstrap-notify" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/mouse0270/bootstrap-notify/master/LICENSE", }, // "msavin:mongol": {licenses: "MIT", licenseUrl: // "https://raw.githubusercontent.com/MeteorToys/allthings/master/LICENSE.md"}, - "natestrauser:select2": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/nate-strauser/meteor-select2/master/LICENSE.txt", - }, - "ostrio:files": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/VeliovGroup/Meteor-Files/master/LICENSE", - }, - "perak:markdown": { - licenses: "MIT", - licenseUrl: "https://raw.githubusercontent.com/chjj/marked/master/LICENSE", - }, - "percolate:migrations": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/percolatestudio/meteor-migrations/master/LICENSE", - }, - "practicalmeteor:mocha": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/practicalmeteor/meteor-mocha/meteor/LICENSE", - }, - "rcy:pick-a-color": { - licenses: "MIT", - licenseUrl: "https://github.com/lauren/pick-a-color/raw/master/LICENSE", - }, - "sergeyt:typeahead": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/sergeyt/meteor-typeahead/master/LICENSE", - }, - "useraccounts:bootstrap": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/meteor-useraccounts/bootstrap/master/LICENSE", - }, - "universe:i18n": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/vazco/meteor-universe-i18n/master/LICENSE", - }, - "universe:i18n-blaze": { - licenses: "MIT", - licenseUrl: - "https://raw.githubusercontent.com/vazco/universe-i18n-blaze/master/LICENSE", + "natestrauser:select2" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/nate-strauser/meteor-select2/master/LICENSE.txt", + }, + "ostrio:files" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/VeliovGroup/Meteor-Files/master/LICENSE", + }, + "perak:markdown" : { + licenses : "MIT", + licenseUrl : "https://raw.githubusercontent.com/chjj/marked/master/LICENSE", + }, + "percolate:migrations" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/percolatestudio/meteor-migrations/master/LICENSE", + }, + "practicalmeteor:mocha" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/practicalmeteor/meteor-mocha/meteor/LICENSE", + }, + "rcy:pick-a-color" : { + licenses : "MIT", + licenseUrl : "https://github.com/lauren/pick-a-color/raw/master/LICENSE", + }, + "sergeyt:typeahead" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/sergeyt/meteor-typeahead/master/LICENSE", + }, + "useraccounts:bootstrap" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/meteor-useraccounts/bootstrap/master/LICENSE", + }, + "universe:i18n" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/vazco/meteor-universe-i18n/master/LICENSE", + }, + "universe:i18n-blaze" : { + licenses : "MIT", + licenseUrl : + "https://raw.githubusercontent.com/vazco/universe-i18n-blaze/master/LICENSE", }, }; @@ -115,14 +116,15 @@ function get(url, callback) { function downloadToStream(project, url, licenseId, originalLicenseUrl) { if (!url) { - return Promise.resolve({ project, stream: null, url }); + return Promise.resolve({project, stream : null, url}); } // handle projects that declare a license but only with their SPDX id in // package.json and don't provide the license text in their repo SPDX provides // a repo with all licenses at https://github.com/spdx/license-list if (url.includes("raw")) { - const SPDXUrl = `https://github.com/spdx/license-list/raw/master/${licenseId}.txt`; + const SPDXUrl = + `https://github.com/spdx/license-list/raw/master/${licenseId}.txt`; return downloadToStream(project, SPDXUrl, licenseId, url); } @@ -140,9 +142,9 @@ function downloadToStream(project, url, licenseId, originalLicenseUrl) { // handle client and server errors } else if (response.statusCode >= 400) { console.log(`${response.statusCode}: ${url} not found`); - resolve({ project, url }); + resolve({project, url}); } else { - resolve({ project, stream: response, url }); + resolve({project, stream : response, url}); } }; @@ -156,44 +158,46 @@ function streamCollector(streams, index, outStream) { } streams[index] - .then(({ project, stream, url }) => { - const underlineProject = Array(project.length).join("="), - licenseSeparator = Array(80).join("="); - - outStream.write(`${project}\n${underlineProject}\n\n${url}\n\n`); - if (stream) { - console.log(`Writing license of ${project}`); - - stream.pipe(outStream, { end: false }); - stream.on("end", () => { + .then(({project, stream, url}) => { + const underlineProject = Array(project.length).join("="), + licenseSeparator = Array(80).join("="); + + outStream.write(`${project}\n${underlineProject}\n\n${url}\n\n`); + if (stream) { + console.log(`Writing license of ${project}`); + + stream.pipe(outStream, {end : false}); + stream.on("end", () => { + outStream.write(`\n\n${licenseSeparator}\n\n`); + streamCollector(streams, index + 1, outStream); + }); + } else { + console.log(`NO LICENSE TEXT FOUND FOR ${project}`); outStream.write(`\n\n${licenseSeparator}\n\n`); streamCollector(streams, index + 1, outStream); - }); - } else { - console.log(`NO LICENSE TEXT FOUND FOR ${project}`); - outStream.write(`\n\n${licenseSeparator}\n\n`); - streamCollector(streams, index + 1, outStream); - } - }) - .catch(console.error); + } + }) + .catch(console.error); } const licenseCount = {}; function getSortedKeys(obj) { const keys = []; - for (const key in obj) keys.push(key); + for (const key in obj) + keys.push(key); return keys.sort((a, b) => obj[b] - obj[a]); } -crawler.dumpLicenses({ start: ["."] }, (error, res) => { +crawler.dumpLicenses({start : [ "." ]}, (error, res) => { if (error) { console.error("Error:", error); return; } const output = fs.createWriteStream("LicensesOfDependencies.txt"); - const streams = Object.keys(res).map((project) => - downloadToStream(project, res[project].licenseUrl, res[project].licenses), + const streams = Object.keys(res).map( + (project) => downloadToStream(project, res[project].licenseUrl, + res[project].licenses), ); streamCollector(streams, 0, output); @@ -203,10 +207,11 @@ crawler.dumpLicenses({ start: ["."] }, (error, res) => { Object.assign(res, meteorPackages); Object.keys(res).forEach((project) => { licenseCount[res[project].licenses] = - (licenseCount[res[project].licenses] || 0) + 1; + (licenseCount[res[project].licenses] || 0) + 1; }); - getSortedKeys(licenseCount).forEach((license) => - console.log(`${license} ${licenseCount[license]}`), - ); + getSortedKeys(licenseCount) + .forEach( + (license) => console.log(`${license} ${licenseCount[license]}`), + ); console.log("********************"); }); diff --git a/tests/unit/client/helpers/submitOnEnter.test.js b/tests/unit/client/helpers/submitOnEnter.test.js index 7ce5bd9d2..a6b8a95a5 100644 --- a/tests/unit/client/helpers/submitOnEnter.test.js +++ b/tests/unit/client/helpers/submitOnEnter.test.js @@ -1,46 +1,46 @@ -import { expect } from "chai"; +import {expect} from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; import rewiremock from "../../test-helper/rewiremock.cjs"; - const jQueryOnStub = sinon.stub(); const $ = sinon.stub().returns({ - on: jQueryOnStub, + on : jQueryOnStub, }); -const submitOnEnter = await rewiremock.module( - () => import("../../../../client/helpers/submitOnEnter.js"), - { - jquery: $, - lodash: _, - }, -).default; - - -describe("submitOnEnter", function () { +const submitOnEnter = + await rewiremock + .module( + () => import("../../../../client/helpers/submitOnEnter.js"), + { + jquery : $, + lodash : _, + }, + ) + .default; + +describe("submitOnEnter", function() { const action = sinon.stub(); function fakeEnterPressed(controlPressed) { return { - keyCode: 13, - key: "Enter", - ctrlKey: controlPressed, - preventDefault: sinon.stub(), + keyCode : 13, + key : "Enter", + ctrlKey : controlPressed, + preventDefault : sinon.stub(), }; } - beforeEach(function () { + beforeEach(function() { jQueryOnStub.resetHistory(); $.resetHistory(); action.resetHistory(); }); - it("attaches event handlers to the given textareas", function () { - let textareas = ["one", "two"], - numberOfTextareas = textareas.length; + it("attaches event handlers to the given textareas", function() { + let textareas = [ "one", "two" ], numberOfTextareas = textareas.length; submitOnEnter(textareas, action); @@ -52,21 +52,20 @@ describe("submitOnEnter", function () { sinon.assert.calledWith($, "two"); }); - it("action is not triggered when control is not pressed for textarea", function () { - let input = ["one"], - event = fakeEnterPressed(false); + it("action is not triggered when control is not pressed for textarea", + function() { + let input = [ "one" ], event = fakeEnterPressed(false); - submitOnEnter(input, action); + submitOnEnter(input, action); - const handler = jQueryOnStub.getCall(0).args[1]; - handler(event); + const handler = jQueryOnStub.getCall(0).args[1]; + handler(event); - expect(action.calledOnce).to.be.false; - }); + expect(action.calledOnce).to.be.false; + }); - it("action is triggered when control is pressed for textareas", function () { - let input = ["one"], - event = fakeEnterPressed(true); + it("action is triggered when control is pressed for textareas", function() { + let input = [ "one" ], event = fakeEnterPressed(true); submitOnEnter(input, action); @@ -76,18 +75,18 @@ describe("submitOnEnter", function () { expect(action.calledOnce).to.be.true; }); - it("action is not triggered for textareas when something other than enter is entered", function () { - let input = ["one"], - event = fakeEnterPressed(true); + it("action is not triggered for textareas when something other than enter is entered", + function() { + let input = [ "one" ], event = fakeEnterPressed(true); - event.key = "Something Else"; - event.keyCode = 15; + event.key = "Something Else"; + event.keyCode = 15; - submitOnEnter(input, action); + submitOnEnter(input, action); - const handler = jQueryOnStub.getCall(0).args[1]; - handler(event); + const handler = jQueryOnStub.getCall(0).args[1]; + handler(event); - expect(action.calledOnce).to.be.false; - }); + expect(action.calledOnce).to.be.false; + }); }); diff --git a/tests/unit/imports/ActionItem.test.js b/tests/unit/imports/ActionItem.test.js index bf6f41ad4..7dea008c7 100644 --- a/tests/unit/imports/ActionItem.test.js +++ b/tests/unit/imports/ActionItem.test.js @@ -1,9 +1,10 @@ -import { expect } from "chai"; +import "../../../imports/helpers/date.js"; + +import {expect} from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; -import "../../../imports/helpers/date.js"; import rewiremock from "../test-helper/rewiremock.cjs"; const doNothing = () => {}; @@ -14,110 +15,106 @@ const Label = {}; class MeteorError {} const Meteor = { - call: sinon.stub(), - Error: MeteorError, - user: () => { - return { username: "unit-test" }; - }, + call : sinon.stub(), + Error : MeteorError, + user : () => { return {username : "unit-test"}; }, }; const Random = { - id: () => {}, + id : () => {}, }; const i18n = { - setLocale: sinon.stub(), - getLocale: sinon.stub(), - __: sinon.stub(), + setLocale : sinon.stub(), + getLocale : sinon.stub(), + __ : sinon.stub(), }; -const { Priority } = rewiremock.proxy("#root/imports/priority", { - "meteor/universe:i18n": { i18n, "@noCallThru": true }, +const {Priority} = rewiremock.proxy("#root/imports/priority", { + "meteor/universe:i18n" : {i18n, "@noCallThru" : true}, }); -const { InfoItem } = rewiremock.proxy("#root/imports/infoitem", { - "meteor/meteor": Meteor, - "meteor/random": Random, - "/imports/user": { null: null, "@noCallThru": true }, - lodash: _, - "./topic": Topic, - "./label": Label, +const {InfoItem} = rewiremock.proxy("#root/imports/infoitem", { + "meteor/meteor" : Meteor, + "meteor/random" : Random, + "/imports/user" : {null : null, "@noCallThru" : true}, + lodash : _, + "./topic" : Topic, + "./label" : Label, }); -const { ActionItem } = rewiremock.proxy("#root/imports/actionitem", { - "meteor/meteor": { Meteor, "@noCallThru": true }, - "/imports/priority": { Priority, "@noCallThru": true }, - "./infoitem": { InfoItem, "@noCallThru": true }, +const {ActionItem} = rewiremock.proxy("#root/imports/actionitem", { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "/imports/priority" : {Priority, "@noCallThru" : true}, + "./infoitem" : {InfoItem, "@noCallThru" : true}, }); -describe("ActionItem", function () { +describe("ActionItem", function() { let dummyTopic; let infoItemDoc; - beforeEach(function () { + beforeEach(function() { dummyTopic = { - _id: "AaBbCcDd", - save: doNothing, - findInfoItem: doNothing, + _id : "AaBbCcDd", + save : doNothing, + findInfoItem : doNothing, }; infoItemDoc = { - _id: "AaBbCcDd01", - createdInMinute: "AaBbCcDd01", - subject: "infoItemDoc", - createdAt: new Date(), - details: [ + _id : "AaBbCcDd01", + createdInMinute : "AaBbCcDd01", + subject : "infoItemDoc", + createdAt : new Date(), + details : [ { - date: "2016-05-06", - text: "details Text", + date : "2016-05-06", + text : "details Text", }, ], }; }); - describe("#constructor", function () { - it("sets the reference to the parent topic correctly", function () { + describe("#constructor", function() { + it("sets the reference to the parent topic correctly", function() { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); // the infoItem should have a reference of our dummyTopic expect(myActionItem._parentTopic).to.equal(dummyTopic); }); - it("sets the document correctly", function () { + it("sets the document correctly", function() { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); // the doc should be equal to our initial document expect(myActionItem._infoItemDoc).to.deep.equal(infoItemDoc); }); - it("sets the initial value for the isOpen-flag correctly", function () { + it("sets the initial value for the isOpen-flag correctly", function() { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); // the isOpen-filed should be initially true for a new actionItem expect(myActionItem._infoItemDoc.isOpen).to.be.true; }); - it("sets the initial value for the isNew-flag correctly", function () { + it("sets the initial value for the isNew-flag correctly", function() { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); // the isOpen-filed should be initially true for a new actionItem expect(myActionItem._infoItemDoc.isNew).to.be.true; }); }); - it("#getDateFromDetails", function () { + it("#getDateFromDetails", function() { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); - expect(myActionItem.getDateFromDetails()).to.equal( - infoItemDoc.details[0].date - ); + expect(myActionItem.getDateFromDetails()) + .to.equal(infoItemDoc.details[0].date); }); - it("#getTextFromDetails", function () { + it("#getTextFromDetails", function() { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); - expect(myActionItem.getTextFromDetails()).to.equal( - infoItemDoc.details[0].text - ); + expect(myActionItem.getTextFromDetails()) + .to.equal(infoItemDoc.details[0].text); }); - it("#toggleState", function () { + it("#toggleState", function() { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); const oldState = myActionItem._infoItemDoc.isOpen; diff --git a/tests/unit/imports/GlobalSettings.test.js b/tests/unit/imports/GlobalSettings.test.js index e7f92b42b..818e8ac2b 100644 --- a/tests/unit/imports/GlobalSettings.test.js +++ b/tests/unit/imports/GlobalSettings.test.js @@ -1,4 +1,4 @@ -import { expect } from "chai"; +import {expect} from "chai"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -6,12 +6,14 @@ import rewiremock from "../../test-helper/rewiremock.cjs"; class MeteorError {} const Meteor = { - Error: MeteorError, - absoluteUrl: (path, config) => { - if (!path) path = ""; + Error : MeteorError, + absoluteUrl : (path, config) => { + if (!path) + path = ""; if (config?.rootUrl) { - if (path !== "") path = `/${path}`; + if (path !== "") + path = `/${path}`; return config.rootUrl + path; } return path; @@ -19,94 +21,101 @@ const Meteor = { }; const LdapSettings = { - publish: sinon.stub(), + publish : sinon.stub(), }; -const { GlobalSettings } = rewiremock.proxy( - "#root/imports/config/GlobalSettings", - { - "meteor/meteor": { Meteor, "@noCallThru": true }, - "/imports/config/LdapSettings": { LdapSettings, "@noCallThru": true }, - }, +const {GlobalSettings} = rewiremock.proxy( + "#root/imports/config/GlobalSettings", + { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "/imports/config/LdapSettings" : {LdapSettings, "@noCallThru" : true}, + }, ); -describe("GlobalSettings", function () { - beforeEach("publish public settings", function () { +describe("GlobalSettings", function() { + beforeEach("publish public settings", function() { Meteor.settings = require("../../../settings_sample.json"); GlobalSettings.publishSettings(); }); - describe("#getRootUrl", function () { - it("returns the correct value", function () { + describe("#getRootUrl", function() { + it("returns the correct value", function() { expect(GlobalSettings.getRootUrl()).to.equal(Meteor.settings.ROOT_URL); }); - it("returns an empty string if property is not set", function () { + it("returns an empty string if property is not set", function() { delete Meteor.settings.ROOT_URL; expect(GlobalSettings.getRootUrl()).to.equal(""); }); - it("does not fail if no settings file give", function () { + it("does not fail if no settings file give", function() { Meteor.settings = {}; expect(GlobalSettings.getRootUrl()).to.equal(""); }); }); - describe("#isTrustedIntranetInstallation", function () { - it("returns the correct value", function () { - expect(GlobalSettings.isTrustedIntranetInstallation()).to.equal( - Meteor.settings.trustedIntranetInstallation, - ); + describe("#isTrustedIntranetInstallation", function() { + it("returns the correct value", function() { + expect(GlobalSettings.isTrustedIntranetInstallation()) + .to.equal( + Meteor.settings.trustedIntranetInstallation, + ); }); - it("returns false if property is not set", function () { + it("returns false if property is not set", function() { delete Meteor.settings.trustedIntranetInstallation; expect(GlobalSettings.isTrustedIntranetInstallation()).to.be.false; }); - it("does not fail if no settings file give", function () { + it("does not fail if no settings file give", function() { Meteor.settings = {}; expect(GlobalSettings.isTrustedIntranetInstallation()).to.be.false; }); }); - describe("#getDefaultEmailSenderAddress", function () { - it("returns the default email sender address", function () { - expect(GlobalSettings.getDefaultEmailSenderAddress()).to.equal( - Meteor.settings.email.defaultEMailSenderAddress, - ); - }); - - it("returns the alternative address of the current user if property is left empty", function () { - Meteor.settings.email.defaultEMailSenderAddress = ""; - const alternative = "alternativeSenderAddress"; - expect(GlobalSettings.getDefaultEmailSenderAddress(alternative)).to.equal( - alternative, - ); - }); - - it("returns fallback sender address if no alternative address is given", function () { - Meteor.settings.email.defaultEMailSenderAddress = ""; - expect(GlobalSettings.getDefaultEmailSenderAddress()).to.equal( - Meteor.settings.email.fallbackEMailSenderAddress, - ); - }); - - it("throws exception if fallback sender address required but not given", function () { - Meteor.settings.email.defaultEMailSenderAddress = ""; - delete Meteor.settings.email.fallbackEMailSenderAddress; - let exceptionThrown; - try { - GlobalSettings.getDefaultEmailSenderAddress(); - exceptionThrown = false; - } catch (e) { - exceptionThrown = e instanceof MeteorError; - } - - expect(exceptionThrown, "Method did not throw exception").to.be.true; - }); - - it("throws exception if property is not set", function () { + describe("#getDefaultEmailSenderAddress", function() { + it("returns the default email sender address", function() { + expect(GlobalSettings.getDefaultEmailSenderAddress()) + .to.equal( + Meteor.settings.email.defaultEMailSenderAddress, + ); + }); + + it("returns the alternative address of the current user if property is left empty", + function() { + Meteor.settings.email.defaultEMailSenderAddress = ""; + const alternative = "alternativeSenderAddress"; + expect(GlobalSettings.getDefaultEmailSenderAddress(alternative)) + .to.equal( + alternative, + ); + }); + + it("returns fallback sender address if no alternative address is given", + function() { + Meteor.settings.email.defaultEMailSenderAddress = ""; + expect(GlobalSettings.getDefaultEmailSenderAddress()) + .to.equal( + Meteor.settings.email.fallbackEMailSenderAddress, + ); + }); + + it("throws exception if fallback sender address required but not given", + function() { + Meteor.settings.email.defaultEMailSenderAddress = ""; + delete Meteor.settings.email.fallbackEMailSenderAddress; + let exceptionThrown; + try { + GlobalSettings.getDefaultEmailSenderAddress(); + exceptionThrown = false; + } catch (e) { + exceptionThrown = e instanceof MeteorError; + } + + expect(exceptionThrown, "Method did not throw exception").to.be.true; + }); + + it("throws exception if property is not set", function() { delete Meteor.settings.email.defaultEMailSenderAddress; let exceptionThrown; @@ -121,69 +130,73 @@ describe("GlobalSettings", function () { }); }); - describe("#isEMailDeliveryEnabled", function () { - it("returns the correct value", function () { - expect(GlobalSettings.isEMailDeliveryEnabled()).to.equal( - Meteor.settings.email.enableMailDelivery, - ); + describe("#isEMailDeliveryEnabled", function() { + it("returns the correct value", function() { + expect(GlobalSettings.isEMailDeliveryEnabled()) + .to.equal( + Meteor.settings.email.enableMailDelivery, + ); }); - it("returns false if property is not set", function () { + it("returns false if property is not set", function() { delete Meteor.settings.email.enableMailDelivery; GlobalSettings.publishSettings(); expect(GlobalSettings.isEMailDeliveryEnabled()).to.be.false; }); - it("does not fail if no settings file give", function () { + it("does not fail if no settings file give", function() { Meteor.settings = {}; expect(GlobalSettings.isEMailDeliveryEnabled()).to.be.false; }); }); - describe("#getMailDeliverer", function () { - it("returns the correct value", function () { - expect(GlobalSettings.getMailDeliverer()).to.equal( - Meteor.settings.email.mailDeliverer, - ); + describe("#getMailDeliverer", function() { + it("returns the correct value", function() { + expect(GlobalSettings.getMailDeliverer()) + .to.equal( + Meteor.settings.email.mailDeliverer, + ); }); - it("returns smtp if property is not set", function () { + it("returns smtp if property is not set", function() { delete Meteor.settings.email.mailDeliverer; expect(GlobalSettings.getMailDeliverer()).to.equal("smtp"); }); - it("does not fail if no settings file give", function () { + it("does not fail if no settings file give", function() { Meteor.settings = {}; expect(GlobalSettings.getMailDeliverer()).to.equal("smtp"); }); }); - describe("#getSMTPMailUrl", function () { - it("returns the correct value", function () { - expect(GlobalSettings.getSMTPMailUrl()).to.equal( - Meteor.settings.email.smtp.mailUrl, - ); + describe("#getSMTPMailUrl", function() { + it("returns the correct value", function() { + expect(GlobalSettings.getSMTPMailUrl()) + .to.equal( + Meteor.settings.email.smtp.mailUrl, + ); }); - it("returns an empty string if property is not set", function () { + it("returns an empty string if property is not set", function() { delete Meteor.settings.email.smtp.mailUrl; expect(GlobalSettings.getSMTPMailUrl()).to.equal(""); }); - it("does not fail if no settings file give", function () { + it("does not fail if no settings file give", function() { Meteor.settings = {}; expect(GlobalSettings.getSMTPMailUrl()).to.equal(""); }); }); - describe("#getMailgunSettings", function () { - it("returns the correct value", function () { - expect(GlobalSettings.getMailgunSettings()).to.equal( - Meteor.settings.email.mailgun, - ); + describe("#getMailgunSettings", function() { + it("returns the correct value", function() { + expect(GlobalSettings.getMailgunSettings()) + .to.equal( + Meteor.settings.email.mailgun, + ); }); - it("throws exception if property is not set", function () { + it("throws exception if property is not set", function() { delete Meteor.settings.email.mailgun; let exceptionThrown; diff --git a/tests/unit/imports/InfoItem.test.js b/tests/unit/imports/InfoItem.test.js index 1e437db1b..4efe1ae98 100644 --- a/tests/unit/imports/InfoItem.test.js +++ b/tests/unit/imports/InfoItem.test.js @@ -1,10 +1,10 @@ -import { expect } from "chai"; +import {expect} from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; import * as Helpers from "../../../imports/helpers/date"; -import { subElementsHelper } from "../../../imports/helpers/subElements"; +import {subElementsHelper} from "../../../imports/helpers/subElements"; import rewiremock from "../../test-helper/rewiremock.cjs"; const Topic = {}; @@ -14,43 +14,42 @@ Helpers["@noCallThru"] = true; class MeteorError {} const Meteor = { - Error: MeteorError, - user: () => { - return { username: "unit-test" }; - }, + Error : MeteorError, + user : () => { return {username : "unit-test"}; }, }; const Random = { - id: () => {}, + id : () => {}, }; const User = { - profileNameWithFallback: sinon.stub(), + profileNameWithFallback : sinon.stub(), }; -const { InfoItem } = rewiremock.proxy("#root/imports/infoitem", { - "meteor/meteor": { Meteor, "@noCallThru": true }, - "meteor/random": { Random, "@noCallThru": true }, - lodash: { _, "@noCallThru": true }, - "/imports/user": { User, "@noCallThru": true }, - "/imports/helpers/date": Helpers, - "./topic": { Topic, "@noCallThru": true }, - "./label": { Label, "@noCallThru": true }, +const {InfoItem} = rewiremock.proxy("#root/imports/infoitem", { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "meteor/random" : {Random, "@noCallThru" : true}, + lodash : {_, "@noCallThru" : true}, + "/imports/user" : {User, "@noCallThru" : true}, + "/imports/helpers/date" : Helpers, + "./topic" : {Topic, "@noCallThru" : true}, + "./label" : {Label, "@noCallThru" : true}, }); // skipcq: JS-0241 -describe("InfoItem", function () { +describe("InfoItem", function() { let dummyTopic; let infoItemDoc; // skipcq: JS-0241 - beforeEach(function () { + beforeEach(function() { dummyTopic = { - _id: "AaBbCcDd", - _infoItems: [], - upsertInfoItem: sinon.stub(), + _id : "AaBbCcDd", + _infoItems : [], + upsertInfoItem : sinon.stub(), findInfoItem(id) { const index = subElementsHelper.findIndexById(id, this._infoItems); - if (index === undefined) return undefined; + if (index === undefined) + return undefined; return new InfoItem(this, this._infoItems[index]); }, // test-only method @@ -61,62 +60,65 @@ describe("InfoItem", function () { }; infoItemDoc = { - _id: "AaBbCcDd01", - subject: "infoItemDoc", - createdAt: new Date(), - createdInMinute: "AaBbCcDd01", + _id : "AaBbCcDd01", + subject : "infoItemDoc", + createdAt : new Date(), + createdInMinute : "AaBbCcDd01", }; }); // skipcq: JS-0241 - describe("#constructor", function () { + describe("#constructor", function() { // skipcq: JS-0241 - it("sets the reference to the parent topic correctly", function () { + it("sets the reference to the parent topic correctly", function() { const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); // the infoItem should have a reference of our dummyTopic expect(myInfoItem._parentTopic).to.equal(dummyTopic); }); // skipcq: JS-0241 - it("sets the document correctly", function () { + it("sets the document correctly", function() { const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); // the doc should be equal to our initial document expect(myInfoItem._infoItemDoc).to.equal(infoItemDoc); }); // skipcq: JS-0241 - it("creates the same object by passing the id of an existing one", function () { - const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); - // add the created info item to our dummy topic - dummyTopic.addInfoItem(myInfoItem); + it("creates the same object by passing the id of an existing one", + function() { + const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); + // add the created info item to our dummy topic + dummyTopic.addInfoItem(myInfoItem); - // Now we should be able to create the same info item again - // by passing the dummyTopic together with the info items id - const sameInfoItem = new InfoItem( - dummyTopic, - myInfoItem._infoItemDoc._id, - ); - // the associated documents of both info items should be the same - expect(sameInfoItem._infoItemDoc).to.equal(myInfoItem._infoItemDoc); - }); + // Now we should be able to create the same info item again + // by passing the dummyTopic together with the info items id + const sameInfoItem = new InfoItem( + dummyTopic, + myInfoItem._infoItemDoc._id, + ); + // the associated documents of both info items should be the same + expect(sameInfoItem._infoItemDoc).to.equal(myInfoItem._infoItemDoc); + }); }); // skipcq: JS-0241 - it("#isActionItem", function () { + it("#isActionItem", function() { const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); expect( - myInfoItem.isActionItem(), - "Item without the itemType-property should not be an ActionItem", - ).to.be.false; + myInfoItem.isActionItem(), + "Item without the itemType-property should not be an ActionItem", + ) + .to.be.false; const actionItemDoc = { - _id: "AaBbCcDd02", - subject: "actionItemDoc", - itemType: "actionItem", + _id : "AaBbCcDd02", + subject : "actionItemDoc", + itemType : "actionItem", }; expect( - InfoItem.isActionItem(actionItemDoc), - "Item with the itemType-property set to actionItem should be an ActionItem", - ).to.be.true; + InfoItem.isActionItem(actionItemDoc), + "Item with the itemType-property set to actionItem should be an ActionItem", + ) + .to.be.true; }); // skipcq: JS-0241 - it("#save", function () { + it("#save", function() { const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); myInfoItem.save(); diff --git a/tests/unit/imports/InfoItemFactory.test.js b/tests/unit/imports/InfoItemFactory.test.js index 9b9d2c25f..c5b827c49 100644 --- a/tests/unit/imports/InfoItemFactory.test.js +++ b/tests/unit/imports/InfoItemFactory.test.js @@ -1,14 +1,14 @@ -import { expect } from "chai"; +import {expect} from "chai"; import proxyquire from "proxyquire"; import rewiremock from "../../test-helper/rewiremock.cjs"; const TestSetup = { - nextItemIsAnActionItem: false, - infoItemConstructorCallCount: 0, - actionItemConstructorCallCount: 0, - infoItemConstructorArguments: [], - actionItemConstructorArguments: [], + nextItemIsAnActionItem : false, + infoItemConstructorCallCount : 0, + actionItemConstructorCallCount : 0, + infoItemConstructorArguments : [], + actionItemConstructorArguments : [], reset() { this.nextItemIsAnActionItem = false; this.infoItemConstructorCallCount = 0; @@ -23,9 +23,7 @@ class InfoItem { TestSetup.infoItemConstructorCallCount++; TestSetup.infoItemConstructorArguments.push(arguments); } - static isActionItem() { - return TestSetup.nextItemIsAnActionItem; - } + static isActionItem() { return TestSetup.nextItemIsAnActionItem; } } class ActionItem { @@ -35,15 +33,13 @@ class ActionItem { } } -const { InfoItemFactory } = rewiremock.proxy("#root/imports/InfoItemFactory", { - "./infoitem": { InfoItem, "@noCallThru": true }, - "./actionitem": { ActionItem, "@noCallThru": true }, +const {InfoItemFactory} = rewiremock.proxy("#root/imports/InfoItemFactory", { + "./infoitem" : {InfoItem, "@noCallThru" : true}, + "./actionitem" : {ActionItem, "@noCallThru" : true}, }); describe("InfoItemFactory", () => { - afterEach(() => { - TestSetup.reset(); - }); + afterEach(() => { TestSetup.reset(); }); describe("#createInfoItem", () => { let infoItemDoc, parentItemDoc; @@ -54,44 +50,51 @@ describe("InfoItemFactory", () => { }; beforeEach(() => { - infoItemDoc = { name: "A Info Item" }; - parentItemDoc = { name: "A Parent Item" }; + infoItemDoc = {name : "A Info Item"}; + parentItemDoc = {name : "A Parent Item"}; }); - it("should call the info item constructor if InfoItem.isActionItem returns false", () => { - InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); - expect( - TestSetup.infoItemConstructorCallCount, - "InfoItem constructor should have been called once", - ).to.equal(1); - expect( - TestSetup.actionItemConstructorCallCount, - "actionItem constructor should not have been called", - ).to.equal(0); - }); + it("should call the info item constructor if InfoItem.isActionItem returns false", + () => { + InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); + expect( + TestSetup.infoItemConstructorCallCount, + "InfoItem constructor should have been called once", + ) + .to.equal(1); + expect( + TestSetup.actionItemConstructorCallCount, + "actionItem constructor should not have been called", + ) + .to.equal(0); + }); - it("should create a new info item if InfoItem.isActionItem returns true", () => { - TestSetup.nextItemIsAnActionItem = true; - InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); - expect( - TestSetup.infoItemConstructorCallCount, - "InfoItem constructor should not have been called", - ).to.equal(0); - expect( - TestSetup.actionItemConstructorCallCount, - "actionItem constructor should have been called once", - ).to.equal(1); - }); + it("should create a new info item if InfoItem.isActionItem returns true", + () => { + TestSetup.nextItemIsAnActionItem = true; + InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); + expect( + TestSetup.infoItemConstructorCallCount, + "InfoItem constructor should not have been called", + ) + .to.equal(0); + expect( + TestSetup.actionItemConstructorCallCount, + "actionItem constructor should have been called once", + ) + .to.equal(1); + }); it("should pass the correct arguments to the info item constructor", () => { InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); verifyArguments(TestSetup.infoItemConstructorArguments); }); - it("should pass the correct arguments to the action item constructor", () => { - TestSetup.nextItemIsAnActionItem = true; - InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); - verifyArguments(TestSetup.actionItemConstructorArguments); - }); + it("should pass the correct arguments to the action item constructor", + () => { + TestSetup.nextItemIsAnActionItem = true; + InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); + verifyArguments(TestSetup.actionItemConstructorArguments); + }); }); }); diff --git a/tests/unit/imports/MeetingSeries.test.js b/tests/unit/imports/MeetingSeries.test.js index ec0ee0933..7a2823218 100644 --- a/tests/unit/imports/MeetingSeries.test.js +++ b/tests/unit/imports/MeetingSeries.test.js @@ -1,59 +1,55 @@ -import { expect } from "chai"; +import {expect} from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; import * as DateHelpers from "../../../imports/helpers/date"; import * as SubElements from "../../../imports/helpers/subElements"; - import rewiremock from "../../test-helper/rewiremock.cjs"; - const MeetingSeriesSchema = {}; const Meteor = { - call: sinon.stub(), - callAsync: sinon.stub(), + call : sinon.stub(), + callAsync : sinon.stub(), }; const Minutes = {}; const Topic = {}; const UserRoles = {}; const PromisedMethods = {}; const MinutesFinder = { - result: undefined, - lastMinutesOfMeetingSeries() { - return this.result; - }, + result : undefined, + lastMinutesOfMeetingSeries() { return this.result; }, }; DateHelpers["@noCallThru"] = true; SubElements["@noCallThru"] = true; const Random = { - id: () => {}, + id : () => {}, }; const jQuery = {}; const TopicsFinder = {}; -const { MeetingSeries } = rewiremock.proxy("#root/imports/meetingseries", { - "meteor/meteor": { Meteor, "@noCallThru": true }, - "meteor/random": { Random, "@noCallThru": true }, - "meteor/jquery": { jQuery, "@noCallThru": true }, - "./collections/meetingseries.schema": { +const {MeetingSeries} = rewiremock.proxy("#root/imports/meetingseries", { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "meteor/random" : {Random, "@noCallThru" : true}, + "meteor/jquery" : {jQuery, "@noCallThru" : true}, + "./collections/meetingseries.schema" : { MeetingSeriesSchema, - "@noCallThru": true, + "@noCallThru" : true, }, - "./collections/meetingseries_private": { + "./collections/meetingseries_private" : { MeetingSeriesSchema, - "@noCallThru": true, + "@noCallThru" : true, }, - "./helpers/promisedMethods": { PromisedMethods, "@noCallThru": true }, - "./minutes": { Minutes, "@noCallThru": true }, - "./topic": { Topic, "@noCallThru": true }, - "./userroles": { UserRoles, "@noCallThru": true }, - "/imports/helpers/date": DateHelpers, - "/imports/helpers/subElements": SubElements, - lodash: { _, "@noCallThru": true }, - "./services/topicsFinder": { TopicsFinder, "@noCallThru": true }, - "/imports/services/minutesFinder": { MinutesFinder, "@noCallThru": true }, + "./helpers/promisedMethods" : {PromisedMethods, "@noCallThru" : true}, + "./minutes" : {Minutes, "@noCallThru" : true}, + "./topic" : {Topic, "@noCallThru" : true}, + "./userroles" : {UserRoles, "@noCallThru" : true}, + "/imports/helpers/date" : DateHelpers, + "/imports/helpers/subElements" : SubElements, + lodash : {_, "@noCallThru" : true}, + "./services/topicsFinder" : {TopicsFinder, "@noCallThru" : true}, + "/imports/services/minutesFinder" : {MinutesFinder, "@noCallThru" : true}, }); describe("MeetingSeries", () => { @@ -62,8 +58,8 @@ describe("MeetingSeries", () => { beforeEach(() => { meetingSeries = { - project: "foo", - name: "bar", + project : "foo", + name : "bar", }; }); @@ -83,9 +79,7 @@ describe("MeetingSeries", () => { describe("#getMinimumAllowedDateForMinutes", () => { let series; - beforeEach(() => { - series = new MeetingSeries(); - }); + beforeEach(() => { series = new MeetingSeries(); }); afterEach(() => { if (Object.prototype.hasOwnProperty.call(Minutes, "findAllIn")) { @@ -94,67 +88,71 @@ describe("MeetingSeries", () => { }); function compareDates(actualDate, expectedDate) { - expect(actualDate.getYear(), "year mismatch").to.be.equal( - expectedDate.getYear(), - ); - expect(actualDate.getMonth(), "month mismatch").to.be.equal( - expectedDate.getMonth(), - ); - expect(actualDate.getDay(), "day mismatch").to.be.equal( - expectedDate.getDay(), - ); + expect(actualDate.getYear(), "year mismatch") + .to.be.equal( + expectedDate.getYear(), + ); + expect(actualDate.getMonth(), "month mismatch") + .to.be.equal( + expectedDate.getMonth(), + ); + expect(actualDate.getDay(), "day mismatch") + .to.be.equal( + expectedDate.getDay(), + ); } it("retrieves the date of the lastMinutes() if no id is given", () => { const expectedDate = new Date(); - MinutesFinder.result = { date: expectedDate }; + MinutesFinder.result = {date : expectedDate}; const actualDate = series.getMinimumAllowedDateForMinutes(); compareDates(actualDate, expectedDate); }); - it("gets the date from the second to last minute if id of last minute is given", () => { - let lastMinuteId = "lastMinuteId", - expectedDate = new Date(); - - Minutes.findAllIn = sinon.stub().returns([ - { - _id: "someid", - date: expectedDate, - }, - { - _id: lastMinuteId, - date: new Date(2013, 12, 11, 0, 0), - }, - ]); - - const actualDate = series.getMinimumAllowedDateForMinutes(lastMinuteId); - - compareDates(actualDate, expectedDate); - }); - - it("gets the date from the last minute if id of second to last minute is given", () => { - let secondToLastMinuteId = "minuteId", - expectedDate = new Date(); - - Minutes.findAllIn = sinon.stub().returns([ - { - _id: secondToLastMinuteId, - date: new Date(2013, 12, 11, 0, 0), - }, - { - _id: "last minute", - date: expectedDate, - }, - ]); - - const actualDate = - series.getMinimumAllowedDateForMinutes(secondToLastMinuteId); - - compareDates(actualDate, expectedDate); - }); + it("gets the date from the second to last minute if id of last minute is given", + () => { + let lastMinuteId = "lastMinuteId", expectedDate = new Date(); + + Minutes.findAllIn = sinon.stub().returns([ + { + _id : "someid", + date : expectedDate, + }, + { + _id : lastMinuteId, + date : new Date(2013, 12, 11, 0, 0), + }, + ]); + + const actualDate = + series.getMinimumAllowedDateForMinutes(lastMinuteId); + + compareDates(actualDate, expectedDate); + }); + + it("gets the date from the last minute if id of second to last minute is given", + () => { + let secondToLastMinuteId = "minuteId", expectedDate = new Date(); + + Minutes.findAllIn = sinon.stub().returns([ + { + _id : secondToLastMinuteId, + date : new Date(2013, 12, 11, 0, 0), + }, + { + _id : "last minute", + date : expectedDate, + }, + ]); + + const actualDate = + series.getMinimumAllowedDateForMinutes(secondToLastMinuteId); + + compareDates(actualDate, expectedDate); + }); }); describe("#save", () => { @@ -162,8 +160,8 @@ describe("MeetingSeries", () => { beforeEach(() => { meetingSeries = new MeetingSeries({ - project: "foo", - name: "bar", + project : "foo", + name : "bar", }); }); @@ -177,7 +175,7 @@ describe("MeetingSeries", () => { meetingSeries.save(); expect(Meteor.callAsync.calledWith("meetingseries.insert", meetingSeries)) - .to.be.true; + .to.be.true; }); }); }); diff --git a/tests/unit/imports/Minutes.test.js b/tests/unit/imports/Minutes.test.js index fd7eb8387..b3f7bebc2 100644 --- a/tests/unit/imports/Minutes.test.js +++ b/tests/unit/imports/Minutes.test.js @@ -1,4 +1,4 @@ -import { expect } from "chai"; +import {expect} from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -9,8 +9,8 @@ import * as SubElements from "../../../imports/helpers/subElements"; import rewiremock from "../../test-helper/rewiremock.cjs"; const MinutesSchema = { - find: sinon.stub(), - findOne: sinon.stub(), + find : sinon.stub(), + findOne : sinon.stub(), }; MinutesSchema.getCollection = (_) => MinutesSchema; @@ -18,9 +18,9 @@ MinutesSchema.getCollection = (_) => MinutesSchema; class MeteorError {} const Meteor = { - call: sinon.stub(), - callAsync: sinon.stub().resolves(true), - Error: MeteorError, + call : sinon.stub(), + callAsync : sinon.stub().resolves(true), + Error : MeteorError, }; const PromisedMethods = {}; @@ -28,7 +28,7 @@ const PromisedMethods = {}; const isCurrentUserModeratorStub = sinon.stub(); const updateLastMinutesFieldsStub = sinon.stub(); const updateLastMinutesFieldsAsyncStub = sinon.stub().resolves(true); -const MeetingSeries = function (seriesId) { +const MeetingSeries = function(seriesId) { this._id = seriesId; this.isCurrentUserModerator = isCurrentUserModeratorStub; this.updateLastMinutesFields = updateLastMinutesFieldsStub; @@ -36,14 +36,11 @@ const MeetingSeries = function (seriesId) { }; const topicGetOpenActionItemsStub = sinon.stub().returns([]); -const Topic = function () { - this.getOpenActionItems = topicGetOpenActionItemsStub; -}; -Topic.hasOpenActionItem = () => { - return false; -}; +const Topic = + function() { this.getOpenActionItems = topicGetOpenActionItemsStub; }; +Topic.hasOpenActionItem = () => { return false; }; -const ActionItem = function (topic, doc) { +const ActionItem = function(topic, doc) { this._parentTopic = topic; this._infoItemDoc = doc; }; @@ -51,23 +48,23 @@ const ActionItem = function (topic, doc) { SubElements["@noCallThru"] = true; EmailHelpers["@noCallThru"] = true; const Random = { - id: () => {}, + id : () => {}, }; -const { Minutes } = rewiremock.proxy("#root/imports/minutes", { - "meteor/meteor": { Meteor, "@noCallThru": true }, - "meteor/universe:i18n": { Meteor, "@noCallThru": true }, - "meteor/random": { Random, "@noCallThru": true }, - "./collections/minutes_private": { MinutesSchema, "@noCallThru": true }, - "./collections/minutes.schema": { MinutesSchema, "@noCallThru": true }, - "./collections/workflow_private": { null: null, "@noCallThru": true }, - "./helpers/promisedMethods": { PromisedMethods, "@noCallThru": true }, - "./meetingseries": { MeetingSeries, "@noCallThru": true }, - "./topic": { Topic, "@noCallThru": true }, - "/imports/user": { null: null, "@noCallThru": true }, - "./actionitem": { ActionItem, "@noCallThru": true }, - "/imports/helpers/email": EmailHelpers, - "/imports/helpers/subElements": SubElements, - lodash: { _, "@noCallThru": true }, +const {Minutes} = rewiremock.proxy("#root/imports/minutes", { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "meteor/universe:i18n" : {Meteor, "@noCallThru" : true}, + "meteor/random" : {Random, "@noCallThru" : true}, + "./collections/minutes_private" : {MinutesSchema, "@noCallThru" : true}, + "./collections/minutes.schema" : {MinutesSchema, "@noCallThru" : true}, + "./collections/workflow_private" : {null : null, "@noCallThru" : true}, + "./helpers/promisedMethods" : {PromisedMethods, "@noCallThru" : true}, + "./meetingseries" : {MeetingSeries, "@noCallThru" : true}, + "./topic" : {Topic, "@noCallThru" : true}, + "/imports/user" : {null : null, "@noCallThru" : true}, + "./actionitem" : {ActionItem, "@noCallThru" : true}, + "/imports/helpers/email" : EmailHelpers, + "/imports/helpers/subElements" : SubElements, + lodash : {_, "@noCallThru" : true}, }); describe("Minutes", () => { @@ -75,14 +72,14 @@ describe("Minutes", () => { beforeEach(() => { minutesDoc = { - meetingSeries_id: "AaBbCc01", - _id: "AaBbCc02", - date: "2016-05-06", - createdAt: new Date(), - topics: [], - isFinalized: false, - participants: "", - agenda: "", + meetingSeries_id : "AaBbCc01", + _id : "AaBbCc02", + date : "2016-05-06", + createdAt : new Date(), + topics : [], + isFinalized : false, + participants : "", + agenda : "", }; minute = new Minutes(minutesDoc); @@ -106,47 +103,52 @@ describe("Minutes", () => { it("fetches the minute from the database if the id was given", () => { new Minutes(minutesDoc._id); expect(MinutesSchema.findOne.calledOnce, "findOne should be called once") - .to.be.true; + .to.be.true; expect( - MinutesSchema.findOne.calledWith(minutesDoc._id), - "findOne should be called with the id", - ).to.be.true; - }); - - it("throws exception if constructor will be called without any arguments", () => { - let exceptionThrown; - try { - new Minutes(); - exceptionThrown = false; - } catch (e) { - exceptionThrown = e instanceof MeteorError; - } - - expect(exceptionThrown).to.be.true; - }); + MinutesSchema.findOne.calledWith(minutesDoc._id), + "findOne should be called with the id", + ) + .to.be.true; + }); + + it("throws exception if constructor will be called without any arguments", + () => { + let exceptionThrown; + try { + new Minutes(); + exceptionThrown = false; + } catch (e) { + exceptionThrown = e instanceof MeteorError; + } + + expect(exceptionThrown).to.be.true; + }); }); describe("find", () => { it("#find", () => { Minutes.find("myArg"); expect(MinutesSchema.find.calledOnce, "find-Method should be called once") - .to.be.true; + .to.be.true; expect( - MinutesSchema.find.calledWithExactly("myArg"), - "arguments should be passed", - ).to.be.true; + MinutesSchema.find.calledWithExactly("myArg"), + "arguments should be passed", + ) + .to.be.true; }); it("#findOne", () => { Minutes.findOne("myArg"); expect( - MinutesSchema.findOne.calledOnce, - "findOne-Method should be called once", - ).to.be.true; + MinutesSchema.findOne.calledOnce, + "findOne-Method should be called once", + ) + .to.be.true; expect( - MinutesSchema.findOne.calledWithExactly("myArg"), - "arguments should be passed", - ).to.be.true; + MinutesSchema.findOne.calledWithExactly("myArg"), + "arguments should be passed", + ) + .to.be.true; }); describe("#findAllIn", () => { @@ -154,42 +156,46 @@ describe("Minutes", () => { let limit; beforeEach(() => { - minIdArray = ["1", "2"]; + minIdArray = [ "1", "2" ]; limit = 3; }); it("calls the find-Method of the Collection", () => { Minutes.findAllIn(minIdArray, limit); expect( - MinutesSchema.find.calledOnce, - "find-Method should be called once", - ).to.be.true; + MinutesSchema.find.calledOnce, + "find-Method should be called once", + ) + .to.be.true; }); it("sets the id selector correctly", () => { Minutes.findAllIn(minIdArray, limit); const selector = MinutesSchema.find.getCall(0).args[0]; - expect(selector, "Selector has the property _id").to.have.ownProperty( - "_id", - ); + expect(selector, "Selector has the property _id") + .to.have.ownProperty( + "_id", + ); expect( - selector._id, - "_id-selector has propery $in", - ).to.have.ownProperty("$in"); - expect(selector._id.$in, "idArray should be passed").to.deep.equal( - minIdArray, - ); + selector._id, + "_id-selector has propery $in", + ) + .to.have.ownProperty("$in"); + expect(selector._id.$in, "idArray should be passed") + .to.deep.equal( + minIdArray, + ); }); it("sets the option correctly (sort, no limit)", () => { - const expectedOption = { sort: { date: -1 } }; + const expectedOption = {sort : {date : -1}}; Minutes.findAllIn(minIdArray); const options = MinutesSchema.find.getCall(0).args[1]; expect(options).to.deep.equal(expectedOption); }); it("sets the option correctly (sort and limit)", () => { - const expectedOption = { sort: { date: -1 }, limit }; + const expectedOption = {sort : {date : -1}, limit}; Minutes.findAllIn(minIdArray, limit); const options = MinutesSchema.find.getCall(0).args[1]; expect(options).to.deep.equal(expectedOption); @@ -206,8 +212,10 @@ describe("Minutes", () => { it("sends the minutes id to the meteor method minutes.remove", () => { Minutes.remove(minute._id); expect( - Meteor.callAsync.calledWithExactly("workflow.removeMinute", minute._id), - ).to.be.true; + Meteor.callAsync.calledWithExactly("workflow.removeMinute", + minute._id), + ) + .to.be.true; }); }); @@ -215,7 +223,7 @@ describe("Minutes", () => { let visibleForArray, parentSeriesId; beforeEach(() => { - visibleForArray = ["1", "2"]; + visibleForArray = [ "1", "2" ]; parentSeriesId = minute.meetingSeries_id; }); @@ -224,16 +232,18 @@ describe("Minutes", () => { expect(Meteor.callAsync.calledOnce).to.be.true; }); - it("sends the parentSeriesId and the visibleFor-array to the meteor method minutes.syncVisibilityAndParticipants", () => { - Minutes.syncVisibility(parentSeriesId, visibleForArray); - expect( - Meteor.callAsync.calledWithExactly( - "minutes.syncVisibilityAndParticipants", - parentSeriesId, - visibleForArray, - ), - ).to.be.true; - }); + it("sends the parentSeriesId and the visibleFor-array to the meteor method minutes.syncVisibilityAndParticipants", + () => { + Minutes.syncVisibility(parentSeriesId, visibleForArray); + expect( + Meteor.callAsync.calledWithExactly( + "minutes.syncVisibilityAndParticipants", + parentSeriesId, + visibleForArray, + ), + ) + .to.be.true; + }); }); describe("#update", () => { @@ -241,7 +251,7 @@ describe("Minutes", () => { beforeEach(() => { updateDocPart = { - date: "2016-05-07", + date : "2016-05-07", }; }); @@ -250,44 +260,49 @@ describe("Minutes", () => { expect(Meteor.callAsync.calledOnce).to.be.true; }); - it("sends the doc part and the minutes id to the meteor method minutes.update", () => { - minute.update(updateDocPart); - const sentObj = JSON.parse(JSON.stringify(updateDocPart)); - sentObj._id = minute._id; - expect( - Meteor.callAsync.calledWithExactly( - "minutes.update", - sentObj, - undefined, - ), - ).to.be.true; - }); - - it("updates the changed property of the minute object", async function () { + it("sends the doc part and the minutes id to the meteor method minutes.update", + () => { + minute.update(updateDocPart); + const sentObj = JSON.parse(JSON.stringify(updateDocPart)); + sentObj._id = minute._id; + expect( + Meteor.callAsync.calledWithExactly( + "minutes.update", + sentObj, + undefined, + ), + ) + .to.be.true; + }); + + it("updates the changed property of the minute object", async function() { await minute.update(updateDocPart); expect(minute.date).to.equal(updateDocPart.date); }); }); describe("#save", () => { - it("calls the meteor method minutes.insert if a new minute will be saved", () => { - delete minute._id; - minute.save(); - expect(Meteor.call.calledOnce).to.be.true; - }); - - it("uses the workflow.addMinutes method to save a new minutes document", () => { - delete minute._id; - minute.save(); - expect( - Meteor.call.calledWithExactly( - "workflow.addMinutes", - minute, - undefined, - undefined, - ), - ).to.be.true; - }); + it("calls the meteor method minutes.insert if a new minute will be saved", + () => { + delete minute._id; + minute.save(); + expect(Meteor.call.calledOnce).to.be.true; + }); + + it("uses the workflow.addMinutes method to save a new minutes document", + () => { + delete minute._id; + minute.save(); + expect( + Meteor.call.calledWithExactly( + "workflow.addMinutes", + minute, + undefined, + undefined, + ), + ) + .to.be.true; + }); it("sets the createdAt-property if it is not set", () => { delete minute._id; @@ -296,28 +311,31 @@ describe("Minutes", () => { expect(minute).to.have.ownProperty("createdAt"); }); - it("calls the meteor method minutes.update if a existing minute will be saved", () => { - minute.save(); - expect(Meteor.call.calledOnce).to.be.true; - }); + it("calls the meteor method minutes.update if a existing minute will be saved", + () => { + minute.save(); + expect(Meteor.call.calledOnce).to.be.true; + }); it("sends the minutes object to the meteor method minutes.update", () => { minute.save(); - expect(Meteor.call.calledWithExactly("minutes.update", minute)).to.be - .true; + expect(Meteor.call.calledWithExactly("minutes.update", minute)) + .to.be.true; }); }); it("#parentMeetingSeries", () => { const parentSeries = minute.parentMeetingSeries(); expect( - parentSeries instanceof MeetingSeries, - "result should be an instance of MeetingSeries", - ).to.be.true; + parentSeries instanceof MeetingSeries, + "result should be an instance of MeetingSeries", + ) + .to.be.true; expect( - parentSeries._id, - "created meeting series object should have the correct series id", - ).to.equal(minute.meetingSeries_id); + parentSeries._id, + "created meeting series object should have the correct series id", + ) + .to.equal(minute.meetingSeries_id); }); it("#parentMeetingSeriesID", () => { @@ -329,28 +347,28 @@ describe("Minutes", () => { beforeEach(() => { topic1 = { - _id: "01", - subject: "firstTopic", - isNew: true, - isOpen: true, + _id : "01", + subject : "firstTopic", + isNew : true, + isOpen : true, }; topic2 = { - _id: "02", - subject: "2ndTopic", - isNew: true, - isOpen: false, + _id : "02", + subject : "2ndTopic", + isNew : true, + isOpen : false, }; topic3 = { - _id: "03", - subject: "3rdTopic", - isNew: false, - isOpen: true, + _id : "03", + subject : "3rdTopic", + isNew : false, + isOpen : true, }; topic4 = { - _id: "04", - subject: "4thTopic", - isNew: false, - isOpen: false, + _id : "04", + subject : "4thTopic", + isNew : false, + isOpen : false, }; minute.topics.push(topic1); minute.topics.push(topic2); @@ -359,13 +377,11 @@ describe("Minutes", () => { }); describe("#findTopic", () => { - it("finds the correct topic identified by its id", () => { - expect(minute.findTopic(topic1._id)).to.deep.equal(topic1); - }); + it("finds the correct topic identified by its id", + () => { expect(minute.findTopic(topic1._id)).to.deep.equal(topic1); }); - it("returns undefined if topic was not found", () => { - expect(minute.findTopic("unknownId")).to.be.undefined; - }); + it("returns undefined if topic was not found", + () => { expect(minute.findTopic("unknownId")).to.be.undefined; }); }); describe("#removeTopic", () => { @@ -382,9 +398,8 @@ describe("Minutes", () => { }); describe("#getNewTopics", () => { - it("returns the correct amount of topics", () => { - expect(minute.getNewTopics()).to.have.length(2); - }); + it("returns the correct amount of topics", + () => { expect(minute.getNewTopics()).to.have.length(2); }); it("returns only new topics", () => { const newTopics = minute.getNewTopics(); @@ -395,17 +410,17 @@ describe("Minutes", () => { }); describe("#getOldClosedTopics", () => { - it("returns the correct amount of topics", () => { - expect(minute.getOldClosedTopics()).to.have.length(1); - }); + it("returns the correct amount of topics", + () => { expect(minute.getOldClosedTopics()).to.have.length(1); }); it("returns only old and closed topics", () => { const oldClosedTopics = minute.getOldClosedTopics(); oldClosedTopics.forEach((topic) => { expect( - topic.isNew && topic.isOpen, - "isNew and isOpen flag should both not set", - ).to.be.false; + topic.isNew && topic.isOpen, + "isNew and isOpen flag should both not set", + ) + .to.be.false; }); }); }); @@ -413,16 +428,18 @@ describe("Minutes", () => { describe("#getOpenActionItems", () => { it("calls the getOpenActionItems method for each topic", () => { minute.getOpenActionItems(); - expect(topicGetOpenActionItemsStub.callCount).to.equal( - minute.topics.length, - ); + expect(topicGetOpenActionItemsStub.callCount) + .to.equal( + minute.topics.length, + ); }); it("concatenates all results of each getOpenActionItems-call", () => { - topicGetOpenActionItemsStub.returns([5, 7]); - expect(minute.getOpenActionItems()).to.have.length( - minute.topics.length * 2, - ); + topicGetOpenActionItemsStub.returns([ 5, 7 ]); + expect(minute.getOpenActionItems()) + .to.have.length( + minute.topics.length * 2, + ); }); }); }); @@ -432,7 +449,7 @@ describe("Minutes", () => { beforeEach(() => { topicDoc = { - subject: "myTopic", + subject : "myTopic", }; }); @@ -440,11 +457,11 @@ describe("Minutes", () => { minute.upsertTopic(topicDoc); expect(Meteor.callAsync.calledOnce).to.be.true; expect( - Meteor.callAsync.calledWithExactly( - "minutes.addTopic", - sinon.match.string, - topicDoc, - ), + Meteor.callAsync.calledWithExactly( + "minutes.addTopic", + sinon.match.string, + topicDoc, + ), ); }); @@ -453,11 +470,11 @@ describe("Minutes", () => { minute.upsertTopic(topicDoc); expect(Meteor.callAsync.calledOnce).to.be.true; expect( - Meteor.callAsync.calledWithExactly( - "minutes.addTopic", - topicDoc._id, - topicDoc, - ), + Meteor.callAsync.calledWithExactly( + "minutes.addTopic", + topicDoc._id, + topicDoc, + ), ); }); @@ -467,13 +484,15 @@ describe("Minutes", () => { topicDoc.subject = "changedSubject"; minute.upsertTopic(topicDoc); expect( - minute.topics, - "update an existing topic should not change the size of the topics array", - ).to.have.length(1); + minute.topics, + "update an existing topic should not change the size of the topics array", + ) + .to.have.length(1); expect( - minute.topics[0].subject, - "the subject should have been updated", - ).to.equal(topicDoc.subject); + minute.topics[0].subject, + "the subject should have been updated", + ) + .to.equal(topicDoc.subject); }); it("calls the meteor method minutes.update", () => { @@ -481,24 +500,27 @@ describe("Minutes", () => { expect(Meteor.callAsync.calledOnce).to.be.true; }); - it("sends the minutes id and the topic doc to the meteor method minutes.addTopic", () => { - minute.upsertTopic(topicDoc); - const callArgs = Meteor.callAsync.getCall(0).args; - expect( - callArgs[0], - "first argument should be the name of the meteor method", - "minutes.addTopic", - ); - const sentDoc = callArgs[1]; - expect( - callArgs[1], - "minutes id should be sent to the meteor method", - ).to.equal(minutesDoc._id); - expect( - callArgs[2], - "topic-doc should be sent to the meteor method", - ).to.equal(topicDoc); - }); + it("sends the minutes id and the topic doc to the meteor method minutes.addTopic", + () => { + minute.upsertTopic(topicDoc); + const callArgs = Meteor.callAsync.getCall(0).args; + expect( + callArgs[0], + "first argument should be the name of the meteor method", + "minutes.addTopic", + ); + const sentDoc = callArgs[1]; + expect( + callArgs[1], + "minutes id should be sent to the meteor method", + ) + .to.equal(minutesDoc._id); + expect( + callArgs[2], + "topic-doc should be sent to the meteor method", + ) + .to.equal(topicDoc); + }); }); it("#isCurrentUserModerator", () => { diff --git a/tests/unit/imports/Topic.test.js b/tests/unit/imports/Topic.test.js index e4ec06a91..a11ed33d7 100644 --- a/tests/unit/imports/Topic.test.js +++ b/tests/unit/imports/Topic.test.js @@ -1,5 +1,5 @@ -import { expect } from "chai"; -import { _ } from "lodash"; +import {expect} from "chai"; +import {_} from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -8,19 +8,15 @@ import * as SubElements from "../../../imports/helpers/subElements"; class MeteorError {} const Meteor = { - call: sinon.stub(), - Error: MeteorError, - callAsync: sinon.stub(), - user: () => { - return { username: "unit-test" }; - }, + call : sinon.stub(), + Error : MeteorError, + callAsync : sinon.stub(), + user : () => { return {username : "unit-test"}; }, }; const meetingSeriesId = "AaBbCcDd01"; class MeetingSeries { - constructor(id) { - this._id = id; - } + constructor(id) { this._id = id; } static findOne(id) { if (id === meetingSeriesId) { return dummySeries; @@ -31,9 +27,7 @@ class MeetingSeries { const minuteId = "AaBbCcDd02"; class Minutes { - constructor(id) { - this._id = id; - } + constructor(id) { this._id = id; } upsertTopic() {} static findOne(id) { if (id === minuteId) { @@ -47,89 +41,88 @@ const dummyMinute = new Minutes(minuteId); const dummySeries = new MeetingSeries(meetingSeriesId); const Random = { - i: 1, - id() { - return this.i++; - }, + i : 1, + id() { return this.i++; }, }; SubElements["@noCallThru"] = true; DateHelpers["@noCallThru"] = true; -const { Label } = proxyquire("../../../imports/label", { - "meteor/meteor": { Meteor, "@noCallThru": true }, - lodash: { _, "@noCallThru": true }, +const {Label} = proxyquire("../../../imports/label", { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + lodash : {_, "@noCallThru" : true}, }); -const { InfoItem } = proxyquire("../../../imports/infoitem", { - "meteor/meteor": { Meteor, "@noCallThru": true }, - "meteor/random": { Random, "@noCallThru": true }, - lodash: { _, "@noCallThru": true }, - "/imports/user": { null: null, "@noCallThru": true }, - "/imports/helpers/date": DateHelpers, - "./label": { Label, "@noCallThru": true }, +const {InfoItem} = proxyquire("../../../imports/infoitem", { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "meteor/random" : {Random, "@noCallThru" : true}, + lodash : {_, "@noCallThru" : true}, + "/imports/user" : {null : null, "@noCallThru" : true}, + "/imports/helpers/date" : DateHelpers, + "./label" : {Label, "@noCallThru" : true}, }); -const { ActionItem } = proxyquire("../../../imports/actionitem", { - "meteor/meteor": { Meteor, "@noCallThru": true }, - "./infoitem": { InfoItem, "@noCallThru": true }, +const {ActionItem} = proxyquire("../../../imports/actionitem", { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "./infoitem" : {InfoItem, "@noCallThru" : true}, }); -const { InfoItemFactory } = proxyquire("../../../imports/InfoItemFactory", { - "./infoitem": { InfoItem, "@noCallThru": true }, - "./actionitem": { ActionItem, "@noCallThru": true }, +const {InfoItemFactory} = proxyquire("../../../imports/InfoItemFactory", { + "./infoitem" : {InfoItem, "@noCallThru" : true}, + "./actionitem" : {ActionItem, "@noCallThru" : true}, }); -const { Topic } = proxyquire("../../../imports/topic", { - "meteor/meteor": { Meteor, "@noCallThru": true }, - "meteor/random": { Random, "@noCallThru": true }, - "/imports/helpers/subElements": SubElements, - "./label": { Label, "@noCallThru": true }, - "./infoitem": { InfoItem, "@noCallThru": true }, - "./InfoItemFactory": { InfoItemFactory, "@noCallThru": true }, - "./minutes": { Minutes, "@noCallThru": true }, - "./meetingseries": { MeetingSeries, "@noCallThru": true }, - "./helpers/promisedMethods": { null: null, "@noCallThru": true }, - "./collections/minutes_private": { null: null, "@noCallThru": true }, +const {Topic} = proxyquire("../../../imports/topic", { + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "meteor/random" : {Random, "@noCallThru" : true}, + "/imports/helpers/subElements" : SubElements, + "./label" : {Label, "@noCallThru" : true}, + "./infoitem" : {InfoItem, "@noCallThru" : true}, + "./InfoItemFactory" : {InfoItemFactory, "@noCallThru" : true}, + "./minutes" : {Minutes, "@noCallThru" : true}, + "./meetingseries" : {MeetingSeries, "@noCallThru" : true}, + "./helpers/promisedMethods" : {null : null, "@noCallThru" : true}, + "./collections/minutes_private" : {null : null, "@noCallThru" : true}, }); -describe("Topic", function () { +describe("Topic", function() { let topicDoc; - beforeEach(function () { + beforeEach(function() { topicDoc = { - subject: "topic-subject", - infoItems: [], + subject : "topic-subject", + infoItems : [], }; }); - describe("#constructor", function () { - it("sets the reference to the parent minute correctly", function () { + describe("#constructor", function() { + it("sets the reference to the parent minute correctly", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic._parentMinutes).to.equal(dummyMinute); }); - it("can instantiate a topic with the parent minutes object instead of its id", function () { - const myTopic = new Topic(dummyMinute, topicDoc); - expect(myTopic._parentMinutes).to.equal(dummyMinute); - }); + it("can instantiate a topic with the parent minutes object instead of its id", + function() { + const myTopic = new Topic(dummyMinute, topicDoc); + expect(myTopic._parentMinutes).to.equal(dummyMinute); + }); - it("sets the subject correctly", function () { + it("sets the subject correctly", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic._topicDoc.subject).to.equal(topicDoc.subject); }); - it("sets the initial value of the isOpen-flag correctly", function () { + it("sets the initial value of the isOpen-flag correctly", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic._topicDoc.isOpen).to.be.true; }); - it("sets the initial value of the isNew-flag correctly", function () { + it("sets the initial value of the isNew-flag correctly", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic._topicDoc.isNew).to.be.true; }); - it("enforces infoItems to be of type Array", function () { + it("enforces infoItems to be of type Array", function() { topicDoc.infoItems = "something"; const myTopic = new Topic(dummyMinute._id, topicDoc); @@ -137,95 +130,97 @@ describe("Topic", function () { }); }); - it("#findTopicIndexInArray", function () { - const topicArray = [topicDoc]; + it("#findTopicIndexInArray", function() { + const topicArray = [ topicDoc ]; const index = Topic.findTopicIndexInArray(topicDoc._id, topicArray); expect(index).to.equal(0); }); - describe("#hasOpenActionItem", function () { - it("returns false if the topic does not have any sub items", function () { - expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; - }); - - it("returns true if the topic has at least one open action items", function () { - topicDoc.infoItems.push({ - itemType: "actionItem", - isOpen: false, - }); - topicDoc.infoItems.push({ - itemType: "actionItem", - isOpen: true, - }); - - expect(Topic.hasOpenActionItem(topicDoc)).to.be.true; - }); - - it("returns false if the topic has only closed action items", function () { + describe("#hasOpenActionItem", function() { + it("returns false if the topic does not have any sub items", + function() { expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; }); + + it("returns true if the topic has at least one open action items", + function() { + topicDoc.infoItems.push({ + itemType : "actionItem", + isOpen : false, + }); + topicDoc.infoItems.push({ + itemType : "actionItem", + isOpen : true, + }); + + expect(Topic.hasOpenActionItem(topicDoc)).to.be.true; + }); + + it("returns false if the topic has only closed action items", function() { topicDoc.infoItems.push({ - itemType: "actionItem", - isOpen: false, + itemType : "actionItem", + isOpen : false, }); topicDoc.infoItems.push({ - itemType: "actionItem", - isOpen: false, + itemType : "actionItem", + isOpen : false, }); expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; }); - it("returns false if the topic has only info items (whose open state is unimportant)", function () { - topicDoc.infoItems.push({ - itemType: "infoItem", - isOpen: false, - }); - topicDoc.infoItems.push({ - itemType: "infoItem", - isOpen: true, - }); - topicDoc.infoItems.push({ - itemType: "infoItem", - // isOpen: keep it "undefined"!!! - }); - expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; - }); - - it("returns true if the topic has a open action item (object method call)", function () { - topicDoc.infoItems.push({ - itemType: "actionItem", - isOpen: true, - }); - const myTopic = new Topic(dummyMinute._id, topicDoc); - expect(myTopic.hasOpenActionItem()).to.be.true; - }); + it("returns false if the topic has only info items (whose open state is unimportant)", + function() { + topicDoc.infoItems.push({ + itemType : "infoItem", + isOpen : false, + }); + topicDoc.infoItems.push({ + itemType : "infoItem", + isOpen : true, + }); + topicDoc.infoItems.push({ + itemType : "infoItem", + // isOpen: keep it "undefined"!!! + }); + expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; + }); + + it("returns true if the topic has a open action item (object method call)", + function() { + topicDoc.infoItems.push({ + itemType : "actionItem", + isOpen : true, + }); + const myTopic = new Topic(dummyMinute._id, topicDoc); + expect(myTopic.hasOpenActionItem()).to.be.true; + }); }); - describe("#invalidateIsNewFlag", function () { + describe("#invalidateIsNewFlag", function() { let myTopic; - beforeEach(function () { + beforeEach(function() { topicDoc.isNew = true; topicDoc.infoItems.push({ - isOpen: true, - isNew: true, - itemType: "actionItem", - createdInMinute: dummyMinute._id, + isOpen : true, + isNew : true, + itemType : "actionItem", + createdInMinute : dummyMinute._id, }); myTopic = new Topic(dummyMinute._id, topicDoc); }); - it("clears the isNew-Flag of the topic itself", function () { + it("clears the isNew-Flag of the topic itself", function() { myTopic.invalidateIsNewFlag(); expect(topicDoc.isNew).to.be.false; }); - it("clears the isNew-Flag of the action item", function () { + it("clears the isNew-Flag of the action item", function() { myTopic.invalidateIsNewFlag(); expect(topicDoc.infoItems[0].isNew).to.be.false; }); }); - it("#toggleState", function () { + it("#toggleState", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); const oldState = myTopic._topicDoc.isOpen; @@ -236,71 +231,68 @@ describe("Topic", function () { expect(myTopic._topicDoc.isOpen).to.not.equal(oldState); }); - describe("#isRecurring", function () { + describe("#isRecurring", function() { let myTopic; - beforeEach(function () { - myTopic = new Topic(dummyMinute._id, topicDoc); - }); + beforeEach(function() { myTopic = new Topic(dummyMinute._id, topicDoc); }); - it("sets the default value correctly", function () { - expect(myTopic.isRecurring()).to.be.false; - }); + it("sets the default value correctly", + function() { expect(myTopic.isRecurring()).to.be.false; }); - it("returns the correct value", function () { + it("returns the correct value", function() { myTopic.getDocument().isRecurring = true; expect(myTopic.isRecurring()).to.be.true; }); }); - describe("#toggleRecurring", function () { + describe("#toggleRecurring", function() { let myTopic; - beforeEach(function () { - myTopic = new Topic(dummyMinute._id, topicDoc); - }); + beforeEach(function() { myTopic = new Topic(dummyMinute._id, topicDoc); }); - it("can change the value correctly", function () { + it("can change the value correctly", function() { myTopic.toggleRecurring(); expect(myTopic.isRecurring()).to.be.true; }); - it("can reset the isRecurring-Flag", function () { + it("can reset the isRecurring-Flag", function() { myTopic.toggleRecurring(); myTopic.toggleRecurring(); expect(myTopic.isRecurring()).to.be.false; }); }); - describe("#upsertInfoItem", function () { + describe("#upsertInfoItem", function() { let myTopic; let topicItemDoc; - beforeEach(function () { + beforeEach(function() { myTopic = new Topic(dummyMinute._id, topicDoc); topicItemDoc = { - subject: "info-item-subject", - createdAt: new Date(), + subject : "info-item-subject", + createdAt : new Date(), }; }); - it("adds a new info item to our topic", function () { + it("adds a new info item to our topic", function() { myTopic.upsertInfoItem(topicItemDoc); expect( - myTopic.getInfoItems().length, - "the topic should have exactly one item", - ).to.equal(1); - expect(myTopic.getInfoItems()[0]._id, "the item should have an id").to.not - .be.false; + myTopic.getInfoItems().length, + "the topic should have exactly one item", + ) + .to.equal(1); + expect(myTopic.getInfoItems()[0]._id, "the item should have an id") + .to.not.be.false; expect( - myTopic.getInfoItems()[0].subject, - "the subject should be set correctly", - ).to.equal(topicItemDoc.subject); + myTopic.getInfoItems()[0].subject, + "the subject should be set correctly", + ) + .to.equal(topicItemDoc.subject); }); - it("updates an existing info item", function () { + it("updates an existing info item", function() { myTopic.upsertInfoItem(topicItemDoc); // Change the subject and call the upsertTopicItem method again @@ -310,27 +302,30 @@ describe("Topic", function () { myTopic.upsertInfoItem(topicItem); expect( - myTopic.getInfoItems().length, - "the topic should have exactly one item", - ).to.equal(1); + myTopic.getInfoItems().length, + "the topic should have exactly one item", + ) + .to.equal(1); expect( - myTopic.getInfoItems()[0]._id, - "the item should have an id", - ).to.equal(topicItem._id); + myTopic.getInfoItems()[0]._id, + "the item should have an id", + ) + .to.equal(topicItem._id); expect( - myTopic.getInfoItems()[0].subject, - "the subject should be set correctly", - ).to.equal(topicItem.subject); + myTopic.getInfoItems()[0].subject, + "the subject should be set correctly", + ) + .to.equal(topicItem.subject); }); }); - it("#findInfoItem", function () { + it("#findInfoItem", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); const infoItemDoc = { - _id: "AaBbCcDd01", - subject: "info-item-subject", - createdAt: new Date(), - createdInMinute: dummyMinute._id, + _id : "AaBbCcDd01", + subject : "info-item-subject", + createdAt : new Date(), + createdInMinute : dummyMinute._id, }; // new info item is not added yet, so our topic should not find it @@ -345,23 +340,24 @@ describe("Topic", function () { expect(foundItem, "the result should not be undefined").to.not.equal(); // the subject of the found item should be equal to its initial value expect( - foundItem._infoItemDoc.subject, - "the correct info item should be found", - ).to.equal(infoItemDoc.subject); + foundItem._infoItemDoc.subject, + "the correct info item should be found", + ) + .to.equal(infoItemDoc.subject); }); - it("#removeInfoItem", function () { + it("#removeInfoItem", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); const infoItemDoc = { - _id: "AaBbCcDd01", - subject: "info-item-subject", - createdAt: new Date(), + _id : "AaBbCcDd01", + subject : "info-item-subject", + createdAt : new Date(), }; const infoItemDoc2 = { - _id: "AaBbCcDd02", - subject: "info-item-subject2", - createdAt: new Date(), + _id : "AaBbCcDd02", + subject : "info-item-subject2", + createdAt : new Date(), }; // now we add the info items to our topic @@ -378,93 +374,95 @@ describe("Topic", function () { // check that there are now only one items expect( - diff, - "The length of the info items should be decreased by one", - ).to.equal(1); + diff, + "The length of the info items should be decreased by one", + ) + .to.equal(1); // check that the first item is still part of our topic expect( - myTopic.getInfoItems()[0]._id, - "The other info item should not be removed.", - ).to.equal(infoItemDoc._id); + myTopic.getInfoItems()[0]._id, + "The other info item should not be removed.", + ) + .to.equal(infoItemDoc._id); }); - describe("#tailorTopic", function () { + describe("#tailorTopic", function() { let myTopic; - beforeEach(function () { + beforeEach(function() { topicDoc.infoItems.push({ - subject: "myInfoItem", - createdInMinute: dummyMinute._id, + subject : "myInfoItem", + createdInMinute : dummyMinute._id, }); topicDoc.infoItems.push({ - subject: "myClosedActionItem", - isOpen: false, - itemType: "actionItem", - createdInMinute: dummyMinute._id, + subject : "myClosedActionItem", + isOpen : false, + itemType : "actionItem", + createdInMinute : dummyMinute._id, }); topicDoc.infoItems.push({ - subject: "myOpenActionItem", - isOpen: true, - itemType: "actionItem", - createdInMinute: dummyMinute._id, + subject : "myOpenActionItem", + isOpen : true, + itemType : "actionItem", + createdInMinute : dummyMinute._id, }); myTopic = new Topic(dummyMinute._id, topicDoc); }); - it("removes all info items and closed action items", function () { + it("removes all info items and closed action items", function() { myTopic.tailorTopic(); expect(myTopic.getInfoItems()).to.have.length(1); }); - it("keeps the open action items", function () { + it("keeps the open action items", function() { myTopic.tailorTopic(); expect(myTopic._topicDoc.infoItems[0].isOpen).to.be.true; }); }); - describe("#getOpenActionItems", function () { + describe("#getOpenActionItems", function() { let myTopic; - beforeEach(function () { + beforeEach(function() { topicDoc.infoItems.push({ - subject: "myInfoItem", + subject : "myInfoItem", }); topicDoc.infoItems.push({ - subject: "myClosedActionItem", - isOpen: false, - itemType: "actionItem", + subject : "myClosedActionItem", + isOpen : false, + itemType : "actionItem", }); topicDoc.infoItems.push({ - subject: "myOpenActionItem", - isOpen: true, - itemType: "actionItem", + subject : "myOpenActionItem", + isOpen : true, + itemType : "actionItem", }); topicDoc.infoItems.push({ - subject: "my2ndOpenActionItem", - isOpen: true, - itemType: "actionItem", + subject : "my2ndOpenActionItem", + isOpen : true, + itemType : "actionItem", }); myTopic = new Topic(dummyMinute._id, topicDoc); }); - it("returns the correct amount of items", function () { - expect(myTopic.getOpenActionItems()).to.have.length(2); - }); + it("returns the correct amount of items", + function() { expect(myTopic.getOpenActionItems()).to.have.length(2); }); - it("returns only open action items", function () { + it("returns only open action items", function() { myTopic.getOpenActionItems().forEach((item) => { - expect(item, "the item should be a action item").to.have.ownProperty( - "isOpen", - ); + expect(item, "the item should be a action item") + .to.have.ownProperty( + "isOpen", + ); expect(item.isOpen, "the item should marked as open").to.be.true; }); }); }); - it("#save", function () { + it("#save", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); // the save-method should call the upsertTopic-Method of the parent Minute @@ -473,17 +471,18 @@ describe("Topic", function () { myTopic.save(); - expect(spy.calledOnce, "the upsertTopic method should be called once").to.be - .true; + expect(spy.calledOnce, "the upsertTopic method should be called once") + .to.be.true; expect( - spy.calledWith(myTopic._topicDoc), - "the document should be sent to the upsertTopic method", - ).to.be.true; + spy.calledWith(myTopic._topicDoc), + "the document should be sent to the upsertTopic method", + ) + .to.be.true; spy.restore(); }); - it("#getDocument", function () { + it("#getDocument", function() { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic.getDocument()).to.equal(topicDoc); diff --git a/tests/unit/imports/client/ResponsiblePreparer.test.js b/tests/unit/imports/client/ResponsiblePreparer.test.js index 369c40cc5..b5282ac08 100644 --- a/tests/unit/imports/client/ResponsiblePreparer.test.js +++ b/tests/unit/imports/client/ResponsiblePreparer.test.js @@ -1,56 +1,44 @@ -import { faker } from "@faker-js/faker"; -import { expect } from "chai"; +import {faker} from "@faker-js/faker"; +import {expect} from "chai"; import _ from "lodash"; -import { ParticipantsPreparer } from "../../../../imports/client/ParticipantsPreparer"; -const generateId = () => { - return faker.string.uuid(); -}; +import { + ParticipantsPreparer +} from "../../../../imports/client/ParticipantsPreparer"; -const createUser = (id, username, name) => { - return { _id: id, username, profile: { name } }; -}; +const generateId = () => { return faker.string.uuid(); }; + +const createUser = + (id, username, name) => { return {_id : id, username, profile : {name}}; }; const USER_1 = createUser(generateId(), "user1", "First User"); const USER_2 = createUser(generateId(), "user2", "Second User"); const USER_3 = createUser(generateId(), "user3", "Third User"); -describe("ParticipantsPreparer", function () { - let preparer, - fakeMinutes, - fakeParentSeries, - fakeTopicOrItem, - fakeUserCollection; +describe("ParticipantsPreparer", function() { + let preparer, fakeMinutes, fakeParentSeries, fakeTopicOrItem, + fakeUserCollection; - beforeEach(function () { + beforeEach(function() { fakeMinutes = { - participants: [], - participantsAdditional: "", - parentMeetingSeries: () => { - return fakeParentSeries; - }, + participants : [], + participantsAdditional : "", + parentMeetingSeries : () => { return fakeParentSeries; }, }; - fakeParentSeries = { additionalResponsibles: [] }; + fakeParentSeries = {additionalResponsibles : []}; fakeTopicOrItem = { - _topicDoc: { responsibles: [] }, - hasResponsibles() { - return this._topicDoc.responsibles.length > 0; - }, - getResponsibles() { - return this._topicDoc.responsibles; - }, + _topicDoc : {responsibles : []}, + hasResponsibles() { return this._topicDoc.responsibles.length > 0; }, + getResponsibles() { return this._topicDoc.responsibles; }, }; fakeUserCollection = { - users: [USER_1, USER_2, USER_3], + users : [ USER_1, USER_2, USER_3 ], find(selector) { const excludeIds = selector.$and[0]._id.$nin; - const result = this.users.filter((user) => { - return !_.contains(excludeIds, user._id); - }); + const result = this.users.filter( + (user) => { return !_.contains(excludeIds, user._id); }); return { - fetch: () => { - return result; - }, + fetch : () => { return result; }, }; }, findOne(id) { @@ -64,56 +52,57 @@ describe("ParticipantsPreparer", function () { }; preparer = new ParticipantsPreparer( - fakeMinutes, - fakeTopicOrItem, - fakeUserCollection, + fakeMinutes, + fakeTopicOrItem, + fakeUserCollection, ); preparer._init(); }); - describe("#getPossibleResponsibles", function () { + describe("#getPossibleResponsibles", function() { const ADDITIONAL_RESP_TEXT = "guest"; const ADDITIONAL_RESP_MAIL = "guest@mail.de"; const FORMER_RESP_TEXT = "old guest"; const FORMER_RESP_MAIL = "old_guest@mail.de"; - beforeEach(function () { + beforeEach(function() { fakeMinutes.participants = [ - { userId: USER_2._id }, - { userId: USER_1._id }, + {userId : USER_2._id}, + {userId : USER_1._id}, ]; }); - it("returns all participants of the current minutes", function () { + it("returns all participants of the current minutes", function() { preparer._prepareResponsibles(); const result = preparer.getPossibleResponsibles(); expect(result).to.have.length(2); expect(result).to.deep.include({ - id: USER_1._id, - text: `${USER_1.username} - ${USER_1.profile.name}`, + id : USER_1._id, + text : `${USER_1.username} - ${USER_1.profile.name}`, }); expect(result).to.deep.include({ - id: USER_2._id, - text: `${USER_2.username} - ${USER_2.profile.name}`, + id : USER_2._id, + text : `${USER_2.username} - ${USER_2.profile.name}`, }); }); - it("returns the additional responsible, too", function () { - fakeMinutes.participantsAdditional = `${ADDITIONAL_RESP_TEXT}, ${ADDITIONAL_RESP_MAIL}`; + it("returns the additional responsible, too", function() { + fakeMinutes.participantsAdditional = + `${ADDITIONAL_RESP_TEXT}, ${ADDITIONAL_RESP_MAIL}`; preparer._prepareResponsibles(); const result = preparer.getPossibleResponsibles(); expect(result).to.have.length(4); expect(result).to.deep.include({ - id: ADDITIONAL_RESP_TEXT, - text: ADDITIONAL_RESP_TEXT, + id : ADDITIONAL_RESP_TEXT, + text : ADDITIONAL_RESP_TEXT, }); expect(result).to.deep.include({ - id: ADDITIONAL_RESP_MAIL, - text: ADDITIONAL_RESP_MAIL, + id : ADDITIONAL_RESP_MAIL, + text : ADDITIONAL_RESP_MAIL, }); }); - it("returns the former responsible, too", function () { + it("returns the former responsible, too", function() { fakeParentSeries.additionalResponsibles = [ FORMER_RESP_TEXT, FORMER_RESP_MAIL, @@ -122,41 +111,41 @@ describe("ParticipantsPreparer", function () { const result = preparer.getPossibleResponsibles(); expect(result).to.have.length(4); expect(result).to.deep.include({ - id: FORMER_RESP_TEXT, - text: FORMER_RESP_TEXT, + id : FORMER_RESP_TEXT, + text : FORMER_RESP_TEXT, }); expect(result).to.deep.include({ - id: FORMER_RESP_MAIL, - text: FORMER_RESP_MAIL, + id : FORMER_RESP_MAIL, + text : FORMER_RESP_MAIL, }); }); - it("returns only valid entries from the former/additional responsible if desired", function () { - fakeMinutes.participantsAdditional = `${ADDITIONAL_RESP_TEXT}, ${ADDITIONAL_RESP_MAIL}`; - fakeParentSeries.additionalResponsibles = [ - FORMER_RESP_TEXT, - FORMER_RESP_MAIL, - ]; - preparer.freeTextValidator = (text) => { - return text.includes("@"); - }; - preparer._prepareResponsibles(); - const result = preparer.getPossibleResponsibles(); - expect(result).to.have.length(4); - expect(result).to.deep.include({ - id: ADDITIONAL_RESP_MAIL, - text: ADDITIONAL_RESP_MAIL, - }); - expect(result).to.deep.include({ - id: FORMER_RESP_MAIL, - text: FORMER_RESP_MAIL, - }); - }); + it("returns only valid entries from the former/additional responsible if desired", + function() { + fakeMinutes.participantsAdditional = + `${ADDITIONAL_RESP_TEXT}, ${ADDITIONAL_RESP_MAIL}`; + fakeParentSeries.additionalResponsibles = [ + FORMER_RESP_TEXT, + FORMER_RESP_MAIL, + ]; + preparer.freeTextValidator = (text) => { return text.includes("@"); }; + preparer._prepareResponsibles(); + const result = preparer.getPossibleResponsibles(); + expect(result).to.have.length(4); + expect(result).to.deep.include({ + id : ADDITIONAL_RESP_MAIL, + text : ADDITIONAL_RESP_MAIL, + }); + expect(result).to.deep.include({ + id : FORMER_RESP_MAIL, + text : FORMER_RESP_MAIL, + }); + }); - it("returns also the responsible of the current topic/item", function () { + it("returns also the responsible of the current topic/item", function() { fakeTopicOrItem._topicDoc.responsibles = [ - { id: "free-text-entry", text: "free-text-entry" }, - { id: USER_2._id, text: USER_2.name }, + {id : "free-text-entry", text : "free-text-entry"}, + {id : USER_2._id, text : USER_2.name}, ]; preparer._prepareResponsibles(); const result = preparer.getPossibleResponsibles(); diff --git a/tests/unit/imports/ldap/getLDAPUsers.test.js b/tests/unit/imports/ldap/getLDAPUsers.test.js index 615d02774..6e2cfcf5f 100644 --- a/tests/unit/imports/ldap/getLDAPUsers.test.js +++ b/tests/unit/imports/ldap/getLDAPUsers.test.js @@ -1,19 +1,19 @@ -import { expect } from "chai"; +import {expect} from "chai"; import proxyquire from "proxyquire"; -import { rewiremock } from "../../test-helper/rewiremock"; import sinon from "sinon"; import asyncStubs from "../../../support/lib/asyncStubs"; +import {rewiremock} from "../../test-helper/rewiremock"; import rewiremock from "../../test-helper/rewiremock.cjs"; const ldap = { - createClient: sinon.stub(), + createClient : sinon.stub(), }; const ldapSearchResponseWithResult = { - on: (event, callback) => { + on : (event, callback) => { if (event === "searchEntry") { - callback({ object: { uid: "foo" } }); + callback({object : {uid : "foo"}}); } if (event === "end") { @@ -23,7 +23,7 @@ const ldapSearchResponseWithResult = { }; const ldapSearchResponseWithError = { - on: (event, callback) => { + on : (event, callback) => { if (event === "error") { callback("Some error"); } @@ -34,364 +34,343 @@ const ldapSearchResponseWithError = { // ldapjs: ldap, // }); const getLDAPUsers = rewiremock.proxy("#root/imports/ldap/getLDAPUsers.js", { - ldapjs: ldap, + ldapjs : ldap, }); // skipcq: JS-0241 -describe("getLDAPUsers", function () { +describe("getLDAPUsers", function() { let settings; - const expectedSuccessfulResult = [{ uid: "foo", isInactive: false }]; + const expectedSuccessfulResult = [ {uid : "foo", isInactive : false} ]; // skipcq: JS-0241 - beforeEach(function () { + beforeEach(function() { ldap.createClient.reset(); settings = { - propertyMap: {}, - allowListedFields: [], - inactiveUsers: { - strategy: "none", + propertyMap : {}, + allowListedFields : [], + inactiveUsers : { + strategy : "none", }, }; }); // skipcq: JS-0241 - it("uses ldapjs to connect to ldap and gets users", function (done) { + it("uses ldapjs to connect to ldap and gets users", function(done) { const client = { - search: asyncStubs.returns(2, ldapSearchResponseWithResult), - unbind: asyncStubs.returns(0, {}), + search : asyncStubs.returns(2, ldapSearchResponseWithResult), + unbind : asyncStubs.returns(0, {}), }; ldap.createClient.returns(client); getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users).to.deep.equal(expectedSuccessfulResult); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { - done(error); - }); + .then((result) => { + try { + expect(result.users).to.deep.equal(expectedSuccessfulResult); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { done(error); }); }); // skipcq: JS-0241 - it("handles connection errors to ldap properly", function (done) { + it("handles connection errors to ldap properly", function(done) { ldap.createClient.throws(new Error("Some connection error")); getLDAPUsers(settings) - .then((result) => { - done(new Error(`Unexpected result: ${result}`)); - }) - .catch((error) => { - try { - expect(error).to.equal( - "Error creating client: Error: Some connection error", - ); - done(); - } catch (error) { - done(error); - } - }); - }); - // skipcq: JS-0241 - it("handles ldap search errors properly", function (done) { - const client = { - search: asyncStubs.returns(2, ldapSearchResponseWithError), - unbind: asyncStubs.returns(0, {}), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - done(new Error(`Unexpected result: ${result}`)); - }) - .catch((error) => { - try { - expect(error).to.equal("Some error"); - done(); - } catch (error) { - done(error); - } - }); + .then((result) => { done(new Error(`Unexpected result: ${result}`)); }) + .catch((error) => { + try { + expect(error).to.equal( + "Error creating client: Error: Some connection error", + ); + done(); + } catch (error) { + done(error); + } + }); }); // skipcq: JS-0241 - it("handles ldap search errors properly", function (done) { + it("handles ldap search errors properly", function(done) { const client = { - search: asyncStubs.returns(2, ldapSearchResponseWithError), - unbind: asyncStubs.returns(0, {}), + search : asyncStubs.returns(2, ldapSearchResponseWithError), + unbind : asyncStubs.returns(0, {}), }; ldap.createClient.returns(client); getLDAPUsers(settings) - .then((result) => { - done(new Error(`Unexpected result: ${result}`)); - }) - .catch((error) => { - try { - expect(error).to.equal("Some error"); - done(); - } catch (error) { - done(error); - } - }); + .then((result) => { done(new Error(`Unexpected result: ${result}`)); }) + .catch((error) => { + try { + expect(error).to.equal("Some error"); + done(); + } catch (error) { + done(error); + } + }); }); // skipcq: JS-0241 - it("ignores errors during unbind", function (done) { + it("handles ldap search errors properly", function(done) { const client = { - search: asyncStubs.returns(2, ldapSearchResponseWithResult), - unbind: asyncStubs.returnsError(0, "Some error"), + search : asyncStubs.returns(2, ldapSearchResponseWithError), + unbind : asyncStubs.returns(0, {}), }; ldap.createClient.returns(client); getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users).to.deep.equal(expectedSuccessfulResult); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { - done(new Error(error)); - }); - }); - // skipcq: JS-0241 - describe("legacy inactive user detection settings", function (done) { - let client; - // skipcq: JS-0241 - beforeEach(function () { - ldap.createClient.reset(); - }); - - const ldapSearchResult = (activeValue) => { - return { - on: (event, callback) => { - if (event === "searchEntry") { - callback({ object: { active: activeValue } }); - } - - if (event === "end") { - callback(); - } - }, - }; - }, - settings = { - isInactivePredicate: { - active: "no", - }, - }; - // skipcq: JS-0241 - it("returns user object with isInactive property set to true", function (done) { - const client = { - search: asyncStubs.returns(2, ldapSearchResult("no")), - unbind: asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive).to.deep.equal(true); - done(); - } catch (error) { - done(error); - } - }) + .then((result) => { done(new Error(`Unexpected result: ${result}`)); }) .catch((error) => { - done(error2); - }); - }); - // skipcq: JS-0241 - it("adds property map attributes to allowlist automatically", function (done) { - const s = Object.assign({}, settings, { - propertyMap: { - username: "someweirdAttribute", - email: "anEmailAttribute", - }, - allowListedFields: ["someField"], - }); - const parameters = []; - const client = { - search: asyncStubs.returns(2, ldapSearchResult("no"), parameters), - unbind: asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(s) - .then((result) => { try { - const parametersOfFirstCall = parameters[0], - options = parametersOfFirstCall["1"]; - expect(options.attributes).to.include.members([ - "someweirdAttribute", - "anEmailAttribute", - ]); + expect(error).to.equal("Some error"); done(); } catch (error) { done(error); } - }) - .catch((error) => { - done(error2); }); - }); - // skipcq: JS-0241 - it("returns user object with isInactive property set to false", function (done) { - const client = { - search: asyncStubs.returns(2, ldapSearchResult("yes")), - unbind: asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); + }); + // skipcq: JS-0241 + it("ignores errors during unbind", function(done) { + const client = { + search : asyncStubs.returns(2, ldapSearchResponseWithResult), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); - getLDAPUsers(settings) + getLDAPUsers(settings) .then((result) => { try { - expect(result.users[0].isInactive).to.deep.equal(false); + expect(result.users).to.deep.equal(expectedSuccessfulResult); done(); } catch (error) { done(error); } }) - .catch((error) => { - done(error2); - }); - }); + .catch((error) => { done(new Error(error)); }); }); // skipcq: JS-0241 - describe("inactive user detection strategy: none", function (done) { - const activeUsers = [{ isInactive: false, uid: "foo" }]; + describe("legacy inactive user detection settings", function(done) { + let client; // skipcq: JS-0241 - it("returns user object with isInactive property set to false", function (done) { - const settings = { - inactiveUsers: { - strategy: "none", - }, - }; + beforeEach(function() { ldap.createClient.reset(); }); - const client = { - search: asyncStubs.returns(2, ldapSearchResponseWithResult), - unbind: asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); + const ldapSearchResult = (activeValue) => { + return { + on : (event, callback) => { + if (event === "searchEntry") { + callback({object : {active : activeValue}}); + } - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users).to.deep.equal(activeUsers); - done(); - } catch (error) { - done(error); + if (event === "end") { + callback(); } - }) - .catch((error) => { - done(error2); - }); - }); - // skipcq: JS-0241 - it("uses the none strategy if an invalid strategy is given", function (done) { - const settings = { - inactiveUsers: { - strategy: "doesnotexist", }, }; - - const client = { - search: asyncStubs.returns(2, ldapSearchResponseWithResult), - unbind: asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users).to.deep.equal(activeUsers); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { - done(error2); - }); - }); + }, settings = { + isInactivePredicate : { + active : "no", + }, + }; + // skipcq: JS-0241 + it("returns user object with isInactive property set to true", + function(done) { + const client = { + search : asyncStubs.returns(2, ldapSearchResult("no")), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive).to.deep.equal(true); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { done(error2); }); + }); + // skipcq: JS-0241 + it("adds property map attributes to allowlist automatically", + function(done) { + const s = Object.assign({}, settings, { + propertyMap : { + username : "someweirdAttribute", + email : "anEmailAttribute", + }, + allowListedFields : [ "someField" ], + }); + const parameters = []; + const client = { + search : asyncStubs.returns(2, ldapSearchResult("no"), parameters), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(s) + .then((result) => { + try { + const parametersOfFirstCall = parameters[0], + options = parametersOfFirstCall["1"]; + expect(options.attributes).to.include.members([ + "someweirdAttribute", + "anEmailAttribute", + ]); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { done(error2); }); + }); + // skipcq: JS-0241 + it("returns user object with isInactive property set to false", + function(done) { + const client = { + search : asyncStubs.returns(2, ldapSearchResult("yes")), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive).to.deep.equal(false); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { done(error2); }); + }); + }); + // skipcq: JS-0241 + describe("inactive user detection strategy: none", function(done) { + const activeUsers = [ {isInactive : false, uid : "foo"} ]; + // skipcq: JS-0241 + it("returns user object with isInactive property set to false", + function(done) { + const settings = { + inactiveUsers : { + strategy : "none", + }, + }; + + const client = { + search : asyncStubs.returns(2, ldapSearchResponseWithResult), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users).to.deep.equal(activeUsers); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { done(error2); }); + }); + // skipcq: JS-0241 + it("uses the none strategy if an invalid strategy is given", + function(done) { + const settings = { + inactiveUsers : { + strategy : "doesnotexist", + }, + }; + + const client = { + search : asyncStubs.returns(2, ldapSearchResponseWithResult), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users).to.deep.equal(activeUsers); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { done(error2); }); + }); }); // skipcq: JS-0241 - describe("inactive user detection strategy: UAC", function () { + describe("inactive user detection strategy: UAC", function() { let client; - const activeUsers = false, - inactiveUsers = true, - ldapSearchResponseWithGivenUACValue = (uac) => { - return { - on: (event, callback) => { - if (event === "searchEntry") { - callback({ object: { userAccountControl: uac } }); - } - - if (event === "end") { - callback(); - } - }, - }; - }, - generateTestCase = (value, expectedResult) => { - return (done) => { - const settings = { - inactiveUsers: { - strategy: "userAccountControl", - }, - }; - - client = { - search: asyncStubs.returns( - 2, - ldapSearchResponseWithGivenUACValue(value), - ), - unbind: asyncStubs.returnsError(0, "Some error"), + const activeUsers = false, inactiveUsers = true, + ldapSearchResponseWithGivenUACValue = (uac) => { + return { + on : (event, callback) => { + if (event === "searchEntry") { + callback({object : {userAccountControl : uac}}); + } + + if (event === "end") { + callback(); + } + }, + }; + }, generateTestCase = (value, expectedResult) => { + return (done) => { + const settings = { + inactiveUsers : { + strategy : "userAccountControl", + }, + }; + + client = { + search : asyncStubs.returns( + 2, + ldapSearchResponseWithGivenUACValue(value), + ), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive) + .to.equal(expectedResult); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => done(error)); + }; }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive).to.equal(expectedResult); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => done(error)); - }; - }; // skipcq: JS-0241 - beforeEach(function () { - ldap.createClient.reset(); - }); + beforeEach(function() { ldap.createClient.reset(); }); for (let i = 0; i < 32; ++i) { const value = Math.pow(2, i), - expectedResult = i === 1 ? inactiveUsers : activeUsers; + expectedResult = i === 1 ? inactiveUsers : activeUsers; it( - `uAC property set to ${value}: returns user object with isInactive === ${expectedResult}`, - generateTestCase(value, expectedResult), + `uAC property set to ${ + value}: returns user object with isInactive === ${ + expectedResult}`, + generateTestCase(value, expectedResult), ); } }); // skipcq: JS-0241 - describe("inactive user detection strategy: property", function () { + describe("inactive user detection strategy: property", function() { let client; // skipcq: JS-0241 - beforeEach(function () { - ldap.createClient.reset(); - }); + beforeEach(function() { ldap.createClient.reset(); }); const ldapSearchResponseWithGivenAttribute = (attribute, value) => { return { - on: (event, callback) => { + on : (event, callback) => { if (event === "searchEntry") { - callback({ object: { [attribute]: value } }); + callback({object : {[attribute] : value}}); } if (event === "end") { @@ -401,66 +380,68 @@ describe("getLDAPUsers", function () { }; }; // skipcq: JS-0241 - it("returns isInactive == true if given property is set to requested value", function (done) { - const settings = { - inactiveUsers: { - strategy: "property", - properties: { - active: "1", - }, - }, - }; - - client = { - search: asyncStubs.returns( - 2, - ldapSearchResponseWithGivenAttribute("active", "1"), - ), - unbind: asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive).to.equal(true); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => done(error)); - }); + it("returns isInactive == true if given property is set to requested value", + function(done) { + const settings = { + inactiveUsers : { + strategy : "property", + properties : { + active : "1", + }, + }, + }; + + client = { + search : asyncStubs.returns( + 2, + ldapSearchResponseWithGivenAttribute("active", "1"), + ), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive).to.equal(true); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => done(error)); + }); // skipcq: JS-0241 - it("returns isInactive == false if given property is not set to requested value", function (done) { - const settings = { - inactiveUsers: { - strategy: "property", - properties: { - active: "1", - }, - }, - }; - - client = { - search: asyncStubs.returns( - 2, - ldapSearchResponseWithGivenAttribute("active", "2"), - ), - unbind: asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive).to.equal(false); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => done(error)); - }); + it("returns isInactive == false if given property is not set to requested value", + function(done) { + const settings = { + inactiveUsers : { + strategy : "property", + properties : { + active : "1", + }, + }, + }; + + client = { + search : asyncStubs.returns( + 2, + ldapSearchResponseWithGivenAttribute("active", "2"), + ), + unbind : asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive).to.equal(false); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => done(error)); + }); }); }); diff --git a/tests/unit/imports/priority.test.js b/tests/unit/imports/priority.test.js index 645740240..c53829d64 100644 --- a/tests/unit/imports/priority.test.js +++ b/tests/unit/imports/priority.test.js @@ -1,26 +1,26 @@ -import { expect } from "chai"; +import {expect} from "chai"; import proxyquire from "proxyquire"; import sinon from "sinon"; import rewiremock from "../../test-helper/rewiremock.cjs"; -import { AssertHelper } from "../test-helper/assert-helper"; +import {AssertHelper} from "../test-helper/assert-helper"; const EXPECTED_PRIORITY_MAP = { - 1: "1 - High", - 2: "2", - 3: "3 - Medium", - 4: "4", - 5: "5 - Low", + 1 : "1 - High", + 2 : "2", + 3 : "3 - Medium", + 4 : "4", + 5 : "5 - Low", }; const i18n = { - setLocale: sinon.stub(), - getLocale: sinon.stub(), - __: sinon.stub(), + setLocale : sinon.stub(), + getLocale : sinon.stub(), + __ : sinon.stub(), }; -const { Priority } = rewiremock.proxy("#root/imports/priority", { - "meteor/universe:i18n": { i18n, "@noCallThru": true }, +const {Priority} = rewiremock.proxy("#root/imports/priority", { + "meteor/universe:i18n" : {i18n, "@noCallThru" : true}, }); describe("Priority", () => { @@ -39,22 +39,22 @@ describe("Priority", () => { it("should throw an exception for values below 1", () => { AssertHelper.shouldThrow( - () => new Priority(0), - "Constructor should throw an exception for the value 0", + () => new Priority(0), + "Constructor should throw an exception for the value 0", ); }); it("should throw an exception for values over 5", () => { AssertHelper.shouldThrow( - () => new Priority(6), - "Constructor should throw an exception for the value 6", + () => new Priority(6), + "Constructor should throw an exception for the value 6", ); }); it("should throw an exception for values of an invalid type", () => { AssertHelper.shouldThrow( - () => new Priority("b"), - "Constructor should throw an exception for the value of type string", + () => new Priority("b"), + "Constructor should throw an exception for the value of type string", ); }); }); @@ -69,8 +69,8 @@ describe("Priority", () => { const prio = new Priority(3); prio.value = 7; AssertHelper.shouldThrow( - () => prio.toString(), - "should throw for the value 7", + () => prio.toString(), + "should throw for the value 7", ); }); }); diff --git a/tests/unit/imports/search/ItemsFilter.test.js b/tests/unit/imports/search/ItemsFilter.test.js index 9859729e4..413606427 100644 --- a/tests/unit/imports/search/ItemsFilter.test.js +++ b/tests/unit/imports/search/ItemsFilter.test.js @@ -1,81 +1,80 @@ -import { expect } from "chai"; +import {expect} from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; class MeteorError {} const Meteor = { - Error: MeteorError, + Error : MeteorError, }; -const { ITEM_KEYWORDS } = proxyquire( - "../../../../imports/search/FilterKeywords", +const {ITEM_KEYWORDS} = proxyquire( + "../../../../imports/search/FilterKeywords", - - {}, + {}, ); -const { ItemsFilter } = proxyquire("../../../../imports/search/ItemsFilter", { - lodash: { _, "@noCallThru": true }, - "meteor/meteor": { Meteor, "@noCallThru": true }, - "./FilterKeywords": { ITEM_KEYWORDS, "@noCallThru": true }, +const {ItemsFilter} = proxyquire("../../../../imports/search/ItemsFilter", { + lodash : {_, "@noCallThru" : true}, + "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "./FilterKeywords" : {ITEM_KEYWORDS, "@noCallThru" : true}, }); -import { QueryParserMock } from "./QueryParserMock"; +import {QueryParserMock} from "./QueryParserMock"; // skipcq: JS-0241 -describe("ItemsFilter", function () { +describe("ItemsFilter", function() { let items; let itemsFilter; let parser; // skipcq: JS-0241 - beforeEach(function () { + beforeEach(function() { parser = new QueryParserMock(); itemsFilter = new ItemsFilter(); items = [ - { subject: "one.one", labels: ["L2", "L1"], itemType: "infoItem" }, + {subject : "one.one", labels : [ "L2", "L1" ], itemType : "infoItem"}, { - subject: "one.two", - labels: [], - itemType: "actionItem", - isOpen: true, + subject : "one.two", + labels : [], + itemType : "actionItem", + isOpen : true, }, - { subject: "two.one", labels: ["L1"], itemType: "infoItem" }, - { subject: "two.two", labels: [], itemType: "infoItem" }, + {subject : "two.one", labels : [ "L1" ], itemType : "infoItem"}, + {subject : "two.two", labels : [], itemType : "infoItem"}, { - subject: "two.three", - labels: ["L1"], - itemType: "actionItem", - isOpen: true, - duedate: "2017-06-09", + subject : "two.three", + labels : [ "L1" ], + itemType : "actionItem", + isOpen : true, + duedate : "2017-06-09", }, - { subject: "three.one", labels: [], itemType: "infoItem" }, - { subject: "three.two", labels: [], itemType: "infoItem" }, - { subject: "three.three", labels: [], itemType: "infoItem" }, + {subject : "three.one", labels : [], itemType : "infoItem"}, + {subject : "three.two", labels : [], itemType : "infoItem"}, + {subject : "three.three", labels : [], itemType : "infoItem"}, { - subject: "three.four", - labels: [], - itemType: "actionItem", - isOpen: false, - duedate: "2017-05-30", + subject : "three.four", + labels : [], + itemType : "actionItem", + isOpen : false, + duedate : "2017-05-30", }, ]; }); // skipcq: JS-0241 - it("does not change the original array of items", function () { + it("does not change the original array of items", function() { parser.searchTokens.push("three"); itemsFilter.filter(items, parser); expect(items, "Length of the items array should be 9").have.length(9); }); // skipcq: JS-0241 - it("returns the filtered array of items", function () { + it("returns the filtered array of items", function() { parser.searchTokens.push("three"); const res = itemsFilter.filter(items, parser); expect(res, "Length of the result items array should be 5").have.length(5); }); // skipcq: JS-0241 - it("can filter for multiple search tokens", function () { + it("can filter for multiple search tokens", function() { parser.searchTokens.push("three"); parser.searchTokens.push("two"); const res = itemsFilter.filter(items, parser); @@ -83,29 +82,31 @@ describe("ItemsFilter", function () { expect(res, "Length of the result items array should be 2").have.length(2); }); // skipcq: JS-0241 - it("should return an items array containing only info items matching the search query", function () { - const query = "three"; - parser.searchTokens.push(query); - const res = itemsFilter.filter(items, parser); - let foundAWrongItem = false; - res.forEach((item) => { - if (item.subject.indexOf(query) === -1) { - foundAWrongItem = true; - } - }); - expect( - foundAWrongItem, - "Result array contains info item which does not match the search query", - ).to.be.false; - }); + it("should return an items array containing only info items matching the search query", + function() { + const query = "three"; + parser.searchTokens.push(query); + const res = itemsFilter.filter(items, parser); + let foundAWrongItem = false; + res.forEach((item) => { + if (item.subject.indexOf(query) === -1) { + foundAWrongItem = true; + } + }); + expect( + foundAWrongItem, + "Result array contains info item which does not match the search query", + ) + .to.be.false; + }); // skipcq: JS-0241 - it("can filter for labels", function () { + it("can filter for labels", function() { parser.labelTokens.push("L1"); const res = itemsFilter.filter(items, parser); expect(res, "Length of the result items array should be 3").have.length(3); }); // skipcq: JS-0241 - it("filters case insensitive per default for search tokens", function () { + it("filters case insensitive per default for search tokens", function() { parser.searchTokens.push("THREE"); parser.searchTokens.push("TWO"); const res = itemsFilter.filter(items, parser); @@ -113,7 +114,7 @@ describe("ItemsFilter", function () { expect(res, "Length of the result items array should be 2").have.length(2); }); // skipcq: JS-0241 - it("can enable case sensitive search", function () { + it("can enable case sensitive search", function() { parser.caseSensitive = true; parser.searchTokens.push("THREE"); const res = itemsFilter.filter(items, parser); @@ -122,26 +123,29 @@ describe("ItemsFilter", function () { expect(res, "Length of the result items array should be 0").have.length(0); }); // skipcq: JS-0241 - it("can combine multiple is-filter-tokens as logical AND which is a conjunctive operation", function () { - parser.filterTokens.push({ key: "is", value: "open" }); - parser.filterTokens.push({ key: "is", value: "action" }); - const res = itemsFilter.filter(items, parser); - - expect(res, "Length of the result items array should be 2").have.length(2); - - parser.init(); - parser.filterTokens.push({ key: "is", value: "action" }); - parser.filterTokens.push({ key: "is", value: "open" }); - const res2 = itemsFilter.filter(items, parser); - - expect( - res2, - "The order of the filter tokens should not matter", - ).have.length(2); - }); + it("can combine multiple is-filter-tokens as logical AND which is a conjunctive operation", + function() { + parser.filterTokens.push({key : "is", value : "open"}); + parser.filterTokens.push({key : "is", value : "action"}); + const res = itemsFilter.filter(items, parser); + + expect(res, "Length of the result items array should be 2") + .have.length(2); + + parser.init(); + parser.filterTokens.push({key : "is", value : "action"}); + parser.filterTokens.push({key : "is", value : "open"}); + const res2 = itemsFilter.filter(items, parser); + + expect( + res2, + "The order of the filter tokens should not matter", + ) + .have.length(2); + }); // skipcq: JS-0241 - it("can filter items depending on their due date", function () { - parser.filterTokens.push({ key: "due", value: "2017-" }); + it("can filter items depending on their due date", function() { + parser.filterTokens.push({key : "due", value : "2017-"}); const res = itemsFilter.filter(items, parser); expect(res, "Length of the result items array should be 2").have.length(2); diff --git a/tests/unit/imports/search/QueryParser.test.js b/tests/unit/imports/search/QueryParser.test.js index 4a283b954..46b7e76b6 100644 --- a/tests/unit/imports/search/QueryParser.test.js +++ b/tests/unit/imports/search/QueryParser.test.js @@ -1,137 +1,141 @@ -import { expect } from "chai"; - +import {expect} from "chai"; import _ from "lodash"; - import proxyquire from "proxyquire"; class MeteorError {} const Meteor = { - Error: MeteorError, + Error : MeteorError, }; // No dependecies left to mock. Replace this with normal import for test -const { ITEM_KEYWORDS } = proxyquire( - "../../../../imports/search/FilterKeywords", +const {ITEM_KEYWORDS} = proxyquire( + "../../../../imports/search/FilterKeywords", - { - lodash: { _, "@noCallThru": true }, - }, + { + lodash : {_, "@noCallThru" : true}, + }, ); -const { QueryParser } = proxyquire("../../../../imports/search/QueryParser", { - lodash: { _, "@noCallThru": true }, +const {QueryParser} = proxyquire("../../../../imports/search/QueryParser", { + lodash : {_, "@noCallThru" : true}, - "meteor/meteor": { Meteor, "@noCallThru": true }, + "meteor/meteor" : {Meteor, "@noCallThru" : true}, }); // skipcq: JS-0241 -describe("QueryParser", function () { +describe("QueryParser", function() { let parser; // skipcq: JS-0241 - beforeEach(function () { - parser = new QueryParser(ITEM_KEYWORDS); - }); + beforeEach(function() { parser = new QueryParser(ITEM_KEYWORDS); }); // skipcq: JS-0241 - it("parses a simple query string containing only search tokens correctly", function () { - const QUERY = "hello world"; - parser.parse(QUERY); - const filterTokens = parser.getFilterTokens(); - const labelTokens = parser.getLabelTokens(); - const searchTokens = parser.getSearchTokens(); - - expect(filterTokens, "should contain no filter tokens").to.have.length(0); - expect(labelTokens, "should contain no label tokens").to.have.length(0); - expect(searchTokens, "should contain 2 search tokens").to.have.length(2); - - expect(searchTokens).to.contain("hello"); - expect(searchTokens).to.contain("world"); - }); + it("parses a simple query string containing only search tokens correctly", + function() { + const QUERY = "hello world"; + parser.parse(QUERY); + const filterTokens = parser.getFilterTokens(); + const labelTokens = parser.getLabelTokens(); + const searchTokens = parser.getSearchTokens(); + + expect(filterTokens, "should contain no filter tokens") + .to.have.length(0); + expect(labelTokens, "should contain no label tokens").to.have.length(0); + expect(searchTokens, "should contain 2 search tokens").to.have.length(2); + + expect(searchTokens).to.contain("hello"); + expect(searchTokens).to.contain("world"); + }); // skipcq: JS-0241 - it("parses a simple query string containing only label tokens correctly", function () { - const QUERY = "#label 1 #label zwo"; - parser.parse(QUERY); - - const filterTokens = parser.getFilterTokens(); - const labelTokens = parser.getLabelTokens().map((token) => { - return token.token; - }); - const searchTokens = parser.getSearchTokens(); - - expect(filterTokens, "should contain no filter tokens").to.have.length(0); - expect(labelTokens, "should contain 2 label tokens").to.have.length(2); - expect(searchTokens, "should contain no search tokens").to.have.length(0); - - expect(labelTokens).to.contain("label 1"); - expect(labelTokens).to.contain("label zwo"); - }); + it("parses a simple query string containing only label tokens correctly", + function() { + const QUERY = "#label 1 #label zwo"; + parser.parse(QUERY); + + const filterTokens = parser.getFilterTokens(); + const labelTokens = + parser.getLabelTokens().map((token) => { return token.token; }); + const searchTokens = parser.getSearchTokens(); + + expect(filterTokens, "should contain no filter tokens") + .to.have.length(0); + expect(labelTokens, "should contain 2 label tokens").to.have.length(2); + expect(searchTokens, "should contain no search tokens") + .to.have.length(0); + + expect(labelTokens).to.contain("label 1"); + expect(labelTokens).to.contain("label zwo"); + }); // skipcq: JS-0241 - it("parses a simple query string containing search tokens, keywords and labels correctly", function () { - const QUERY = "hello is:open world #my label"; - parser.parse(QUERY); - const filterTokens = parser.getFilterTokens(); - const labelTokens = parser.getLabelTokens().map((token) => { - return token.token; - }); - const searchTokens = parser.getSearchTokens(); - - expect(filterTokens, "should contain 1 filter tokens").to.have.length(1); - expect(labelTokens, "should contain 1 label token").to.have.length(1); - expect(searchTokens, "should contain 2 search tokens").to.have.length(2); - - expect(searchTokens).to.contain("hello"); - expect(searchTokens).to.contain("world"); - expect(filterTokens).to.deep.contain({ key: "is", value: "open", ids: [] }); - expect(labelTokens).to.contain("my label"); - }); + it("parses a simple query string containing search tokens, keywords and labels correctly", + function() { + const QUERY = "hello is:open world #my label"; + parser.parse(QUERY); + const filterTokens = parser.getFilterTokens(); + const labelTokens = + parser.getLabelTokens().map((token) => { return token.token; }); + const searchTokens = parser.getSearchTokens(); + + expect(filterTokens, "should contain 1 filter tokens").to.have.length(1); + expect(labelTokens, "should contain 1 label token").to.have.length(1); + expect(searchTokens, "should contain 2 search tokens").to.have.length(2); + + expect(searchTokens).to.contain("hello"); + expect(searchTokens).to.contain("world"); + expect(filterTokens) + .to.deep.contain({key : "is", value : "open", ids : []}); + expect(labelTokens).to.contain("my label"); + }); // skipcq: JS-0241 - it("identifies the due-keyword correctly", function () { + it("identifies the due-keyword correctly", function() { const QUERY = "hello due:2017 world"; parser.parse(QUERY); const filterTokens = parser.getFilterTokens(); expect(filterTokens, "should contain 1 filter tokens").to.have.length(1); expect(filterTokens).to.deep.contain({ - key: "due", - value: "2017", - ids: [], + key : "due", + value : "2017", + ids : [], }); }); // skipcq: JS-0241 - it("can query if a specific keyword is set", function () { + it("can query if a specific keyword is set", function() { const QUERY = "hello is:open world #my label"; parser.parse(QUERY); expect(parser.hasKeyword("is", "open")).to.be.true; - expect(parser.hasKeyword({ key: "is" }, "open")).to.be.true; + expect(parser.hasKeyword({key : "is"}, "open")).to.be.true; }); // skipcq: JS-0241 - describe("Query LabelIds", function () { + describe("Query LabelIds", function() { // skipcq: JS-0241 - beforeEach(function () { + beforeEach(function() { parser = new QueryParser(ITEM_KEYWORDS, (labelName) => { if (labelName.split(/\s/).length > 2) { return []; } const length = labelName.length; - return [`${labelName}-${length}`]; + return [ `${labelName}-${length}` ]; }); }); // skipcq: JS-0241 - it("can query the label id for a given name using the passed function", function () { - const QUERY = "#my label hello world"; - parser.parse(QUERY); - const filterTokens = parser.getFilterTokens(); - const labelTokens = parser.getLabelTokens(); - const searchTokens = parser.getSearchTokens(); - - expect(filterTokens, "should contain no filter tokens").to.have.length(0); - expect(labelTokens, "should contain 1 label token").to.have.length(1); - expect(searchTokens, "should contain 2 search tokens").to.have.length(2); - - expect(labelTokens[0].token).to.equal("my label"); - expect(labelTokens).to.deep.contain({ - token: "my label", - ids: ["my label-8"], - }); - }); + it("can query the label id for a given name using the passed function", + function() { + const QUERY = "#my label hello world"; + parser.parse(QUERY); + const filterTokens = parser.getFilterTokens(); + const labelTokens = parser.getLabelTokens(); + const searchTokens = parser.getSearchTokens(); + + expect(filterTokens, "should contain no filter tokens") + .to.have.length(0); + expect(labelTokens, "should contain 1 label token").to.have.length(1); + expect(searchTokens, "should contain 2 search tokens") + .to.have.length(2); + + expect(labelTokens[0].token).to.equal("my label"); + expect(labelTokens).to.deep.contain({ + token : "my label", + ids : [ "my label-8" ], + }); + }); }); }); diff --git a/tests/unit/test-helper/rewiremock.js b/tests/unit/test-helper/rewiremock.js index e1071c8b1..24289b7ec 100644 --- a/tests/unit/test-helper/rewiremock.js +++ b/tests/unit/test-helper/rewiremock.js @@ -2,5 +2,7 @@ import rewiremock from 'rewiremock'; // settings // .... -rewiremock.overrideEntryPoint(module); // this is important. This command is "transfering" this module parent to rewiremock -export { rewiremock }; +rewiremock.overrideEntryPoint( + module); // this is important. This command is "transfering" this module + // parent to rewiremock +export {rewiremock}; From 67711ab79d82fb2155c9fc61a2bd1de9339dc7d4 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 31 May 2024 04:15:14 +0000 Subject: [PATCH 2/2] style: format code with prettier --- client/helpers/submitOnEnter.js | 9 +- .../helpers/tabFilterDatabaseOperations.js | 24 +- imports/ldap/getLDAPUsers.js | 106 +-- imports/ldap/import.js | 48 +- imports/ldap/loadLDAPSettings.js | 52 +- imports/ldap/saveUsers.js | 67 +- imports/priority.js | 28 +- .../exportimport/expImpFilesAttachments.js | 94 +-- .../exportimport/expImpFilesDocuments.js | 104 +-- .../exportimport/expImpMeetingseries.js | 97 +-- imports/server/exportimport/expImpMinutes.js | 144 ++-- imports/server/exportimport/expImpSchema.js | 149 ++-- imports/server/exportimport/expImpTopics.js | 85 ++- imports/server/exportimport/expImpUsers.js | 222 +++--- private/createTestUsers.js | 46 +- private/exportMeetingSeries.js | 72 +- private/importMeetingSeries.js | 108 ++- programs/generateLicenseList.js | 255 ++++--- .../unit/client/helpers/submitOnEnter.test.js | 81 ++- tests/unit/imports/ActionItem.test.js | 94 +-- tests/unit/imports/GlobalSettings.test.js | 191 +++-- tests/unit/imports/InfoItem.test.js | 108 ++- tests/unit/imports/InfoItemFactory.test.js | 93 ++- tests/unit/imports/MeetingSeries.test.js | 166 ++--- tests/unit/imports/Minutes.test.js | 444 ++++++------ tests/unit/imports/Topic.test.js | 429 +++++------ .../client/ResponsiblePreparer.test.js | 154 ++-- tests/unit/imports/ldap/getLDAPUsers.test.js | 671 +++++++++--------- tests/unit/imports/priority.test.js | 40 +- tests/unit/imports/search/ItemsFilter.test.js | 144 ++-- tests/unit/imports/search/QueryParser.test.js | 184 +++-- tests/unit/test-helper/rewiremock.js | 9 +- 32 files changed, 2288 insertions(+), 2230 deletions(-) diff --git a/client/helpers/submitOnEnter.js b/client/helpers/submitOnEnter.js index 582a308b9..e52361115 100644 --- a/client/helpers/submitOnEnter.js +++ b/client/helpers/submitOnEnter.js @@ -1,4 +1,4 @@ -import jQuery from 'jquery'; +import jQuery from "jquery"; window.$ = window.jQuery = jQuery; /** @@ -33,7 +33,8 @@ function createHandler(action) { * @param {Array} textareas - An array of textarea elements. * @param {Function} action - The action to be triggered on keyup event. */ -export default function(textareas, action) { - textareas.forEach( - (input) => { window.$(input).on("keyup", createHandler(action)); }); +export default function (textareas, action) { + textareas.forEach((input) => { + window.$(input).on("keyup", createHandler(action)); + }); } diff --git a/client/templates/meetingseries/helpers/tabFilterDatabaseOperations.js b/client/templates/meetingseries/helpers/tabFilterDatabaseOperations.js index edac1768b..35d978aa7 100644 --- a/client/templates/meetingseries/helpers/tabFilterDatabaseOperations.js +++ b/client/templates/meetingseries/helpers/tabFilterDatabaseOperations.js @@ -1,16 +1,18 @@ -import {Meteor} from "meteor/meteor"; +import { Meteor } from "meteor/meteor"; -import {Label} from "../imports/label"; +import { Label } from "../imports/label"; export function createLabelIdsReceiver(parentMeetingSeriesId) { return function getLabelIdsByName(labelName, caseSensitive) { const label = Label.findLabelsContainingSubstring( - parentMeetingSeriesId, - labelName, - caseSensitive, + parentMeetingSeriesId, + labelName, + caseSensitive, ); if (label !== null) { - return label.map((label) => { return label._id; }); + return label.map((label) => { + return label._id; + }); } return null; }; @@ -18,11 +20,13 @@ export function createLabelIdsReceiver(parentMeetingSeriesId) { export function createUserIdsReceiver(userName) { const users = - userName === "me" - ? [ Meteor.user() ] - : Meteor.users.find({username : {$regex : userName}}).fetch(); + userName === "me" + ? [Meteor.user()] + : Meteor.users.find({ username: { $regex: userName } }).fetch(); if (users) { - return users.map((user) => { return user._id; }); + return users.map((user) => { + return user._id; + }); } return []; diff --git a/imports/ldap/getLDAPUsers.js b/imports/ldap/getLDAPUsers.js index 3831b0384..1b58d1c5c 100644 --- a/imports/ldap/getLDAPUsers.js +++ b/imports/ldap/getLDAPUsers.js @@ -1,44 +1,46 @@ import ldap from "ldapjs"; import _ from "lodash"; -const _createLDAPClient = (settings) => new Promise((resolve, reject) => { - try { - const client = ldap.createClient({ - url : settings.serverUrl, - }); - - resolve({ - client, - settings, - }); - } catch (error) { - reject(`Error creating client: ${error}`); - } -}); +const _createLDAPClient = (settings) => + new Promise((resolve, reject) => { + try { + const client = ldap.createClient({ + url: settings.serverUrl, + }); -const _bind = (connection) => new Promise((resolve, reject) => { - const client = connection.client; - const settings = connection.settings; - const auth = settings.authentication; - const userDn = auth?.userDn; - const password = auth?.password; - - // no authentication details provided - // => the ldap server probably allows anonymous access - if (!userDn || !password) { - resolve(connection); - return; - } + resolve({ + client, + settings, + }); + } catch (error) { + reject(`Error creating client: ${error}`); + } + }); - client.bind(userDn, password, (error) => { - if (error) { - reject(error); +const _bind = (connection) => + new Promise((resolve, reject) => { + const client = connection.client; + const settings = connection.settings; + const auth = settings.authentication; + const userDn = auth?.userDn; + const password = auth?.password; + + // no authentication details provided + // => the ldap server probably allows anonymous access + if (!userDn || !password) { + resolve(connection); return; } - resolve(connection); + client.bind(userDn, password, (error) => { + if (error) { + reject(error); + return; + } + + resolve(connection); + }); }); -}); const inactivityStrategies = { userAccountControl(inactivitySettings, entry) { @@ -54,13 +56,15 @@ const inactivityStrategies = { return result || entry.object[key] === inactiveProperties[key]; }, false); }, - none() { return false; }, + none() { + return false; + }, }; function isInactive(inactivitySettings, entry) { const strategy = inactivitySettings?.strategy || "none"; const strategyFunction = - inactivityStrategies[strategy] || inactivityStrategies.none; + inactivityStrategies[strategy] || inactivityStrategies.none; return strategyFunction(inactivitySettings, entry); } @@ -71,9 +75,9 @@ const _fetchLDAPUsers = (connection) => { const base = settings.serverDn; const searchDn = _.get(settings, "propertyMap.username", "cn"); const userLongNameAttribute = _.get( - settings, - "propertyMap.longname", - searchDn, + settings, + "propertyMap.longname", + searchDn, ); const emailAttribute = _.get(settings, "propertyMap.email", searchDn); const filter = `(&(${searchDn}=*)${settings.searchFilter})`; @@ -85,32 +89,35 @@ const _fetchLDAPUsers = (connection) => { userLongNameAttribute, emailAttribute, ]); - const options = {filter, scope, attributes, paged : true}; + const options = { filter, scope, attributes, paged: true }; if (settings.isInactivePredicate && !settings.inactiveUsers) { settings.inactiveUsers = { - strategy : "property", - properties : settings.isInactivePredicate, + strategy: "property", + properties: settings.isInactivePredicate, }; } return new Promise((resolve, reject) => { try { client.search(base, options, (error, response) => { - if (error) - reject(`Search failed: ${error}`); + if (error) reject(`Search failed: ${error}`); const entries = []; response.on("searchEntry", (entry) => { const userIsInactive = isInactive(settings.inactiveUsers, entry); const userData = Object.assign({}, entry.object, { - isInactive : userIsInactive, + isInactive: userIsInactive, }); entries.push(userData); }); - response.on("error", (error) => { reject(error); }); - response.on("end", () => { resolve({client, settings, entries}); }); + response.on("error", (error) => { + reject(error); + }); + response.on("end", () => { + resolve({ client, settings, entries }); + }); }); } catch (error) { reject(error); @@ -127,18 +134,19 @@ const _closeLDAPClient = (connection) => { client.unbind(() => { // even if disconnect fails: we still have the users // ignore the error and return the users - resolve({settings, users}); + resolve({ settings, users }); }); }); }; -const getLDAPUsers = (settings) => new Promise((resolve, reject) => { - _createLDAPClient(settings) +const getLDAPUsers = (settings) => + new Promise((resolve, reject) => { + _createLDAPClient(settings) .then(_bind) .then(_fetchLDAPUsers) .then(_closeLDAPClient) .then(resolve) .catch(reject); -}); + }); export default getLDAPUsers; diff --git a/imports/ldap/import.js b/imports/ldap/import.js index c0ea35155..f8b2e9d06 100644 --- a/imports/ldap/import.js +++ b/imports/ldap/import.js @@ -2,32 +2,34 @@ import getLDAPUsers from "./getLDAPUsers"; import saveUsers from "./saveUsers"; const report = (bulkResult) => { - let inserted = bulkResult.nUpserted, updated = bulkResult.nModified; + let inserted = bulkResult.nUpserted, + updated = bulkResult.nModified; console.log( - `Successfully inserted ${inserted} users and updated ${updated} users.`, + `Successfully inserted ${inserted} users and updated ${updated} users.`, ); }; let selfSignedTLSAllowed = process.env.NODE_TLS_REJECT_UNAUTHORIZED; let importLock = false; -const setSelfSigned = (ldapSettings) => new Promise((resolve, reject) => { - if (importLock) { - reject("There already is a user import running."); - return; - } +const setSelfSigned = (ldapSettings) => + new Promise((resolve, reject) => { + if (importLock) { + reject("There already is a user import running."); + return; + } - importLock = true; + importLock = true; - const allowSelfSignedTLS = ldapSettings.allowSelfSignedTLS; - selfSignedTLSAllowed = process.env.NODE_TLS_REJECT_UNAUTHORIZED; + const allowSelfSignedTLS = ldapSettings.allowSelfSignedTLS; + selfSignedTLSAllowed = process.env.NODE_TLS_REJECT_UNAUTHORIZED; - if (allowSelfSignedTLS) { - process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; - } + if (allowSelfSignedTLS) { + process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; + } - resolve(ldapSettings); -}); + resolve(ldapSettings); + }); const resetSelfSigned = () => { process.env.NODE_TLS_REJECT_UNAUTHORIZED = selfSignedTLSAllowed; @@ -44,13 +46,13 @@ const handleRejection = (error) => { }; const importUsers = (ldapSettings, mongoUrl) => - setSelfSigned(ldapSettings) - .then(getLDAPUsers) - .then((data) => { - return saveUsers(data.settings, mongoUrl, data.users); - }) - .then(report) - .then(resetSelfSigned) - .catch(handleRejection); + setSelfSigned(ldapSettings) + .then(getLDAPUsers) + .then((data) => { + return saveUsers(data.settings, mongoUrl, data.users); + }) + .then(report) + .then(resetSelfSigned) + .catch(handleRejection); export default importUsers; diff --git a/imports/ldap/loadLDAPSettings.js b/imports/ldap/loadLDAPSettings.js index 9bfd4613c..f69384fd9 100644 --- a/imports/ldap/loadLDAPSettings.js +++ b/imports/ldap/loadLDAPSettings.js @@ -1,35 +1,41 @@ import fs from "fs"; -const _readSettingsFile = (filename) => new Promise((resolve, reject) => { - fs.readFile(filename, "utf8", (error, data) => { - if (error) { - reject(`Could not read settings file "${filename}"`); - } else { +const _readSettingsFile = (filename) => + new Promise((resolve, reject) => { + fs.readFile(filename, "utf8", (error, data) => { + if (error) { + reject(`Could not read settings file "${filename}"`); + } else { + resolve(data); + } + }); + }); + +const _parseJSON = (json) => + new Promise((resolve, reject) => { + try { + const data = JSON.parse(json); resolve(data); + } catch (error) { + reject("Could not parse json."); } }); -}); - -const _parseJSON = (json) => new Promise((resolve, reject) => { - try { - const data = JSON.parse(json); - resolve(data); - } catch (error) { - reject("Could not parse json."); - } -}); -const _property = (property, object) => new Promise((resolve, reject) => { - const sub = object[property]; - return sub ? resolve(sub) : reject(`Property "${property}" not found.`); -}); +const _property = (property, object) => + new Promise((resolve, reject) => { + const sub = object[property]; + return sub ? resolve(sub) : reject(`Property "${property}" not found.`); + }); -const loadLDAPSettings = (filename) => new Promise((resolve, reject) => { - _readSettingsFile(filename) +const loadLDAPSettings = (filename) => + new Promise((resolve, reject) => { + _readSettingsFile(filename) .then(_parseJSON) - .then((settings) => { return _property("ldap", settings); }) + .then((settings) => { + return _property("ldap", settings); + }) .then(resolve) .catch(reject); -}); + }); export default loadLDAPSettings; diff --git a/imports/ldap/saveUsers.js b/imports/ldap/saveUsers.js index 009f804c8..45059fec0 100644 --- a/imports/ldap/saveUsers.js +++ b/imports/ldap/saveUsers.js @@ -1,13 +1,13 @@ -import {_} from "lodash"; +import { _ } from "lodash"; import mongoUriParser from "mongo-uri"; -import {MongoClient as mongo} from "mongodb"; +import { MongoClient as mongo } from "mongodb"; -import {Random} from "../../tests/performance/fixtures/lib/random"; +import { Random } from "../../tests/performance/fixtures/lib/random"; import transformUser from "./transformUser"; const _transformUsers = (settings, users) => - _.map(users, (user) => transformUser(settings, user)); + _.map(users, (user) => transformUser(settings, user)); const _connectMongo = (mongoUrl) => mongo.connect(mongoUrl); @@ -20,46 +20,49 @@ const _insertUsers = (client, mongoUri, users) => { // string length: // https://github.com/meteor/meteor/blob/release/METEOR%401.4.0.1/packages/random/random.js#L197 const randomStringConfig = { - length : 17, - charset : "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", + length: 17, + charset: "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", }; return new Promise((resolve, reject) => { try { const mongoConnection = mongoUriParser.parse(mongoUri); - const bulk = client.db(mongoConnection.database) - .collection("users") - .initializeUnorderedBulkOp(); + const bulk = client + .db(mongoConnection.database) + .collection("users") + .initializeUnorderedBulkOp(); _.forEach(users, (user) => { if (user?.username && user.emails[0] && user.emails[0].address) { user.isLDAPuser = true; const usrRegExp = new RegExp( - `^${RegExp.escape(user.username)}$`, - "i", + `^${RegExp.escape(user.username)}$`, + "i", ); - bulk.find({username : usrRegExp}).upsert().updateOne({ - $setOnInsert : { - _id : Random.generateId(), - // by setting this only on insert we won't log out everyone - // everytime we sync the users - services : { - password : {bcrypt : ""}, - resume : {loginTokens : []}, + bulk + .find({ username: usrRegExp }) + .upsert() + .updateOne({ + $setOnInsert: { + _id: Random.generateId(), + // by setting this only on insert we won't log out everyone + // everytime we sync the users + services: { + password: { bcrypt: "" }, + resume: { loginTokens: [] }, + }, }, - }, - $set : user, - }); + $set: user, + }); } else { const stringifiedUser = JSON.stringify(user, null, 2); console.log( - `SKIPPED INVALID USER (no username or no valid emails[0].address): ${ - stringifiedUser}`, + `SKIPPED INVALID USER (no username or no valid emails[0].address): ${stringifiedUser}`, ); } }); const bulkResult = bulk.execute(); - resolve({client, bulkResult}); + resolve({ client, bulkResult }); } catch (error) { reject(error); } @@ -67,7 +70,9 @@ const _insertUsers = (client, mongoUri, users) => { }; const _closeMongo = (data) => { - let force = false, client = data.client, result = data.bulkResult; + let force = false, + client = data.client, + result = data.bulkResult; return new Promise((resolve) => { client.close(force); @@ -80,10 +85,12 @@ const saveUsers = (settings, mongoUrl, users) => { return new Promise((resolve, reject) => { _connectMongo(mongoUrl) - .then((client) => { return _insertUsers(client, mongoUrl, dbUsers); }) - .then(_closeMongo) - .then(resolve) - .catch(reject); + .then((client) => { + return _insertUsers(client, mongoUrl, dbUsers); + }) + .then(_closeMongo) + .then(resolve) + .catch(reject); }); }; diff --git a/imports/priority.js b/imports/priority.js index 6d0335b87..46add4e15 100644 --- a/imports/priority.js +++ b/imports/priority.js @@ -1,15 +1,15 @@ import assert from "assert"; -import {i18n} from "meteor/universe:i18n"; +import { i18n } from "meteor/universe:i18n"; // #I18N - Attention: the below strings with longer texts will be never be used // in UI! Instead they will be pulled from translation language files via // toString() method below const PRIORITY_MAP = { - 1 : "1 - High", - 2 : "2", - 3 : "3 - Medium", - 4 : "4", - 5 : "5 - Low", + 1: "1 - High", + 2: "2", + 3: "3 - Medium", + 4: "4", + 5: "5 - Low", }; /** @@ -23,7 +23,9 @@ const PRIORITY_MAP = { * the highest priority and 5 is the lowest priority. */ export class Priority { - static GET_DEFAULT_PRIORITY() { return new Priority(3); } + static GET_DEFAULT_PRIORITY() { + return new Priority(3); + } static GET_PRIORITIES() { return Object.keys(PRIORITY_MAP).map((value) => new Priority(value)); @@ -46,12 +48,12 @@ export class Priority { toString() { if (Object.prototype.hasOwnProperty.call(PRIORITY_MAP, this.value)) { switch (this.value) { - case 1: - return i18n.__("Item.Priorities.high"); - case 3: - return i18n.__("Item.Priorities.medium"); - case 5: - return i18n.__("Item.Priorities.low"); + case 1: + return i18n.__("Item.Priorities.high"); + case 3: + return i18n.__("Item.Priorities.medium"); + case 5: + return i18n.__("Item.Priorities.low"); } return PRIORITY_MAP[this.value]; } diff --git a/imports/server/exportimport/expImpFilesAttachments.js b/imports/server/exportimport/expImpFilesAttachments.js index 12546fc79..f8b49737f 100644 --- a/imports/server/exportimport/expImpFilesAttachments.js +++ b/imports/server/exportimport/expImpFilesAttachments.js @@ -1,32 +1,34 @@ -import {EJSON} from "bson"; +import { EJSON } from "bson"; import fs from "fs"; class ExpImpFilesAttachments { - static get FILENAME_POSTFIX() { return "_filesAttachments.json"; } + static get FILENAME_POSTFIX() { + return "_filesAttachments.json"; + } static doExport(db, msID, userIDs) { return new Promise((resolve, reject) => { db.collection("AttachmentsCollection") - .find({"meta.parentseries_id" : msID}) - .toArray() - .then((doc) => { - if (doc) { - const attFile = msID + ExpImpFilesAttachments.FILENAME_POSTFIX; - fs.writeFileSync(attFile, EJSON.stringify(doc, null, 2)); + .find({ "meta.parentseries_id": msID }) + .toArray() + .then((doc) => { + if (doc) { + const attFile = msID + ExpImpFilesAttachments.FILENAME_POSTFIX; + fs.writeFileSync(attFile, EJSON.stringify(doc, null, 2)); + console.log( + `Saved: ${attFile} with ${doc.length} file attachments`, + ); + if (doc[0]) { console.log( - `Saved: ${attFile} with ${doc.length} file attachments`, + " *** Hint *** Please manually copy all files below:", ); - if (doc[0]) { - console.log( - " *** Hint *** Please manually copy all files below:", - ); - console.log(` ${doc[0]._storagePath}`); - } - resolve({db, userIDs}); - return; + console.log(` ${doc[0]._storagePath}`); } - return reject(`Unknown meeting series ID: ${msID}`); - }); + resolve({ db, userIDs }); + return; + } + return reject(`Unknown meeting series ID: ${msID}`); + }); }); } @@ -36,7 +38,7 @@ class ExpImpFilesAttachments { let AllAttachmentsDoc = undefined; try { AllAttachmentsDoc = EJSON.parse( - fs.readFileSync(attachmentFile, "utf8"), + fs.readFileSync(attachmentFile, "utf8"), ); if (!AllAttachmentsDoc) { return reject(`Could not read attachment file ${attachmentFile}`); @@ -50,33 +52,37 @@ class ExpImpFilesAttachments { for (let a = 0; a < AllAttachmentsDoc.length; a++) { attachmentIDs.push(AllAttachmentsDoc[a]._id); AllAttachmentsDoc[a] = ExpImpFilesAttachments.patchUsers( - AllAttachmentsDoc[a], - usrMap, + AllAttachmentsDoc[a], + usrMap, ); } - return db.collection("AttachmentsCollection") - .deleteMany({ - _id : {$in : attachmentIDs}, - }) // delete existing attachments with same IDs - .then((res) => { - if (res.result && !res.result.ok) { - console.log(res); - } - return db.collection("AttachmentsCollection") - .insertMany(AllAttachmentsDoc) // insert imported minutes - .then((res) => { - if (res.result.ok === 1 && - res.result.n === AllAttachmentsDoc.length) { - console.log( - `OK, inserted ${res.result.n} attachments meta data.`, - ); - resolve({db, usrMap}); - } else { - reject("Could not insert attachment meta data"); - } - }); - }); + return db + .collection("AttachmentsCollection") + .deleteMany({ + _id: { $in: attachmentIDs }, + }) // delete existing attachments with same IDs + .then((res) => { + if (res.result && !res.result.ok) { + console.log(res); + } + return db + .collection("AttachmentsCollection") + .insertMany(AllAttachmentsDoc) // insert imported minutes + .then((res) => { + if ( + res.result.ok === 1 && + res.result.n === AllAttachmentsDoc.length + ) { + console.log( + `OK, inserted ${res.result.n} attachments meta data.`, + ); + resolve({ db, usrMap }); + } else { + reject("Could not insert attachment meta data"); + } + }); + }); }); } diff --git a/imports/server/exportimport/expImpFilesDocuments.js b/imports/server/exportimport/expImpFilesDocuments.js index e1f791554..75cd7f260 100644 --- a/imports/server/exportimport/expImpFilesDocuments.js +++ b/imports/server/exportimport/expImpFilesDocuments.js @@ -1,38 +1,39 @@ -import {EJSON} from "bson"; +import { EJSON } from "bson"; import fs from "fs"; class ExpImpFilesDocuments { - static get FILENAME_POSTFIX() { return "_filesDocuments.json"; } + static get FILENAME_POSTFIX() { + return "_filesDocuments.json"; + } static doExport(db, msID, userIDs) { return new Promise((resolve, reject) => { db.collection("DocumentsCollection") - .find({"meta.meetingSeriesId" : msID}) - .toArray() - .then((doc) => { - if (doc) { - const protFile = msID + ExpImpFilesDocuments.FILENAME_POSTFIX; - fs.writeFileSync(protFile, EJSON.stringify(doc, null, 2)); + .find({ "meta.meetingSeriesId": msID }) + .toArray() + .then((doc) => { + if (doc) { + const protFile = msID + ExpImpFilesDocuments.FILENAME_POSTFIX; + fs.writeFileSync(protFile, EJSON.stringify(doc, null, 2)); + console.log( + `Saved: ${protFile} with ${doc.length} protocol documents`, + ); + if (doc[0]) { console.log( - `Saved: ${protFile} with ${doc.length} protocol documents`, + " *** Hint *** Please manually copy all files below:", + ); + console.log( + ` ${doc[0]._storagePath.substring( + 0, + doc[0]._storagePath.lastIndexOf("/"), + )}`, ); - if (doc[0]) { - console.log( - " *** Hint *** Please manually copy all files below:", - ); - console.log( - ` ${ - doc[0]._storagePath.substring( - 0, - doc[0]._storagePath.lastIndexOf("/"), - )}`, - ); - } - resolve({db, userIDs}); - return; } - return reject(`Unknown meeting series ID: ${msID}`); - }); + resolve({ db, userIDs }); + return; + } + return reject(`Unknown meeting series ID: ${msID}`); + }); }); } @@ -54,34 +55,37 @@ class ExpImpFilesDocuments { for (let p = 0; p < AllProtocolsDoc.length; p++) { protcolsIDs.push(AllProtocolsDoc[p]._id); AllProtocolsDoc[p] = ExpImpFilesDocuments.patchUsers( - AllProtocolsDoc[p], - usrMap, + AllProtocolsDoc[p], + usrMap, ); } - return db.collection("DocumentsCollection") - .deleteMany({ - _id : {$in : protcolsIDs}, - }) // delete existing attachments with same IDs - .then((res) => { - if (res.result && !res.result.ok) { - console.log(res); - } - return db.collection("DocumentsCollection") - .insertMany(AllProtocolsDoc) // insert imported minutes - .then((res) => { - if (res.result.ok === 1 && - res.result.n === AllProtocolsDoc.length) { - console.log( - `OK, inserted ${ - res.result.n} protocol files meta data.`, - ); - resolve({db, usrMap}); - } else { - reject("Could not insert protocol files meta data"); - } - }); - }); + return db + .collection("DocumentsCollection") + .deleteMany({ + _id: { $in: protcolsIDs }, + }) // delete existing attachments with same IDs + .then((res) => { + if (res.result && !res.result.ok) { + console.log(res); + } + return db + .collection("DocumentsCollection") + .insertMany(AllProtocolsDoc) // insert imported minutes + .then((res) => { + if ( + res.result.ok === 1 && + res.result.n === AllProtocolsDoc.length + ) { + console.log( + `OK, inserted ${res.result.n} protocol files meta data.`, + ); + resolve({ db, usrMap }); + } else { + reject("Could not insert protocol files meta data"); + } + }); + }); }); } diff --git a/imports/server/exportimport/expImpMeetingseries.js b/imports/server/exportimport/expImpMeetingseries.js index c2f6fa9c9..cf94c46e4 100644 --- a/imports/server/exportimport/expImpMeetingseries.js +++ b/imports/server/exportimport/expImpMeetingseries.js @@ -1,63 +1,76 @@ -import {EJSON} from "bson"; +import { EJSON } from "bson"; import fs from "fs"; class ExpImpMeetingSeries { - static get FILENAME_POSTFIX() { return "_meetingSeries.json"; } + static get FILENAME_POSTFIX() { + return "_meetingSeries.json"; + } static doExport(db, msID) { return new Promise((resolve, reject) => { const userIDs = {}; - db.collection("meetingSeries").findOne({_id : msID}).then((doc) => { - if (doc) { - const msFile = msID + ExpImpMeetingSeries.FILENAME_POSTFIX; - fs.writeFileSync(msFile, EJSON.stringify(doc, null, 2)); - console.log(`Saved: ${msFile}`); - doc.visibleFor?.map((userID) => { userIDs[userID] = 1; }); - doc.informedUsers?.map((userID) => { userIDs[userID] = 1; }); - resolve({db, userIDs}); - return; - } - return reject(`Unknown meeting series ID: ${msID}`); - }); + db.collection("meetingSeries") + .findOne({ _id: msID }) + .then((doc) => { + if (doc) { + const msFile = msID + ExpImpMeetingSeries.FILENAME_POSTFIX; + fs.writeFileSync(msFile, EJSON.stringify(doc, null, 2)); + console.log(`Saved: ${msFile}`); + doc.visibleFor?.map((userID) => { + userIDs[userID] = 1; + }); + doc.informedUsers?.map((userID) => { + userIDs[userID] = 1; + }); + resolve({ db, userIDs }); + return; + } + return reject(`Unknown meeting series ID: ${msID}`); + }); }); } static doImport(db, msID, usrMap) { return new Promise((resolve, reject) => { - db.collection("meetingSeries").findOne({_id : msID}).then((doc) => { - if (doc) { - return reject( + db.collection("meetingSeries") + .findOne({ _id: msID }) + .then((doc) => { + if (doc) { + return reject( `Meeting series with ID: ${msID} already exists. Cannot import.`, - ); - } - const msFile = msID + ExpImpMeetingSeries.FILENAME_POSTFIX; - let msDoc = undefined; - try { - msDoc = EJSON.parse(fs.readFileSync(msFile, "utf8")); - if (!msDoc) { + ); + } + const msFile = msID + ExpImpMeetingSeries.FILENAME_POSTFIX; + let msDoc = undefined; + try { + msDoc = EJSON.parse(fs.readFileSync(msFile, "utf8")); + if (!msDoc) { + return reject(`Could not read meeting series file ${msFile}`); + } + } catch (e) { return reject(`Could not read meeting series file ${msFile}`); } - } catch (e) { - return reject(`Could not read meeting series file ${msFile}`); - } - - // Replace old user IDs with new users IDs - for (let i = 0; i < msDoc.visibleFor.length; i++) { - msDoc.visibleFor[i] = usrMap[msDoc.visibleFor[i]]; - } - for (let i = 0; i < msDoc.informedUsers.length; i++) { - msDoc.informedUsers[i] = usrMap[msDoc.informedUsers[i]]; - } - return db.collection("meetingSeries").insert(msDoc).then((res) => { - if (res.result.ok === 1) { - console.log(`OK, inserted meeting series with ID: ${msID}`); - resolve({db, usrMap}); - } else { - reject(`Could not insert meeting series with ID: ${msID}`); + // Replace old user IDs with new users IDs + for (let i = 0; i < msDoc.visibleFor.length; i++) { + msDoc.visibleFor[i] = usrMap[msDoc.visibleFor[i]]; } + for (let i = 0; i < msDoc.informedUsers.length; i++) { + msDoc.informedUsers[i] = usrMap[msDoc.informedUsers[i]]; + } + + return db + .collection("meetingSeries") + .insert(msDoc) + .then((res) => { + if (res.result.ok === 1) { + console.log(`OK, inserted meeting series with ID: ${msID}`); + resolve({ db, usrMap }); + } else { + reject(`Could not insert meeting series with ID: ${msID}`); + } + }); }); - }); }); } } diff --git a/imports/server/exportimport/expImpMinutes.js b/imports/server/exportimport/expImpMinutes.js index 5674e03f4..64372afca 100644 --- a/imports/server/exportimport/expImpMinutes.js +++ b/imports/server/exportimport/expImpMinutes.js @@ -1,10 +1,12 @@ -import {EJSON} from "bson"; +import { EJSON } from "bson"; import fs from "fs"; import ExpImpTopics from "./expImpTopics"; class ExpImpMinutes { - static get FILENAME_POSTFIX() { return "_minutes.json"; } + static get FILENAME_POSTFIX() { + return "_minutes.json"; + } /** * Export minutes of a meeting series to a file and collect additional user * IDs. @@ -19,49 +21,50 @@ class ExpImpMinutes { static doExport(db, msID, userIDs) { return new Promise((resolve, reject) => { db.collection("minutes") - .find({meetingSeries_id : msID}) - .toArray() - .then((allMinutesDoc) => { - if (allMinutesDoc) { - const minFile = msID + ExpImpMinutes.FILENAME_POSTFIX; - fs.writeFileSync(minFile, - EJSON.stringify(allMinutesDoc, null, 2)); - console.log( - `Saved: ${minFile} with ${allMinutesDoc.length} minutes`, - ); + .find({ meetingSeries_id: msID }) + .toArray() + .then((allMinutesDoc) => { + if (allMinutesDoc) { + const minFile = msID + ExpImpMinutes.FILENAME_POSTFIX; + fs.writeFileSync(minFile, EJSON.stringify(allMinutesDoc, null, 2)); + console.log( + `Saved: ${minFile} with ${allMinutesDoc.length} minutes`, + ); - // Collect additional invited / informed users from older minutes - allMinutesDoc.map((min) => { - min.visibleFor?.map((userID) => { - // should be identical to meeting series - userIDs[userID] = 1; - }); - min.informedUsers?.map((userID) => { - // should be identical to meeting series - userIDs[userID] = 1; - }); - min.participants?.map((part) => { - // might differ from meeting series users! - userIDs[part.userId] = 1; + // Collect additional invited / informed users from older minutes + allMinutesDoc.map((min) => { + min.visibleFor?.map((userID) => { + // should be identical to meeting series + userIDs[userID] = 1; + }); + min.informedUsers?.map((userID) => { + // should be identical to meeting series + userIDs[userID] = 1; + }); + min.participants?.map((part) => { + // might differ from meeting series users! + userIDs[part.userId] = 1; + }); + min.topics?.map((top) => { + // iterate topics + top.responsibles?.map((resp) => { + // topic-responsibles + userIDs[resp] = 1; }); - min.topics?.map((top) => { - // iterate topics - top.responsibles?.map((resp) => { - // topic-responsibles + top.infoItems?.map((item) => { + // topic-actionitem-responsibles + item.responsibles?.map((resp) => { userIDs[resp] = 1; }); - top.infoItems?.map((item) => { - // topic-actionitem-responsibles - item.responsibles?.map((resp) => { userIDs[resp] = 1; }); - }); }); }); + }); - resolve({db, userIDs}); - return; - } - return reject(new Error(`Unknown meeting series ID: ${msID}`)); - }); + resolve({ db, userIDs }); + return; + } + return reject(new Error(`Unknown meeting series ID: ${msID}`)); + }); }); } // TODO big function. consider refactoring. @@ -76,33 +79,33 @@ class ExpImpMinutes { } } catch (e) { return reject( - new Error(`Could not read minutes file ${minFile}\n${e}`), + new Error(`Could not read minutes file ${minFile}\n${e}`), ); } // Replace old user IDs with new users IDs let minIDs; - ({minIDs, minDoc} = ExpImpMinutes.patchUsers(minDoc, usrMap)); + ({ minIDs, minDoc } = ExpImpMinutes.patchUsers(minDoc, usrMap)); - return db.collection("minutes") - .deleteMany( - {_id : {$in : minIDs}}) // delete existing minutes with same IDs - .then((res) => { - if (res.result && !res.result.ok) { - console.log(res); - } - return db.collection("minutes") - .insertMany(minDoc) // insert imported minutes - .then((res) => { - if (res.result.ok === 1 && res.result.n === minDoc.length) { - console.log( - `OK, inserted ${res.result.n} meeting minutes.`); - resolve({db, usrMap}); - } else { - reject(new Error("Could not insert meeting minutes")); - } - }); - }); + return db + .collection("minutes") + .deleteMany({ _id: { $in: minIDs } }) // delete existing minutes with same IDs + .then((res) => { + if (res.result && !res.result.ok) { + console.log(res); + } + return db + .collection("minutes") + .insertMany(minDoc) // insert imported minutes + .then((res) => { + if (res.result.ok === 1 && res.result.n === minDoc.length) { + console.log(`OK, inserted ${res.result.n} meeting minutes.`); + resolve({ db, usrMap }); + } else { + reject(new Error("Could not insert meeting minutes")); + } + }); + }); }); } // TODO big function. consider refactoring. @@ -111,16 +114,25 @@ class ExpImpMinutes { for (const element of minDoc) { // iterate all minutes minIDs.push(element._id); - for (let i = 0; element.visibleFor && i < element.visibleFor.length; - i++) { + for ( + let i = 0; + element.visibleFor && i < element.visibleFor.length; + i++ + ) { element.visibleFor[i] = usrMap[element.visibleFor[i]]; } - for (let i = 0; element.informedUsers && i < element.informedUsers.length; - i++) { + for ( + let i = 0; + element.informedUsers && i < element.informedUsers.length; + i++ + ) { element.informedUsers[i] = usrMap[element.informedUsers[i]]; } - for (let i = 0; element.participants && i < element.participants.length; - i++) { + for ( + let i = 0; + element.participants && i < element.participants.length; + i++ + ) { element.participants[i].userId = usrMap[element.participants[i].userId]; } @@ -130,7 +142,7 @@ class ExpImpMinutes { } } - return {minIDs, minDoc}; + return { minIDs, minDoc }; } } diff --git a/imports/server/exportimport/expImpSchema.js b/imports/server/exportimport/expImpSchema.js index 02e2d1bca..d3a00ea9a 100644 --- a/imports/server/exportimport/expImpSchema.js +++ b/imports/server/exportimport/expImpSchema.js @@ -1,103 +1,108 @@ -import {EJSON} from "bson"; +import { EJSON } from "bson"; import fs from "fs"; class ExpImpSchema { - static get MADE_FOR_SCHEMA() { return 21; } + static get MADE_FOR_SCHEMA() { + return 21; + } - static get FILENAME_POSTFIX() { return "_schema.json"; } + static get FILENAME_POSTFIX() { + return "_schema.json"; + } static exportCheck(db, msID) { return new Promise((resolve, reject) => { - db.collection("migrations").findOne().then((doc) => { - if (doc) { - console.log(`DB Schema Version: ${doc.version}`); - if (ExpImpSchema.MADE_FOR_SCHEMA !== doc.version) { - console.log("*** WARNING *** Schema mismatch!"); - console.log( - ` This exporter is made for database schema version: ${ - ExpImpSchema.MADE_FOR_SCHEMA}`, - ); - console.log( - ` But your database has schema version : ${ - doc.version}`, - ); - console.log( + db.collection("migrations") + .findOne() + .then((doc) => { + if (doc) { + console.log(`DB Schema Version: ${doc.version}`); + if (ExpImpSchema.MADE_FOR_SCHEMA !== doc.version) { + console.log("*** WARNING *** Schema mismatch!"); + console.log( + ` This exporter is made for database schema version: ${ExpImpSchema.MADE_FOR_SCHEMA}`, + ); + console.log( + ` But your database has schema version : ${doc.version}`, + ); + console.log( " Alyways migrate to the most recent DB schema before export!", - ); - console.log(" Alyways use matching exporter!"); - console.log( + ); + console.log(" Alyways use matching exporter!"); + console.log( " Exported data may be corrupt. Continue at your own risk.", - ); + ); + } + const schemaFile = msID + ExpImpSchema.FILENAME_POSTFIX; + fs.writeFileSync(schemaFile, EJSON.stringify(doc, null, 2)); + console.log(`Saved: ${schemaFile}`); + resolve(db); + return; } - const schemaFile = msID + ExpImpSchema.FILENAME_POSTFIX; - fs.writeFileSync(schemaFile, EJSON.stringify(doc, null, 2)); - console.log(`Saved: ${schemaFile}`); - resolve(db); - return; - } - return reject( + return reject( "No migrations schema version found in your DB! Unable to export.", - ); - }); + ); + }); }); } static preImportCheck(db, msID, force = false) { return new Promise((resolve, reject) => { - db.collection("migrations").findOne().then((doc) => { - if (doc) { - console.log(`DB Schema Version: ${doc.version}`); + db.collection("migrations") + .findOne() + .then((doc) => { + if (doc) { + console.log(`DB Schema Version: ${doc.version}`); - const schemaFile = msID + ExpImpSchema.FILENAME_POSTFIX; - let exportedSchema = undefined; - try { - exportedSchema = EJSON.parse(fs.readFileSync(schemaFile, "utf8")); - if (!exportedSchema) { + const schemaFile = msID + ExpImpSchema.FILENAME_POSTFIX; + let exportedSchema = undefined; + try { + exportedSchema = EJSON.parse(fs.readFileSync(schemaFile, "utf8")); + if (!exportedSchema) { + return reject(`Could not read schema file ${schemaFile}`); + } + } catch (e) { return reject(`Could not read schema file ${schemaFile}`); } - } catch (e) { - return reject(`Could not read schema file ${schemaFile}`); - } - if (ExpImpSchema.MADE_FOR_SCHEMA !== doc.version || + if ( + ExpImpSchema.MADE_FOR_SCHEMA !== doc.version || ExpImpSchema.MADE_FOR_SCHEMA !== exportedSchema.version || - doc.version !== exportedSchema.version) { - console.log("*** WARNING *** Schema mismatch!"); - console.log( - ` This importer is made for database schema version: ${ - ExpImpSchema.MADE_FOR_SCHEMA}`, - ); - console.log( - ` Your database has schema version : ${ - doc.version}`, - ); - console.log( - ` Your exported data has schema version : ${ - exportedSchema.version}`, - ); - console.log( - " Alyways migrate to the most recent DB schema before export/import!", - ); - console.log(" Alyways use matching exporter!"); - if (force) { + doc.version !== exportedSchema.version + ) { + console.log("*** WARNING *** Schema mismatch!"); console.log( - " --force switch detected. Continueing...", + ` This importer is made for database schema version: ${ExpImpSchema.MADE_FOR_SCHEMA}`, ); - } else { - console.log(" Import will stop."); console.log( - " Use --force switch to enforce import at your own risk.", + ` Your database has schema version : ${doc.version}`, + ); + console.log( + ` Your exported data has schema version : ${exportedSchema.version}`, ); - return reject("Schema mismatch"); + console.log( + " Alyways migrate to the most recent DB schema before export/import!", + ); + console.log(" Alyways use matching exporter!"); + if (force) { + console.log( + " --force switch detected. Continueing...", + ); + } else { + console.log(" Import will stop."); + console.log( + " Use --force switch to enforce import at your own risk.", + ); + return reject("Schema mismatch"); + } } + resolve(db); + return; } - resolve(db); - return; - } - return reject( + return reject( "No migrations schema version found in your DB! Unable to import.", - ); - }); + ); + }); }); } } diff --git a/imports/server/exportimport/expImpTopics.js b/imports/server/exportimport/expImpTopics.js index b5ea5b534..4c8f38e2d 100644 --- a/imports/server/exportimport/expImpTopics.js +++ b/imports/server/exportimport/expImpTopics.js @@ -1,21 +1,26 @@ -import {EJSON} from "bson"; +import { EJSON } from "bson"; import fs from "fs"; class ExpImpTopics { - static get FILENAME_POSTFIX() { return "_topics.json"; } + static get FILENAME_POSTFIX() { + return "_topics.json"; + } static doExport(db, msID, userIDs) { return new Promise((resolve, reject) => { - db.collection("topics").find({parentId : msID}).toArray().then((doc) => { - if (doc) { - const topFile = msID + ExpImpTopics.FILENAME_POSTFIX; - fs.writeFileSync(topFile, EJSON.stringify(doc, null, 2)); - console.log(`Saved: ${topFile} with ${doc.length} topics`); - resolve({db, userIDs}); - return; - } - return reject(`Unknown meeting series ID: ${msID}`); - }); + db.collection("topics") + .find({ parentId: msID }) + .toArray() + .then((doc) => { + if (doc) { + const topFile = msID + ExpImpTopics.FILENAME_POSTFIX; + fs.writeFileSync(topFile, EJSON.stringify(doc, null, 2)); + console.log(`Saved: ${topFile} with ${doc.length} topics`); + resolve({ db, userIDs }); + return; + } + return reject(`Unknown meeting series ID: ${msID}`); + }); }); } @@ -39,32 +44,35 @@ class ExpImpTopics { AllTopicsDoc[t] = ExpImpTopics.patchUsers(AllTopicsDoc[t], usrMap); } - return db.collection("topics") - .deleteMany( - {_id : {$in : topicIDs}}) // delete existing topics with same IDs - .then((res) => { - if (res.result && !res.result.ok) { - console.log(res); - } - return db.collection("topics") - .insertMany(AllTopicsDoc) // insert imported minutes - .then((res) => { - if (res.result.ok === 1 && - res.result.n === AllTopicsDoc.length) { - console.log(`OK, inserted ${res.result.n} topics.`); - resolve({db, usrMap}); - } else { - reject("Could not insert topics"); - } - }); - }); + return db + .collection("topics") + .deleteMany({ _id: { $in: topicIDs } }) // delete existing topics with same IDs + .then((res) => { + if (res.result && !res.result.ok) { + console.log(res); + } + return db + .collection("topics") + .insertMany(AllTopicsDoc) // insert imported minutes + .then((res) => { + if (res.result.ok === 1 && res.result.n === AllTopicsDoc.length) { + console.log(`OK, inserted ${res.result.n} topics.`); + resolve({ db, usrMap }); + } else { + reject("Could not insert topics"); + } + }); + }); }); } static patchUsers(topicDoc, usrMap) { // patch topic-responsibles - for (let i = 0; topicDoc.responsibles && i < topicDoc.responsibles.length; - i++) { + for ( + let i = 0; + topicDoc.responsibles && i < topicDoc.responsibles.length; + i++ + ) { if (usrMap[topicDoc.responsibles[i]]) { // may be "free text" user topicDoc.responsibles[i] = usrMap[topicDoc.responsibles[i]]; @@ -72,13 +80,16 @@ class ExpImpTopics { } // patch topic-actionitem-responsibles for (let i = 0; topicDoc.infoItems && i < topicDoc.infoItems.length; i++) { - for (let j = 0; topicDoc.infoItems[i].responsibles && - j < topicDoc.infoItems[i].responsibles.length; - j++) { + for ( + let j = 0; + topicDoc.infoItems[i].responsibles && + j < topicDoc.infoItems[i].responsibles.length; + j++ + ) { if (usrMap[topicDoc.infoItems[i].responsibles[j]]) { // may be "free text" user topicDoc.infoItems[i].responsibles[j] = - usrMap[topicDoc.infoItems[i].responsibles[j]]; + usrMap[topicDoc.infoItems[i].responsibles[j]]; } } } diff --git a/imports/server/exportimport/expImpUsers.js b/imports/server/exportimport/expImpUsers.js index 8d6cbf033..b13636099 100644 --- a/imports/server/exportimport/expImpUsers.js +++ b/imports/server/exportimport/expImpUsers.js @@ -1,9 +1,13 @@ -import {EJSON} from "bson"; +import { EJSON } from "bson"; import fs from "fs"; class ExpImpUsers { - static get FILENAME_POSTFIX() { return "_users.json"; } - static get MAPNAME_POSTFIX() { return "_userMap.json"; } + static get FILENAME_POSTFIX() { + return "_users.json"; + } + static get MAPNAME_POSTFIX() { + return "_userMap.json"; + } static searchUser(allUserDoc, searchID) { for (let i = 0; i < allUserDoc.length; i++) { @@ -20,47 +24,48 @@ class ExpImpUsers { const userIDsOuputMap = {}; db.collection("users") - .find({_id : {$in : userIDsFlat}}) - .toArray() - .then((allUsersDoc) => { - if (allUsersDoc) { - // userIDsFlat may contain "free text" users that are not in DB - // We create a dict to look up which collected userIDs are really - // from DB - const userIDsFromDB = {}; - allUsersDoc.map((usr) => { userIDsFromDB[usr._id] = 1; }); - const usrFile = msID + ExpImpUsers.FILENAME_POSTFIX; - fs.writeFileSync(usrFile, EJSON.stringify(allUsersDoc, null, 2)); - console.log(`Saved: ${usrFile} with ${allUsersDoc.length} users`); + .find({ _id: { $in: userIDsFlat } }) + .toArray() + .then((allUsersDoc) => { + if (allUsersDoc) { + // userIDsFlat may contain "free text" users that are not in DB + // We create a dict to look up which collected userIDs are really + // from DB + const userIDsFromDB = {}; + allUsersDoc.map((usr) => { + userIDsFromDB[usr._id] = 1; + }); + const usrFile = msID + ExpImpUsers.FILENAME_POSTFIX; + fs.writeFileSync(usrFile, EJSON.stringify(allUsersDoc, null, 2)); + console.log(`Saved: ${usrFile} with ${allUsersDoc.length} users`); - // Save mapping file old => new user ID - // But only with REAL DB users (skip free text users) - userIDsFlat.map((usrID) => { - if (userIDsFromDB[usrID]) { - // default: newID === oldID - // This means, users are copied(!) from source DB to - // destination DB If newID is changed to an existing id from - // destination ID, this target user is used - const thisUser = ExpImpUsers.searchUser(allUsersDoc, usrID); - userIDsOuputMap[usrID] = { - newID : usrID, - hint : `${thisUser.username} ${thisUser.profile.name}`, - }; - } - }); - const mapFile = msID + ExpImpUsers.MAPNAME_POSTFIX; - fs.writeFileSync(mapFile, - JSON.stringify(userIDsOuputMap, null, 2)); - console.log(`Saved: ${mapFile}`); - console.log( - " *** IMPORTANT!!! EDIT USER MAP FILE BEFORE IMPORT!!!", - ); + // Save mapping file old => new user ID + // But only with REAL DB users (skip free text users) + userIDsFlat.map((usrID) => { + if (userIDsFromDB[usrID]) { + // default: newID === oldID + // This means, users are copied(!) from source DB to + // destination DB If newID is changed to an existing id from + // destination ID, this target user is used + const thisUser = ExpImpUsers.searchUser(allUsersDoc, usrID); + userIDsOuputMap[usrID] = { + newID: usrID, + hint: `${thisUser.username} ${thisUser.profile.name}`, + }; + } + }); + const mapFile = msID + ExpImpUsers.MAPNAME_POSTFIX; + fs.writeFileSync(mapFile, JSON.stringify(userIDsOuputMap, null, 2)); + console.log(`Saved: ${mapFile}`); + console.log( + " *** IMPORTANT!!! EDIT USER MAP FILE BEFORE IMPORT!!!", + ); - resolve(db); - return; - } - return reject("Could not find users: ", userIDsFlat); - }); + resolve(db); + return; + } + return reject("Could not find users: ", userIDsFlat); + }); }); } @@ -77,8 +82,9 @@ class ExpImpUsers { return reject(`Could not read user map file ${mapFile}\n${e}`); } const usrMapSimple = {}; // make flat map: oldID => newID - usrMap = Object.keys(usrMap).map( - (key) => { usrMapSimple[key] = usrMap[key].newID; }); + usrMap = Object.keys(usrMap).map((key) => { + usrMapSimple[key] = usrMap[key].newID; + }); usrMap = usrMapSimple; const usrMapCount = Object.keys(usrMap).length; @@ -96,46 +102,42 @@ class ExpImpUsers { // Check#1: All "link targets" should exist db.collection("users") - .find({_id : {$in : usrMapTargetIDs}}) - .toArray() - .then((doc) => { - if (doc) { - console.log( - `Found ${doc.length} target users in current user DB.`); - console.log( - `Will copy over ${ - usrCopyIDs.length} export users to current user DB.`, + .find({ _id: { $in: usrMapTargetIDs } }) + .toArray() + .then((doc) => { + if (doc) { + console.log(`Found ${doc.length} target users in current user DB.`); + console.log( + `Will copy over ${usrCopyIDs.length} export users to current user DB.`, + ); + if (doc.length !== usrMapTargetIDs.length) { + return reject( + `Not all to-be patched target users found in current user DB: ${usrMapTargetIDs}`, ); - if (doc.length !== usrMapTargetIDs.length) { - return reject( - `Not all to-be patched target users found in current user DB: ${ - usrMapTargetIDs}`, - ); - } - // Check#2: All copy-users MUST NOT exist! - db.collection("users") - .find({_id : {$in : usrCopyIDs}}) - .toArray() - .then((shouldBeEmpty) => { - if (shouldBeEmpty && shouldBeEmpty.length > 0) { - const errorUsers = shouldBeEmpty.map((usr) => { - return {_id : usr._id, username : usr.username}; - }); - return reject( - `${ - shouldBeEmpty - .length} to-be copied user(s) already exists:\n${ - JSON.stringify( - errorUsers, - )}`, - ); - } - resolve({db, usrMap}); - }); - return; } - return reject("Could not find users: ", usrMapTargetIDs); - }); + // Check#2: All copy-users MUST NOT exist! + db.collection("users") + .find({ _id: { $in: usrCopyIDs } }) + .toArray() + .then((shouldBeEmpty) => { + if (shouldBeEmpty && shouldBeEmpty.length > 0) { + const errorUsers = shouldBeEmpty.map((usr) => { + return { _id: usr._id, username: usr.username }; + }); + return reject( + `${ + shouldBeEmpty.length + } to-be copied user(s) already exists:\n${JSON.stringify( + errorUsers, + )}`, + ); + } + resolve({ db, usrMap }); + }); + return; + } + return reject("Could not find users: ", usrMapTargetIDs); + }); }); } @@ -158,45 +160,47 @@ class ExpImpUsers { for (let u = 0; u < allUsersDoc.length; u++) { if (allUsersDoc[u]._id === usrMap[allUsersDoc[u]._id]) { // before/after ID are same in mapping file! - const roleValueForMS = - allUsersDoc[u].roles[msID]; // Case#1: clone this user from source + const roleValueForMS = allUsersDoc[u].roles[msID]; // Case#1: clone this user from source // DB => target DB! allUsersDoc[u].roles = { - msID : roleValueForMS, + msID: roleValueForMS, }; // Kill all other roles, just keep the one for this MS promiseChain.push(db.collection("users").insert(allUsersDoc[u])); } else { promiseChain.push( - // Case#2: only update user role for existing user in target DB - db.collection("users") - .findOne({ - _id : usrMap[allUsersDoc[u]._id], - }) // find the user in target DB - .then((usr) => { - const roleValueForMS = allUsersDoc[u].roles[msID]; - if (!(roleValueForMS && roleValueForMS.length > 0)) { - return; - } - // user needs role for import meeting series? - const roles = usr.roles ? usr.roles : {}; - roles[msID] = roleValueForMS; - return db - .collection("users") // upsert role field - .update({_id : usr._id}, {$set : {roles}}); - }), + // Case#2: only update user role for existing user in target DB + db + .collection("users") + .findOne({ + _id: usrMap[allUsersDoc[u]._id], + }) // find the user in target DB + .then((usr) => { + const roleValueForMS = allUsersDoc[u].roles[msID]; + if (!(roleValueForMS && roleValueForMS.length > 0)) { + return; + } + // user needs role for import meeting series? + const roles = usr.roles ? usr.roles : {}; + roles[msID] = roleValueForMS; + return db + .collection("users") // upsert role field + .update({ _id: usr._id }, { $set: { roles } }); + }), ); } } // Now execute the chain. Promise.all(promiseChain) - .then((res) => { - if (res?.[0] && res[0].result && !res[0].result.ok) { - console.log("Promisechain result: ", res); - } - resolve(db); - }) - .catch((err) => { reject(err); }); + .then((res) => { + if (res?.[0] && res[0].result && !res[0].result.ok) { + console.log("Promisechain result: ", res); + } + resolve(db); + }) + .catch((err) => { + reject(err); + }); }); } } diff --git a/private/createTestUsers.js b/private/createTestUsers.js index 94b558224..106ae02e0 100644 --- a/private/createTestUsers.js +++ b/private/createTestUsers.js @@ -7,8 +7,8 @@ * users: node createTestUsers.js -m mongodb://localhost:3101/meteor -n 5000 */ -import {faker} from "@faker-js/faker"; -import {MongoClient as mongo} from "mongodb"; +import { faker } from "@faker-js/faker"; +import { MongoClient as mongo } from "mongodb"; import random from "randomstring"; class UserFactory { @@ -16,22 +16,22 @@ class UserFactory { UserFactory.counter++; const username = `user_${UserFactory.postfix}_${UserFactory.counter}`; return { - _id : random.generate({ - length : 17, - charset : "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", + _id: random.generate({ + length: 17, + charset: "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", }), username, - createdAt : new Date(), - isInactive : false, - services : { - password : { + createdAt: new Date(), + isInactive: false, + services: { + password: { // PwdPwd1 - bcrypt : - "$2a$10$mtPbwEoJmaAO01fxI/WnZepoUz4D.U6f/yYl6KG1oojxNI7JZmn.S", + bcrypt: + "$2a$10$mtPbwEoJmaAO01fxI/WnZepoUz4D.U6f/yYl6KG1oojxNI7JZmn.S", }, }, - profile : {name : faker.person.fullName()}, - emails : [ {address : `${username}@4minitz.com`, verified : false} ], + profile: { name: faker.person.fullName() }, + emails: [{ address: `${username}@4minitz.com`, verified: false }], }; } @@ -48,11 +48,11 @@ class UserFactory { } UserFactory.counter = 0; UserFactory.postfix = random.generate({ - length : 3, - charset : "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", + length: 3, + charset: "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz", }); -const _connectMongo = function(mongoUrl) { +const _connectMongo = function (mongoUrl) { return new Promise((resolve, reject) => { mongo.connect(mongoUrl, (error, db) => { if (error) { @@ -64,9 +64,9 @@ const _connectMongo = function(mongoUrl) { }; const optionParser = require("node-getopt").create([ - [ "n", "number=[ARG]", "Number of users to be created" ], - [ "m", "mongourl=[ARG]", "Mongo DB url" ], - [ "h", "help", "Display this help" ], + ["n", "number=[ARG]", "Number of users to be created"], + ["m", "mongourl=[ARG]", "Mongo DB url"], + ["h", "help", "Display this help"], ]); const arg = optionParser.bindHelp().parseSystem(); const mongoUrl = arg.options.mongourl || process.env.MONGO_URL; @@ -82,6 +82,8 @@ if (!mongoUrl) { } _connectMongo(mongoUrl) - .then((db) => UserFactory.saveUsers(db, numberOfUsers)) - .then((db) => db.close()) - .catch((error) => { console.log(`Error: ${error}`); }); + .then((db) => UserFactory.saveUsers(db, numberOfUsers)) + .then((db) => db.close()) + .catch((error) => { + console.log(`Error: ${error}`); + }); diff --git a/private/exportMeetingSeries.js b/private/exportMeetingSeries.js index 8aa7657dc..939f23ed1 100644 --- a/private/exportMeetingSeries.js +++ b/private/exportMeetingSeries.js @@ -4,25 +4,20 @@ mongodb://localhost:3101/meteor --id icwrCdJjqWpoH9ugQ */ -import {MongoClient as mongo} from "mongodb"; +import { MongoClient as mongo } from "mongodb"; -import ExpImpFileAttachments from - "../imports/server/exportimport/expImpFilesAttachments"; -import ExpImpFileDocuments from - "../imports/server/exportimport/expImpFilesDocuments"; -import ExpImpMeetingSeries from - "../imports/server/exportimport/expImpMeetingseries"; +import ExpImpFileAttachments from "../imports/server/exportimport/expImpFilesAttachments"; +import ExpImpFileDocuments from "../imports/server/exportimport/expImpFilesDocuments"; +import ExpImpMeetingSeries from "../imports/server/exportimport/expImpMeetingseries"; import ExpImpMinutes from "../imports/server/exportimport/expImpMinutes"; import ExpImpSchema from "../imports/server/exportimport/expImpSchema"; import ExpImpTopics from "../imports/server/exportimport/expImpTopics"; import ExpImpUsers from "../imports/server/exportimport/expImpUsers"; const optionParser = require("node-getopt").create([ - [ "i", "id=[ARG]", "ID of meeting series, e.g. icwrCdJjqWpoH9ugQ" ], - [ - "m", "mongourl=[ARG]", "Mongo DB url, e.g. mongodb://localhost:3101/meteor" - ], - [ "h", "help", "Display this help" ], + ["i", "id=[ARG]", "ID of meeting series, e.g. icwrCdJjqWpoH9ugQ"], + ["m", "mongourl=[ARG]", "Mongo DB url, e.g. mongodb://localhost:3101/meteor"], + ["h", "help", "Display this help"], ]); const arg = optionParser.bindHelp().parseSystem(); const mongoUrl = arg.options.mongourl || process.env.MONGO_URL; @@ -35,7 +30,7 @@ if (!mongoUrl) { optionParser.showHelp(); throw new Error("No --mongourl parameter or MONGO_URL in env"); } -const _connectMongo = function(mongoUrl) { +const _connectMongo = function (mongoUrl) { return new Promise((resolve, reject) => { mongo.connect(mongoUrl, (error, db) => { if (error) { @@ -48,29 +43,32 @@ const _connectMongo = function(mongoUrl) { console.log(""); console.log( - `*** 4Minitz MeetingSeries Export Tool *** (made for schema version: ${ - ExpImpSchema.MADE_FOR_SCHEMA})`, + `*** 4Minitz MeetingSeries Export Tool *** (made for schema version: ${ExpImpSchema.MADE_FOR_SCHEMA})`, ); _connectMongo(mongoUrl) - .then((db) => { return ExpImpSchema.exportCheck(db, meetingseriesID); }) - .then((db) => { return ExpImpMeetingSeries.doExport(db, meetingseriesID); }) - .then(({db, userIDs}) => { - return ExpImpMinutes.doExport(db, meetingseriesID, userIDs); - }) - .then(({db, userIDs}) => { - return ExpImpTopics.doExport(db, meetingseriesID, userIDs); - }) - .then(({db, userIDs}) => { - return ExpImpFileAttachments.doExport(db, meetingseriesID, userIDs); - }) - .then(({db, userIDs}) => { - return ExpImpFileDocuments.doExport(db, meetingseriesID, userIDs); - }) - .then(({db, userIDs}) => { - return ExpImpUsers.doExport(db, meetingseriesID, userIDs); - }) - .then((db) => db.close()) - .catch((error) => { - console.log(`Error: ${error}`); - console.log("Press Ctrl+C to stop."); - }); + .then((db) => { + return ExpImpSchema.exportCheck(db, meetingseriesID); + }) + .then((db) => { + return ExpImpMeetingSeries.doExport(db, meetingseriesID); + }) + .then(({ db, userIDs }) => { + return ExpImpMinutes.doExport(db, meetingseriesID, userIDs); + }) + .then(({ db, userIDs }) => { + return ExpImpTopics.doExport(db, meetingseriesID, userIDs); + }) + .then(({ db, userIDs }) => { + return ExpImpFileAttachments.doExport(db, meetingseriesID, userIDs); + }) + .then(({ db, userIDs }) => { + return ExpImpFileDocuments.doExport(db, meetingseriesID, userIDs); + }) + .then(({ db, userIDs }) => { + return ExpImpUsers.doExport(db, meetingseriesID, userIDs); + }) + .then((db) => db.close()) + .catch((error) => { + console.log(`Error: ${error}`); + console.log("Press Ctrl+C to stop."); + }); diff --git a/private/importMeetingSeries.js b/private/importMeetingSeries.js index 57ca41bad..faaf90d86 100644 --- a/private/importMeetingSeries.js +++ b/private/importMeetingSeries.js @@ -4,26 +4,21 @@ mongodb://localhost:3101/meteor --id icwrCdJjqWpoH9ugQ */ -import {MongoClient as mongo} from "mongodb"; +import { MongoClient as mongo } from "mongodb"; -import ExpImpFileAttachments from - "../imports/server/exportimport/expImpFilesAttachments"; -import ExpImpFileDocuments from - "../imports/server/exportimport/expImpFilesDocuments"; -import ExpImpMeetingSeries from - "../imports/server/exportimport/expImpMeetingseries"; +import ExpImpFileAttachments from "../imports/server/exportimport/expImpFilesAttachments"; +import ExpImpFileDocuments from "../imports/server/exportimport/expImpFilesDocuments"; +import ExpImpMeetingSeries from "../imports/server/exportimport/expImpMeetingseries"; import ExpImpMinutes from "../imports/server/exportimport/expImpMinutes"; import ExpImpSchema from "../imports/server/exportimport/expImpSchema"; import ExpImpTopics from "../imports/server/exportimport/expImpTopics"; import ExpImpUsers from "../imports/server/exportimport/expImpUsers"; const optionParser = require("node-getopt").create([ - [ "i", "id=[ARG]", "ID of meeting series, e.g. icwrCdJjqWpoH9ugQ" ], - [ - "m", "mongourl=[ARG]", "Mongo DB url, e.g. mongodb://localhost:3101/meteor" - ], - [ "f", "force", "Force import even if schema mismatch" ], - [ "h", "help", "Display this help" ], + ["i", "id=[ARG]", "ID of meeting series, e.g. icwrCdJjqWpoH9ugQ"], + ["m", "mongourl=[ARG]", "Mongo DB url, e.g. mongodb://localhost:3101/meteor"], + ["f", "force", "Force import even if schema mismatch"], + ["h", "help", "Display this help"], ]); const arg = optionParser.bindHelp().parseSystem(); const mongoUrl = arg.options.mongourl || process.env.MONGO_URL; @@ -38,30 +33,30 @@ if (!mongoUrl) { throw new Error("No --mongourl parameter or MONGO_URL in env"); throw new Error("No --mongourl parameter or MONGO_URL in env"); } -const _connectMongo = (mongoUrl) => new Promise((resolve, reject) => { - mongo.connect(mongoUrl, (error, db) => { - if (error) { - reject(error); - } - closeDB = db; - resolve(db); +const _connectMongo = (mongoUrl) => + new Promise((resolve, reject) => { + mongo.connect(mongoUrl, (error, db) => { + if (error) { + reject(error); + } + closeDB = db; + resolve(db); + }); }); -}); console.log(""); console.log( - `*** 4Minitz MeetingSeries Import Tool *** (made for schema version: ${ - ExpImpSchema.MADE_FOR_SCHEMA})`, + `*** 4Minitz MeetingSeries Import Tool *** (made for schema version: ${ExpImpSchema.MADE_FOR_SCHEMA})`, ); console.log("*** ATTENTION ***"); console.log( - "- This script will import a meeting series and all dependecies to your DB.", + "- This script will import a meeting series and all dependecies to your DB.", ); console.log( - "- This script has to change existing user roles, so users can access the new data.", + "- This script has to change existing user roles, so users can access the new data.", ); console.log( - "- This script may overwrite edited data if you import the same data multiple times.", + "- This script may overwrite edited data if you import the same data multiple times.", ); console.log("So, this script is DANGEROUS!!!"); console.log("Experts only!"); @@ -72,37 +67,38 @@ console.log(" e.g.: mongodump -h 127.0.0.1 --port 3101 -d meteor"); console.log(""); console.log("Press ENTER to continue - or Ctrl+C to quit..."); require("child_process").spawnSync("read _ ", { - shell : true, - stdio : [ 0, 1, 2 ], + shell: true, + stdio: [0, 1, 2], }); var closeDB = undefined; _connectMongo(mongoUrl) - .then((db) => { - return ExpImpSchema.preImportCheck(db, meetingseriesID, - arg.options.force); - }) - .then((db) => { return ExpImpUsers.preImportCheck(db, meetingseriesID); }) - .then(({db, usrMap}) => { - return ExpImpMeetingSeries.doImport(db, meetingseriesID, usrMap); - }) - .then(({db, usrMap}) => { - return ExpImpMinutes.doImport(db, meetingseriesID, usrMap); - }) - .then(({db, usrMap}) => { - return ExpImpTopics.doImport(db, meetingseriesID, usrMap); - }) - .then(({db, usrMap}) => { - return ExpImpFileAttachments.doImport(db, meetingseriesID, usrMap); - }) - .then(({db, usrMap}) => { - return ExpImpFileDocuments.doImport(db, meetingseriesID, usrMap); - }) - .then(({db, usrMap}) => { - return ExpImpUsers.doImport(db, meetingseriesID, usrMap); - }) - .then((db) => closeDB.close()) - .catch((error) => { - console.log(`Error: ${error}`); - console.log("Press Ctrl+C to stop."); - }); + .then((db) => { + return ExpImpSchema.preImportCheck(db, meetingseriesID, arg.options.force); + }) + .then((db) => { + return ExpImpUsers.preImportCheck(db, meetingseriesID); + }) + .then(({ db, usrMap }) => { + return ExpImpMeetingSeries.doImport(db, meetingseriesID, usrMap); + }) + .then(({ db, usrMap }) => { + return ExpImpMinutes.doImport(db, meetingseriesID, usrMap); + }) + .then(({ db, usrMap }) => { + return ExpImpTopics.doImport(db, meetingseriesID, usrMap); + }) + .then(({ db, usrMap }) => { + return ExpImpFileAttachments.doImport(db, meetingseriesID, usrMap); + }) + .then(({ db, usrMap }) => { + return ExpImpFileDocuments.doImport(db, meetingseriesID, usrMap); + }) + .then(({ db, usrMap }) => { + return ExpImpUsers.doImport(db, meetingseriesID, usrMap); + }) + .then((db) => closeDB.close()) + .catch((error) => { + console.log(`Error: ${error}`); + console.log("Press Ctrl+C to stop."); + }); diff --git a/programs/generateLicenseList.js b/programs/generateLicenseList.js index 0d6658c70..832790eb6 100644 --- a/programs/generateLicenseList.js +++ b/programs/generateLicenseList.js @@ -4,105 +4,104 @@ import https from "https"; import crawler from "npm-license-crawler"; const meteorPackages = { - meteor : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/meteor/meteor/devel/LICENSE", - }, - "alanning:roles" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/alanning/meteor-roles/master/LICENSE", - }, - "babrahams:accounts-ldap" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/JackAdams/meteor-accounts-ldap/master/LICENSE", - }, - "felixble:server-templates" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/felixble/meteor-server-templates/master/LICENSE.md", - }, - "fourseven:scss" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/fourseven/meteor-scss/master/LICENSE.txt", - }, - "jagi:astronomy" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/jagi/meteor-astronomy/v2/LICENSE", - }, - "kadira:blaze-layout" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/kadirahq/blaze-layout/master/LICENSE", - }, - "ostrio:flow-router-extra" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/VeliovGroup/flow-router/master/LICENSE", - }, - "meteorhacks:subs-manager" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/kadirahq/subs-manager/master/LICENSE", - }, - "mouse0270:bootstrap-notify" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/mouse0270/bootstrap-notify/master/LICENSE", + meteor: { + licenses: "MIT", + licenseUrl: "https://raw.githubusercontent.com/meteor/meteor/devel/LICENSE", + }, + "alanning:roles": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/alanning/meteor-roles/master/LICENSE", + }, + "babrahams:accounts-ldap": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/JackAdams/meteor-accounts-ldap/master/LICENSE", + }, + "felixble:server-templates": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/felixble/meteor-server-templates/master/LICENSE.md", + }, + "fourseven:scss": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/fourseven/meteor-scss/master/LICENSE.txt", + }, + "jagi:astronomy": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/jagi/meteor-astronomy/v2/LICENSE", + }, + "kadira:blaze-layout": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/kadirahq/blaze-layout/master/LICENSE", + }, + "ostrio:flow-router-extra": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/VeliovGroup/flow-router/master/LICENSE", + }, + "meteorhacks:subs-manager": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/kadirahq/subs-manager/master/LICENSE", + }, + "mouse0270:bootstrap-notify": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/mouse0270/bootstrap-notify/master/LICENSE", }, // "msavin:mongol": {licenses: "MIT", licenseUrl: // "https://raw.githubusercontent.com/MeteorToys/allthings/master/LICENSE.md"}, - "natestrauser:select2" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/nate-strauser/meteor-select2/master/LICENSE.txt", - }, - "ostrio:files" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/VeliovGroup/Meteor-Files/master/LICENSE", - }, - "perak:markdown" : { - licenses : "MIT", - licenseUrl : "https://raw.githubusercontent.com/chjj/marked/master/LICENSE", - }, - "percolate:migrations" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/percolatestudio/meteor-migrations/master/LICENSE", - }, - "practicalmeteor:mocha" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/practicalmeteor/meteor-mocha/meteor/LICENSE", - }, - "rcy:pick-a-color" : { - licenses : "MIT", - licenseUrl : "https://github.com/lauren/pick-a-color/raw/master/LICENSE", - }, - "sergeyt:typeahead" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/sergeyt/meteor-typeahead/master/LICENSE", - }, - "useraccounts:bootstrap" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/meteor-useraccounts/bootstrap/master/LICENSE", - }, - "universe:i18n" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/vazco/meteor-universe-i18n/master/LICENSE", - }, - "universe:i18n-blaze" : { - licenses : "MIT", - licenseUrl : - "https://raw.githubusercontent.com/vazco/universe-i18n-blaze/master/LICENSE", + "natestrauser:select2": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/nate-strauser/meteor-select2/master/LICENSE.txt", + }, + "ostrio:files": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/VeliovGroup/Meteor-Files/master/LICENSE", + }, + "perak:markdown": { + licenses: "MIT", + licenseUrl: "https://raw.githubusercontent.com/chjj/marked/master/LICENSE", + }, + "percolate:migrations": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/percolatestudio/meteor-migrations/master/LICENSE", + }, + "practicalmeteor:mocha": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/practicalmeteor/meteor-mocha/meteor/LICENSE", + }, + "rcy:pick-a-color": { + licenses: "MIT", + licenseUrl: "https://github.com/lauren/pick-a-color/raw/master/LICENSE", + }, + "sergeyt:typeahead": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/sergeyt/meteor-typeahead/master/LICENSE", + }, + "useraccounts:bootstrap": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/meteor-useraccounts/bootstrap/master/LICENSE", + }, + "universe:i18n": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/vazco/meteor-universe-i18n/master/LICENSE", + }, + "universe:i18n-blaze": { + licenses: "MIT", + licenseUrl: + "https://raw.githubusercontent.com/vazco/universe-i18n-blaze/master/LICENSE", }, }; @@ -116,15 +115,14 @@ function get(url, callback) { function downloadToStream(project, url, licenseId, originalLicenseUrl) { if (!url) { - return Promise.resolve({project, stream : null, url}); + return Promise.resolve({ project, stream: null, url }); } // handle projects that declare a license but only with their SPDX id in // package.json and don't provide the license text in their repo SPDX provides // a repo with all licenses at https://github.com/spdx/license-list if (url.includes("raw")) { - const SPDXUrl = - `https://github.com/spdx/license-list/raw/master/${licenseId}.txt`; + const SPDXUrl = `https://github.com/spdx/license-list/raw/master/${licenseId}.txt`; return downloadToStream(project, SPDXUrl, licenseId, url); } @@ -142,9 +140,9 @@ function downloadToStream(project, url, licenseId, originalLicenseUrl) { // handle client and server errors } else if (response.statusCode >= 400) { console.log(`${response.statusCode}: ${url} not found`); - resolve({project, url}); + resolve({ project, url }); } else { - resolve({project, stream : response, url}); + resolve({ project, stream: response, url }); } }; @@ -158,46 +156,44 @@ function streamCollector(streams, index, outStream) { } streams[index] - .then(({project, stream, url}) => { - const underlineProject = Array(project.length).join("="), - licenseSeparator = Array(80).join("="); - - outStream.write(`${project}\n${underlineProject}\n\n${url}\n\n`); - if (stream) { - console.log(`Writing license of ${project}`); - - stream.pipe(outStream, {end : false}); - stream.on("end", () => { - outStream.write(`\n\n${licenseSeparator}\n\n`); - streamCollector(streams, index + 1, outStream); - }); - } else { - console.log(`NO LICENSE TEXT FOUND FOR ${project}`); + .then(({ project, stream, url }) => { + const underlineProject = Array(project.length).join("="), + licenseSeparator = Array(80).join("="); + + outStream.write(`${project}\n${underlineProject}\n\n${url}\n\n`); + if (stream) { + console.log(`Writing license of ${project}`); + + stream.pipe(outStream, { end: false }); + stream.on("end", () => { outStream.write(`\n\n${licenseSeparator}\n\n`); streamCollector(streams, index + 1, outStream); - } - }) - .catch(console.error); + }); + } else { + console.log(`NO LICENSE TEXT FOUND FOR ${project}`); + outStream.write(`\n\n${licenseSeparator}\n\n`); + streamCollector(streams, index + 1, outStream); + } + }) + .catch(console.error); } const licenseCount = {}; function getSortedKeys(obj) { const keys = []; - for (const key in obj) - keys.push(key); + for (const key in obj) keys.push(key); return keys.sort((a, b) => obj[b] - obj[a]); } -crawler.dumpLicenses({start : [ "." ]}, (error, res) => { +crawler.dumpLicenses({ start: ["."] }, (error, res) => { if (error) { console.error("Error:", error); return; } const output = fs.createWriteStream("LicensesOfDependencies.txt"); - const streams = Object.keys(res).map( - (project) => downloadToStream(project, res[project].licenseUrl, - res[project].licenses), + const streams = Object.keys(res).map((project) => + downloadToStream(project, res[project].licenseUrl, res[project].licenses), ); streamCollector(streams, 0, output); @@ -207,11 +203,10 @@ crawler.dumpLicenses({start : [ "." ]}, (error, res) => { Object.assign(res, meteorPackages); Object.keys(res).forEach((project) => { licenseCount[res[project].licenses] = - (licenseCount[res[project].licenses] || 0) + 1; + (licenseCount[res[project].licenses] || 0) + 1; }); - getSortedKeys(licenseCount) - .forEach( - (license) => console.log(`${license} ${licenseCount[license]}`), - ); + getSortedKeys(licenseCount).forEach((license) => + console.log(`${license} ${licenseCount[license]}`), + ); console.log("********************"); }); diff --git a/tests/unit/client/helpers/submitOnEnter.test.js b/tests/unit/client/helpers/submitOnEnter.test.js index a6b8a95a5..8bd425149 100644 --- a/tests/unit/client/helpers/submitOnEnter.test.js +++ b/tests/unit/client/helpers/submitOnEnter.test.js @@ -1,4 +1,4 @@ -import {expect} from "chai"; +import { expect } from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -7,40 +7,38 @@ import rewiremock from "../../test-helper/rewiremock.cjs"; const jQueryOnStub = sinon.stub(); const $ = sinon.stub().returns({ - on : jQueryOnStub, + on: jQueryOnStub, }); -const submitOnEnter = - await rewiremock - .module( - () => import("../../../../client/helpers/submitOnEnter.js"), - { - jquery : $, - lodash : _, - }, - ) - .default; - -describe("submitOnEnter", function() { +const submitOnEnter = await rewiremock.module( + () => import("../../../../client/helpers/submitOnEnter.js"), + { + jquery: $, + lodash: _, + }, +).default; + +describe("submitOnEnter", function () { const action = sinon.stub(); function fakeEnterPressed(controlPressed) { return { - keyCode : 13, - key : "Enter", - ctrlKey : controlPressed, - preventDefault : sinon.stub(), + keyCode: 13, + key: "Enter", + ctrlKey: controlPressed, + preventDefault: sinon.stub(), }; } - beforeEach(function() { + beforeEach(function () { jQueryOnStub.resetHistory(); $.resetHistory(); action.resetHistory(); }); - it("attaches event handlers to the given textareas", function() { - let textareas = [ "one", "two" ], numberOfTextareas = textareas.length; + it("attaches event handlers to the given textareas", function () { + let textareas = ["one", "two"], + numberOfTextareas = textareas.length; submitOnEnter(textareas, action); @@ -52,20 +50,21 @@ describe("submitOnEnter", function() { sinon.assert.calledWith($, "two"); }); - it("action is not triggered when control is not pressed for textarea", - function() { - let input = [ "one" ], event = fakeEnterPressed(false); + it("action is not triggered when control is not pressed for textarea", function () { + let input = ["one"], + event = fakeEnterPressed(false); - submitOnEnter(input, action); + submitOnEnter(input, action); - const handler = jQueryOnStub.getCall(0).args[1]; - handler(event); + const handler = jQueryOnStub.getCall(0).args[1]; + handler(event); - expect(action.calledOnce).to.be.false; - }); + expect(action.calledOnce).to.be.false; + }); - it("action is triggered when control is pressed for textareas", function() { - let input = [ "one" ], event = fakeEnterPressed(true); + it("action is triggered when control is pressed for textareas", function () { + let input = ["one"], + event = fakeEnterPressed(true); submitOnEnter(input, action); @@ -75,18 +74,18 @@ describe("submitOnEnter", function() { expect(action.calledOnce).to.be.true; }); - it("action is not triggered for textareas when something other than enter is entered", - function() { - let input = [ "one" ], event = fakeEnterPressed(true); + it("action is not triggered for textareas when something other than enter is entered", function () { + let input = ["one"], + event = fakeEnterPressed(true); - event.key = "Something Else"; - event.keyCode = 15; + event.key = "Something Else"; + event.keyCode = 15; - submitOnEnter(input, action); + submitOnEnter(input, action); - const handler = jQueryOnStub.getCall(0).args[1]; - handler(event); + const handler = jQueryOnStub.getCall(0).args[1]; + handler(event); - expect(action.calledOnce).to.be.false; - }); + expect(action.calledOnce).to.be.false; + }); }); diff --git a/tests/unit/imports/ActionItem.test.js b/tests/unit/imports/ActionItem.test.js index 7dea008c7..bbeb84720 100644 --- a/tests/unit/imports/ActionItem.test.js +++ b/tests/unit/imports/ActionItem.test.js @@ -1,6 +1,6 @@ import "../../../imports/helpers/date.js"; -import {expect} from "chai"; +import { expect } from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -15,106 +15,110 @@ const Label = {}; class MeteorError {} const Meteor = { - call : sinon.stub(), - Error : MeteorError, - user : () => { return {username : "unit-test"}; }, + call: sinon.stub(), + Error: MeteorError, + user: () => { + return { username: "unit-test" }; + }, }; const Random = { - id : () => {}, + id: () => {}, }; const i18n = { - setLocale : sinon.stub(), - getLocale : sinon.stub(), - __ : sinon.stub(), + setLocale: sinon.stub(), + getLocale: sinon.stub(), + __: sinon.stub(), }; -const {Priority} = rewiremock.proxy("#root/imports/priority", { - "meteor/universe:i18n" : {i18n, "@noCallThru" : true}, +const { Priority } = rewiremock.proxy("#root/imports/priority", { + "meteor/universe:i18n": { i18n, "@noCallThru": true }, }); -const {InfoItem} = rewiremock.proxy("#root/imports/infoitem", { - "meteor/meteor" : Meteor, - "meteor/random" : Random, - "/imports/user" : {null : null, "@noCallThru" : true}, - lodash : _, - "./topic" : Topic, - "./label" : Label, +const { InfoItem } = rewiremock.proxy("#root/imports/infoitem", { + "meteor/meteor": Meteor, + "meteor/random": Random, + "/imports/user": { null: null, "@noCallThru": true }, + lodash: _, + "./topic": Topic, + "./label": Label, }); -const {ActionItem} = rewiremock.proxy("#root/imports/actionitem", { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "/imports/priority" : {Priority, "@noCallThru" : true}, - "./infoitem" : {InfoItem, "@noCallThru" : true}, +const { ActionItem } = rewiremock.proxy("#root/imports/actionitem", { + "meteor/meteor": { Meteor, "@noCallThru": true }, + "/imports/priority": { Priority, "@noCallThru": true }, + "./infoitem": { InfoItem, "@noCallThru": true }, }); -describe("ActionItem", function() { +describe("ActionItem", function () { let dummyTopic; let infoItemDoc; - beforeEach(function() { + beforeEach(function () { dummyTopic = { - _id : "AaBbCcDd", - save : doNothing, - findInfoItem : doNothing, + _id: "AaBbCcDd", + save: doNothing, + findInfoItem: doNothing, }; infoItemDoc = { - _id : "AaBbCcDd01", - createdInMinute : "AaBbCcDd01", - subject : "infoItemDoc", - createdAt : new Date(), - details : [ + _id: "AaBbCcDd01", + createdInMinute: "AaBbCcDd01", + subject: "infoItemDoc", + createdAt: new Date(), + details: [ { - date : "2016-05-06", - text : "details Text", + date: "2016-05-06", + text: "details Text", }, ], }; }); - describe("#constructor", function() { - it("sets the reference to the parent topic correctly", function() { + describe("#constructor", function () { + it("sets the reference to the parent topic correctly", function () { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); // the infoItem should have a reference of our dummyTopic expect(myActionItem._parentTopic).to.equal(dummyTopic); }); - it("sets the document correctly", function() { + it("sets the document correctly", function () { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); // the doc should be equal to our initial document expect(myActionItem._infoItemDoc).to.deep.equal(infoItemDoc); }); - it("sets the initial value for the isOpen-flag correctly", function() { + it("sets the initial value for the isOpen-flag correctly", function () { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); // the isOpen-filed should be initially true for a new actionItem expect(myActionItem._infoItemDoc.isOpen).to.be.true; }); - it("sets the initial value for the isNew-flag correctly", function() { + it("sets the initial value for the isNew-flag correctly", function () { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); // the isOpen-filed should be initially true for a new actionItem expect(myActionItem._infoItemDoc.isNew).to.be.true; }); }); - it("#getDateFromDetails", function() { + it("#getDateFromDetails", function () { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); - expect(myActionItem.getDateFromDetails()) - .to.equal(infoItemDoc.details[0].date); + expect(myActionItem.getDateFromDetails()).to.equal( + infoItemDoc.details[0].date, + ); }); - it("#getTextFromDetails", function() { + it("#getTextFromDetails", function () { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); - expect(myActionItem.getTextFromDetails()) - .to.equal(infoItemDoc.details[0].text); + expect(myActionItem.getTextFromDetails()).to.equal( + infoItemDoc.details[0].text, + ); }); - it("#toggleState", function() { + it("#toggleState", function () { const myActionItem = new ActionItem(dummyTopic, infoItemDoc); const oldState = myActionItem._infoItemDoc.isOpen; diff --git a/tests/unit/imports/GlobalSettings.test.js b/tests/unit/imports/GlobalSettings.test.js index 818e8ac2b..e7f92b42b 100644 --- a/tests/unit/imports/GlobalSettings.test.js +++ b/tests/unit/imports/GlobalSettings.test.js @@ -1,4 +1,4 @@ -import {expect} from "chai"; +import { expect } from "chai"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -6,14 +6,12 @@ import rewiremock from "../../test-helper/rewiremock.cjs"; class MeteorError {} const Meteor = { - Error : MeteorError, - absoluteUrl : (path, config) => { - if (!path) - path = ""; + Error: MeteorError, + absoluteUrl: (path, config) => { + if (!path) path = ""; if (config?.rootUrl) { - if (path !== "") - path = `/${path}`; + if (path !== "") path = `/${path}`; return config.rootUrl + path; } return path; @@ -21,101 +19,94 @@ const Meteor = { }; const LdapSettings = { - publish : sinon.stub(), + publish: sinon.stub(), }; -const {GlobalSettings} = rewiremock.proxy( - "#root/imports/config/GlobalSettings", - { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "/imports/config/LdapSettings" : {LdapSettings, "@noCallThru" : true}, - }, +const { GlobalSettings } = rewiremock.proxy( + "#root/imports/config/GlobalSettings", + { + "meteor/meteor": { Meteor, "@noCallThru": true }, + "/imports/config/LdapSettings": { LdapSettings, "@noCallThru": true }, + }, ); -describe("GlobalSettings", function() { - beforeEach("publish public settings", function() { +describe("GlobalSettings", function () { + beforeEach("publish public settings", function () { Meteor.settings = require("../../../settings_sample.json"); GlobalSettings.publishSettings(); }); - describe("#getRootUrl", function() { - it("returns the correct value", function() { + describe("#getRootUrl", function () { + it("returns the correct value", function () { expect(GlobalSettings.getRootUrl()).to.equal(Meteor.settings.ROOT_URL); }); - it("returns an empty string if property is not set", function() { + it("returns an empty string if property is not set", function () { delete Meteor.settings.ROOT_URL; expect(GlobalSettings.getRootUrl()).to.equal(""); }); - it("does not fail if no settings file give", function() { + it("does not fail if no settings file give", function () { Meteor.settings = {}; expect(GlobalSettings.getRootUrl()).to.equal(""); }); }); - describe("#isTrustedIntranetInstallation", function() { - it("returns the correct value", function() { - expect(GlobalSettings.isTrustedIntranetInstallation()) - .to.equal( - Meteor.settings.trustedIntranetInstallation, - ); + describe("#isTrustedIntranetInstallation", function () { + it("returns the correct value", function () { + expect(GlobalSettings.isTrustedIntranetInstallation()).to.equal( + Meteor.settings.trustedIntranetInstallation, + ); }); - it("returns false if property is not set", function() { + it("returns false if property is not set", function () { delete Meteor.settings.trustedIntranetInstallation; expect(GlobalSettings.isTrustedIntranetInstallation()).to.be.false; }); - it("does not fail if no settings file give", function() { + it("does not fail if no settings file give", function () { Meteor.settings = {}; expect(GlobalSettings.isTrustedIntranetInstallation()).to.be.false; }); }); - describe("#getDefaultEmailSenderAddress", function() { - it("returns the default email sender address", function() { - expect(GlobalSettings.getDefaultEmailSenderAddress()) - .to.equal( - Meteor.settings.email.defaultEMailSenderAddress, - ); - }); - - it("returns the alternative address of the current user if property is left empty", - function() { - Meteor.settings.email.defaultEMailSenderAddress = ""; - const alternative = "alternativeSenderAddress"; - expect(GlobalSettings.getDefaultEmailSenderAddress(alternative)) - .to.equal( - alternative, - ); - }); - - it("returns fallback sender address if no alternative address is given", - function() { - Meteor.settings.email.defaultEMailSenderAddress = ""; - expect(GlobalSettings.getDefaultEmailSenderAddress()) - .to.equal( - Meteor.settings.email.fallbackEMailSenderAddress, - ); - }); - - it("throws exception if fallback sender address required but not given", - function() { - Meteor.settings.email.defaultEMailSenderAddress = ""; - delete Meteor.settings.email.fallbackEMailSenderAddress; - let exceptionThrown; - try { - GlobalSettings.getDefaultEmailSenderAddress(); - exceptionThrown = false; - } catch (e) { - exceptionThrown = e instanceof MeteorError; - } - - expect(exceptionThrown, "Method did not throw exception").to.be.true; - }); - - it("throws exception if property is not set", function() { + describe("#getDefaultEmailSenderAddress", function () { + it("returns the default email sender address", function () { + expect(GlobalSettings.getDefaultEmailSenderAddress()).to.equal( + Meteor.settings.email.defaultEMailSenderAddress, + ); + }); + + it("returns the alternative address of the current user if property is left empty", function () { + Meteor.settings.email.defaultEMailSenderAddress = ""; + const alternative = "alternativeSenderAddress"; + expect(GlobalSettings.getDefaultEmailSenderAddress(alternative)).to.equal( + alternative, + ); + }); + + it("returns fallback sender address if no alternative address is given", function () { + Meteor.settings.email.defaultEMailSenderAddress = ""; + expect(GlobalSettings.getDefaultEmailSenderAddress()).to.equal( + Meteor.settings.email.fallbackEMailSenderAddress, + ); + }); + + it("throws exception if fallback sender address required but not given", function () { + Meteor.settings.email.defaultEMailSenderAddress = ""; + delete Meteor.settings.email.fallbackEMailSenderAddress; + let exceptionThrown; + try { + GlobalSettings.getDefaultEmailSenderAddress(); + exceptionThrown = false; + } catch (e) { + exceptionThrown = e instanceof MeteorError; + } + + expect(exceptionThrown, "Method did not throw exception").to.be.true; + }); + + it("throws exception if property is not set", function () { delete Meteor.settings.email.defaultEMailSenderAddress; let exceptionThrown; @@ -130,73 +121,69 @@ describe("GlobalSettings", function() { }); }); - describe("#isEMailDeliveryEnabled", function() { - it("returns the correct value", function() { - expect(GlobalSettings.isEMailDeliveryEnabled()) - .to.equal( - Meteor.settings.email.enableMailDelivery, - ); + describe("#isEMailDeliveryEnabled", function () { + it("returns the correct value", function () { + expect(GlobalSettings.isEMailDeliveryEnabled()).to.equal( + Meteor.settings.email.enableMailDelivery, + ); }); - it("returns false if property is not set", function() { + it("returns false if property is not set", function () { delete Meteor.settings.email.enableMailDelivery; GlobalSettings.publishSettings(); expect(GlobalSettings.isEMailDeliveryEnabled()).to.be.false; }); - it("does not fail if no settings file give", function() { + it("does not fail if no settings file give", function () { Meteor.settings = {}; expect(GlobalSettings.isEMailDeliveryEnabled()).to.be.false; }); }); - describe("#getMailDeliverer", function() { - it("returns the correct value", function() { - expect(GlobalSettings.getMailDeliverer()) - .to.equal( - Meteor.settings.email.mailDeliverer, - ); + describe("#getMailDeliverer", function () { + it("returns the correct value", function () { + expect(GlobalSettings.getMailDeliverer()).to.equal( + Meteor.settings.email.mailDeliverer, + ); }); - it("returns smtp if property is not set", function() { + it("returns smtp if property is not set", function () { delete Meteor.settings.email.mailDeliverer; expect(GlobalSettings.getMailDeliverer()).to.equal("smtp"); }); - it("does not fail if no settings file give", function() { + it("does not fail if no settings file give", function () { Meteor.settings = {}; expect(GlobalSettings.getMailDeliverer()).to.equal("smtp"); }); }); - describe("#getSMTPMailUrl", function() { - it("returns the correct value", function() { - expect(GlobalSettings.getSMTPMailUrl()) - .to.equal( - Meteor.settings.email.smtp.mailUrl, - ); + describe("#getSMTPMailUrl", function () { + it("returns the correct value", function () { + expect(GlobalSettings.getSMTPMailUrl()).to.equal( + Meteor.settings.email.smtp.mailUrl, + ); }); - it("returns an empty string if property is not set", function() { + it("returns an empty string if property is not set", function () { delete Meteor.settings.email.smtp.mailUrl; expect(GlobalSettings.getSMTPMailUrl()).to.equal(""); }); - it("does not fail if no settings file give", function() { + it("does not fail if no settings file give", function () { Meteor.settings = {}; expect(GlobalSettings.getSMTPMailUrl()).to.equal(""); }); }); - describe("#getMailgunSettings", function() { - it("returns the correct value", function() { - expect(GlobalSettings.getMailgunSettings()) - .to.equal( - Meteor.settings.email.mailgun, - ); + describe("#getMailgunSettings", function () { + it("returns the correct value", function () { + expect(GlobalSettings.getMailgunSettings()).to.equal( + Meteor.settings.email.mailgun, + ); }); - it("throws exception if property is not set", function() { + it("throws exception if property is not set", function () { delete Meteor.settings.email.mailgun; let exceptionThrown; diff --git a/tests/unit/imports/InfoItem.test.js b/tests/unit/imports/InfoItem.test.js index 4efe1ae98..4d1b7bfdf 100644 --- a/tests/unit/imports/InfoItem.test.js +++ b/tests/unit/imports/InfoItem.test.js @@ -1,10 +1,10 @@ -import {expect} from "chai"; +import { expect } from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; import * as Helpers from "../../../imports/helpers/date"; -import {subElementsHelper} from "../../../imports/helpers/subElements"; +import { subElementsHelper } from "../../../imports/helpers/subElements"; import rewiremock from "../../test-helper/rewiremock.cjs"; const Topic = {}; @@ -14,42 +14,43 @@ Helpers["@noCallThru"] = true; class MeteorError {} const Meteor = { - Error : MeteorError, - user : () => { return {username : "unit-test"}; }, + Error: MeteorError, + user: () => { + return { username: "unit-test" }; + }, }; const Random = { - id : () => {}, + id: () => {}, }; const User = { - profileNameWithFallback : sinon.stub(), + profileNameWithFallback: sinon.stub(), }; -const {InfoItem} = rewiremock.proxy("#root/imports/infoitem", { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "meteor/random" : {Random, "@noCallThru" : true}, - lodash : {_, "@noCallThru" : true}, - "/imports/user" : {User, "@noCallThru" : true}, - "/imports/helpers/date" : Helpers, - "./topic" : {Topic, "@noCallThru" : true}, - "./label" : {Label, "@noCallThru" : true}, +const { InfoItem } = rewiremock.proxy("#root/imports/infoitem", { + "meteor/meteor": { Meteor, "@noCallThru": true }, + "meteor/random": { Random, "@noCallThru": true }, + lodash: { _, "@noCallThru": true }, + "/imports/user": { User, "@noCallThru": true }, + "/imports/helpers/date": Helpers, + "./topic": { Topic, "@noCallThru": true }, + "./label": { Label, "@noCallThru": true }, }); // skipcq: JS-0241 -describe("InfoItem", function() { +describe("InfoItem", function () { let dummyTopic; let infoItemDoc; // skipcq: JS-0241 - beforeEach(function() { + beforeEach(function () { dummyTopic = { - _id : "AaBbCcDd", - _infoItems : [], - upsertInfoItem : sinon.stub(), + _id: "AaBbCcDd", + _infoItems: [], + upsertInfoItem: sinon.stub(), findInfoItem(id) { const index = subElementsHelper.findIndexById(id, this._infoItems); - if (index === undefined) - return undefined; + if (index === undefined) return undefined; return new InfoItem(this, this._infoItems[index]); }, // test-only method @@ -60,65 +61,62 @@ describe("InfoItem", function() { }; infoItemDoc = { - _id : "AaBbCcDd01", - subject : "infoItemDoc", - createdAt : new Date(), - createdInMinute : "AaBbCcDd01", + _id: "AaBbCcDd01", + subject: "infoItemDoc", + createdAt: new Date(), + createdInMinute: "AaBbCcDd01", }; }); // skipcq: JS-0241 - describe("#constructor", function() { + describe("#constructor", function () { // skipcq: JS-0241 - it("sets the reference to the parent topic correctly", function() { + it("sets the reference to the parent topic correctly", function () { const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); // the infoItem should have a reference of our dummyTopic expect(myInfoItem._parentTopic).to.equal(dummyTopic); }); // skipcq: JS-0241 - it("sets the document correctly", function() { + it("sets the document correctly", function () { const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); // the doc should be equal to our initial document expect(myInfoItem._infoItemDoc).to.equal(infoItemDoc); }); // skipcq: JS-0241 - it("creates the same object by passing the id of an existing one", - function() { - const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); - // add the created info item to our dummy topic - dummyTopic.addInfoItem(myInfoItem); + it("creates the same object by passing the id of an existing one", function () { + const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); + // add the created info item to our dummy topic + dummyTopic.addInfoItem(myInfoItem); - // Now we should be able to create the same info item again - // by passing the dummyTopic together with the info items id - const sameInfoItem = new InfoItem( - dummyTopic, - myInfoItem._infoItemDoc._id, - ); - // the associated documents of both info items should be the same - expect(sameInfoItem._infoItemDoc).to.equal(myInfoItem._infoItemDoc); - }); + // Now we should be able to create the same info item again + // by passing the dummyTopic together with the info items id + const sameInfoItem = new InfoItem( + dummyTopic, + myInfoItem._infoItemDoc._id, + ); + // the associated documents of both info items should be the same + expect(sameInfoItem._infoItemDoc).to.equal(myInfoItem._infoItemDoc); + }); }); // skipcq: JS-0241 - it("#isActionItem", function() { + it("#isActionItem", function () { const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); expect( - myInfoItem.isActionItem(), - "Item without the itemType-property should not be an ActionItem", - ) - .to.be.false; + myInfoItem.isActionItem(), + "Item without the itemType-property should not be an ActionItem", + ).to.be.false; const actionItemDoc = { - _id : "AaBbCcDd02", - subject : "actionItemDoc", - itemType : "actionItem", + _id: "AaBbCcDd02", + subject: "actionItemDoc", + itemType: "actionItem", }; expect( - InfoItem.isActionItem(actionItemDoc), - "Item with the itemType-property set to actionItem should be an ActionItem", - ) - .to.be.true; + InfoItem.isActionItem(actionItemDoc), + "Item with the itemType-property set to actionItem should be an ActionItem", + ).to.be.true; }); // skipcq: JS-0241 - it("#save", function() { + it("#save", function () { const myInfoItem = new InfoItem(dummyTopic, infoItemDoc); myInfoItem.save(); diff --git a/tests/unit/imports/InfoItemFactory.test.js b/tests/unit/imports/InfoItemFactory.test.js index c5b827c49..9b9d2c25f 100644 --- a/tests/unit/imports/InfoItemFactory.test.js +++ b/tests/unit/imports/InfoItemFactory.test.js @@ -1,14 +1,14 @@ -import {expect} from "chai"; +import { expect } from "chai"; import proxyquire from "proxyquire"; import rewiremock from "../../test-helper/rewiremock.cjs"; const TestSetup = { - nextItemIsAnActionItem : false, - infoItemConstructorCallCount : 0, - actionItemConstructorCallCount : 0, - infoItemConstructorArguments : [], - actionItemConstructorArguments : [], + nextItemIsAnActionItem: false, + infoItemConstructorCallCount: 0, + actionItemConstructorCallCount: 0, + infoItemConstructorArguments: [], + actionItemConstructorArguments: [], reset() { this.nextItemIsAnActionItem = false; this.infoItemConstructorCallCount = 0; @@ -23,7 +23,9 @@ class InfoItem { TestSetup.infoItemConstructorCallCount++; TestSetup.infoItemConstructorArguments.push(arguments); } - static isActionItem() { return TestSetup.nextItemIsAnActionItem; } + static isActionItem() { + return TestSetup.nextItemIsAnActionItem; + } } class ActionItem { @@ -33,13 +35,15 @@ class ActionItem { } } -const {InfoItemFactory} = rewiremock.proxy("#root/imports/InfoItemFactory", { - "./infoitem" : {InfoItem, "@noCallThru" : true}, - "./actionitem" : {ActionItem, "@noCallThru" : true}, +const { InfoItemFactory } = rewiremock.proxy("#root/imports/InfoItemFactory", { + "./infoitem": { InfoItem, "@noCallThru": true }, + "./actionitem": { ActionItem, "@noCallThru": true }, }); describe("InfoItemFactory", () => { - afterEach(() => { TestSetup.reset(); }); + afterEach(() => { + TestSetup.reset(); + }); describe("#createInfoItem", () => { let infoItemDoc, parentItemDoc; @@ -50,51 +54,44 @@ describe("InfoItemFactory", () => { }; beforeEach(() => { - infoItemDoc = {name : "A Info Item"}; - parentItemDoc = {name : "A Parent Item"}; + infoItemDoc = { name: "A Info Item" }; + parentItemDoc = { name: "A Parent Item" }; }); - it("should call the info item constructor if InfoItem.isActionItem returns false", - () => { - InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); - expect( - TestSetup.infoItemConstructorCallCount, - "InfoItem constructor should have been called once", - ) - .to.equal(1); - expect( - TestSetup.actionItemConstructorCallCount, - "actionItem constructor should not have been called", - ) - .to.equal(0); - }); + it("should call the info item constructor if InfoItem.isActionItem returns false", () => { + InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); + expect( + TestSetup.infoItemConstructorCallCount, + "InfoItem constructor should have been called once", + ).to.equal(1); + expect( + TestSetup.actionItemConstructorCallCount, + "actionItem constructor should not have been called", + ).to.equal(0); + }); - it("should create a new info item if InfoItem.isActionItem returns true", - () => { - TestSetup.nextItemIsAnActionItem = true; - InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); - expect( - TestSetup.infoItemConstructorCallCount, - "InfoItem constructor should not have been called", - ) - .to.equal(0); - expect( - TestSetup.actionItemConstructorCallCount, - "actionItem constructor should have been called once", - ) - .to.equal(1); - }); + it("should create a new info item if InfoItem.isActionItem returns true", () => { + TestSetup.nextItemIsAnActionItem = true; + InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); + expect( + TestSetup.infoItemConstructorCallCount, + "InfoItem constructor should not have been called", + ).to.equal(0); + expect( + TestSetup.actionItemConstructorCallCount, + "actionItem constructor should have been called once", + ).to.equal(1); + }); it("should pass the correct arguments to the info item constructor", () => { InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); verifyArguments(TestSetup.infoItemConstructorArguments); }); - it("should pass the correct arguments to the action item constructor", - () => { - TestSetup.nextItemIsAnActionItem = true; - InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); - verifyArguments(TestSetup.actionItemConstructorArguments); - }); + it("should pass the correct arguments to the action item constructor", () => { + TestSetup.nextItemIsAnActionItem = true; + InfoItemFactory.createInfoItem(parentItemDoc, infoItemDoc); + verifyArguments(TestSetup.actionItemConstructorArguments); + }); }); }); diff --git a/tests/unit/imports/MeetingSeries.test.js b/tests/unit/imports/MeetingSeries.test.js index 7a2823218..5f3491f90 100644 --- a/tests/unit/imports/MeetingSeries.test.js +++ b/tests/unit/imports/MeetingSeries.test.js @@ -1,4 +1,4 @@ -import {expect} from "chai"; +import { expect } from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -9,47 +9,49 @@ import rewiremock from "../../test-helper/rewiremock.cjs"; const MeetingSeriesSchema = {}; const Meteor = { - call : sinon.stub(), - callAsync : sinon.stub(), + call: sinon.stub(), + callAsync: sinon.stub(), }; const Minutes = {}; const Topic = {}; const UserRoles = {}; const PromisedMethods = {}; const MinutesFinder = { - result : undefined, - lastMinutesOfMeetingSeries() { return this.result; }, + result: undefined, + lastMinutesOfMeetingSeries() { + return this.result; + }, }; DateHelpers["@noCallThru"] = true; SubElements["@noCallThru"] = true; const Random = { - id : () => {}, + id: () => {}, }; const jQuery = {}; const TopicsFinder = {}; -const {MeetingSeries} = rewiremock.proxy("#root/imports/meetingseries", { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "meteor/random" : {Random, "@noCallThru" : true}, - "meteor/jquery" : {jQuery, "@noCallThru" : true}, - "./collections/meetingseries.schema" : { +const { MeetingSeries } = rewiremock.proxy("#root/imports/meetingseries", { + "meteor/meteor": { Meteor, "@noCallThru": true }, + "meteor/random": { Random, "@noCallThru": true }, + "meteor/jquery": { jQuery, "@noCallThru": true }, + "./collections/meetingseries.schema": { MeetingSeriesSchema, - "@noCallThru" : true, + "@noCallThru": true, }, - "./collections/meetingseries_private" : { + "./collections/meetingseries_private": { MeetingSeriesSchema, - "@noCallThru" : true, + "@noCallThru": true, }, - "./helpers/promisedMethods" : {PromisedMethods, "@noCallThru" : true}, - "./minutes" : {Minutes, "@noCallThru" : true}, - "./topic" : {Topic, "@noCallThru" : true}, - "./userroles" : {UserRoles, "@noCallThru" : true}, - "/imports/helpers/date" : DateHelpers, - "/imports/helpers/subElements" : SubElements, - lodash : {_, "@noCallThru" : true}, - "./services/topicsFinder" : {TopicsFinder, "@noCallThru" : true}, - "/imports/services/minutesFinder" : {MinutesFinder, "@noCallThru" : true}, + "./helpers/promisedMethods": { PromisedMethods, "@noCallThru": true }, + "./minutes": { Minutes, "@noCallThru": true }, + "./topic": { Topic, "@noCallThru": true }, + "./userroles": { UserRoles, "@noCallThru": true }, + "/imports/helpers/date": DateHelpers, + "/imports/helpers/subElements": SubElements, + lodash: { _, "@noCallThru": true }, + "./services/topicsFinder": { TopicsFinder, "@noCallThru": true }, + "/imports/services/minutesFinder": { MinutesFinder, "@noCallThru": true }, }); describe("MeetingSeries", () => { @@ -58,8 +60,8 @@ describe("MeetingSeries", () => { beforeEach(() => { meetingSeries = { - project : "foo", - name : "bar", + project: "foo", + name: "bar", }; }); @@ -79,7 +81,9 @@ describe("MeetingSeries", () => { describe("#getMinimumAllowedDateForMinutes", () => { let series; - beforeEach(() => { series = new MeetingSeries(); }); + beforeEach(() => { + series = new MeetingSeries(); + }); afterEach(() => { if (Object.prototype.hasOwnProperty.call(Minutes, "findAllIn")) { @@ -88,71 +92,67 @@ describe("MeetingSeries", () => { }); function compareDates(actualDate, expectedDate) { - expect(actualDate.getYear(), "year mismatch") - .to.be.equal( - expectedDate.getYear(), - ); - expect(actualDate.getMonth(), "month mismatch") - .to.be.equal( - expectedDate.getMonth(), - ); - expect(actualDate.getDay(), "day mismatch") - .to.be.equal( - expectedDate.getDay(), - ); + expect(actualDate.getYear(), "year mismatch").to.be.equal( + expectedDate.getYear(), + ); + expect(actualDate.getMonth(), "month mismatch").to.be.equal( + expectedDate.getMonth(), + ); + expect(actualDate.getDay(), "day mismatch").to.be.equal( + expectedDate.getDay(), + ); } it("retrieves the date of the lastMinutes() if no id is given", () => { const expectedDate = new Date(); - MinutesFinder.result = {date : expectedDate}; + MinutesFinder.result = { date: expectedDate }; const actualDate = series.getMinimumAllowedDateForMinutes(); compareDates(actualDate, expectedDate); }); - it("gets the date from the second to last minute if id of last minute is given", - () => { - let lastMinuteId = "lastMinuteId", expectedDate = new Date(); - - Minutes.findAllIn = sinon.stub().returns([ - { - _id : "someid", - date : expectedDate, - }, - { - _id : lastMinuteId, - date : new Date(2013, 12, 11, 0, 0), - }, - ]); - - const actualDate = - series.getMinimumAllowedDateForMinutes(lastMinuteId); - - compareDates(actualDate, expectedDate); - }); - - it("gets the date from the last minute if id of second to last minute is given", - () => { - let secondToLastMinuteId = "minuteId", expectedDate = new Date(); - - Minutes.findAllIn = sinon.stub().returns([ - { - _id : secondToLastMinuteId, - date : new Date(2013, 12, 11, 0, 0), - }, - { - _id : "last minute", - date : expectedDate, - }, - ]); - - const actualDate = - series.getMinimumAllowedDateForMinutes(secondToLastMinuteId); - - compareDates(actualDate, expectedDate); - }); + it("gets the date from the second to last minute if id of last minute is given", () => { + let lastMinuteId = "lastMinuteId", + expectedDate = new Date(); + + Minutes.findAllIn = sinon.stub().returns([ + { + _id: "someid", + date: expectedDate, + }, + { + _id: lastMinuteId, + date: new Date(2013, 12, 11, 0, 0), + }, + ]); + + const actualDate = series.getMinimumAllowedDateForMinutes(lastMinuteId); + + compareDates(actualDate, expectedDate); + }); + + it("gets the date from the last minute if id of second to last minute is given", () => { + let secondToLastMinuteId = "minuteId", + expectedDate = new Date(); + + Minutes.findAllIn = sinon.stub().returns([ + { + _id: secondToLastMinuteId, + date: new Date(2013, 12, 11, 0, 0), + }, + { + _id: "last minute", + date: expectedDate, + }, + ]); + + const actualDate = + series.getMinimumAllowedDateForMinutes(secondToLastMinuteId); + + compareDates(actualDate, expectedDate); + }); }); describe("#save", () => { @@ -160,8 +160,8 @@ describe("MeetingSeries", () => { beforeEach(() => { meetingSeries = new MeetingSeries({ - project : "foo", - name : "bar", + project: "foo", + name: "bar", }); }); @@ -175,7 +175,7 @@ describe("MeetingSeries", () => { meetingSeries.save(); expect(Meteor.callAsync.calledWith("meetingseries.insert", meetingSeries)) - .to.be.true; + .to.be.true; }); }); }); diff --git a/tests/unit/imports/Minutes.test.js b/tests/unit/imports/Minutes.test.js index b3f7bebc2..fd7eb8387 100644 --- a/tests/unit/imports/Minutes.test.js +++ b/tests/unit/imports/Minutes.test.js @@ -1,4 +1,4 @@ -import {expect} from "chai"; +import { expect } from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -9,8 +9,8 @@ import * as SubElements from "../../../imports/helpers/subElements"; import rewiremock from "../../test-helper/rewiremock.cjs"; const MinutesSchema = { - find : sinon.stub(), - findOne : sinon.stub(), + find: sinon.stub(), + findOne: sinon.stub(), }; MinutesSchema.getCollection = (_) => MinutesSchema; @@ -18,9 +18,9 @@ MinutesSchema.getCollection = (_) => MinutesSchema; class MeteorError {} const Meteor = { - call : sinon.stub(), - callAsync : sinon.stub().resolves(true), - Error : MeteorError, + call: sinon.stub(), + callAsync: sinon.stub().resolves(true), + Error: MeteorError, }; const PromisedMethods = {}; @@ -28,7 +28,7 @@ const PromisedMethods = {}; const isCurrentUserModeratorStub = sinon.stub(); const updateLastMinutesFieldsStub = sinon.stub(); const updateLastMinutesFieldsAsyncStub = sinon.stub().resolves(true); -const MeetingSeries = function(seriesId) { +const MeetingSeries = function (seriesId) { this._id = seriesId; this.isCurrentUserModerator = isCurrentUserModeratorStub; this.updateLastMinutesFields = updateLastMinutesFieldsStub; @@ -36,11 +36,14 @@ const MeetingSeries = function(seriesId) { }; const topicGetOpenActionItemsStub = sinon.stub().returns([]); -const Topic = - function() { this.getOpenActionItems = topicGetOpenActionItemsStub; }; -Topic.hasOpenActionItem = () => { return false; }; +const Topic = function () { + this.getOpenActionItems = topicGetOpenActionItemsStub; +}; +Topic.hasOpenActionItem = () => { + return false; +}; -const ActionItem = function(topic, doc) { +const ActionItem = function (topic, doc) { this._parentTopic = topic; this._infoItemDoc = doc; }; @@ -48,23 +51,23 @@ const ActionItem = function(topic, doc) { SubElements["@noCallThru"] = true; EmailHelpers["@noCallThru"] = true; const Random = { - id : () => {}, + id: () => {}, }; -const {Minutes} = rewiremock.proxy("#root/imports/minutes", { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "meteor/universe:i18n" : {Meteor, "@noCallThru" : true}, - "meteor/random" : {Random, "@noCallThru" : true}, - "./collections/minutes_private" : {MinutesSchema, "@noCallThru" : true}, - "./collections/minutes.schema" : {MinutesSchema, "@noCallThru" : true}, - "./collections/workflow_private" : {null : null, "@noCallThru" : true}, - "./helpers/promisedMethods" : {PromisedMethods, "@noCallThru" : true}, - "./meetingseries" : {MeetingSeries, "@noCallThru" : true}, - "./topic" : {Topic, "@noCallThru" : true}, - "/imports/user" : {null : null, "@noCallThru" : true}, - "./actionitem" : {ActionItem, "@noCallThru" : true}, - "/imports/helpers/email" : EmailHelpers, - "/imports/helpers/subElements" : SubElements, - lodash : {_, "@noCallThru" : true}, +const { Minutes } = rewiremock.proxy("#root/imports/minutes", { + "meteor/meteor": { Meteor, "@noCallThru": true }, + "meteor/universe:i18n": { Meteor, "@noCallThru": true }, + "meteor/random": { Random, "@noCallThru": true }, + "./collections/minutes_private": { MinutesSchema, "@noCallThru": true }, + "./collections/minutes.schema": { MinutesSchema, "@noCallThru": true }, + "./collections/workflow_private": { null: null, "@noCallThru": true }, + "./helpers/promisedMethods": { PromisedMethods, "@noCallThru": true }, + "./meetingseries": { MeetingSeries, "@noCallThru": true }, + "./topic": { Topic, "@noCallThru": true }, + "/imports/user": { null: null, "@noCallThru": true }, + "./actionitem": { ActionItem, "@noCallThru": true }, + "/imports/helpers/email": EmailHelpers, + "/imports/helpers/subElements": SubElements, + lodash: { _, "@noCallThru": true }, }); describe("Minutes", () => { @@ -72,14 +75,14 @@ describe("Minutes", () => { beforeEach(() => { minutesDoc = { - meetingSeries_id : "AaBbCc01", - _id : "AaBbCc02", - date : "2016-05-06", - createdAt : new Date(), - topics : [], - isFinalized : false, - participants : "", - agenda : "", + meetingSeries_id: "AaBbCc01", + _id: "AaBbCc02", + date: "2016-05-06", + createdAt: new Date(), + topics: [], + isFinalized: false, + participants: "", + agenda: "", }; minute = new Minutes(minutesDoc); @@ -103,52 +106,47 @@ describe("Minutes", () => { it("fetches the minute from the database if the id was given", () => { new Minutes(minutesDoc._id); expect(MinutesSchema.findOne.calledOnce, "findOne should be called once") - .to.be.true; + .to.be.true; expect( - MinutesSchema.findOne.calledWith(minutesDoc._id), - "findOne should be called with the id", - ) - .to.be.true; - }); - - it("throws exception if constructor will be called without any arguments", - () => { - let exceptionThrown; - try { - new Minutes(); - exceptionThrown = false; - } catch (e) { - exceptionThrown = e instanceof MeteorError; - } - - expect(exceptionThrown).to.be.true; - }); + MinutesSchema.findOne.calledWith(minutesDoc._id), + "findOne should be called with the id", + ).to.be.true; + }); + + it("throws exception if constructor will be called without any arguments", () => { + let exceptionThrown; + try { + new Minutes(); + exceptionThrown = false; + } catch (e) { + exceptionThrown = e instanceof MeteorError; + } + + expect(exceptionThrown).to.be.true; + }); }); describe("find", () => { it("#find", () => { Minutes.find("myArg"); expect(MinutesSchema.find.calledOnce, "find-Method should be called once") - .to.be.true; + .to.be.true; expect( - MinutesSchema.find.calledWithExactly("myArg"), - "arguments should be passed", - ) - .to.be.true; + MinutesSchema.find.calledWithExactly("myArg"), + "arguments should be passed", + ).to.be.true; }); it("#findOne", () => { Minutes.findOne("myArg"); expect( - MinutesSchema.findOne.calledOnce, - "findOne-Method should be called once", - ) - .to.be.true; + MinutesSchema.findOne.calledOnce, + "findOne-Method should be called once", + ).to.be.true; expect( - MinutesSchema.findOne.calledWithExactly("myArg"), - "arguments should be passed", - ) - .to.be.true; + MinutesSchema.findOne.calledWithExactly("myArg"), + "arguments should be passed", + ).to.be.true; }); describe("#findAllIn", () => { @@ -156,46 +154,42 @@ describe("Minutes", () => { let limit; beforeEach(() => { - minIdArray = [ "1", "2" ]; + minIdArray = ["1", "2"]; limit = 3; }); it("calls the find-Method of the Collection", () => { Minutes.findAllIn(minIdArray, limit); expect( - MinutesSchema.find.calledOnce, - "find-Method should be called once", - ) - .to.be.true; + MinutesSchema.find.calledOnce, + "find-Method should be called once", + ).to.be.true; }); it("sets the id selector correctly", () => { Minutes.findAllIn(minIdArray, limit); const selector = MinutesSchema.find.getCall(0).args[0]; - expect(selector, "Selector has the property _id") - .to.have.ownProperty( - "_id", - ); + expect(selector, "Selector has the property _id").to.have.ownProperty( + "_id", + ); expect( - selector._id, - "_id-selector has propery $in", - ) - .to.have.ownProperty("$in"); - expect(selector._id.$in, "idArray should be passed") - .to.deep.equal( - minIdArray, - ); + selector._id, + "_id-selector has propery $in", + ).to.have.ownProperty("$in"); + expect(selector._id.$in, "idArray should be passed").to.deep.equal( + minIdArray, + ); }); it("sets the option correctly (sort, no limit)", () => { - const expectedOption = {sort : {date : -1}}; + const expectedOption = { sort: { date: -1 } }; Minutes.findAllIn(minIdArray); const options = MinutesSchema.find.getCall(0).args[1]; expect(options).to.deep.equal(expectedOption); }); it("sets the option correctly (sort and limit)", () => { - const expectedOption = {sort : {date : -1}, limit}; + const expectedOption = { sort: { date: -1 }, limit }; Minutes.findAllIn(minIdArray, limit); const options = MinutesSchema.find.getCall(0).args[1]; expect(options).to.deep.equal(expectedOption); @@ -212,10 +206,8 @@ describe("Minutes", () => { it("sends the minutes id to the meteor method minutes.remove", () => { Minutes.remove(minute._id); expect( - Meteor.callAsync.calledWithExactly("workflow.removeMinute", - minute._id), - ) - .to.be.true; + Meteor.callAsync.calledWithExactly("workflow.removeMinute", minute._id), + ).to.be.true; }); }); @@ -223,7 +215,7 @@ describe("Minutes", () => { let visibleForArray, parentSeriesId; beforeEach(() => { - visibleForArray = [ "1", "2" ]; + visibleForArray = ["1", "2"]; parentSeriesId = minute.meetingSeries_id; }); @@ -232,18 +224,16 @@ describe("Minutes", () => { expect(Meteor.callAsync.calledOnce).to.be.true; }); - it("sends the parentSeriesId and the visibleFor-array to the meteor method minutes.syncVisibilityAndParticipants", - () => { - Minutes.syncVisibility(parentSeriesId, visibleForArray); - expect( - Meteor.callAsync.calledWithExactly( - "minutes.syncVisibilityAndParticipants", - parentSeriesId, - visibleForArray, - ), - ) - .to.be.true; - }); + it("sends the parentSeriesId and the visibleFor-array to the meteor method minutes.syncVisibilityAndParticipants", () => { + Minutes.syncVisibility(parentSeriesId, visibleForArray); + expect( + Meteor.callAsync.calledWithExactly( + "minutes.syncVisibilityAndParticipants", + parentSeriesId, + visibleForArray, + ), + ).to.be.true; + }); }); describe("#update", () => { @@ -251,7 +241,7 @@ describe("Minutes", () => { beforeEach(() => { updateDocPart = { - date : "2016-05-07", + date: "2016-05-07", }; }); @@ -260,49 +250,44 @@ describe("Minutes", () => { expect(Meteor.callAsync.calledOnce).to.be.true; }); - it("sends the doc part and the minutes id to the meteor method minutes.update", - () => { - minute.update(updateDocPart); - const sentObj = JSON.parse(JSON.stringify(updateDocPart)); - sentObj._id = minute._id; - expect( - Meteor.callAsync.calledWithExactly( - "minutes.update", - sentObj, - undefined, - ), - ) - .to.be.true; - }); - - it("updates the changed property of the minute object", async function() { + it("sends the doc part and the minutes id to the meteor method minutes.update", () => { + minute.update(updateDocPart); + const sentObj = JSON.parse(JSON.stringify(updateDocPart)); + sentObj._id = minute._id; + expect( + Meteor.callAsync.calledWithExactly( + "minutes.update", + sentObj, + undefined, + ), + ).to.be.true; + }); + + it("updates the changed property of the minute object", async function () { await minute.update(updateDocPart); expect(minute.date).to.equal(updateDocPart.date); }); }); describe("#save", () => { - it("calls the meteor method minutes.insert if a new minute will be saved", - () => { - delete minute._id; - minute.save(); - expect(Meteor.call.calledOnce).to.be.true; - }); - - it("uses the workflow.addMinutes method to save a new minutes document", - () => { - delete minute._id; - minute.save(); - expect( - Meteor.call.calledWithExactly( - "workflow.addMinutes", - minute, - undefined, - undefined, - ), - ) - .to.be.true; - }); + it("calls the meteor method minutes.insert if a new minute will be saved", () => { + delete minute._id; + minute.save(); + expect(Meteor.call.calledOnce).to.be.true; + }); + + it("uses the workflow.addMinutes method to save a new minutes document", () => { + delete minute._id; + minute.save(); + expect( + Meteor.call.calledWithExactly( + "workflow.addMinutes", + minute, + undefined, + undefined, + ), + ).to.be.true; + }); it("sets the createdAt-property if it is not set", () => { delete minute._id; @@ -311,31 +296,28 @@ describe("Minutes", () => { expect(minute).to.have.ownProperty("createdAt"); }); - it("calls the meteor method minutes.update if a existing minute will be saved", - () => { - minute.save(); - expect(Meteor.call.calledOnce).to.be.true; - }); + it("calls the meteor method minutes.update if a existing minute will be saved", () => { + minute.save(); + expect(Meteor.call.calledOnce).to.be.true; + }); it("sends the minutes object to the meteor method minutes.update", () => { minute.save(); - expect(Meteor.call.calledWithExactly("minutes.update", minute)) - .to.be.true; + expect(Meteor.call.calledWithExactly("minutes.update", minute)).to.be + .true; }); }); it("#parentMeetingSeries", () => { const parentSeries = minute.parentMeetingSeries(); expect( - parentSeries instanceof MeetingSeries, - "result should be an instance of MeetingSeries", - ) - .to.be.true; + parentSeries instanceof MeetingSeries, + "result should be an instance of MeetingSeries", + ).to.be.true; expect( - parentSeries._id, - "created meeting series object should have the correct series id", - ) - .to.equal(minute.meetingSeries_id); + parentSeries._id, + "created meeting series object should have the correct series id", + ).to.equal(minute.meetingSeries_id); }); it("#parentMeetingSeriesID", () => { @@ -347,28 +329,28 @@ describe("Minutes", () => { beforeEach(() => { topic1 = { - _id : "01", - subject : "firstTopic", - isNew : true, - isOpen : true, + _id: "01", + subject: "firstTopic", + isNew: true, + isOpen: true, }; topic2 = { - _id : "02", - subject : "2ndTopic", - isNew : true, - isOpen : false, + _id: "02", + subject: "2ndTopic", + isNew: true, + isOpen: false, }; topic3 = { - _id : "03", - subject : "3rdTopic", - isNew : false, - isOpen : true, + _id: "03", + subject: "3rdTopic", + isNew: false, + isOpen: true, }; topic4 = { - _id : "04", - subject : "4thTopic", - isNew : false, - isOpen : false, + _id: "04", + subject: "4thTopic", + isNew: false, + isOpen: false, }; minute.topics.push(topic1); minute.topics.push(topic2); @@ -377,11 +359,13 @@ describe("Minutes", () => { }); describe("#findTopic", () => { - it("finds the correct topic identified by its id", - () => { expect(minute.findTopic(topic1._id)).to.deep.equal(topic1); }); + it("finds the correct topic identified by its id", () => { + expect(minute.findTopic(topic1._id)).to.deep.equal(topic1); + }); - it("returns undefined if topic was not found", - () => { expect(minute.findTopic("unknownId")).to.be.undefined; }); + it("returns undefined if topic was not found", () => { + expect(minute.findTopic("unknownId")).to.be.undefined; + }); }); describe("#removeTopic", () => { @@ -398,8 +382,9 @@ describe("Minutes", () => { }); describe("#getNewTopics", () => { - it("returns the correct amount of topics", - () => { expect(minute.getNewTopics()).to.have.length(2); }); + it("returns the correct amount of topics", () => { + expect(minute.getNewTopics()).to.have.length(2); + }); it("returns only new topics", () => { const newTopics = minute.getNewTopics(); @@ -410,17 +395,17 @@ describe("Minutes", () => { }); describe("#getOldClosedTopics", () => { - it("returns the correct amount of topics", - () => { expect(minute.getOldClosedTopics()).to.have.length(1); }); + it("returns the correct amount of topics", () => { + expect(minute.getOldClosedTopics()).to.have.length(1); + }); it("returns only old and closed topics", () => { const oldClosedTopics = minute.getOldClosedTopics(); oldClosedTopics.forEach((topic) => { expect( - topic.isNew && topic.isOpen, - "isNew and isOpen flag should both not set", - ) - .to.be.false; + topic.isNew && topic.isOpen, + "isNew and isOpen flag should both not set", + ).to.be.false; }); }); }); @@ -428,18 +413,16 @@ describe("Minutes", () => { describe("#getOpenActionItems", () => { it("calls the getOpenActionItems method for each topic", () => { minute.getOpenActionItems(); - expect(topicGetOpenActionItemsStub.callCount) - .to.equal( - minute.topics.length, - ); + expect(topicGetOpenActionItemsStub.callCount).to.equal( + minute.topics.length, + ); }); it("concatenates all results of each getOpenActionItems-call", () => { - topicGetOpenActionItemsStub.returns([ 5, 7 ]); - expect(minute.getOpenActionItems()) - .to.have.length( - minute.topics.length * 2, - ); + topicGetOpenActionItemsStub.returns([5, 7]); + expect(minute.getOpenActionItems()).to.have.length( + minute.topics.length * 2, + ); }); }); }); @@ -449,7 +432,7 @@ describe("Minutes", () => { beforeEach(() => { topicDoc = { - subject : "myTopic", + subject: "myTopic", }; }); @@ -457,11 +440,11 @@ describe("Minutes", () => { minute.upsertTopic(topicDoc); expect(Meteor.callAsync.calledOnce).to.be.true; expect( - Meteor.callAsync.calledWithExactly( - "minutes.addTopic", - sinon.match.string, - topicDoc, - ), + Meteor.callAsync.calledWithExactly( + "minutes.addTopic", + sinon.match.string, + topicDoc, + ), ); }); @@ -470,11 +453,11 @@ describe("Minutes", () => { minute.upsertTopic(topicDoc); expect(Meteor.callAsync.calledOnce).to.be.true; expect( - Meteor.callAsync.calledWithExactly( - "minutes.addTopic", - topicDoc._id, - topicDoc, - ), + Meteor.callAsync.calledWithExactly( + "minutes.addTopic", + topicDoc._id, + topicDoc, + ), ); }); @@ -484,15 +467,13 @@ describe("Minutes", () => { topicDoc.subject = "changedSubject"; minute.upsertTopic(topicDoc); expect( - minute.topics, - "update an existing topic should not change the size of the topics array", - ) - .to.have.length(1); + minute.topics, + "update an existing topic should not change the size of the topics array", + ).to.have.length(1); expect( - minute.topics[0].subject, - "the subject should have been updated", - ) - .to.equal(topicDoc.subject); + minute.topics[0].subject, + "the subject should have been updated", + ).to.equal(topicDoc.subject); }); it("calls the meteor method minutes.update", () => { @@ -500,27 +481,24 @@ describe("Minutes", () => { expect(Meteor.callAsync.calledOnce).to.be.true; }); - it("sends the minutes id and the topic doc to the meteor method minutes.addTopic", - () => { - minute.upsertTopic(topicDoc); - const callArgs = Meteor.callAsync.getCall(0).args; - expect( - callArgs[0], - "first argument should be the name of the meteor method", - "minutes.addTopic", - ); - const sentDoc = callArgs[1]; - expect( - callArgs[1], - "minutes id should be sent to the meteor method", - ) - .to.equal(minutesDoc._id); - expect( - callArgs[2], - "topic-doc should be sent to the meteor method", - ) - .to.equal(topicDoc); - }); + it("sends the minutes id and the topic doc to the meteor method minutes.addTopic", () => { + minute.upsertTopic(topicDoc); + const callArgs = Meteor.callAsync.getCall(0).args; + expect( + callArgs[0], + "first argument should be the name of the meteor method", + "minutes.addTopic", + ); + const sentDoc = callArgs[1]; + expect( + callArgs[1], + "minutes id should be sent to the meteor method", + ).to.equal(minutesDoc._id); + expect( + callArgs[2], + "topic-doc should be sent to the meteor method", + ).to.equal(topicDoc); + }); }); it("#isCurrentUserModerator", () => { diff --git a/tests/unit/imports/Topic.test.js b/tests/unit/imports/Topic.test.js index a11ed33d7..e4ec06a91 100644 --- a/tests/unit/imports/Topic.test.js +++ b/tests/unit/imports/Topic.test.js @@ -1,5 +1,5 @@ -import {expect} from "chai"; -import {_} from "lodash"; +import { expect } from "chai"; +import { _ } from "lodash"; import proxyquire from "proxyquire"; import sinon from "sinon"; @@ -8,15 +8,19 @@ import * as SubElements from "../../../imports/helpers/subElements"; class MeteorError {} const Meteor = { - call : sinon.stub(), - Error : MeteorError, - callAsync : sinon.stub(), - user : () => { return {username : "unit-test"}; }, + call: sinon.stub(), + Error: MeteorError, + callAsync: sinon.stub(), + user: () => { + return { username: "unit-test" }; + }, }; const meetingSeriesId = "AaBbCcDd01"; class MeetingSeries { - constructor(id) { this._id = id; } + constructor(id) { + this._id = id; + } static findOne(id) { if (id === meetingSeriesId) { return dummySeries; @@ -27,7 +31,9 @@ class MeetingSeries { const minuteId = "AaBbCcDd02"; class Minutes { - constructor(id) { this._id = id; } + constructor(id) { + this._id = id; + } upsertTopic() {} static findOne(id) { if (id === minuteId) { @@ -41,88 +47,89 @@ const dummyMinute = new Minutes(minuteId); const dummySeries = new MeetingSeries(meetingSeriesId); const Random = { - i : 1, - id() { return this.i++; }, + i: 1, + id() { + return this.i++; + }, }; SubElements["@noCallThru"] = true; DateHelpers["@noCallThru"] = true; -const {Label} = proxyquire("../../../imports/label", { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - lodash : {_, "@noCallThru" : true}, +const { Label } = proxyquire("../../../imports/label", { + "meteor/meteor": { Meteor, "@noCallThru": true }, + lodash: { _, "@noCallThru": true }, }); -const {InfoItem} = proxyquire("../../../imports/infoitem", { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "meteor/random" : {Random, "@noCallThru" : true}, - lodash : {_, "@noCallThru" : true}, - "/imports/user" : {null : null, "@noCallThru" : true}, - "/imports/helpers/date" : DateHelpers, - "./label" : {Label, "@noCallThru" : true}, +const { InfoItem } = proxyquire("../../../imports/infoitem", { + "meteor/meteor": { Meteor, "@noCallThru": true }, + "meteor/random": { Random, "@noCallThru": true }, + lodash: { _, "@noCallThru": true }, + "/imports/user": { null: null, "@noCallThru": true }, + "/imports/helpers/date": DateHelpers, + "./label": { Label, "@noCallThru": true }, }); -const {ActionItem} = proxyquire("../../../imports/actionitem", { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "./infoitem" : {InfoItem, "@noCallThru" : true}, +const { ActionItem } = proxyquire("../../../imports/actionitem", { + "meteor/meteor": { Meteor, "@noCallThru": true }, + "./infoitem": { InfoItem, "@noCallThru": true }, }); -const {InfoItemFactory} = proxyquire("../../../imports/InfoItemFactory", { - "./infoitem" : {InfoItem, "@noCallThru" : true}, - "./actionitem" : {ActionItem, "@noCallThru" : true}, +const { InfoItemFactory } = proxyquire("../../../imports/InfoItemFactory", { + "./infoitem": { InfoItem, "@noCallThru": true }, + "./actionitem": { ActionItem, "@noCallThru": true }, }); -const {Topic} = proxyquire("../../../imports/topic", { - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "meteor/random" : {Random, "@noCallThru" : true}, - "/imports/helpers/subElements" : SubElements, - "./label" : {Label, "@noCallThru" : true}, - "./infoitem" : {InfoItem, "@noCallThru" : true}, - "./InfoItemFactory" : {InfoItemFactory, "@noCallThru" : true}, - "./minutes" : {Minutes, "@noCallThru" : true}, - "./meetingseries" : {MeetingSeries, "@noCallThru" : true}, - "./helpers/promisedMethods" : {null : null, "@noCallThru" : true}, - "./collections/minutes_private" : {null : null, "@noCallThru" : true}, +const { Topic } = proxyquire("../../../imports/topic", { + "meteor/meteor": { Meteor, "@noCallThru": true }, + "meteor/random": { Random, "@noCallThru": true }, + "/imports/helpers/subElements": SubElements, + "./label": { Label, "@noCallThru": true }, + "./infoitem": { InfoItem, "@noCallThru": true }, + "./InfoItemFactory": { InfoItemFactory, "@noCallThru": true }, + "./minutes": { Minutes, "@noCallThru": true }, + "./meetingseries": { MeetingSeries, "@noCallThru": true }, + "./helpers/promisedMethods": { null: null, "@noCallThru": true }, + "./collections/minutes_private": { null: null, "@noCallThru": true }, }); -describe("Topic", function() { +describe("Topic", function () { let topicDoc; - beforeEach(function() { + beforeEach(function () { topicDoc = { - subject : "topic-subject", - infoItems : [], + subject: "topic-subject", + infoItems: [], }; }); - describe("#constructor", function() { - it("sets the reference to the parent minute correctly", function() { + describe("#constructor", function () { + it("sets the reference to the parent minute correctly", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic._parentMinutes).to.equal(dummyMinute); }); - it("can instantiate a topic with the parent minutes object instead of its id", - function() { - const myTopic = new Topic(dummyMinute, topicDoc); - expect(myTopic._parentMinutes).to.equal(dummyMinute); - }); + it("can instantiate a topic with the parent minutes object instead of its id", function () { + const myTopic = new Topic(dummyMinute, topicDoc); + expect(myTopic._parentMinutes).to.equal(dummyMinute); + }); - it("sets the subject correctly", function() { + it("sets the subject correctly", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic._topicDoc.subject).to.equal(topicDoc.subject); }); - it("sets the initial value of the isOpen-flag correctly", function() { + it("sets the initial value of the isOpen-flag correctly", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic._topicDoc.isOpen).to.be.true; }); - it("sets the initial value of the isNew-flag correctly", function() { + it("sets the initial value of the isNew-flag correctly", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic._topicDoc.isNew).to.be.true; }); - it("enforces infoItems to be of type Array", function() { + it("enforces infoItems to be of type Array", function () { topicDoc.infoItems = "something"; const myTopic = new Topic(dummyMinute._id, topicDoc); @@ -130,97 +137,95 @@ describe("Topic", function() { }); }); - it("#findTopicIndexInArray", function() { - const topicArray = [ topicDoc ]; + it("#findTopicIndexInArray", function () { + const topicArray = [topicDoc]; const index = Topic.findTopicIndexInArray(topicDoc._id, topicArray); expect(index).to.equal(0); }); - describe("#hasOpenActionItem", function() { - it("returns false if the topic does not have any sub items", - function() { expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; }); - - it("returns true if the topic has at least one open action items", - function() { - topicDoc.infoItems.push({ - itemType : "actionItem", - isOpen : false, - }); - topicDoc.infoItems.push({ - itemType : "actionItem", - isOpen : true, - }); - - expect(Topic.hasOpenActionItem(topicDoc)).to.be.true; - }); - - it("returns false if the topic has only closed action items", function() { + describe("#hasOpenActionItem", function () { + it("returns false if the topic does not have any sub items", function () { + expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; + }); + + it("returns true if the topic has at least one open action items", function () { + topicDoc.infoItems.push({ + itemType: "actionItem", + isOpen: false, + }); + topicDoc.infoItems.push({ + itemType: "actionItem", + isOpen: true, + }); + + expect(Topic.hasOpenActionItem(topicDoc)).to.be.true; + }); + + it("returns false if the topic has only closed action items", function () { topicDoc.infoItems.push({ - itemType : "actionItem", - isOpen : false, + itemType: "actionItem", + isOpen: false, }); topicDoc.infoItems.push({ - itemType : "actionItem", - isOpen : false, + itemType: "actionItem", + isOpen: false, }); expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; }); - it("returns false if the topic has only info items (whose open state is unimportant)", - function() { - topicDoc.infoItems.push({ - itemType : "infoItem", - isOpen : false, - }); - topicDoc.infoItems.push({ - itemType : "infoItem", - isOpen : true, - }); - topicDoc.infoItems.push({ - itemType : "infoItem", - // isOpen: keep it "undefined"!!! - }); - expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; - }); - - it("returns true if the topic has a open action item (object method call)", - function() { - topicDoc.infoItems.push({ - itemType : "actionItem", - isOpen : true, - }); - const myTopic = new Topic(dummyMinute._id, topicDoc); - expect(myTopic.hasOpenActionItem()).to.be.true; - }); + it("returns false if the topic has only info items (whose open state is unimportant)", function () { + topicDoc.infoItems.push({ + itemType: "infoItem", + isOpen: false, + }); + topicDoc.infoItems.push({ + itemType: "infoItem", + isOpen: true, + }); + topicDoc.infoItems.push({ + itemType: "infoItem", + // isOpen: keep it "undefined"!!! + }); + expect(Topic.hasOpenActionItem(topicDoc)).to.be.false; + }); + + it("returns true if the topic has a open action item (object method call)", function () { + topicDoc.infoItems.push({ + itemType: "actionItem", + isOpen: true, + }); + const myTopic = new Topic(dummyMinute._id, topicDoc); + expect(myTopic.hasOpenActionItem()).to.be.true; + }); }); - describe("#invalidateIsNewFlag", function() { + describe("#invalidateIsNewFlag", function () { let myTopic; - beforeEach(function() { + beforeEach(function () { topicDoc.isNew = true; topicDoc.infoItems.push({ - isOpen : true, - isNew : true, - itemType : "actionItem", - createdInMinute : dummyMinute._id, + isOpen: true, + isNew: true, + itemType: "actionItem", + createdInMinute: dummyMinute._id, }); myTopic = new Topic(dummyMinute._id, topicDoc); }); - it("clears the isNew-Flag of the topic itself", function() { + it("clears the isNew-Flag of the topic itself", function () { myTopic.invalidateIsNewFlag(); expect(topicDoc.isNew).to.be.false; }); - it("clears the isNew-Flag of the action item", function() { + it("clears the isNew-Flag of the action item", function () { myTopic.invalidateIsNewFlag(); expect(topicDoc.infoItems[0].isNew).to.be.false; }); }); - it("#toggleState", function() { + it("#toggleState", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); const oldState = myTopic._topicDoc.isOpen; @@ -231,68 +236,71 @@ describe("Topic", function() { expect(myTopic._topicDoc.isOpen).to.not.equal(oldState); }); - describe("#isRecurring", function() { + describe("#isRecurring", function () { let myTopic; - beforeEach(function() { myTopic = new Topic(dummyMinute._id, topicDoc); }); + beforeEach(function () { + myTopic = new Topic(dummyMinute._id, topicDoc); + }); - it("sets the default value correctly", - function() { expect(myTopic.isRecurring()).to.be.false; }); + it("sets the default value correctly", function () { + expect(myTopic.isRecurring()).to.be.false; + }); - it("returns the correct value", function() { + it("returns the correct value", function () { myTopic.getDocument().isRecurring = true; expect(myTopic.isRecurring()).to.be.true; }); }); - describe("#toggleRecurring", function() { + describe("#toggleRecurring", function () { let myTopic; - beforeEach(function() { myTopic = new Topic(dummyMinute._id, topicDoc); }); + beforeEach(function () { + myTopic = new Topic(dummyMinute._id, topicDoc); + }); - it("can change the value correctly", function() { + it("can change the value correctly", function () { myTopic.toggleRecurring(); expect(myTopic.isRecurring()).to.be.true; }); - it("can reset the isRecurring-Flag", function() { + it("can reset the isRecurring-Flag", function () { myTopic.toggleRecurring(); myTopic.toggleRecurring(); expect(myTopic.isRecurring()).to.be.false; }); }); - describe("#upsertInfoItem", function() { + describe("#upsertInfoItem", function () { let myTopic; let topicItemDoc; - beforeEach(function() { + beforeEach(function () { myTopic = new Topic(dummyMinute._id, topicDoc); topicItemDoc = { - subject : "info-item-subject", - createdAt : new Date(), + subject: "info-item-subject", + createdAt: new Date(), }; }); - it("adds a new info item to our topic", function() { + it("adds a new info item to our topic", function () { myTopic.upsertInfoItem(topicItemDoc); expect( - myTopic.getInfoItems().length, - "the topic should have exactly one item", - ) - .to.equal(1); - expect(myTopic.getInfoItems()[0]._id, "the item should have an id") - .to.not.be.false; + myTopic.getInfoItems().length, + "the topic should have exactly one item", + ).to.equal(1); + expect(myTopic.getInfoItems()[0]._id, "the item should have an id").to.not + .be.false; expect( - myTopic.getInfoItems()[0].subject, - "the subject should be set correctly", - ) - .to.equal(topicItemDoc.subject); + myTopic.getInfoItems()[0].subject, + "the subject should be set correctly", + ).to.equal(topicItemDoc.subject); }); - it("updates an existing info item", function() { + it("updates an existing info item", function () { myTopic.upsertInfoItem(topicItemDoc); // Change the subject and call the upsertTopicItem method again @@ -302,30 +310,27 @@ describe("Topic", function() { myTopic.upsertInfoItem(topicItem); expect( - myTopic.getInfoItems().length, - "the topic should have exactly one item", - ) - .to.equal(1); + myTopic.getInfoItems().length, + "the topic should have exactly one item", + ).to.equal(1); expect( - myTopic.getInfoItems()[0]._id, - "the item should have an id", - ) - .to.equal(topicItem._id); + myTopic.getInfoItems()[0]._id, + "the item should have an id", + ).to.equal(topicItem._id); expect( - myTopic.getInfoItems()[0].subject, - "the subject should be set correctly", - ) - .to.equal(topicItem.subject); + myTopic.getInfoItems()[0].subject, + "the subject should be set correctly", + ).to.equal(topicItem.subject); }); }); - it("#findInfoItem", function() { + it("#findInfoItem", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); const infoItemDoc = { - _id : "AaBbCcDd01", - subject : "info-item-subject", - createdAt : new Date(), - createdInMinute : dummyMinute._id, + _id: "AaBbCcDd01", + subject: "info-item-subject", + createdAt: new Date(), + createdInMinute: dummyMinute._id, }; // new info item is not added yet, so our topic should not find it @@ -340,24 +345,23 @@ describe("Topic", function() { expect(foundItem, "the result should not be undefined").to.not.equal(); // the subject of the found item should be equal to its initial value expect( - foundItem._infoItemDoc.subject, - "the correct info item should be found", - ) - .to.equal(infoItemDoc.subject); + foundItem._infoItemDoc.subject, + "the correct info item should be found", + ).to.equal(infoItemDoc.subject); }); - it("#removeInfoItem", function() { + it("#removeInfoItem", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); const infoItemDoc = { - _id : "AaBbCcDd01", - subject : "info-item-subject", - createdAt : new Date(), + _id: "AaBbCcDd01", + subject: "info-item-subject", + createdAt: new Date(), }; const infoItemDoc2 = { - _id : "AaBbCcDd02", - subject : "info-item-subject2", - createdAt : new Date(), + _id: "AaBbCcDd02", + subject: "info-item-subject2", + createdAt: new Date(), }; // now we add the info items to our topic @@ -374,95 +378,93 @@ describe("Topic", function() { // check that there are now only one items expect( - diff, - "The length of the info items should be decreased by one", - ) - .to.equal(1); + diff, + "The length of the info items should be decreased by one", + ).to.equal(1); // check that the first item is still part of our topic expect( - myTopic.getInfoItems()[0]._id, - "The other info item should not be removed.", - ) - .to.equal(infoItemDoc._id); + myTopic.getInfoItems()[0]._id, + "The other info item should not be removed.", + ).to.equal(infoItemDoc._id); }); - describe("#tailorTopic", function() { + describe("#tailorTopic", function () { let myTopic; - beforeEach(function() { + beforeEach(function () { topicDoc.infoItems.push({ - subject : "myInfoItem", - createdInMinute : dummyMinute._id, + subject: "myInfoItem", + createdInMinute: dummyMinute._id, }); topicDoc.infoItems.push({ - subject : "myClosedActionItem", - isOpen : false, - itemType : "actionItem", - createdInMinute : dummyMinute._id, + subject: "myClosedActionItem", + isOpen: false, + itemType: "actionItem", + createdInMinute: dummyMinute._id, }); topicDoc.infoItems.push({ - subject : "myOpenActionItem", - isOpen : true, - itemType : "actionItem", - createdInMinute : dummyMinute._id, + subject: "myOpenActionItem", + isOpen: true, + itemType: "actionItem", + createdInMinute: dummyMinute._id, }); myTopic = new Topic(dummyMinute._id, topicDoc); }); - it("removes all info items and closed action items", function() { + it("removes all info items and closed action items", function () { myTopic.tailorTopic(); expect(myTopic.getInfoItems()).to.have.length(1); }); - it("keeps the open action items", function() { + it("keeps the open action items", function () { myTopic.tailorTopic(); expect(myTopic._topicDoc.infoItems[0].isOpen).to.be.true; }); }); - describe("#getOpenActionItems", function() { + describe("#getOpenActionItems", function () { let myTopic; - beforeEach(function() { + beforeEach(function () { topicDoc.infoItems.push({ - subject : "myInfoItem", + subject: "myInfoItem", }); topicDoc.infoItems.push({ - subject : "myClosedActionItem", - isOpen : false, - itemType : "actionItem", + subject: "myClosedActionItem", + isOpen: false, + itemType: "actionItem", }); topicDoc.infoItems.push({ - subject : "myOpenActionItem", - isOpen : true, - itemType : "actionItem", + subject: "myOpenActionItem", + isOpen: true, + itemType: "actionItem", }); topicDoc.infoItems.push({ - subject : "my2ndOpenActionItem", - isOpen : true, - itemType : "actionItem", + subject: "my2ndOpenActionItem", + isOpen: true, + itemType: "actionItem", }); myTopic = new Topic(dummyMinute._id, topicDoc); }); - it("returns the correct amount of items", - function() { expect(myTopic.getOpenActionItems()).to.have.length(2); }); + it("returns the correct amount of items", function () { + expect(myTopic.getOpenActionItems()).to.have.length(2); + }); - it("returns only open action items", function() { + it("returns only open action items", function () { myTopic.getOpenActionItems().forEach((item) => { - expect(item, "the item should be a action item") - .to.have.ownProperty( - "isOpen", - ); + expect(item, "the item should be a action item").to.have.ownProperty( + "isOpen", + ); expect(item.isOpen, "the item should marked as open").to.be.true; }); }); }); - it("#save", function() { + it("#save", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); // the save-method should call the upsertTopic-Method of the parent Minute @@ -471,18 +473,17 @@ describe("Topic", function() { myTopic.save(); - expect(spy.calledOnce, "the upsertTopic method should be called once") - .to.be.true; + expect(spy.calledOnce, "the upsertTopic method should be called once").to.be + .true; expect( - spy.calledWith(myTopic._topicDoc), - "the document should be sent to the upsertTopic method", - ) - .to.be.true; + spy.calledWith(myTopic._topicDoc), + "the document should be sent to the upsertTopic method", + ).to.be.true; spy.restore(); }); - it("#getDocument", function() { + it("#getDocument", function () { const myTopic = new Topic(dummyMinute._id, topicDoc); expect(myTopic.getDocument()).to.equal(topicDoc); diff --git a/tests/unit/imports/client/ResponsiblePreparer.test.js b/tests/unit/imports/client/ResponsiblePreparer.test.js index b5282ac08..f2ee42599 100644 --- a/tests/unit/imports/client/ResponsiblePreparer.test.js +++ b/tests/unit/imports/client/ResponsiblePreparer.test.js @@ -1,44 +1,57 @@ -import {faker} from "@faker-js/faker"; -import {expect} from "chai"; +import { faker } from "@faker-js/faker"; +import { expect } from "chai"; import _ from "lodash"; -import { - ParticipantsPreparer -} from "../../../../imports/client/ParticipantsPreparer"; +import { ParticipantsPreparer } from "../../../../imports/client/ParticipantsPreparer"; -const generateId = () => { return faker.string.uuid(); }; +const generateId = () => { + return faker.string.uuid(); +}; -const createUser = - (id, username, name) => { return {_id : id, username, profile : {name}}; }; +const createUser = (id, username, name) => { + return { _id: id, username, profile: { name } }; +}; const USER_1 = createUser(generateId(), "user1", "First User"); const USER_2 = createUser(generateId(), "user2", "Second User"); const USER_3 = createUser(generateId(), "user3", "Third User"); -describe("ParticipantsPreparer", function() { - let preparer, fakeMinutes, fakeParentSeries, fakeTopicOrItem, - fakeUserCollection; +describe("ParticipantsPreparer", function () { + let preparer, + fakeMinutes, + fakeParentSeries, + fakeTopicOrItem, + fakeUserCollection; - beforeEach(function() { + beforeEach(function () { fakeMinutes = { - participants : [], - participantsAdditional : "", - parentMeetingSeries : () => { return fakeParentSeries; }, + participants: [], + participantsAdditional: "", + parentMeetingSeries: () => { + return fakeParentSeries; + }, }; - fakeParentSeries = {additionalResponsibles : []}; + fakeParentSeries = { additionalResponsibles: [] }; fakeTopicOrItem = { - _topicDoc : {responsibles : []}, - hasResponsibles() { return this._topicDoc.responsibles.length > 0; }, - getResponsibles() { return this._topicDoc.responsibles; }, + _topicDoc: { responsibles: [] }, + hasResponsibles() { + return this._topicDoc.responsibles.length > 0; + }, + getResponsibles() { + return this._topicDoc.responsibles; + }, }; fakeUserCollection = { - users : [ USER_1, USER_2, USER_3 ], + users: [USER_1, USER_2, USER_3], find(selector) { const excludeIds = selector.$and[0]._id.$nin; - const result = this.users.filter( - (user) => { return !_.contains(excludeIds, user._id); }); + const result = this.users.filter((user) => { + return !_.contains(excludeIds, user._id); + }); return { - fetch : () => { return result; }, + fetch: () => { + return result; + }, }; }, findOne(id) { @@ -52,57 +65,56 @@ describe("ParticipantsPreparer", function() { }; preparer = new ParticipantsPreparer( - fakeMinutes, - fakeTopicOrItem, - fakeUserCollection, + fakeMinutes, + fakeTopicOrItem, + fakeUserCollection, ); preparer._init(); }); - describe("#getPossibleResponsibles", function() { + describe("#getPossibleResponsibles", function () { const ADDITIONAL_RESP_TEXT = "guest"; const ADDITIONAL_RESP_MAIL = "guest@mail.de"; const FORMER_RESP_TEXT = "old guest"; const FORMER_RESP_MAIL = "old_guest@mail.de"; - beforeEach(function() { + beforeEach(function () { fakeMinutes.participants = [ - {userId : USER_2._id}, - {userId : USER_1._id}, + { userId: USER_2._id }, + { userId: USER_1._id }, ]; }); - it("returns all participants of the current minutes", function() { + it("returns all participants of the current minutes", function () { preparer._prepareResponsibles(); const result = preparer.getPossibleResponsibles(); expect(result).to.have.length(2); expect(result).to.deep.include({ - id : USER_1._id, - text : `${USER_1.username} - ${USER_1.profile.name}`, + id: USER_1._id, + text: `${USER_1.username} - ${USER_1.profile.name}`, }); expect(result).to.deep.include({ - id : USER_2._id, - text : `${USER_2.username} - ${USER_2.profile.name}`, + id: USER_2._id, + text: `${USER_2.username} - ${USER_2.profile.name}`, }); }); - it("returns the additional responsible, too", function() { - fakeMinutes.participantsAdditional = - `${ADDITIONAL_RESP_TEXT}, ${ADDITIONAL_RESP_MAIL}`; + it("returns the additional responsible, too", function () { + fakeMinutes.participantsAdditional = `${ADDITIONAL_RESP_TEXT}, ${ADDITIONAL_RESP_MAIL}`; preparer._prepareResponsibles(); const result = preparer.getPossibleResponsibles(); expect(result).to.have.length(4); expect(result).to.deep.include({ - id : ADDITIONAL_RESP_TEXT, - text : ADDITIONAL_RESP_TEXT, + id: ADDITIONAL_RESP_TEXT, + text: ADDITIONAL_RESP_TEXT, }); expect(result).to.deep.include({ - id : ADDITIONAL_RESP_MAIL, - text : ADDITIONAL_RESP_MAIL, + id: ADDITIONAL_RESP_MAIL, + text: ADDITIONAL_RESP_MAIL, }); }); - it("returns the former responsible, too", function() { + it("returns the former responsible, too", function () { fakeParentSeries.additionalResponsibles = [ FORMER_RESP_TEXT, FORMER_RESP_MAIL, @@ -111,41 +123,41 @@ describe("ParticipantsPreparer", function() { const result = preparer.getPossibleResponsibles(); expect(result).to.have.length(4); expect(result).to.deep.include({ - id : FORMER_RESP_TEXT, - text : FORMER_RESP_TEXT, + id: FORMER_RESP_TEXT, + text: FORMER_RESP_TEXT, }); expect(result).to.deep.include({ - id : FORMER_RESP_MAIL, - text : FORMER_RESP_MAIL, + id: FORMER_RESP_MAIL, + text: FORMER_RESP_MAIL, }); }); - it("returns only valid entries from the former/additional responsible if desired", - function() { - fakeMinutes.participantsAdditional = - `${ADDITIONAL_RESP_TEXT}, ${ADDITIONAL_RESP_MAIL}`; - fakeParentSeries.additionalResponsibles = [ - FORMER_RESP_TEXT, - FORMER_RESP_MAIL, - ]; - preparer.freeTextValidator = (text) => { return text.includes("@"); }; - preparer._prepareResponsibles(); - const result = preparer.getPossibleResponsibles(); - expect(result).to.have.length(4); - expect(result).to.deep.include({ - id : ADDITIONAL_RESP_MAIL, - text : ADDITIONAL_RESP_MAIL, - }); - expect(result).to.deep.include({ - id : FORMER_RESP_MAIL, - text : FORMER_RESP_MAIL, - }); - }); + it("returns only valid entries from the former/additional responsible if desired", function () { + fakeMinutes.participantsAdditional = `${ADDITIONAL_RESP_TEXT}, ${ADDITIONAL_RESP_MAIL}`; + fakeParentSeries.additionalResponsibles = [ + FORMER_RESP_TEXT, + FORMER_RESP_MAIL, + ]; + preparer.freeTextValidator = (text) => { + return text.includes("@"); + }; + preparer._prepareResponsibles(); + const result = preparer.getPossibleResponsibles(); + expect(result).to.have.length(4); + expect(result).to.deep.include({ + id: ADDITIONAL_RESP_MAIL, + text: ADDITIONAL_RESP_MAIL, + }); + expect(result).to.deep.include({ + id: FORMER_RESP_MAIL, + text: FORMER_RESP_MAIL, + }); + }); - it("returns also the responsible of the current topic/item", function() { + it("returns also the responsible of the current topic/item", function () { fakeTopicOrItem._topicDoc.responsibles = [ - {id : "free-text-entry", text : "free-text-entry"}, - {id : USER_2._id, text : USER_2.name}, + { id: "free-text-entry", text: "free-text-entry" }, + { id: USER_2._id, text: USER_2.name }, ]; preparer._prepareResponsibles(); const result = preparer.getPossibleResponsibles(); diff --git a/tests/unit/imports/ldap/getLDAPUsers.test.js b/tests/unit/imports/ldap/getLDAPUsers.test.js index 6e2cfcf5f..d54494e85 100644 --- a/tests/unit/imports/ldap/getLDAPUsers.test.js +++ b/tests/unit/imports/ldap/getLDAPUsers.test.js @@ -1,19 +1,19 @@ -import {expect} from "chai"; +import { expect } from "chai"; import proxyquire from "proxyquire"; import sinon from "sinon"; import asyncStubs from "../../../support/lib/asyncStubs"; -import {rewiremock} from "../../test-helper/rewiremock"; +import { rewiremock } from "../../test-helper/rewiremock"; import rewiremock from "../../test-helper/rewiremock.cjs"; const ldap = { - createClient : sinon.stub(), + createClient: sinon.stub(), }; const ldapSearchResponseWithResult = { - on : (event, callback) => { + on: (event, callback) => { if (event === "searchEntry") { - callback({object : {uid : "foo"}}); + callback({ object: { uid: "foo" } }); } if (event === "end") { @@ -23,7 +23,7 @@ const ldapSearchResponseWithResult = { }; const ldapSearchResponseWithError = { - on : (event, callback) => { + on: (event, callback) => { if (event === "error") { callback("Some error"); } @@ -34,343 +34,364 @@ const ldapSearchResponseWithError = { // ldapjs: ldap, // }); const getLDAPUsers = rewiremock.proxy("#root/imports/ldap/getLDAPUsers.js", { - ldapjs : ldap, + ldapjs: ldap, }); // skipcq: JS-0241 -describe("getLDAPUsers", function() { +describe("getLDAPUsers", function () { let settings; - const expectedSuccessfulResult = [ {uid : "foo", isInactive : false} ]; + const expectedSuccessfulResult = [{ uid: "foo", isInactive: false }]; // skipcq: JS-0241 - beforeEach(function() { + beforeEach(function () { ldap.createClient.reset(); settings = { - propertyMap : {}, - allowListedFields : [], - inactiveUsers : { - strategy : "none", + propertyMap: {}, + allowListedFields: [], + inactiveUsers: { + strategy: "none", }, }; }); // skipcq: JS-0241 - it("uses ldapjs to connect to ldap and gets users", function(done) { + it("uses ldapjs to connect to ldap and gets users", function (done) { const client = { - search : asyncStubs.returns(2, ldapSearchResponseWithResult), - unbind : asyncStubs.returns(0, {}), + search: asyncStubs.returns(2, ldapSearchResponseWithResult), + unbind: asyncStubs.returns(0, {}), }; ldap.createClient.returns(client); getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users).to.deep.equal(expectedSuccessfulResult); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { done(error); }); + .then((result) => { + try { + expect(result.users).to.deep.equal(expectedSuccessfulResult); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { + done(error); + }); }); // skipcq: JS-0241 - it("handles connection errors to ldap properly", function(done) { + it("handles connection errors to ldap properly", function (done) { ldap.createClient.throws(new Error("Some connection error")); getLDAPUsers(settings) - .then((result) => { done(new Error(`Unexpected result: ${result}`)); }) - .catch((error) => { - try { - expect(error).to.equal( - "Error creating client: Error: Some connection error", - ); - done(); - } catch (error) { - done(error); - } - }); + .then((result) => { + done(new Error(`Unexpected result: ${result}`)); + }) + .catch((error) => { + try { + expect(error).to.equal( + "Error creating client: Error: Some connection error", + ); + done(); + } catch (error) { + done(error); + } + }); }); // skipcq: JS-0241 - it("handles ldap search errors properly", function(done) { + it("handles ldap search errors properly", function (done) { const client = { - search : asyncStubs.returns(2, ldapSearchResponseWithError), - unbind : asyncStubs.returns(0, {}), + search: asyncStubs.returns(2, ldapSearchResponseWithError), + unbind: asyncStubs.returns(0, {}), }; ldap.createClient.returns(client); getLDAPUsers(settings) - .then((result) => { done(new Error(`Unexpected result: ${result}`)); }) - .catch((error) => { - try { - expect(error).to.equal("Some error"); - done(); - } catch (error) { - done(error); - } - }); + .then((result) => { + done(new Error(`Unexpected result: ${result}`)); + }) + .catch((error) => { + try { + expect(error).to.equal("Some error"); + done(); + } catch (error) { + done(error); + } + }); }); // skipcq: JS-0241 - it("handles ldap search errors properly", function(done) { + it("handles ldap search errors properly", function (done) { const client = { - search : asyncStubs.returns(2, ldapSearchResponseWithError), - unbind : asyncStubs.returns(0, {}), + search: asyncStubs.returns(2, ldapSearchResponseWithError), + unbind: asyncStubs.returns(0, {}), }; ldap.createClient.returns(client); getLDAPUsers(settings) - .then((result) => { done(new Error(`Unexpected result: ${result}`)); }) - .catch((error) => { - try { - expect(error).to.equal("Some error"); - done(); - } catch (error) { - done(error); - } - }); + .then((result) => { + done(new Error(`Unexpected result: ${result}`)); + }) + .catch((error) => { + try { + expect(error).to.equal("Some error"); + done(); + } catch (error) { + done(error); + } + }); }); // skipcq: JS-0241 - it("ignores errors during unbind", function(done) { + it("ignores errors during unbind", function (done) { const client = { - search : asyncStubs.returns(2, ldapSearchResponseWithResult), - unbind : asyncStubs.returnsError(0, "Some error"), + search: asyncStubs.returns(2, ldapSearchResponseWithResult), + unbind: asyncStubs.returnsError(0, "Some error"), }; ldap.createClient.returns(client); getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users).to.deep.equal(expectedSuccessfulResult); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { + done(new Error(error)); + }); + }); + // skipcq: JS-0241 + describe("legacy inactive user detection settings", function (done) { + let client; + // skipcq: JS-0241 + beforeEach(function () { + ldap.createClient.reset(); + }); + + const ldapSearchResult = (activeValue) => { + return { + on: (event, callback) => { + if (event === "searchEntry") { + callback({ object: { active: activeValue } }); + } + + if (event === "end") { + callback(); + } + }, + }; + }, + settings = { + isInactivePredicate: { + active: "no", + }, + }; + // skipcq: JS-0241 + it("returns user object with isInactive property set to true", function (done) { + const client = { + search: asyncStubs.returns(2, ldapSearchResult("no")), + unbind: asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) .then((result) => { try { - expect(result.users).to.deep.equal(expectedSuccessfulResult); + expect(result.users[0].isInactive).to.deep.equal(true); done(); } catch (error) { done(error); } }) - .catch((error) => { done(new Error(error)); }); - }); - // skipcq: JS-0241 - describe("legacy inactive user detection settings", function(done) { - let client; + .catch((error) => { + done(error2); + }); + }); // skipcq: JS-0241 - beforeEach(function() { ldap.createClient.reset(); }); + it("adds property map attributes to allowlist automatically", function (done) { + const s = Object.assign({}, settings, { + propertyMap: { + username: "someweirdAttribute", + email: "anEmailAttribute", + }, + allowListedFields: ["someField"], + }); + const parameters = []; + const client = { + search: asyncStubs.returns(2, ldapSearchResult("no"), parameters), + unbind: asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); - const ldapSearchResult = (activeValue) => { - return { - on : (event, callback) => { - if (event === "searchEntry") { - callback({object : {active : activeValue}}); + getLDAPUsers(s) + .then((result) => { + try { + const parametersOfFirstCall = parameters[0], + options = parametersOfFirstCall["1"]; + expect(options.attributes).to.include.members([ + "someweirdAttribute", + "anEmailAttribute", + ]); + done(); + } catch (error) { + done(error); } + }) + .catch((error) => { + done(error2); + }); + }); + // skipcq: JS-0241 + it("returns user object with isInactive property set to false", function (done) { + const client = { + search: asyncStubs.returns(2, ldapSearchResult("yes")), + unbind: asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); - if (event === "end") { - callback(); + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive).to.deep.equal(false); + done(); + } catch (error) { + done(error); } - }, - }; - }, settings = { - isInactivePredicate : { - active : "no", - }, - }; - // skipcq: JS-0241 - it("returns user object with isInactive property set to true", - function(done) { - const client = { - search : asyncStubs.returns(2, ldapSearchResult("no")), - unbind : asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive).to.deep.equal(true); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { done(error2); }); - }); - // skipcq: JS-0241 - it("adds property map attributes to allowlist automatically", - function(done) { - const s = Object.assign({}, settings, { - propertyMap : { - username : "someweirdAttribute", - email : "anEmailAttribute", - }, - allowListedFields : [ "someField" ], - }); - const parameters = []; - const client = { - search : asyncStubs.returns(2, ldapSearchResult("no"), parameters), - unbind : asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(s) - .then((result) => { - try { - const parametersOfFirstCall = parameters[0], - options = parametersOfFirstCall["1"]; - expect(options.attributes).to.include.members([ - "someweirdAttribute", - "anEmailAttribute", - ]); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { done(error2); }); - }); - // skipcq: JS-0241 - it("returns user object with isInactive property set to false", - function(done) { - const client = { - search : asyncStubs.returns(2, ldapSearchResult("yes")), - unbind : asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive).to.deep.equal(false); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { done(error2); }); - }); + }) + .catch((error) => { + done(error2); + }); + }); }); // skipcq: JS-0241 - describe("inactive user detection strategy: none", function(done) { - const activeUsers = [ {isInactive : false, uid : "foo"} ]; + describe("inactive user detection strategy: none", function (done) { + const activeUsers = [{ isInactive: false, uid: "foo" }]; // skipcq: JS-0241 - it("returns user object with isInactive property set to false", - function(done) { - const settings = { - inactiveUsers : { - strategy : "none", - }, - }; - - const client = { - search : asyncStubs.returns(2, ldapSearchResponseWithResult), - unbind : asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users).to.deep.equal(activeUsers); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { done(error2); }); - }); + it("returns user object with isInactive property set to false", function (done) { + const settings = { + inactiveUsers: { + strategy: "none", + }, + }; + + const client = { + search: asyncStubs.returns(2, ldapSearchResponseWithResult), + unbind: asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users).to.deep.equal(activeUsers); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { + done(error2); + }); + }); // skipcq: JS-0241 - it("uses the none strategy if an invalid strategy is given", - function(done) { - const settings = { - inactiveUsers : { - strategy : "doesnotexist", - }, - }; - - const client = { - search : asyncStubs.returns(2, ldapSearchResponseWithResult), - unbind : asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users).to.deep.equal(activeUsers); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => { done(error2); }); - }); + it("uses the none strategy if an invalid strategy is given", function (done) { + const settings = { + inactiveUsers: { + strategy: "doesnotexist", + }, + }; + + const client = { + search: asyncStubs.returns(2, ldapSearchResponseWithResult), + unbind: asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users).to.deep.equal(activeUsers); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => { + done(error2); + }); + }); }); // skipcq: JS-0241 - describe("inactive user detection strategy: UAC", function() { + describe("inactive user detection strategy: UAC", function () { let client; - const activeUsers = false, inactiveUsers = true, - ldapSearchResponseWithGivenUACValue = (uac) => { - return { - on : (event, callback) => { - if (event === "searchEntry") { - callback({object : {userAccountControl : uac}}); - } - - if (event === "end") { - callback(); - } - }, - }; - }, generateTestCase = (value, expectedResult) => { - return (done) => { - const settings = { - inactiveUsers : { - strategy : "userAccountControl", - }, - }; - - client = { - search : asyncStubs.returns( - 2, - ldapSearchResponseWithGivenUACValue(value), - ), - unbind : asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive) - .to.equal(expectedResult); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => done(error)); - }; + const activeUsers = false, + inactiveUsers = true, + ldapSearchResponseWithGivenUACValue = (uac) => { + return { + on: (event, callback) => { + if (event === "searchEntry") { + callback({ object: { userAccountControl: uac } }); + } + + if (event === "end") { + callback(); + } + }, + }; + }, + generateTestCase = (value, expectedResult) => { + return (done) => { + const settings = { + inactiveUsers: { + strategy: "userAccountControl", + }, + }; + + client = { + search: asyncStubs.returns( + 2, + ldapSearchResponseWithGivenUACValue(value), + ), + unbind: asyncStubs.returnsError(0, "Some error"), }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive).to.equal(expectedResult); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => done(error)); + }; + }; // skipcq: JS-0241 - beforeEach(function() { ldap.createClient.reset(); }); + beforeEach(function () { + ldap.createClient.reset(); + }); for (let i = 0; i < 32; ++i) { const value = Math.pow(2, i), - expectedResult = i === 1 ? inactiveUsers : activeUsers; + expectedResult = i === 1 ? inactiveUsers : activeUsers; it( - `uAC property set to ${ - value}: returns user object with isInactive === ${ - expectedResult}`, - generateTestCase(value, expectedResult), + `uAC property set to ${value}: returns user object with isInactive === ${expectedResult}`, + generateTestCase(value, expectedResult), ); } }); // skipcq: JS-0241 - describe("inactive user detection strategy: property", function() { + describe("inactive user detection strategy: property", function () { let client; // skipcq: JS-0241 - beforeEach(function() { ldap.createClient.reset(); }); + beforeEach(function () { + ldap.createClient.reset(); + }); const ldapSearchResponseWithGivenAttribute = (attribute, value) => { return { - on : (event, callback) => { + on: (event, callback) => { if (event === "searchEntry") { - callback({object : {[attribute] : value}}); + callback({ object: { [attribute]: value } }); } if (event === "end") { @@ -380,68 +401,66 @@ describe("getLDAPUsers", function() { }; }; // skipcq: JS-0241 - it("returns isInactive == true if given property is set to requested value", - function(done) { - const settings = { - inactiveUsers : { - strategy : "property", - properties : { - active : "1", - }, - }, - }; - - client = { - search : asyncStubs.returns( - 2, - ldapSearchResponseWithGivenAttribute("active", "1"), - ), - unbind : asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive).to.equal(true); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => done(error)); - }); + it("returns isInactive == true if given property is set to requested value", function (done) { + const settings = { + inactiveUsers: { + strategy: "property", + properties: { + active: "1", + }, + }, + }; + + client = { + search: asyncStubs.returns( + 2, + ldapSearchResponseWithGivenAttribute("active", "1"), + ), + unbind: asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive).to.equal(true); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => done(error)); + }); // skipcq: JS-0241 - it("returns isInactive == false if given property is not set to requested value", - function(done) { - const settings = { - inactiveUsers : { - strategy : "property", - properties : { - active : "1", - }, - }, - }; - - client = { - search : asyncStubs.returns( - 2, - ldapSearchResponseWithGivenAttribute("active", "2"), - ), - unbind : asyncStubs.returnsError(0, "Some error"), - }; - ldap.createClient.returns(client); - - getLDAPUsers(settings) - .then((result) => { - try { - expect(result.users[0].isInactive).to.equal(false); - done(); - } catch (error) { - done(error); - } - }) - .catch((error) => done(error)); - }); + it("returns isInactive == false if given property is not set to requested value", function (done) { + const settings = { + inactiveUsers: { + strategy: "property", + properties: { + active: "1", + }, + }, + }; + + client = { + search: asyncStubs.returns( + 2, + ldapSearchResponseWithGivenAttribute("active", "2"), + ), + unbind: asyncStubs.returnsError(0, "Some error"), + }; + ldap.createClient.returns(client); + + getLDAPUsers(settings) + .then((result) => { + try { + expect(result.users[0].isInactive).to.equal(false); + done(); + } catch (error) { + done(error); + } + }) + .catch((error) => done(error)); + }); }); }); diff --git a/tests/unit/imports/priority.test.js b/tests/unit/imports/priority.test.js index c53829d64..645740240 100644 --- a/tests/unit/imports/priority.test.js +++ b/tests/unit/imports/priority.test.js @@ -1,26 +1,26 @@ -import {expect} from "chai"; +import { expect } from "chai"; import proxyquire from "proxyquire"; import sinon from "sinon"; import rewiremock from "../../test-helper/rewiremock.cjs"; -import {AssertHelper} from "../test-helper/assert-helper"; +import { AssertHelper } from "../test-helper/assert-helper"; const EXPECTED_PRIORITY_MAP = { - 1 : "1 - High", - 2 : "2", - 3 : "3 - Medium", - 4 : "4", - 5 : "5 - Low", + 1: "1 - High", + 2: "2", + 3: "3 - Medium", + 4: "4", + 5: "5 - Low", }; const i18n = { - setLocale : sinon.stub(), - getLocale : sinon.stub(), - __ : sinon.stub(), + setLocale: sinon.stub(), + getLocale: sinon.stub(), + __: sinon.stub(), }; -const {Priority} = rewiremock.proxy("#root/imports/priority", { - "meteor/universe:i18n" : {i18n, "@noCallThru" : true}, +const { Priority } = rewiremock.proxy("#root/imports/priority", { + "meteor/universe:i18n": { i18n, "@noCallThru": true }, }); describe("Priority", () => { @@ -39,22 +39,22 @@ describe("Priority", () => { it("should throw an exception for values below 1", () => { AssertHelper.shouldThrow( - () => new Priority(0), - "Constructor should throw an exception for the value 0", + () => new Priority(0), + "Constructor should throw an exception for the value 0", ); }); it("should throw an exception for values over 5", () => { AssertHelper.shouldThrow( - () => new Priority(6), - "Constructor should throw an exception for the value 6", + () => new Priority(6), + "Constructor should throw an exception for the value 6", ); }); it("should throw an exception for values of an invalid type", () => { AssertHelper.shouldThrow( - () => new Priority("b"), - "Constructor should throw an exception for the value of type string", + () => new Priority("b"), + "Constructor should throw an exception for the value of type string", ); }); }); @@ -69,8 +69,8 @@ describe("Priority", () => { const prio = new Priority(3); prio.value = 7; AssertHelper.shouldThrow( - () => prio.toString(), - "should throw for the value 7", + () => prio.toString(), + "should throw for the value 7", ); }); }); diff --git a/tests/unit/imports/search/ItemsFilter.test.js b/tests/unit/imports/search/ItemsFilter.test.js index 413606427..cac89e89e 100644 --- a/tests/unit/imports/search/ItemsFilter.test.js +++ b/tests/unit/imports/search/ItemsFilter.test.js @@ -1,80 +1,79 @@ -import {expect} from "chai"; +import { expect } from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; class MeteorError {} const Meteor = { - Error : MeteorError, + Error: MeteorError, }; -const {ITEM_KEYWORDS} = proxyquire( - "../../../../imports/search/FilterKeywords", - - {}, +const { ITEM_KEYWORDS } = proxyquire( + "../../../../imports/search/FilterKeywords", + {}, ); -const {ItemsFilter} = proxyquire("../../../../imports/search/ItemsFilter", { - lodash : {_, "@noCallThru" : true}, - "meteor/meteor" : {Meteor, "@noCallThru" : true}, - "./FilterKeywords" : {ITEM_KEYWORDS, "@noCallThru" : true}, +const { ItemsFilter } = proxyquire("../../../../imports/search/ItemsFilter", { + lodash: { _, "@noCallThru": true }, + "meteor/meteor": { Meteor, "@noCallThru": true }, + "./FilterKeywords": { ITEM_KEYWORDS, "@noCallThru": true }, }); -import {QueryParserMock} from "./QueryParserMock"; +import { QueryParserMock } from "./QueryParserMock"; // skipcq: JS-0241 -describe("ItemsFilter", function() { +describe("ItemsFilter", function () { let items; let itemsFilter; let parser; // skipcq: JS-0241 - beforeEach(function() { + beforeEach(function () { parser = new QueryParserMock(); itemsFilter = new ItemsFilter(); items = [ - {subject : "one.one", labels : [ "L2", "L1" ], itemType : "infoItem"}, + { subject: "one.one", labels: ["L2", "L1"], itemType: "infoItem" }, { - subject : "one.two", - labels : [], - itemType : "actionItem", - isOpen : true, + subject: "one.two", + labels: [], + itemType: "actionItem", + isOpen: true, }, - {subject : "two.one", labels : [ "L1" ], itemType : "infoItem"}, - {subject : "two.two", labels : [], itemType : "infoItem"}, + { subject: "two.one", labels: ["L1"], itemType: "infoItem" }, + { subject: "two.two", labels: [], itemType: "infoItem" }, { - subject : "two.three", - labels : [ "L1" ], - itemType : "actionItem", - isOpen : true, - duedate : "2017-06-09", + subject: "two.three", + labels: ["L1"], + itemType: "actionItem", + isOpen: true, + duedate: "2017-06-09", }, - {subject : "three.one", labels : [], itemType : "infoItem"}, - {subject : "three.two", labels : [], itemType : "infoItem"}, - {subject : "three.three", labels : [], itemType : "infoItem"}, + { subject: "three.one", labels: [], itemType: "infoItem" }, + { subject: "three.two", labels: [], itemType: "infoItem" }, + { subject: "three.three", labels: [], itemType: "infoItem" }, { - subject : "three.four", - labels : [], - itemType : "actionItem", - isOpen : false, - duedate : "2017-05-30", + subject: "three.four", + labels: [], + itemType: "actionItem", + isOpen: false, + duedate: "2017-05-30", }, ]; }); // skipcq: JS-0241 - it("does not change the original array of items", function() { + it("does not change the original array of items", function () { parser.searchTokens.push("three"); itemsFilter.filter(items, parser); expect(items, "Length of the items array should be 9").have.length(9); }); // skipcq: JS-0241 - it("returns the filtered array of items", function() { + it("returns the filtered array of items", function () { parser.searchTokens.push("three"); const res = itemsFilter.filter(items, parser); expect(res, "Length of the result items array should be 5").have.length(5); }); // skipcq: JS-0241 - it("can filter for multiple search tokens", function() { + it("can filter for multiple search tokens", function () { parser.searchTokens.push("three"); parser.searchTokens.push("two"); const res = itemsFilter.filter(items, parser); @@ -82,31 +81,29 @@ describe("ItemsFilter", function() { expect(res, "Length of the result items array should be 2").have.length(2); }); // skipcq: JS-0241 - it("should return an items array containing only info items matching the search query", - function() { - const query = "three"; - parser.searchTokens.push(query); - const res = itemsFilter.filter(items, parser); - let foundAWrongItem = false; - res.forEach((item) => { - if (item.subject.indexOf(query) === -1) { - foundAWrongItem = true; - } - }); - expect( - foundAWrongItem, - "Result array contains info item which does not match the search query", - ) - .to.be.false; - }); + it("should return an items array containing only info items matching the search query", function () { + const query = "three"; + parser.searchTokens.push(query); + const res = itemsFilter.filter(items, parser); + let foundAWrongItem = false; + res.forEach((item) => { + if (item.subject.indexOf(query) === -1) { + foundAWrongItem = true; + } + }); + expect( + foundAWrongItem, + "Result array contains info item which does not match the search query", + ).to.be.false; + }); // skipcq: JS-0241 - it("can filter for labels", function() { + it("can filter for labels", function () { parser.labelTokens.push("L1"); const res = itemsFilter.filter(items, parser); expect(res, "Length of the result items array should be 3").have.length(3); }); // skipcq: JS-0241 - it("filters case insensitive per default for search tokens", function() { + it("filters case insensitive per default for search tokens", function () { parser.searchTokens.push("THREE"); parser.searchTokens.push("TWO"); const res = itemsFilter.filter(items, parser); @@ -114,7 +111,7 @@ describe("ItemsFilter", function() { expect(res, "Length of the result items array should be 2").have.length(2); }); // skipcq: JS-0241 - it("can enable case sensitive search", function() { + it("can enable case sensitive search", function () { parser.caseSensitive = true; parser.searchTokens.push("THREE"); const res = itemsFilter.filter(items, parser); @@ -123,29 +120,26 @@ describe("ItemsFilter", function() { expect(res, "Length of the result items array should be 0").have.length(0); }); // skipcq: JS-0241 - it("can combine multiple is-filter-tokens as logical AND which is a conjunctive operation", - function() { - parser.filterTokens.push({key : "is", value : "open"}); - parser.filterTokens.push({key : "is", value : "action"}); - const res = itemsFilter.filter(items, parser); + it("can combine multiple is-filter-tokens as logical AND which is a conjunctive operation", function () { + parser.filterTokens.push({ key: "is", value: "open" }); + parser.filterTokens.push({ key: "is", value: "action" }); + const res = itemsFilter.filter(items, parser); - expect(res, "Length of the result items array should be 2") - .have.length(2); + expect(res, "Length of the result items array should be 2").have.length(2); - parser.init(); - parser.filterTokens.push({key : "is", value : "action"}); - parser.filterTokens.push({key : "is", value : "open"}); - const res2 = itemsFilter.filter(items, parser); + parser.init(); + parser.filterTokens.push({ key: "is", value: "action" }); + parser.filterTokens.push({ key: "is", value: "open" }); + const res2 = itemsFilter.filter(items, parser); - expect( - res2, - "The order of the filter tokens should not matter", - ) - .have.length(2); - }); + expect( + res2, + "The order of the filter tokens should not matter", + ).have.length(2); + }); // skipcq: JS-0241 - it("can filter items depending on their due date", function() { - parser.filterTokens.push({key : "due", value : "2017-"}); + it("can filter items depending on their due date", function () { + parser.filterTokens.push({ key: "due", value: "2017-" }); const res = itemsFilter.filter(items, parser); expect(res, "Length of the result items array should be 2").have.length(2); diff --git a/tests/unit/imports/search/QueryParser.test.js b/tests/unit/imports/search/QueryParser.test.js index 46b7e76b6..a1e2bade4 100644 --- a/tests/unit/imports/search/QueryParser.test.js +++ b/tests/unit/imports/search/QueryParser.test.js @@ -1,141 +1,135 @@ -import {expect} from "chai"; +import { expect } from "chai"; import _ from "lodash"; import proxyquire from "proxyquire"; class MeteorError {} const Meteor = { - Error : MeteorError, + Error: MeteorError, }; // No dependecies left to mock. Replace this with normal import for test -const {ITEM_KEYWORDS} = proxyquire( - "../../../../imports/search/FilterKeywords", +const { ITEM_KEYWORDS } = proxyquire( + "../../../../imports/search/FilterKeywords", - { - lodash : {_, "@noCallThru" : true}, - }, + { + lodash: { _, "@noCallThru": true }, + }, ); -const {QueryParser} = proxyquire("../../../../imports/search/QueryParser", { - lodash : {_, "@noCallThru" : true}, +const { QueryParser } = proxyquire("../../../../imports/search/QueryParser", { + lodash: { _, "@noCallThru": true }, - "meteor/meteor" : {Meteor, "@noCallThru" : true}, + "meteor/meteor": { Meteor, "@noCallThru": true }, }); // skipcq: JS-0241 -describe("QueryParser", function() { +describe("QueryParser", function () { let parser; // skipcq: JS-0241 - beforeEach(function() { parser = new QueryParser(ITEM_KEYWORDS); }); + beforeEach(function () { + parser = new QueryParser(ITEM_KEYWORDS); + }); // skipcq: JS-0241 - it("parses a simple query string containing only search tokens correctly", - function() { - const QUERY = "hello world"; - parser.parse(QUERY); - const filterTokens = parser.getFilterTokens(); - const labelTokens = parser.getLabelTokens(); - const searchTokens = parser.getSearchTokens(); - - expect(filterTokens, "should contain no filter tokens") - .to.have.length(0); - expect(labelTokens, "should contain no label tokens").to.have.length(0); - expect(searchTokens, "should contain 2 search tokens").to.have.length(2); - - expect(searchTokens).to.contain("hello"); - expect(searchTokens).to.contain("world"); - }); + it("parses a simple query string containing only search tokens correctly", function () { + const QUERY = "hello world"; + parser.parse(QUERY); + const filterTokens = parser.getFilterTokens(); + const labelTokens = parser.getLabelTokens(); + const searchTokens = parser.getSearchTokens(); + + expect(filterTokens, "should contain no filter tokens").to.have.length(0); + expect(labelTokens, "should contain no label tokens").to.have.length(0); + expect(searchTokens, "should contain 2 search tokens").to.have.length(2); + + expect(searchTokens).to.contain("hello"); + expect(searchTokens).to.contain("world"); + }); // skipcq: JS-0241 - it("parses a simple query string containing only label tokens correctly", - function() { - const QUERY = "#label 1 #label zwo"; - parser.parse(QUERY); - - const filterTokens = parser.getFilterTokens(); - const labelTokens = - parser.getLabelTokens().map((token) => { return token.token; }); - const searchTokens = parser.getSearchTokens(); - - expect(filterTokens, "should contain no filter tokens") - .to.have.length(0); - expect(labelTokens, "should contain 2 label tokens").to.have.length(2); - expect(searchTokens, "should contain no search tokens") - .to.have.length(0); - - expect(labelTokens).to.contain("label 1"); - expect(labelTokens).to.contain("label zwo"); - }); + it("parses a simple query string containing only label tokens correctly", function () { + const QUERY = "#label 1 #label zwo"; + parser.parse(QUERY); + + const filterTokens = parser.getFilterTokens(); + const labelTokens = parser.getLabelTokens().map((token) => { + return token.token; + }); + const searchTokens = parser.getSearchTokens(); + + expect(filterTokens, "should contain no filter tokens").to.have.length(0); + expect(labelTokens, "should contain 2 label tokens").to.have.length(2); + expect(searchTokens, "should contain no search tokens").to.have.length(0); + + expect(labelTokens).to.contain("label 1"); + expect(labelTokens).to.contain("label zwo"); + }); // skipcq: JS-0241 - it("parses a simple query string containing search tokens, keywords and labels correctly", - function() { - const QUERY = "hello is:open world #my label"; - parser.parse(QUERY); - const filterTokens = parser.getFilterTokens(); - const labelTokens = - parser.getLabelTokens().map((token) => { return token.token; }); - const searchTokens = parser.getSearchTokens(); - - expect(filterTokens, "should contain 1 filter tokens").to.have.length(1); - expect(labelTokens, "should contain 1 label token").to.have.length(1); - expect(searchTokens, "should contain 2 search tokens").to.have.length(2); - - expect(searchTokens).to.contain("hello"); - expect(searchTokens).to.contain("world"); - expect(filterTokens) - .to.deep.contain({key : "is", value : "open", ids : []}); - expect(labelTokens).to.contain("my label"); - }); + it("parses a simple query string containing search tokens, keywords and labels correctly", function () { + const QUERY = "hello is:open world #my label"; + parser.parse(QUERY); + const filterTokens = parser.getFilterTokens(); + const labelTokens = parser.getLabelTokens().map((token) => { + return token.token; + }); + const searchTokens = parser.getSearchTokens(); + + expect(filterTokens, "should contain 1 filter tokens").to.have.length(1); + expect(labelTokens, "should contain 1 label token").to.have.length(1); + expect(searchTokens, "should contain 2 search tokens").to.have.length(2); + + expect(searchTokens).to.contain("hello"); + expect(searchTokens).to.contain("world"); + expect(filterTokens).to.deep.contain({ key: "is", value: "open", ids: [] }); + expect(labelTokens).to.contain("my label"); + }); // skipcq: JS-0241 - it("identifies the due-keyword correctly", function() { + it("identifies the due-keyword correctly", function () { const QUERY = "hello due:2017 world"; parser.parse(QUERY); const filterTokens = parser.getFilterTokens(); expect(filterTokens, "should contain 1 filter tokens").to.have.length(1); expect(filterTokens).to.deep.contain({ - key : "due", - value : "2017", - ids : [], + key: "due", + value: "2017", + ids: [], }); }); // skipcq: JS-0241 - it("can query if a specific keyword is set", function() { + it("can query if a specific keyword is set", function () { const QUERY = "hello is:open world #my label"; parser.parse(QUERY); expect(parser.hasKeyword("is", "open")).to.be.true; - expect(parser.hasKeyword({key : "is"}, "open")).to.be.true; + expect(parser.hasKeyword({ key: "is" }, "open")).to.be.true; }); // skipcq: JS-0241 - describe("Query LabelIds", function() { + describe("Query LabelIds", function () { // skipcq: JS-0241 - beforeEach(function() { + beforeEach(function () { parser = new QueryParser(ITEM_KEYWORDS, (labelName) => { if (labelName.split(/\s/).length > 2) { return []; } const length = labelName.length; - return [ `${labelName}-${length}` ]; + return [`${labelName}-${length}`]; }); }); // skipcq: JS-0241 - it("can query the label id for a given name using the passed function", - function() { - const QUERY = "#my label hello world"; - parser.parse(QUERY); - const filterTokens = parser.getFilterTokens(); - const labelTokens = parser.getLabelTokens(); - const searchTokens = parser.getSearchTokens(); - - expect(filterTokens, "should contain no filter tokens") - .to.have.length(0); - expect(labelTokens, "should contain 1 label token").to.have.length(1); - expect(searchTokens, "should contain 2 search tokens") - .to.have.length(2); - - expect(labelTokens[0].token).to.equal("my label"); - expect(labelTokens).to.deep.contain({ - token : "my label", - ids : [ "my label-8" ], - }); - }); + it("can query the label id for a given name using the passed function", function () { + const QUERY = "#my label hello world"; + parser.parse(QUERY); + const filterTokens = parser.getFilterTokens(); + const labelTokens = parser.getLabelTokens(); + const searchTokens = parser.getSearchTokens(); + + expect(filterTokens, "should contain no filter tokens").to.have.length(0); + expect(labelTokens, "should contain 1 label token").to.have.length(1); + expect(searchTokens, "should contain 2 search tokens").to.have.length(2); + + expect(labelTokens[0].token).to.equal("my label"); + expect(labelTokens).to.deep.contain({ + token: "my label", + ids: ["my label-8"], + }); + }); }); }); diff --git a/tests/unit/test-helper/rewiremock.js b/tests/unit/test-helper/rewiremock.js index 24289b7ec..5becd889a 100644 --- a/tests/unit/test-helper/rewiremock.js +++ b/tests/unit/test-helper/rewiremock.js @@ -1,8 +1,7 @@ // rewiremock.es6.js -import rewiremock from 'rewiremock'; +import rewiremock from "rewiremock"; // settings // .... -rewiremock.overrideEntryPoint( - module); // this is important. This command is "transfering" this module - // parent to rewiremock -export {rewiremock}; +rewiremock.overrideEntryPoint(module); // this is important. This command is "transfering" this module +// parent to rewiremock +export { rewiremock };