Refactor: Separate some test files

This commit is contained in:
syuilo 2019-01-23 12:15:27 +09:00
parent ff898b4c20
commit 931f17c589
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
3 changed files with 166 additions and 113 deletions

View file

@ -11,7 +11,7 @@
import * as http from 'http'; import * as http from 'http';
import * as fs from 'fs'; import * as fs from 'fs';
import * as assert from 'chai'; import * as assert from 'chai';
import * as WebSocket from 'ws'; import { async, _signup, _request, _uploadFile, _post, _react, resetDb } from './utils';
assert.use(require('chai-http')); assert.use(require('chai-http'));
const expect = assert.expect; const expect = assert.expect;
@ -33,87 +33,16 @@ const db = require('../built/db/mongodb').default;
const server = http.createServer(app.callback()); const server = http.createServer(app.callback());
//#region Utilities //#region Utilities
const async = (fn: Function) => (done: Function) => { const request = _request(server);
fn().then(() => { const signup = _signup(request);
done(); const post = _post(request);
}, (err: Error) => { const react = _react(request);
done(err); const uploadFile = _uploadFile(server);
});
};
const request = async (endpoint: string, params: any, me?: any): Promise<ChaiHttp.Response> => {
const auth = me ? {
i: me.token
} : {};
const res = await assert.request(server)
.post(endpoint)
.send(Object.assign(auth, params));
return res;
};
const signup = async (params?: any): Promise<any> => {
const q = Object.assign({
username: 'test',
password: 'test'
}, params);
const res = await request('/signup', q);
return res.body;
};
const post = async (user: any, params?: any): Promise<any> => {
const q = Object.assign({
text: 'test'
}, params);
const res = await request('/notes/create', q, user);
return res.body.createdNote;
};
const react = async (user: any, note: any, reaction: string): Promise<any> => {
await request('/notes/reactions/create', {
noteId: note.id,
reaction: reaction
}, user);
};
const uploadFile = async (user: any): Promise<any> => {
const res = await assert.request(server)
.post('/drive/files/create')
.field('i', user.token)
.attach('file', fs.readFileSync(__dirname + '/resources/Lenna.png'), 'Lenna.png');
return res.body;
};
//#endregion //#endregion
describe('API', () => { describe('API', () => {
// Reset database each test // Reset database each test
beforeEach(() => new Promise((res) => { beforeEach(resetDb(db));
// APIがなにかレスポンスを返した後に、後処理を行う場合があり、
// レスポンスを受け取ってすぐデータベースをリセットすると
// その後処理と競合し(テスト自体は合格するものの)エラーがコンソールに出力され
// 見た目的に気持ち悪くなるので、後処理が終るのを待つために500msくらい待ってから
// データベースをリセットするようにする
setTimeout(async () => {
await Promise.all([
db.get('users').drop(),
db.get('notes').drop(),
db.get('driveFiles.files').drop(),
db.get('driveFiles.chunks').drop(),
db.get('driveFolders').drop(),
db.get('apps').drop(),
db.get('accessTokens').drop(),
db.get('authSessions').drop()
]);
res();
}, 500);
}));
describe('signup', () => { describe('signup', () => {
it('不正なユーザー名でアカウントが作成できない', async(async () => { it('不正なユーザー名でアカウントが作成できない', async(async () => {
@ -1239,39 +1168,4 @@ describe('API', () => {
expect(res).have.status(400); expect(res).have.status(400);
})); }));
}); });
describe('streaming', () => {
it('投稿がタイムラインに流れる', done => {
const post = {
text: 'foo'
};
signup().then(me => {
const ws = new WebSocket(`ws://localhost/streaming?i=${me.token}`);
ws.on('open', () => {
ws.on('message', data => {
const msg = JSON.parse(data.toString());
if (msg.type == 'channel' && msg.body.id == 'a') {
if (msg.body.type == 'note') {
expect(msg.body.body.text).eql(post.text);
done();
}
} else if (msg.type == 'connected' && msg.body.id == 'a') {
request('/notes/create', post, me);
}
});
ws.send(JSON.stringify({
type: 'connect',
body: {
channel: 'homeTimeline',
id: 'a',
pong: true
}
}));
});
});
});
});
}); });

77
test/streaming.ts Normal file
View file

@ -0,0 +1,77 @@
/*
* Tests of streaming API
*
* How to run the tests:
* > mocha test/streaming.ts --require ts-node/register
*
* To specify test:
* > mocha test/streaming.ts --require ts-node/register -g 'test name'
*/
import * as http from 'http';
import * as WebSocket from 'ws';
import * as assert from 'chai';
import { _signup, _request, _uploadFile, _post, _react, resetDb } from './utils';
assert.use(require('chai-http'));
const expect = assert.expect;
//#region process
Error.stackTraceLimit = Infinity;
// During the test the env variable is set to test
process.env.NODE_ENV = 'test';
// Display detail of unhandled promise rejection
process.on('unhandledRejection', console.dir);
//#endregion
const app = require('../built/server/api').default;
require('../built/server').default();
const db = require('../built/db/mongodb').default;
const server = http.createServer(app.callback());
//#region Utilities
const request = _request(server);
const signup = _signup(request);
//#endregion
describe('Streaming', () => {
// Reset database each test
beforeEach(resetDb(db));
it('投稿がタイムラインに流れる', done => {
const post = {
text: 'foo'
};
signup().then(me => {
const ws = new WebSocket(`ws://localhost/streaming?i=${me.token}`);
ws.on('open', () => {
ws.on('message', data => {
const msg = JSON.parse(data.toString());
if (msg.type == 'channel' && msg.body.id == 'a') {
if (msg.body.type == 'note') {
expect(msg.body.body.text).eql(post.text);
ws.close();
done();
}
} else if (msg.type == 'connected' && msg.body.id == 'a') {
request('/notes/create', post, me);
}
});
ws.send(JSON.stringify({
type: 'connect',
body: {
channel: 'homeTimeline',
id: 'a',
pong: true
}
}));
});
});
});
});

82
test/utils.ts Normal file
View file

@ -0,0 +1,82 @@
import * as fs from 'fs';
import * as http from 'http';
import * as assert from 'chai';
export const async = (fn: Function) => (done: Function) => {
fn().then(() => {
done();
}, (err: Error) => {
done(err);
});
};
export const _request = (server: http.Server) => async (endpoint: string, params: any, me?: any): Promise<ChaiHttp.Response> => {
const auth = me ? {
i: me.token
} : {};
const res = await assert.request(server)
.post(endpoint)
.send(Object.assign(auth, params));
return res;
};
export const _signup = (request: ReturnType<typeof _request>) => async (params?: any): Promise<any> => {
const q = Object.assign({
username: 'test',
password: 'test'
}, params);
const res = await request('/signup', q);
return res.body;
};
export const _post = (request: ReturnType<typeof _request>) => async (user: any, params?: any): Promise<any> => {
const q = Object.assign({
text: 'test'
}, params);
const res = await request('/notes/create', q, user);
return res.body.createdNote;
};
export const _react = (request: ReturnType<typeof _request>) => async (user: any, note: any, reaction: string): Promise<any> => {
await request('/notes/reactions/create', {
noteId: note.id,
reaction: reaction
}, user);
};
export const _uploadFile = (server: http.Server) => async (user: any): Promise<any> => {
const res = await assert.request(server)
.post('/drive/files/create')
.field('i', user.token)
.attach('file', fs.readFileSync(__dirname + '/resources/Lenna.png'), 'Lenna.png');
return res.body;
};
export const resetDb = (db: any) => () => new Promise(res => {
// APIがなにかレスポンスを返した後に、後処理を行う場合があり、
// レスポンスを受け取ってすぐデータベースをリセットすると
// その後処理と競合し(テスト自体は合格するものの)エラーがコンソールに出力され
// 見た目的に気持ち悪くなるので、後処理が終るのを待つために500msくらい待ってから
// データベースをリセットするようにする
setTimeout(async () => {
await Promise.all([
db.get('users').drop(),
db.get('notes').drop(),
db.get('driveFiles.files').drop(),
db.get('driveFiles.chunks').drop(),
db.get('driveFolders').drop(),
db.get('apps').drop(),
db.get('accessTokens').drop(),
db.get('authSessions').drop()
]);
res();
}, 500);
});