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, HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { DomSanitizer } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
import { TranslateCompiler, TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
import { DefaultSettings } from '../../../../lib/default.settings';
import { createTranslateLoader } from '../../../../lib/translation.factory';
import { ActiveQuestionGroupMockService } from '../../../service/active-question-group/active-question-group.mock.service';
import { ActiveQuestionGroupService } from '../../../service/active-question-group/active-question-group.service';
......@@ -19,12 +22,39 @@ import { NicknameManagerComponent } from './nickname-manager.component';
describe('NicknameManagerComponent', () => {
let component: NicknameManagerComponent;
let fixture: ComponentFixture<NicknameManagerComponent>;
let backend: HttpTestingController;
const nicknames = {
disney: [
'Donald Duck',
'Daisy Duck',
'Tarzan',
'Simba',
'Elsa',
'Anna',
'Kuzco',
'Arielle',
'Jasmin',
'Mulan',
'Pluto',
'Nemo',
'Buzz Lightyear',
'Woody',
'Lightning McQueen',
'Tinkerbell',
'Peter Pan',
'Cinderella',
'Dagobert Duck',
'Goofy',
],
};
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
HttpClientModule,
HttpClientTestingModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
......@@ -53,9 +83,208 @@ describe('NicknameManagerComponent', () => {
fixture = TestBed.createComponent(NicknameManagerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
backend = TestBed.get(HttpTestingController);
}));
beforeEach(inject(
[ActiveQuestionGroupService], (activeQuestionGroupService: ActiveQuestionGroupService) => {
activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.selectedNicks.splice(
0, activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.selectedNicks.length,
);
}));
afterEach(() => {
backend.verify();
});
it('should be created', async(() => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush([]);
expect(component).toBeTruthy();
}));
it('should contain a TYPE reference', async(() => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush([]);
expect(NicknameManagerComponent.TYPE).toEqual('NicknameManagerComponent');
}));
describe('filterForKeyword', () => {
afterEach(() => {
const removeFilterEvent = <any>{ target: { value: '' } };
component.filterForKeyword(removeFilterEvent);
});
it('should filter the nicknames for a given keyword', () => {
const value = 'Tarzan';
const event = <any>{ target: { value } };
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(Object.assign({}, nicknames));
component.filterForKeyword(event);
expect(component.availableNicks.disney.length).toEqual(1);
expect(component.availableNicks.disney[0]).toEqual(value);
});
});
describe('#sanitizeHTML', () => {
it('should sanitize the html input',
inject([DomSanitizer], (sanitizer: DomSanitizer) => {
const markup = '<div><span>TestMarkup</span></div>';
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
spyOn(sanitizer, 'bypassSecurityTrustHtml').and.callFake(() => {});
component.sanitizeHTML(markup);
expect(sanitizer.bypassSecurityTrustHtml).toHaveBeenCalled();
}));
});
describe('#availableNickCategories', () => {
it('should list all available categories', () => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
const categories = component.availableNickCategories();
expect(categories).toEqual(jasmine.arrayWithExactContents(['disney']));
});
});
describe('#toggleSelectedCategory', () => {
it('should set a given category as active', () => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
component.toggleSelectedCategory('disney');
expect(component.selectedCategory).toEqual('disney');
});
it('should not set an invalid category as active', () => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
component.toggleSelectedCategory('notexisting');
expect(component.selectedCategory).toEqual('');
});
});
describe('#selectNick', () => {
it('should select a given nickname', inject(
[ActiveQuestionGroupService], (activeQuestionGroupService: ActiveQuestionGroupService) => {
const nick = 'Tarzan';
spyOn(activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks, 'toggleSelectedNick').and.callThrough();
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
component.selectNick(nick);
expect(activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.toggleSelectedNick).toHaveBeenCalled();
}));
});
describe('#hasSelectedNick', () => {
it('should return true if a given nickname has been selected', () => {
const nick = 'Tarzan';
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
component.selectNick(nick);
const result = component.hasSelectedNick(nick);
expect(result).toBeTruthy();
});
it('should return false if nickname which is not selected has been given', () => {
const nick = 'NotExsting';
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
const result = component.hasSelectedNick(nick);
expect(result).toBeFalsy();
});
});
describe('#hasSelectedCategory', () => {
it('should return true if a given category has been selected', () => {
const category = 'disney';
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
component.toggleSelectedCategory(category);
const result = component.hasSelectedCategory(category);
expect(result).toBeTruthy();
});
it('should return false if a category which is not selected has been given', () => {
const category = 'NotExisting';
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
const result = component.hasSelectedCategory(category);
expect(result).toBeFalsy();
});
});
describe('#hasSelectedAllNicks', () => {
it('should return true if all nicks of a category have been selected', () => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
spyOnProperty(component, 'selectedCategory').and.returnValue('disney');
component.availableNicks.disney.forEach(nick => component.selectNick(nick));
expect(component.hasSelectedAllNicks()).toBeTruthy();
});
it('should return false if not all nicks of a category have been selected', inject(
[ActiveQuestionGroupService], (activeQuestionGroupService: ActiveQuestionGroupService) => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
spyOnProperty(component, 'selectedCategory').and.returnValue('disney');
expect(component.availableNicks.disney).toEqual(jasmine.arrayWithExactContents(nicknames.disney));
component.selectNick(component.availableNicks.disney[0]);
expect(component.hasSelectedAllNicks()).toBeFalsy();
}));
});
describe('#getNumberOfSelectedNicksOfCategory', () => {
it('should return the number of selected nicks of a given category', () => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
component.selectNick(component.availableNicks.disney[0]);
expect(component.getNumberOfSelectedNicksOfCategory('disney')).toEqual(1);
expect(component.getNumberOfSelectedNicksOfCategory('notSelected')).toEqual(0);
});
});
describe('#getNumberOfAvailableNicksForCategory', () => {
it('should return the number of available nicks for a given category', () => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
expect(component.getNumberOfAvailableNicksForCategory('disney')).toEqual(nicknames.disney.length);
expect(component.getNumberOfAvailableNicksForCategory('notSelected')).toEqual(0);
});
});
describe('#toggleAllNicks', () => {
it('should select all nicks of a given category if not all nicks are selected', inject(
[ActiveQuestionGroupService], (activeQuestionGroupService: ActiveQuestionGroupService) => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
spyOn(component, 'hasSelectedAllNicks').and.callFake(() => false);
spyOnProperty(component, 'selectedCategory').and.returnValue('disney');
component.toggleAllNicks();
const selectedNicksLength = activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.selectedNicks.length;
expect(selectedNicksLength).toEqual(nicknames.disney.length);
}));
it('should deselect all nicks of a given category if all nicks have been selected', inject(
[ActiveQuestionGroupService], (activeQuestionGroupService: ActiveQuestionGroupService) => {
backend.expectOne(`${DefaultSettings.httpApiEndpoint}/nicks/predefined`).flush(nicknames);
spyOn(component, 'hasSelectedAllNicks').and.callFake(() => true);
spyOnProperty(component, 'selectedCategory').and.returnValue('disney');
component.toggleAllNicks();
const selectedNicksLength = activeQuestionGroupService.activeQuestionGroup.sessionConfig.nicks.selectedNicks.length;
expect(selectedNicksLength).toEqual(0);
}));
});
});
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((() => {