From 4f1c6294a4a294a566501e075920948ae0c83f1a Mon Sep 17 00:00:00 2001 From: Carlos Purificacao Date: Tue, 3 May 2016 11:34:55 -0300 Subject: [PATCH] Login block component - initial implementation --- src/app/layout/blocks/login-block/login-block.component.spec.ts | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/app/layout/blocks/login-block/login-block.component.ts | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/app/layout/blocks/login-block/login-block.html | 23 +++++++++++++++++++++++ src/app/login/session.service.ts | 2 -- src/app/main/main.component.ts | 3 ++- src/spec/component-test-helper.ts | 2 ++ src/spec/mocks.ts | 3 ++- 7 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 src/app/layout/blocks/login-block/login-block.component.spec.ts create mode 100644 src/app/layout/blocks/login-block/login-block.component.ts create mode 100644 src/app/layout/blocks/login-block/login-block.html diff --git a/src/app/layout/blocks/login-block/login-block.component.spec.ts b/src/app/layout/blocks/login-block/login-block.component.spec.ts new file mode 100644 index 0000000..bb2e1c9 --- /dev/null +++ b/src/app/layout/blocks/login-block/login-block.component.spec.ts @@ -0,0 +1,108 @@ +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder'; +import {Injectable, Provider, provide} from "ng-forward"; +import {ComponentTestHelper, createClass} from './../../../../spec/component-test-helper'; +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; +import {providers} from 'ng-forward/cjs/testing/providers'; +import {LoginBlockComponent} from './login-block.component'; +import * as helpers from "./../../../../spec/helpers"; +import {SessionService, AuthService, AuthController, IAuthEvents, AUTH_EVENTS} from "./../../../login"; + +const htmlTemplate: string = ''; + +describe("Components", () => { + + describe("Login Block Component", () => { + let helper: ComponentTestHelper; + let person: any = null; + + /** + * Mock objects + */ + let authService: any = helpers.mocks.authService; + let user = { person: person }; + let sessionService: any = helpers.mocks.sessionWithCurrentUser(user); + let state = jasmine.createSpyObj("$state", ["go"]); + let scope = helpers.mocks.scopeWithEvents; + + let providers = [ + new Provider('SessionService', { useValue: sessionService }), + new Provider('$state', { useValue: state }), + new Provider('AuthService', { useValue: authService }), + new Provider('$scope', { useValue: scope }) + ]; + + beforeEach( angular.mock.module("templates") ); + + beforeEach( (done: Function) => { + let cls = createClass({ + template: htmlTemplate, + directives: [LoginBlockComponent], + providers: providers, + properties: {} + }); + helper = new ComponentTestHelper(cls, done); + }); + + it("expect person to be null with no logged in user", () => { + expect(helper.component.currentUser).toBeNull; + }); + + it("expect person to be defined when user login", () => { + // Executes the login method on the component + doComponentLogin(); + expect(helper.component.currentUser.person).toBe(person); + }); + + it("expect person to be null when user logout", () => { + // First do a login + doComponentLogin(); + // The logout the user + doComponentLogout(); + // Check if the current user was cleared + expect(helper.component.currentUser).toBeNull; + }); + + /** + * Execute the logout method on the target component + */ + function doComponentLogout() { + // Create a mock for the AuthService logout method + spyOn(authService, "logout"); + helper.component.logout(); + expect(authService.logout).toHaveBeenCalled(); + // After the component logout method execution, fire the + // AuthService event + simulateLogout(); + } + + /** + * Execute the login method on the target component + */ + function doComponentLogin() { + // Create a mock for the AuthService login method + spyOn(authService, "login"); + helper.component.login(); + expect(authService.login).toHaveBeenCalled(); + // After the component login method execution, fire the + // AuthService event + simulateLogin(); + } + + /** + * Simulate the AuthService loginSuccess event + */ + function simulateLogin() { + let localScope: ng.IScope = helper.component["$scope"]; + localScope.$emit(AUTH_EVENTS.loginSuccess); + } + + /** + * Simulate the AuthService logoutSuccess event + */ + function simulateLogout() { + let localScope: ng.IScope = helper.component["$scope"]; + localScope.$emit(AUTH_EVENTS.logoutSuccess); + } + }); + +}); \ No newline at end of file diff --git a/src/app/layout/blocks/login-block/login-block.component.ts b/src/app/layout/blocks/login-block/login-block.component.ts new file mode 100644 index 0000000..3095da2 --- /dev/null +++ b/src/app/layout/blocks/login-block/login-block.component.ts @@ -0,0 +1,73 @@ +import {Input, Inject, Component} from "ng-forward"; +import {SessionService, AuthService, IAuthEvents, AUTH_EVENTS} from "./../../../login"; + +/** + * @ngdoc controller + * @name layout.blocks.LoginBlockComponent + * @description + * The Noosfero block responible for presenting a login form and user status + */ +@Component({ + selector: "noosfero-login-block", + templateUrl: 'app/layout/blocks/login-block/login-block.html', +}) +@Inject("SessionService", "$state", 'AuthService', "$scope") +export class LoginBlockComponent { + + /** + * @ngdoc property + * @name currentUser + * @propertyOf layout.blocks.LoginBlockComponent + * @description + * The current loged in user + */ + currentUser: noosfero.User; + + /** + * @ngdoc property + * @name credentials + * @propertyOf layout.blocks.LoginBlockComponent + * @description + * The credentials of the currentUser + */ + credentials: noosfero.Credentials; + + constructor( + private session: SessionService, + private $state: ng.ui.IStateService, + private authService: AuthService, + private $scope: ng.IScope) { + this.currentUser = this.session.currentUser(); + + this.$scope.$on(AUTH_EVENTS.loginSuccess, () => { + this.currentUser = this.session.currentUser(); + }); + + this.$scope.$on(AUTH_EVENTS.logoutSuccess, () => { + this.currentUser = this.session.currentUser(); + }); + + } + + /** + * @ngdoc method + * @name login + * @methodOf layout.blocks.LoginBlockComponent + * @description + * Logs in the user using its credentials + */ + login() { + this.authService.login(this.credentials); + } + + /** + * @ngdoc method + * @name logout + * @methodOf layout.blocks.LoginBlockComponent + * @description + * Logout the user + */ + logout() { + this.authService.logout(); + }; +} diff --git a/src/app/layout/blocks/login-block/login-block.html b/src/app/layout/blocks/login-block/login-block.html new file mode 100644 index 0000000..8e61eaf --- /dev/null +++ b/src/app/layout/blocks/login-block/login-block.html @@ -0,0 +1,23 @@ + + \ No newline at end of file diff --git a/src/app/login/session.service.ts b/src/app/login/session.service.ts index 8ac0b8b..07b3f70 100644 --- a/src/app/login/session.service.ts +++ b/src/app/login/session.service.ts @@ -11,13 +11,11 @@ export class SessionService { create(data: UserResponse): noosfero.User { this.$localStorage.currentUser = data.user; - this.$log.debug('User session created.', this.$localStorage.currentUser); return this.$localStorage.currentUser; }; destroy() { delete this.$localStorage.currentUser; - this.$log.debug('User session destroyed.'); }; currentUser(): noosfero.User { diff --git a/src/app/main/main.component.ts b/src/app/main/main.component.ts index 7cef8e7..efd8368 100644 --- a/src/app/main/main.component.ts +++ b/src/app/main/main.component.ts @@ -9,6 +9,7 @@ import {BlockComponent} from "../layout/blocks/block.component"; import {EnvironmentComponent} from "../environment/environment.component"; import {EnvironmentHomeComponent} from "../environment/environment-home.component"; import {PeopleBlockComponent} from "../layout/blocks/people-block/people-block.component"; +import {LoginBlockComponent} from "../layout/blocks/login-block/login-block.component"; import {LinkListBlockComponent} from "./../layout/blocks/link-list/link-list.component"; import {RecentDocumentsBlockComponent} from "../layout/blocks/recent-documents/recent-documents.component"; import {ProfileImageBlockComponent} from "../layout/blocks/profile-image-block/profile-image-block.component"; @@ -81,7 +82,7 @@ export class EnvironmentContent { template: '
', directives: [ ArticleBlogComponent, ArticleViewComponent, BoxesComponent, BlockComponent, - EnvironmentComponent, PeopleBlockComponent, + EnvironmentComponent, PeopleBlockComponent, LoginBlockComponent, LinkListBlockComponent, CommunitiesBlockComponent, MainBlockComponent, RecentDocumentsBlockComponent, Navbar, ProfileImageBlockComponent, MembersBlockComponent, NoosferoTemplate, DateFormat, RawHTMLBlockComponent diff --git a/src/spec/component-test-helper.ts b/src/spec/component-test-helper.ts index 2441994..508473b 100644 --- a/src/spec/component-test-helper.ts +++ b/src/spec/component-test-helper.ts @@ -2,6 +2,7 @@ import { Component } from "ng-forward"; import { TestComponentBuilder, ngClass } from 'ng-forward/cjs/testing/test-component-builder'; import { INgForwardJQuery } from "ng-forward/cjs/util/jqlite-extensions"; import { ComponentFixture } from 'ng-forward/cjs/testing/test-component-builder'; +import * as helpers from './helpers'; /** * @ngdoc object @@ -135,6 +136,7 @@ export function createClass({ providers = [], properties = {} }): any { + providers = providers.concat(helpers.provideFilters("translateFilter")); @Component({ selector: 'component-test-helper-container', template, directives, providers }) class Test { constructor() { diff --git a/src/spec/mocks.ts b/src/spec/mocks.ts index 21a9497..82a396b 100644 --- a/src/spec/mocks.ts +++ b/src/spec/mocks.ts @@ -41,7 +41,8 @@ export var mocks = { } }, authService: { - logout: () => { } + logout: () => { }, + login: () => { } }, articleService: { getByProfile: (profileId: number, params?: any) => { -- libgit2 0.21.2