From e492a985b1737209a844fbacf06273429ba0e6e6 Mon Sep 17 00:00:00 2001 From: ABNER SILVA DE OLIVEIRA Date: Wed, 9 Mar 2016 19:36:38 -0300 Subject: [PATCH] remodeled the navbar specs. added more helpers. added mock file --- src/app/components/navbar/navbar.spec.ts | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ src/app/components/navbar/navbar.ts | 23 ++++++++++------------- src/app/components/noosfero-articles/blog/blog.component.spec.ts | 1 - src/lib/ng-noosfero-api/http/profile.service.spec.ts | 1 - src/spec/helpers.ts | 40 +++++++++++++++------------------------- src/spec/mocks.ts | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 207 insertions(+), 238 deletions(-) create mode 100644 src/spec/mocks.ts diff --git a/src/app/components/navbar/navbar.spec.ts b/src/app/components/navbar/navbar.spec.ts index 774f9db..f0ef2fb 100644 --- a/src/app/components/navbar/navbar.spec.ts +++ b/src/app/components/navbar/navbar.spec.ts @@ -1,238 +1,175 @@ -import { -createComponentFromClass, -quickCreateComponent, -provideEmptyObjects -} from "./../../../spec/helpers"; -import { -Navbar -} from "./navbar"; -import { -AUTH_EVENTS -} from "./../auth"; -import { -User -} from "./../../models/interfaces"; -import { -Injectable, -Provider, -provide -} from "ng-forward"; +import * as helpers from "./../../../spec/helpers"; +import {Navbar} from "./navbar"; +import {AUTH_EVENTS} from "./../auth"; +import {User} from "./../../models/interfaces"; +import {Injectable, Provider, provide} from "ng-forward"; + +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; import {Session, AuthService, AuthController, IAuthEvents} from "./../auth"; + describe("Components", () => { describe("Navbar Component", () => { + let user: User = null; + let scope: any; let $rootScope: ng.IRootScopeService; - let user = { - id: 1, - login: "user" - }; + let modalInstance: any; + let $modal: any; + let authService: any; + let stateService: any; + let sessionService: any; + + let provideFunc = provide; + + // before Each -> loading mocks on locals variables + beforeEach(() => { + user = { + id: 1, + login: "user" + }; + scope = helpers.mocks.scopeWithEvents; + modalInstance = helpers.mocks.modalInstance; + $modal = helpers.mocks.$modal; + authService = helpers.mocks.authService; + stateService = jasmine.createSpyObj("$state", ["go"]); + sessionService = helpers.mocks.sessionWithCurrentUser(user); + }); - let scope = { - eventCalledHook: () => { }, - $on: (eventName: string, func: Function) => { - this.eventCalledHook = func; - } - } - let modalInstance = { - close: () => { } - } + // loading the templates + beforeEach(angular.mock.module("templates")); - let $modal = { - open: (args: {}) => { - return modalInstance; - } - } - let authService = { - logout: () => { } + // this function allow build the fixture of the container component + // and is reused in each test + // The main idea behing not prebuild it on a general beforeEach block is + // to allow tests configure the mock services accordilly their own needs + let buildComponent = (): Promise => { + return helpers.quickCreateComponent({ + providers: [ + provide('$modal', { + useValue: $modal + }), + provide('AuthService', { + useValue: authService + }), + helpers.provideEmptyObjects('moment'), + provide('$state', { + useValue: stateService + }), + provide("$scope", { + useValue: scope + }), + provide('Session', { + useValue: sessionService + }), + provide('AUTH_EVENTS', { + useValue: { + AUTH_EVENTS + } + }) + ], + directives: [Navbar], + template: '' + }); } - let stateService = jasmine.createSpyObj("$state", ["go"]); - let providers = [ - new Provider('moment', { useValue: {} }), - new Provider('$modal', { useValue: $modal }), - new Provider('AuthService', { useValue: authService }), - new Provider('Session', { - useValue: { - currentUser: () => { return user } - } - }), - new Provider('$scope', { useValue: scope }), - new Provider('$state', { useValue: stateService }), - new Provider('AUTH_EVENTS', { useValue: { AUTH_EVENTS } }) - ]; - - - beforeEach(angular.mock.module("templates")); - - // beforeEach(inject((_$rootScope_: ng.IRootScopeService) => { - // $rootScope = _$rootScope_; - // })); it('should get the loggedIn user', (done: Function) => { - - let scope = jasmine.createSpyObj("scope", ["$on"]); - let providers = [ - provideEmptyObjects('moment', '$modal', 'AuthService', '$state'), - new Provider('Session', { - useValue: { - currentUser: () => { - return user; - } - } - }), - new Provider('$scope', { - useValue: scope - }), - new Provider('AUTH_EVENTS', { - useValue: { - AUTH_EVENTS - } - }) - ]; - - quickCreateComponent({ - providers: providers, - template: "", - directives: [Navbar] - }).then(fixture => { + buildComponent().then((fixture: ComponentFixture) => { let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; expect(navbarInstance).toBeDefined(); - expect(navbarInstance["currentUser"]).toEqual(user) + expect(navbarInstance["currentUser"]).toEqual(user); done(); }); }); it('should open on click', (done: Function) => { - - quickCreateComponent({ - providers: providers, - template: "", - directives: [Navbar] - }) - .then(fixture => { - let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; - spyOn($modal, "open"); - navbarComp.openLogin(); - expect($modal.open).toHaveBeenCalled(); - expect($modal.open).toHaveBeenCalledWith({ - templateUrl: 'app/components/auth/login.html', - controller: AuthController, - controllerAs: 'vm', - bindToController: true - }); - done(); - }) + spyOn($modal, "open"); + buildComponent().then((fixture: ComponentFixture) => { + let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; + navbarComp.openLogin(); + expect($modal.open).toHaveBeenCalled(); + expect($modal.open).toHaveBeenCalledWith({ + templateUrl: 'app/components/auth/login.html', + controller: AuthController, + controllerAs: 'vm', + bindToController: true + }); + done(); + }); }); it('should logout', (done: Function) => { - - quickCreateComponent({ - providers: providers, - template: "", - directives: [Navbar] - }) - .then(fixture => { - let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; - spyOn(authService, "logout"); + buildComponent().then((fixture: ComponentFixture) => { + let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; + spyOn(authService, "logout"); + try { navbarComp.logout(); expect(authService.logout).toHaveBeenCalled(); done(); - }) + } catch (e) { + console.error(e); + fail(e.message); + done(); + } + }); }); it('should not activate user when logged in', (done: Function) => { - quickCreateComponent({ - providers: providers, - template: "", - directives: [Navbar] - }) - .then(fixture => { - let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; - spyOn(navbarComp, "openLogin"); - navbarComp.activate(); - expect((navbarComp.openLogin).calls.count()).toBe(0); - done(); - }) - + buildComponent().then((fixture: ComponentFixture) => { + let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; + spyOn(navbarComp, "openLogin"); + navbarComp.activate(); + expect((navbarComp.openLogin).calls.count()).toBe(0); + done(); + }); }); it('should activate when user not logged in', (done: Function) => { - user = null; - quickCreateComponent({ - providers: providers, - template: "", - directives: [Navbar] - }) - .then(fixture => { - let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; - spyOn(navbarComp, "openLogin"); - navbarComp.activate(); - expect(navbarComp.openLogin).toHaveBeenCalled(); + spyOn(sessionService, 'currentUser').and.returnValue(null); + buildComponent().then((fixture: ComponentFixture) => { + let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; + spyOn(navbarComp, "openLogin"); + navbarComp.activate(); + expect(navbarComp.openLogin).toHaveBeenCalled(); + done(); + }); + }); + + + it('closes the modal after login', (done: Function) => { + modalInstance = jasmine.createSpyObj("modalInstance", ["close"]); + modalInstance.close = jasmine.createSpy("close"); + + $modal.open = () => { + return modalInstance; + }; + + buildComponent().then((fixture: ComponentFixture) => { + let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; + let localScope: ng.IScope = navbarComp["$scope"]; + + + navbarComp.openLogin(); + + localScope.$on(AUTH_EVENTS.loginSuccess, () => { + expect(modalInstance.close).toHaveBeenCalled(); done(); - }) + }); + + localScope.$emit(AUTH_EVENTS.loginSuccess); + fixture.detectChanges(); + + + }); }); - - - // it('closes the modal the login', (done: Function) => { - // let scope = { - // eventCalledHook: () => { }, - // $on: (eventName: string, func: Function) => { - // console.log("ON Called!"); - // this.eventCalledHook = func; - // } - // } - // - // let modalInstance = { - // close: () => { - // console.log("CLOSE Called!"); - // } - // } - // - // let $modal = { - // $open: (args: {}) => { - // return modalInstance; - // } - // } - // - // let stateService = jasmine.createSpyObj("$state", ["go"]); - // let providers = [ - // new Provider('moment', { useValue: {} }), - // new Provider('$modal', { useValue: $modal }), - // new Provider('AuthService', { useValue: {} }), - // new Provider('Session', { - // useValue: { - // currentUser: () => { return user } - // } - // }), - // new Provider('$scope', { useValue: scope }), - // new Provider('$state', { useValue: stateService }), - // new Provider('AUTH_EVENTS', { useValue: { AUTH_EVENTS } }) - // ]; - // spyOn(modalInstance, "close"); - // - // quickCreateComponent({ - // providers: providers, - // template: "", - // directives: [Navbar] - // }) - // .then(fixture => { - // let navbarComp: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; - // navbarComp.activate(); - // navbarComp.openLogin - // - // expect($modal.open).toHaveBeenCalledWith({}) - // scope.eventCalledHook(); - // expect(modalInstance.close).toHaveBeenCalled(); - // done(); - // }) - // //done(); - // }); + + }); -}); +}); \ No newline at end of file diff --git a/src/app/components/navbar/navbar.ts b/src/app/components/navbar/navbar.ts index d00bfe5..f6cac6d 100644 --- a/src/app/components/navbar/navbar.ts +++ b/src/app/components/navbar/navbar.ts @@ -1,14 +1,15 @@ import {Component, Inject} from "ng-forward"; -import {Session, AuthService, AuthController, IAuthEvents} from "./../auth"; +import {Session, AuthService, AuthController, IAuthEvents, AUTH_EVENTS} from "./../auth"; import {User} from "./../../models/interfaces"; @Component({ selector: "acme-navbar", - templateUrl: "app/components/navbar/navbar.html" + templateUrl: "app/components/navbar/navbar.html", + providers: [AuthService, Session] }) -@Inject("moment", "$modal", "AuthService", "Session", "$scope", "$state", "AUTH_EVENTS") +@Inject("$modal", AuthService, "Session", "$scope", "$state") export class Navbar { private currentUser: User; @@ -17,30 +18,26 @@ export class Navbar { * */ constructor( - private moment: moment.MomentStatic, private $modal: any, private authService: AuthService, private session: Session, private $scope: ng.IScope, - private $state: ng.ui.IStateService, - private AUTH_EVENTS: IAuthEvents + private $state: ng.ui.IStateService ) { + this.currentUser = this.session.currentUser(); - this.currentUser = session.currentUser(); - - $scope.$on(AUTH_EVENTS.loginSuccess, () => { + this.$scope.$on(AUTH_EVENTS.loginSuccess, () => { if (this.modalInstance) { this.modalInstance.close(); this.modalInstance = null; } - this.$state.go(this.$state.current, {}, { reload: true }); //TODO move to auth + this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth }); - $scope.$on(AUTH_EVENTS.logoutSuccess, () => { + this.$scope.$on(AUTH_EVENTS.logoutSuccess, () => { this.currentUser = this.session.currentUser(); }); - } openLogin() { @@ -54,7 +51,7 @@ export class Navbar { logout() { this.authService.logout(); - this.$state.go(this.$state.current, {}, { reload: true }); //TODO move to auth + this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth }; diff --git a/src/app/components/noosfero-articles/blog/blog.component.spec.ts b/src/app/components/noosfero-articles/blog/blog.component.spec.ts index 4bebe13..23b04a5 100644 --- a/src/app/components/noosfero-articles/blog/blog.component.spec.ts +++ b/src/app/components/noosfero-articles/blog/blog.component.spec.ts @@ -15,7 +15,6 @@ import { quickCreateComponent, provideEmptyObjects, createProviderToValue, - getAngularService, provideFilters } from "../../../../spec/helpers.ts"; diff --git a/src/lib/ng-noosfero-api/http/profile.service.spec.ts b/src/lib/ng-noosfero-api/http/profile.service.spec.ts index 6b91d0b..a78c924 100644 --- a/src/lib/ng-noosfero-api/http/profile.service.spec.ts +++ b/src/lib/ng-noosfero-api/http/profile.service.spec.ts @@ -1,6 +1,5 @@ import {Profile} from "../../../app/models/interfaces"; import {ProfileService} from "./profile.service"; -import {getAngularService} from "../../../spec/helpers"; describe("Services", () => { diff --git a/src/spec/helpers.ts b/src/spec/helpers.ts index ccf9100..3f5cfbb 100644 --- a/src/spec/helpers.ts +++ b/src/spec/helpers.ts @@ -1,9 +1,16 @@ import {ngClass, TestComponentBuilder, ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; +import {providers} from 'ng-forward/cjs/testing/providers'; import {Injectable, Inject, Provider, Input, provide, Component} from 'ng-forward'; import {User, Person} from "./../app/models/interfaces"; +export var ngforward = { + providers: providers, + TestComponentBuilder: TestComponentBuilder, + ComponentFixture: ComponentFixture +}; + export interface ComponentFixtureTemplate { providers?: any[]; directives?: any[]; @@ -60,11 +67,13 @@ class AngularServiceHookComponent { } } +/** + * This helper class allows get angular services to be used in integration tests + * i.e: '$http', '$q', '$location', etc... + */ class AngularServiceFactory { - fixtureComponentHookPoint: ComponentFixture; - // tcb: TestComponentBuilder = new TestComponentBuilder(); - constructor() { + constructor(private fixtureComponentHookPoint: ComponentFixture) { this.fixtureComponentHookPoint = (tcb)["create"](AngularServiceHookComponent); } @@ -81,30 +90,11 @@ class AngularServiceFactory { } } -export function getAngularServiceFactory() { - return new AngularServiceFactory(); -} -/** - * This help function allows get angular services to be used in integration tests - * i.e: '$http', '$q', '$location', etc... - */ -export function getAngularService(angularService: string) { - return getAngularServiceFactory().getAngularService(angularService); -} - -export function getQService(): ng.IQService { - return getAngularServiceFactory().getQService(); -} - -export function getHttpBackendService(): ng.IHttpBackendService { - return getAngularServiceFactory().getHttpBackendService(); +export function getAngularServiceFactory(fixture: ComponentFixture) { + return new AngularServiceFactory(fixture); } -// export function getResolvablePromise() { -// let $q = getQService(); -// -// return null; -// } +export {mocks} from "./mocks"; export var fixtures = { user: { diff --git a/src/spec/mocks.ts b/src/spec/mocks.ts new file mode 100644 index 0000000..59beda3 --- /dev/null +++ b/src/spec/mocks.ts @@ -0,0 +1,47 @@ + +class ScopeWithEvents { + listeners = {}; + constructor() { + + } + + public $on(eventName: string, func: Function) { + console.log(this.listeners); + if ((this.listeners)[eventName]) { + (this.listeners)[eventName].push(func); + } else { + (this.listeners)[eventName] = [func]; + } + console.log(this.listeners); + } + + public $emit(message: string, arg?: any) { + console.log("Emitted " + message); + if ( (this.listeners)[message]) { + console.log("LISTENERS:", (this.listeners)[message]); + (this.listeners)[message].forEach((f: Function) => { + f(arg); + }); + } + } +} +export var mocks = { + scopeWithEvents: new ScopeWithEvents(), + modalInstance: { + close: () => { } + }, + $modal: { + open: (args: {}) => { + return this.modalInstance; + } + }, + authService: { + logout: () => { } + }, + sessionWithCurrentUser: (user: any) => { + return { + currentUser: () => { return user; } + }; + } + +}; \ No newline at end of file -- libgit2 0.21.2