Commit d2590816220ba082c9eb8fecbedc192f4e7ef712

Authored by ABNER SILVA DE OLIVEIRA
2 parents 6f744e76 f18ccc08

added coverage task

Showing 34 changed files with 526 additions and 187 deletions   Show diff stats
.vscode/tasks.json
@@ -23,6 +23,10 @@ @@ -23,6 +23,10 @@
23 { 23 {
24 "taskName": "test", 24 "taskName": "test",
25 "isTestCommand": true 25 "isTestCommand": true
  26 + },
  27 + {
  28 + "taskName": "generate-indexes",
  29 + "args": []
26 } 30 }
27 ] 31 ]
28 } 32 }
29 \ No newline at end of file 33 \ No newline at end of file
gulp/server.js
@@ -36,6 +36,7 @@ function browserSyncInit(baseDir, browser) { @@ -36,6 +36,7 @@ function browserSyncInit(baseDir, browser) {
36 browserSync.instance = browserSync.init({ 36 browserSync.instance = browserSync.init({
37 startPath: '/', 37 startPath: '/',
38 server: server, 38 server: server,
  39 + port: 3001,
39 browser: browser 40 browser: browser
40 }); 41 });
41 } 42 }
@@ -112,7 +112,6 @@ module.exports = function (config) { @@ -112,7 +112,6 @@ module.exports = function (config) {
112 112
113 browsers: ['PhantomJS'], 113 browsers: ['PhantomJS'],
114 114
115 -  
116 plugins: karmaPlugins, 115 plugins: karmaPlugins,
117 116
118 117
@@ -124,6 +123,7 @@ module.exports = function (config) { @@ -124,6 +123,7 @@ module.exports = function (config) {
124 } 123 }
125 }; 124 };
126 125
  126 +
127 if (argv.coverage) { 127 if (argv.coverage) {
128 128
129 /*configuration.webpack = { 129 /*configuration.webpack = {
@@ -177,9 +177,6 @@ module.exports = function (config) { @@ -177,9 +177,6 @@ module.exports = function (config) {
177 }; 177 };
178 } 178 }
179 179
180 - // 'src/**/*.js': ['sourcemap'],  
181 - // 'src/**/*.[sS]pec.ts': ['sourcemap']  
182 - // };  
183 180
184 pathSrcHtml.forEach(function (path) { 181 pathSrcHtml.forEach(function (path) {
185 configuration.preprocessors[path] = ['ng-html2js']; 182 configuration.preprocessors[path] = ['ng-html2js'];
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 "remap-coverage": "ts-node --project ./dev-scripts ./dev-scripts/remapCoverage.ts", 11 "remap-coverage": "ts-node --project ./dev-scripts ./dev-scripts/remapCoverage.ts",
12 "test-single": "webpack && karma start --single-run", 12 "test-single": "webpack && karma start --single-run",
13 "test": "concurrently \"webpack -w\" \"karma start\"", 13 "test": "concurrently \"webpack -w\" \"karma start\"",
14 - "postinstall": "npm install -g bower && bower install", 14 + "postinstall": "npm install -g bower && bower install && typings install",
15 "start": "concurrently \"webpack -w\" \"gulp serve\"", 15 "start": "concurrently \"webpack -w\" \"gulp serve\"",
16 "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts" 16 "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts"
17 }, 17 },
src/app/components/auth/index.ts
1 -/* Module Index Entry - generated using the script npm run generate-indexes */ 1 +/* Module Index Entry - generated using the script npm run generate-index */
2 export * from "./auth_controller"; 2 export * from "./auth_controller";
3 export * from "./auth_events"; 3 export * from "./auth_events";
4 export * from "./auth_service"; 4 export * from "./auth_service";
src/app/components/navbar/index.ts
1 /* Module Index Entry - generated using the script npm run generate-index */ 1 /* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./navbar";
src/app/components/navbar/navbar.directive.js
@@ -1,58 +0,0 @@ @@ -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
@@ -17,25 +17,25 @@ @@ -17,25 +17,25 @@
17 </ul> 17 </ul>
18 18
19 <ul class="nav navbar-nav navbar-right"> 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 </li> 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 <a href="#" class="dropdown-toggle" aria-expanded="false" dropdown-toggle> 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 </a> 28 </a>
29 <ul class="dropdown-menu" dropdown-menu> 29 <ul class="dropdown-menu" dropdown-menu>
30 <li> 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 </li> 32 </li>
33 <li> 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 </li> 35 </li>
36 <li class="divider"></li> 36 <li class="divider"></li>
37 <li> 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 </li> 39 </li>
40 </ul> 40 </ul>
41 </li> 41 </li>
src/app/components/navbar/navbar.spec.ts 0 → 100644
@@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
  1 +import {createComponentFromClass, quickCreateComponent} from "./../../../spec/helpers";
  2 +import {Navbar} from "./";
  3 +import {AUTH_EVENTS} from "./../auth";
  4 +import {User} from "./../../models/interfaces";
  5 +import {Injectable, Provider, provide} from "ng-forward";
  6 +
  7 +
  8 +
  9 +describe("Navbar Component", () => {
  10 +
  11 + let $rootScope: ng.IRootScopeService;
  12 + let user = <User>{
  13 + id: 1,
  14 + login: "user"
  15 + };
  16 +
  17 + beforeEach(angular.mock.module("templates"));
  18 +
  19 + // beforeEach(inject((_$rootScope_: ng.IRootScopeService) => {
  20 + // $rootScope = _$rootScope_;
  21 + // }));
  22 +
  23 + it('should get the loggedIn user', (done: Function) => {
  24 +
  25 +
  26 + let scope = jasmine.createSpyObj("scope", ["$on"]);
  27 +
  28 + let providers = [
  29 +
  30 +
  31 + new Provider('moment', { useValue: {} }),
  32 + new Provider('$modal', { useValue: {} }),
  33 + new Provider('AuthService', { useValue: {} }),
  34 + new Provider('Session', { useValue: {
  35 + getCurrentUser: () => { return user}
  36 + } }),
  37 + new Provider('$scope', { useValue: scope }),
  38 + new Provider('$state', { useValue: {} }),
  39 + new Provider('AUTH_EVENTS', { useValue: {AUTH_EVENTS} })
  40 + ];
  41 +
  42 +
  43 +
  44 + quickCreateComponent({
  45 + providers: providers,
  46 + template: "<acme-navbar></acme-navbar>",
  47 + directives: [Navbar]
  48 + }).then(fixture => {
  49 + let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance;
  50 + expect(navbarInstance).toBeDefined();
  51 + expect(navbarInstance["currentUser"]).toEqual(user)
  52 + done();
  53 + })
  54 + });
  55 +
  56 +});
0 \ No newline at end of file 57 \ No newline at end of file
src/app/components/navbar/navbar.ts 0 → 100644
@@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
  1 +import {Component, Inject} from "ng-forward";
  2 +
  3 +
  4 +import {Session, AuthService, IAuthEvents} from "./../auth";
  5 +import {User} from "./../../models/interfaces";
  6 +
  7 +@Component({
  8 + selector: "acme-navbar",
  9 + templateUrl: "app/components/navbar/navbar.html"
  10 +})
  11 +@Inject("moment", "$modal", "AuthService", "Session", "$scope", "$state", "AUTH_EVENTS")
  12 +export class Navbar {
  13 +
  14 + private currentUser: User;
  15 + private modalInstance: any = null;
  16 + /**
  17 + *
  18 + */
  19 + constructor(
  20 + private moment: moment.MomentStatic,
  21 + private $modal: any,
  22 + private authService: AuthService,
  23 + private session: Session,
  24 + private $scope: ng.IScope,
  25 + private $state: ng.ui.IStateService,
  26 + private AUTH_EVENTS: IAuthEvents
  27 + ) {
  28 +
  29 + this.currentUser = session.getCurrentUser();
  30 +
  31 + $scope.$on(AUTH_EVENTS.loginSuccess, function() {
  32 + if (this.modalInstance) {
  33 + this.modalInstance.close();
  34 + this.modalInstance = null;
  35 + }
  36 +
  37 + this.$state.go(this.$state.current, {}, { reload: true }); //TODO move to auth
  38 + });
  39 +
  40 + $scope.$on(AUTH_EVENTS.logoutSuccess, () => {
  41 + this.currentUser = this.session.getCurrentUser();
  42 + });
  43 +
  44 + }
  45 +
  46 + openLogin() {
  47 + this.modalInstance = this.$modal.open({
  48 + templateUrl: 'app/components/auth/login.html',
  49 + controller: 'AuthController',
  50 + controllerAs: 'vm',
  51 + bindToController: true
  52 + });
  53 + };
  54 +
  55 + logout() {
  56 + this.authService.logout();
  57 + this.$state.go(this.$state.current, {}, { reload: true }); //TODO move to auth
  58 + };
  59 +
  60 +
  61 +
  62 + activate() {
  63 + if (!this.currentUser) {
  64 + this.openLogin();
  65 + }
  66 + }
  67 +
  68 +}
0 \ No newline at end of file 69 \ No newline at end of file
src/app/components/noosfero-blocks/block.component.ts
@@ -11,7 +11,7 @@ export class Block { @@ -11,7 +11,7 @@ export class Block {
11 @Input() owner: any; 11 @Input() owner: any;
12 12
13 ngOnInit() { 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 this.$element.replaceWith(this.$compile('<noosfero-' + blockName + ' [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-' + blockName + '>')(this.$scope)); 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/index.ts
1 /* Module Index Entry - generated using the script npm run generate-index */ 1 /* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./link-list.component";
src/app/components/noosfero-blocks/link-list/link-list.component.spec.ts 0 → 100644
@@ -0,0 +1,64 @@ @@ -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
@@ -12,7 +12,9 @@ export class LinkListBlock { @@ -12,7 +12,9 @@ export class LinkListBlock {
12 links: any; 12 links: any;
13 13
14 ngOnInit() { 14 ngOnInit() {
15 - this.links = this.block.settings.links; 15 + if (this.block && this.block.settings) {
  16 + this.links = this.block.settings.links;
  17 + }
16 } 18 }
17 19
18 } 20 }
src/app/components/noosfero-blocks/main-block/main-block.component.js
@@ -1,20 +0,0 @@ @@ -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 @@ @@ -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 @@ @@ -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/components/noosfero-blocks/members-block/members-block.component.js
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - angular  
5 - .module('noosferoApp')  
6 - .component('noosferoMembersBlock', {  
7 - restrict: 'E',  
8 - templateUrl: 'app/components/noosfero-blocks/members-block/members-block.html',  
9 - bindings: {  
10 - block: '<',  
11 - owner: '<'  
12 - },  
13 - controller: MembersBlockController  
14 - });  
15 -  
16 - /** @ngInject */  
17 - function MembersBlockController(noosfero) {  
18 - var vm = this;  
19 - vm.members = [];  
20 -  
21 - noosfero.members(noosfero.profiles.one(vm.owner.id)).one().get({per_page: 6}).then(function(response) {  
22 - vm.members = response.data.people;  
23 - });  
24 - }  
25 -  
26 -})();  
src/app/components/noosfero-blocks/members-block/members-block.component.spec.ts 0 → 100644
@@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
  1 +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
  2 +import {Provider, Input, provide, Component} from 'ng-forward';
  3 +
  4 +import {MembersBlock} from './members-block.component';
  5 +
  6 +const htmlTemplate: string = '<noosfero-members-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-members-block>';
  7 +
  8 +const tcb = new TestComponentBuilder();
  9 +
  10 +describe("Members Block Component", () => {
  11 +
  12 + beforeEach(angular.mock.module("templates"));
  13 +
  14 + let state = jasmine.createSpyObj("state", ["go"]);
  15 + let providers = [
  16 + new Provider('truncateFilter', { useValue: () => { } }),
  17 + new Provider('stripTagsFilter', { useValue: () => { } }),
  18 + new Provider('$state', { useValue: state }),
  19 + new Provider('ProfileService', {
  20 + useValue: {
  21 + getProfileMembers: (profileId: number, filters: any): any => {
  22 + return Promise.resolve({ data: { people: [{ identifier: "person1" }] } });
  23 + }
  24 + }
  25 + }),
  26 + ];
  27 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [MembersBlock], providers: providers })
  28 + class BlockContainerComponent {
  29 + block = { type: 'Block', settings: {} };
  30 + owner = { name: 'profile-name' };
  31 + constructor() {
  32 + }
  33 + }
  34 +
  35 + it("get members of the block owner", done => {
  36 + tcb.createAsync(BlockContainerComponent).then(fixture => {
  37 + let recentDocumentsBlock: MembersBlock = fixture.debugElement.componentViewChildren[0].componentInstance;
  38 + expect(recentDocumentsBlock.members).toEqual([{ identifier: "person1" }]);
  39 + done();
  40 + });
  41 + });
  42 +
  43 + it("render the profile image for each member", done => {
  44 + tcb.createAsync(BlockContainerComponent).then(fixture => {
  45 + let recentDocumentsBlock: MembersBlock = fixture.debugElement.componentViewChildren[0].componentInstance;
  46 + fixture.debugElement.getLocal("$rootScope").$apply();
  47 + expect(fixture.debugElement.queryAll("noosfero-profile-image").length).toEqual(1);
  48 + done();
  49 + });
  50 + });
  51 +
  52 +});
src/app/components/noosfero-blocks/members-block/members-block.component.ts 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +import {Input, Inject, Component} from "ng-forward";
  2 +import {ProfileService} from "../../../../lib/ng-noosfero-api/http/profile.service";
  3 +
  4 +@Component({
  5 + selector: "noosfero-members-block",
  6 + templateUrl: 'app/components/noosfero-blocks/members-block/members-block.html',
  7 +})
  8 +@Inject(ProfileService)
  9 +export class MembersBlock {
  10 +
  11 + @Input() block: any;
  12 + @Input() owner: any;
  13 +
  14 + members: any = [];
  15 +
  16 + constructor(private ProfileService: ProfileService) {
  17 +
  18 + }
  19 +
  20 + ngOnInit() {
  21 + this.ProfileService.getProfileMembers(this.owner.id, { per_page: 6 }).then((response: any) => {
  22 + this.members = response.data.people;
  23 + });
  24 + }
  25 +}
src/app/components/noosfero-blocks/members-block/members-block.html
1 <div class="members-block"> 1 <div class="members-block">
2 - <a ng-repeat="member in $ctrl.members" ui-sref="main.profile({profile: member.identifier})" class="member"> 2 + <a ng-repeat="member in ctrl.members" ui-sref="main.profile({profile: member.identifier})" class="member">
3 <noosfero-profile-image profile="member"></noosfero-profile-image> 3 <noosfero-profile-image profile="member"></noosfero-profile-image>
4 </a> 4 </a>
5 </div> 5 </div>
src/app/components/noosfero-blocks/profile-image/profile-image.component.js
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - angular  
5 - .module('noosferoApp')  
6 - .component('noosferoProfileImageBlock', {  
7 - restrict: 'E',  
8 - templateUrl: 'app/components/noosfero-blocks/profile-image/profile-image.html',  
9 - bindings: {  
10 - block: '<',  
11 - owner: '<'  
12 - },  
13 - controller: ProfileImageBlockController  
14 - });  
15 -  
16 - /** @ngInject */  
17 - function ProfileImageBlockController() {  
18 - var vm = this;  
19 - vm.profile = vm.owner;  
20 - }  
21 -  
22 -})();  
src/app/components/noosfero-blocks/profile-image/profile-image.component.spec.ts 0 → 100644
@@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
  1 +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
  2 +import {Pipe, Input, provide, Component} from 'ng-forward';
  3 +
  4 +import {ProfileImageBlock} from './profile-image.component';
  5 +
  6 +const tcb = new TestComponentBuilder();
  7 +
  8 +const htmlTemplate: string = '<noosfero-profile-image-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-profile-image-block>';
  9 +
  10 +
  11 +describe("Profile Image Block Component", () => {
  12 +
  13 + beforeEach(angular.mock.module("templates"));
  14 +
  15 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ProfileImageBlock] })
  16 + class BlockContainerComponent {
  17 + block = { type: 'Block' };
  18 + owner = { name: 'profile-name' };
  19 + constructor() {
  20 + }
  21 + }
  22 +
  23 + it("render the profile image", done => {
  24 + tcb.createAsync(BlockContainerComponent).then(fixture => {
  25 + expect(fixture.debugElement.queryAll("noosfero-profile-image").length).toEqual(1);
  26 + done();
  27 + });
  28 + });
  29 +
  30 + it("render the settings link", done => {
  31 + tcb.createAsync(BlockContainerComponent).then(fixture => {
  32 + expect(fixture.debugElement.queryAll(".settings-link").length).toEqual(1);
  33 + done();
  34 + });
  35 + });
  36 +
  37 +});
src/app/components/noosfero-blocks/profile-image/profile-image.component.ts 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +import {Input, Component} from "ng-forward";
  2 +
  3 +@Component({
  4 + selector: "noosfero-profile-image-block",
  5 + templateUrl: 'app/components/noosfero-blocks/profile-image/profile-image.html',
  6 +})
  7 +export class ProfileImageBlock {
  8 +
  9 + @Input() block: any;
  10 + @Input() owner: any;
  11 +
  12 +}
src/app/components/noosfero-blocks/profile-image/profile-image.html
1 <div class="center-block text-center profile-image-block"> 1 <div class="center-block text-center profile-image-block">
2 - <a ui-sref="main.profile.info({profile: $ctrl.owner.identifier})">  
3 - <noosfero-profile-image profile="$ctrl.owner"></noosfero-profile-image> 2 + <a ui-sref="main.profile.info({profile: ctrl.owner.identifier})">
  3 + <noosfero-profile-image profile="ctrl.owner"></noosfero-profile-image>
4 </a> 4 </a>
5 - <a class="settings-link" target="_self" ui-sref="main.profile.settings({profile: $ctrl.owner.identifier})">Control panel</a> 5 + <a class="settings-link" target="_self" ui-sref="main.profile.settings({profile: ctrl.owner.identifier})">Control panel</a>
6 </div> 6 </div>
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.js
@@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - angular  
5 - .module('noosferoApp')  
6 - .component('noosferoRecentDocumentsBlock', {  
7 - restrict: 'E',  
8 - templateUrl: 'app/components/noosfero-blocks/recent-documents/recent-documents.html',  
9 - bindings: {  
10 - block: '<',  
11 - owner: '<'  
12 - },  
13 - controller: RecentDocumentsController  
14 - });  
15 -  
16 - /** @ngInject */  
17 - function RecentDocumentsController(noosfero, $state) {  
18 - var vm = this;  
19 - vm.profile = vm.owner;  
20 - vm.documents = [];  
21 -  
22 - vm.openDocument = function(article) {  
23 - $state.go("main.profile.page", {page: article.path, profile: article.profile.identifier});  
24 - }  
25 -  
26 - var limit = vm.block.settings.limit || 5;  
27 - //FIXME get all text articles  
28 - noosfero.profiles.one(vm.profile.id).one('articles').get({content_type: 'TinyMceArticle', per_page: limit}).then(function(response) {  
29 - vm.documents = response.data.articles;  
30 - });  
31 - }  
32 -  
33 -})();  
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.spec.ts 0 → 100644
@@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
  1 +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
  2 +import {Provider, Input, provide, Component} from 'ng-forward';
  3 +
  4 +import {RecentDocumentsBlock} from './recent-documents.component';
  5 +
  6 +const htmlTemplate: string = '<noosfero-recent-documents-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-recent-documents-block>';
  7 +
  8 +const tcb = new TestComponentBuilder();
  9 +
  10 +describe("Recent Documents Block Component", () => {
  11 +
  12 + beforeEach(angular.mock.module("templates"));
  13 +
  14 + let state = jasmine.createSpyObj("state", ["go"]);
  15 + let providers = [
  16 + new Provider('truncateFilter', { useValue: () => { } }),
  17 + new Provider('stripTagsFilter', { useValue: () => { } }),
  18 + new Provider('$state', { useValue: state }),
  19 + new Provider('ArticleService', {
  20 + useValue: {
  21 + getByProfile: (profileId: number, filters: any): any => {
  22 + return Promise.resolve({ data: { articles: [{ name: "article1" }] } });
  23 + }
  24 + }
  25 + }),
  26 + ];
  27 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [RecentDocumentsBlock], providers: providers })
  28 + class BlockContainerComponent {
  29 + block = { type: 'Block', settings: {} };
  30 + owner = { name: 'profile-name' };
  31 + constructor() {
  32 + }
  33 + }
  34 +
  35 + it("get recent documents from the article service", done => {
  36 + tcb.createAsync(BlockContainerComponent).then(fixture => {
  37 + let recentDocumentsBlock: RecentDocumentsBlock = fixture.debugElement.componentViewChildren[0].componentInstance;
  38 + expect(recentDocumentsBlock.documents).toEqual([{ name: "article1" }]);
  39 + done();
  40 + });
  41 + });
  42 +
  43 + it("go to article page when open a document", done => {
  44 + tcb.createAsync(BlockContainerComponent).then(fixture => {
  45 + let recentDocumentsBlock: RecentDocumentsBlock = fixture.debugElement.componentViewChildren[0].componentInstance;
  46 + recentDocumentsBlock.openDocument({ path: "path", profile: { identifier: "identifier" } });
  47 + expect(state.go).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "identifier" });
  48 + done();
  49 + });
  50 + });
  51 +
  52 +});
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.ts 0 → 100644
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  1 +import {Component, Inject, Input} from "ng-forward";
  2 +import {ArticleService} from "../../../../lib/ng-noosfero-api/http/article.service";
  3 +
  4 +@Component({
  5 + selector: "noosfero-recent-documents-block",
  6 + templateUrl: 'app/components/noosfero-blocks/recent-documents/recent-documents.html'
  7 +})
  8 +@Inject(ArticleService, "$state")
  9 +export class RecentDocumentsBlock {
  10 +
  11 + @Input() block: any;
  12 + @Input() owner: any;
  13 +
  14 + profile: any;
  15 + documents: any;
  16 +
  17 + constructor(private ArticleService: ArticleService, private $state: any) {
  18 + }
  19 +
  20 + ngOnInit() {
  21 + this.profile = this.owner;
  22 + this.documents = [];
  23 +
  24 + var limit = (this.block && this.block.settings) ? this.block.settings.limit : null || 5;
  25 + //FIXME get all text articles
  26 + this.ArticleService.getByProfile(this.profile.id, { content_type: 'TinyMceArticle', per_page: limit }).then((response: any) => {
  27 + this.documents = response.data.articles;
  28 + });
  29 + }
  30 +
  31 + openDocument(article: any) {
  32 + this.$state.go("main.profile.page", { page: article.path, profile: article.profile.identifier });
  33 + }
  34 +
  35 +}
src/app/components/noosfero-blocks/recent-documents/recent-documents.html
1 -<div deckgrid source="$ctrl.documents" class="deckgrid">  
2 - <div class="a-card panel media" ng-click="mother.$ctrl.openDocument(card);"> 1 +<div deckgrid source="ctrl.documents" class="deckgrid">
  2 + <div class="a-card panel media" ng-click="mother.ctrl.openDocument(card);">
3 <div class="author media-left" ng-show="card.author.image"> 3 <div class="author media-left" ng-show="card.author.image">
4 <img ng-src="{{card.author.image.url}}" class="img-circle"> 4 <img ng-src="{{card.author.image.url}}" class="img-circle">
5 </div> 5 </div>
src/app/index.ts
@@ -19,6 +19,8 @@ import {bootstrap, bundle} from &quot;ng-forward&quot;; @@ -19,6 +19,8 @@ import {bootstrap, bundle} from &quot;ng-forward&quot;;
19 import {AUTH_EVENTS} from "./components/auth/auth_events"; 19 import {AUTH_EVENTS} from "./components/auth/auth_events";
20 import {AuthController} from "./components/auth/auth_controller"; 20 import {AuthController} from "./components/auth/auth_controller";
21 21
  22 +import {Navbar} from "./components/navbar";
  23 +
22 declare var moment: any; 24 declare var moment: any;
23 25
24 let noosferoApp: any = bundle("noosferoApp", Main, ["ngAnimate", "ngCookies", "ngStorage", "ngTouch", 26 let noosferoApp: any = bundle("noosferoApp", Main, ["ngAnimate", "ngCookies", "ngStorage", "ngTouch",
@@ -41,13 +43,8 @@ NoosferoApp.run(noosferoAngularRunBlock); @@ -41,13 +43,8 @@ NoosferoApp.run(noosferoAngularRunBlock);
41 NoosferoApp.addController("AuthController", AuthController); 43 NoosferoApp.addController("AuthController", AuthController);
42 44
43 45
44 -require("./components/navbar/navbar.directive.js");  
45 require("./components/noosfero-activities/activities.component.js"); 46 require("./components/noosfero-activities/activities.component.js");
46 require("./components/noosfero-activities/activity/activity.component.js"); 47 require("./components/noosfero-activities/activity/activity.component.js");
47 -require("./components/noosfero-blocks/main-block/main-block.component.js");  
48 -require("./components/noosfero-blocks/members-block/members-block.component.js");  
49 -require("./components/noosfero-blocks/profile-image/profile-image.component.js");  
50 -require("./components/noosfero-blocks/recent-documents/recent-documents.component.js");  
51 require("./components/noosfero/noosfero-template.filter.js"); 48 require("./components/noosfero/noosfero-template.filter.js");
52 require("./components/noosfero/noosfero.service.js"); 49 require("./components/noosfero/noosfero.service.js");
53 require("./components/noosfero/profile-image/profile-image.component.js"); 50 require("./components/noosfero/profile-image/profile-image.component.js");
src/app/main/main.component.ts
@@ -7,11 +7,20 @@ import {Profile} from &quot;../profile/profile.component&quot;; @@ -7,11 +7,20 @@ import {Profile} from &quot;../profile/profile.component&quot;;
7 import {Boxes} from "../components/noosfero-boxes/boxes.component"; 7 import {Boxes} from "../components/noosfero-boxes/boxes.component";
8 import {Block} from "../components/noosfero-blocks/block.component"; 8 import {Block} from "../components/noosfero-blocks/block.component";
9 import {LinkListBlock} from "../components/noosfero-blocks/link-list/link-list.component"; 9 import {LinkListBlock} from "../components/noosfero-blocks/link-list/link-list.component";
  10 +import {RecentDocumentsBlock} from "../components/noosfero-blocks/recent-documents/recent-documents.component";
  11 +import {ProfileImageBlock} from "../components/noosfero-blocks/profile-image/profile-image.component";
  12 +import {MembersBlock} from "../components/noosfero-blocks/members-block/members-block.component";
10 13
11 14
12 import {AuthService} from "./../components/auth/auth_service"; 15 import {AuthService} from "./../components/auth/auth_service";
13 import {Session} from "./../components/auth/session"; 16 import {Session} from "./../components/auth/session";
14 17
  18 +
  19 +import {Navbar} from "../components/navbar";
  20 +
  21 +import {MainBlock} from "../components/noosfero-blocks/main-block/main-block.component";
  22 +
  23 +
15 @Component({ 24 @Component({
16 selector: 'main-content', 25 selector: 'main-content',
17 templateUrl: "app/main/main.html", 26 templateUrl: "app/main/main.html",
@@ -24,7 +33,10 @@ export class MainContent { @@ -24,7 +33,10 @@ export class MainContent {
24 @Component({ 33 @Component({
25 selector: 'main', 34 selector: 'main',
26 template: '<div ng-view></div>', 35 template: '<div ng-view></div>',
27 - directives: [NoosferoArticleBlog, ArticleView, Boxes, Block, LinkListBlock], 36 + directives: [
  37 + NoosferoArticleBlog, ArticleView, Boxes, Block, LinkListBlock,
  38 + MainBlock, RecentDocumentsBlock, Navbar, ProfileImageBlock, MembersBlock
  39 + ],
28 providers: [AuthService, Session] 40 providers: [AuthService, Session]
29 }) 41 })
30 @StateConfig([ 42 @StateConfig([
src/lib/ng-noosfero-api/http/article.service.ts 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +import { Injectable, Inject } from "ng-forward";
  2 +
  3 +@Injectable()
  4 +@Inject("Restangular")
  5 +export class ArticleService {
  6 +
  7 + constructor(private Restangular: any) {
  8 +
  9 + }
  10 +
  11 + getByProfile(profileId: number, filters: any) {
  12 + return this.Restangular.service('profiles').one(profileId).one('articles').get(filters);
  13 + }
  14 +
  15 +}
src/lib/ng-noosfero-api/http/profile.service.ts 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +import { Injectable, Inject } from "ng-forward";
  2 +
  3 +@Injectable()
  4 +@Inject("Restangular")
  5 +export class ProfileService {
  6 +
  7 + constructor(private Restangular: any) {
  8 +
  9 + }
  10 +
  11 + getProfileMembers(profileId: number, filters: any) {
  12 + return this.Restangular.service('profiles').one(profileId).customGET("members", filters);
  13 + }
  14 +
  15 +}
@@ -9,6 +9,8 @@ @@ -9,6 +9,8 @@
9 "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c", 9 "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c",
10 "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dd638012d63e069f2c99d06ef4dcc9616a943ee4", 10 "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dd638012d63e069f2c99d06ef4dcc9616a943ee4",
11 "jquery": "github:DefinitelyTyped/DefinitelyTyped/jquery/jquery.d.ts#470954c4f427e0805a2d633636a7c6aa7170def8", 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 "ngstorage": "github:DefinitelyTyped/DefinitelyTyped/ngstorage/ngstorage.d.ts#f59279e1f7535149b4e14d2ccf537b2c81cfff75", 14 "ngstorage": "github:DefinitelyTyped/DefinitelyTyped/ngstorage/ngstorage.d.ts#f59279e1f7535149b4e14d2ccf537b2c81cfff75",
13 "restangular": "github:DefinitelyTyped/DefinitelyTyped/restangular/restangular.d.ts#f2ae460e1751bb6668d291d4eb9255f047dd0ac5" 15 "restangular": "github:DefinitelyTyped/DefinitelyTyped/restangular/restangular.d.ts#f2ae460e1751bb6668d291d4eb9255f047dd0ac5"
14 } 16 }