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 9 import {Session, AuthService, AuthController, IAuthEvents} from "./../auth";
22 10  
  11 +
23 12 describe("Components", () => {
24 13  
25 14 describe("Navbar Component", () => {
26 15  
  16 + let user: User = null;
  17 + let scope: any;
27 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 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 84 let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance;
105 85 expect(navbarInstance).toBeDefined();
106   - expect(navbarInstance["currentUser"]).toEqual(user)
  86 + expect(navbarInstance["currentUser"]).toEqual(user);
107 87 done();
108 88 });
109 89 });
110 90  
111 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 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 112 navbarComp.logout();
144 113 expect(authService.logout).toHaveBeenCalled();
145 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 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 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 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 177 \ No newline at end of file
... ...
src/app/components/navbar/navbar.ts
1 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 5 import {User} from "./../../models/interfaces";
6 6  
7 7 @Component({
8 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 13 export class Navbar {
13 14  
14 15 private currentUser: User;
... ... @@ -17,30 +18,26 @@ export class Navbar {
17 18 *
18 19 */
19 20 constructor(
20   - private moment: moment.MomentStatic,
21 21 private $modal: any,
22 22 private authService: AuthService,
23 23 private session: Session,
24 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 30 if (this.modalInstance) {
33 31 this.modalInstance.close();
34 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 39 this.currentUser = this.session.currentUser();
42 40 });
43   -
44 41 }
45 42  
46 43 openLogin() {
... ... @@ -54,7 +51,7 @@ export class Navbar {
54 51  
55 52 logout() {
56 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 15 quickCreateComponent,
16 16 provideEmptyObjects,
17 17 createProviderToValue,
18   - getAngularService,
19 18 provideFilters
20 19 } from "../../../../spec/helpers.ts";
21 20  
... ...
src/lib/ng-noosfero-api/http/profile.service.spec.ts
1 1 import {Profile} from "../../../app/models/interfaces";
2 2 import {ProfileService} from "./profile.service";
3   -import {getAngularService} from "../../../spec/helpers";
4 3  
5 4 describe("Services", () => {
6 5  
... ...
src/spec/helpers.ts
1 1  
2 2 import {ngClass, TestComponentBuilder, ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
  3 +import {providers} from 'ng-forward/cjs/testing/providers';
3 4 import {Injectable, Inject, Provider, Input, provide, Component} from 'ng-forward';
4 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 14 export interface ComponentFixtureTemplate {
8 15 providers?: any[];
9 16 directives?: any[];
... ... @@ -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 74 class AngularServiceFactory {
64   - fixtureComponentHookPoint: ComponentFixture;
65   - // tcb: TestComponentBuilder = new TestComponentBuilder();
66 75  
67   - constructor() {
  76 + constructor(private fixtureComponentHookPoint: ComponentFixture) {
68 77 this.fixtureComponentHookPoint = (<any>tcb)["create"](AngularServiceHookComponent);
69 78 }
70 79  
... ... @@ -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 99 export var fixtures = {
110 100 user: {
... ...
src/spec/mocks.ts 0 → 100644
... ... @@ -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 48 \ No newline at end of file
... ...