Skip to content

Commit 085a0d5

Browse files
author
Guilherme Andrade Pinto
committed
Creating components tests
1 parent fdc367d commit 085a0d5

28 files changed

+300
-66
lines changed

angular.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@
106106
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
107107
"src/styles.scss"
108108
],
109+
"stylePreprocessorOptions": {
110+
"includePaths": [
111+
"src/assets/styles"
112+
]
113+
},
109114
"scripts": []
110115
}
111116
},

ngsw-config.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,19 @@
2525
]
2626
}
2727
}
28+
],
29+
"dataGroups": [
30+
{
31+
"name": "api-tech-crunch-rss-reader",
32+
"urls": [
33+
"http://0.0.0.0:4000/api/posts"
34+
],
35+
"cacheConfig": {
36+
"strategy": "freshness",
37+
"timeout": "6s",
38+
"maxSize": 100,
39+
"maxAge": "1h"
40+
}
41+
}
2842
]
2943
}

src/app/app.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<mat-toolbar color="primary">
22
<mat-toolbar-row>
3-
<span>TechCrunch</span>
3+
<span class="toolbar-title">TechCrunch</span>
44
</mat-toolbar-row>
55
</mat-toolbar>
66
<main class="main-container">

src/app/app.component.spec.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { TestBed, async } from '@angular/core/testing';
22
import { RouterTestingModule } from '@angular/router/testing';
33
import { AppComponent } from './app.component';
4+
import { MatToolbarModule } from '@angular/material';
45

56
describe('AppComponent', () => {
67
beforeEach(async(() => {
78
TestBed.configureTestingModule({
89
imports: [
9-
RouterTestingModule
10+
RouterTestingModule,
11+
MatToolbarModule
1012
],
1113
declarations: [
1214
AppComponent
@@ -20,16 +22,10 @@ describe('AppComponent', () => {
2022
expect(app).toBeTruthy();
2123
});
2224

23-
it(`should have as title 'tech-crunch-rss-reader'`, () => {
24-
const fixture = TestBed.createComponent(AppComponent);
25-
const app = fixture.debugElement.componentInstance;
26-
expect(app.title).toEqual('tech-crunch-rss-reader');
27-
});
28-
29-
it('should render title', () => {
25+
it('should render title in toolbar', () => {
3026
const fixture = TestBed.createComponent(AppComponent);
3127
fixture.detectChanges();
3228
const compiled = fixture.debugElement.nativeElement;
33-
expect(compiled.querySelector('.content span').textContent).toContain('tech-crunch-rss-reader app is running!');
29+
expect(compiled.querySelector('.toolbar-title').textContent).toContain('TechCrunch');
3430
});
3531
});

src/app/app.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Component, OnInit } from '@angular/core';
55
styleUrls: ['./app.component.scss']
66
})
77
export class AppComponent {
8-
title = 'tech-crunch-rss-reader';
98

109
constructor() {}
1110

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div class="close-full-post-content">
2-
<mat-icon (click)="close()">close</mat-icon>
2+
<mat-icon (click)="close()" class="close">close</mat-icon>
33
</div>
44

5-
<app-post-card [showDescription]="showDescription" [post]="post"></app-post-card>
5+
<app-post-card [showDescription]="false" [post]="post"></app-post-card>
66

7-
<span [innerHTML]="post.encondedContent | sanitizeHtml"></span>
7+
<span class="encodedContent" [innerHTML]="post.encodedContent | sanitizeHtml"></span>
Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,59 @@
11
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
22

33
import { FullPostContentComponent } from './full-post-content.component';
4+
import Util from '../util-post-spec';
5+
import { Component } from '@angular/core';
6+
import { MatIcon } from '@angular/material';
7+
import { PostCardComponent } from '../post-card/post-card.component';
8+
import { SanitizeHtmlPipe } from '../../shared/pipes/sanitize-html.pipe';
49

510
describe('FullPostContentComponent', () => {
611
let component: FullPostContentComponent;
712
let fixture: ComponentFixture<FullPostContentComponent>;
813

14+
const setup = () => {
15+
const post = Util.createPost();
16+
component.post = post;
17+
fixture.detectChanges();
18+
const compile = fixture.debugElement.nativeElement;
19+
20+
return { post, compile};
21+
};
22+
923
beforeEach(async(() => {
1024
TestBed.configureTestingModule({
11-
declarations: [ FullPostContentComponent ]
25+
declarations: [ MatIcon, PostCardComponent, SanitizeHtmlPipe, FullPostContentComponent ]
1226
})
1327
.compileComponents();
1428
}));
1529

1630
beforeEach(() => {
1731
fixture = TestBed.createComponent(FullPostContentComponent);
1832
component = fixture.componentInstance;
19-
fixture.detectChanges();
2033
});
2134

2235
it('should create', () => {
36+
setup();
2337
expect(component).toBeTruthy();
2438
});
39+
40+
it(`should not render the post description`, () => {
41+
const { post, compile} = setup();
42+
43+
expect(compile.querySelector('.post-card-content')).toBeNull();
44+
});
45+
46+
it(`should render the enconded content`, () => {
47+
const { post, compile} = setup();
48+
49+
expect(compile.querySelector('.encodedContent').textContent).toContain(post.encodedContent);
50+
});
51+
52+
it('should trigger fullPostContentClosed event emmiter when click on close', () => {
53+
spyOn(component.fullPostContentClosed, 'emit');
54+
55+
component.close();
56+
57+
expect(component.fullPostContentClosed.emit).toHaveBeenCalled();
58+
});
2559
});

src/app/posts/full-post-content/full-post-content.component.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
2-
import { Post } from '../../shared/models/post';
2+
import { Post } from '../models/post';
33

44
@Component({
55
selector: 'app-full-post-content',
@@ -11,9 +11,6 @@ export class FullPostContentComponent {
1111
@Input()
1212
post: Post;
1313

14-
@Input()
15-
showDescription: true;
16-
1714
@Output()
1815
fullPostContentClosed: EventEmitter<Post> = new EventEmitter();
1916

src/app/posts/models/post.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Post } from './post';
2+
3+
const createPost = ({
4+
title = 'Post card component',
5+
link = '',
6+
creator = 'Guilherme Andrade',
7+
pubDate = new Date(),
8+
description = 'description',
9+
encodedContent = '<p>Component Tests</p>',
10+
categories = ['Component Tests']
11+
} = {}) => {
12+
return new Post(title, link, creator, pubDate, description, encodedContent, categories);
13+
};
14+
15+
describe('Post', () => {
16+
it('should create an instance', () => {
17+
expect(createPost.call(this)).toBeTruthy();
18+
});
19+
});

src/app/shared/models/post.ts renamed to src/app/posts/models/post.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export class Post {
44
creator: string;
55
pubDate: Date;
66
description: string;
7-
encondedContent: string;
7+
encodedContent: string;
88
categories: string[];
99

1010
constructor(
@@ -13,7 +13,7 @@ export class Post {
1313
creator: string,
1414
pubDate: Date,
1515
description: string,
16-
encondedContent: string,
16+
encodedContent: string,
1717
categories: string[]
1818
) {
1919
this.title = title;
Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,61 @@
1-
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
1+
import { async, ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing';
22

33
import { PostCardListHeaderComponent } from './post-card-list-header.component';
4+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
5+
import { MatAutocompleteModule, MatInputModule, MatFormFieldModule, MatAutocompleteSelectedEvent, MatOption } from '@angular/material';
6+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
47

58
describe('PostCardListHeaderComponent', () => {
69
let component: PostCardListHeaderComponent;
710
let fixture: ComponentFixture<PostCardListHeaderComponent>;
811

912
beforeEach(async(() => {
1013
TestBed.configureTestingModule({
11-
declarations: [ PostCardListHeaderComponent ]
14+
declarations: [PostCardListHeaderComponent],
15+
imports: [
16+
FormsModule,
17+
ReactiveFormsModule,
18+
MatAutocompleteModule,
19+
MatFormFieldModule,
20+
MatInputModule,
21+
BrowserAnimationsModule
22+
]
1223
})
13-
.compileComponents();
24+
.compileComponents();
1425
}));
1526

1627
beforeEach(() => {
1728
fixture = TestBed.createComponent(PostCardListHeaderComponent);
1829
component = fixture.componentInstance;
30+
component.categories = ['Music', 'Technology'];
1931
fixture.detectChanges();
2032
});
2133

2234
it('should create', () => {
2335
expect(component).toBeTruthy();
2436
});
37+
38+
it(`should emit 'selectedCategory' when 'onPanelClosing' is called`, () => {
39+
40+
spyOn(component.selectedCategory, 'emit');
41+
42+
component.onPanelClosing();
43+
44+
expect(component.selectedCategory.emit).toHaveBeenCalled();
45+
});
46+
47+
it(`should emit 'selectedCategory' when 'onPanelClosing' is called`, () => {
48+
49+
spyOn(component.selectedCategory, 'emit');
50+
const option: any = {
51+
value: 'mock_value'
52+
};
53+
const event: MatAutocompleteSelectedEvent = new MatAutocompleteSelectedEvent(
54+
null,
55+
option
56+
);
57+
component.onSelectOption(event);
58+
59+
expect(component.selectedCategory.emit).toHaveBeenCalled();
60+
});
2561
});

src/app/posts/post-card-list/post-card-list.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
<ul class="post-card-list">
55
<li *ngFor="let post of filteredPosts">
6-
<app-post-card [post]="post" [showDescription]="true" (click)="selectPost(post)"></app-post-card>
6+
<app-post-card
7+
[post]="post"
8+
[showDescription]="true"
9+
(click)="selectPost(post)">
10+
</app-post-card>
711
</li>
812
</ul>
913
</section>
Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,89 @@
11
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
22

33
import { PostCardListComponent } from './post-card-list.component';
4+
import Util from '../util-post-spec';
5+
import { PostCardListHeaderComponent } from '../post-card-list-header/post-card-list-header.component';
6+
import { PostCardComponent } from '../post-card/post-card.component';
7+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
8+
import { MatAutocompleteModule, MatFormField, MatFormFieldModule, MatInputModule } from '@angular/material';
9+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
10+
import { By } from '@angular/platform-browser';
411

512
describe('PostCardListComponent', () => {
613
let component: PostCardListComponent;
714
let fixture: ComponentFixture<PostCardListComponent>;
815

16+
const setup = () => {
17+
const posts = [{ title: 'First Post', categories: ['Music'] }, { title: 'Music', categories: ['Technology'] }]
18+
.map(postData => Util.createPost(postData));
19+
component.posts = posts;
20+
fixture.detectChanges();
21+
22+
return posts;
23+
};
24+
925
beforeEach(async(() => {
1026
TestBed.configureTestingModule({
11-
declarations: [ PostCardListComponent ]
27+
declarations: [PostCardListHeaderComponent, PostCardComponent, PostCardListComponent],
28+
imports: [FormsModule, ReactiveFormsModule, MatAutocompleteModule, MatFormFieldModule, MatInputModule, BrowserAnimationsModule]
1229
})
13-
.compileComponents();
30+
.compileComponents();
1431
}));
1532

1633
beforeEach(() => {
1734
fixture = TestBed.createComponent(PostCardListComponent);
1835
component = fixture.componentInstance;
19-
fixture.detectChanges();
2036
});
2137

2238
it('should create', () => {
39+
setup();
2340
expect(component).toBeTruthy();
2441
});
42+
43+
it(`should initialize 'filteredPosts' and 'categories'`, () => {
44+
const posts = setup();
45+
46+
expect(component.filteredPosts).toEqual(posts);
47+
expect(component.categories).toEqual( ['Music', 'Technology'] );
48+
});
49+
50+
it(`should render the posts`, () => {
51+
const posts = setup();
52+
const debugElement = fixture.debugElement.queryAll(By.css('.post-card'));
53+
54+
expect(debugElement.length).toEqual(2);
55+
});
56+
57+
it(`should emit 'postCardSelected' when 'selectPost' is called`, () => {
58+
const posts = setup();
59+
60+
spyOn(component.postCardSelected, 'emit');
61+
62+
component.selectPost(posts[1]);
63+
64+
expect(component.postCardSelected.emit).toHaveBeenCalled();
65+
});
66+
67+
it(`should emit 'postCardListFiltered' when 'onSelectCategory' is called`, () => {
68+
const posts = setup();
69+
70+
spyOn(component.postCardListFiltered, 'emit');
71+
72+
component.onSelectCategory('Technology');
73+
74+
expect(component.postCardListFiltered.emit).toHaveBeenCalled();
75+
});
76+
77+
it(`should filter posts`, () => {
78+
const posts = setup();
79+
80+
spyOn(component.postCardListFiltered, 'emit');
81+
82+
component.onSelectCategory('Technology');
83+
84+
fixture.detectChanges();
85+
86+
const debugElement = fixture.debugElement.queryAll(By.css('.post-card'));
87+
expect(debugElement.length).toEqual(1);
88+
});
2589
});

src/app/posts/post-card-list/post-card-list.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
2-
import { Post } from '../../shared/models/post';
2+
import { Post } from '../models/post';
33

44
@Component({
55
selector: 'app-post-card-list',

0 commit comments

Comments
 (0)