Add Service-HTTP test beginning; add template form test for blog

merge-requests/1/head
Florian Hartwich 2017-04-07 05:52:13 +02:00
parent 263fff1036
commit 30cc500000
9 changed files with 319 additions and 9 deletions

View File

@ -58,7 +58,7 @@ describe('Blog Entry Isolated Test', () => {
}); });
describe('BlogEntryComp -> BlogComp Relational Test', () => { describe('BlogEntryComp -> BlogComp Dependent Test', () => {
it('should remove entry from BlogComponent on "delete" button click', () => { it('should remove entry from BlogComponent on "delete" button click', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({

View File

@ -1,4 +1,8 @@
import {BlogComponent} from './blog.component' import {BlogComponent} from './blog.component'
import {TestBed} from "@angular/core/testing";
import {RouterTestingModule} from "@angular/router/testing";
import {BlogEntryComponent} from "./blog-entry/blog-entry.component";
import {BlogEntry} from "./blog-entry/blog-entry";
describe('Blog Component Isolated Test', () => { describe('Blog Component Isolated Test', () => {
@ -45,3 +49,39 @@ describe('Blog Component Isolated Test', () => {
}).not.toBe(latestId); }).not.toBe(latestId);
}); });
}); });
describe('Blog Component Integration Form Test', () => {
let fixture;
let instance;
let element;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([])],
declarations: [BlogEntryComponent, BlogComponent]
});
fixture = TestBed.createComponent(BlogComponent);
instance = fixture.componentInstance;
element = fixture.nativeElement;
});
it('should call create method with provided field input', () => {
const spy = spyOn(instance, 'createBlogEntry');
const testTitle = 'testTitle';
const testImage = 'imageUrl';
const testText = 'testText';
// beachten : value würde immer funktionieren um Werte als Variable
// übertragbar einzutragen, textContent hingegen nur bei textarea
element.querySelector('div /deep/ div > #title').value = testTitle;
element.querySelector('div /deep/ div > #image').value = testImage;
element.querySelector('div /deep/ div > #text').textContent = testText;
element.querySelector('div /deep/ div > button').click();
expect(spy).toHaveBeenCalledWith(testTitle, testImage, testText);
})
});

View File

@ -61,7 +61,7 @@ describe('Model Driven Form', () => {
// helper method // helper method
// check for error object according to given input value // check for error object according to given input value
function expectErrorOnInput(formControl, inputString, expectedErrorObject?, expectedErrorAttribute?) { let expectErrorOnInput = (formControl, inputString, expectedErrorObject?, expectedErrorAttribute?) => {
formControl.setValue(inputString); formControl.setValue(inputString);
if (expectedErrorObject && expectedErrorAttribute) { if (expectedErrorObject && expectedErrorAttribute) {
expect(formControl.errors[expectedErrorAttribute]).toEqual(expectedErrorObject); expect(formControl.errors[expectedErrorAttribute]).toEqual(expectedErrorObject);

View File

@ -19,8 +19,6 @@ export class LoginService {
users$: Observable<User[]>; users$: Observable<User[]>;
results$: User[];
constructor(@Optional() @Inject(AUTH_ENABLED) public authEnabled = false, private http: Http, private userStore: UserStore, constructor(@Optional() @Inject(AUTH_ENABLED) public authEnabled = false, private http: Http, private userStore: UserStore,
@Inject(SOCKET_IO) socketIO) { @Inject(SOCKET_IO) socketIO) {
this.users$ = userStore.items$; this.users$ = userStore.items$;
@ -28,13 +26,15 @@ export class LoginService {
} }
getUser(name: string): User[] { getUser(name: string): User[] {
this.http.get(BASE_URL + "?name=" + name).subscribe(result => this.results$ = result.json()); let results;
return this.results$; this.http.get(BASE_URL + "?name=" + name).subscribe(result => results = result.json());
return results;
} }
login(name, password) { login(name, password) {
if (this.getUser(name)) { let results = this.getUser(name);
let user = this.results$[0]; if (results) {
let user = results[0];
let passMd5 = Md5.hashStr(password); let passMd5 = Md5.hashStr(password);
if (user && user.password === passMd5) { if (user && user.password === passMd5) {
localStorage.setItem(CURRENT_USER, JSON.stringify(user)); localStorage.setItem(CURRENT_USER, JSON.stringify(user));

View File

@ -0,0 +1,50 @@
import {MockBackend} from "@angular/http/testing";
import {inject, TestBed} from "@angular/core/testing";
import {mockIO} from "../../mocks/mock-socket";
import {SOCKET_IO} from "../../app.tokens";
import {BaseRequestOptions, ConnectionBackend, Http, RequestMethod, ResponseOptions} from "@angular/http";
import {LoginService} from "./login-service";
import {UserStore} from "../stores/user.store";
describe('Login-Service', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
LoginService,
UserStore,
{provide: SOCKET_IO, useValue: mockIO},
BaseRequestOptions,
MockBackend,
{
provide: Http, useFactory: (mockBackend: ConnectionBackend,
defaultOptions: BaseRequestOptions) => {
return new Http(mockBackend, defaultOptions);
}, deps: [MockBackend, BaseRequestOptions]
},
]
});
});
let loginService: LoginService;
let userStore: UserStore;
let mockBackend: MockBackend;
beforeEach(inject([LoginService, UserStore, MockBackend],
(_loginService, _userStore, _mockBackend) => {
loginService = _loginService;
userStore = _userStore;
mockBackend = _mockBackend;
})
);
it('should trigger a HTTP-GET and receive Task', (() => {
console.log(userStore.items$);
mockBackend.connections.subscribe(connection => {
const expectedUrl = 'http://localhost:3000/api/users/';
expect(connection.request.url).toBe(expectedUrl);
expect(connection.request.method).toBe(RequestMethod.Get);
});
}));
});

View File

@ -1,8 +1,38 @@
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {User} from '../../models/model-interfaces'; import {User} from '../../models/model-interfaces';
import {ADD, EDIT, LOAD, REMOVE} from "./generic-store";
export class UserStore { export class UserStore {
private users: User[] = [];
items$ = new BehaviorSubject<User[]>([]); items$ = new BehaviorSubject<User[]>([]);
dispatch(action) {
console.log("dispatched")
this.users = this._reduce(this.users, action);
this.items$.next(this.users);
}
_reduce(tasks: User[], action) {
switch (action.type) {
case LOAD:
return [...action.data];
case ADD:
return [...tasks, action.data];
case EDIT:
return tasks.map(task => {
const editedTask = action.data;
if (task.id !== editedTask.id) {
return task;
}
return editedTask;
});
case REMOVE:
return tasks.filter(task => task.id !== action.data.id);
default:
return tasks;
}
}
} }

View File

@ -0,0 +1,90 @@
import {TestBed, inject, fakeAsync} from '@angular/core/testing';
import { BaseRequestOptions, Http, ConnectionBackend, Response, ResponseOptions, RequestMethod } from '@angular/http';
import {TaskService} from './task.service';
import {MockBackend} from '@angular/http/testing';
import {TaskStore} from '../stores/task.store';
import {SOCKET_IO} from '../../app.tokens';
import {mockIO} from '../../mocks/mock-socket';
describe('Task-Service', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
TaskService,
TaskStore,
{provide: SOCKET_IO, useValue: mockIO},
BaseRequestOptions,
MockBackend,
{provide: Http, useFactory: (mockBackend: ConnectionBackend,
defaultOptions: BaseRequestOptions) => {
return new Http(mockBackend, defaultOptions);
}, deps: [MockBackend, BaseRequestOptions]},
]
});
});
let taskService: TaskService;
let taskStore: TaskStore;
let mockBackend: MockBackend;
beforeEach(inject([TaskService, TaskStore, MockBackend],
(_taskService, _taskStore, _mockBackend) => {
taskService = _taskService;
taskStore = _taskStore;
mockBackend = _mockBackend;
})
);
const saveTask = (task, expectedUrl = null, expectedMethod = null) => {
mockBackend.connections.subscribe(connection => {
if (expectedUrl) {
expect(connection.request.url).toBe(expectedUrl);
}
if (expectedMethod) {
expect(connection.request.method).toBe(expectedMethod);
}
const response = new ResponseOptions({body: JSON.stringify(task)});
connection.mockRespond(new Response(response));
});
taskService.saveTask(task).subscribe();
};
it('should trigger a HTTP-POST for new Tasks', (() => {
const task = {title: 'Task 1'};
mockBackend.connections.subscribe(connection => {
const expectedUrl = 'http://localhost:3000/api/tasks/';
expect(connection.request.url).toBe(expectedUrl);
expect(connection.request.method).toBe(RequestMethod.Post);
const response = new ResponseOptions({body: JSON.stringify(task)});
connection.mockRespond(new Response(response));
});
taskService.saveTask(task).subscribe();
}));
it('should trigger a HTTP-POST for new Tasks', (() => {
const task = {title: 'Task 1'};
saveTask(task, 'http://localhost:3000/api/tasks/', RequestMethod.Post);
}));
it('should do a HTTP-Put for existing Tasks', (() => {
const task = {id: 1, title: 'Existing Task'};
saveTask(task, 'http://localhost:3000/api/tasks/1', RequestMethod.Put);
}));
it('should add the Task to the store', (() => {
const spy = spyOn(taskStore, 'dispatch').and.callThrough();
saveTask({title: 'Task 1'});
const dispatchedAction = spy.calls.mostRecent().args[0];
expect(dispatchedAction.type).toEqual('ADD');
expect(dispatchedAction.data.title).toEqual('Task 1');
}));
it('should save the Task in store', (() => {
const spy = spyOn(taskStore, 'dispatch').and.callThrough();
saveTask({id: 1, title: 'Task 1'});
const dispatchedAction = spy.calls.mostRecent().args[0];
expect(dispatchedAction.type).toEqual('EDIT');
expect(dispatchedAction.data.title).toEqual('Task 1');
}));
});

View File

@ -0,0 +1,100 @@
import {TaskService} from '../../services/task-service/task.service';
import {RouterTestingModule} from '@angular/router/testing';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {TestBed, inject} from '@angular/core/testing';
import {EditTaskComponent} from './edit-task.component';
import {ShowErrorComponent} from '../../show-error/show-error.component';
import {APPLICATION_VALIDATORS} from '../../models/app-validators';
import {ActivatedRoute, Router} from '@angular/router';
import {fakeAsync, tick} from '@angular/core/testing';
import {Title} from '@angular/platform-browser';
import {Component} from '@angular/core';
import {ReactiveFormsModule, FormsModule} from '@angular/forms';
import {MockTaskService} from '../../mocks/mock-task-service';
@Component({
template: '<router-outlet></router-outlet>'
})
class TestComponent {
}
describe('EditTask Component', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [FormsModule, RouterTestingModule.withRoutes([
{path: 'new', component: EditTaskComponent},
{path: 'edit/:id', component: EditTaskComponent}
],
)],
declarations: [EditTaskComponent, ShowErrorComponent, APPLICATION_VALIDATORS, TestComponent],
providers: [
Title,
{provide: TaskService, useClass: MockTaskService},
]
});
});
let taskService: TaskService;
beforeEach(inject([TaskService], (_taskService) => {
taskService = _taskService;
}));
it('should load the correct task in Edit-Mode', fakeAsync(() => {
const fixture = TestBed.createComponent(EditTaskComponent);
const route = TestBed.get(ActivatedRoute);
(<any>route.params).next({id: '42'});
const element = fixture.nativeElement;
const spy = spyOn(taskService, 'getTask');
const fakeTask = {title: 'Task1', assignee: {name: 'John'}};
spy.and.returnValue(new BehaviorSubject(fakeTask));
fixture.autoDetectChanges(true);
fixture.whenStable().then(() => {
tick();
expect(spy).toHaveBeenCalledWith('42');
const titleInput = element.querySelector('#title');
expect(titleInput.value).toBe(fakeTask.title);
const assigneeInput = element.querySelector('#assignee_name');
expect(assigneeInput.value).toBe(fakeTask.assignee.name);
});
}));
it('should load the correct task (with router)', fakeAsync(() => {
const fixture = TestBed.createComponent(TestComponent);
const router = TestBed.get(Router);
router.navigateByUrl('edit/42');
const spy = spyOn(taskService, 'getTask');
const fakeTask = {title: 'Task1', assignee: {name: 'John'}};
spy.and.returnValue(new BehaviorSubject(fakeTask));
fixture.whenStable().then(() => {
tick();
expect(spy).toHaveBeenCalledWith('42');
const titleInput = fixture.nativeElement.querySelector('#title');
expect(titleInput.value).toBe(fakeTask.title);
});
}));
it('should work without passing URL-Parameter', fakeAsync(() => {
const fixture = TestBed.createComponent(TestComponent);
const router = TestBed.get(Router);
router.navigateByUrl('new');
const spy = spyOn(taskService, 'getTask');
fixture.whenStable().then(() => {
tick();
expect(spy).not.toHaveBeenCalled();
const titleInput = fixture.nativeElement.querySelector('#title');
expect(titleInput.value).toBe('');
});
}));
});