mirror of
https://github.com/wekan/wekan.git
synced 2025-04-24 14:08:31 -04:00
Merge branch 'tests' of https://github.com/jankapunkt/wekan into jankapunkt-tests
This commit is contained in:
commit
66729e4c05
13 changed files with 1155 additions and 5975 deletions
9
.babelrc
9
.babelrc
|
@ -1,5 +1,12 @@
|
||||||
{
|
{
|
||||||
"presets": [
|
"presets": [
|
||||||
"@babel/preset-stage-3"
|
"@babel/preset-stage-3"
|
||||||
]
|
],
|
||||||
|
"env": {
|
||||||
|
"COVERAGE": {
|
||||||
|
"plugins": [
|
||||||
|
"istanbul"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
161
.github/workflows/test_suite.yml
vendored
Normal file
161
.github/workflows/test_suite.yml
vendored
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
name: Test suite
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# the following are optional jobs and need to be configured according
|
||||||
|
# to this project's settings:
|
||||||
|
#
|
||||||
|
# lintcode:
|
||||||
|
# name: Javascript lint
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# steps:
|
||||||
|
# - name: checkout
|
||||||
|
# uses: actions/checkout@v2
|
||||||
|
#
|
||||||
|
# - name: setup node
|
||||||
|
# uses: actions/setup-node@v1
|
||||||
|
# with:
|
||||||
|
# node-version: '12.x'
|
||||||
|
#
|
||||||
|
# - name: cache dependencies
|
||||||
|
# uses: actions/cache@v1
|
||||||
|
# with:
|
||||||
|
# path: ~/.npm
|
||||||
|
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
# restore-keys: |
|
||||||
|
# ${{ runner.os }}-node-
|
||||||
|
#
|
||||||
|
# - run: npm install
|
||||||
|
# - run: npm run lint:code
|
||||||
|
#
|
||||||
|
# lintstyle:
|
||||||
|
# name: SCSS lint
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# needs: [lintcode]
|
||||||
|
# steps:
|
||||||
|
# - name: checkout
|
||||||
|
# uses: actions/checkout@v2
|
||||||
|
#
|
||||||
|
# - name: setup node
|
||||||
|
# uses: actions/setup-node@v1
|
||||||
|
# with:
|
||||||
|
# node-version: '12.x'
|
||||||
|
#
|
||||||
|
# - name: cache dependencies
|
||||||
|
# uses: actions/cache@v1
|
||||||
|
# with:
|
||||||
|
# path: ~/.npm
|
||||||
|
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
# restore-keys: |
|
||||||
|
# ${{ runner.os }}-node-
|
||||||
|
# - run: npm install
|
||||||
|
# - run: npm run lint:style
|
||||||
|
#
|
||||||
|
# lintdocs:
|
||||||
|
# name: documentation lint
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# needs: [lintcode,lintstyle]
|
||||||
|
# steps:
|
||||||
|
# - name: checkout
|
||||||
|
# uses: actions/checkout@v2
|
||||||
|
#
|
||||||
|
# - name: setup node
|
||||||
|
# uses: actions/setup-node@v1
|
||||||
|
# with:
|
||||||
|
# node-version: '12.x'
|
||||||
|
#
|
||||||
|
# - name: cache dependencies
|
||||||
|
# uses: actions/cache@v1
|
||||||
|
# with:
|
||||||
|
# path: ~/.npm
|
||||||
|
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
# restore-keys: |
|
||||||
|
# ${{ runner.os }}-node-
|
||||||
|
#
|
||||||
|
# - run: npm install
|
||||||
|
# - run: npm run lint:markdown
|
||||||
|
|
||||||
|
tests:
|
||||||
|
name: Meteor ${{ matrix.meteor }} tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# CHECKOUTS
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# CACHING
|
||||||
|
- name: Install Meteor
|
||||||
|
id: cache-meteor-install
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.meteor
|
||||||
|
key: v1-meteor-${{ hashFiles('.meteor/versions') }}
|
||||||
|
restore-keys: |
|
||||||
|
v1-meteor-
|
||||||
|
|
||||||
|
- name: Cache NPM dependencies
|
||||||
|
id: cache-meteor-npm
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: v1-npm-${{ hashFiles('package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
v1-npm-
|
||||||
|
|
||||||
|
- name: Cache Meteor build
|
||||||
|
id: cache-meteor-build
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
.meteor/local/resolver-result-cache.json
|
||||||
|
.meteor/local/plugin-cache
|
||||||
|
.meteor/local/isopacks
|
||||||
|
.meteor/local/bundler-cache/scanner
|
||||||
|
key: v1-meteor_build_cache-${{ github.ref }}-${{ github.sha }}
|
||||||
|
restore-key: |
|
||||||
|
v1-meteor_build_cache-
|
||||||
|
|
||||||
|
- name: Setup meteor
|
||||||
|
uses: meteorengineer/setup-meteor@v1
|
||||||
|
with:
|
||||||
|
meteor-release: '2.2'
|
||||||
|
|
||||||
|
- name: Install NPM Dependencies
|
||||||
|
run: meteor npm ci
|
||||||
|
|
||||||
|
- name: Run Tests
|
||||||
|
run: sh ./test-wekan.sh -cv
|
||||||
|
|
||||||
|
- name: Upload coverage
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: coverage-folder
|
||||||
|
path: .coverage/
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
name: Coverage report
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [tests]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Download coverage
|
||||||
|
uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
name: coverage-folder
|
||||||
|
path: .coverage/
|
||||||
|
|
||||||
|
|
||||||
|
- name: Coverage Report
|
||||||
|
uses: VeryGoodOpenSource/very_good_coverage@v1.1.1
|
||||||
|
with:
|
||||||
|
path: ".coverage/lcov.info"
|
||||||
|
min_coverage: 1 # TODO add tests and increase to 95!
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -33,3 +33,4 @@ ehthumbs.db
|
||||||
.meteor/local
|
.meteor/local
|
||||||
.devcontainer/docker-compose.extend.yml
|
.devcontainer/docker-compose.extend.yml
|
||||||
.devcontainer/volumes*/
|
.devcontainer/volumes*/
|
||||||
|
.coverage
|
||||||
|
|
|
@ -145,3 +145,5 @@ spacebars
|
||||||
easylogic:summernote
|
easylogic:summernote
|
||||||
pascoual:pdfkit
|
pascoual:pdfkit
|
||||||
wekan-accounts-lockout
|
wekan-accounts-lockout
|
||||||
|
lmieulet:meteor-coverage
|
||||||
|
meteortesting:mocha
|
||||||
|
|
|
@ -69,6 +69,7 @@ lamhieu:meteorx@2.1.1
|
||||||
lamhieu:unblock@1.0.0
|
lamhieu:unblock@1.0.0
|
||||||
launch-screen@1.2.1
|
launch-screen@1.2.1
|
||||||
livedata@1.0.18
|
livedata@1.0.18
|
||||||
|
lmieulet:meteor-coverage@3.2.0
|
||||||
localstorage@1.2.0
|
localstorage@1.2.0
|
||||||
logging@1.2.0
|
logging@1.2.0
|
||||||
matb33:collection-hooks@0.9.1
|
matb33:collection-hooks@0.9.1
|
||||||
|
@ -82,6 +83,9 @@ meteorhacks:collection-utils@1.2.0
|
||||||
meteorhacks:picker@1.0.3
|
meteorhacks:picker@1.0.3
|
||||||
meteorhacks:subs-manager@1.6.4
|
meteorhacks:subs-manager@1.6.4
|
||||||
meteorspark:util@0.2.0
|
meteorspark:util@0.2.0
|
||||||
|
meteortesting:browser-tests@1.3.4
|
||||||
|
meteortesting:mocha@2.0.1
|
||||||
|
meteortesting:mocha-core@8.0.1
|
||||||
minifier-css@1.5.4
|
minifier-css@1.5.4
|
||||||
minifier-js@2.6.0
|
minifier-js@2.6.0
|
||||||
minifiers@1.1.8-faster-rebuild.0
|
minifiers@1.1.8-faster-rebuild.0
|
||||||
|
|
197
client/lib/tests/Utils.tests.js
Normal file
197
client/lib/tests/Utils.tests.js
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
/* eslint-env mocha */
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import { Random } from 'meteor/random';
|
||||||
|
import '../utils';
|
||||||
|
|
||||||
|
|
||||||
|
describe('Utils', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
sinon.stub(Utils, 'reload').callsFake(() => {});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
window.localStorage.removeItem(boardView);
|
||||||
|
sinon.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
const boardView = 'boardView';
|
||||||
|
|
||||||
|
describe(Utils.setBoardView.name, function() {
|
||||||
|
it('sets the board view if the user exists', function(done) {
|
||||||
|
const viewId = Random.id();
|
||||||
|
const user = {
|
||||||
|
setBoardView: (view) => {
|
||||||
|
expect(view).to.equal(viewId);
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
sinon.stub(Meteor, 'user').callsFake(() => user);
|
||||||
|
Utils.setBoardView(viewId);
|
||||||
|
|
||||||
|
expect(window.localStorage.getItem(boardView)).to.equal(viewId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets a specific view if no user exists but a view is defined', function() {
|
||||||
|
const views = [
|
||||||
|
'board-view-swimlanes',
|
||||||
|
'board-view-lists',
|
||||||
|
'board-view-cal'
|
||||||
|
];
|
||||||
|
|
||||||
|
sinon.stub(Meteor, 'user').callsFake(() => {});
|
||||||
|
|
||||||
|
views.forEach(viewName => {
|
||||||
|
Utils.setBoardView(viewName);
|
||||||
|
expect(window.localStorage.getItem(boardView)).to.equal(viewName);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets a default view if no user and no view are given', function() {
|
||||||
|
sinon.stub(Meteor, 'user').callsFake(() => {});
|
||||||
|
Utils.setBoardView();
|
||||||
|
expect(window.localStorage.getItem(boardView)).to.equal('board-view-swimlanes');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.unsetBoardView.name, function() {
|
||||||
|
it('removes the boardview from localStoage', function() {
|
||||||
|
window.localStorage.setItem(boardView, Random.id());
|
||||||
|
window.localStorage.setItem('collapseSwimlane', Random.id());
|
||||||
|
|
||||||
|
Utils.unsetBoardView();
|
||||||
|
|
||||||
|
expect(window.localStorage.getItem(boardView)).to.equal(null);
|
||||||
|
expect(window.localStorage.getItem('collapseSwimlane')).to.equal(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.boardView.name, function() {
|
||||||
|
it('returns the user\'s board view if a user exists', function() {
|
||||||
|
const viewId = Random.id();
|
||||||
|
const user = {};
|
||||||
|
sinon.stub(Meteor, 'user').callsFake(() => user);
|
||||||
|
expect(Utils.boardView()).to.equal(undefined);
|
||||||
|
|
||||||
|
const boardView = Random.id();
|
||||||
|
user.profile = { boardView };
|
||||||
|
|
||||||
|
expect(Utils.boardView()).to.equal(boardView);
|
||||||
|
});
|
||||||
|
it('returns the current defined view', function() {
|
||||||
|
const views = [
|
||||||
|
'board-view-swimlanes',
|
||||||
|
'board-view-lists',
|
||||||
|
'board-view-cal'
|
||||||
|
];
|
||||||
|
|
||||||
|
sinon.stub(Meteor, 'user').callsFake(() => {});
|
||||||
|
|
||||||
|
views.forEach(viewName => {
|
||||||
|
window.localStorage.setItem(boardView, viewName);
|
||||||
|
expect(Utils.boardView()).to.equal(viewName);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('returns a default if nothing is set', function() {
|
||||||
|
sinon.stub(Meteor, 'user').callsFake(() => {});
|
||||||
|
expect(Utils.boardView()).to.equal('board-view-swimlanes');
|
||||||
|
expect(window.localStorage.getItem(boardView)).to.equal('board-view-swimlanes');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.myCardsSort.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.myCardsSortToggle.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.setMyCardsSort.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.archivedBoardIds.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.dueCardsView.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.setDueCardsView.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.goBoardId.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.goCardId.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.processUploadedAttachment.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.shrinkImage.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.capitalize.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.isMiniScreen.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.isShowDesktopDragHandles.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.isMiniScreenOrShowDesktopDragHandles.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.calculateIndexData.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.calculateIndex.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.isTouchDevice.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.calculateTouchDistance.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.enableClickOnTouch.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.manageCustomUI.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.setCustomUI.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.setMatomo.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.manageMatomo.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(Utils.getTriggerActionDesc.name, function() {
|
||||||
|
it('has no tests yet');
|
||||||
|
});
|
||||||
|
});
|
1
client/lib/tests/index.js
Normal file
1
client/lib/tests/index.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
import './Utils.tests';
|
|
@ -1,20 +1,27 @@
|
||||||
Utils = {
|
Utils = {
|
||||||
|
reload () {
|
||||||
|
// we move all window.location.reload calls into this function
|
||||||
|
// so we can disable it when running tests.
|
||||||
|
// This is because we are not allowed to override location.reload but
|
||||||
|
// we can override Utils.reload to prevent reload during tests.
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
setBoardView(view) {
|
setBoardView(view) {
|
||||||
currentUser = Meteor.user();
|
currentUser = Meteor.user();
|
||||||
if (currentUser) {
|
if (currentUser) {
|
||||||
Meteor.user().setBoardView(view);
|
Meteor.user().setBoardView(view);
|
||||||
} else if (view === 'board-view-swimlanes') {
|
} else if (view === 'board-view-swimlanes') {
|
||||||
window.localStorage.setItem('boardView', 'board-view-swimlanes'); //true
|
window.localStorage.setItem('boardView', 'board-view-swimlanes'); //true
|
||||||
location.reload();
|
Utils.reload();
|
||||||
} else if (view === 'board-view-lists') {
|
} else if (view === 'board-view-lists') {
|
||||||
window.localStorage.setItem('boardView', 'board-view-lists'); //true
|
window.localStorage.setItem('boardView', 'board-view-lists'); //true
|
||||||
location.reload();
|
Utils.reload();
|
||||||
} else if (view === 'board-view-cal') {
|
} else if (view === 'board-view-cal') {
|
||||||
window.localStorage.setItem('boardView', 'board-view-cal'); //true
|
window.localStorage.setItem('boardView', 'board-view-cal'); //true
|
||||||
location.reload();
|
Utils.reload();
|
||||||
} else {
|
} else {
|
||||||
window.localStorage.setItem('boardView', 'board-view-swimlanes'); //true
|
window.localStorage.setItem('boardView', 'board-view-swimlanes'); //true
|
||||||
location.reload();
|
Utils.reload();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -39,7 +46,7 @@ Utils = {
|
||||||
return 'board-view-cal';
|
return 'board-view-cal';
|
||||||
} else {
|
} else {
|
||||||
window.localStorage.setItem('boardView', 'board-view-swimlanes'); //true
|
window.localStorage.setItem('boardView', 'board-view-swimlanes'); //true
|
||||||
location.reload();
|
Utils.reload();
|
||||||
return 'board-view-swimlanes';
|
return 'board-view-swimlanes';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -64,7 +71,7 @@ Utils = {
|
||||||
|
|
||||||
setMyCardsSort(sort) {
|
setMyCardsSort(sort) {
|
||||||
window.localStorage.setItem('myCardsSort', sort);
|
window.localStorage.setItem('myCardsSort', sort);
|
||||||
location.reload();
|
Utils.reload();
|
||||||
},
|
},
|
||||||
|
|
||||||
archivedBoardIds() {
|
archivedBoardIds() {
|
||||||
|
@ -87,7 +94,7 @@ Utils = {
|
||||||
|
|
||||||
setDueCardsView(view) {
|
setDueCardsView(view) {
|
||||||
window.localStorage.setItem('dueCardsView', view);
|
window.localStorage.setItem('dueCardsView', view);
|
||||||
location.reload();
|
Utils.reload();
|
||||||
},
|
},
|
||||||
|
|
||||||
// XXX We should remove these two methods
|
// XXX We should remove these two methods
|
||||||
|
|
6491
package-lock.json
generated
6491
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,11 @@
|
||||||
},
|
},
|
||||||
"homepage": "https://wekan.github.io",
|
"homepage": "https://wekan.github.io",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"flatted": "^3.1.1"
|
"babel-plugin-istanbul": "^6.0.0",
|
||||||
|
"chai": "^4.3.4",
|
||||||
|
"flatted": "^3.1.1",
|
||||||
|
"puppeteer": "^10.0.0",
|
||||||
|
"sinon": "^11.1.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.14.0",
|
"@babel/core": "^7.14.0",
|
||||||
|
@ -41,5 +45,8 @@
|
||||||
"papaparse": "^5.3.0",
|
"papaparse": "^5.3.0",
|
||||||
"qs": "^6.10.1",
|
"qs": "^6.10.1",
|
||||||
"source-map-support": "^0.5.19"
|
"source-map-support": "^0.5.19"
|
||||||
|
},
|
||||||
|
"meteor": {
|
||||||
|
"testModule": "tests/main.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
106
server/lib/utils.tests.js
Normal file
106
server/lib/utils.tests.js
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/* eslint-env mocha */
|
||||||
|
import { Random } from 'meteor/random';
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import './utils';
|
||||||
|
|
||||||
|
describe('utils', function() {
|
||||||
|
describe(allowIsBoardAdmin.name, function() {
|
||||||
|
it('returns if a board has an admin', function() {
|
||||||
|
const userId = Random.id();
|
||||||
|
const board = {
|
||||||
|
hasAdmin: id => {
|
||||||
|
return id === userId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(allowIsBoardAdmin(userId, board)).to.equal(true);
|
||||||
|
expect(allowIsBoardAdmin(Random.id(), board)).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(allowIsBoardMember.name, function() {
|
||||||
|
it('returns if a board has a member', function() {
|
||||||
|
const userId = Random.id();
|
||||||
|
const board = {
|
||||||
|
hasMember: id => {
|
||||||
|
return id === userId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(allowIsBoardMember(userId, board)).to.equal(true);
|
||||||
|
expect(allowIsBoardMember(Random.id(), board)).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(allowIsAnyBoardMember.name, function() {
|
||||||
|
it('returns if any board has a member', function() {
|
||||||
|
const userId = Random.id();
|
||||||
|
const boardsExpectedTrue = [{
|
||||||
|
hasMember: id => {
|
||||||
|
return id === userId;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
expect(allowIsAnyBoardMember(userId, boardsExpectedTrue)).to.equal(true);
|
||||||
|
expect(allowIsAnyBoardMember(Random.id(), boardsExpectedTrue)).to.equal(false);
|
||||||
|
|
||||||
|
const boardsExpectedFalse = [{
|
||||||
|
hasMember: () => false
|
||||||
|
}];
|
||||||
|
|
||||||
|
expect(allowIsAnyBoardMember(userId, boardsExpectedFalse)).to.equal(false);
|
||||||
|
expect(allowIsAnyBoardMember(Random.id(), boardsExpectedFalse)).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(allowIsBoardMemberCommentOnly.name, function() {
|
||||||
|
it('returns if a board has a member that is not comment-only member', function() {
|
||||||
|
const userId = Random.id();
|
||||||
|
const board = {
|
||||||
|
hasMember: id => {
|
||||||
|
return id === userId;
|
||||||
|
},
|
||||||
|
hasCommentOnly: id => {
|
||||||
|
return id !== userId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(allowIsBoardMemberCommentOnly(userId, board)).to.equal(true);
|
||||||
|
expect(allowIsBoardMemberCommentOnly(Random.id(), board)).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(allowIsBoardMemberNoComments.name, function() {
|
||||||
|
it('returns if a board has a member that has comment any comments', function() {
|
||||||
|
const userId = Random.id();
|
||||||
|
const board = {
|
||||||
|
hasMember: id => {
|
||||||
|
return id === userId;
|
||||||
|
},
|
||||||
|
hasNoComments: id => {
|
||||||
|
return id !== userId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(allowIsBoardMemberNoComments(userId, board)).to.equal(true);
|
||||||
|
expect(allowIsBoardMemberNoComments(Random.id(), board)).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(allowIsBoardMemberByCard.name, function() {
|
||||||
|
it('returns if the board for a given card has a member', function() {
|
||||||
|
const userId = Random.id();
|
||||||
|
const board = {
|
||||||
|
hasMember: id => {
|
||||||
|
return id === userId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const card = {
|
||||||
|
board: () => board
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(allowIsBoardMemberByCard(userId, card)).to.equal(true);
|
||||||
|
expect(allowIsBoardMemberByCard(Random.id(), card)).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
98
test-wekan.sh
Executable file
98
test-wekan.sh
Executable file
|
@ -0,0 +1,98 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
#
|
||||||
|
# Variable declarations
|
||||||
|
#
|
||||||
|
# ------------------------------------------
|
||||||
|
|
||||||
|
PROJECT_ROOT=$(pwd)
|
||||||
|
PORT=4040
|
||||||
|
RUN_ONCE='--once'
|
||||||
|
VERBOSE_MODE=0
|
||||||
|
WATCH_MODE=0
|
||||||
|
COVERAGE=0
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
#
|
||||||
|
# Read args from script call
|
||||||
|
#
|
||||||
|
# ------------------------------------------
|
||||||
|
|
||||||
|
while getopts "vcw" opt; do
|
||||||
|
case $opt in
|
||||||
|
v)
|
||||||
|
VERBOSE_MODE=1
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
COVERAGE=1
|
||||||
|
;;
|
||||||
|
w)
|
||||||
|
WATCH_MODE=1
|
||||||
|
RUN_ONCE=''
|
||||||
|
;;
|
||||||
|
\?)
|
||||||
|
echo "Invalid option: -$OPTARG" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
#
|
||||||
|
# Print variables on verbose mode
|
||||||
|
#
|
||||||
|
# ------------------------------------------
|
||||||
|
|
||||||
|
if [ "$VERBOSE_MODE" -eq "1" ];
|
||||||
|
then
|
||||||
|
PROJECT_NAME=`basename "$PROJECT_ROOT"`
|
||||||
|
echo "=> Test $PROJECT_NAME"
|
||||||
|
echo "=> Path: [${PROJECT_ROOT}]"
|
||||||
|
echo "=> Port: [${PORT}]"
|
||||||
|
echo "=> Watch mode: [${WATCH_MODE}] ${RUN_ONCE}"
|
||||||
|
echo "=> COVERAGE: [${COVERAGE}]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$WATCH_MODE" -eq "0" ];
|
||||||
|
then
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# in cli mode we use a headless browser to include client tests
|
||||||
|
# and we activate the coverage reporting functionality
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
BABEL_ENV=COVERAGE \
|
||||||
|
TEST_BROWSER_DRIVER=puppeteer \
|
||||||
|
TEST_SERVER=1 \
|
||||||
|
TEST_CLIENT=1 \
|
||||||
|
COVERAGE=${COVERAGE} \
|
||||||
|
COVERAGE_OUT_HTML=1 \
|
||||||
|
COVERAGE_OUT_LCOVONLY=1 \
|
||||||
|
COVERAGE_OUT_TEXT_SUMMARY=1 \
|
||||||
|
COVERAGE_OUT_JSON_SUMMARY=1 \
|
||||||
|
COVERAGE_APP_FOLDER=$PWD/ \
|
||||||
|
COVERAGE_VERBOSE_MODE=${VERBOSE_MODE} \
|
||||||
|
meteor test \
|
||||||
|
--exclude-archs=web.browser.legacy,web.cordova \
|
||||||
|
--driver-package=meteortesting:mocha \
|
||||||
|
--settings=settings.json \
|
||||||
|
--port=${PORT} \
|
||||||
|
--once
|
||||||
|
cat ./.coverage/summary.txt
|
||||||
|
else
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# in watch mode we neither use a browser driver, nor coverage
|
||||||
|
# se we speed up the test reload in the development phase
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
TEST_BROWSER_DRIVER=puppeteer \
|
||||||
|
TEST_SERVER=1 \
|
||||||
|
TEST_CLIENT=1 \
|
||||||
|
meteor test \
|
||||||
|
--exclude-archs=web.browser.legacy,web.cordova \
|
||||||
|
--driver-package=meteortesting:mocha \
|
||||||
|
--settings=settings.json \
|
||||||
|
--port=${PORT}
|
||||||
|
fi
|
30
tests/main.js
Normal file
30
tests/main.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/* eslint-env mocha */
|
||||||
|
|
||||||
|
// This is the main test file from which all tests can be imported top-down,
|
||||||
|
// creating a directed sequence for tests that sums up to our test-suite.
|
||||||
|
//
|
||||||
|
// You propably want to start with low-level code and follow up to higher-level
|
||||||
|
// code, like for example:
|
||||||
|
//
|
||||||
|
// infrastructure
|
||||||
|
// utils / helpers
|
||||||
|
// contexts
|
||||||
|
// api
|
||||||
|
// components
|
||||||
|
// ui
|
||||||
|
|
||||||
|
// If you want to run tests on both, server AND client, simply import them as
|
||||||
|
// they are. However, if you want to restict tests to server-only or client-only
|
||||||
|
// you need to wrap them inside a new describe-block
|
||||||
|
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
describe('server', function() {
|
||||||
|
import '../server/lib/utils.tests';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Meteor.isClient) {
|
||||||
|
describe('lib', function() {
|
||||||
|
import '../client/lib/tests';
|
||||||
|
});
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue