<commit_before>/*
 * Tests of API
 */

import * as http from 'http';
import * as fs from 'fs';
import * as assert from 'chai';

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;
const db = require('../built/db/mongodb').default;

const server = http.createServer(app.callback());

//#region Utilities
const async = (fn: Function) => (done: Function) => {
	fn().then(() => {
		done();
	}, (err: Error) => {
		done(err);
	});
};

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: '<PASSWORD>'
	}, 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

describe('API', () => {
	// Reset database each test
	beforeEach(() => new Promise((res) => {
		// APIがなにかレスポンスを返した後に、後処理を行う場合があり、
		// レスポンスを受け取ってすぐデータベースをリセットすると
		// その後処理と競合し(テスト自体は合格するものの)エラーがコンソールに出力され
		// 見た目的に気持ち悪くなるので、後処理が終るのを待つために500msくらい待ってから
		// データベースをリセットするようにする
		setTimeout(async () => {
			await Promise.all([
				db.get('users').drop(),
				db.get('posts').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()
			]);<commit_msg>Update test/api.ts<commit_after>/*
 * Tests of API
 */

import * as http from 'http';
import * as fs from 'fs';
import * as assert from 'chai';

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;
const db = require('../built/db/mongodb').default;

const server = http.createServer(app.callback());

//#region Utilities
const async = (fn: Function) => (done: Function) => {
	fn().then(() => {
		done();
	}, (err: Error) => {
		done(err);
	});
};

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: '<PASSWORD>'
	}, 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

describe('API', () => {
	// Reset database each test
	beforeEach(() => 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()
			]);
{'fraction_non_alphanumeric': 0.18836788086134032, 'fraction_numerical': 0.0012074864157778226, 'mean_word_length': 4.01008064516129, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3455213', 'n_tokens_mistral': 1998, 'n_tokens_neox': 1865, 'n_words': 397}