diff --git a/project-manager/src/app/blog/blog-entry/blog-entry.component.spec.ts b/project-manager/src/app/blog/blog-entry/blog-entry.component.spec.ts index 42a4743..c669a2a 100644 --- a/project-manager/src/app/blog/blog-entry/blog-entry.component.spec.ts +++ b/project-manager/src/app/blog/blog-entry/blog-entry.component.spec.ts @@ -6,79 +6,84 @@ import {RouterTestingModule} from "@angular/router/testing"; describe('Blog Entry Isolated Test', () => { - it('should render DOM correctly according to Input', () => { - // Umgebung initialisieren - TestBed.configureTestingModule({ - declarations: [BlogEntryComponent] + describe('Isolated Test', () => { + it('should render DOM correctly according to Input', () => { + // Umgebung initialisieren + TestBed.configureTestingModule({ + declarations: [BlogEntryComponent] + }); + const fixture = TestBed.createComponent(BlogEntryComponent); + const blogEntryComponent: BlogEntryComponent = fixture.componentInstance; + const element = fixture.nativeElement; + const blogEntry: BlogEntry = new BlogEntry; + + // Testdaten + const testId = 101; + const testTitle = "test title"; + const testText = "test text"; + const testImage = "https://www.google.de/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"; + + // Input-Daten + blogEntry.id = testId; + blogEntry.title = testTitle; + blogEntry.text = testText; + blogEntry.image = testImage; + blogEntry.createdAt = new Date(); + ( blogEntryComponent).entry = blogEntry; + + // DOM update + fixture.detectChanges(); + + // DOM auslesen und Daten abgleichen + const imageSrc = element.querySelector('div /deep/ .blog-image > img').getAttribute("src"); + expect(imageSrc).toBe(testImage); + + // textContent statt innerHtml + // siehe http://stackoverflow.com/questions/40227533/angular-2-and-jasmine-unit-testing-cannot-get-the-innerhtml + const blogTitle = element.querySelector('div /deep/ .blog-summary > span').textContent; + expect(blogTitle).toBe(testTitle); + + const blogText = element.querySelector('div /deep/ .blog-summary > p').textContent; + expect(blogText).toBe(testText); + + const blogTs = element.querySelector('div /deep/ .blog-timestamp > .timestamp').textContent; + expect(new Date(blogTs).getDate()).toBe(new Date().getDate()); + + const blogDelete = element.querySelector('div /deep/ .blog-delete > button').textContent; + expect(blogDelete).toBe("Entfernen") + + // keine Überprüfung der id, die lediglich im EventListener des Delete Button hinterlegt ist, möglich! + // nur durch click-Event auslösen, was jedoch BlogComponent vorraussetzt + }); - const fixture = TestBed.createComponent(BlogEntryComponent); - const blogEntryComponent: BlogEntryComponent = fixture.componentInstance; - const element = fixture.nativeElement; - const blogEntry: BlogEntry = new BlogEntry; + }); - // Testdaten - const testId = 101; - const testTitle = "test title"; - const testText = "test text"; - const testImage = "https://www.google.de/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"; - // Input-Daten - blogEntry.id = testId; - blogEntry.title = testTitle; - blogEntry.text = testText; - blogEntry.image = testImage; - blogEntry.createdAt = new Date(); - ( blogEntryComponent).entry = blogEntry; + describe('BlogEntryComp -> BlogComp Dependent Test', () => { - // DOM update - fixture.detectChanges(); + it('should remove entry from BlogComponent on "delete" button click', () => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule.withRoutes([])], + declarations: [BlogEntryComponent, BlogComponent] + }); - // DOM auslesen und Daten abgleichen - const imageSrc = element.querySelector('div /deep/ .blog-image > img').getAttribute("src"); - expect(imageSrc).toBe(testImage); + const entryFixture = TestBed.createComponent(BlogEntryComponent); + const entryInstance: BlogEntryComponent = entryFixture.componentInstance; - // textContent statt innerHtml - // siehe http://stackoverflow.com/questions/40227533/angular-2-and-jasmine-unit-testing-cannot-get-the-innerhtml - const blogTitle = element.querySelector('div /deep/ .blog-summary > span').textContent; - expect(blogTitle).toBe(testTitle); + const blogFixture = TestBed.createComponent(BlogComponent); + const blogInstance: BlogComponent = blogFixture.componentInstance; - const blogText = element.querySelector('div /deep/ .blog-summary > p').textContent; - expect(blogText).toBe(testText); + const blogEntry: BlogEntry = blogInstance.entries[0]; + entryInstance.entry = blogEntry; + entryInstance.blogComponent = blogInstance; - const blogTs = element.querySelector('div /deep/ .blog-timestamp > .timestamp').textContent; - expect(new Date(blogTs).getDate()).toBe(new Date().getDate()); - - const blogDelete = element.querySelector('div /deep/ .blog-delete > button').textContent; - expect(blogDelete).toBe("Entfernen") - - // keine Überprüfung der id, die lediglich im EventListener des Delete Button hinterlegt ist, möglich! - // nur durch click-Event auslösen, was jedoch BlogComponent vorraussetzt + const oldLength = blogInstance.entries.length; + entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click(); + expect(blogInstance.entries.length).toBe(oldLength - 1); + }); }); }); -describe('BlogEntryComp -> BlogComp Dependent Test', () => { - it('should remove entry from BlogComponent on "delete" button click', () => { - TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], - declarations: [BlogEntryComponent, BlogComponent] - }); - - const entryFixture = TestBed.createComponent(BlogEntryComponent); - const entryInstance: BlogEntryComponent = entryFixture.componentInstance; - - const blogFixture = TestBed.createComponent(BlogComponent); - const blogInstance: BlogComponent = blogFixture.componentInstance; - - const blogEntry: BlogEntry = blogInstance.entries[0]; - entryInstance.entry = blogEntry; - entryInstance.blogComponent = blogInstance; - - const oldLength = blogInstance.entries.length; - entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click(); - expect(blogInstance.entries.length).toBe(oldLength - 1); - }); - -}); diff --git a/project-manager/src/app/blog/blog.component.spec.ts b/project-manager/src/app/blog/blog.component.spec.ts index fba66a7..e2b995e 100644 --- a/project-manager/src/app/blog/blog.component.spec.ts +++ b/project-manager/src/app/blog/blog.component.spec.ts @@ -2,86 +2,88 @@ 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', () => { - let blogComponent: BlogComponent; + describe('Isolated Class Test', () => { + let blogComponent: BlogComponent; - beforeEach(() => { - blogComponent = new BlogComponent(null, null, null); - }); - - it('should have initial entries', () => { - expect(blogComponent.entries.length).toBe(2); - blogComponent.entries.forEach((entry) => { - expect(entry.id).toBeLessThanOrEqual(blogComponent.id); - expect(entry.createdAt.getDate()).toBe(new Date().getDate()); - }) - }); - - it('should create new list entry and increment id', () => { - let preCreationId = blogComponent.id; - let entryTitle = "some fancy title"; - let entryImage = "https://avatars1.githubusercontent.com/u/3284117"; - let entryText = "some important text"; - blogComponent.createBlogEntry(entryTitle, entryImage, entryText); - - let newEntry = blogComponent.entries[blogComponent.entries.length - 1]; - expect(newEntry.id - 1).toBe(preCreationId); - expect(newEntry.image).toBe(entryImage); - expect(newEntry.text).toBe(entryText); - expect(newEntry.createdAt.getDate()).toBe(new Date().getDate()); - }); - - it('should delete entry by given id - and not change global max-id', () => { - let preDeletionId = blogComponent.id; - let latestId = blogComponent.entries[blogComponent.entries.length - 1].id; - blogComponent.deleteBlogEntry(latestId); - - expect(blogComponent.id).toBe(preDeletionId); - expect(() => { - if (blogComponent.entries.length > 0) { - return blogComponent.entries[blogComponent.entries.length - 1]; - } else { - return 0; - } - }).not.toBe(latestId); - }); -}); - - -describe('Blog Component Integration Form Test', () => { - - let fixture; - let instance; - let element; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], - declarations: [BlogEntryComponent, BlogComponent] + beforeEach(() => { + blogComponent = new BlogComponent(null, null, null); }); - fixture = TestBed.createComponent(BlogComponent); - instance = fixture.componentInstance; - element = fixture.nativeElement; - }); - it('should call create method with provided field input', () => { - const spy = spyOn(instance, 'createBlogEntry'); + it('should have initial entries', () => { + expect(blogComponent.entries.length).toBe(2); + blogComponent.entries.forEach((entry) => { + expect(entry.id).toBeLessThanOrEqual(blogComponent.id); + expect(entry.createdAt.getDate()).toBe(new Date().getDate()); + }) + }); - const testTitle = 'testTitle'; - const testImage = 'imageUrl'; - const testText = 'testText'; + it('should create new list entry and increment id-pointer', () => { + let preCreationId = blogComponent.id; + let entryTitle = "some fancy title"; + let entryImage = "https://avatars1.githubusercontent.com/u/3284117"; + let entryText = "some important text"; + blogComponent.createBlogEntry(entryTitle, entryImage, entryText); - // 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(); + let newEntry = blogComponent.entries[blogComponent.entries.length - 1]; + expect(newEntry.id - 1).toBe(preCreationId); + expect(newEntry.image).toBe(entryImage); + expect(newEntry.text).toBe(entryText); + expect(newEntry.createdAt.getDate()).toBe(new Date().getDate()); + }); - expect(spy).toHaveBeenCalledWith(testTitle, testImage, testText); - }) + it('should delete entry by given id - and not change global max-id', () => { + let preDeletionId = blogComponent.id; + let latestId = blogComponent.entries[blogComponent.entries.length - 1].id; + blogComponent.deleteBlogEntry(latestId); + + expect(blogComponent.id).toBe(preDeletionId); + expect(() => { + if (blogComponent.entries.length > 0) { + return blogComponent.entries[blogComponent.entries.length - 1]; + } else { + return 0; + } + }).not.toBe(latestId); + }); + }); + + + describe('Template Driven Form Integration 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); + }) + + }); }); diff --git a/project-manager/src/app/services/login-service/login-service.ts b/project-manager/src/app/services/login-service/login-service.ts index 378d60d..48075f2 100644 --- a/project-manager/src/app/services/login-service/login-service.ts +++ b/project-manager/src/app/services/login-service/login-service.ts @@ -32,6 +32,7 @@ export class LoginService { return this.results$; } + // Nur als theoretische Umsetzung - in Realität findet die PW-Validierung serverseitig statt login(name, password) : boolean { if (this.getUser(name)) { let user = this.results$[0]; diff --git a/project-manager/src/app/services/login-service/login.service.spec.ts b/project-manager/src/app/services/login-service/login.service.spec.ts index c82ac2b..a52af17 100644 --- a/project-manager/src/app/services/login-service/login.service.spec.ts +++ b/project-manager/src/app/services/login-service/login.service.spec.ts @@ -38,7 +38,7 @@ describe('Login-Service', () => { }) ); - it('should trigger a HTTP-GET and receive Task', (() => { + it('should trigger a HTTP-GET and receive Users', (() => { mockBackend.connections.subscribe(connection => { const expectedUrl = 'http://localhost:3000/api/users/'; expect(connection.request.url).toBe(expectedUrl); diff --git a/project-manager/src/app/services/stores/user.store.ts b/project-manager/src/app/services/stores/user.store.ts index cb8edce..60a92ed 100644 --- a/project-manager/src/app/services/stores/user.store.ts +++ b/project-manager/src/app/services/stores/user.store.ts @@ -13,24 +13,24 @@ export class UserStore { this.items$.next(this.users); } - _reduce(tasks: User[], action) { + _reduce(users: User[], action) { switch (action.type) { case LOAD: return [...action.data]; case ADD: - return [...tasks, action.data]; + return [...users, action.data]; case EDIT: - return tasks.map(task => { - const editedTask = action.data; - if (task.id !== editedTask.id) { - return task; + return users.map(user => { + const editedUser = action.data; + if (user.id !== editedUser.id) { + return user; } - return editedTask; + return editedUser; }); case REMOVE: - return tasks.filter(task => task.id !== action.data.id); + return users.filter(task => task.id !== action.data.id); default: - return tasks; + return users; } } diff --git a/project-manager/src/app/tasks/edit-task/edit-task.component.spec.ts b/project-manager/src/app/tasks/edit-task/edit-task.component.spec.ts index 9753acf..da272b7 100644 --- a/project-manager/src/app/tasks/edit-task/edit-task.component.spec.ts +++ b/project-manager/src/app/tasks/edit-task/edit-task.component.spec.ts @@ -40,7 +40,7 @@ describe('EditTask Component', () => { }); - describe('Template Driven Form API-based Test', ()=>{ + describe('Template Driven Form API-based Test', () => { let fixture; @@ -51,7 +51,7 @@ describe('EditTask Component', () => { fixture.autoDetectChanges(true); }); - it('should validate the title correctly', (done)=> { + it('should validate the title correctly', (done) => { fixture.whenStable().then(() => { form = fixture.componentInstance.form.form; const titleControl = form.get('title'); @@ -103,7 +103,7 @@ describe('EditTask Component', () => { }); }); - it('should show error on tag name provided with gt 0 and lt 3', (done) => { + it('should validate assignee email correctly', (done) => { fixture.whenStable().then(() => { form = fixture.componentInstance.form.form; const invalidEmailObject = {invalidEMail: true}; @@ -127,7 +127,7 @@ describe('EditTask Component', () => { }); - describe('Routing', ()=>{ + describe('Routing', () => { let taskService: TaskService;