Fixes tests

parent 9c758f28
......@@ -32,7 +32,8 @@ npm_test:
- nodejs
script:
- npm install
- node_modules/mocha/bin/mocha --opts src/tests/mocha.opts
- export NODE_ENV='test'
- node_modules/nyc/bin/nyc.js --reporter=text node_modules/mocha/bin/mocha --opts src/tests/mocha.opts
build:
stage: build
......
......@@ -6,7 +6,7 @@
"description": "Version 2 of arsnova.click (Backend)",
"scripts": {
"clean": "rm -rf ./dist/*",
"test": "mocha --opts src/tests/mocha.opts",
"test": "node_modules/nyc/bin/nyc.js --reporter=text mocha --opts src/tests/mocha.opts",
"prebuild:DEV": "npm run clean",
"prebuild:PROD": "npm run clean",
"build:DEV": "tsc && cp -r assets dist/",
......@@ -76,12 +76,30 @@
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"mocha": "^6.2.2",
"mocha-prepare": "^0.1.0",
"mocha-typescript": "^1.1.17",
"mongo-unit": "^1.4.5",
"nyc": "^14.1.1",
"sinon": "latest",
"ts-loader": "^6.2.1",
"ts-node": "^8.4.1",
"tslint": "^5.20.1",
"typescript": "^3.7.2"
},
"nyc": {
"extension": [
".ts",
".tsx"
],
"exclude": [
"**/*.d.ts",
"jobs/**",
"src/tests/**",
"src/interfaces/**"
],
"reporter": [
"text"
],
"all": true
}
}
......@@ -170,7 +170,7 @@ class QuizDAO extends AbstractDAO {
public isActiveQuiz(quizName: string): Promise<boolean> {
return QuizModel.exists({
name: this.buildQuiznameQuery(name),
name: this.buildQuiznameQuery(quizName),
state: { $in: [QuizState.Active, QuizState.Running, QuizState.Finished] },
});
}
......
import { EventEmitter } from 'events';
import * as xlsx from 'excel4node';
import * as MessageFormat from 'messageformat';
import { Document } from 'mongoose';
......@@ -7,7 +8,6 @@ import { IQuizBase } from '../interfaces/quizzes/IQuizEntity';
import { Leaderboard } from '../lib/leaderboard/leaderboard';
import { MemberModelItem } from '../models/member/MemberModel';
import { excelDefaultWorksheetOptions } from './lib/excel_default_options';
import { ExcelTheme } from './lib/excel_default_styles';
export abstract class ExcelWorksheet {
......@@ -27,12 +27,6 @@ export abstract class ExcelWorksheet {
return this._mf;
}
protected _leaderBoardData: Array<ILeaderBoardItemBase>;
get leaderBoardData(): Array<ILeaderBoardItemBase> {
return this._leaderBoardData;
}
protected _ws: xlsx.Worksheet;
get ws(): xlsx.Worksheet {
......@@ -52,6 +46,7 @@ export abstract class ExcelWorksheet {
private readonly _createdAt: string;
private readonly _quiz: IQuizBase;
private _columnsToFormat: number;
protected readonly loaded = new EventEmitter();
protected constructor({ theme, translation, quiz, mf, questionIndex }) {
this._theme = theme;
......@@ -88,13 +83,13 @@ export abstract class ExcelWorksheet {
if (this._responsesWithConfidenceValue.length > 0) {
this._columnsToFormat++;
}
this.loaded.emit('load');
});
if (this._quiz.sessionConfig.nicks.restrictToCasLogin) {
this._columnsToFormat += 2;
}
this.getLeaderboardData(questionIndex).then(data => this._leaderBoardData = data);
}
protected generateCreatedAtString(): string {
......@@ -104,7 +99,7 @@ export abstract class ExcelWorksheet {
return `${dateYMD} ${this._mf('export.exported_at')} ${dateHM} ${this._mf('export.exported_at_time')}`;
}
protected async getLeaderboardData(questionIndex: number): Promise<Array<ILeaderBoardItemBase>> {
protected async getLeaderboardData(): Promise<Array<ILeaderBoardItemBase>> {
const leaderBoard = new Leaderboard();
const { correctResponses } = await leaderBoard.buildLeaderboard(this.quiz);
return leaderBoard.sortBy(correctResponses, 'score');
......
import MemberDAO from '../db/MemberDAO';
import { IExcelWorksheet } from '../interfaces/iExcel';
import { IQuestionFreetext } from '../interfaces/questions/IQuestionFreetext';
import { asyncForEach } from '../lib/async-for-each';
import { MemberModelItem } from '../models/member/MemberModel';
import { ExcelWorksheet } from './ExcelWorksheet';
......@@ -28,8 +29,10 @@ export class FreeTextExcelWorksheet extends ExcelWorksheet implements IExcelWork
});
}));
this.formatSheet();
this.addSheetData();
this.loaded.on('load', () => {
this.formatSheet();
this.addSheetData();
});
}
public async formatSheet(): Promise<void> {
......@@ -104,8 +107,8 @@ export class FreeTextExcelWorksheet extends ExcelWorksheet implements IExcelWork
});
this.ws.cell(11, 1, attendeeEntryRows + 10, columnsToFormat, !hasEntries).style(attendeeEntryRowStyle);
this.allResponses.forEach((responseItem, indexInList) => {
const leaderboardItem = this.leaderBoardData.filter(lbItem => lbItem.name === responseItem.name)[0];
await asyncForEach(this.allResponses, async (responseItem, indexInList) => {
const leaderboardItem = (await this.getLeaderboardData()).filter(lbItem => lbItem.name === responseItem.name)[0];
let nextColumnIndex = 2;
const targetRow = indexInList + 11;
if (this._isCasRequired) {
......@@ -158,7 +161,7 @@ export class FreeTextExcelWorksheet extends ExcelWorksheet implements IExcelWork
${this.mf(answerOption.configTrimWhitespaces ? 'global.yes' : 'global.no')}`);
this.ws.cell(7, 1).string(this.mf('export.percent_correct') + ':');
const correctResponsesPercentage: number = this.leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
const correctResponsesPercentage: number = (await this.getLeaderboardData()).map(leaderboard => leaderboard.correctQuestions)
.filter(correctQuestions => correctQuestions.includes(this._questionIndex)).length
/ (await MemberDAO.getMembersOfQuiz(this.quiz.name)).length * 100;
this.ws.cell(7, 2).number((isNaN(correctResponsesPercentage) ? 0 : Math.round(correctResponsesPercentage)));
......
......@@ -24,8 +24,11 @@ export class MultipleChoiceExcelWorksheet extends ExcelWorksheet implements IExc
this._ws = wb.addWorksheet(`${mf('export.question')} ${questionIndex + 1}`, this._options);
this._questionIndex = questionIndex;
this._question = this.quiz.questionList[questionIndex] as IQuestionChoice;
this.formatSheet();
this.addSheetData();
this.loaded.on('load', () => {
this.formatSheet();
this.addSheetData();
});
}
public async formatSheet(): Promise<void> {
......@@ -152,7 +155,7 @@ export class MultipleChoiceExcelWorksheet extends ExcelWorksheet implements IExc
this.ws.cell(6, 1).string(this.mf('export.number_of_answers') + ':');
this.ws.cell(7, 1).string(this.mf('export.percent_correct') + ':');
const correctResponsesPercentage: number = this.leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
const correctResponsesPercentage: number = (await this.getLeaderboardData()).map(leaderboard => leaderboard.correctQuestions)
.filter(correctQuestions => correctQuestions.includes(this._questionIndex)).length
/ (await MemberDAO.getMembersOfQuiz(this.quiz.name)).length * 100;
this.ws.cell(7, 2).number((isNaN(correctResponsesPercentage) ? 0 : Math.round(correctResponsesPercentage)));
......@@ -171,7 +174,7 @@ export class MultipleChoiceExcelWorksheet extends ExcelWorksheet implements IExc
for (let j = 0; j < answerList.length; j++) {
this.ws.cell(2, (j + 2)).string(this.mf('export.answer') + ' ' + (j + 1));
this.ws.cell(4, (j + 2)).string(answerList[j].answerText);
this.ws.cell(6, (j + 2)).number(calculateNumberOfAnswers(this.quiz, this._questionIndex, j));
this.ws.cell(6, (j + 2)).number(await calculateNumberOfAnswers(this.quiz, this._questionIndex, j));
}
let nextColumnIndex = 1;
......
......@@ -22,8 +22,11 @@ export class RangedExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
this._ws = wb.addWorksheet(`${mf('export.question')} ${questionIndex + 1}`, this._options);
this._questionIndex = questionIndex;
this._question = this.quiz.questionList[questionIndex] as IQuestionRanged;
this.formatSheet();
this.addSheetData();
this.loaded.on('load', () => {
this.formatSheet();
this.addSheetData();
});
}
public async formatSheet(): Promise<void> {
......@@ -138,8 +141,10 @@ export class RangedExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
lastColumn: minColums,
});
const hasEntries = this.leaderBoardData.length > 0;
const attendeeEntryRows = hasEntries ? (this.leaderBoardData.length) : 1;
const leaderBoardData = await this.getLeaderboardData();
const hasEntries = leaderBoardData.length > 0;
const attendeeEntryRows = hasEntries ? (leaderBoardData.length) : 1;
const attendeeEntryRowStyle = hasEntries ? defaultStyles.attendeeEntryRowStyle : Object.assign({}, defaultStyles.attendeeEntryRowStyle, {
alignment: {
horizontal: 'center',
......@@ -147,7 +152,7 @@ export class RangedExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
});
this.ws.cell(11, 1, attendeeEntryRows + 10, columnsToFormat, !hasEntries).style(attendeeEntryRowStyle);
await asyncForEach(this.leaderBoardData, async (leaderboardItem, indexInList) => {
await asyncForEach(leaderBoardData, async (leaderboardItem, indexInList) => {
let nextColumnIndex = 2;
const targetRow = indexInList + 11;
if (this._isCasRequired) {
......@@ -190,6 +195,7 @@ export class RangedExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
}
public async addSheetData(): Promise<void> {
const leaderBoardData = await this.getLeaderboardData();
const castedQuestion = this._question as IQuestionRanged;
const numberOfInputValuesPerGroup = await calculateNumberOfRangedAnswers(this.quiz, this._questionIndex, castedQuestion.rangeMin,
castedQuestion.correctValue, castedQuestion.rangeMax);
......@@ -212,7 +218,7 @@ export class RangedExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
this.ws.cell(6, 4).number(numberOfInputValuesPerGroup.maxRange);
this.ws.cell(7, 1).string(this.mf('export.percent_correct') + ':');
const correctResponsesPercentage: number = this.leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
const correctResponsesPercentage: number = leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
.filter(correctQuestions => correctQuestions.includes(this._questionIndex)).length
/ (await MemberDAO.getMembersOfQuiz(this.quiz.name)).length * 100;
this.ws.cell(7, 2).number((isNaN(correctResponsesPercentage) ? 0 : Math.round(correctResponsesPercentage)));
......@@ -239,7 +245,7 @@ export class RangedExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
this.ws.cell(10, nextColumnIndex++).string(this.mf('export.time'));
let nextStartRow = 10;
await asyncForEach(this.leaderBoardData, async leaderboardItem => {
await asyncForEach(leaderBoardData, async leaderboardItem => {
const responseItem = (await MemberDAO.getMembersOfQuiz(this.quiz.name)).filter(nickitem => {
return nickitem.name === leaderboardItem.name;
})[0].responses[this._questionIndex];
......
......@@ -24,8 +24,11 @@ export class SingleChoiceExcelWorksheet extends ExcelWorksheet implements IExcel
this._ws = wb.addWorksheet(`${mf('export.question')} ${questionIndex + 1}`, this._options);
this._questionIndex = questionIndex;
this._question = this.quiz.questionList[questionIndex] as IQuestionChoice;
this.formatSheet();
this.addSheetData();
this.loaded.on('load', () => {
this.formatSheet();
this.addSheetData();
});
}
public async formatSheet(): Promise<void> {
......@@ -164,12 +167,12 @@ export class SingleChoiceExcelWorksheet extends ExcelWorksheet implements IExcel
for (let j = 0; j < answerList.length; j++) {
this.ws.cell(2, (j + 2)).string(this.mf('export.answer') + ' ' + (j + 1));
this.ws.cell(4, (j + 2)).string(answerList[j].answerText);
this.ws.cell(6, (j + 2)).number(calculateNumberOfAnswers(this.quiz, this._questionIndex, j));
this.ws.cell(6, (j + 2)).number(await calculateNumberOfAnswers(this.quiz, this._questionIndex, j));
}
this.ws.cell(6, 1).string(this.mf('export.number_of_answers') + ':');
this.ws.cell(7, 1).string(this.mf('export.percent_correct') + ':');
const correctResponsesPercentage: number = this.leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
const correctResponsesPercentage: number = (await this.getLeaderboardData()).map(leaderboard => leaderboard.correctQuestions)
.filter(correctQuestions => correctQuestions.includes(this._questionIndex)).length
/ (await MemberDAO.getMembersOfQuiz(this.quiz.name)).length * 100;
this.ws.cell(7, 2).number((isNaN(correctResponsesPercentage) ? 0 : Math.round(correctResponsesPercentage)));
......
......@@ -16,17 +16,6 @@ declare global {
setWidth(width: number): void;
}
interface IWorksheet {
cell: Function;
addImage: Function;
row(index: number): IRow;
}
interface IWorkbook {
addWorksheet: Function;
}
}
}
......@@ -42,12 +31,14 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
questionIndex: null,
});
this._ws = wb.addWorksheet(mf('export.summary'), this._options);
this.formatSheet();
this.addSheetData();
Promise.all([
this.formatSheet(), this.addSheetData(),
]);
}
public formatSheet(): void {
public async formatSheet(): Promise<void> {
const defaultStyles = this._theme.getStyles();
const leaderBoardData = await this.getLeaderboardData();
this.ws.row(1).setHeight(20);
this.ws.column(1).setWidth(30);
......@@ -112,7 +103,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
});
let dataWithoutCompleteCorrectQuestions = 0;
this.leaderBoardData.forEach((leaderboardItem, indexInList) => {
await asyncForEach(leaderBoardData, (leaderboardItem, indexInList) => {
let hasNotAllQuestionsCorrect = false;
this.quiz.questionList.forEach((item, index) => {
if (![
......@@ -148,15 +139,14 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
});
});
if (dataWithoutCompleteCorrectQuestions === this.leaderBoardData.length) {
if (dataWithoutCompleteCorrectQuestions === leaderBoardData.length) {
this.ws.cell(++currentRowIndex, 1, currentRowIndex, this.columnsToFormat, true).style(Object.assign({}, defaultStyles.attendeeEntryRowStyle, {
alignment: {
horizontal: 'center',
},
}));
} else {
this.ws.cell(currentRowIndex, 1, (this.leaderBoardData.length + currentRowIndex - 1 - dataWithoutCompleteCorrectQuestions),
this.columnsToFormat)
this.ws.cell(currentRowIndex, 1, (leaderBoardData.length + currentRowIndex - 1 - dataWithoutCompleteCorrectQuestions), this.columnsToFormat)
.style(defaultStyles.attendeeEntryRowStyle);
}
currentRowIndex += 6;
......@@ -172,10 +162,10 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
});
currentRowIndex++;
this.ws.cell(currentRowIndex, 1, (this.leaderBoardData.length + (currentRowIndex - 1)), this.columnsToFormat)
this.ws.cell(currentRowIndex, 1, (leaderBoardData.length + (currentRowIndex - 1)), this.columnsToFormat)
.style(defaultStyles.attendeeEntryRowStyle);
this.leaderBoardData.forEach((leaderboardItem, indexInList) => {
leaderBoardData.forEach((leaderboardItem, indexInList) => {
let nextColumnIndex = 3;
const targetRow = indexInList + currentRowIndex;
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
......@@ -201,6 +191,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
}
public async addSheetData(): Promise<void> {
const leaderBoardData = await this.getLeaderboardData();
let currentRowIndex = 1;
const numberOfResponses = (await MemberDAO.getMembersOfQuiz(this.quiz.name)).filter(nickname => {
return nickname.responses.filter(response => {
......@@ -232,7 +223,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
currentRowIndex++;
this.ws.cell(currentRowIndex, 1).string(`${this.mf('export.average_correct_answered_questions')}:`);
this.ws.cell(currentRowIndex, 3).number((this.leaderBoardData.map((x) => {
this.ws.cell(currentRowIndex, 3).number((leaderBoardData.map((x) => {
return x.correctQuestions.length;
}).reduce((a, b) => {
return a + b;
......@@ -241,7 +232,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
this.ws.cell(currentRowIndex, 1).string(`${this.mf('export.average_confidence')}:`);
const averageConfidencePercentage = (this.leaderBoardData.filter((x) => {
const averageConfidencePercentage = (leaderBoardData.filter((x) => {
return x.confidenceValue > -1;
}).map((x) => {
return x.confidenceValue;
......@@ -253,7 +244,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
}
this.ws.cell(currentRowIndex, 1).string(`${this.mf('export.average_response_time')}:`);
this.ws.cell(currentRowIndex, 3).number((Math.round((this.leaderBoardData.map((x) => {
this.ws.cell(currentRowIndex, 3).number((Math.round((leaderBoardData.map((x) => {
return x.responseTime;
}).reduce((a, b) => {
return a + b;
......@@ -280,7 +271,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
currentRowIndex++;
let nextStartRow = currentRowIndex + 5;
await asyncForEach(this.leaderBoardData, async (leaderboardItem, indexInList) => {
await asyncForEach(leaderBoardData, async (leaderboardItem, indexInList) => {
if (this.quiz.questionList.some((item, index) => ![QuestionType.SurveyQuestion, QuestionType.ABCDSingleChoiceQuestion].includes(item.TYPE)
&& leaderboardItem.correctQuestions.indexOf((index)) === -1)) {
return;
......@@ -302,7 +293,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
}
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(leaderboardItem.responseTime));
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round((leaderboardItem.responseTime / this.leaderBoardData.length)));
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round((leaderboardItem.responseTime / leaderBoardData.length)));
});
if (nextStartRow === currentRowIndex + 5) {
......@@ -341,7 +332,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
this.ws.cell(targetRow, nextColumnIndex++).string(profile.username[0]);
this.ws.cell(targetRow, nextColumnIndex++).string(profile.mail[0]);
}
const leaderboardItem = this._leaderBoardData.find((item) => item.name === responseItem.name);
const leaderboardItem = leaderBoardData.find((item) => item.name === responseItem.name);
if (leaderboardItem) {
if (leaderboardItem.correctQuestions.length > 0) {
const correctQuestionNumbers = leaderboardItem.correctQuestions.map((item) => item + 1);
......
......@@ -20,8 +20,11 @@ export class SurveyExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
this._ws = wb.addWorksheet(`${this.mf('export.question')} ${questionIndex + 1}`, this._options);
this._questionIndex = questionIndex;
this._question = this.quiz.questionList[questionIndex] as IQuestionSurvey;
this.formatSheet();
this.addSheetData();
this.loaded.on('load', () => {
this.formatSheet();
this.addSheetData();
});
}
public async formatSheet(): Promise<void> {
......@@ -133,7 +136,7 @@ export class SurveyExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
for (let j = 0; j < answerList.length; j++) {
this.ws.cell(2, (j + 2)).string(this.mf('export.answer') + ' ' + (j + 1));
this.ws.cell(4, (j + 2)).string(answerList[j].answerText);
this.ws.cell(6, (j + 2)).number(calculateNumberOfAnswers(this.quiz, this._questionIndex, j));
this.ws.cell(6, (j + 2)).number(await calculateNumberOfAnswers(this.quiz, this._questionIndex, j));
}
this.ws.cell(6, 1).string(this.mf('export.number_of_answers') + ':');
......
import { getModelForClass, index, prop } from '@typegoose/typegoose';
import { getModelForClass, index, prop, Severity } from '@typegoose/typegoose';
import DbDAO from '../db/DbDAO';
import { DbCollection } from '../enums/DbOperation';
import { IAssetSerialized } from '../interfaces/IAsset';
import LoggerService from '../services/LoggerService';
@index({ digest: 1 }, { unique: true })
export class AssetModelItem implements IAssetSerialized {
......@@ -21,12 +20,8 @@ export const AssetModel = getModelForClass(AssetModelItem, {
timestamps: true,
},
existingConnection: DbDAO.dbCon,
options: {
runSyncIndexes: true,
allowMixed: Severity.ALLOW,
},
});
AssetModel.collection.dropIndexes().then(() => AssetModel.createIndexes(err => {
if (!err) {
return;
}
LoggerService.error('Unique index for AssetModel created with error', err);
}));
import { arrayProp, getModelForClass, index, prop } from '@typegoose/typegoose';
import { arrayProp, getModelForClass, index, prop, Severity } from '@typegoose/typegoose';
import DbDAO from '../../db/DbDAO';
import { DbCollection } from '../../enums/DbOperation';
import { IUserSerialized } from '../../interfaces/users/IUserSerialized';
import LoggerService from '../../services/LoggerService';
@index({ name: 1 }, { unique: true })
export class UserModelItem implements IUserSerialized {
......@@ -24,12 +23,8 @@ export const UserModel = getModelForClass(UserModelItem, {
timestamps: true,
},
existingConnection: DbDAO.dbCon,
options: {
runSyncIndexes: true,
allowMixed: Severity.ALLOW,
},
});
UserModel.collection.dropIndexes().then(() => UserModel.createIndexes(err => {
if (!err) {
return;
}
LoggerService.error('Unique index for UserModel created with error', err);
}));
import { arrayProp, getModelForClass, index, pre, prop } from '@typegoose/typegoose';
import { arrayProp, getModelForClass, index, pre, prop, Severity } from '@typegoose/typegoose';
import DbDAO from '../../db/DbDAO';
import { DbCollection } from '../../enums/DbOperation';
import { IMemberSerialized } from '../../interfaces/entities/Member/IMemberSerialized';
import { IQuizResponse } from '../../interfaces/quizzes/IQuizResponse';
import { ICasData } from '../../interfaces/users/ICasData';
import LoggerService from '../../services/LoggerService';
@index({
name: 1,
......@@ -58,12 +57,9 @@ export const MemberModel = getModelForClass(MemberModelItem, {
timestamps: true,
},
existingConnection: DbDAO.dbCon,
options: {
runSyncIndexes: true,
allowMixed: Severity.ALLOW,
},
});
MemberModel.collection.dropIndexes().then(() => MemberModel.createIndexes(err => {
if (!err) {
return;
}
LoggerService.error('Unique index for MemberModel created with error', err);
}));
import { arrayProp, getModelForClass, index, prop } from '@typegoose/typegoose';
import { arrayProp, getModelForClass, index, prop, Severity } from '@typegoose/typegoose';
import DbDAO from '../../db/DbDAO';
import { DbCollection } from '../../enums/DbOperation';
import { QuizState } from '../../enums/QuizState';
import { QuizVisibility } from '../../enums/QuizVisibility';
import { IQuestion } from '../../interfaces/questions/IQuestion';
import LoggerService from '../../services/LoggerService';
import { SessionConfigurationModelItem } from '../session-config/SessionConfigurationModelItem';
@index({ name: 1 }, {
......@@ -44,12 +43,8 @@ export const QuizModel = getModelForClass(QuizModelItem, {
timestamps: true,
},
existingConnection: DbDAO.dbCon,
options: {
runSyncIndexes: true,
allowMixed: Severity.ALLOW,
},
});
QuizModel.collection.dropIndexes().then(() => QuizModel.createIndexes(err => {
if (!err) {
return;
}
LoggerService.error('Unique index for QuizModel created with error', err);
}));
......@@ -17,7 +17,7 @@ import { MessageProtocol, StatusProtocol } from '../../enums/Message';
import { IMessage } from '../../interfaces/communication/IMessage';
import { IQuiz } from '../../interfaces/quizzes/IQuizEntity';
import { ICasData } from '../../interfaces/users/ICasData';
import { MatchAssetCachedQuiz, MatchTextToAssetsDb } from '../../lib/cache/assets';
import { MatchAssetCachedQuiz } from '../../lib/cache/assets';
import { UserModelItem } from '../../models/UserModelItem/UserModel';
import { AuthService } from '../../services/AuthService';
import LoggerService from '../../services/LoggerService';
......@@ -230,33 +230,6 @@ export class LibRouter extends AbstractRouter {
});
}
@Post('/cache/quiz/assets')
public async cacheQuizAssets(@BodyParam('quiz') quiz: IQuiz): Promise<IMessage> {
if (!quiz) {
throw new BadRequestError(`Malformed request received -> ${quiz}`);
}
const promises: Array<Promise<any>> = [];
quiz.questionList.forEach(question => {
promises.push(MatchTextToAssetsDb(question.questionText).then(val => question.questionText = val));
question.answerOptionList.forEach(answerOption => {
promises.push(MatchTextToAssetsDb(answerOption.answerText).then(val => answerOption.answerText = val));
});
});
await Promise.all<any>(promises);
return {
status: StatusProtocol.Success,
step: MessageProtocol.QuizAssets,
payload: {
quiz,
},
};
}
@Get('/cache/quiz/assets/:digest')
public async getCache(@Param('digest') digest: string, @Res() response: Response): Promise<ArrayBufferLike> {
const doc = await AssetDAO.getAssetByDigestAsLean(digest);
......
......@@ -134,7 +134,7 @@ export class MemberRouter extends AbstractRouter {
@Put('/response')
public async addResponse(
@HeaderParam('authorization') token: string, //
@BodyParam('response', { required: false }) value: string, //
@BodyParam('response', { required: false }) value: Array<number> | string | number, //
): Promise<IMessage> {
if (!Array.isArray(value) && !['string', 'number'].includes(typeof value)) {
......
......@@ -6,6 +6,7 @@ import { staticStatistics } from '../statistics';
class LoggerService {
private static instance: LoggerService;
public useLog = true;
private _logger: bunyan;
......
......@@ -2,6 +2,7 @@
import { setGlobalOptions } from '@typegoose/typegoose';
import { suite, test } from 'mocha-typescript';
import * as mongoUnit from 'mongo-unit';
setGlobalOptions({
globalOptions: {
......@@ -12,6 +13,14 @@ setGlobalOptions({
@suite
class AppBootstrapRouterTestSuite {
public async before(): Promise<void> {
await mongoUnit.initDb(process.env.MONGODB_CONN_URL, []);
}
public async after(): Promise<void> {
return mongoUnit.drop();
}
@test
public async ensureDefaultPathsExist(): Promise<void> {
}
......
......@@ -4,16 +4,15 @@ import * as assert from 'assert';
import * as fs from 'fs';
import * as i18n from 'i18n';
import * as MessageFormat from 'messageformat';
import { skip, slow, suite, test } from 'mocha-typescript';
import { slow, suite, test } from 'mocha-typescript';
import * as mongoUnit from 'mongo-unit';
import { Document } from 'mongoose';
import * as path from 'path';
import * as sinon from 'sinon';
import AMQPConnector from '../../db/AMQPConnector';
import MemberDAO from '../../db/MemberDAO';
import MongoDBConnector from '../../db/MongoDBConnector';
import QuizDAO from '../../db/quiz/QuizDAO';
import { QuestionType } from '../../enums/QuestionType';
import { QuizState } from '../../enums/QuizState';
import { ExcelWorkbook } from '../../export/ExcelWorkbook';
import { IQuestionRanged } from '../../interfaces/questions/IQuestionRanged';
import { IQuestionSurvey } from '../../interfaces/questions/IQuestionSurvey';
......@@ -22,7 +21,7 @@ import LoggerService from '../../services/LoggerService';
import { staticStatistics } from '../../statistics';
import { generateQuiz } from '../fixtures';
@suite @skip
@suite
class ExcelExportTestSuite {
private readonly _hashtag = 'mocha-export-test';
private _memberCount = 20;
......@@ -33,7 +32,7 @@ class ExcelExportTestSuite {
private _dateFormatted = `${this._dateDay}-${this._date.getHours()}_${this._date.getMinutes()}`;
private _exportLocation = path.join(__dirname, '..', '..', '..', 'test-generated', `Export-${this._hashtag}-${this._dateFormatted}.xlsx`);
public static before(): void {
public static async before(): Promise<void> {
i18n.configure({
locales: ['en'],
defaultLocale: 'en',
......@@ -61,7 +60,7 @@ class ExcelExportTestSuite {
}
public async after(): Promise<void> {
await QuizDAO.removeQuiz((await QuizDAO.getQuizByName(this._hashtag)).id);
return mongoUnit.drop();
}
public async before(): Promise<void> {
......@@ -70,31 +69,37 @@ class ExcelExportTestSuite {
assertExchange: () => {},
publish: () => {},
});
sandbox.stub(MongoDBConnector, 'connect').value({ assertExchange: () => {} });
await mongoUnit.initDb(process.env.MONGODB_CONN_URL, []);
}