Skip to content

Commit 04b0846

Browse files
committed
feat(todos): create tests for todos container
1 parent 936741b commit 04b0846

File tree

2 files changed

+127
-4
lines changed

2 files changed

+127
-4
lines changed

src/app/examples/todos/todos.component.spec.ts

Lines changed: 115 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,76 @@
1-
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
1+
import {
2+
async,
3+
ComponentFixture,
4+
TestBed,
5+
fakeAsync,
6+
tick
7+
} from '@angular/core/testing';
28
import { RouterTestingModule } from '@angular/router/testing';
39

410
import { CoreModule } from '@app/core';
511
import { SharedModule } from '@app/shared';
612

7-
import { ExamplesModule } from '../examples.module';
8-
913
import { TodosComponent } from './todos.component';
14+
import { Store, StoreModule } from '@ngrx/store';
15+
16+
import {
17+
todosReducer,
18+
ActionTodosAdd,
19+
ActionTodosToggle,
20+
ActionTodosFilter
21+
} from './todos.reducer';
22+
23+
import { By } from '@angular/platform-browser';
24+
25+
import { resetStateTestMetaReducer } from '@app/../test-utils';
26+
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
1027

1128
describe('TodosComponent', () => {
1229
let component: TodosComponent;
1330
let fixture: ComponentFixture<TodosComponent>;
31+
const getTodos = () => fixture.debugElement.queryAll(By.css('.todo'));
32+
const deleteDoneTodosBtn = () =>
33+
fixture.debugElement.query(
34+
By.css('anms-big-input-action[icon="delete_forever"] > button')
35+
);
36+
const addTodoBtn = () =>
37+
fixture.debugElement.query(
38+
By.css('anms-big-input-action[icon="add"] > button')
39+
);
1440

41+
const setTodosFromArray = function(
42+
names: string[],
43+
toggleTheLastOne: boolean
44+
) {
45+
const store = fixture.debugElement.injector.get(Store);
46+
names.forEach(name => store.dispatch(new ActionTodosAdd({ name })));
47+
if (toggleTheLastOne) {
48+
store.dispatch(
49+
new ActionTodosToggle({
50+
id: component.todos.items.find(
51+
todo => todo.name === names[names.length - 1]
52+
).id
53+
})
54+
);
55+
}
56+
return store;
57+
};
1558
beforeEach(
1659
async(() => {
1760
TestBed.configureTestingModule({
18-
imports: [RouterTestingModule, CoreModule, SharedModule, ExamplesModule]
61+
declarations: [TodosComponent],
62+
imports: [
63+
NoopAnimationsModule,
64+
RouterTestingModule,
65+
CoreModule,
66+
SharedModule,
67+
StoreModule.forFeature('examples', {
68+
todos: resetStateTestMetaReducer({ items: [], filter: 'ALL' })(
69+
todosReducer
70+
)
71+
})
72+
],
73+
providers: []
1974
}).compileComponents();
2075
})
2176
);
@@ -29,4 +84,60 @@ describe('TodosComponent', () => {
2984
it('should be created', () => {
3085
expect(component).toBeTruthy();
3186
});
87+
88+
it('should display todos', () => {
89+
expect(component.todos.items.length).toBe(0);
90+
expect(getTodos().length).toBe(0);
91+
});
92+
93+
it('when some sate contains some todos - component must show them', () => {
94+
expect(component.todos.items.length).toBe(0);
95+
96+
setTodosFromArray(['SOME TODO', 'SOME OTHER TODO'], false);
97+
98+
fixture.detectChanges();
99+
expect(getTodos().length).toBe(2);
100+
});
101+
102+
it('should show only "DONE" todos after setting filter to "DONE"', () => {
103+
const store = setTodosFromArray(['SOME TODO', 'SOME OTHER TODO'], true);
104+
105+
store.dispatch(new ActionTodosFilter({ filter: 'DONE' }));
106+
107+
fixture.detectChanges();
108+
expect(getTodos().length).toBe(1);
109+
expect(
110+
getTodos()[0].nativeElement.querySelector('.todo-label').innerHTML
111+
).toContain('SOME OTHER TODO');
112+
});
113+
114+
it('should remove "DONE" todos when clicking "Remove Done Todos" button', () => {
115+
setTodosFromArray(['SOME TODO', 'SOME OTHER TODO', 'ONE MORE TODO'], true);
116+
deleteDoneTodosBtn().triggerEventHandler('click', {});
117+
fixture.detectChanges();
118+
expect(getTodos().length).toBe(2);
119+
const existingTodos = getTodos()
120+
.map(elem =>
121+
elem.nativeElement.querySelector('.todo-label').textContent.trim()
122+
)
123+
.join(',');
124+
component.todos.items.forEach(item => {
125+
expect(existingTodos).toContain(item.name);
126+
});
127+
});
128+
129+
it(
130+
'should add new todo when input has some text and "Add Todo" button clicked',
131+
fakeAsync(() => {
132+
expect(component.todos.items.length).toBe(0);
133+
134+
component.newTodo = 'NEW TODO';
135+
136+
addTodoBtn().triggerEventHandler('click', {});
137+
fixture.detectChanges();
138+
tick(2500);
139+
expect(getTodos().length).toBe(1);
140+
expect(component.todos.items[0].name).toContain('NEW TODO');
141+
})
142+
);
32143
});

src/test-utils/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { ROOT_EFFECTS_INIT as INIT } from '@ngrx/effects';
2+
3+
export function resetStateTestMetaReducer(resetTestState) {
4+
return function(reducer) {
5+
return function(state, action) {
6+
if (action.type === INIT) {
7+
state = resetTestState;
8+
}
9+
return reducer(state, action);
10+
};
11+
};
12+
}

0 commit comments

Comments
 (0)