Add more unit tests

parent 4c7b2621
......@@ -1229,7 +1229,7 @@
"dev": true
},
"arsnova-click-v2-types": {
"version": "git+https://git.thm.de/arsnova/arsnova-click-v2-types.git#5d88ec8b9494541e3644f534cb839e1047167857",
"version": "git+https://git.thm.de/arsnova/arsnova-click-v2-types.git#88ca43a877a3243c7945396d07fca67b659aa9ab",
"from": "git+https://git.thm.de/arsnova/arsnova-click-v2-types.git",
"dev": true
},
......
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { TranslateCompiler, TranslateLoader, TranslateModule } from '@ngx-translate/core';
......@@ -19,7 +19,7 @@ describe('MemberGroupManagerComponent', () => {
let component: MemberGroupManagerComponent;
let fixture: ComponentFixture<MemberGroupManagerComponent>;
beforeEach(async(() => {
beforeEach((() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
......@@ -48,13 +48,54 @@ describe('MemberGroupManagerComponent', () => {
}).compileComponents();
}));
beforeEach(async(() => {
beforeEach((() => {
fixture = TestBed.createComponent(MemberGroupManagerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', async(() => {
beforeEach(() => {
component.memberGroups.splice(0, component.memberGroups.length);
component.memberGroups.push('Default');
});
it('should create', (() => {
expect(component).toBeTruthy();
}));
it('should contain a TYPE reference', (() => {
expect(MemberGroupManagerComponent.TYPE).toEqual('MemberGroupManagerComponent');
}));
describe('#addMemberGroup', () => {
it('should add a member group on valid input', (() => {
component.memberGroupName = 'testgroup';
component.addMemberGroup();
expect(component.memberGroups.length).toEqual(2);
}));
it('should not add a member group on invalid input', (() => {
component.memberGroupName = '';
component.addMemberGroup();
expect(component.memberGroups.length).toEqual(1);
}));
it('should not add an existing member group', (() => {
component.memberGroupName = 'testgroup';
component.addMemberGroup();
component.addMemberGroup();
expect(component.memberGroups.length).toEqual(2);
}));
});
describe('#removeMemberGroup', () => {
it('should remove an existing member group', (() => {
component.removeMemberGroup('Default');
expect(component.memberGroups.length).toEqual(0);
}));
it('should not remove a not existing member group', (() => {
component.removeMemberGroup('notexisting');
expect(component.memberGroups.length).toEqual(1);
}));
});
});
......@@ -61,7 +61,7 @@ export class MemberGroupManagerComponent implements OnDestroy {
}
public addMemberGroup(): void {
if (this.memberGroups.indexOf(this.memberGroupName) > -1 || !this.memberGroupName.length) {
if (!this.memberGroupName.length || this.memberGroups.find(group => group === this.memberGroupName)) {
return;
}
......@@ -70,7 +70,11 @@ export class MemberGroupManagerComponent implements OnDestroy {
}
public removeMemberGroup(groupName: string): void {
this.memberGroups.splice(this.memberGroups.indexOf(groupName), 1);
if (!this.memberGroups.find(group => group === groupName)) {
return;
}
this.memberGroups.splice(this.memberGroups.findIndex(group => group === groupName), 1);
}
}
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { HttpClient } from '@angular/common/http';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { IAvailableNicks } from 'arsnova-click-v2-types/src/common';
......@@ -23,7 +23,9 @@ export class NicknameManagerComponent implements OnInit, OnDestroy {
set availableNicks(value: IAvailableNicks) {
this._availableNicks = value;
this._availableNicks.emojis = this._availableNicks.emojis.map(nick => this.sanitizeHTML(parseGithubFlavoredMarkdown(nick)));
if (this._availableNicks.emojis) {
this._availableNicks.emojis = this._availableNicks.emojis.map(nick => this.sanitizeHTML(parseGithubFlavoredMarkdown(nick)));
}
this._availableNicksBackup = Object.assign({}, value);
}
......@@ -52,7 +54,7 @@ export class NicknameManagerComponent implements OnInit, OnDestroy {
}
public filterForKeyword(event: Event): void {
const searchValue = (<HTMLInputElement>event.target).value;
const searchValue = (<HTMLInputElement>event.target).value.toString().toLowerCase();
if (searchValue.length < this._previousSearchValue.length) {
this._availableNicks = Object.assign({}, this._availableNicksBackup);
......@@ -64,8 +66,8 @@ export class NicknameManagerComponent implements OnInit, OnDestroy {
return;
}
Object.keys(this._availableNicks).forEach(category => {
this._availableNicks[category] = this._availableNicks[category].filter(baseNick => {
Object.keys(this.availableNicks).forEach(category => {
this.availableNicks[category] = this.availableNicks[category].filter(baseNick => {
return baseNick.toString().toLowerCase().indexOf(searchValue) > -1;
});
});
......@@ -75,12 +77,8 @@ export class NicknameManagerComponent implements OnInit, OnDestroy {
return this.sanitizer.bypassSecurityTrustHtml(`${value}`);
}
public parseAvailableNick(name: string): SafeHtml {
return name;
}
public availableNickCategories(): Array<string> {
return Object.keys(this._availableNicks || {});
return Object.keys(this.availableNicks || {});
}
public toggleSelectedCategory(name: string): void {
......@@ -88,62 +86,70 @@ export class NicknameManagerComponent implements OnInit, OnDestroy {
return;
}
this._selectedCategory = this._selectedCategory === name ? '' : name;
this._selectedCategory = this.selectedCategory === name ? '' : name;
}
public selectNick(name: any): void {
if (this._selectedCategory === 'emojis') {
if (this.selectedCategory === 'emojis') {
name = name.changingThisBreaksApplicationSecurity.match(/:[\w\+\-]+:/g)[0];
}
this.activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.toggleSelectedNick(name.toString());
}
public hasSelectedNick(name: any): boolean {
if (this._selectedCategory === 'emojis') {
if (this.selectedCategory === 'emojis') {
name = name.changingThisBreaksApplicationSecurity.match(/:[\w\+\-]+:/g)[0];
}
return this.activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.hasSelectedNick(name.toString());
}
public hasSelectedCategory(category?: string): boolean {
return category ? category === this._selectedCategory : !!this._selectedCategory;
return category ? category === this.selectedCategory : !!this.selectedCategory;
}
public hasSelectedAllNicks(): boolean {
const selectedNicks = this.activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.selectedNicks;
const filteredNicksLength = this._availableNicks[this._selectedCategory].filter(elem => {
if (this._selectedCategory === 'emojis') {
const filteredNicksLength = this.availableNicks[this.selectedCategory].filter(elem => {
if (this.selectedCategory === 'emojis') {
const emojiMatch = elem.changingThisBreaksApplicationSecurity.match(/:[\w\+\-]+:/g);
return selectedNicks.indexOf(emojiMatch ? emojiMatch[0] : null) > -1;
} else {
return selectedNicks.indexOf(elem) > -1;
}
}).length;
return filteredNicksLength === this._availableNicks[this._selectedCategory].length;
return filteredNicksLength === this.availableNicks[this.selectedCategory].length;
}
public getNumberOfSelectedNicksOfCategory(category: string): number {
if (!this.availableNicks[category]) {
return 0;
}
const selectedNicks = this.activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.selectedNicks;
return this._availableNicks[category].filter(elem => {
return this.availableNicks[category].filter(elem => {
return selectedNicks.indexOf(elem) > -1;
}).length;
}
public getNumberOfAvailableNicksForCategory(category: string): number {
return this._availableNicks[category].length;
if (!this.availableNicks[category]) {
return 0;
}
return this.availableNicks[category].length;
}
public toggleAllNicks(): void {
if (this.hasSelectedAllNicks()) {
this._availableNicks[this._selectedCategory].forEach(elem => {
if (this._selectedCategory === 'emojis') {
this.availableNicks[this.selectedCategory].forEach(elem => {
if (this.selectedCategory === 'emojis') {
elem = elem.changingThisBreaksApplicationSecurity.match(/:[\w\+\-]+:/g)[0];
}
this.activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.removeSelectedNickByName(elem.toString());
});
} else {
this._availableNicks[this._selectedCategory].forEach(elem => {
if (this._selectedCategory === 'emojis') {
this.availableNicks[this.selectedCategory].forEach(elem => {
if (this.selectedCategory === 'emojis') {
elem = elem.changingThisBreaksApplicationSecurity.match(/:[\w\+\-]+:/g)[0];
}
this.activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.addSelectedNick(elem.toString());
......@@ -152,11 +158,8 @@ export class NicknameManagerComponent implements OnInit, OnDestroy {
}
public ngOnInit(): void {
const headers = new HttpHeaders();
headers.append('Content-Type', 'multipart/form-data');
headers.append('Accept', 'application/json');
this.http.get(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`, { headers }).subscribe(
(data: IAvailableNicks) => {
this.http.get<IAvailableNicks>(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).subscribe(
data => {
this.availableNicks = data;
},
error => {
......
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateCompiler, TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { DefaultAnswerOption } from 'arsnova-click-v2-types/src/answeroptions/answeroption_default';
import { IQuestionSurvey } from 'arsnova-click-v2-types/src/questions/interfaces';
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
import { createTranslateLoader } from '../../../../../../lib/translation.factory';
import { HeaderComponent } from '../../../../../header/header/header.component';
......@@ -24,7 +26,7 @@ import { WebsocketService } from '../../../../../service/websocket/websocket.ser
import { AnsweroptionsDefaultComponent } from './answeroptions-default.component';
class MockRouter {
class MockRouterSC {
public params = {
subscribe: (cb) => {
cb({
......@@ -34,55 +36,141 @@ class MockRouter {
};
}
class MockRouterSurvey {
public params = {
subscribe: (cb) => {
cb({
questionIndex: 3,
});
},
};
}
const imports = [
RouterTestingModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient],
},
compiler: {
provide: TranslateCompiler,
useClass: TranslateMessageFormatCompiler,
},
}),
NgbModalModule.forRoot(),
];
const providers: Array<any> = [
{ provide: ActiveQuestionGroupService, useClass: ActiveQuestionGroupMockService },
FooterBarService,
SettingsService,
{ provide: ConnectionService, useClass: ConnectionMockService },
{ provide: WebsocketService, useClass: WebsocketMockService },
SharedService,
HeaderLabelService,
QuestionTextService,
{ provide: TrackingService, useClass: TrackingMockService },
];
const declarations = [
HeaderComponent,
LivePreviewComponent,
AnsweroptionsDefaultComponent,
];
describe('AnsweroptionsDefaultComponent', () => {
let component: AnsweroptionsDefaultComponent;
let fixture: ComponentFixture<AnsweroptionsDefaultComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient],
},
compiler: {
provide: TranslateCompiler,
useClass: TranslateMessageFormatCompiler,
},
}),
NgbModalModule.forRoot(),
],
providers: [
{ provide: ActiveQuestionGroupService, useClass: ActiveQuestionGroupMockService },
FooterBarService,
SettingsService,
{ provide: ConnectionService, useClass: ConnectionMockService },
{ provide: WebsocketService, useClass: WebsocketMockService },
SharedService,
HeaderLabelService,
QuestionTextService,
{ provide: ActivatedRoute, useClass: MockRouter },
{ provide: TrackingService, useClass: TrackingMockService },
],
declarations: [
HeaderComponent,
LivePreviewComponent,
AnsweroptionsDefaultComponent,
],
}).compileComponents();
}));
beforeEach(async(() => {
fixture = TestBed.createComponent(AnsweroptionsDefaultComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should be created', async(() => {
expect(component).toBeTruthy();
}));
describe('SingleChoiceQuestion', () => {
let component: AnsweroptionsDefaultComponent;
let fixture: ComponentFixture<AnsweroptionsDefaultComponent>;
beforeEach((() => {
providers.push({ provide: ActivatedRoute, useClass: MockRouterSC });
TestBed.configureTestingModule({ imports, providers, declarations }).compileComponents();
}));
beforeEach((() => {
fixture = TestBed.createComponent(AnsweroptionsDefaultComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should be created', (() => {
expect(component).toBeTruthy();
}));
it('should contain a TYPE reference', (() => {
expect(AnsweroptionsDefaultComponent.TYPE).toEqual('AnsweroptionsDefaultComponent');
}));
describe('#addAnswer', () => {
it('should add an answer', () => {
component.addAnswer();
expect(component.question.answerOptionList.length).toEqual(1);
expect(component.question.answerOptionList[0].TYPE).toEqual('DefaultAnswerOption');
});
});
describe('#deleteAnswer', () => {
it('should delete an answer', () => {
component.deleteAnswer(0);
expect(component.question.answerOptionList.length).toEqual(0);
});
});
describe('#updateAnswerValue', () => {
it('should update the answertext', () => {
const value = 'newValue';
const event = <any>{ target: { value } };
component.addAnswer();
component.updateAnswerValue(event, 0);
expect(component.question.answerOptionList[0].answerText).toEqual(value);
});
});
describe('#toggleShowOneAnswerPerRow', () => {
it('should toggle the showOneAnswerPerRow option of the question', () => {
const initValue = component.question.showOneAnswerPerRow;
component.toggleShowOneAnswerPerRow();
expect(component.question.showOneAnswerPerRow).not.toEqual(initValue);
});
});
describe('#toggleShowAnswerContentOnButtons', () => {
it('should toggle the displayAnswerText option of the question', () => {
const initValue = component.question.displayAnswerText;
component.toggleShowAnswerContentOnButtons();
expect(component.question.displayAnswerText).not.toEqual(initValue);
});
});
});
describe('SurveyQuestion', () => {
let component: AnsweroptionsDefaultComponent;
let fixture: ComponentFixture<AnsweroptionsDefaultComponent>;
beforeEach((() => {
providers.push({ provide: ActivatedRoute, useClass: MockRouterSurvey });
TestBed.configureTestingModule({ imports, providers, declarations }).compileComponents();
}));
beforeEach((() => {
fixture = TestBed.createComponent(AnsweroptionsDefaultComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
describe('#toggleMultipleSelectionSurvey', () => {
it('should toggle the multipleSelectionEnabled option of a survey question', () => {
const initValue = (<IQuestionSurvey>component.question).multipleSelectionEnabled;
component.toggleMultipleSelectionSurvey();
expect((<IQuestionSurvey>component.question).multipleSelectionEnabled).not.toEqual(initValue);
});
});
});
});
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { TranslateCompiler, TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { IFreetextAnswerOption } from 'arsnova-click-v2-types/src/answeroptions/interfaces';
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
import { createTranslateLoader } from '../../../../../../lib/translation.factory';
import { ActiveQuestionGroupMockService } from '../../../../../service/active-question-group/active-question-group.mock.service';
......@@ -32,7 +33,7 @@ describe('AnsweroptionsFreetextComponent', () => {
let component: AnsweroptionsFreetextComponent;
let fixture: ComponentFixture<AnsweroptionsFreetextComponent>;
beforeEach(async(() => {
beforeEach((() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
......@@ -63,13 +64,81 @@ describe('AnsweroptionsFreetextComponent', () => {
}).compileComponents();
}));
beforeEach(async(() => {
beforeEach((() => {
fixture = TestBed.createComponent(AnsweroptionsFreetextComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should be created', async(() => {
it('should be created', (() => {
expect(component).toBeTruthy();
}));
it('should contain a TYPE reference', (() => {
expect(AnsweroptionsFreetextComponent.TYPE).toEqual('AnsweroptionsFreetextComponent');
}));
describe('#setTestInput', () => {
it('should add a test input', () => {
const value = 'Testinputvalue';
const event = <any>{ target: { value } };
component.setTestInput(event);
expect(component.testInput).toEqual(value);
});
});
describe('#setMatchText', () => {
it('should add a match text to the answer text', () => {
const value = 'Testinputvalue';
const event = <any>{ target: { value } };
component.setMatchText(event);
expect(component.question.answerOptionList[0].answerText).toEqual(value);
});
});
describe('#hasTestInput', () => {
it('should return true if a testinput has been set', () => {
const value = 'Testinputvalue';
const event = <any>{ target: { value } };
component.setTestInput(event);
expect(component.hasTestInput()).toBeTruthy();
});
it('should return false if no testinput has been set', () => {
const value = '';
const event = <any>{ target: { value } };
component.setTestInput(event);
expect(component.hasTestInput()).toBeFalsy();
});
});
describe('#isTestInputCorrect', () => {
it('should return true if the testinput matches the answer text', () => {
const value = 'Testvalue';
const event = <any>{ target: { value } };
component.setTestInput(event);
component.setMatchText(event);
expect(component.isTestInputCorrect()).toBeTruthy();
});
it('should return false if the testinput does not match the answer text', () => {
const testinput = <any>{ target: { value: 'Testinputvalue' } };
const testmatch = <any>{ target: { value: 'Testmatchvalue' } };
component.setTestInput(testinput);
component.setMatchText(testmatch);
expect(component.isTestInputCorrect()).toBeFalsy();
});
});
describe('#setConfig', () => {
it('should set a validation configuration of the question', () => {
const initValue = (<IFreetextAnswerOption>component.question.answerOptionList[0]).getConfig()[0];
component.setConfig(initValue.id, !initValue.enabled);
const newValue = (<IFreetextAnswerOption>component.question.answerOptionList[0]).getConfig()[0];
expect(newValue.id).toEqual(initValue.id);
expect(newValue.enabled).not.toEqual(initValue.enabled);
});
it('should throw an error if an invalid config is set', () => {
expect(() => component.setConfig('NotExisting', true)).toThrowError('Config not found');
});
});
});
......@@ -33,9 +33,14 @@ export class AnsweroptionsFreetextComponent implements OnInit, OnDestroy {
return this._answer;
}
private _testInput = '';
get testInput(): string {
return this._testInput;
}
private _questionIndex: number;
private _routerSubscription: Subscription;
private _testInput = '';
constructor(
private headerLabelService: HeaderLabelService,
......
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { TranslateCompiler, TranslateLoader, TranslateModule } from '@ngx-translate/core';
......@@ -22,7 +22,7 @@ class MockRouter {
public params = {
subscribe: (cb) => {
cb({
questionIndex: 0,
questionIndex: 2,
});
},
};
......@@ -32,7 +32,7 @@ describe('AnsweroptionsRangedComponent', () => {
let component: AnsweroptionsRangedComponent;
let fixture: ComponentFixture<AnsweroptionsRangedComponent>;
beforeEach(async(() => {
beforeEach((() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
......@@ -63,13 +63,62 @@ describe('AnsweroptionsRangedComponent', () => {
}).compileComponents();
}));
beforeEach(async(() => {
beforeEach((() => {
fixture = TestBed.createComponent(AnsweroptionsRangedComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should be created', async(() => {
it('should be created', (() => {
expect(component).toBeTruthy();
}));
it('should contain a TYPE reference', (() => {
expect(AnsweroptionsRangedComponent.TYPE).toEqual('AnsweroptionsRangedComponent');