Commit 7f10a7cf1158f9ab70ea753f4581624ae9028f2e
Exists in
master
and in
35 other branches
merge. after changes on navbar
Showing
15 changed files
with
207 additions
and
93 deletions
Show diff stats
.vscode/tasks.json
package.json
| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | }, |
| 9 | 9 | "scripts": { |
| 10 | 10 | "test": "concurrently \"webpack -w\" \"karma start\"", |
| 11 | - "postinstall": "npm install -g bower && bower install", | |
| 11 | + "postinstall": "npm install -g bower && bower install && typings install", | |
| 12 | 12 | "start": "concurrently \"webpack -w\" \"gulp serve\"", |
| 13 | 13 | "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts" |
| 14 | 14 | }, | ... | ... |
| ... | ... | @@ -0,0 +1,67 @@ |
| 1 | + | |
| 2 | + | |
| 3 | +import {AuthService, AUTH_EVENTS} from "./"; | |
| 4 | +import {User, Credentials} from "./../../models/interfaces"; | |
| 5 | + | |
| 6 | +describe("Auth Service", () => { | |
| 7 | + | |
| 8 | + let $httpBackend: ng.IHttpBackendService; | |
| 9 | + let authService: AuthService; | |
| 10 | + let credentials: Credentials; | |
| 11 | + let $rootScope: ng.IRootScopeService; | |
| 12 | + let user: User; | |
| 13 | + | |
| 14 | + beforeEach(angular.mock.module("noosferoApp")); | |
| 15 | + | |
| 16 | + beforeEach(inject((_$httpBackend_: ng.IHttpBackendService, _$rootScope_: ng.IRootScopeService, _AuthService_: AuthService) => { | |
| 17 | + $httpBackend = _$httpBackend_; | |
| 18 | + authService = _AuthService_; | |
| 19 | + $rootScope = _$rootScope_; | |
| 20 | + | |
| 21 | + user = <User>{ | |
| 22 | + id: 1, | |
| 23 | + login: "user" | |
| 24 | + }; | |
| 25 | + })); | |
| 26 | + | |
| 27 | + | |
| 28 | + describe("Succesffull login", () => { | |
| 29 | + | |
| 30 | + beforeEach(() => { | |
| 31 | + credentials = { username: "user", password: "password" }; | |
| 32 | + | |
| 33 | + $httpBackend.expectPOST("/api/v1/login", "login=user&password=password").respond(200, { user: user }); | |
| 34 | + }); | |
| 35 | + | |
| 36 | + it("should return loggedUser", (done) => { | |
| 37 | + authService.login(credentials).then((loggedUser) => { | |
| 38 | + expect(loggedUser).toBeDefined(); | |
| 39 | + done(); | |
| 40 | + }); | |
| 41 | + $httpBackend.flush(); | |
| 42 | + expect($httpBackend.verifyNoOutstandingRequest()); | |
| 43 | + }); | |
| 44 | + | |
| 45 | + | |
| 46 | + it("should emit event loggin successful with user logged data", () => { | |
| 47 | + | |
| 48 | + authService.login(credentials); | |
| 49 | + | |
| 50 | + let eventEmmited: boolean = false; | |
| 51 | + $rootScope.$on(AUTH_EVENTS.loginSuccess, (event: ng.IAngularEvent, userThroughEvent: User) => { | |
| 52 | + eventEmmited = true; | |
| 53 | + expect(userThroughEvent).toEqual(user) | |
| 54 | + }); | |
| 55 | + | |
| 56 | + $httpBackend.flush(); | |
| 57 | + | |
| 58 | + expect(eventEmmited).toBeTruthy(AUTH_EVENTS.loginSuccess + " was not emmited!"); | |
| 59 | + }); | |
| 60 | + | |
| 61 | + }); | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | +}); | |
| 67 | + | |
| 0 | 68 | \ No newline at end of file | ... | ... |
src/app/components/auth/auth_service.ts
| ... | ... | @@ -32,7 +32,7 @@ export class AuthService { |
| 32 | 32 | return currentUser; |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | - login(credentials: Credentials) { | |
| 35 | + login(credentials: Credentials): ng.IPromise<User> { | |
| 36 | 36 | let url = '/api/v1/login'; |
| 37 | 37 | let encodedData = 'login=' + credentials.username + '&password=' + credentials.password; |
| 38 | 38 | return this.$http.post(url, encodedData).then(this.loginSuccessCallback.bind(this), this.loginFailedCallback.bind(this)); | ... | ... |
src/app/components/navbar/navbar.directive.js
| ... | ... | @@ -1,58 +0,0 @@ |
| 1 | -(function() { | |
| 2 | - 'use strict'; | |
| 3 | - | |
| 4 | - angular | |
| 5 | - .module('noosferoApp') | |
| 6 | - .directive('acmeNavbar', acmeNavbar); | |
| 7 | - | |
| 8 | - /** @ngInject */ | |
| 9 | - function acmeNavbar() { | |
| 10 | - var directive = { | |
| 11 | - restrict: 'E', | |
| 12 | - templateUrl: 'app/components/navbar/navbar.html', | |
| 13 | - scope: {}, | |
| 14 | - controller: NavbarController, | |
| 15 | - controllerAs: 'vm', | |
| 16 | - bindToController: true | |
| 17 | - }; | |
| 18 | - | |
| 19 | - return directive; | |
| 20 | - | |
| 21 | - /** @ngInject */ | |
| 22 | - function NavbarController(moment, $modal, AuthService, Session, $scope, $state, AUTH_EVENTS) { | |
| 23 | - var vm = this; | |
| 24 | - | |
| 25 | - vm.currentUser = Session.getCurrentUser(); | |
| 26 | - vm.modalInstance = null; | |
| 27 | - | |
| 28 | - vm.openLogin = function() { | |
| 29 | - vm.modalInstance = $modal.open({ | |
| 30 | - templateUrl: 'app/components/auth/login.html', | |
| 31 | - controller: 'AuthController', | |
| 32 | - controllerAs: 'vm', | |
| 33 | - bindToController: true | |
| 34 | - }); | |
| 35 | - }; | |
| 36 | - vm.logout = function() { | |
| 37 | - AuthService.logout(); | |
| 38 | - $state.go($state.current, {}, {reload: true}); //TODO move to auth | |
| 39 | - }; | |
| 40 | - $scope.$on(AUTH_EVENTS.loginSuccess, function() { | |
| 41 | - if(vm.modalInstance) { | |
| 42 | - vm.modalInstance.close(); | |
| 43 | - vm.modalInstance = null; | |
| 44 | - } | |
| 45 | - $state.go($state.current, {}, {reload: true}); //TODO move to auth | |
| 46 | - }); | |
| 47 | - $scope.$on(AUTH_EVENTS.logoutSuccess, function() { | |
| 48 | - vm.currentUser = Session.getCurrentUser(); | |
| 49 | - }); | |
| 50 | - | |
| 51 | - vm.activate = function() { | |
| 52 | - if(!vm.currentUser) vm.openLogin(); | |
| 53 | - } | |
| 54 | - vm.activate(); | |
| 55 | - } | |
| 56 | - } | |
| 57 | - | |
| 58 | -})(); |
src/app/components/navbar/navbar.html
| 1 | 1 | <nav class="navbar navbar-static-top navbar-inverse"> |
| 2 | 2 | <div class="container-fluid"> |
| 3 | 3 | <div class="navbar-header"> |
| 4 | - <button type="button" class="navbar-toggle collapsed" ng-click="isCollapsed = !isCollapsed"> | |
| 4 | + <button type="button" class="navbar-toggle collapsed" (ng-click)="isCollapsed = !isCollapsed"> | |
| 5 | 5 | <span class="sr-only">Toggle navigation</span> |
| 6 | 6 | <span class="icon-bar"></span> |
| 7 | 7 | <span class="icon-bar"></span> |
| ... | ... | @@ -17,25 +17,25 @@ |
| 17 | 17 | </ul> |
| 18 | 18 | |
| 19 | 19 | <ul class="nav navbar-nav navbar-right"> |
| 20 | - <li ng-show="!vm.currentUser"> | |
| 21 | - <a ng-href="#" ng-click="vm.openLogin()">Login</a> | |
| 20 | + <li ng-show="!ctrl.currentUser"> | |
| 21 | + <a ng-href="#" (ng-click)="ctrl.openLogin()">Login</a> | |
| 22 | 22 | </li> |
| 23 | 23 | |
| 24 | - <li class="dropdown profile-menu" ng-show="vm.currentUser" dropdown> | |
| 24 | + <li class="dropdown profile-menu" ng-show="ctrl.currentUser" dropdown> | |
| 25 | 25 | <a href="#" class="dropdown-toggle" aria-expanded="false" dropdown-toggle> |
| 26 | - <noosfero-profile-image profile="vm.currentUser.person" class="profile-image"></noosfero-profile-image> | |
| 27 | - <span ng-bind="vm.currentUser.person.name"></span> <b class="caret"></b> | |
| 26 | + <noosfero-profile-image profile="ctrl.currentUser.person" class="profile-image"></noosfero-profile-image> | |
| 27 | + <span ng-bind="ctrl.currentUser.person.name"></span> <b class="caret"></b> | |
| 28 | 28 | </a> |
| 29 | 29 | <ul class="dropdown-menu" dropdown-menu> |
| 30 | 30 | <li> |
| 31 | - <a ui-sref="main.profile.info({profile: vm.currentUser.person.identifier})"><i class="fa fa-fw fa-user"></i> Profile</a> | |
| 31 | + <a ui-sref="main.profile.info({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-user"></i> Profile</a> | |
| 32 | 32 | </li> |
| 33 | 33 | <li> |
| 34 | - <a target="_self" ui-sref="main.profile.settings({profile: vm.currentUser.person.identifier})"><i class="fa fa-fw fa-gear"></i> Settings</a> | |
| 34 | + <a target="_self" ui-sref="main.profile.settings({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-gear"></i> Settings</a> | |
| 35 | 35 | </li> |
| 36 | 36 | <li class="divider"></li> |
| 37 | 37 | <li> |
| 38 | - <a href="#" ng-click="vm.logout()"><i class="fa fa-fw fa-power-off"></i> Log Out</a> | |
| 38 | + <a href="#" (ng-click)="ctrl.logout()"><i class="fa fa-fw fa-power-off"></i> Log Out</a> | |
| 39 | 39 | </li> |
| 40 | 40 | </ul> |
| 41 | 41 | </li> | ... | ... |
src/app/components/noosfero-blocks/block.component.ts
| ... | ... | @@ -11,7 +11,7 @@ export class Block { |
| 11 | 11 | @Input() owner: any; |
| 12 | 12 | |
| 13 | 13 | ngOnInit() { |
| 14 | - let blockName = this.block.type ? this.block.type.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() : "default-block"; | |
| 14 | + let blockName = (this.block && this.block.type) ? this.block.type.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() : "default-block"; | |
| 15 | 15 | this.$element.replaceWith(this.$compile('<noosfero-' + blockName + ' [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-' + blockName + '>')(this.$scope)); |
| 16 | 16 | } |
| 17 | 17 | ... | ... |
src/app/components/noosfero-blocks/link-list/link-list.component.spec.ts
0 → 100644
| ... | ... | @@ -0,0 +1,64 @@ |
| 1 | +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder'; | |
| 2 | +import {Pipe, Input, provide, Component} from 'ng-forward'; | |
| 3 | + | |
| 4 | +import {LinkListBlock} from './link-list.component'; | |
| 5 | + | |
| 6 | +const tcb = new TestComponentBuilder(); | |
| 7 | + | |
| 8 | +const htmlTemplate: string = '<noosfero-link-list-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-link-list-block>'; | |
| 9 | + | |
| 10 | + | |
| 11 | +describe("Link List Block Component", () => { | |
| 12 | + | |
| 13 | + beforeEach(angular.mock.module("templates")); | |
| 14 | + | |
| 15 | + it("receives the block and the owner as inputs", done => { | |
| 16 | + | |
| 17 | + // Creating a container component (BlockContainerComponent) to include | |
| 18 | + // the component under test (Block) | |
| 19 | + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [LinkListBlock] }) | |
| 20 | + class BlockContainerComponent { | |
| 21 | + block = { type: 'Block' }; | |
| 22 | + owner = { name: 'profile-name' }; | |
| 23 | + constructor() { | |
| 24 | + } | |
| 25 | + } | |
| 26 | + | |
| 27 | + // uses the TestComponentBuilder instance to initialize the component | |
| 28 | + //.overrideView(LinkListBlock, { template: 'asdasdasd', pipes: [NoosferoTemplate] }) | |
| 29 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | |
| 30 | + // and here we can inspect and run the test assertions | |
| 31 | + let myComponent: LinkListBlock = fixture.componentInstance; | |
| 32 | + | |
| 33 | + // assure the block object inside the Block matches | |
| 34 | + // the provided through the parent component | |
| 35 | + expect(myComponent.block.type).toEqual("Block"); | |
| 36 | + expect(myComponent.owner.name).toEqual("profile-name"); | |
| 37 | + done(); | |
| 38 | + }); | |
| 39 | + }); | |
| 40 | + | |
| 41 | + | |
| 42 | + it("display links stored in block settings", done => { | |
| 43 | + | |
| 44 | + @Pipe('noosferoTemplateFilter') | |
| 45 | + class NoosferoTemplateFilter { | |
| 46 | + transform(input: any, changeTo: any) { | |
| 47 | + return input; | |
| 48 | + } | |
| 49 | + } | |
| 50 | + | |
| 51 | + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [LinkListBlock] }) | |
| 52 | + class CustomBlockType { | |
| 53 | + block: any = { settings: { links: [{ name: 'link1', address: 'address1' }, { name: 'link2', address: 'address2' }] } }; | |
| 54 | + owner: any = { name: 'profile-name' }; | |
| 55 | + constructor() { | |
| 56 | + } | |
| 57 | + } | |
| 58 | + tcb.overrideView(LinkListBlock, { templateUrl: "app/components/noosfero-blocks/link-list/link-list.html", pipes: [NoosferoTemplateFilter] }).createAsync(CustomBlockType).then(fixture => { | |
| 59 | + expect(fixture.debugElement.queryAll(".link-list-block a").length).toEqual(2); | |
| 60 | + done(); | |
| 61 | + }); | |
| 62 | + }); | |
| 63 | + | |
| 64 | +}); | ... | ... |
src/app/components/noosfero-blocks/link-list/link-list.component.ts
src/app/components/noosfero-blocks/main-block/main-block.component.js
| ... | ... | @@ -1,20 +0,0 @@ |
| 1 | -(function() { | |
| 2 | - 'use strict'; | |
| 3 | - | |
| 4 | - angular | |
| 5 | - .module('noosferoApp') | |
| 6 | - .component('noosferoMainBlock', { | |
| 7 | - restrict: 'E', | |
| 8 | - templateUrl: 'app/components/noosfero-blocks/main-block/main-block.html', | |
| 9 | - bindings: { | |
| 10 | - block: '<', | |
| 11 | - owner: '<' | |
| 12 | - }, | |
| 13 | - controller: MainBlockController | |
| 14 | - }); | |
| 15 | - | |
| 16 | - /** @ngInject */ | |
| 17 | - function MainBlockController() { | |
| 18 | - } | |
| 19 | - | |
| 20 | -})(); |
src/app/components/noosfero-blocks/main-block/main-block.component.spec.ts
0 → 100644
| ... | ... | @@ -0,0 +1,40 @@ |
| 1 | +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder'; | |
| 2 | +import {Input, provide, Component, StateConfig} from 'ng-forward'; | |
| 3 | + | |
| 4 | +import {MainBlock} from './main-block.component'; | |
| 5 | +import {NoosferoApp} from '../../../index.module'; | |
| 6 | + | |
| 7 | +const tcb = new TestComponentBuilder(); | |
| 8 | + | |
| 9 | +const htmlTemplate: string = '<noosfero-main-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-main-block>'; | |
| 10 | + | |
| 11 | + | |
| 12 | +describe("Main Block Component", () => { | |
| 13 | + | |
| 14 | + // the karma preprocessor html2js transform the templates html into js files which put | |
| 15 | + // the templates to the templateCache into the module templates | |
| 16 | + // we need to load the module templates here as the template for the | |
| 17 | + // component Block will be load on our tests | |
| 18 | + beforeEach(angular.mock.module("templates")); | |
| 19 | + | |
| 20 | + it("check if the main block has a tag with ui-view attribute", done => { | |
| 21 | + | |
| 22 | + // Creating a container component (BlockContainerComponent) to include | |
| 23 | + // the component under test (Block) | |
| 24 | + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [MainBlock] }) | |
| 25 | + class BlockContainerComponent { | |
| 26 | + } | |
| 27 | + | |
| 28 | + // uses the TestComponentBuilder instance to initialize the component | |
| 29 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | |
| 30 | + // and here we can inspect and run the test assertions | |
| 31 | + //let myComponent: MainBlock = fixture.componentInstance; | |
| 32 | + | |
| 33 | + // assure the block object inside the Block matches | |
| 34 | + // the provided through the parent component | |
| 35 | + expect(fixture.debugElement.queryAll('[ui-view="mainBlockContent"]').length).toEqual(1) | |
| 36 | + done(); | |
| 37 | + }); | |
| 38 | + }); | |
| 39 | + | |
| 40 | +}); | ... | ... |
src/app/components/noosfero-blocks/main-block/main-block.component.ts
0 → 100644
| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | +import {Component, Input} from 'ng-forward' | |
| 2 | +import {Block} from '../block.component'; | |
| 3 | + | |
| 4 | +@Component({ | |
| 5 | + selector: 'noosfero-main-block', | |
| 6 | + templateUrl: 'app/components/noosfero-blocks/main-block/main-block.html' | |
| 7 | +}) | |
| 8 | +export class MainBlock { | |
| 9 | + | |
| 10 | +} | ... | ... |
src/app/index.ts
| ... | ... | @@ -45,7 +45,6 @@ NoosferoApp.addController("AuthController", AuthController); |
| 45 | 45 | |
| 46 | 46 | require("./components/noosfero-activities/activities.component.js"); |
| 47 | 47 | require("./components/noosfero-activities/activity/activity.component.js"); |
| 48 | -require("./components/noosfero-blocks/main-block/main-block.component.js"); | |
| 49 | 48 | require("./components/noosfero-blocks/members-block/members-block.component.js"); |
| 50 | 49 | require("./components/noosfero-blocks/profile-image/profile-image.component.js"); |
| 51 | 50 | require("./components/noosfero-blocks/recent-documents/recent-documents.component.js"); | ... | ... |
src/app/main/main.component.ts
| ... | ... | @@ -12,8 +12,12 @@ import {LinkListBlock} from "../components/noosfero-blocks/link-list/link-list.c |
| 12 | 12 | import {AuthService} from "./../components/auth/auth_service"; |
| 13 | 13 | import {Session} from "./../components/auth/session"; |
| 14 | 14 | |
| 15 | + | |
| 15 | 16 | import {Navbar} from "../components/navbar"; |
| 16 | 17 | |
| 18 | +import {MainBlock} from "../components/noosfero-blocks/main-block/main-block.component"; | |
| 19 | + | |
| 20 | + | |
| 17 | 21 | @Component({ |
| 18 | 22 | selector: 'main-content', |
| 19 | 23 | templateUrl: "app/main/main.html", |
| ... | ... | @@ -26,7 +30,7 @@ export class MainContent { |
| 26 | 30 | @Component({ |
| 27 | 31 | selector: 'main', |
| 28 | 32 | template: '<div ng-view></div>', |
| 29 | - directives: [NoosferoArticleBlog, ArticleView, Boxes, Block, LinkListBlock, Navbar], | |
| 33 | + directives: [NoosferoArticleBlog, ArticleView, Boxes, Block, LinkListBlock, MainBlock, Navbar], | |
| 30 | 34 | providers: [AuthService, Session] |
| 31 | 35 | }) |
| 32 | 36 | @StateConfig([ | ... | ... |
typings.json
| ... | ... | @@ -9,6 +9,8 @@ |
| 9 | 9 | "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c", |
| 10 | 10 | "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dd638012d63e069f2c99d06ef4dcc9616a943ee4", |
| 11 | 11 | "jquery": "github:DefinitelyTyped/DefinitelyTyped/jquery/jquery.d.ts#470954c4f427e0805a2d633636a7c6aa7170def8", |
| 12 | + "moment": "github:DefinitelyTyped/DefinitelyTyped/moment/moment.d.ts#b090bcf9ba9f756ec8ff53e7707269729172a325", | |
| 13 | + "moment-node": "github:DefinitelyTyped/DefinitelyTyped/moment/moment-node.d.ts#b090bcf9ba9f756ec8ff53e7707269729172a325", | |
| 12 | 14 | "ngstorage": "github:DefinitelyTyped/DefinitelyTyped/ngstorage/ngstorage.d.ts#f59279e1f7535149b4e14d2ccf537b2c81cfff75", |
| 13 | 15 | "restangular": "github:DefinitelyTyped/DefinitelyTyped/restangular/restangular.d.ts#f2ae460e1751bb6668d291d4eb9255f047dd0ac5" |
| 14 | 16 | } | ... | ... |