Sfoglia il codice sorgente

Merge branch 'imprv/abolish-old-config-api' into imprv/abolish-old-config-api-cleaning

mizozobu 6 anni fa
parent
commit
daffe3fd0e

+ 3 - 5
.eslintrc.js

@@ -2,10 +2,11 @@ module.exports = {
   extends: [
     'weseek',
     'weseek/react',
+    "plugin:jest/recommended",
   ],
   env: {
-    mocha: true,
     jquery: true,
+    "jest/globals": true,
   },
   globals: {
     $: true,
@@ -15,7 +16,7 @@ module.exports = {
     window: true,
   },
   plugins: [
-    'chai-friendly',
+    "jest",
   ],
   rules: {
     'indent': [
@@ -35,8 +36,5 @@ module.exports = {
     ],
     // eslint-plugin-import rules
     'import/no-unresolved': [2, { ignore: ['^@'] }], // ignore @alias/..., @commons/..., ...
-    // eslint-plugin-chai-friendly rules
-    'no-unused-expressions': 0,
-    'chai-friendly/no-unused-expressions': 2,
   },
 };

+ 54 - 0
config/jest.config.js

@@ -0,0 +1,54 @@
+// For a detailed explanation regarding each configuration property, visit:
+// https://jestjs.io/docs/en/configuration.html
+
+module.exports = {
+  // Indicates whether each individual test should be reported during the run
+  verbose: true,
+
+  rootDir: '../',
+
+  // Automatically clear mock calls and instances between every test
+  clearMocks: true,
+  // Automatically reset mock state between every test
+  resetMocks: true,
+
+  projects: [
+    {
+      displayName: 'server',
+      testEnvironment: 'node',
+      rootDir: '.',
+      setupFilesAfterEnv: ['<rootDir>/src/test/setup.js'],
+      testMatch: ['<rootDir>/src/test/**/*.test.js'],
+      // A map from regular expressions to module names that allow to stub out resources with a single module
+      moduleNameMapper: {
+        '@root/(.+)': '<rootDir>/$1',
+        '@commons/(.+)': '<rootDir>/src/lib/$1',
+        '@server/(.+)': '<rootDir>/src/server/$1',
+        '@alias/logger': '<rootDir>/src/lib/service/logger',
+        // -- doesn't work with unknown error -- 2019.06.19 Yuki Takei
+        // debug: '<rootDir>/src/lib/service/logger/alias-for-debug',
+      },
+    },
+    // {
+    //   displayName: 'client',
+    //   rootDir: '.',
+    //   testMatch: ['<rootDir>/src/test/client/**/*.test.js'],
+    // },
+  ],
+
+
+  // Indicates whether the coverage information should be collected while executing the test
+  // collectCoverage: false,
+
+  // An array of glob patterns indicating a set of files for which coverage information should be collected
+  collectCoverageFrom: [
+    'src/client/**/*.js',
+    'src/lib/**/*.js',
+    'src/migrations/**/*.js',
+    'src/server/**/*.js',
+  ],
+
+  // The directory where Jest should output its coverage files
+  coverageDirectory: 'coverage',
+
+};

+ 7 - 6
package.json

@@ -55,7 +55,7 @@
     "server:prod": "env-cmd -f config/env.prod.js node src/server/app.js",
     "server": "npm run server:dev",
     "start": "npm run server:prod",
-    "test": "mocha --timeout 10000 --exit -r src/test/bootstrap.js src/test/**/*.js",
+    "test": "jest --config=config/jest.config.js --passWithNoTests -- ",
     "version": "node -p \"require('./package.json').version\"",
     "webpack": "webpack"
   },
@@ -146,7 +146,6 @@
     "browser-bunyan": "^1.3.0",
     "browser-sync": "^2.26.3",
     "bunyan-debug": "^2.0.0",
-    "chai": "^4.1.0",
     "cli": "~1.0.1",
     "codemirror": "^5.42.0",
     "colors": "^1.2.5",
@@ -159,13 +158,14 @@
     "eazy-logger": "^3.0.2",
     "eslint": "^5.15.1",
     "eslint-config-weseek": "^1.0.1",
-    "eslint-plugin-chai-friendly": "^0.4.1",
     "eslint-plugin-import": "^2.16.0",
     "eslint-plugin-react": "^7.12.4",
+    "eslint-plugin-jest": "^22.6.4",
     "file-loader": "^4.0.0",
     "handsontable": "^6.0.1",
     "i18next-browser-languagedetector": "^3.0.1",
     "imports-loader": "^0.8.0",
+    "jest": "^24.8.0",
     "jquery-slimscroll": "^1.3.8",
     "jquery-ui": "^1.12.1",
     "jquery.cookie": "~1.4.1",
@@ -183,7 +183,6 @@
     "markdown-table": "^1.1.1",
     "metismenu": "^3.0.3",
     "mini-css-extract-plugin": "^0.7.0",
-    "mocha": "^6.0.1",
     "morgan": "^1.9.0",
     "node-dev": "^4.0.0",
     "node-sass": "^4.11.0",
@@ -209,8 +208,6 @@
     "reveal.js": "^3.5.0",
     "sass-loader": "^7.1.0",
     "simple-load-script": "^1.0.2",
-    "sinon": "^7.2.2",
-    "sinon-chai": "^3.3.0",
     "socket.io-client": "^2.0.3",
     "style-loader": "^0.23.0",
     "stylelint-config-recess-order": "^2.0.1",
@@ -225,6 +222,10 @@
     "webpack-cli": "^3.2.3",
     "webpack-merge": "^4.2.1"
   },
+  "resolutions": {
+    "//": "see https://github.com/facebook/jest/issues/8155",
+    "babel-jest": "23.6.0"
+  },
   "_moduleAliases": {
     "@root": ".",
     "@commons": "src/lib",

+ 41 - 8
src/server/crowi/index.js

@@ -101,9 +101,38 @@ Crowi.prototype.init = async function() {
     this.setUpAcl(),
     this.setUpCustomize(),
     this.setUpRestQiitaAPI(),
+    this.setupUserGroup(),
   ]);
 };
 
+Crowi.prototype.initForTest = async function() {
+  await this.setupModels();
+  await this.setupConfigManager();
+
+  // // customizeService depends on AppService and XssService
+  // // passportService depends on appService
+  // // slack depends on setUpSlacklNotification
+  await Promise.all([
+    this.setUpApp(),
+    // this.setUpXss(),
+    // this.setUpSlacklNotification(),
+  ]);
+
+  // await Promise.all([
+  //   this.scanRuntimeVersions(),
+  //   this.setupPassport(),
+  //   this.setupSearcher(),
+  //   this.setupMailer(),
+  //   this.setupSlack(),
+  //   this.setupCsrf(),
+  //   this.setUpGlobalNotification(),
+  //   this.setUpFileUpload(),
+  //   this.setUpAcl(),
+  //   this.setUpCustomize(),
+  //   this.setUpRestQiitaAPI(),
+  // ]);
+};
+
 Crowi.prototype.isPageId = function(pageId) {
   if (!pageId) {
     return false;
@@ -202,14 +231,10 @@ Crowi.prototype.setupConfigManager = async function() {
   return this.configManager.loadConfigs();
 };
 
-Crowi.prototype.setupModels = function() {
-  const self = this;
-  return new Promise(((resolve, reject) => {
-    Object.keys(models).forEach((key) => {
-      self.model(key, models[key](self));
-    });
-    resolve();
-  }));
+Crowi.prototype.setupModels = async function() {
+  Object.keys(models).forEach((key) => {
+    return this.model(key, models[key](this));
+  });
 };
 
 Crowi.prototype.getIo = function() {
@@ -497,4 +522,12 @@ Crowi.prototype.setUpRestQiitaAPI = function() {
   }
 };
 
+Crowi.prototype.setupUserGroup = async function() {
+  const UserGroupService = require('../service/user-group');
+  if (this.userGroupService == null) {
+    this.userGroupService = new UserGroupService(this);
+    return this.userGroupService.init();
+  }
+};
+
 module.exports = Crowi;

+ 0 - 5
src/server/models/user-group-relation.js

@@ -41,10 +41,6 @@ class UserGroupRelation {
     return this._crowi;
   }
 
-  static init() {
-    this.removeAllInvalidRelations();
-  }
-
   /**
    * remove all invalid relations that has reference to unlinked document
    */
@@ -288,6 +284,5 @@ module.exports = function(crowi) {
   UserGroupRelation.crowi = crowi;
   schema.loadClass(UserGroupRelation);
   const model = mongoose.model('UserGroupRelation', schema);
-  model.init();
   return model;
 };

+ 1 - 1
src/server/service/app.js

@@ -1,4 +1,4 @@
-const logger = require('@alias/logger')('growi:service:SiteUrl'); // eslint-disable-line no-unused-vars
+const logger = require('@alias/logger')('growi:service:AppService'); // eslint-disable-line no-unused-vars
 const { pathUtils } = require('growi-commons');
 
 /**

+ 7 - 7
src/server/service/config-manager.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('growi:service:ConfigManager');
+const logger = require('@alias/logger')('growi:service:ConfigManager');
 const ConfigLoader = require('../service/config-loader');
 
 const KEYS_FOR_SAML_USE_ONLY_ENV_OPTION = [
@@ -29,7 +29,7 @@ class ConfigManager {
    */
   async loadConfigs() {
     this.configObject = await this.configLoader.load();
-    debug('ConfigManager#loadConfigs', this.configObject);
+    logger.debug('ConfigManager#loadConfigs', this.configObject);
 
     // cache all config keys
     this.reloadConfigKeys();
@@ -185,31 +185,31 @@ class ConfigManager {
   defaultSearch(namespace, key) {
     // does not exist neither in db nor in env vars
     if (!this.configExistsInDB(namespace, key) && !this.configExistsInEnvVars(namespace, key)) {
-      debug(`${namespace}.${key} does not exist neither in db nor in env vars`);
+      logger.debug(`${namespace}.${key} does not exist neither in db nor in env vars`);
       return undefined;
     }
 
     // only exists in db
     if (this.configExistsInDB(namespace, key) && !this.configExistsInEnvVars(namespace, key)) {
-      debug(`${namespace}.${key} only exists in db`);
+      logger.debug(`${namespace}.${key} only exists in db`);
       return this.configObject.fromDB[namespace][key];
     }
 
     // only exists env vars
     if (!this.configExistsInDB(namespace, key) && this.configExistsInEnvVars(namespace, key)) {
-      debug(`${namespace}.${key} only exists in env vars`);
+      logger.debug(`${namespace}.${key} only exists in env vars`);
       return this.configObject.fromEnvVars[namespace][key];
     }
 
     // exists both in db and in env vars [db > env var]
     if (this.configExistsInDB(namespace, key) && this.configExistsInEnvVars(namespace, key)) {
       if (this.configObject.fromDB[namespace][key] !== null) {
-        debug(`${namespace}.${key} exists both in db and in env vars. loaded from db`);
+        logger.debug(`${namespace}.${key} exists both in db and in env vars. loaded from db`);
         return this.configObject.fromDB[namespace][key];
       }
       /* eslint-disable-next-line no-else-return */
       else {
-        debug(`${namespace}.${key} exists both in db and in env vars. loaded from env vars`);
+        logger.debug(`${namespace}.${key} exists both in db and in env vars. loaded from env vars`);
         return this.configObject.fromEnvVars[namespace][key];
       }
     }

+ 23 - 0
src/server/service/user-group.js

@@ -0,0 +1,23 @@
+const logger = require('@alias/logger')('growi:service:UserGroupService'); // eslint-disable-line no-unused-vars
+
+const mongoose = require('mongoose');
+
+const UserGroupRelation = mongoose.model('UserGroupRelation');
+
+/**
+ * the service class of GlobalNotificationSetting
+ */
+class UserGroupService {
+
+  constructor(configManager) {
+    this.configManager = configManager;
+  }
+
+  async init() {
+    logger.debug('removing all invalid relations');
+    return UserGroupRelation.removeAllInvalidRelations();
+  }
+
+}
+
+module.exports = UserGroupService;

+ 0 - 42
src/test/bootstrap.js

@@ -1,42 +0,0 @@
-process.env.NODE_ENV = 'test';
-
-require('module-alias/register');
-
-const helpers = require('@commons/util/helpers');
-
-const express = require('express');
-
-const testDBUtil = {
-  generateFixture(conn, model, fixture) {
-    if (conn.readyState === 0) {
-      return Promise.reject();
-    }
-    const m = conn.model(model);
-
-    return new Promise(((resolve) => {
-      const createdModels = [];
-      fixture.reduce((promise, entity) => {
-        return promise.then(() => {
-          const newDoc = new m(); // eslint-disable-line new-cap
-
-          Object.keys(entity).forEach((k) => {
-            newDoc[k] = entity[k];
-          });
-          return new Promise(((r) => {
-            newDoc.save((err, data) => {
-              createdModels.push(data);
-              return r();
-            });
-          }));
-        });
-      }, Promise.resolve()).then(() => {
-        resolve(createdModels);
-      });
-    }));
-  },
-};
-
-global.express = express;
-global.ROOT_DIR = helpers.root();
-global.MODEL_DIR = helpers.root('src/server/models');
-global.testDBUtil = testDBUtil;

+ 10 - 43
src/test/crowi/crowi.test.js

@@ -1,63 +1,30 @@
-const chai = require('chai');
-
-const { expect } = chai;
-const sinonChai = require('sinon-chai');
 const helpers = require('@commons/util/helpers');
 
-chai.use(sinonChai);
-
 describe('Test for Crowi application context', () => {
-  const Crowi = require('@server/crowi');
 
+  const Crowi = require('@server/crowi');
 
-  const mongoose = require('mongoose');
   describe('construction', () => {
-    it('initialize crowi context', () => {
+    test('initialize crowi context', () => {
       const crowi = new Crowi(helpers.root());
-      expect(crowi).to.be.instanceof(Crowi);
-      expect(crowi.version).to.equal(require('../../../package.json').version);
-      expect(crowi.env).to.be.an('Object');
+      expect(crowi).toBeInstanceOf(Crowi);
+      expect(crowi.version).toBe(require('@root/package.json').version);
+      expect(typeof crowi.env).toBe('object');
     });
 
-    it('config getter, setter', () => {
+    test('config getter, setter', () => {
       const crowi = new Crowi(helpers.root());
-      expect(crowi.getConfig()).to.deep.equals({});
+      expect(crowi.getConfig()).toEqual({});
       crowi.setConfig({ test: 1 });
-      expect(crowi.getConfig()).to.deep.equals({ test: 1 });
+      expect(crowi.getConfig()).toEqual({ test: 1 });
     });
 
-    it('model getter, setter', () => {
+    test('model getter, setter', () => {
       const crowi = new Crowi(helpers.root());
       // set
       crowi.model('hoge', { fuga: 1 });
-      expect(crowi.model('hoge')).to.deep.equals({ fuga: 1 });
+      expect(crowi.model('hoge')).toEqual({ fuga: 1 });
     });
   });
 
-  describe('.setupDatabase', () => {
-    before(() => {
-      mongoose.disconnect(); // avoid error of Trying to open unclosed connection
-    });
-    it('setup completed', (done) => {
-      const crowi = new Crowi(helpers.root());
-      // set
-      const p = crowi.setupDatabase();
-      expect(p).to.instanceof(Promise);
-      p
-        .then(() => {
-          expect(mongoose.connection.readyState).to.equals(1);
-          done();
-        })
-        .catch((err) => { // eslint-disable-line no-unused-vars
-          // console.log('readyState', mongoose.connection.readyState);
-          if (mongoose.connection.readyState === 2 || mongoose.connection.readyState === 1) { // alreaady connected
-            // throught
-          }
-          else {
-            expect(mongoose.connection.readyState).to.equals(0);
-          }
-          done();
-        });
-    });
-  });
 });

+ 16 - 49
src/test/models/config.test.js

@@ -1,61 +1,28 @@
-const chai = require('chai');
-const sinonChai = require('sinon-chai');
-const utils = require('../utils.js');
-
-const { expect } = chai;
-
-chai.use(sinonChai);
-
-/* global testDBUtil */
+const mongoose = require('mongoose');
 
+const { getInstance } = require('../setup-crowi');
 
 describe('Config model test', () => {
-  const Config = utils.models.Config;
+  // eslint-disable-next-line no-unused-vars
+  let crowi;
+  let Config;
 
-  const conn = utils.mongoose.connection;
-
-  before((done) => {
-    const fixture = [
-      { ns: 'crowi', key: 'test:test', value: JSON.stringify('crowi test value') },
-      { ns: 'crowi', key: 'test:test2', value: JSON.stringify(11111) },
-      { ns: 'crowi', key: 'test:test3', value: JSON.stringify([1, 2, 3, 4, 5]) },
-      { ns: 'plugin', key: 'other:config', value: JSON.stringify('this is data') },
-    ];
+  beforeAll(async(done) => {
+    crowi = await getInstance();
+    done();
+  });
 
-    testDBUtil.generateFixture(conn, 'Config', fixture)
-      .then((configs) => {  // eslint-disable-line
-        done();
-      }).catch(() => {
-        done(new Error('Skip this test.'));
-      });
+  beforeEach(async(done) => {
+    Config = mongoose.model('Config');
+    done();
   });
 
   describe('.CONSTANTS', () => {
-    it('Config has constants', () => {
-      expect(Config.SECURITY_REGISTRATION_MODE_OPEN).to.have.string('Open');
-      expect(Config.SECURITY_REGISTRATION_MODE_RESTRICTED).to.have.string('Resricted');
-      expect(Config.SECURITY_REGISTRATION_MODE_CLOSED).to.have.string('Closed');
+    test('Config has constants', async() => {
+      expect(Config.SECURITY_REGISTRATION_MODE_OPEN).toBe('Open');
+      expect(Config.SECURITY_REGISTRATION_MODE_RESTRICTED).toBe('Resricted');
+      expect(Config.SECURITY_REGISTRATION_MODE_CLOSED).toBe('Closed');
     });
   });
 
-  describe('.loadAllConfig', () => {
-    it('Get config array', (done) => {
-      Config.loadAllConfig((err, config) => {
-        expect(config.crowi).to.be.an('Object');
-        expect(config.crowi).to.have.property('test:test')
-          .and.equal('crowi test value');
-        expect(config.crowi).to.have.property('test:test2')
-          .and.equal(11111);
-        expect(config.crowi).to.have.property('test:test3')
-          .and.to.be.instanceof(Array)
-          .and.deep.equal([1, 2, 3, 4, 5]);
-
-        expect(config.plugin).to.be.an('Object')
-          .and.have.property('other:config')
-          .and.equal('this is data');
-
-        done();
-      });
-    });
-  });
 });

+ 210 - 201
src/test/models/page.test.js

@@ -1,43 +1,51 @@
-const chai = require('chai');
-const sinonChai = require('sinon-chai');
-const utils = require('../utils.js');
+const mongoose = require('mongoose');
 
-const { expect } = chai;
-const testDBUtil = global.testDBUtil;
-
-chai.use(sinonChai);
+const { getInstance } = require('../setup-crowi');
 
 describe('Page', () => {
-  const Page = utils.models.Page;
-  const User = utils.models.User;
-  const conn = utils.mongoose.connection;
-
-  let createdPages;
-  let createdUsers;
-
-  before(async() => {
-    await conn.collection('pages').remove();
+  // eslint-disable-next-line no-unused-vars
+  let crowi;
+  let Page;
+  let User;
+  let UserGroup;
+  let UserGroupRelation;
+
+  beforeAll(async(done) => {
+    crowi = await getInstance();
+    done();
+  });
 
-    const userFixture = [
+  beforeEach(async(done) => {
+    User = mongoose.model('User');
+    UserGroup = mongoose.model('UserGroup');
+    UserGroupRelation = mongoose.model('UserGroupRelation');
+    Page = mongoose.model('Page');
+
+    // remove all
+    await Promise.all([
+      Page.remove({}),
+      User.remove({}),
+      UserGroup.remove({}),
+      UserGroupRelation.remove({}),
+    ]);
+
+    await User.insertMany([
       { name: 'Anon 0', username: 'anonymous0', email: 'anonymous0@example.com' },
       { name: 'Anon 1', username: 'anonymous1', email: 'anonymous1@example.com' },
       { name: 'Anon 2', username: 'anonymous2', email: 'anonymous2@example.com' },
-    ];
+    ]);
 
-    createdUsers = await testDBUtil.generateFixture(conn, 'User', userFixture);
+    await UserGroup.insertMany([
+      { name: 'TestGroup0' },
+      { name: 'TestGroup1' },
+    ]);
 
-    const testUser0 = createdUsers[0];
-    const testUser1 = createdUsers[1];
+    const testUser0 = await User.findOne({ username: 'anonymous0' });
+    const testUser1 = await User.findOne({ username: 'anonymous1' });
 
-    const UserGroup = conn.model('UserGroup');
-    let testGroup0 = new UserGroup();
-    testGroup0.name = 'TestGroup0';
-    let testGroup1 = new UserGroup();
-    testGroup1.name = 'TestGroup1';
-    testGroup0 = await testGroup0.save();
-    testGroup1 = await testGroup1.save();
+    const testGroup0 = await UserGroup.findOne({ name: 'TestGroup0' });
 
-    const userGroupRelationFixture = [
+    await UserGroupRelation.insertMany([
       {
         relatedGroup: testGroup0,
         relatedUser: testUser0,
@@ -46,10 +54,9 @@ describe('Page', () => {
         relatedGroup: testGroup0,
         relatedUser: testUser1,
       },
-    ];
-    await testDBUtil.generateFixture(conn, 'UserGroupRelation', userGroupRelationFixture);
+    ]);
 
-    const fixture = [
+    await Page.insertMany([
       {
         path: '/user/anonymous0/memo',
         grant: Page.GRANT_RESTRICTED,
@@ -108,27 +115,28 @@ describe('Page', () => {
         grant: Page.GRANT_PUBLIC,
         creator: testUser0,
       },
-    ];
-    createdPages = await testDBUtil.generateFixture(conn, 'Page', fixture);
+    ]);
+
+    done();
   });
 
   describe('.isPublic', () => {
-    context('with a public page', () => {
-      it('should return true', (done) => {
+    describe('with a public page', () => {
+      test('should return true', (done) => {
         Page.findOne({ path: '/grant/public' }, (err, page) => {
-          expect(err).to.be.null;
-          expect(page.isPublic()).to.be.equal(true);
+          expect(err).toBeNull();
+          expect(page.isPublic()).toEqual(true);
           done();
         });
       });
     });
 
     ['restricted', 'specified', 'owner'].forEach((grant) => {
-      context(`with a ${grant} page`, () => {
-        it('should return false', (done) => {
+      describe(`with a ${grant} page`, () => {
+        test('should return false', (done) => {
           Page.findOne({ path: `/grant/${grant}` }, (err, page) => {
-            expect(err).to.be.null;
-            expect(page.isPublic()).to.be.equal(false);
+            expect(err).toBeNull();
+            expect(page.isPublic()).toEqual(false);
             done();
           });
         });
@@ -137,230 +145,231 @@ describe('Page', () => {
   });
 
   describe('.getDeletedPageName', () => {
-    it('should return trash page name', () => {
-      expect(Page.getDeletedPageName('/hoge')).to.be.equal('/trash/hoge');
-      expect(Page.getDeletedPageName('hoge')).to.be.equal('/trash/hoge');
+    test('should return trash page name', () => {
+      expect(Page.getDeletedPageName('/hoge')).toEqual('/trash/hoge');
+      expect(Page.getDeletedPageName('hoge')).toEqual('/trash/hoge');
     });
   });
   describe('.getRevertDeletedPageName', () => {
-    it('should return reverted trash page name', () => {
-      expect(Page.getRevertDeletedPageName('/hoge')).to.be.equal('/hoge');
-      expect(Page.getRevertDeletedPageName('/trash/hoge')).to.be.equal('/hoge');
-      expect(Page.getRevertDeletedPageName('/trash/hoge/trash')).to.be.equal('/hoge/trash');
+    test('should return reverted trash page name', () => {
+      expect(Page.getRevertDeletedPageName('/hoge')).toEqual('/hoge');
+      expect(Page.getRevertDeletedPageName('/trash/hoge')).toEqual('/hoge');
+      expect(Page.getRevertDeletedPageName('/trash/hoge/trash')).toEqual('/hoge/trash');
     });
   });
 
   describe('.isDeletableName', () => {
-    it('should decide deletable or not', () => {
-      expect(Page.isDeletableName('/hoge')).to.be.true;
-      expect(Page.isDeletableName('/user/xxx')).to.be.false;
-      expect(Page.isDeletableName('/user/xxx123')).to.be.false;
-      expect(Page.isDeletableName('/user/xxx/')).to.be.true;
-      expect(Page.isDeletableName('/user/xxx/hoge')).to.be.true;
+    test('should decide deletable or not', () => {
+      expect(Page.isDeletableName('/hoge')).toBeTruthy();
+      expect(Page.isDeletableName('/user/xxx')).toBeFalsy();
+      expect(Page.isDeletableName('/user/xxx123')).toBeFalsy();
+      expect(Page.isDeletableName('/user/xxx/')).toBeTruthy();
+      expect(Page.isDeletableName('/user/xxx/hoge')).toBeTruthy();
     });
   });
 
   describe('.isCreatableName', () => {
-    it('should decide creatable or not', () => {
-      expect(Page.isCreatableName('/hoge')).to.be.true;
+    test('should decide creatable or not', () => {
+      expect(Page.isCreatableName('/hoge')).toBeTruthy();
 
       // edge cases
-      expect(Page.isCreatableName('/me')).to.be.false;
-      expect(Page.isCreatableName('/me/')).to.be.false;
-      expect(Page.isCreatableName('/me/x')).to.be.false;
-      expect(Page.isCreatableName('/meeting')).to.be.true;
-      expect(Page.isCreatableName('/meeting/x')).to.be.true;
+      expect(Page.isCreatableName('/me')).toBeFalsy();
+      expect(Page.isCreatableName('/me/')).toBeFalsy();
+      expect(Page.isCreatableName('/me/x')).toBeFalsy();
+      expect(Page.isCreatableName('/meeting')).toBeTruthy();
+      expect(Page.isCreatableName('/meeting/x')).toBeTruthy();
 
       // end with "edit"
-      expect(Page.isCreatableName('/meeting/edit')).to.be.false;
+      expect(Page.isCreatableName('/meeting/edit')).toBeFalsy();
 
       // under score
-      expect(Page.isCreatableName('/_')).to.be.true;
-      expect(Page.isCreatableName('/_template')).to.be.true;
-      expect(Page.isCreatableName('/__template')).to.be.true;
-      expect(Page.isCreatableName('/_r/x')).to.be.false;
-      expect(Page.isCreatableName('/_api')).to.be.false;
-      expect(Page.isCreatableName('/_apix')).to.be.false;
-      expect(Page.isCreatableName('/_api/x')).to.be.false;
+      expect(Page.isCreatableName('/_')).toBeTruthy();
+      expect(Page.isCreatableName('/_template')).toBeTruthy();
+      expect(Page.isCreatableName('/__template')).toBeTruthy();
+      expect(Page.isCreatableName('/_r/x')).toBeFalsy();
+      expect(Page.isCreatableName('/_api')).toBeFalsy();
+      expect(Page.isCreatableName('/_apix')).toBeFalsy();
+      expect(Page.isCreatableName('/_api/x')).toBeFalsy();
 
-      expect(Page.isCreatableName('/hoge/xx.md')).to.be.false;
+      expect(Page.isCreatableName('/hoge/xx.md')).toBeFalsy();
 
       // start with https?
-      expect(Page.isCreatableName('/http://demo.growi.org/hoge')).to.be.false;
-      expect(Page.isCreatableName('/https://demo.growi.org/hoge')).to.be.false;
-      expect(Page.isCreatableName('http://demo.growi.org/hoge')).to.be.false;
-      expect(Page.isCreatableName('https://demo.growi.org/hoge')).to.be.false;
+      expect(Page.isCreatableName('/http://demo.growi.org/hoge')).toBeFalsy();
+      expect(Page.isCreatableName('/https://demo.growi.org/hoge')).toBeFalsy();
+      expect(Page.isCreatableName('http://demo.growi.org/hoge')).toBeFalsy();
+      expect(Page.isCreatableName('https://demo.growi.org/hoge')).toBeFalsy();
 
-      expect(Page.isCreatableName('/ the / path / with / space')).to.be.false;
+      expect(Page.isCreatableName('/ the / path / with / space')).toBeFalsy();
 
       const forbidden = ['installer', 'register', 'login', 'logout',
                          'admin', 'files', 'trash', 'paste', 'comments'];
       for (let i = 0; i < forbidden.length; i++) {
         const pn = forbidden[i];
-        expect(Page.isCreatableName(`/${pn}`)).to.be.false;
-        expect(Page.isCreatableName(`/${pn}/`)).to.be.false;
-        expect(Page.isCreatableName(`/${pn}/abc`)).to.be.false;
+        expect(Page.isCreatableName(`/${pn}`)).toBeFalsy();
+        expect(Page.isCreatableName(`/${pn}/`)).toBeFalsy();
+        expect(Page.isCreatableName(`/${pn}/abc`)).toBeFalsy();
       }
     });
   });
 
   describe('.isAccessiblePageByViewer', () => {
-    context('with a granted user', () => {
-      it('should return true', async() => {
+    describe('with a granted user', () => {
+      test('should return true', async() => {
         const user = await User.findOne({ email: 'anonymous0@example.com' });
         const page = await Page.findOne({ path: '/user/anonymous0/memo' });
 
         const bool = await Page.isAccessiblePageByViewer(page.id, user);
-        expect(bool).to.be.equal(true);
+        expect(bool).toEqual(true);
       });
     });
 
-    context('with a public page', () => {
-      it('should return true', async() => {
+    describe('with a public page', () => {
+      test('should return true', async() => {
         const user = await User.findOne({ email: 'anonymous1@example.com' });
         const page = await Page.findOne({ path: '/grant/public' });
 
         const bool = await Page.isAccessiblePageByViewer(page.id, user);
-        expect(bool).to.be.equal(true);
+        expect(bool).toEqual(true);
       });
     });
 
-    context('with a restricted page and an user who has no grant', () => {
-      it('should return false', async() => {
+    describe('with a restricted page and an user who has no grant', () => {
+      test('should return false', async() => {
         const user = await User.findOne({ email: 'anonymous1@example.com' });
         const page = await Page.findOne({ path: '/grant/owner' });
 
         const bool = await Page.isAccessiblePageByViewer(page.id, user);
-        expect(bool).to.be.equal(false);
+        expect(bool).toEqual(false);
       });
     });
   });
 
   describe('Extended field', () => {
-    context('Slack Channel.', () => {
-      it('should be empty', (done) => {
+    describe('Slack Channel.', () => {
+      test('should be empty', (done) => {
         Page.findOne({ path: '/page/for/extended' }, (err, page) => {
-          expect(page.extended.hoge).to.be.equal(1);
-          expect(page.getSlackChannel()).to.be.equal('');
+          expect(page.extended.hoge).toEqual(1);
+          expect(page.getSlackChannel()).toEqual('');
           done();
         });
       });
 
-      it('set slack channel and should get it and should keep hoge ', async() => {
+      test('set slack channel and should get it and should keep hoge ', async() => {
         let page = await Page.findOne({ path: '/page/for/extended' });
         await page.updateSlackChannel('slack-channel1');
         page = await Page.findOne({ path: '/page/for/extended' });
-        expect(page.extended.hoge).to.be.equal(1);
-        expect(page.getSlackChannel()).to.be.equal('slack-channel1');
-      });
-    });
-  });
-
-  describe('.findPage', () => {
-    context('findByIdAndViewer', () => {
-      it('should find page (public)', async() => {
-        const pageToFind = createdPages[1];
-        const grantedUser = createdUsers[0];
-
-        const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
-        expect(page).to.be.not.null;
-        expect(page.path).to.equal(pageToFind.path);
-      });
-
-      it('should find page (anyone knows link)', async() => {
-        const pageToFind = createdPages[2];
-        const grantedUser = createdUsers[1];
-
-        const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
-        expect(page).to.be.not.null;
-        expect(page.path).to.equal(pageToFind.path);
-      });
-
-      it('should find page (just me)', async() => {
-        const pageToFind = createdPages[4];
-        const grantedUser = createdUsers[0];
-
-        const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
-        expect(page).to.be.not.null;
-        expect(page.path).to.equal(pageToFind.path);
-      });
-
-      it('should not be found by grant (just me)', async() => {
-        const pageToFind = createdPages[4];
-        const grantedUser = createdUsers[1];
-
-        const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
-        expect(page).to.be.null;
-      });
-    });
-
-    context('findByIdAndViewer granted userGroup', () => {
-      it('should find page', async() => {
-        const pageToFind = createdPages[6];
-        const grantedUser = createdUsers[0];
-
-        const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
-        expect(page).to.be.not.null;
-        expect(page.path).to.equal(pageToFind.path);
-      });
-
-      it('should not be found by grant', async() => {
-        const pageToFind = createdPages[6];
-        const grantedUser = createdUsers[2];
-
-        const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
-        expect(page).to.be.null;
+        expect(page.extended.hoge).toEqual(1);
+        expect(page.getSlackChannel()).toEqual('slack-channel1');
       });
     });
   });
 
-  context('findListWithDescendants', () => {
-    it('should return only /page/', async() => {
-      const user = createdUsers[0];
-
-      const result = await Page.findListWithDescendants('/page/', user, { isRegExpEscapedFromPath: true });
-
-      // assert totalCount
-      expect(result.totalCount).to.equal(1);
-      // assert paths
-      const pagePaths = result.pages.map((page) => { return page.path });
-      expect(pagePaths).to.include.members(['/page/for/extended']);
-    });
-    it('should return only /page1/', async() => {
-      const user = createdUsers[0];
-
-      const result = await Page.findListWithDescendants('/page1/', user, { isRegExpEscapedFromPath: true });
-
-      // assert totalCount
-      expect(result.totalCount).to.equal(2);
-      // assert paths
-      const pagePaths = result.pages.map((page) => { return page.path });
-      expect(pagePaths).to.include.members(['/page1', '/page1/child1']);
-    });
-  });
-
-  context('findListByStartWith', () => {
-    it('should return pages which starts with /page', async() => {
-      const user = createdUsers[0];
-
-      const result = await Page.findListByStartWith('/page', user, {});
+  // describe('.findPage', () => {
+  //   describe('findByIdAndViewer', () => {
+  //     test('should find page (public)', async() => {
+  //       const pageToFind = createdPages[1];
+  //       const grantedUser = createdUsers[0];
+
+  //       const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
+  //       expect(page).to.be.not.null;
+  //       expect(page.path).to.equal(pageToFind.path);
+  //     });
+
+  //     test('should find page (anyone knows link)', async() => {
+  //       const pageToFind = createdPages[2];
+  //       const grantedUser = createdUsers[1];
+
+  //       const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
+  //       expect(page).to.be.not.null;
+  //       expect(page.path).to.equal(pageToFind.path);
+  //     });
+
+  //     test('should find page (just me)', async() => {
+  //       const pageToFind = createdPages[4];
+  //       const grantedUser = createdUsers[0];
+
+  //       const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
+  //       expect(page).to.be.not.null;
+  //       expect(page.path).to.equal(pageToFind.path);
+  //     });
+
+  //     test('should not be found by grant (just me)', async() => {
+  //       const pageToFind = createdPages[4];
+  //       const grantedUser = createdUsers[1];
+
+  //       const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
+  //       expect(page).toBeNull();
+  //     });
+  //   });
+
+  //   describe('findByIdAndViewer granted userGroup', () => {
+  //     test('should find page', async() => {
+  //       const pageToFind = createdPages[6];
+  //       const grantedUser = createdUsers[0];
+
+  //       const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
+  //       expect(page).to.be.not.null;
+  //       expect(page.path).to.equal(pageToFind.path);
+  //     });
+
+  //     test('should not be found by grant', async() => {
+  //       const pageToFind = createdPages[6];
+  //       const grantedUser = createdUsers[2];
+
+  //       const page = await Page.findByIdAndViewer(pageToFind.id, grantedUser);
+  //       expect(page).toBeNull();
+  //     });
+  //   });
+  // });
+
+  // describe('findListWithDescendants', () => {
+  //   test('should return only /page/', async() => {
+  //     const user = createdUsers[0];
+
+  //     const result = await Page.findListWithDescendants('/page/', user, { isRegExpEscapedFromPath: true });
+
+  //     // assert totalCount
+  //     expect(result.totalCount).to.equal(1);
+  //     // assert paths
+  //     const pagePaths = result.pages.map((page) => { return page.path });
+  //     expect(pagePaths).to.include.members(['/page/for/extended']);
+  //   });
+  //   test('should return only /page1/', async() => {
+  //     const user = createdUsers[0];
+
+  //     const result = await Page.findListWithDescendants('/page1/', user, { isRegExpEscapedFromPath: true });
+
+  //     // assert totalCount
+  //     expect(result.totalCount).to.equal(2);
+  //     // assert paths
+  //     const pagePaths = result.pages.map((page) => { return page.path });
+  //     expect(pagePaths).to.include.members(['/page1', '/page1/child1']);
+  //   });
+  // });
+
+  // describe('findListByStartWith', () => {
+  //   test('should return pages which starts with /page', async() => {
+  //     const user = createdUsers[0];
+
+  //     const result = await Page.findListByStartWith('/page', user, {});
+
+  //     // assert totalCount
+  //     expect(result.totalCount).to.equal(4);
+  //     // assert paths
+  //     const pagePaths = result.pages.map((page) => { return page.path });
+  //     expect(pagePaths).to.include.members(['/page/for/extended', '/page1', '/page1/child1', '/page2']);
+  //   });
+  //   test('should process with regexp', async() => {
+  //     const user = createdUsers[0];
+
+  //     const result = await Page.findListByStartWith('/page\\d{1}/', user, {});
+
+  //     // assert totalCount
+  //     expect(result.totalCount).to.equal(3);
+  //     // assert paths
+  //     const pagePaths = result.pages.map((page) => { return page.path });
+  //     expect(pagePaths).to.include.members(['/page1', '/page1/child1', '/page2']);
+  //   });
+  // });
 
-      // assert totalCount
-      expect(result.totalCount).to.equal(4);
-      // assert paths
-      const pagePaths = result.pages.map((page) => { return page.path });
-      expect(pagePaths).to.include.members(['/page/for/extended', '/page1', '/page1/child1', '/page2']);
-    });
-    it('should process with regexp', async() => {
-      const user = createdUsers[0];
-
-      const result = await Page.findListByStartWith('/page\\d{1}/', user, {});
-
-      // assert totalCount
-      expect(result.totalCount).to.equal(3);
-      // assert paths
-      const pagePaths = result.pages.map((page) => { return page.path });
-      expect(pagePaths).to.include.members(['/page1', '/page1/child1', '/page2']);
-    });
-  });
 });

+ 35 - 27
src/test/models/updatePost.test.js

@@ -1,23 +1,31 @@
-const chai = require('chai');
-const sinonChai = require('sinon-chai');
+const mongoose = require('mongoose');
 
-const expect = chai.expect;
-const utils = require('../utils.js');
-
-chai.use(sinonChai);
+const { getInstance } = require('../setup-crowi');
 
 describe('UpdatePost', () => {
-  const UpdatePost = utils.models.UpdatePost;
+  // eslint-disable-next-line no-unused-vars
+  let crowi;
+  let UpdatePost;
+
+  beforeAll(async(done) => {
+    crowi = await getInstance();
+    done();
+  });
+
+  beforeEach(async(done) => {
+    UpdatePost = mongoose.model('UpdatePost');
+    done();
+  });
 
   describe('.createPrefixesByPathPattern', () => {
-    context('with a path', () => {
-      it('should return right patternPrfixes', (done) => {
-        expect(UpdatePost.createPrefixesByPathPattern('/*')).to.deep.equal(['*', '*']);
-        expect(UpdatePost.createPrefixesByPathPattern('/user/*/日報*')).to.deep.equal(['user', '*']);
-        expect(UpdatePost.createPrefixesByPathPattern('/project/hoge/*')).to.deep.equal(['project', 'hoge']);
-        expect(UpdatePost.createPrefixesByPathPattern('/*/MTG/*')).to.deep.equal(['*', 'MTG']);
-        expect(UpdatePost.createPrefixesByPathPattern('自己紹介')).to.deep.equal(['*', '*']);
-        expect(UpdatePost.createPrefixesByPathPattern('/user/aoi/メモ/2016/02/10/xxx')).to.deep.equal(['user', 'aoi']);
+    describe('with a path', () => {
+      test('should return right patternPrfixes', (done) => {
+        expect(UpdatePost.createPrefixesByPathPattern('/*')).toEqual(['*', '*']);
+        expect(UpdatePost.createPrefixesByPathPattern('/user/*/日報*')).toEqual(['user', '*']);
+        expect(UpdatePost.createPrefixesByPathPattern('/project/hoge/*')).toEqual(['project', 'hoge']);
+        expect(UpdatePost.createPrefixesByPathPattern('/*/MTG/*')).toEqual(['*', 'MTG']);
+        expect(UpdatePost.createPrefixesByPathPattern('自己紹介')).toEqual(['*', '*']);
+        expect(UpdatePost.createPrefixesByPathPattern('/user/aoi/メモ/2016/02/10/xxx')).toEqual(['user', 'aoi']);
 
         done();
       });
@@ -25,24 +33,24 @@ describe('UpdatePost', () => {
   });
 
   describe('.getRegExpByPattern', () => {
-    context('with a pattern', () => {
-      it('should return right regexp', (done) => {
-        expect(UpdatePost.getRegExpByPattern('/*')).to.deep.equal(/^\/.*/);
-        expect(UpdatePost.getRegExpByPattern('/user/*/日報*')).to.deep.equal(/^\/user\/.*\/日報.*/);
-        expect(UpdatePost.getRegExpByPattern('/project/hoge/*')).to.deep.equal(/^\/project\/hoge\/.*/);
-        expect(UpdatePost.getRegExpByPattern('/*/MTG/*')).to.deep.equal(/^\/.*\/MTG\/.*/);
-        expect(UpdatePost.getRegExpByPattern('自己紹介')).to.deep.equal(/^\/.*自己紹介.*/);
-        expect(UpdatePost.getRegExpByPattern('/user/aoi/メモ/2016/02/10/xxx')).to.deep.equal(/^\/user\/aoi\/メモ\/2016\/02\/10\/xxx/);
+    describe('with a pattern', () => {
+      test('should return right regexp', (done) => {
+        expect(UpdatePost.getRegExpByPattern('/*')).toEqual(/^\/.*/);
+        expect(UpdatePost.getRegExpByPattern('/user/*/日報*')).toEqual(/^\/user\/.*\/日報.*/);
+        expect(UpdatePost.getRegExpByPattern('/project/hoge/*')).toEqual(/^\/project\/hoge\/.*/);
+        expect(UpdatePost.getRegExpByPattern('/*/MTG/*')).toEqual(/^\/.*\/MTG\/.*/);
+        expect(UpdatePost.getRegExpByPattern('自己紹介')).toEqual(/^\/.*自己紹介.*/);
+        expect(UpdatePost.getRegExpByPattern('/user/aoi/メモ/2016/02/10/xxx')).toEqual(/^\/user\/aoi\/メモ\/2016\/02\/10\/xxx/);
         done();
       });
     });
   });
 
   describe('.normalizeChannelName', () => {
-    context('with a channel name', () => {
-      it('should return true', (done) => {
-        expect(UpdatePost.normalizeChannelName('#pj-hoge')).to.be.equal('pj-hoge');
-        expect(UpdatePost.normalizeChannelName('pj-hoge')).to.be.equal('pj-hoge');
+    describe('with a channel name', () => {
+      test('should return true', (done) => {
+        expect(UpdatePost.normalizeChannelName('#pj-hoge')).toEqual('pj-hoge');
+        expect(UpdatePost.normalizeChannelName('pj-hoge')).toEqual('pj-hoge');
 
         done();
       });

+ 30 - 29
src/test/models/user.test.js

@@ -1,46 +1,47 @@
-const chai = require('chai');
-const sinonChai = require('sinon-chai');
-const utils = require('../utils.js');
+const mongoose = require('mongoose');
+
+const { getInstance } = require('../setup-crowi');
 
-const expect = chai.expect;
-chai.use(sinonChai);
 
 describe('User', () => {
-  const User = utils.models.User;
-  const conn = utils.mongoose.connection;
+  // eslint-disable-next-line no-unused-vars
+  let crowi;
+  let User;
 
-  // clear collection
-  before((done) => {
-    conn.collection('users').remove()
-      .then(() => {
-        done();
-      });
+  beforeAll(async(done) => {
+    crowi = await getInstance();
+    done();
+  });
+
+  beforeEach(async(done) => {
+    User = mongoose.model('User');
+    done();
   });
 
   describe('Create and Find.', () => {
-    context('The user', () => {
-      it('should created', (done) => {
+    describe('The user', () => {
+      test('should created', (done) => {
         User.createUserByEmailAndPassword('Aoi Miyazaki', 'aoi', 'aoi@example.com', 'hogefuga11', 'en', (err, userData) => {
-          expect(err).to.be.null;
-          expect(userData).to.instanceof(User);
+          expect(err).toBeNull();
+          expect(userData).toBeInstanceOf(User);
           done();
         });
       });
 
-      it('should be found by findUserByUsername', (done) => {
+      test('should be found by findUserByUsername', (done) => {
         User.findUserByUsername('aoi')
           .then((userData) => {
-            expect(userData).to.instanceof(User);
+            expect(userData).toBeInstanceOf(User);
             done();
           });
       });
 
-      it('should be found by findUsersByPartOfEmail', (done) => {
+      test('should be found by findUsersByPartOfEmail', (done) => {
         User.findUsersByPartOfEmail('ao', {})
           .then((userData) => {
-            expect(userData).to.instanceof(Array);
-            expect(userData[0]).to.instanceof(User);
-            expect(userData[0].email).to.equal('aoi@example.com');
+            expect(userData).toBeInstanceOf(Array);
+            expect(userData[0]).toBeInstanceOf(User);
+            expect(userData[0].email).toEqual('aoi@example.com');
             done();
           });
       });
@@ -48,22 +49,22 @@ describe('User', () => {
   });
 
   describe('User Utilities', () => {
-    context('Get username from path', () => {
-      it('found', (done) => {
+    describe('Get username from path', () => {
+      test('found', (done) => {
         let username = null;
         username = User.getUsernameByPath('/user/sotarok');
-        expect(username).to.equal('sotarok');
+        expect(username).toEqual('sotarok');
 
         username = User.getUsernameByPath('/user/some.user.name12/'); // with slash
-        expect(username).to.equal('some.user.name12');
+        expect(username).toEqual('some.user.name12');
 
         done();
       });
 
-      it('not found', (done) => {
+      test('not found', (done) => {
         let username = null;
         username = User.getUsernameByPath('/the/page/is/not/related/to/user/page');
-        expect(username).to.be.null;
+        expect(username).toBeNull();
 
         done();
       });

+ 32 - 0
src/test/setup-crowi.js

@@ -0,0 +1,32 @@
+const helpers = require('@commons/util/helpers');
+
+const Crowi = require('@server/crowi');
+
+let _instance = null;
+
+async function createInstance() {
+  const crowi = new Crowi(helpers.root());
+  await crowi.initForTest();
+
+  // init DB
+  const appService = crowi.appService;
+  await appService.initDB();
+
+  return crowi;
+}
+
+async function getInstance(isNewInstance) {
+  if (isNewInstance) {
+    return createInstance();
+  }
+
+  // initialize singleton instance
+  if (_instance == null) {
+    _instance = await createInstance();
+  }
+  return _instance;
+}
+
+module.exports = {
+  getInstance,
+};

+ 19 - 0
src/test/setup.js

@@ -0,0 +1,19 @@
+
+const mongoUri = process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || process.env.MONGO_URI || 'mongodb://localhost/growi_test';
+
+const mongoose = require('mongoose');
+
+mongoose.Promise = global.Promise;
+
+beforeAll(async(done) => {
+  await mongoose.connect(mongoUri, { useNewUrlParser: true });
+  await mongoose.connection.dropDatabase();
+  done();
+});
+
+afterAll(async(done) => {
+  await mongoose.disconnect();
+  done();
+});
+
+module.exports = {};

+ 7 - 12
src/test/util/slack.test.js

@@ -1,21 +1,16 @@
-const chai = require('chai');
-const sinonChai = require('sinon-chai');
+const helpers = require('@commons/util/helpers');
 
-const expect = chai.expect;
-
-chai.use(sinonChai);
+const Crowi = require('@server/crowi');
 
 describe('Slack Util', () => {
-  const helpers = require('@commons/util/helpers');
-  const Crowi = require('@server/crowi');
-  const crowi = new Crowi(helpers.root(), process.env);
+  const crowi = new Crowi(helpers.root());
   const slack = require(`${crowi.libDir}/util/slack`)(crowi);
 
-  it('post comment method exists', () => {
-    expect(slack).to.respondTo('postComment');
+  test('post comment method exists', () => {
+    expect(slack.postComment).toBeInstanceOf(Function);
   });
 
-  it('post page method exists', () => {
-    expect(slack).to.respondTo('postPage');
+  test('post page method exists', () => {
+    expect(slack.postPage).toBeInstanceOf(Function);
   });
 });

+ 0 - 69
src/test/utils.js

@@ -1,69 +0,0 @@
-
-const mongoUri = process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || process.env.MONGO_URI || 'mongodb://localhost/growi_test';
-const mongoose = require('mongoose');
-const fs = require('fs');
-const helpers = require('@commons/util/helpers');
-const Crowi = require('@server/crowi');
-
-const crowi = new Crowi(helpers.root(), process.env);
-
-const models = {};
-
-mongoose.Promise = global.Promise;
-
-before('Create database connection and clean up', (done) => {
-  if (!mongoUri) {
-    return done();
-  }
-
-  mongoose.connect(mongoUri, { useNewUrlParser: true });
-
-  function clearDB() {
-    Object.values(mongoose.connection.collections).forEach((collection) => {
-      collection.remove(() => {});
-    });
-    return done();
-  }
-
-  if (mongoose.connection.readyState === 0) {
-    mongoose.connect(mongoUri, { useNewUrlParser: true }, (err) => {
-      if (err) {
-        throw err;
-      }
-      return clearDB();
-    });
-  }
-
-  return clearDB();
-});
-
-after('Close database connection', (done) => {
-  if (!mongoUri) {
-    return done();
-  }
-
-  mongoose.disconnect();
-  return done();
-});
-
-// Setup Models
-fs.readdirSync(helpers.root('src/server/models')).forEach((file) => {
-  if (file.match(/^([\w-]+)\.js$/)) {
-    const name = RegExp.$1;
-    if (name === 'index') {
-      return;
-    }
-    let modelName = '';
-    name.split('-').forEach((splitted) => {
-      modelName += (splitted.charAt(0).toUpperCase() + splitted.slice(1));
-    });
-    models[modelName] = require(`@server/models/${file}`)(crowi);
-  }
-});
-
-crowi.models = models;
-
-module.exports = {
-  models,
-  mongoose,
-};

File diff suppressed because it is too large
+ 502 - 100
yarn.lock


Some files were not shown because too many files changed in this diff