Add Service-HTTP test beginning; add template form test for blog
parent
263fff1036
commit
30cc500000
|
@ -54,4 +54,4 @@
|
|||
"change_settings": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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', () => {
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
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', () => {
|
||||
|
||||
|
@ -45,3 +49,39 @@ describe('Blog Component Isolated Test', () => {
|
|||
}).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);
|
||||
})
|
||||
|
||||
});
|
||||
|
|
|
@ -61,7 +61,7 @@ describe('Model Driven Form', () => {
|
|||
|
||||
// helper method
|
||||
// check for error object according to given input value
|
||||
function expectErrorOnInput(formControl, inputString, expectedErrorObject?, expectedErrorAttribute?) {
|
||||
let expectErrorOnInput = (formControl, inputString, expectedErrorObject?, expectedErrorAttribute?) => {
|
||||
formControl.setValue(inputString);
|
||||
if (expectedErrorObject && expectedErrorAttribute) {
|
||||
expect(formControl.errors[expectedErrorAttribute]).toEqual(expectedErrorObject);
|
||||
|
|
|
@ -19,8 +19,6 @@ export class LoginService {
|
|||
|
||||
users$: Observable<User[]>;
|
||||
|
||||
results$: User[];
|
||||
|
||||
constructor(@Optional() @Inject(AUTH_ENABLED) public authEnabled = false, private http: Http, private userStore: UserStore,
|
||||
@Inject(SOCKET_IO) socketIO) {
|
||||
this.users$ = userStore.items$;
|
||||
|
@ -28,13 +26,15 @@ export class LoginService {
|
|||
}
|
||||
|
||||
getUser(name: string): User[] {
|
||||
this.http.get(BASE_URL + "?name=" + name).subscribe(result => this.results$ = result.json());
|
||||
return this.results$;
|
||||
let results;
|
||||
this.http.get(BASE_URL + "?name=" + name).subscribe(result => results = result.json());
|
||||
return results;
|
||||
}
|
||||
|
||||
login(name, password) {
|
||||
if (this.getUser(name)) {
|
||||
let user = this.results$[0];
|
||||
let results = this.getUser(name);
|
||||
if (results) {
|
||||
let user = results[0];
|
||||
let passMd5 = Md5.hashStr(password);
|
||||
if (user && user.password === passMd5) {
|
||||
localStorage.setItem(CURRENT_USER, JSON.stringify(user));
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
|
@ -1,8 +1,38 @@
|
|||
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
|
||||
import {User} from '../../models/model-interfaces';
|
||||
import {ADD, EDIT, LOAD, REMOVE} from "./generic-store";
|
||||
|
||||
export class UserStore {
|
||||
|
||||
private users: 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}));
|
||||
|
||||
});
|
|
@ -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('');
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
});
|
Loading…
Reference in New Issue