Commit e492a985b1737209a844fbacf06273429ba0e6e6

Authored by ABNER SILVA DE OLIVEIRA
1 parent f4c0320e

remodeled the navbar specs. added more helpers. added mock file

src/app/components/navbar/navbar.spec.ts
1 -import {  
2 -createComponentFromClass,  
3 -quickCreateComponent,  
4 -provideEmptyObjects  
5 -} from "./../../../spec/helpers";  
6 -import {  
7 -Navbar  
8 -} from "./navbar";  
9 -import {  
10 -AUTH_EVENTS  
11 -} from "./../auth";  
12 -import {  
13 -User  
14 -} from "./../../models/interfaces";  
15 -import {  
16 -Injectable,  
17 -Provider,  
18 -provide  
19 -} from "ng-forward"; 1 +import * as helpers from "./../../../spec/helpers";
  2 +import {Navbar} from "./navbar";
  3 +import {AUTH_EVENTS} from "./../auth";
  4 +import {User} from "./../../models/interfaces";
  5 +import {Injectable, Provider, provide} from "ng-forward";
  6 +
  7 +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
20 8
21 import {Session, AuthService, AuthController, IAuthEvents} from "./../auth"; 9 import {Session, AuthService, AuthController, IAuthEvents} from "./../auth";
22 10
  11 +
23 describe("Components", () => { 12 describe("Components", () => {
24 13
25 describe("Navbar Component", () => { 14 describe("Navbar Component", () => {
26 15
  16 + let user: User = null;
  17 + let scope: any;
27 let $rootScope: ng.IRootScopeService; 18 let $rootScope: ng.IRootScopeService;
28 19
29 - let user = <User>{  
30 - id: 1,  
31 - login: "user"  
32 - }; 20 + let modalInstance: any;
  21 + let $modal: any;
  22 + let authService: any;
  23 + let stateService: any;
  24 + let sessionService: any;
  25 +
  26 + let provideFunc = provide;
  27 +
  28 + // before Each -> loading mocks on locals variables
  29 + beforeEach(() => {
  30 + user = <User>{
  31 + id: 1,
  32 + login: "user"
  33 + };
  34 + scope = helpers.mocks.scopeWithEvents;
  35 + modalInstance = helpers.mocks.modalInstance;
  36 + $modal = helpers.mocks.$modal;
  37 + authService = helpers.mocks.authService;
  38 + stateService = jasmine.createSpyObj("$state", ["go"]);
  39 + sessionService = helpers.mocks.sessionWithCurrentUser(user);
  40 + });
33 41
34 - let scope = {  
35 - eventCalledHook: () => { },  
36 - $on: (eventName: string, func: Function) => {  
37 - this.eventCalledHook = func;  
38 - }  
39 - }  
40 42
41 - let modalInstance = {  
42 - close: () => { }  
43 - } 43 + // loading the templates
  44 + beforeEach(angular.mock.module("templates"));
44 45
45 - let $modal = {  
46 - open: (args: {}) => {  
47 - return modalInstance;  
48 - }  
49 - }  
50 46
51 - let authService = {  
52 - logout: () => { } 47 + // this function allow build the fixture of the container component
  48 + // and is reused in each test
  49 + // The main idea behing not prebuild it on a general beforeEach block is
  50 + // to allow tests configure the mock services accordilly their own needs
  51 + let buildComponent = (): Promise<ComponentFixture> => {
  52 + return helpers.quickCreateComponent({
  53 + providers: [
  54 + provide('$modal', {
  55 + useValue: $modal
  56 + }),
  57 + provide('AuthService', {
  58 + useValue: authService
  59 + }),
  60 + helpers.provideEmptyObjects('moment'),
  61 + provide('$state', {
  62 + useValue: stateService
  63 + }),
  64 + provide("$scope", {
  65 + useValue: scope
  66 + }),
  67 + provide('Session', {
  68 + useValue: sessionService
  69 + }),
  70 + provide('AUTH_EVENTS', {
  71 + useValue: {
  72 + AUTH_EVENTS
  73 + }
  74 + })
  75 + ],
  76 + directives: [Navbar],
  77 + template: '<acme-navbar></acme-navbar>'
  78 + });
53 } 79 }
54 80
55 - let stateService = jasmine.createSpyObj("$state", ["go"]);  
56 - let providers = [  
57 - new Provider('moment', { useValue: {} }),  
58 - new Provider('$modal', { useValue: $modal }),  
59 - new Provider('AuthService', { useValue: authService }),  
60 - new Provider('Session', {  
61 - useValue: {  
62 - currentUser: () => { return user }  
63 - }  
64 - }),  
65 - new Provider('$scope', { useValue: scope }),  
66 - new Provider('$state', { useValue: stateService }),  
67 - new Provider('AUTH_EVENTS', { useValue: { AUTH_EVENTS } })  
68 - ];  
69 -  
70 -  
71 - beforeEach(angular.mock.module("templates"));  
72 -  
73 - // beforeEach(inject((_$rootScope_: ng.IRootScopeService) => {  
74 - // $rootScope = _$rootScope_;  
75 - // }));  
76 81
77 it('should get the loggedIn user', (done: Function) => { 82 it('should get the loggedIn user', (done: Function) => {
78 -  
79 - let scope = jasmine.createSpyObj("scope", ["$on"]);  
80 - let providers = [  
81 - provideEmptyObjects('moment', '$modal', 'AuthService', '$state'),  
82 - new Provider('Session', {  
83 - useValue: {  
84 - currentUser: () => {  
85 - return user;  
86 - }  
87 - }  
88 - }),  
89 - new Provider('$scope', {  
90 - useValue: scope  
91 - }),  
92 - new Provider('AUTH_EVENTS', {  
93 - useValue: {  
94 - AUTH_EVENTS  
95 - }  
96 - })  
97 - ];  
98 -  
99 - quickCreateComponent({  
100 - providers: providers,  
101 - template: "<acme-navbar></acme-navbar>",  
102 - directives: [Navbar]  
103 - }).then(fixture => { 83 + buildComponent().then((fixture: ComponentFixture) => {
104 let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; 84 let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance;
105 expect(navbarInstance).toBeDefined(); 85 expect(navbarInstance).toBeDefined();
106 - expect(navbarInstance["currentUser"]).toEqual(user) 86 + expect(navbarInstance["currentUser"]).toEqual(user);
107 done(); 87 done();
108 }); 88 });
109 }); 89 });
110 90
111 it('should open on click', (done: Function) => { 91 it('should open on click', (done: Function) => {
112 -  
113 - quickCreateComponent({  
114 - providers: providers,  
115 - template: "<acme-navbar></acme-navbar>",  
116 - directives: [Navbar]  
117 - })  
118 - .then(fixture => {  
119 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
120 - spyOn($modal, "open");  
121 - navbarComp.openLogin();  
122 - expect($modal.open).toHaveBeenCalled();  
123 - expect($modal.open).toHaveBeenCalledWith({  
124 - templateUrl: 'app/components/auth/login.html',  
125 - controller: AuthController,  
126 - controllerAs: 'vm',  
127 - bindToController: true  
128 - });  
129 - done();  
130 - }) 92 + spyOn($modal, "open");
  93 + buildComponent().then((fixture: ComponentFixture) => {
  94 + let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
  95 + navbarComp.openLogin();
  96 + expect($modal.open).toHaveBeenCalled();
  97 + expect($modal.open).toHaveBeenCalledWith({
  98 + templateUrl: 'app/components/auth/login.html',
  99 + controller: AuthController,
  100 + controllerAs: 'vm',
  101 + bindToController: true
  102 + });
  103 + done();
  104 + });
131 }); 105 });
132 106
133 it('should logout', (done: Function) => { 107 it('should logout', (done: Function) => {
134 -  
135 - quickCreateComponent({  
136 - providers: providers,  
137 - template: "<acme-navbar></acme-navbar>",  
138 - directives: [Navbar]  
139 - })  
140 - .then(fixture => {  
141 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
142 - spyOn(authService, "logout"); 108 + buildComponent().then((fixture: ComponentFixture) => {
  109 + let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
  110 + spyOn(authService, "logout");
  111 + try {
143 navbarComp.logout(); 112 navbarComp.logout();
144 expect(authService.logout).toHaveBeenCalled(); 113 expect(authService.logout).toHaveBeenCalled();
145 done(); 114 done();
146 - }) 115 + } catch (e) {
  116 + console.error(e);
  117 + fail(e.message);
  118 + done();
  119 + }
  120 + });
147 }); 121 });
148 122
149 123
150 it('should not activate user when logged in', (done: Function) => { 124 it('should not activate user when logged in', (done: Function) => {
151 - quickCreateComponent({  
152 - providers: providers,  
153 - template: "<acme-navbar></acme-navbar>",  
154 - directives: [Navbar]  
155 - })  
156 - .then(fixture => {  
157 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
158 - spyOn(navbarComp, "openLogin");  
159 - navbarComp.activate();  
160 - expect((<any>navbarComp.openLogin).calls.count()).toBe(0);  
161 - done();  
162 - })  
163 - 125 + buildComponent().then((fixture: ComponentFixture) => {
  126 + let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
  127 + spyOn(navbarComp, "openLogin");
  128 + navbarComp.activate();
  129 + expect((<any>navbarComp.openLogin).calls.count()).toBe(0);
  130 + done();
  131 + });
164 }); 132 });
165 133
166 it('should activate when user not logged in', (done: Function) => { 134 it('should activate when user not logged in', (done: Function) => {
167 - user = null;  
168 - quickCreateComponent({  
169 - providers: providers,  
170 - template: "<acme-navbar></acme-navbar>",  
171 - directives: [Navbar]  
172 - })  
173 - .then(fixture => {  
174 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
175 - spyOn(navbarComp, "openLogin");  
176 - navbarComp.activate();  
177 - expect(navbarComp.openLogin).toHaveBeenCalled(); 135 + spyOn(sessionService, 'currentUser').and.returnValue(null);
  136 + buildComponent().then((fixture: ComponentFixture) => {
  137 + let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
  138 + spyOn(navbarComp, "openLogin");
  139 + navbarComp.activate();
  140 + expect(navbarComp.openLogin).toHaveBeenCalled();
  141 + done();
  142 + });
  143 + });
  144 +
  145 +
  146 + it('closes the modal after login', (done: Function) => {
  147 + modalInstance = jasmine.createSpyObj("modalInstance", ["close"]);
  148 + modalInstance.close = jasmine.createSpy("close");
  149 +
  150 + $modal.open = () => {
  151 + return modalInstance;
  152 + };
  153 +
  154 + buildComponent().then((fixture: ComponentFixture) => {
  155 + let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
  156 + let localScope: ng.IScope = navbarComp["$scope"];
  157 +
  158 +
  159 + navbarComp.openLogin();
  160 +
  161 + localScope.$on(AUTH_EVENTS.loginSuccess, () => {
  162 + expect(modalInstance.close).toHaveBeenCalled();
178 done(); 163 done();
179 - }) 164 + });
  165 +
  166 + localScope.$emit(AUTH_EVENTS.loginSuccess);
  167 + fixture.detectChanges();
  168 +
  169 +
  170 + });
180 }); 171 });
181 -  
182 -  
183 - // it('closes the modal the login', (done: Function) => {  
184 - // let scope = {  
185 - // eventCalledHook: () => { },  
186 - // $on: (eventName: string, func: Function) => {  
187 - // console.log("ON Called!");  
188 - // this.eventCalledHook = func;  
189 - // }  
190 - // }  
191 - //  
192 - // let modalInstance = {  
193 - // close: () => {  
194 - // console.log("CLOSE Called!");  
195 - // }  
196 - // }  
197 - //  
198 - // let $modal = {  
199 - // $open: (args: {}) => {  
200 - // return modalInstance;  
201 - // }  
202 - // }  
203 - //  
204 - // let stateService = jasmine.createSpyObj("$state", ["go"]);  
205 - // let providers = [  
206 - // new Provider('moment', { useValue: {} }),  
207 - // new Provider('$modal', { useValue: $modal }),  
208 - // new Provider('AuthService', { useValue: {} }),  
209 - // new Provider('Session', {  
210 - // useValue: {  
211 - // currentUser: () => { return user }  
212 - // }  
213 - // }),  
214 - // new Provider('$scope', { useValue: scope }),  
215 - // new Provider('$state', { useValue: stateService }),  
216 - // new Provider('AUTH_EVENTS', { useValue: { AUTH_EVENTS } })  
217 - // ];  
218 - // spyOn(modalInstance, "close");  
219 - //  
220 - // quickCreateComponent({  
221 - // providers: providers,  
222 - // template: "<acme-navbar></acme-navbar>",  
223 - // directives: [Navbar]  
224 - // })  
225 - // .then(fixture => {  
226 - // let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
227 - // navbarComp.activate();  
228 - // navbarComp.openLogin  
229 - //  
230 - // expect($modal.open).toHaveBeenCalledWith({})  
231 - // scope.eventCalledHook();  
232 - // expect(modalInstance.close).toHaveBeenCalled();  
233 - // done();  
234 - // })  
235 - // //done();  
236 - // }); 172 +
  173 +
237 }); 174 });
238 -}); 175 -});
  176 +});
239 \ No newline at end of file 177 \ No newline at end of file
src/app/components/navbar/navbar.ts
1 import {Component, Inject} from "ng-forward"; 1 import {Component, Inject} from "ng-forward";
2 2
3 3
4 -import {Session, AuthService, AuthController, IAuthEvents} from "./../auth"; 4 +import {Session, AuthService, AuthController, IAuthEvents, AUTH_EVENTS} from "./../auth";
5 import {User} from "./../../models/interfaces"; 5 import {User} from "./../../models/interfaces";
6 6
7 @Component({ 7 @Component({
8 selector: "acme-navbar", 8 selector: "acme-navbar",
9 - templateUrl: "app/components/navbar/navbar.html" 9 + templateUrl: "app/components/navbar/navbar.html",
  10 + providers: [AuthService, Session]
10 }) 11 })
11 -@Inject("moment", "$modal", "AuthService", "Session", "$scope", "$state", "AUTH_EVENTS") 12 +@Inject("$modal", AuthService, "Session", "$scope", "$state")
12 export class Navbar { 13 export class Navbar {
13 14
14 private currentUser: User; 15 private currentUser: User;
@@ -17,30 +18,26 @@ export class Navbar { @@ -17,30 +18,26 @@ export class Navbar {
17 * 18 *
18 */ 19 */
19 constructor( 20 constructor(
20 - private moment: moment.MomentStatic,  
21 private $modal: any, 21 private $modal: any,
22 private authService: AuthService, 22 private authService: AuthService,
23 private session: Session, 23 private session: Session,
24 private $scope: ng.IScope, 24 private $scope: ng.IScope,
25 - private $state: ng.ui.IStateService,  
26 - private AUTH_EVENTS: IAuthEvents 25 + private $state: ng.ui.IStateService
27 ) { 26 ) {
  27 + this.currentUser = this.session.currentUser();
28 28
29 - this.currentUser = session.currentUser();  
30 -  
31 - $scope.$on(AUTH_EVENTS.loginSuccess, () => { 29 + this.$scope.$on(AUTH_EVENTS.loginSuccess, () => {
32 if (this.modalInstance) { 30 if (this.modalInstance) {
33 this.modalInstance.close(); 31 this.modalInstance.close();
34 this.modalInstance = null; 32 this.modalInstance = null;
35 } 33 }
36 34
37 - this.$state.go(this.$state.current, {}, { reload: true }); //TODO move to auth 35 + this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth
38 }); 36 });
39 37
40 - $scope.$on(AUTH_EVENTS.logoutSuccess, () => { 38 + this.$scope.$on(AUTH_EVENTS.logoutSuccess, () => {
41 this.currentUser = this.session.currentUser(); 39 this.currentUser = this.session.currentUser();
42 }); 40 });
43 -  
44 } 41 }
45 42
46 openLogin() { 43 openLogin() {
@@ -54,7 +51,7 @@ export class Navbar { @@ -54,7 +51,7 @@ export class Navbar {
54 51
55 logout() { 52 logout() {
56 this.authService.logout(); 53 this.authService.logout();
57 - this.$state.go(this.$state.current, {}, { reload: true }); //TODO move to auth 54 + this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth
58 }; 55 };
59 56
60 57
src/app/components/noosfero-articles/blog/blog.component.spec.ts
@@ -15,7 +15,6 @@ import { @@ -15,7 +15,6 @@ import {
15 quickCreateComponent, 15 quickCreateComponent,
16 provideEmptyObjects, 16 provideEmptyObjects,
17 createProviderToValue, 17 createProviderToValue,
18 - getAngularService,  
19 provideFilters 18 provideFilters
20 } from "../../../../spec/helpers.ts"; 19 } from "../../../../spec/helpers.ts";
21 20
src/lib/ng-noosfero-api/http/profile.service.spec.ts
1 import {Profile} from "../../../app/models/interfaces"; 1 import {Profile} from "../../../app/models/interfaces";
2 import {ProfileService} from "./profile.service"; 2 import {ProfileService} from "./profile.service";
3 -import {getAngularService} from "../../../spec/helpers";  
4 3
5 describe("Services", () => { 4 describe("Services", () => {
6 5
src/spec/helpers.ts
1 1
2 import {ngClass, TestComponentBuilder, ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; 2 import {ngClass, TestComponentBuilder, ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
  3 +import {providers} from 'ng-forward/cjs/testing/providers';
3 import {Injectable, Inject, Provider, Input, provide, Component} from 'ng-forward'; 4 import {Injectable, Inject, Provider, Input, provide, Component} from 'ng-forward';
4 import {User, Person} from "./../app/models/interfaces"; 5 import {User, Person} from "./../app/models/interfaces";
5 6
6 7
  8 +export var ngforward = {
  9 + providers: providers,
  10 + TestComponentBuilder: TestComponentBuilder,
  11 + ComponentFixture: ComponentFixture
  12 +};
  13 +
7 export interface ComponentFixtureTemplate { 14 export interface ComponentFixtureTemplate {
8 providers?: any[]; 15 providers?: any[];
9 directives?: any[]; 16 directives?: any[];
@@ -60,11 +67,13 @@ class AngularServiceHookComponent { @@ -60,11 +67,13 @@ class AngularServiceHookComponent {
60 } 67 }
61 } 68 }
62 69
  70 +/**
  71 + * This helper class allows get angular services to be used in integration tests
  72 + * i.e: '$http', '$q', '$location', etc...
  73 + */
63 class AngularServiceFactory { 74 class AngularServiceFactory {
64 - fixtureComponentHookPoint: ComponentFixture;  
65 - // tcb: TestComponentBuilder = new TestComponentBuilder();  
66 75
67 - constructor() { 76 + constructor(private fixtureComponentHookPoint: ComponentFixture) {
68 this.fixtureComponentHookPoint = (<any>tcb)["create"](AngularServiceHookComponent); 77 this.fixtureComponentHookPoint = (<any>tcb)["create"](AngularServiceHookComponent);
69 } 78 }
70 79
@@ -81,30 +90,11 @@ class AngularServiceFactory { @@ -81,30 +90,11 @@ class AngularServiceFactory {
81 } 90 }
82 } 91 }
83 92
84 -export function getAngularServiceFactory() {  
85 - return new AngularServiceFactory();  
86 -}  
87 -/**  
88 - * This help function allows get angular services to be used in integration tests  
89 - * i.e: '$http', '$q', '$location', etc...  
90 - */  
91 -export function getAngularService<T>(angularService: string) {  
92 - return getAngularServiceFactory().getAngularService(angularService);  
93 -}  
94 -  
95 -export function getQService(): ng.IQService {  
96 - return getAngularServiceFactory().getQService();  
97 -}  
98 -  
99 -export function getHttpBackendService(): ng.IHttpBackendService {  
100 - return getAngularServiceFactory().getHttpBackendService(); 93 +export function getAngularServiceFactory(fixture: ComponentFixture) {
  94 + return new AngularServiceFactory(fixture);
101 } 95 }
102 96
103 -// export function getResolvablePromise() {  
104 -// let $q = getQService();  
105 -//  
106 -// return null;  
107 -// } 97 +export {mocks} from "./mocks";
108 98
109 export var fixtures = { 99 export var fixtures = {
110 user: { 100 user: {
src/spec/mocks.ts 0 → 100644
@@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
  1 +
  2 +class ScopeWithEvents {
  3 + listeners = {};
  4 + constructor() {
  5 +
  6 + }
  7 +
  8 + public $on(eventName: string, func: Function) {
  9 + console.log(this.listeners);
  10 + if ((<any>this.listeners)[eventName]) {
  11 + (<any>this.listeners)[eventName].push(func);
  12 + } else {
  13 + (<any>this.listeners)[eventName] = [func];
  14 + }
  15 + console.log(this.listeners);
  16 + }
  17 +
  18 + public $emit(message: string, arg?: any) {
  19 + console.log("Emitted " + message);
  20 + if ( (<any>this.listeners)[message]) {
  21 + console.log("LISTENERS:", (<any>this.listeners)[message]);
  22 + (<any>this.listeners)[message].forEach((f: Function) => {
  23 + f(arg);
  24 + });
  25 + }
  26 + }
  27 +}
  28 +export var mocks = {
  29 + scopeWithEvents: new ScopeWithEvents(),
  30 + modalInstance: {
  31 + close: () => { }
  32 + },
  33 + $modal: {
  34 + open: (args: {}) => {
  35 + return this.modalInstance;
  36 + }
  37 + },
  38 + authService: {
  39 + logout: () => { }
  40 + },
  41 + sessionWithCurrentUser: (user: any) => {
  42 + return {
  43 + currentUser: () => { return user; }
  44 + };
  45 + }
  46 +
  47 +};
0 \ No newline at end of file 48 \ No newline at end of file