Commit d14121298f31300970fed97c1216414bbcdb5037

Authored by Victor Costa
2 parents f5a45d92 a3e051be
Exists in master and in 1 other branch dev-fixes

Merge branch 'ngforward' of softwarepublico.gov.br:noosfero-themes/angular-theme into ngforward

Showing 261 changed files with 3984 additions and 3345 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 261 files displayed.

.vscode/settings.json
@@ -3,7 +3,9 @@ @@ -3,7 +3,9 @@
3 "files.exclude": { 3 "files.exclude": {
4 "**/.git": true, 4 "**/.git": true,
5 "**/.DS_Store": true, 5 "**/.DS_Store": true,
6 - "src/app/*.js": false 6 + "src/**/*.js": true,
  7 + "src/**/*.js.map": true,
  8 + "coverage": true
7 }, 9 },
8 "editor.fontSize": 14, 10 "editor.fontSize": 14,
9 "typescript.useCodeSnippetsOnMethodSuggest": true 11 "typescript.useCodeSnippetsOnMethodSuggest": true
dev-scripts/fix-jqlite.ts 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +let replace = require("replace");
  2 +
  3 +import * as path from "path";
  4 +
  5 +let wrong_jqlite_d_ts_file = path.join(__dirname, "../node_modules/ng-forward/cjs/util/jqlite-extensions.d.ts");
  6 +
  7 +replace({
  8 + regex: /import JQuery from \".\/\";/,
  9 + replacement: "",
  10 + paths: [wrong_jqlite_d_ts_file],
  11 + sillent: false
  12 +});
  13 +
@@ -4,21 +4,23 @@ @@ -4,21 +4,23 @@
4 "dependencies": { 4 "dependencies": {
5 "angular": "^1.5.0", 5 "angular": "^1.5.0",
6 "angular-mock": "^1.0.0", 6 "angular-mock": "^1.0.0",
7 - "moment": "^2.11.2" 7 + "moment": "^2.11.2",
  8 + "ng-forward": "0.0.1-alpha.12"
8 }, 9 },
9 "scripts": { 10 "scripts": {
10 "build": "webpack; gulp build", 11 "build": "webpack; gulp build",
11 "webpack": "webpack", 12 "webpack": "webpack",
  13 + "karma": "concurrently \"webpack -w\" \"karma start\"",
12 "docs": "gulp ngdocs; static-server docs", 14 "docs": "gulp ngdocs; static-server docs",
13 - "karma": "karma",  
14 "coverage": "karma start --single-run; npm run remap-coverage", 15 "coverage": "karma start --single-run; npm run remap-coverage",
15 "remap-coverage": "ts-node --project ./dev-scripts ./dev-scripts/remapCoverage.ts", 16 "remap-coverage": "ts-node --project ./dev-scripts ./dev-scripts/remapCoverage.ts",
16 "test-single": "karma start --single-run", 17 "test-single": "karma start --single-run",
17 "test-and-coverage": "karma start & npm run remap-coverage", 18 "test-and-coverage": "karma start & npm run remap-coverage",
18 "test": "webpack -w --test", 19 "test": "webpack -w --test",
19 - "postinstall": "npm install -g bower && bower install && typings install && cd dev-scripts && typings install", 20 + "postinstall": "npm install -g bower; bower install; typings install; npm run fix-jqlite; cd dev-scripts; typings install",
20 "start": "concurrently \"webpack -w\" \"gulp serve\"", 21 "start": "concurrently \"webpack -w\" \"gulp serve\"",
21 - "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts" 22 + "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts",
  23 + "fix-jqlite": "ts-node --project ./dev-scripts dev-scripts/fix-jqlite.ts"
22 }, 24 },
23 "devDependencies": { 25 "devDependencies": {
24 "browser-sync": "~2.9.11", 26 "browser-sync": "~2.9.11",
@@ -71,7 +73,6 @@ @@ -71,7 +73,6 @@
71 "karma-webpack": "^1.7.0", 73 "karma-webpack": "^1.7.0",
72 "lodash": "~3.10.1", 74 "lodash": "~3.10.1",
73 "main-bower-files": "~2.9.0", 75 "main-bower-files": "~2.9.0",
74 - "ng-forward": "0.0.1-alpha.12",  
75 "on-build-webpack": "^0.1.0", 76 "on-build-webpack": "^0.1.0",
76 "phantomjs": "~1.9.18", 77 "phantomjs": "~1.9.18",
77 "phantomjs-polyfill": "0.0.2", 78 "phantomjs-polyfill": "0.0.2",
src/app/admin/index.ts 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
src/app/article/article-default-view-component.spec.ts 0 → 100644
@@ -0,0 +1,108 @@ @@ -0,0 +1,108 @@
  1 +
  2 +import {Input, provide, Component} from 'ng-forward';
  3 +import {ArticleViewComponent, ArticleDefaultViewComponent} from './article-default-view.component';
  4 +
  5 +import {createComponentFromClass, quickCreateComponent} from "../../spec/helpers";
  6 +
  7 +// this htmlTemplate will be re-used between the container components in this spec file
  8 +const htmlTemplate: string = '<noosfero-article [article]="ctrl.article" [profile]="ctrl.profile"></noosfero-article>';
  9 +
  10 +
  11 +describe("Components", () => {
  12 +
  13 + describe("ArticleView Component", () => {
  14 +
  15 + // the karma preprocessor html2js transform the templates html into js files which put
  16 + // the templates to the templateCache into the module templates
  17 + // we need to load the module templates here as the template for the
  18 + // component Noosfero ArtileView will be load on our tests
  19 + beforeEach(angular.mock.module("templates"));
  20 +
  21 + it("renders the default component when no specific component is found", (done: Function) => {
  22 + // Creating a container component (ArticleContainerComponent) to include
  23 + // the component under test (ArticleView)
  24 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleViewComponent] })
  25 + class ArticleContainerComponent {
  26 + article = { type: 'anyArticleType' };
  27 + profile = { name: 'profile-name' };
  28 + constructor() {
  29 + }
  30 + }
  31 +
  32 + createComponentFromClass(ArticleContainerComponent).then((fixture) => {
  33 + // and here we can inspect and run the test assertions
  34 +
  35 + // gets the children component of ArticleContainerComponent
  36 + let articleView: ArticleViewComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  37 +
  38 + // and checks if the article View rendered was the Default Article View
  39 + expect(articleView.constructor.prototype).toEqual(ArticleDefaultViewComponent.prototype);
  40 +
  41 + // done needs to be called (it isn't really needed, as we can read in
  42 + // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync)
  43 + // because createAsync in ng-forward is not really async, but as the intention
  44 + // here is write tests in angular 2 ways, this is recommended
  45 + done();
  46 + });
  47 +
  48 + });
  49 +
  50 + it("receives the article and profile as inputs", (done: Function) => {
  51 +
  52 + // Creating a container component (ArticleContainerComponent) to include
  53 + // the component under test (ArticleView)
  54 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleViewComponent] })
  55 + class ArticleContainerComponent {
  56 + article = { type: 'anyArticleType' };
  57 + profile = { name: 'profile-name' };
  58 + constructor() {
  59 + }
  60 + }
  61 +
  62 + // uses the TestComponentBuilder instance to initialize the component
  63 + createComponentFromClass(ArticleContainerComponent).then((fixture) => {
  64 + // and here we can inspect and run the test assertions
  65 + let articleView: ArticleViewComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  66 +
  67 + // assure the article object inside the ArticleView matches
  68 + // the provided through the parent component
  69 + expect(articleView.article.type).toEqual("anyArticleType");
  70 + expect(articleView.profile.name).toEqual("profile-name");
  71 +
  72 + // done needs to be called (it isn't really needed, as we can read in
  73 + // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync)
  74 + // because createAsync in ng-forward is not really async, but as the intention
  75 + // here is write tests in angular 2 ways, this is recommended
  76 + done();
  77 + });
  78 + });
  79 +
  80 +
  81 + it("renders a article view which matches to the article type", done => {
  82 + // NoosferoTinyMceArticle component created to check if it will be used
  83 + // when a article with type 'TinyMceArticle' is provided to the noosfero-article (ArticleView)
  84 + // *** Important *** - the selector is what ng-forward uses to define the name of the directive provider
  85 + @Component({ selector: 'noosfero-tiny-mce-article', template: "<h1>TinyMceArticle</h1>" })
  86 + class TinyMceArticleView {
  87 + @Input() article: any;
  88 + @Input() profile: any;
  89 + }
  90 +
  91 + // Creating a container component (ArticleContainerComponent) to include our NoosferoTinyMceArticle
  92 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleViewComponent, TinyMceArticleView] })
  93 + class CustomArticleType {
  94 + article = { type: 'TinyMceArticle' };
  95 + profile = { name: 'profile-name' };
  96 + constructor() {
  97 + }
  98 + }
  99 + createComponentFromClass(CustomArticleType).then(fixture => {
  100 + let myComponent: CustomArticleType = fixture.componentInstance;
  101 + expect(myComponent.article.type).toEqual("TinyMceArticle");
  102 + expect(fixture.debugElement.componentViewChildren[0].text()).toEqual("TinyMceArticle");
  103 + done();
  104 + });
  105 + });
  106 +
  107 + });
  108 +});
0 \ No newline at end of file 109 \ No newline at end of file
src/app/article/article-default-view.component.ts 0 → 100644
@@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
  1 +import { bundle, Input, Inject, Component, Directive } from 'ng-forward';
  2 +import {ArticleBlogComponent} from "./types/blog/blog.component";
  3 +
  4 +/**
  5 + * @ngdoc controller
  6 + * @name ArticleDefaultView
  7 + * @description
  8 + * A default view for Noosfero Articles. If the specific article view is
  9 + * not implemented, then this view is used.
  10 + */
  11 +@Component({
  12 + selector: 'noosfero-default-article',
  13 + templateUrl: 'app/article/article.html'
  14 +})
  15 +export class ArticleDefaultViewComponent {
  16 +
  17 + @Input() article: noosfero.Article;
  18 + @Input() profile: noosfero.Profile;
  19 +
  20 +}
  21 +
  22 +/**
  23 + * @ngdoc controller
  24 + * @name ArticleView
  25 + * @description
  26 + * A dynamic view for articles. It uses the article type to replace
  27 + * the default template with the custom article directive.
  28 + */
  29 +@Component({
  30 + selector: 'noosfero-article',
  31 + template: 'not-used',
  32 + directives: [ArticleDefaultViewComponent, ArticleBlogComponent]
  33 +})
  34 +@Inject("$element", "$scope", "$injector", "$compile")
  35 +export class ArticleViewComponent {
  36 +
  37 + @Input() article: noosfero.Article;
  38 + @Input() profile: noosfero.Profile;
  39 + directiveName: string;
  40 +
  41 + ngOnInit() {
  42 + let specificDirective = 'noosfero' + this.article.type;
  43 + this.directiveName = "noosfero-default-article";
  44 + if (this.$injector.has(specificDirective + 'Directive')) {
  45 + this.directiveName = specificDirective.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
  46 + }
  47 + this.$element.replaceWith(this.$compile('<' + this.directiveName + ' [article]="ctrl.article" [profile]="ctrl.profile"></' + this.directiveName + '>')(this.$scope));
  48 + }
  49 +
  50 + constructor(
  51 + private $element: any,
  52 + private $scope: ng.IScope,
  53 + private $injector: ng.auto.IInjectorService,
  54 + private $compile: ng.ICompileService) {
  55 +
  56 + }
  57 +}
src/app/article/article.html 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +<div class="article">
  2 + <div class="page-header">
  3 + <h3 ng-bind="ctrl.article.title"></h3>
  4 + </div>
  5 +
  6 + <div class="sub-header clearfix">
  7 + <div class="page-info pull-right small text-muted">
  8 + <span class="time">
  9 + <i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.article.created_at | dateFormat"></span>
  10 + </span>
  11 + <span class="author" ng-if="ctrl.article.author">
  12 + <i class="fa fa-user"></i>
  13 + <a ui-sref="main.profile.home({profile: ctrl.article.author.identifier})">
  14 + <span class="author-name" ng-bind="ctrl.article.author.name"></span>
  15 + </a>
  16 + </span>
  17 + </div>
  18 + </div>
  19 +
  20 + <div class="page-body">
  21 + <div ng-bind-html="ctrl.article.body"></div>
  22 + </div>
  23 +</div>
src/app/article/article.scss 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +.article {
  2 + .page-info {
  3 + .author {
  4 + a {
  5 + color: #b4bcc2;
  6 + }
  7 + }
  8 + }
  9 +
  10 + .page-header {
  11 + margin-bottom: 5px;
  12 + }
  13 +
  14 + .sub-header {
  15 + margin-bottom: 20px;
  16 + }
  17 +}
src/app/article/basic-editor.component.spec.ts 0 → 100644
@@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
  1 +import {quickCreateComponent} from "../../spec/helpers";
  2 +import {BasicEditorComponent} from "./basic-editor.component";
  3 +
  4 +
  5 +describe("Article BasicEditor", () => {
  6 +
  7 + let $rootScope: ng.IRootScopeService;
  8 + let $q: ng.IQService;
  9 + let articleServiceMock: any;
  10 + let profileServiceMock: any;
  11 + let $state: any;
  12 + let profile = { id: 1 };
  13 + let notification: any;
  14 +
  15 +
  16 + beforeEach(inject((_$rootScope_: ng.IRootScopeService, _$q_: ng.IQService) => {
  17 + $rootScope = _$rootScope_;
  18 + $q = _$q_;
  19 + }));
  20 +
  21 + beforeEach(() => {
  22 + $state = jasmine.createSpyObj("$state", ["transitionTo"]);
  23 + notification = jasmine.createSpyObj("notification", ["success"]);
  24 + profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["getCurrentProfile"]);
  25 + articleServiceMock = jasmine.createSpyObj("articleServiceMock", ["createInProfile"]);
  26 +
  27 + let getCurrentProfileResponse = $q.defer();
  28 + getCurrentProfileResponse.resolve(profile);
  29 +
  30 + let articleCreate = $q.defer();
  31 + articleCreate.resolve({ data: { path: "path", profile: { identifier: "profile" } } });
  32 +
  33 + profileServiceMock.getCurrentProfile = jasmine.createSpy("getCurrentProfile").and.returnValue(getCurrentProfileResponse.promise);
  34 + articleServiceMock.createInProfile = jasmine.createSpy("createInProfile").and.returnValue(articleCreate.promise);
  35 + });
  36 +
  37 + it("create an article in the current profile when save", done => {
  38 + let component: BasicEditorComponent = new BasicEditorComponent(articleServiceMock, profileServiceMock, $state, notification);
  39 + component.save();
  40 + $rootScope.$apply();
  41 + expect(profileServiceMock.getCurrentProfile).toHaveBeenCalled();
  42 + expect(articleServiceMock.createInProfile).toHaveBeenCalledWith(profile, component.article);
  43 + done();
  44 + });
  45 +
  46 + it("got to the new article page and display an alert when saving sucessfully", done => {
  47 + let component: BasicEditorComponent = new BasicEditorComponent(articleServiceMock, profileServiceMock, $state, notification);
  48 + component.save();
  49 + $rootScope.$apply();
  50 + expect($state.transitionTo).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "profile" });
  51 + expect(notification.success).toHaveBeenCalled();
  52 + done();
  53 + });
  54 +
  55 +});
src/app/article/basic-editor.component.ts 0 → 100644
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  1 +import {StateConfig, Component, Inject, provide} from 'ng-forward';
  2 +import {ArticleService} from "../../lib/ng-noosfero-api/http/article.service";
  3 +import {ProfileService} from "../../lib/ng-noosfero-api/http/profile.service";
  4 +import {NotificationService} from "../shared/services/notification.service.ts";
  5 +
  6 +@Component({
  7 + selector: 'article-basic-editor',
  8 + templateUrl: "app/article/basic-editor.html",
  9 + providers: [
  10 + provide('articleService', { useClass: ArticleService }),
  11 + provide('profileService', { useClass: ProfileService }),
  12 + provide('notification', { useClass: NotificationService })
  13 + ]
  14 +})
  15 +@Inject(ArticleService, ProfileService, "$state", NotificationService)
  16 +export class BasicEditorComponent {
  17 +
  18 + article: noosfero.Article = <noosfero.Article>{};
  19 +
  20 + constructor(private articleService: ArticleService,
  21 + private profileService: ProfileService,
  22 + private $state: ng.ui.IStateService,
  23 + private notification: NotificationService) { }
  24 +
  25 + save() {
  26 + this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => {
  27 + return this.articleService.createInProfile(profile, this.article);
  28 + }).then((response: noosfero.RestResult<noosfero.Article>) => {
  29 + let article = (<noosfero.Article>response.data);
  30 + this.$state.transitionTo('main.profile.page', { page: article.path, profile: article.profile.identifier });
  31 + this.notification.success("Good job!", "Article saved!");
  32 + });
  33 + }
  34 +
  35 +}
src/app/article/basic-editor.html 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<form>
  2 + <div class="form-group">
  3 + <label for="titleInput">Title</label>
  4 + <input type="text" class="form-control" id="titleInput" placeholder="title" ng-model="vm.article.name">
  5 + </div>
  6 + <div class="form-group">
  7 + <label for="bodyInput">Text</label>
  8 + <textarea class="form-control" id="bodyInput" rows="10" ng-model="vm.article.body"></textarea>
  9 + </div>
  10 + <button type="submit" class="btn btn-default" ng-click="vm.save()">Save</button>
  11 +</form>
src/app/article/content-viewer/content-viewer-actions.component.spec.ts 0 → 100644
@@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
  1 +import {providers} from 'ng-forward/cjs/testing/providers';
  2 +
  3 +import {Input, Component, provide} from 'ng-forward';
  4 +
  5 +import * as helpers from "../../../spec/helpers";
  6 +
  7 +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
  8 +import {ContentViewerActions} from './content-viewer-actions.component';
  9 +
  10 +// this htmlTemplate will be re-used between the container components in this spec file
  11 +const htmlTemplate: string = '<content-viewer-actions [article]="ctrl.article" [profile]="ctrl.profile"></content-viewer-actions>';
  12 +
  13 +describe('Content Viewer Actions Component', () => {
  14 +
  15 + beforeEach(() => {
  16 +
  17 + angular.mock.module("templates");
  18 +
  19 + providers((provide: any) => {
  20 + return <any>[
  21 + provide('ProfileService', {
  22 + useValue: helpers.mocks.profileService
  23 + })
  24 + ];
  25 + });
  26 + });
  27 +
  28 + let buildComponent = (): Promise<ComponentFixture> => {
  29 + return helpers.quickCreateComponent({
  30 + providers: [
  31 + helpers.provideEmptyObjects('Restangular'),
  32 + helpers.provideFilters('translateFilter')
  33 + ],
  34 + directives: [ContentViewerActions],
  35 + template: htmlTemplate
  36 + });
  37 + };
  38 +
  39 + it('renders content viewer actions directive', (done: Function) => {
  40 + buildComponent().then((fixture: ComponentFixture) => {
  41 + expect(fixture.debugElement.query('content-viewer-actions').length).toEqual(1);
  42 +
  43 + done();
  44 + });
  45 + });
  46 +
  47 + it('check if profile was loaded', (done: Function) => {
  48 + let profile: any = {
  49 + id: 1,
  50 + identifier: 'the-profile-test',
  51 + type: 'Person'
  52 + };
  53 +
  54 + helpers.mocks.profileService.getCurrentProfile = () => {
  55 + return helpers.mocks.promiseResultTemplate(profile);
  56 + };
  57 +
  58 + buildComponent().then((fixture: ComponentFixture) => {
  59 + let contentViewerComp: ContentViewerActions = fixture.debugElement.componentViewChildren[0].componentInstance;
  60 +
  61 + expect(contentViewerComp.profile).toEqual(jasmine.objectContaining(profile));
  62 +
  63 + done();
  64 + });
  65 + });
  66 +
  67 +});
src/app/article/content-viewer/content-viewer-actions.component.ts 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +import {Component, Inject, provide} from "ng-forward";
  2 +import {ProfileService} from "../../../lib/ng-noosfero-api/http/profile.service";
  3 +
  4 +@Component({
  5 + selector: "content-viewer-actions",
  6 + templateUrl: "app/article/content-viewer/navbar-actions.html",
  7 + providers: [provide('profileService', { useClass: ProfileService })]
  8 +})
  9 +@Inject(ProfileService)
  10 +export class ContentViewerActions {
  11 +
  12 + article: noosfero.Article;
  13 + profile: noosfero.Profile;
  14 +
  15 + constructor(profileService: ProfileService) {
  16 + profileService.getCurrentProfile().then((profile: noosfero.Profile) => {
  17 + this.profile = profile;
  18 + });
  19 + }
  20 +}
src/app/article/content-viewer/content-viewer.component.spec.ts 0 → 100644
@@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
  1 +import {providers} from 'ng-forward/cjs/testing/providers';
  2 +
  3 +import {Input, Component, provide} from 'ng-forward';
  4 +
  5 +import * as helpers from "../../../spec/helpers";
  6 +
  7 +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
  8 +import {ContentViewerComponent} from './content-viewer.component';
  9 +
  10 +// this htmlTemplate will be re-used between the container components in this spec file
  11 +const htmlTemplate: string = '<content-viewer [article]="ctrl.article" [profile]="ctrl.profile"></content-viewer>';
  12 +
  13 +describe('Content Viewer Component', () => {
  14 +
  15 + let stateParamsService: any;
  16 +
  17 + // loading the templates
  18 + beforeEach(() => {
  19 + angular.mock.module("templates");
  20 +
  21 + stateParamsService = { page: 1 };
  22 +
  23 + providers((provide: any) => {
  24 + return <any>[
  25 + provide('ArticleService', {
  26 + useValue: helpers.mocks.articleService
  27 + }),
  28 + provide('ProfileService', {
  29 + useValue: helpers.mocks.profileService
  30 + }),
  31 + // TODO: Como criar um mock do atributo "page" de stateParams
  32 + provide('$stateParams', {
  33 + useValue: stateParamsService
  34 + })
  35 + ];
  36 + });
  37 + });
  38 +
  39 + let buildComponent = (): Promise<ComponentFixture> => {
  40 + return helpers.quickCreateComponent({
  41 + providers: [
  42 + helpers.provideEmptyObjects('Restangular')
  43 + ],
  44 + directives: [ContentViewerComponent],
  45 + template: htmlTemplate
  46 + });
  47 + };
  48 +
  49 + it('renders content viewer directive', (done: Function) => {
  50 + buildComponent().then((fixture: ComponentFixture) => {
  51 + expect(fixture.debugElement.query('content-viewer').length).toEqual(1);
  52 +
  53 + done();
  54 + });
  55 + });
  56 +
  57 + it('check if article was loaded', (done: Function) => {
  58 + let article: any = {
  59 + id: 1,
  60 + title: 'The article test'
  61 + };
  62 + let profile: any = {
  63 + id: 1,
  64 + identifier: 'the-profile-test',
  65 + type: 'Person'
  66 + };
  67 +
  68 + helpers.mocks.profileService.getCurrentProfile = () => {
  69 + return helpers.mocks.promiseResultTemplate(profile);
  70 + };
  71 +
  72 + helpers.mocks.articleService.getArticleByProfileAndPath = (profile: noosfero.Profile, path: string) => {
  73 + return helpers.mocks.promiseResultTemplate({
  74 + data: article
  75 + });
  76 + };
  77 +
  78 +
  79 + buildComponent().then((fixture: ComponentFixture) => {
  80 + let contentViewerComp: ContentViewerComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  81 +
  82 + expect(contentViewerComp.profile).toEqual(profile);
  83 + expect(contentViewerComp.article).toEqual(article);
  84 +
  85 + done();
  86 + });
  87 + });
  88 +});
src/app/article/content-viewer/content-viewer.component.ts 0 → 100644
@@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
  1 +import {ArticleViewComponent} from "./../article-default-view.component";
  2 +import {Input, Component, StateConfig, Inject, provide} from "ng-forward";
  3 +
  4 +import {ArticleBlogComponent} from "./../types/blog/blog.component";
  5 +import {ArticleService} from "../../../lib/ng-noosfero-api/http/article.service";
  6 +import {ProfileService} from "../../../lib/ng-noosfero-api/http/profile.service";
  7 +
  8 +@Component({
  9 + selector: "content-viewer",
  10 + templateUrl: "app/article/content-viewer/page.html",
  11 + directives: [ArticleBlogComponent, ArticleViewComponent],
  12 + providers: [
  13 + provide('articleService', { useClass: ArticleService }),
  14 + provide('profileService', { useClass: ProfileService })
  15 + ]
  16 +})
  17 +@Inject(ArticleService, ProfileService, "$log", "$stateParams")
  18 +export class ContentViewerComponent {
  19 +
  20 + @Input()
  21 + article: noosfero.Article = null;
  22 +
  23 + @Input()
  24 + profile: noosfero.Profile = null;
  25 +
  26 + constructor(private articleService: ArticleService, private profileService: ProfileService, private $log: ng.ILogService, private $stateParams: angular.ui.IStateParamsService) {
  27 + this.activate();
  28 + }
  29 +
  30 + activate() {
  31 + this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => {
  32 + this.profile = profile;
  33 + return this.articleService.getArticleByProfileAndPath(this.profile, this.$stateParams["page"]);
  34 + }).then((result: noosfero.RestResult<any>) => {
  35 + this.article = <noosfero.Article>result.data;
  36 + });
  37 + }
  38 +}
src/app/article/content-viewer/index.ts 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./content-viewer-actions.component";
  3 +export * from "./content-viewer.component";
src/app/article/content-viewer/navbar-actions.html 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +<ul class="nav navbar-nav">
  2 + <li ng-show="vm.profile">
  3 + <a href="#" role="button" ui-sref="main.profile.cms({profile: vm.profile.identifier})">
  4 + <i class="fa fa-file fa-fw fa-lg"></i> {{"navbar.content_viewer_actions.new_post" | translate}}
  5 + </a>
  6 + </li>
  7 +</ul>
src/app/article/content-viewer/page.html 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<noosfero-article ng-if="vm.article" [article]="vm.article" [profile]="vm.profile"></noosfero-article>
src/app/article/index.ts 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./article-default-view.component";
  3 +export * from "./basic-editor.component";
src/app/article/types/blog/blog.component.spec.ts 0 → 100644
@@ -0,0 +1,129 @@ @@ -0,0 +1,129 @@
  1 +import {
  2 +providers
  3 +} from 'ng-forward/cjs/testing/providers';
  4 +
  5 +import {
  6 +Input,
  7 +Component
  8 +} from 'ng-forward';
  9 +import {
  10 +ArticleBlogComponent
  11 +} from './blog.component';
  12 +
  13 +import {
  14 +createComponentFromClass,
  15 +quickCreateComponent,
  16 +provideEmptyObjects,
  17 +createProviderToValue,
  18 +provideFilters
  19 +} from "../../../../spec/helpers.ts";
  20 +
  21 +// this htmlTemplate will be re-used between the container components in this spec file
  22 +const htmlTemplate: string = '<noosfero-blog [article]="ctrl.article" [profile]="ctrl.profile"></noosfero-blog>';
  23 +
  24 +describe("Blog Component", () => {
  25 +
  26 + function promiseResultTemplate(response?: {}) {
  27 + let thenFuncEmpty = (func: Function) => {
  28 + // does nothing
  29 + };
  30 + if (response) {
  31 + return {
  32 + then: (func: (response: any) => void) => {
  33 + func(response);
  34 + }
  35 + };
  36 + } else {
  37 + return {
  38 + then: (func: (response: any) => void) => {
  39 + // does nothing
  40 + }
  41 + };
  42 + }
  43 + }
  44 +
  45 + let articleService = {
  46 + getChildren: (article_id: number, filters: {}) => {
  47 + return promiseResultTemplate(null);
  48 + }
  49 + };
  50 +
  51 + @Component({
  52 + selector: 'test-container-component',
  53 + template: htmlTemplate,
  54 + directives: [ArticleBlogComponent],
  55 + providers: [
  56 + provideEmptyObjects('Restangular'),
  57 + createProviderToValue('ArticleService', articleService),
  58 + provideFilters('truncateFilter')
  59 + ]
  60 + })
  61 + class BlogContainerComponent {
  62 + article = {
  63 + type: 'anyArticleType'
  64 + };
  65 + profile = {
  66 + name: 'profile-name'
  67 + };
  68 + }
  69 +
  70 + beforeEach(() => {
  71 +
  72 + // the karma preprocessor html2js transform the templates html into js files which put
  73 + // the templates to the templateCache into the module templates
  74 + // we need to load the module templates here as the template for the
  75 + // component Noosfero ArtileView will be load on our tests
  76 + angular.mock.module("templates");
  77 +
  78 + providers((provide: any) => {
  79 + return <any>[
  80 + provide('ArticleService', {
  81 + useValue: articleService
  82 + })
  83 + ];
  84 + });
  85 + });
  86 +
  87 + it("renders the blog content", (done: Function) => {
  88 +
  89 + createComponentFromClass(BlogContainerComponent).then((fixture) => {
  90 +
  91 + expect(fixture.debugElement.query('div.blog').length).toEqual(1);
  92 +
  93 + done();
  94 + });
  95 + });
  96 +
  97 + it("verify the blog data", (done: Function) => {
  98 +
  99 + let articles = [{
  100 + id: 1,
  101 + title: 'The article test'
  102 + }];
  103 +
  104 + let result = { data: articles, headers: (name: string) => { return 1; } };
  105 +
  106 + // defining a mock result to articleService.getChildren method
  107 + articleService.getChildren = (article_id: number, filters: {}) => {
  108 + return promiseResultTemplate(result);
  109 + };
  110 +
  111 + createComponentFromClass(BlogContainerComponent).then((fixture) => {
  112 +
  113 + // gets the children component of BlogContainerComponent
  114 + let articleBlog: BlogContainerComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  115 +
  116 + // check if the component property are the provided by the mocked articleService
  117 + let post = {
  118 + id: 1,
  119 + title: 'The article test'
  120 + };
  121 + expect((<any>articleBlog)["posts"][0]).toEqual(jasmine.objectContaining(post));
  122 + expect((<any>articleBlog)["totalPosts"]).toEqual(1);
  123 +
  124 + done();
  125 + });
  126 +
  127 + });
  128 +
  129 +});
0 \ No newline at end of file 130 \ No newline at end of file
src/app/article/types/blog/blog.component.ts 0 → 100644
@@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
  1 +import {Component, Input, Inject} from "ng-forward";
  2 +
  3 +import {ArticleService} from "../../../../lib/ng-noosfero-api/http/article.service";
  4 +
  5 +/**
  6 + * @ngdoc controller
  7 + * @name ArticleBlog
  8 + * @description
  9 + * An specific {@link ArticleView} for Blog articles.
  10 + */
  11 +@Component({
  12 + selector: "noosfero-blog",
  13 + templateUrl: "app/article/types/blog/blog.html"
  14 +})
  15 +@Inject(ArticleService)
  16 +export class ArticleBlogComponent {
  17 +
  18 + @Input() article: noosfero.Article;
  19 + @Input() profile: noosfero.Profile;
  20 +
  21 + private posts: noosfero.Article[];
  22 + private perPage: number = 3;
  23 + private currentPage: number;
  24 + private totalPosts: number = 0;
  25 +
  26 + constructor(private articleService: ArticleService) { }
  27 +
  28 + ngOnInit() {
  29 + this.loadPage();
  30 + }
  31 +
  32 + loadPage() {
  33 + let filters = {
  34 + content_type: "TinyMceArticle",
  35 + per_page: this.perPage,
  36 + page: this.currentPage
  37 + };
  38 +
  39 + this.articleService
  40 + .getChildren(this.article, filters)
  41 + .then((result: noosfero.RestResult<noosfero.Article[]>) => {
  42 + this.totalPosts = <number>result.headers("total");
  43 + this.posts = result.data;
  44 + });
  45 + }
  46 +
  47 +}
src/app/article/types/blog/blog.html 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +<div class="blog">
  2 + <div class="blog-cover" ng-show="ctrl.article.image">
  3 + <img ng-src="{{ctrl.article.image.url}}" class="img-responsive">
  4 + <h3 ng-bind="ctrl.article.title"></h3>
  5 + </div>
  6 +
  7 + <div class="page-header" ng-show="!ctrl.article.image">
  8 + <h3 ng-bind="ctrl.article.title"></h3>
  9 + </div>
  10 +
  11 + <div>
  12 + <div ng-repeat="child in ctrl.posts | orderBy: 'created_at':true">
  13 + <div class="page-header">
  14 + <a class="title" ui-sref="main.profile.page({profile: ctrl.profile.identifier, page: child.path})"><h4 ng-bind="child.title"></h4></a>
  15 + <div class="post-lead" ng-bind-html="child.body | truncate: 500: '...': true"></div>
  16 + </div>
  17 + </div>
  18 + </div>
  19 +
  20 + <pagination ng-model="ctrl.currentPage" total-items="ctrl.totalPosts" class="pagination-sm center-block"
  21 + boundary-links="true" items-per-page="ctrl.perPage" ng-change="ctrl.loadPage()"
  22 + first-text="«" last-text="»" previous-text="‹" next-text="›">
  23 + </pagination>
  24 +</div>
src/app/article/types/blog/blog.scss 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +.blog {
  2 + .blog-cover {
  3 + margin: -15px;
  4 + position: relative;
  5 + h3 {
  6 + position: absolute;
  7 + bottom: 0;
  8 + background-color: rgba(0, 0, 0, 0.4);
  9 + color: white;
  10 + padding: 10px 15px;
  11 + margin: 0;
  12 + width: 100%;
  13 + }
  14 + }
  15 +}
src/app/article/types/blog/index.ts 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./blog.component";
src/app/article/types/index.ts 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
src/app/cms/cms.component.spec.ts
@@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
1 -import {quickCreateComponent} from "../../spec/helpers";  
2 -import {Cms} from "./cms.component";  
3 -  
4 -describe("Components", () => {  
5 - describe("Cms Component", () => {  
6 -  
7 - let $rootScope: ng.IRootScopeService;  
8 - let $q: ng.IQService;  
9 - let articleServiceMock: any;  
10 - let profileServiceMock: any;  
11 - let $state: any;  
12 - let notification: any;  
13 -  
14 - beforeEach(inject((_$rootScope_: ng.IRootScopeService, _$q_: ng.IQService) => {  
15 - $rootScope = _$rootScope_;  
16 - $q = _$q_;  
17 - }));  
18 -  
19 - beforeEach(() => {  
20 - $state = jasmine.createSpyObj("$state", ["transitionTo"]);  
21 - notification = jasmine.createSpyObj("notification", ["success"]);  
22 - profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["getCurrentProfile"]);  
23 - articleServiceMock = jasmine.createSpyObj("articleServiceMock", ["create"]);  
24 -  
25 - let getCurrentProfileResponse = $q.defer();  
26 - getCurrentProfileResponse.resolve({ id: 1 });  
27 -  
28 - let articleCreate = $q.defer();  
29 - articleCreate.resolve({ data: { article: { path: "path", profile: { identifier: "profile" } } } });  
30 -  
31 - profileServiceMock.getCurrentProfile = jasmine.createSpy("getCurrentProfile").and.returnValue(getCurrentProfileResponse.promise);  
32 - articleServiceMock.create = jasmine.createSpy("create").and.returnValue(articleCreate.promise);  
33 - });  
34 -  
35 - it("create an article in the current profile when save", done => {  
36 - let component: Cms = new Cms(articleServiceMock, profileServiceMock, $state, notification);  
37 - component.save();  
38 - $rootScope.$apply();  
39 - expect(profileServiceMock.getCurrentProfile).toHaveBeenCalled();  
40 - expect(articleServiceMock.create).toHaveBeenCalledWith(1, component.article);  
41 - done();  
42 - });  
43 -  
44 - it("got to the new article page and display an alert when saving sucessfully", done => {  
45 - let component: Cms = new Cms(articleServiceMock, profileServiceMock, $state, notification);  
46 - component.save();  
47 - $rootScope.$apply();  
48 - expect($state.transitionTo).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "profile" });  
49 - expect(notification.success).toHaveBeenCalled();  
50 - done();  
51 - });  
52 -  
53 - });  
54 -});  
src/app/cms/cms.component.ts
@@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
1 -import {StateConfig, Component, Inject, provide} from 'ng-forward';  
2 -import {Profile} from "./../models/interfaces";  
3 -import {ArticleService} from "../../lib/ng-noosfero-api/http/article.service";  
4 -import {ProfileService} from "../../lib/ng-noosfero-api/http/profile.service";  
5 -import {Notification} from "../components/notification/notification.component";  
6 -  
7 -@Component({  
8 - selector: 'cms',  
9 - templateUrl: "app/cms/cms.html",  
10 - providers: [  
11 - provide('articleService', { useClass: ArticleService }),  
12 - provide('profileService', { useClass: ProfileService }),  
13 - provide('notification', { useClass: Notification })  
14 - ]  
15 -})  
16 -@Inject(ArticleService, ProfileService, "$state", Notification)  
17 -export class Cms {  
18 -  
19 - article: any = {};  
20 -  
21 - constructor(private articleService: ArticleService,  
22 - private profileService: ProfileService,  
23 - private $state: ng.ui.IStateService,  
24 - private notification: Notification) { }  
25 -  
26 - save() {  
27 - this.profileService.getCurrentProfile().then((profile: Profile) => {  
28 - return this.articleService.create(profile.id, this.article);  
29 - }).then((response: restangular.IResponse) => {  
30 - this.$state.transitionTo('main.profile.page', { page: response.data.article.path, profile: response.data.article.profile.identifier });  
31 - this.notification.success("Good job!", "Article saved!");  
32 - });  
33 - }  
34 -  
35 -}  
src/app/cms/cms.html
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -<form>  
2 - <div class="form-group">  
3 - <label for="titleInput">Title</label>  
4 - <input type="text" class="form-control" id="titleInput" placeholder="title" ng-model="vm.article.name">  
5 - </div>  
6 - <div class="form-group">  
7 - <label for="bodyInput">Text</label>  
8 - <textarea class="form-control" id="bodyInput" rows="10" ng-model="vm.article.body"></textarea>  
9 - </div>  
10 - <button type="submit" class="btn btn-default" ng-click="vm.save()">Save</button>  
11 -</form>  
src/app/cms/index.ts
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
2 -export * from "./cms.component";  
src/app/components/auth/auth_controller.spec.ts
@@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
1 -import {AuthController} from "./auth_controller";  
2 -import {AuthService} from "./auth_service";  
3 -  
4 -describe("Controllers", () => {  
5 -  
6 -  
7 - describe("AuthController", () => {  
8 -  
9 - it("calls authenticate on AuthService when login called", () => {  
10 -  
11 - // creating a Mock AuthService  
12 - let AuthServiceMock: AuthService = jasmine.createSpyObj("AuthService", ["login"]);  
13 -  
14 - // pass AuthServiceMock into the constructor  
15 - let authController = new AuthController(null, null, AuthServiceMock);  
16 -  
17 - // setup of authController -> set the credentials instance property  
18 - let credentials = { username: "username", password: "password" };  
19 -  
20 - authController.credentials = credentials;  
21 -  
22 - // calls the authController login method  
23 - authController.login();  
24 -  
25 - // checks if the method login of the injected AuthService has been called  
26 - expect(AuthServiceMock.login).toHaveBeenCalledWith(credentials);  
27 -  
28 - });  
29 -  
30 -  
31 -  
32 - });  
33 -});  
src/app/components/auth/auth_controller.ts
@@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
1 -import {Credentials} from "./../../models/interfaces";  
2 -import {AuthService} from "./auth_service";  
3 -  
4 -export class AuthController {  
5 -  
6 - static $inject = ["$log", "$stateParams", "AuthService"];  
7 -  
8 - constructor(  
9 - private $log: ng.ILogService,  
10 - private $stateParams: any,  
11 - private AuthService: AuthService  
12 - ) {  
13 -  
14 - }  
15 -  
16 - credentials: Credentials;  
17 -  
18 - login() {  
19 - this.AuthService.login(this.credentials);  
20 - }  
21 -}  
src/app/components/auth/auth_events.ts
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -export interface IAuthEvents {  
2 - loginSuccess: string;  
3 - loginFailed: string;  
4 - logoutSuccess: string;  
5 -}  
6 -  
7 -export const AUTH_EVENTS: IAuthEvents = {  
8 - loginSuccess: "auth-login-success",  
9 - loginFailed: "auth-login-failed",  
10 - logoutSuccess: "auth-logout-success"  
11 -};  
12 \ No newline at end of file 0 \ No newline at end of file
src/app/components/auth/auth_service.spec.ts
@@ -1,82 +0,0 @@ @@ -1,82 +0,0 @@
1 -  
2 -  
3 -import {AuthService, AUTH_EVENTS} from "./";  
4 -import {User, Credentials} from "./../../models/interfaces";  
5 -  
6 -describe("Services", () => {  
7 -  
8 -  
9 - describe("Auth Service", () => {  
10 -  
11 - let $httpBackend: ng.IHttpBackendService;  
12 - let authService: AuthService;  
13 - let credentials: Credentials;  
14 - let $rootScope: ng.IRootScopeService;  
15 - let user: User;  
16 -  
17 - beforeEach(angular.mock.module("noosferoApp", ($translateProvider: angular.translate.ITranslateProvider) => {  
18 - $translateProvider.translations('en', {});  
19 - }));  
20 -  
21 - beforeEach(inject((_$httpBackend_: ng.IHttpBackendService, _$rootScope_: ng.IRootScopeService, _AuthService_: AuthService) => {  
22 - $httpBackend = _$httpBackend_;  
23 - authService = _AuthService_;  
24 - $rootScope = _$rootScope_;  
25 -  
26 - user = <User>{  
27 - id: 1,  
28 - login: "user"  
29 - };  
30 - }));  
31 -  
32 -  
33 - describe("Succesffull login", () => {  
34 -  
35 - beforeEach(() => {  
36 - credentials = { username: "user", password: "password" };  
37 -  
38 - $httpBackend.expectPOST("/api/v1/login", "login=user&password=password").respond(200, { user: user });  
39 - });  
40 -  
41 - it("should return loggedUser", (done) => {  
42 - authService.login(credentials).then((loggedUser) => {  
43 - expect(loggedUser).toBeDefined();  
44 - done();  
45 - });  
46 - $httpBackend.flush();  
47 - expect($httpBackend.verifyNoOutstandingRequest());  
48 - });  
49 -  
50 -  
51 - it("should emit event loggin successful with user logged data", () => {  
52 -  
53 - authService.login(credentials);  
54 -  
55 - let eventEmmited: boolean = false;  
56 - $rootScope.$on(AUTH_EVENTS.loginSuccess, (event: ng.IAngularEvent, userThroughEvent: User) => {  
57 - eventEmmited = true;  
58 - expect(userThroughEvent).toEqual(user)  
59 - });  
60 -  
61 - $httpBackend.flush();  
62 -  
63 - expect(eventEmmited).toBeTruthy(AUTH_EVENTS.loginSuccess + " was not emmited!");  
64 - });  
65 -  
66 - it("should return the current logged in user", () => {  
67 - authService.login(credentials);  
68 - $httpBackend.flush();  
69 - let actual: User = authService.currentUser();  
70 - expect(actual).toEqual(user, "The returned user must be present");  
71 - });  
72 -  
73 - it("should not return the current user after logout", () => {  
74 - authService.logout();  
75 - let actual: any = authService.currentUser();  
76 - expect(actual).toEqual(undefined, "The returned user must not be defined");  
77 - });  
78 - });  
79 -  
80 -  
81 - });  
82 -});  
src/app/components/auth/auth_service.ts
@@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
1 -import {Injectable, Inject} from "ng-forward";  
2 -  
3 -import {Credentials, NoosferoRootScope, User, UserResponse} from "./../../models/interfaces";  
4 -import {Session} from "./session";  
5 -  
6 -import {AUTH_EVENTS, IAuthEvents} from "./auth_events";  
7 -  
8 -@Injectable()  
9 -@Inject("$q", "$http", "$rootScope", "Session", "$log", "AUTH_EVENTS")  
10 -export class AuthService {  
11 -  
12 - constructor(private $q: ng.IQService,  
13 - private $http: ng.IHttpService,  
14 - private $rootScope: NoosferoRootScope,  
15 - private session: Session,  
16 - private $log: ng.ILogService,  
17 - private auth_events: IAuthEvents) {  
18 -  
19 - }  
20 -  
21 - loginFromCookie() {  
22 - let url: string = '/api/v1/login_from_cookie';  
23 - return this.$http.post(url, null).then(this.loginSuccessCallback.bind(this), this.loginFailedCallback.bind(this));  
24 - }  
25 -  
26 -  
27 - private loginSuccessCallback(response: ng.IHttpPromiseCallbackArg<UserResponse>) {  
28 - this.$log.debug('AuthService.login [SUCCESS] response', response);  
29 - let currentUser: User = this.session.create(response.data);  
30 - this.$rootScope.currentUser = currentUser;  
31 - this.$rootScope.$broadcast(this.auth_events.loginSuccess, currentUser);  
32 - return currentUser;  
33 - }  
34 -  
35 - login(credentials: Credentials): ng.IPromise<User> {  
36 - let url = '/api/v1/login';  
37 - let encodedData = 'login=' + credentials.username + '&password=' + credentials.password;  
38 - return this.$http.post(url, encodedData).then(this.loginSuccessCallback.bind(this), this.loginFailedCallback.bind(this));  
39 - }  
40 -  
41 - private loginFailedCallback(response: ng.IHttpPromiseCallbackArg<any>): any {  
42 - this.$log.debug('AuthService.login [FAIL] response', response);  
43 - this.$rootScope.$broadcast(this.auth_events.loginFailed);  
44 - // return $q.reject(response);  
45 - return null;  
46 - }  
47 -  
48 - public logout() {  
49 - this.session.destroy();  
50 - this.$rootScope.currentUser = undefined;  
51 - this.$rootScope.$broadcast(this.auth_events.logoutSuccess);  
52 - this.$http.jsonp('/account/logout'); // FIXME logout from noosfero to sync login state  
53 - }  
54 -  
55 - public isAuthenticated() {  
56 - return !!this.session.currentUser();  
57 - }  
58 -  
59 - public currentUser(): User {  
60 - return this.session.currentUser();  
61 - }  
62 -  
63 - public isAuthorized(authorizedRoles: string | string[]) {  
64 - if (!angular.isArray(authorizedRoles)) {  
65 - authorizedRoles = [<string>authorizedRoles];  
66 - }  
67 - return (this.isAuthenticated() && authorizedRoles.indexOf(this.session.currentUser().userRole) !== -1);  
68 - }  
69 -}  
70 \ No newline at end of file 0 \ No newline at end of file
src/app/components/auth/index.ts
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
2 -export * from "./auth_controller";  
3 -export * from "./auth_events";  
4 -export * from "./auth_service";  
5 -export * from "./session";  
src/app/components/auth/login.html
@@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
1 -<div class="modal-header">  
2 - <h3 class="modal-title">{{"auth.title" | translate}}</h3>  
3 -</div>  
4 -<div class="modal-body">  
5 - <form>  
6 - <div class="form-group">  
7 - <label for="exampleInputEmail1">{{"auth.form.login" | translate}}</label>  
8 - <input type="text" class="form-control" id="exampleInputEmail1" placeholder="Login / Email" ng-model="vm.credentials.username">  
9 - </div>  
10 - <div class="form-group">  
11 - <label for="exampleInputPassword1">{{"auth.form.password" | translate}}</label>  
12 - <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password" ng-model="vm.credentials.password">  
13 - </div>  
14 - <button type="submit" class="btn btn-default" ng-click="vm.login()">{{"auth.form.login_button" | translate}}</button>  
15 - </form>  
16 -</div>  
src/app/components/auth/session.ts
@@ -1,27 +0,0 @@ @@ -1,27 +0,0 @@
1 -import {Injectable, Inject} from "ng-forward";  
2 -import {UserResponse, User, INoosferoLocalStorage} from "./../../models/interfaces";  
3 -  
4 -@Injectable()  
5 -@Inject("$localStorage", "$log")  
6 -export class Session {  
7 -  
8 - constructor(private $localStorage: INoosferoLocalStorage, private $log: ng.ILogService) {  
9 -  
10 - }  
11 -  
12 - create(data: UserResponse): User {  
13 - this.$localStorage.currentUser = data.user;  
14 - this.$log.debug('User session created.', this.$localStorage.currentUser);  
15 - return this.$localStorage.currentUser;  
16 - };  
17 -  
18 - destroy() {  
19 - delete this.$localStorage.currentUser;  
20 - this.$log.debug('User session destroyed.');  
21 - };  
22 -  
23 - currentUser(): User {  
24 - return this.$localStorage.currentUser;  
25 - };  
26 -  
27 -}  
28 \ No newline at end of file 0 \ No newline at end of file
src/app/components/auth/session_spec.ts
@@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
1 -import {Component} from "ng-forward";  
2 -import {Session} from "./";  
3 -import {fixtures, createComponentFromClass, createProviderToValue} from "./../../../spec/helpers";  
4 -import {UserResponse, User, INoosferoLocalStorage} from "./../../models/interfaces";  
5 -  
6 -  
7 -describe("Services", () => {  
8 -  
9 -  
10 - describe("Session Service", () => {  
11 -  
12 - let $localStorage: INoosferoLocalStorage = null;  
13 - let $log: any;  
14 -  
15 - beforeEach(() => {  
16 - $localStorage = <INoosferoLocalStorage>{ currentUser: null };  
17 - $log = jasmine.createSpyObj('$log', ['debug']);  
18 - });  
19 -  
20 - it("method 'create()' saves the current user on $localstorage service", () => {  
21 - let session = new Session($localStorage, $log);  
22 - let userResponse = <UserResponse>{  
23 - user: fixtures.user  
24 - };  
25 - session.create(userResponse);  
26 - expect($localStorage.currentUser).toEqual(userResponse.user);  
27 - });  
28 -  
29 - it("method 'destroy()' clean the currentUser on $localstorage", () => {  
30 - let session = new Session($localStorage, $log);  
31 - let userResponse = <UserResponse>{  
32 - user: fixtures.user  
33 - };  
34 - $localStorage.currentUser = fixtures.user;  
35 - session.destroy();  
36 - expect($localStorage.currentUser).toBeUndefined();  
37 - });  
38 -  
39 - it("method 'currentUser()' returns the user recorded on $localstorage service", () => {  
40 - let session = new Session($localStorage, $log);  
41 - let userResponse = <UserResponse>{  
42 - user: fixtures.user  
43 - };  
44 - $localStorage.currentUser = fixtures.user;  
45 - expect(session.currentUser()).toEqual($localStorage.currentUser);  
46 - });  
47 - });  
48 -  
49 -});  
50 \ No newline at end of file 0 \ No newline at end of file
src/app/components/index.ts
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
src/app/components/language-selector/language-selector.component.spec.ts
@@ -1,46 +0,0 @@ @@ -1,46 +0,0 @@
1 -import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';  
2 -import {provide} from 'ng-forward';  
3 -  
4 -import {LanguageSelector} from './language-selector.component';  
5 -  
6 -import * as helpers from "../../../spec/helpers";  
7 -  
8 -describe("Components", () => {  
9 -  
10 - describe("Language Selector Component", () => {  
11 -  
12 - beforeEach(angular.mock.module("templates"));  
13 -  
14 - let translatorService: any;  
15 -  
16 - let buildComponent = (): Promise<ComponentFixture> => {  
17 - translatorService = jasmine.createSpyObj("translatorService", ["availableLanguages", "currentLanguage"])  
18 - return helpers.quickCreateComponent({  
19 - template: "<language-selector></language-selector>",  
20 - directives: [LanguageSelector],  
21 - providers: [  
22 - provide('TranslatorService', {  
23 - useValue: translatorService  
24 - })  
25 - ].concat(helpers.provideFilters("translateFilter"))  
26 - });  
27 - }  
28 -  
29 - it("display language options", (done) => {  
30 - buildComponent().then(fixture => {  
31 - fixture.debugElement.getLocal("$rootScope").$apply();  
32 - expect(fixture.debugElement.queryAll('li.language').length).toEqual(2);  
33 - done();  
34 - });  
35 - });  
36 -  
37 - it("call the translator service when change the language", (done) => {  
38 - let translatorService = jasmine.createSpyObj("translatorService", ["changeLanguage"]);  
39 - let languageSelector = new LanguageSelector(<any>translatorService);  
40 - languageSelector.changeLanguage("en");  
41 - expect(translatorService.changeLanguage).toHaveBeenCalledWith("en");  
42 - done();  
43 - });  
44 -  
45 - });  
46 -});  
src/app/components/language-selector/language-selector.component.ts
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -import {Component, Inject} from "ng-forward";  
2 -import {TranslatorService} from "../translator/translator.service";  
3 -  
4 -@Component({  
5 - selector: "language-selector",  
6 - templateUrl: "app/components/language-selector/language-selector.html"  
7 -})  
8 -@Inject(TranslatorService)  
9 -export class LanguageSelector {  
10 -  
11 - constructor(private translatorService: TranslatorService) { }  
12 -  
13 - currentLanguage() {  
14 - return this.translatorService.currentLanguage();  
15 - }  
16 -  
17 - changeLanguage(language: string) {  
18 - this.translatorService.changeLanguage(language);  
19 - }  
20 -  
21 - availableLanguages() {  
22 - return this.translatorService.availableLanguages;  
23 - }  
24 -}  
src/app/components/language-selector/language-selector.html
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -<li class="dropdown profile-menu" dropdown>  
2 - <a href="#" class="dropdown-toggle" aria-expanded="false" dropdown-toggle>  
3 - <span>{{"language.selector" | translate}}</span> <b class="caret"></b>  
4 - </a>  
5 - <ul class="dropdown-menu" dropdown-menu>  
6 - <li ng-repeat="(language, description) in ctrl.availableLanguages()"  
7 - class="language language-{{language}}" ng-class="{'active': language==ctrl.currentLanguage()}">  
8 - <a href="#" ng-click="ctrl.changeLanguage(language)">  
9 - {{description}}  
10 - </a>  
11 - </li>  
12 - </ul>  
13 -</li>  
src/app/components/navbar/index.ts
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
2 -export * from "./navbar";  
src/app/components/navbar/navbar.directive.spec.js
@@ -1,45 +0,0 @@ @@ -1,45 +0,0 @@
1 -(function() {  
2 - 'use strict';  
3 -  
4 - describe('directive navbar', function() {  
5 - var vm;  
6 - var el;  
7 - var AUTH_EVENTS;  
8 - var $state;  
9 -  
10 - beforeEach(module('angular'));  
11 - beforeEach(inject(function($compile, $rootScope, $httpBackend, _AUTH_EVENTS_, _$state_) {  
12 - $state = _$state_;  
13 - AUTH_EVENTS = _AUTH_EVENTS_;  
14 - $httpBackend.when('POST','/api/v1/login_from_cookie').respond({});  
15 -  
16 - el = angular.element('<acme-navbar></acme-navbar>');  
17 -  
18 - $compile(el)($rootScope.$new());  
19 - $rootScope.$digest();  
20 - vm = el.isolateScope().vm;  
21 - }));  
22 -  
23 - it('should be compiled', function() {  
24 - expect(el.html()).not.toEqual(null);  
25 - });  
26 -  
27 - it('should have isolate scope object with instanciate members', function() {  
28 - expect(vm).toEqual(jasmine.any(Object));  
29 - expect(vm.currentUser).toEqual(undefined);  
30 - });  
31 -  
32 - it('should reload current state after login', function() {  
33 - spyOn($state, 'go');  
34 - el.isolateScope().$broadcast(AUTH_EVENTS.loginSuccess, {});  
35 - expect($state.go).toHaveBeenCalled();  
36 - });  
37 -  
38 - it('should open login when not logged in', function() {  
39 - spyOn(vm, 'openLogin');  
40 - vm.activate();  
41 - expect(vm.openLogin).toHaveBeenCalled();  
42 - });  
43 -  
44 - });  
45 -})();  
src/app/components/navbar/navbar.html
@@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
1 -<nav class="navbar navbar-static-top navbar-inverse">  
2 - <div class="container-fluid">  
3 - <div class="navbar-header">  
4 - <button type="button" class="navbar-toggle collapsed" ng-click="isCollapsed = !isCollapsed">  
5 - <span class="sr-only">{{"navbar.toggle_menu" | translate}}</span>  
6 - <span class="icon-bar"></span>  
7 - <span class="icon-bar"></span>  
8 - <span class="icon-bar"></span>  
9 - </button>  
10 - <a class="navbar-brand" ui-sref="main">  
11 - <span class="noosfero-logo"><img src="assets/images/logo-noosfero.png"></span> {{"noosfero.name" | translate}}  
12 - </a>  
13 - </div>  
14 -  
15 - <div class="collapse navbar-collapse" id="navbar-collapse" collapse="isCollapsed">  
16 - <ul class="nav navbar-nav">  
17 - </ul>  
18 -  
19 - <ul class="nav navbar-nav navbar-right">  
20 - <li ng-show="!ctrl.currentUser">  
21 - <a ng-href="#" ng-click="ctrl.openLogin()">{{"navbar.login" | translate}}</a>  
22 - </li>  
23 -  
24 - <li class="dropdown profile-menu" ng-show="ctrl.currentUser" dropdown>  
25 - <a href="#" class="dropdown-toggle" aria-expanded="false" dropdown-toggle>  
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>  
29 - <ul class="dropdown-menu" dropdown-menu>  
30 - <li>  
31 - <a ui-sref="main.profile.info({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-user"></i> {{"navbar.profile" | translate}}</a>  
32 - </li>  
33 - <li>  
34 - <a target="_self" ui-sref="main.profile.settings({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-gear"></i> {{"navbar.settings" | translate}}</a>  
35 - </li>  
36 - <li class="divider"></li>  
37 - <li>  
38 - <a href="#" ng-click="ctrl.logout()"><i class="fa fa-fw fa-power-off"></i> {{"navbar.logout" | translate}}</a>  
39 - </li>  
40 - </ul>  
41 - </li>  
42 - </ul>  
43 - <ul class="nav navbar-nav navbar-right">  
44 - <language-selector class="nav navbar-nav navbar-right"></language-selector>  
45 - </ul>  
46 - <div ui-view="actions"></div>  
47 - </div>  
48 - </div>  
49 -</nav>  
src/app/components/navbar/navbar.scss
@@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
1 -.navbar {  
2 -  
3 - .container-fluid {  
4 - padding-right: 12%;  
5 - padding-left: 12%;  
6 - @media (max-width: 978px) {  
7 - padding-right: 2%;  
8 - padding-left: 2%;  
9 - }  
10 -  
11 - .navbar-brand {  
12 - .noosfero-logo img {  
13 - height: 35px;  
14 - }  
15 - }  
16 -  
17 - .navbar-nav {  
18 - .profile-menu .profile-image {  
19 - img {  
20 - height: 30px;  
21 - width: 30px;  
22 - display: inline-block;  
23 - @extend .img-circle;  
24 - }  
25 - i {  
26 - font-size: 1.7em;  
27 - }  
28 - }  
29 - }  
30 - }  
31 -}  
src/app/components/navbar/navbar.spec.ts
@@ -1,188 +0,0 @@ @@ -1,188 +0,0 @@
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';  
8 -  
9 -import {Session, AuthService, AuthController, IAuthEvents} from "./../auth";  
10 -  
11 -  
12 -describe("Components", () => {  
13 -  
14 - describe("Navbar Component", () => {  
15 -  
16 - let user: User = null;  
17 - let scope: any;  
18 - let $rootScope: ng.IRootScopeService;  
19 -  
20 - let modalInstance: any;  
21 - let $modal: any;  
22 - let authService: any;  
23 - let stateService: any;  
24 - let sessionService: Session;  
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 = <any>helpers.mocks.sessionWithCurrentUser(user);  
40 - });  
41 -  
42 -  
43 - // loading the templates  
44 - beforeEach(angular.mock.module("templates"));  
45 -  
46 -  
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 - provide('TranslatorService', {  
76 - useValue: helpers.mocks.translatorService  
77 - })  
78 - ].concat(helpers.provideFilters("translateFilter")),  
79 - directives: [Navbar],  
80 - template: '<acme-navbar></acme-navbar>'  
81 - });  
82 - }  
83 -  
84 -  
85 - it('should get the loggedIn user', (done: Function) => {  
86 - buildComponent().then((fixture: ComponentFixture) => {  
87 - let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance;  
88 - expect(navbarInstance).toBeDefined();  
89 - expect(navbarInstance["currentUser"]).toEqual(user);  
90 - done();  
91 - });  
92 - });  
93 -  
94 - it('should open on click', (done: Function) => {  
95 - spyOn($modal, "open");  
96 - buildComponent().then((fixture: ComponentFixture) => {  
97 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
98 - navbarComp.openLogin();  
99 - expect($modal.open).toHaveBeenCalled();  
100 - expect($modal.open).toHaveBeenCalledWith({  
101 - templateUrl: 'app/components/auth/login.html',  
102 - controller: AuthController,  
103 - controllerAs: 'vm',  
104 - bindToController: true  
105 - });  
106 - done();  
107 - });  
108 - });  
109 -  
110 - it('should logout', (done: Function) => {  
111 - buildComponent().then((fixture: ComponentFixture) => {  
112 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
113 - spyOn(authService, "logout");  
114 - try {  
115 - navbarComp.logout();  
116 - expect(authService.logout).toHaveBeenCalled();  
117 - done();  
118 - } catch (e) {  
119 - console.error(e);  
120 - fail(e.message);  
121 - done();  
122 - }  
123 - });  
124 - });  
125 -  
126 -  
127 - it('should not activate user when logged in', (done: Function) => {  
128 - buildComponent().then((fixture: ComponentFixture) => {  
129 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
130 - spyOn(navbarComp, "openLogin");  
131 - navbarComp.activate();  
132 - expect((<any>navbarComp.openLogin).calls.count()).toBe(0);  
133 - done();  
134 - });  
135 - });  
136 -  
137 - it('should activate when user not logged in', (done: Function) => {  
138 - spyOn(sessionService, 'currentUser').and.returnValue(null);  
139 - buildComponent().then((fixture: ComponentFixture) => {  
140 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
141 - spyOn(navbarComp, "openLogin");  
142 - navbarComp.activate();  
143 - expect(navbarComp.openLogin).toHaveBeenCalled();  
144 - done();  
145 - });  
146 - });  
147 -  
148 -  
149 - it('closes the modal after login', (done: Function) => {  
150 - modalInstance = jasmine.createSpyObj("modalInstance", ["close"]);  
151 - modalInstance.close = jasmine.createSpy("close");  
152 -  
153 - $modal.open = () => {  
154 - return modalInstance;  
155 - };  
156 -  
157 - buildComponent().then((fixture: ComponentFixture) => {  
158 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
159 - let localScope: ng.IScope = navbarComp["$scope"];  
160 -  
161 - navbarComp.openLogin();  
162 - localScope.$emit(AUTH_EVENTS.loginSuccess);  
163 - expect(modalInstance.close).toHaveBeenCalled();  
164 - done();  
165 - });  
166 - });  
167 -  
168 - it('updates current user on logout', (done: Function) => {  
169 - buildComponent().then((fixture: ComponentFixture) => {  
170 - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;  
171 - let localScope: ng.IScope = navbarComp["$scope"];  
172 -  
173 - // init navbar currentUser with some user  
174 - navbarComp["currentUser"] = user;  
175 -  
176 - // changes the current User to return null,  
177 - // and emmit the 'logoutSuccess' event  
178 - // just what happens when user logsout  
179 - sessionService.currentUser = () => { return null; };  
180 - localScope.$emit(AUTH_EVENTS.logoutSuccess);  
181 - expect(navbarComp["currentUser"]).toBeNull();  
182 - done();  
183 - });  
184 - });  
185 -  
186 -  
187 - });  
188 -});  
src/app/components/navbar/navbar.ts
@@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
1 -import {Component, Inject} from "ng-forward";  
2 -import {LanguageSelector} from "../language-selector/language-selector.component";  
3 -  
4 -  
5 -import {Session, AuthService, AuthController, IAuthEvents, AUTH_EVENTS} from "./../auth";  
6 -import {User} from "./../../models/interfaces";  
7 -  
8 -@Component({  
9 - selector: "acme-navbar",  
10 - templateUrl: "app/components/navbar/navbar.html",  
11 - directives: [LanguageSelector],  
12 - providers: [AuthService, Session]  
13 -})  
14 -@Inject("$modal", AuthService, "Session", "$scope", "$state")  
15 -export class Navbar {  
16 -  
17 - private currentUser: User;  
18 - private modalInstance: any = null;  
19 - /**  
20 - *  
21 - */  
22 - constructor(  
23 - private $modal: any,  
24 - private authService: AuthService,  
25 - private session: Session,  
26 - private $scope: ng.IScope,  
27 - private $state: ng.ui.IStateService  
28 - ) {  
29 - this.currentUser = this.session.currentUser();  
30 -  
31 - this.$scope.$on(AUTH_EVENTS.loginSuccess, () => {  
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 - this.$scope.$on(AUTH_EVENTS.logoutSuccess, () => {  
41 - this.currentUser = this.session.currentUser();  
42 - });  
43 - }  
44 -  
45 - openLogin() {  
46 - this.modalInstance = this.$modal.open({  
47 - templateUrl: 'app/components/auth/login.html',  
48 - controller: AuthController,  
49 - controllerAs: 'vm',  
50 - bindToController: true  
51 - });  
52 - };  
53 -  
54 - logout() {  
55 - this.authService.logout();  
56 - this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth  
57 - };  
58 -  
59 -  
60 -  
61 - activate() {  
62 - if (!this.currentUser) {  
63 - this.openLogin();  
64 - }  
65 - }  
66 -  
67 -}  
src/app/components/noosfero-activities/activities.component.spec.ts
@@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
1 -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';  
2 -import {Pipe, Input, provide, Component} from 'ng-forward';  
3 -import {provideFilters} from '../../../spec/helpers';  
4 -  
5 -import {NoosferoActivities} from './activities.component';  
6 -  
7 -const tcb = new TestComponentBuilder();  
8 -  
9 -const htmlTemplate: string = '<noosfero-activities [activities]="ctrl.activities"></noosfero-activities>';  
10 -  
11 -  
12 -describe("Components", () => {  
13 -  
14 - describe("Noosfero Activities", () => {  
15 -  
16 - beforeEach(angular.mock.module("templates"));  
17 -  
18 - @Component({  
19 - selector: 'test-container-component',  
20 - template: htmlTemplate,  
21 - directives: [NoosferoActivities],  
22 - providers: provideFilters("truncateFilter", "stripTagsFilter", "translateFilter")  
23 - })  
24 - class BlockContainerComponent {  
25 - activities = [{ name: "activity1", verb: "create_article" }, { name: "activity2", verb: "create_article" }];  
26 - }  
27 -  
28 - it("render a noosfero activity tag for each activity", done => {  
29 - tcb.createAsync(BlockContainerComponent).then(fixture => {  
30 - expect(fixture.debugElement.queryAll("noosfero-activity").length).toEqual(2);  
31 - done();  
32 - });  
33 - });  
34 - });  
35 -  
36 -});  
src/app/components/noosfero-activities/activities.component.ts
@@ -1,27 +0,0 @@ @@ -1,27 +0,0 @@
1 -import {Component, Input} from "ng-forward";  
2 -import {NoosferoActivity} from "./activity/activity.component";  
3 -import {Activity} from "../../models/interfaces";  
4 -  
5 -/**  
6 - * @ngdoc controller  
7 - * @name NoosferoActivities  
8 - * @description  
9 - * The controller responsible to retreive profile activities.  
10 - */  
11 -  
12 -@Component({  
13 - selector: "noosfero-activities",  
14 - templateUrl: 'app/components/noosfero-activities/activities.html',  
15 - directives: [NoosferoActivity]  
16 -})  
17 -export class NoosferoActivities {  
18 -  
19 - /**  
20 - * @ngdoc property  
21 - * @propertyOf NoosferoActivities  
22 - * @name activities  
23 - * @returns {Activity[]} An array of {@link Activity}.  
24 - */  
25 - @Input() activities: Activity[];  
26 -  
27 -}  
src/app/components/noosfero-activities/activities.html
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -<timeline>  
2 - <timeline-event ng-repeat="activity in ctrl.activities | orderBy: 'created_at':true">  
3 - <noosfero-activity [activity]="activity"></noosfero-activity>  
4 - </timeline-event>  
5 -</timeline>  
src/app/components/noosfero-activities/activities.scss
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -.comma-separated {  
2 - .separated-item {  
3 - &:after {  
4 - content: ", ";  
5 - margin-left: -3px;  
6 - }  
7 - &:last-child:after {  
8 - content: "";  
9 - }  
10 - }  
11 -}  
src/app/components/noosfero-activities/activity/activity.component.spec.ts
@@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
1 -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';  
2 -import {Pipe, Input, provide, Component} from 'ng-forward';  
3 -import {provideFilters} from '../../../../spec/helpers';  
4 -  
5 -import {NoosferoActivity} from './activity.component';  
6 -  
7 -const tcb = new TestComponentBuilder();  
8 -  
9 -const htmlTemplate: string = '<noosfero-activity [activity]="ctrl.activity"></noosfero-activity>';  
10 -  
11 -  
12 -describe("Components", () => {  
13 -  
14 - describe("Noosfero Activity", () => {  
15 -  
16 - beforeEach(angular.mock.module("templates"));  
17 -  
18 - @Component({  
19 - selector: 'test-container-component',  
20 - template: htmlTemplate,  
21 - directives: [NoosferoActivity],  
22 - providers: provideFilters("truncateFilter", "stripTagsFilter", "translateFilter")  
23 - })  
24 - class BlockContainerComponent {  
25 - activity = { name: "activity1", verb: "create_article" };  
26 - }  
27 -  
28 - it("render the specific template for an activity verb", done => {  
29 - tcb.createAsync(BlockContainerComponent).then(fixture => {  
30 - let component: NoosferoActivity = fixture.debugElement.componentViewChildren[0].componentInstance;  
31 - expect(component.getActivityTemplate()).toEqual('app/components/noosfero-activities/activity/create_article.html');  
32 - expect(fixture.debugElement.queryAll(".activity.create_article").length).toEqual(1);  
33 - done();  
34 - });  
35 - });  
36 - });  
37 -  
38 -});  
src/app/components/noosfero-activities/activity/activity.component.ts
@@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
1 -import {Component, Input} from "ng-forward";  
2 -import {Activity} from "../../../models/interfaces";  
3 -  
4 -@Component({  
5 - selector: "noosfero-activity",  
6 - templateUrl: 'app/components/noosfero-activities/activity/activity.html'  
7 -})  
8 -export class NoosferoActivity {  
9 -  
10 - @Input() activity: Activity;  
11 -  
12 - getActivityTemplate() {  
13 - return 'app/components/noosfero-activities/activity/' + this.activity.verb + '.html';  
14 - }  
15 -  
16 -}  
src/app/components/noosfero-activities/activity/activity.html
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -<div class="activity {{ctrl.activity.verb}}">  
2 - <ng-include src="ctrl.getActivityTemplate()"></ng-include>  
3 -</div>  
src/app/components/noosfero-activities/activity/add_member_in_community.html
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -<timeline-badge class="info">  
2 - <i class="fa fa-user-plus"></i>  
3 -</timeline-badge>  
4 -<timeline-panel>  
5 - <timeline-heading>  
6 - <h4 class="timeline-title">  
7 - <a ui-sref="main.profile.info({profile: ctrl.activity.user.identifier})"><strong ng-bind="ctrl.activity.user.name"></strong></a>  
8 - <span> {{"activities.add_member_in_community.description" | translate}}</span>  
9 - </h4>  
10 - <p><small class="text-muted"><i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.activity.created_at | dateFormat"></span></small></p>  
11 - </timeline-heading>  
12 - <div class="timeline-body"></div>  
13 -</timeline-panel>  
src/app/components/noosfero-activities/activity/create_article.html
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -<timeline-badge class="success">  
2 - <i class="fa fa-file-text"></i>  
3 -</timeline-badge>  
4 -<timeline-panel>  
5 - <timeline-heading>  
6 - <h4 class="timeline-title">  
7 - <a ui-sref="main.profile.info({profile: ctrl.activity.user.identifier})"><strong ng-bind="ctrl.activity.user.name"></strong></a>  
8 - <span> {{"activities.create_article.description" | translate}} </span>  
9 - <a ui-sref="main.profile.info({profile: ctrl.activity.target.article.profile.identifier})">  
10 - <strong ng-bind="ctrl.activity.target.article.profile.name"></strong></span>  
11 - </a>  
12 - </h4>  
13 - <p><small class="text-muted"><i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.activity.created_at | dateFormat"></span></small></p>  
14 - </timeline-heading>  
15 - <div class="timeline-body">  
16 - <div class="article">  
17 - <div class="title">  
18 - <a ui-sref="main.profile.page({profile: ctrl.activity.target.article.profile.identifier, page: ctrl.activity.target.article.path})"  
19 - ng-bind="ctrl.activity.target.article.title"></a>  
20 - </div>  
21 - <div class="lead small">  
22 - <div ng-bind-html="ctrl.activity.target.article.body | stripTags | truncate: 100 : '...': true"></div>  
23 - </div>  
24 - </div>  
25 - </div>  
26 -</timeline-panel>  
src/app/components/noosfero-activities/activity/index.ts
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
src/app/components/noosfero-activities/activity/new_friendship.html
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -<timeline-badge class="info">  
2 - <i class="fa fa-user-plus"></i>  
3 -</timeline-badge>  
4 -<timeline-panel>  
5 - <timeline-heading>  
6 - <h4 class="timeline-title">  
7 - <a ui-sref="main.profile.info({profile: ctrl.activity.user.identifier})"><strong ng-bind="ctrl.activity.user.name"></strong></a>  
8 - <span> {{"activities.new_friendship.description" | translate:{friends: ctrl.activity.params.friend_name.length}:"messageformat" }} </span>  
9 - <span class="comma-separated">  
10 - <a class="separated-item" ui-sref="main.profile.info({profile: ctrl.activity.params.friend_url[$index].profile})" ng-repeat="friend in ctrl.activity.params.friend_name">  
11 - <strong ng-bind="friend"></strong>  
12 - </a>  
13 - </span>  
14 - </h4>  
15 - <p><small class="text-muted"><i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.activity.created_at | dateFormat"></span></small></p>  
16 - </timeline-heading>  
17 - <div class="timeline-body"></div>  
18 -</timeline-panel>  
src/app/components/noosfero-activities/index.ts
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
src/app/components/noosfero-articles/article/article.html
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -<div class="article">  
2 - <div class="page-header">  
3 - <h3 ng-bind="ctrl.article.title"></h3>  
4 - </div>  
5 -  
6 - <div class="sub-header clearfix">  
7 - <div class="page-info pull-right small text-muted">  
8 - <span class="time">  
9 - <i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.article.created_at | dateFormat"></span>  
10 - </span>  
11 - <span class="author" ng-if="ctrl.article.author">  
12 - <i class="fa fa-user"></i>  
13 - <a ui-sref="main.profile.home({profile: ctrl.article.author.identifier})">  
14 - <span class="author-name" ng-bind="ctrl.article.author.name"></span>  
15 - </a>  
16 - </span>  
17 - </div>  
18 - </div>  
19 -  
20 - <div class="page-body">  
21 - <div ng-bind-html="ctrl.article.body"></div>  
22 - </div>  
23 -</div>  
src/app/components/noosfero-articles/article/article.scss
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -.article {  
2 - .page-info {  
3 - .author {  
4 - a {  
5 - color: #b4bcc2;  
6 - }  
7 - }  
8 - }  
9 -  
10 - .page-header {  
11 - margin-bottom: 5px;  
12 - }  
13 -  
14 - .sub-header {  
15 - margin-bottom: 20px;  
16 - }  
17 -}  
src/app/components/noosfero-articles/article/article_view.spec.ts
@@ -1,108 +0,0 @@ @@ -1,108 +0,0 @@
1 -  
2 -import {Input, provide, Component} from 'ng-forward';  
3 -import {ArticleView, ArticleDefaultView} from './article_view';  
4 -  
5 -import {createComponentFromClass, quickCreateComponent} from "../../../../spec/helpers";  
6 -  
7 -// this htmlTemplate will be re-used between the container components in this spec file  
8 -const htmlTemplate: string = '<noosfero-article [article]="ctrl.article" [profile]="ctrl.profile"></noosfero-article>';  
9 -  
10 -  
11 -describe("Components", () => {  
12 -  
13 - describe("ArticleView Component", () => {  
14 -  
15 - // the karma preprocessor html2js transform the templates html into js files which put  
16 - // the templates to the templateCache into the module templates  
17 - // we need to load the module templates here as the template for the  
18 - // component Noosfero ArtileView will be load on our tests  
19 - beforeEach(angular.mock.module("templates"));  
20 -  
21 - it("renders the default component when no specific component is found", (done: Function) => {  
22 - // Creating a container component (ArticleContainerComponent) to include  
23 - // the component under test (ArticleView)  
24 - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleView] })  
25 - class ArticleContainerComponent {  
26 - article = { type: 'anyArticleType' };  
27 - profile = { name: 'profile-name' };  
28 - constructor() {  
29 - }  
30 - }  
31 -  
32 - createComponentFromClass(ArticleContainerComponent).then((fixture) => {  
33 - // and here we can inspect and run the test assertions  
34 -  
35 - // gets the children component of ArticleContainerComponent  
36 - let articleView: ArticleView = fixture.debugElement.componentViewChildren[0].componentInstance;  
37 -  
38 - // and checks if the article View rendered was the Default Article View  
39 - expect(articleView.constructor.prototype).toEqual(ArticleDefaultView.prototype);  
40 -  
41 - // done needs to be called (it isn't really needed, as we can read in  
42 - // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync)  
43 - // because createAsync in ng-forward is not really async, but as the intention  
44 - // here is write tests in angular 2 ways, this is recommended  
45 - done();  
46 - });  
47 -  
48 - });  
49 -  
50 - it("receives the article and profile as inputs", (done: Function) => {  
51 -  
52 - // Creating a container component (ArticleContainerComponent) to include  
53 - // the component under test (ArticleView)  
54 - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleView] })  
55 - class ArticleContainerComponent {  
56 - article = { type: 'anyArticleType' };  
57 - profile = { name: 'profile-name' };  
58 - constructor() {  
59 - }  
60 - }  
61 -  
62 - // uses the TestComponentBuilder instance to initialize the component  
63 - createComponentFromClass(ArticleContainerComponent).then((fixture) => {  
64 - // and here we can inspect and run the test assertions  
65 - let articleView: ArticleView = fixture.debugElement.componentViewChildren[0].componentInstance;  
66 -  
67 - // assure the article object inside the ArticleView matches  
68 - // the provided through the parent component  
69 - expect(articleView.article.type).toEqual("anyArticleType");  
70 - expect(articleView.profile.name).toEqual("profile-name");  
71 -  
72 - // done needs to be called (it isn't really needed, as we can read in  
73 - // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync)  
74 - // because createAsync in ng-forward is not really async, but as the intention  
75 - // here is write tests in angular 2 ways, this is recommended  
76 - done();  
77 - });  
78 - });  
79 -  
80 -  
81 - it("renders a article view which matches to the article type", done => {  
82 - // NoosferoTinyMceArticle component created to check if it will be used  
83 - // when a article with type 'TinyMceArticle' is provided to the noosfero-article (ArticleView)  
84 - // *** Important *** - the selector is what ng-forward uses to define the name of the directive provider  
85 - @Component({ selector: 'noosfero-tiny-mce-article', template: "<h1>TinyMceArticle</h1>" })  
86 - class TinyMceArticleView {  
87 - @Input() article: any;  
88 - @Input() profile: any;  
89 - }  
90 -  
91 - // Creating a container component (ArticleContainerComponent) to include our NoosferoTinyMceArticle  
92 - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleView, TinyMceArticleView] })  
93 - class CustomArticleType {  
94 - article = { type: 'TinyMceArticle' };  
95 - profile = { name: 'profile-name' };  
96 - constructor() {  
97 - }  
98 - }  
99 - createComponentFromClass(CustomArticleType).then(fixture => {  
100 - let myComponent: CustomArticleType = fixture.componentInstance;  
101 - expect(myComponent.article.type).toEqual("TinyMceArticle");  
102 - expect(fixture.debugElement.componentViewChildren[0].text()).toEqual("TinyMceArticle");  
103 - done();  
104 - });  
105 - });  
106 -  
107 - });  
108 -});  
109 \ No newline at end of file 0 \ No newline at end of file
src/app/components/noosfero-articles/article/article_view.ts
@@ -1,57 +0,0 @@ @@ -1,57 +0,0 @@
1 -import { bundle, Input, Inject, Component, Directive } from 'ng-forward';  
2 -import {ArticleBlog} from "../blog/blog.component";  
3 -  
4 -/**  
5 - * @ngdoc controller  
6 - * @name ArticleDefaultView  
7 - * @description  
8 - * A default view for Noosfero Articles. If the specific article view is  
9 - * not implemented, then this view is used.  
10 - */  
11 -@Component({  
12 - selector: 'noosfero-default-article',  
13 - templateUrl: 'app/components/noosfero-articles/article/article.html'  
14 -})  
15 -export class ArticleDefaultView {  
16 -  
17 - @Input() article: any;  
18 - @Input() profile: any;  
19 -  
20 -}  
21 -  
22 -/**  
23 - * @ngdoc controller  
24 - * @name ArticleView  
25 - * @description  
26 - * A dynamic view for articles. It uses the article type to replace  
27 - * the default template with the custom article directive.  
28 - */  
29 -@Component({  
30 - selector: 'noosfero-article',  
31 - template: 'not-used',  
32 - directives: [ArticleDefaultView, ArticleBlog]  
33 -})  
34 -@Inject("$element", "$scope", "$injector", "$compile")  
35 -export class ArticleView {  
36 -  
37 - @Input() article: any;  
38 - @Input() profile: any;  
39 - directiveName: string;  
40 -  
41 - ngOnInit() {  
42 - let specificDirective = 'noosfero' + this.article.type;  
43 - this.directiveName = "noosfero-default-article";  
44 - if (this.$injector.has(specificDirective + 'Directive')) {  
45 - this.directiveName = specificDirective.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();  
46 - }  
47 - this.$element.replaceWith(this.$compile('<' + this.directiveName + ' [article]="ctrl.article" [profile]="ctrl.profile"></' + this.directiveName + '>')(this.$scope));  
48 - }  
49 -  
50 - constructor(  
51 - private $element: any,  
52 - private $scope: ng.IScope,  
53 - private $injector: ng.auto.IInjectorService,  
54 - private $compile: ng.ICompileService) {  
55 -  
56 - }  
57 -}  
src/app/components/noosfero-articles/article/index.ts
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
2 -export * from "./article_view";  
src/app/components/noosfero-articles/blog/blog.component.spec.ts
@@ -1,132 +0,0 @@ @@ -1,132 +0,0 @@
1 -import {  
2 - providers  
3 -} from 'ng-forward/cjs/testing/providers';  
4 -  
5 -import {  
6 - Input,  
7 - Component  
8 -} from 'ng-forward';  
9 -import {  
10 - ArticleBlog  
11 -} from './blog.component';  
12 -  
13 -import {  
14 - createComponentFromClass,  
15 - quickCreateComponent,  
16 - provideEmptyObjects,  
17 - createProviderToValue,  
18 - provideFilters  
19 -} from "../../../../spec/helpers.ts";  
20 -  
21 -// this htmlTemplate will be re-used between the container components in this spec file  
22 -const htmlTemplate: string = '<noosfero-blog [article]="ctrl.article" [profile]="ctrl.profile"></noosfero-blog>';  
23 -  
24 -describe("Blog Component", () => {  
25 -  
26 - function promiseResultTemplate(response ? : {}) {  
27 - let thenFuncEmpty = (func: Function) => {  
28 - // does nothing  
29 - };  
30 - if (response) {  
31 - return {  
32 - then: (func: (response: any) => void) => {  
33 - func(response);  
34 - }  
35 - };  
36 - } else {  
37 - return {  
38 - then: (func: (response: any) => void) => {  
39 - // does nothing  
40 - }  
41 - };  
42 - }  
43 - }  
44 -  
45 - let articleService = {  
46 - getChildren: (article_id: number, filters: {}) => {  
47 - return promiseResultTemplate(null);  
48 - }  
49 - };  
50 -  
51 - @Component({  
52 - selector: 'test-container-component',  
53 - template: htmlTemplate,  
54 - directives: [ArticleBlog],  
55 - providers: [  
56 - provideEmptyObjects('Restangular'),  
57 - createProviderToValue('ArticleService', articleService),  
58 - provideFilters('truncateFilter')  
59 - ]  
60 - })  
61 - class BlogContainerComponent {  
62 - article = {  
63 - type: 'anyArticleType'  
64 - };  
65 - profile = {  
66 - name: 'profile-name'  
67 - };  
68 - }  
69 -  
70 - beforeEach(() => {  
71 -  
72 - // the karma preprocessor html2js transform the templates html into js files which put  
73 - // the templates to the templateCache into the module templates  
74 - // we need to load the module templates here as the template for the  
75 - // component Noosfero ArtileView will be load on our tests  
76 - angular.mock.module("templates")  
77 -  
78 - providers((provide: any) => {  
79 - return <any > [  
80 - provide('ArticleService', {  
81 - useValue: articleService  
82 - })  
83 - ]  
84 - });  
85 - });  
86 -  
87 - it("renders the blog content", (done: Function) => {  
88 -  
89 - createComponentFromClass(BlogContainerComponent).then((fixture) => {  
90 -  
91 - expect(fixture.debugElement.query('div.blog').length).toEqual(1);  
92 -  
93 - done();  
94 - });  
95 - });  
96 -  
97 - it("verify the blog data", (done: Function) => {  
98 -  
99 - // defining a mock result to articleService.getChildren method  
100 - articleService.getChildren = (article_id: number, filters: {}) => {  
101 - return promiseResultTemplate({  
102 - headers: (headerName: string) => {  
103 - return 1;  
104 - },  
105 - data: < any > {  
106 - articles: [{  
107 - id: 1,  
108 - title: 'The article test'  
109 - }]  
110 - }  
111 - });  
112 - };  
113 -  
114 - createComponentFromClass(BlogContainerComponent).then((fixture) => {  
115 -  
116 - // gets the children component of BlogContainerComponent  
117 - let articleBlog: BlogContainerComponent = fixture.debugElement.componentViewChildren[0].componentInstance;  
118 -  
119 - // check if the component property are the provided by the mocked articleService  
120 - let post = {  
121 - id: 1,  
122 - title: 'The article test'  
123 - };  
124 - expect(( < any > articleBlog)["posts"][0]).toEqual(jasmine.objectContaining(post));  
125 - expect(( < any > articleBlog)["totalPosts"]).toEqual(1);  
126 -  
127 - done();  
128 - });  
129 -  
130 - });  
131 -  
132 -});  
133 \ No newline at end of file 0 \ No newline at end of file
src/app/components/noosfero-articles/blog/blog.component.ts
@@ -1,48 +0,0 @@ @@ -1,48 +0,0 @@
1 -import {Component, Input, Inject} from "ng-forward";  
2 -  
3 -import {Article, Profile} from "./../../../models/interfaces";  
4 -import {ArticleService} from "../../../../lib/ng-noosfero-api/http/article.service";  
5 -  
6 -/**  
7 - * @ngdoc controller  
8 - * @name ArticleBlog  
9 - * @description  
10 - * An specific {@link ArticleView} for Blog articles.  
11 - */  
12 -@Component({  
13 - selector: "noosfero-blog",  
14 - templateUrl: "app/components/noosfero-articles/blog/blog.html"  
15 -})  
16 -@Inject(ArticleService)  
17 -export class ArticleBlog {  
18 -  
19 - @Input() article: Article;  
20 - @Input() profile: Profile;  
21 -  
22 - private posts: any[];  
23 - private perPage: number = 3;  
24 - private currentPage: number;  
25 - private totalPosts: number = 0;  
26 -  
27 - constructor(private articleService: ArticleService) { }  
28 -  
29 - ngOnInit() {  
30 - this.loadPage();  
31 - }  
32 -  
33 - loadPage() {  
34 - let filters = {  
35 - content_type: "TinyMceArticle",  
36 - per_page: this.perPage,  
37 - page: this.currentPage  
38 - };  
39 -  
40 - this.articleService  
41 - .getChildren(this.article.id, filters)  
42 - .then((response: restangular.IResponse) => {  
43 - this.totalPosts = <number>(<any>response.headers("total"));  
44 - this.posts = response.data.articles;  
45 - });  
46 - }  
47 -  
48 -}  
src/app/components/noosfero-articles/blog/blog.html
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -<div class="blog">  
2 - <div class="blog-cover" ng-show="ctrl.article.image">  
3 - <img ng-src="{{ctrl.article.image.url}}" class="img-responsive">  
4 - <h3 ng-bind="ctrl.article.title"></h3>  
5 - </div>  
6 -  
7 - <div class="page-header" ng-show="!ctrl.article.image">  
8 - <h3 ng-bind="ctrl.article.title"></h3>  
9 - </div>  
10 -  
11 - <div>  
12 - <div ng-repeat="child in ctrl.posts | orderBy: 'created_at':true">  
13 - <div class="page-header">  
14 - <a class="title" ui-sref="main.profile.page({profile: ctrl.profile.identifier, page: child.path})"><h4 ng-bind="child.title"></h4></a>  
15 - <div class="post-lead" ng-bind-html="child.body | truncate: 500: '...': true"></div>  
16 - </div>  
17 - </div>  
18 - </div>  
19 -  
20 - <pagination ng-model="ctrl.currentPage" total-items="ctrl.totalPosts" class="pagination-sm center-block"  
21 - boundary-links="true" items-per-page="ctrl.perPage" ng-change="ctrl.loadPage()"  
22 - first-text="«" last-text="»" previous-text="‹" next-text="›">  
23 - </pagination>  
24 -</div>  
src/app/components/noosfero-articles/blog/blog.scss
@@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
1 -.blog {  
2 - .blog-cover {  
3 - margin: -15px;  
4 - position: relative;  
5 - h3 {  
6 - position: absolute;  
7 - bottom: 0;  
8 - background-color: rgba(0, 0, 0, 0.4);  
9 - color: white;  
10 - padding: 10px 15px;  
11 - margin: 0;  
12 - width: 100%;  
13 - }  
14 - }  
15 -}  
src/app/components/noosfero-articles/blog/index.ts
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
2 -export * from "./blog.component";  
src/app/components/noosfero-articles/index.ts
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
src/app/components/noosfero-blocks/block.component.spec.ts
@@ -1,91 +0,0 @@ @@ -1,91 +0,0 @@
1 -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';  
2 -import {Input, provide, Component} from 'ng-forward';  
3 -  
4 -import {Block} from './block.component';  
5 -  
6 -const tcb = new TestComponentBuilder();  
7 -  
8 -const htmlTemplate: string = '<noosfero-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-block>';  
9 -  
10 -describe("Components", () => {  
11 - describe("Block Component", () => {  
12 -  
13 - // the karma preprocessor html2js transform the templates html into js files which put  
14 - // the templates to the templateCache into the module templates  
15 - // we need to load the module templates here as the template for the  
16 - // component Block will be load on our tests  
17 - beforeEach(angular.mock.module("templates"));  
18 -  
19 - it("receives the block and the owner as inputs", done => {  
20 -  
21 - // Creating a container component (BlockContainerComponent) to include  
22 - // the component under test (Block)  
23 - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [Block] })  
24 - class BlockContainerComponent {  
25 - block = { type: 'Block' };  
26 - owner = { name: 'profile-name' };  
27 - constructor() {  
28 - }  
29 - }  
30 -  
31 - // uses the TestComponentBuilder instance to initialize the component  
32 - tcb  
33 - .createAsync(BlockContainerComponent).then(fixture => {  
34 - // and here we can inspect and run the test assertions  
35 - let myComponent: Block = fixture.componentInstance;  
36 -  
37 - // assure the block object inside the Block matches  
38 - // the provided through the parent component  
39 - expect(myComponent.block.type).toEqual("Block");  
40 - expect(myComponent.owner.name).toEqual("profile-name");  
41 - done();  
42 - });  
43 - });  
44 -  
45 -  
46 - it("renders a component which matches to the block type", done => {  
47 - // CustomBlock component created to check if it will be used  
48 - // when a block with type 'CustomBlock' is provided to the noosfero-block (Block)  
49 - // *** Important *** - the selector is what ng-forward uses to define the name of the directive provider  
50 - @Component({ selector: 'noosfero-custom-block', template: "<h1>My Custom Block</h1>" })  
51 - class CustomBlock {  
52 - @Input() block: any;  
53 - @Input() owner: any;  
54 - }  
55 -  
56 - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [Block, CustomBlock] })  
57 - class CustomBlockType {  
58 - block = { type: 'CustomBlock' };  
59 - owner = { name: 'profile-name' };  
60 - constructor() {  
61 - }  
62 - }  
63 - tcb  
64 - .createAsync(CustomBlockType).then(fixture => {  
65 - let myComponent: CustomBlockType = fixture.componentInstance;  
66 - expect(myComponent.block.type).toEqual("CustomBlock");  
67 - expect(fixture.debugElement.componentViewChildren[0].text()).toEqual("My Custom Block");  
68 - done();  
69 - });  
70 - });  
71 -  
72 -  
73 - it("renders the default block when hasn't defined a block type", done => {  
74 - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [Block] })  
75 - class CustomBlockType {  
76 - block: any = { type: null };  
77 - owner: any = { name: 'profile-name' };  
78 - constructor() {  
79 - }  
80 - }  
81 - tcb  
82 - .createAsync(CustomBlockType).then(fixture => {  
83 - let myComponent: CustomBlockType = fixture.componentInstance;  
84 - expect(myComponent.block.type).toBeNull();  
85 - expect(!!fixture.debugElement.nativeElement.querySelector("noosfero-default-block")).toBeTruthy();  
86 - done();  
87 - });  
88 - });  
89 -  
90 - });  
91 -});  
92 \ No newline at end of file 0 \ No newline at end of file
src/app/components/noosfero-blocks/block.component.ts
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -import { Input, Inject, Component } from 'ng-forward';  
2 -  
3 -@Component({  
4 - selector: 'noosfero-block',  
5 - template: '<div></div>'  
6 -})  
7 -@Inject("$element", "$scope", "$injector", "$compile")  
8 -export class Block {  
9 -  
10 - @Input() block: any;  
11 - @Input() owner: any;  
12 -  
13 - ngOnInit() {  
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));  
16 - }  
17 -  
18 - constructor(private $element: any, private $scope: ng.IScope, private $injector: ng.auto.IInjectorService, private $compile: ng.ICompileService) {  
19 - }  
20 -}  
src/app/components/noosfero-blocks/block.scss
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -.block {  
2 - .panel-title {  
3 - font-size: 15px;  
4 - font-weight: bold;  
5 - }  
6 - .panel-heading {  
7 - background-color: transparent;  
8 - border: 0;  
9 - }  
10 -}  
src/app/components/noosfero-blocks/index.ts
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
2 -export * from "./block.component";  
src/app/components/noosfero-blocks/link-list/index.ts
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
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
@@ -1,65 +0,0 @@ @@ -1,65 +0,0 @@
1 -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';  
2 -import {Pipe, Input, provide, Component} from 'ng-forward';  
3 -import {provideFilters} from '../../../../spec/helpers';  
4 -  
5 -import {LinkListBlock} from './link-list.component';  
6 -  
7 -const tcb = new TestComponentBuilder();  
8 -  
9 -const htmlTemplate: string = '<noosfero-link-list-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-link-list-block>';  
10 -  
11 -  
12 -describe("Components", () => {  
13 -  
14 - describe("Link List Block Component", () => {  
15 -  
16 - beforeEach(angular.mock.module("templates"));  
17 -  
18 - it("receives the block and the owner as inputs", done => {  
19 -  
20 - // Creating a container component (BlockContainerComponent) to include  
21 - // the component under test (Block)  
22 - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [LinkListBlock] })  
23 - class BlockContainerComponent {  
24 - block = { type: 'Block' };  
25 - owner = { name: 'profile-name' };  
26 - constructor() {  
27 - }  
28 - }  
29 -  
30 - // uses the TestComponentBuilder instance to initialize the component  
31 - //.overrideView(LinkListBlock, { template: 'asdasdasd', pipes: [NoosferoTemplate] })  
32 - tcb.createAsync(BlockContainerComponent).then(fixture => {  
33 - // and here we can inspect and run the test assertions  
34 - let myComponent: LinkListBlock = fixture.componentInstance;  
35 -  
36 - // assure the block object inside the Block matches  
37 - // the provided through the parent component  
38 - expect(myComponent.block.type).toEqual("Block");  
39 - expect(myComponent.owner.name).toEqual("profile-name");  
40 - done();  
41 - });  
42 - });  
43 -  
44 -  
45 - it("display links stored in block settings", done => {  
46 -  
47 - @Component({  
48 - selector: 'test-container-component',  
49 - template: htmlTemplate,  
50 - directives: [LinkListBlock],  
51 - providers: provideFilters("noosferoTemplateFilter")  
52 - })  
53 - class CustomBlockType {  
54 - block: any = { settings: { links: [{ name: 'link1', address: 'address1' }, { name: 'link2', address: 'address2' }] } };  
55 - owner: any = { name: 'profile-name' };  
56 - }  
57 - tcb.createAsync(CustomBlockType).then(fixture => {  
58 - expect(fixture.debugElement.queryAll(".link-list-block a").length).toEqual(2);  
59 - done();  
60 - });  
61 - });  
62 -  
63 - });  
64 -  
65 -});  
66 \ No newline at end of file 0 \ No newline at end of file
src/app/components/noosfero-blocks/link-list/link-list.component.ts
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -import {Component, Input} from "ng-forward";  
2 -  
3 -@Component({  
4 - selector: "noosfero-link-list-block",  
5 - templateUrl: "app/components/noosfero-blocks/link-list/link-list.html"  
6 -})  
7 -export class LinkListBlock {  
8 -  
9 - @Input() block: any;  
10 - @Input() owner: any;  
11 -  
12 - links: any;  
13 -  
14 - ngOnInit() {  
15 - if (this.block && this.block.settings) {  
16 - this.links = this.block.settings.links;  
17 - }  
18 - }  
19 -  
20 -}  
src/app/components/noosfero-blocks/link-list/link-list.html
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -<div class="link-list-block">  
2 - <div ng-repeat="link in ctrl.links">  
3 - <a ng-href="{{link.address | noosferoTemplate:{profile: ctrl.owner.identifier} }}">  
4 - <i class="fa fa-fw icon-{{link.icon}}"></i> <span>{{link.name}}</span>  
5 - </a>  
6 - </div>  
7 -</div>  
src/app/components/noosfero-blocks/link-list/link-list.scss
@@ -1,34 +0,0 @@ @@ -1,34 +0,0 @@
1 -.icon-event {  
2 - @extend .fa-calendar;  
3 -}  
4 -.icon-photos {  
5 - @extend .fa-photo;  
6 -}  
7 -.icon-edit {  
8 - @extend .fa-edit;  
9 -}  
10 -.icon-ok {  
11 - @extend .fa-check;  
12 -}  
13 -.icon-send {  
14 - @extend .fa-send-o;  
15 -}  
16 -.icon-menu-people {  
17 - @extend .fa-user;  
18 -}  
19 -.icon-forum {  
20 - @extend .fa-users;  
21 -}  
22 -.icon-new {  
23 - @extend .fa-file-o;  
24 -}  
25 -.icon-save {  
26 - @extend .fa-save;  
27 -}  
28 -  
29 -.link-list-block {  
30 - a i {  
31 - line-height: 25px;  
32 - color: #949494;  
33 - }  
34 -}  
src/app/components/noosfero-blocks/main-block/index.ts
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
src/app/components/noosfero-blocks/main-block/main-block.component.spec.ts
@@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
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 -describe("Components", () => {  
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 - });  
41 -});  
42 \ No newline at end of file 0 \ No newline at end of file
src/app/components/noosfero-blocks/main-block/main-block.component.ts
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
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/main-block/main-block.html
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -<div ui-view="mainBlockContent" autoscroll></div>  
src/app/components/noosfero-blocks/members-block/index.ts
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
src/app/components/noosfero-blocks/members-block/members-block.component.spec.ts
@@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
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("Components", () => {  
11 - describe("Members Block Component", () => {  
12 -  
13 - beforeEach(angular.mock.module("templates"));  
14 -  
15 - let state = jasmine.createSpyObj("state", ["go"]);  
16 - let providers = [  
17 - new Provider('truncateFilter', { useValue: () => { } }),  
18 - new Provider('stripTagsFilter', { useValue: () => { } }),  
19 - new Provider('$state', { useValue: state }),  
20 - new Provider('ProfileService', {  
21 - useValue: {  
22 - getProfileMembers: (profileId: number, filters: any): any => {  
23 - return Promise.resolve({ data: { people: [{ identifier: "person1" }] } });  
24 - }  
25 - }  
26 - }),  
27 - ];  
28 - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [MembersBlock], providers: providers })  
29 - class BlockContainerComponent {  
30 - block = { type: 'Block', settings: {} };  
31 - owner = { name: 'profile-name' };  
32 - constructor() {  
33 - }  
34 - }  
35 -  
36 - it("get members of the block owner", done => {  
37 - tcb.createAsync(BlockContainerComponent).then(fixture => {  
38 - let block: MembersBlock = fixture.debugElement.componentViewChildren[0].componentInstance;  
39 - expect(block.members).toEqual([{ identifier: "person1" }]);  
40 - done();  
41 - });  
42 - });  
43 -  
44 - it("render the profile image for each member", done => {  
45 - tcb.createAsync(BlockContainerComponent).then(fixture => {  
46 - fixture.debugElement.getLocal("$rootScope").$apply();  
47 - expect(fixture.debugElement.queryAll("noosfero-profile-image").length).toEqual(1);  
48 - done();  
49 - });  
50 - });  
51 -  
52 - });  
53 -});  
54 \ No newline at end of file 0 \ No newline at end of file
src/app/components/noosfero-blocks/members-block/members-block.component.ts
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
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,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -<div class="members-block">  
2 - <a ng-repeat="member in ctrl.members" ui-sref="main.profile.home({profile: member.identifier})" class="member">  
3 - <noosfero-profile-image [profile]="member"></noosfero-profile-image>  
4 - </a>  
5 -</div>  
src/app/components/noosfero-blocks/members-block/members-block.scss
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -.members-block {  
2 - .member {  
3 - img, i.profile-image {  
4 - width: 60px;  
5 - }  
6 - img {  
7 - display: inline-block;  
8 - vertical-align: top;  
9 - }  
10 - i.profile-image {  
11 - text-align: center;  
12 - background-color: #889DB1;  
13 - color: #F1F1F1;  
14 - font-size: 4.5em;  
15 - }  
16 - }  
17 -}  
src/app/components/noosfero-blocks/profile-image-block/profile-image-block.component.spec.ts
@@ -1,46 +0,0 @@ @@ -1,46 +0,0 @@
1 -import {TestComponentBuilder, ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';  
2 -import {Pipe, Input, provide, Component} from 'ng-forward';  
3 -  
4 -import {ProfileImageBlock} from './profile-image-block.component';  
5 -  
6 -import * as helpers from "./../../../../spec/helpers";  
7 -  
8 -const tcb = new TestComponentBuilder();  
9 -  
10 -const htmlTemplate: string = '<noosfero-profile-image-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-profile-image-block>';  
11 -  
12 -describe("Components", () => {  
13 -  
14 - describe("Profile Image Block Component", () => {  
15 -  
16 - beforeEach(angular.mock.module("templates"));  
17 -  
18 - @Component({  
19 - selector: 'test-container-component',  
20 - template: htmlTemplate,  
21 - directives: [ProfileImageBlock],  
22 - providers: helpers.provideFilters("translateFilter")  
23 - })  
24 - class BlockContainerComponent {  
25 - block = { type: 'Block' };  
26 - owner = { name: 'profile-name' };  
27 - constructor() {  
28 - }  
29 - }  
30 -  
31 - it("show image if present", () => {  
32 - helpers.tcb.createAsync(BlockContainerComponent).then(fixture => {  
33 - var elProfile = fixture.debugElement.componentViewChildren[0];  
34 - expect(elProfile.query('div.profile-image-block').length).toEqual(1);  
35 - });  
36 - });  
37 -  
38 - it("has link to the profile", () => {  
39 - helpers.tcb.createAsync(BlockContainerComponent).then(fixture => {  
40 - var elProfile = fixture.debugElement.componentViewChildren[0];  
41 - expect(elProfile.query('a.settings-link').length).toEqual(1);  
42 - });  
43 - });  
44 -  
45 - });  
46 -});  
src/app/components/noosfero-blocks/profile-image-block/profile-image-block.component.ts
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -import {Inject, Input, Component} from "ng-forward";  
2 -import {ProfileImage} from "./../../../components/noosfero/profile-image/profile-image.component";  
3 -  
4 -@Component({  
5 - selector: "noosfero-profile-image-block",  
6 - templateUrl: 'app/components/noosfero-blocks/profile-image-block/profile-image-block.html',  
7 - directives: [ProfileImage]  
8 -})  
9 -export class ProfileImageBlock {  
10 -  
11 - @Input() block: any;  
12 - @Input() owner: any;  
13 -  
14 -}  
src/app/components/noosfero-blocks/profile-image-block/profile-image-block.html
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
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>  
4 - </a>  
5 - <a class="settings-link" target="_self" ui-sref="main.profile.settings({profile: ctrl.owner.identifier})">{{"blocks.profile_image.control_panel" | translate}}</a>  
6 -</div>  
src/app/components/noosfero-blocks/profile-image-block/profile-image-block.scss
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -.profile-image-block {  
2 - .settings-link {  
3 - display: block;  
4 - }  
5 -}  
src/app/components/noosfero-blocks/raw-html/raw-html.component.spec.ts
@@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
1 -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';  
2 -import {Component} from 'ng-forward';  
3 -  
4 -import {RawHTMLBlock} from './raw-html.component';  
5 -  
6 -const tcb = new TestComponentBuilder();  
7 -  
8 -const htmlTemplate: string = '<noosfero-raw-htmlblock [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-raw-htmlblock>';  
9 -  
10 -describe("Components", () => {  
11 -  
12 - describe("Raw Html Block Component", () => {  
13 -  
14 - beforeEach(angular.mock.module("templates"));  
15 - beforeEach(angular.mock.module("ngSanitize"));  
16 -  
17 - it("display html stored in block settings", done => {  
18 -  
19 - @Component({  
20 - selector: 'test-container-component',  
21 - template: htmlTemplate,  
22 - directives: [RawHTMLBlock],  
23 - })  
24 - class CustomBlockType {  
25 - block: any = { settings: { html: '<em>block content</em>' } };  
26 - owner: any = { name: 'profile-name' };  
27 - }  
28 - tcb.createAsync(CustomBlockType).then(fixture => {  
29 - expect(fixture.debugElement.query(".raw-html-block em").text().trim()).toEqual('block content');  
30 - done();  
31 - });  
32 - });  
33 -  
34 - });  
35 -  
36 -});  
src/app/components/noosfero-blocks/raw-html/raw-html.component.ts
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -import {Component, Input} from "ng-forward";  
2 -  
3 -@Component({  
4 - selector: "noosfero-raw-htmlblock",  
5 - templateUrl: 'app/components/noosfero-blocks/raw-html/raw-html.html'  
6 -})  
7 -  
8 -export class RawHTMLBlock {  
9 -  
10 - @Input() block: any;  
11 - @Input() owner: any;  
12 -  
13 - html: string;  
14 -  
15 - ngOnInit() {  
16 - this.html = this.block.settings.html;  
17 - }  
18 -}  
src/app/components/noosfero-blocks/raw-html/raw-html.html
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -<div class="raw-html-block" ng-bind-html="ctrl.html">  
2 -</div>  
src/app/components/noosfero-blocks/recent-documents/index.ts
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -/* Module Index Entry - generated using the script npm run generate-index */  
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.spec.ts
@@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
1 -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';  
2 -import {Provider, Input, provide, Component} from 'ng-forward';  
3 -import {provideFilters} from '../../../../spec/helpers';  
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("Components", () => {  
11 - describe("Recent Documents Block Component", () => {  
12 -  
13 - beforeEach(angular.mock.module("templates"));  
14 -  
15 - let state = jasmine.createSpyObj("state", ["go"]);  
16 - let providers = [  
17 - new Provider('$state', { useValue: state }),  
18 - new Provider('ArticleService', {  
19 - useValue: {  
20 - getByProfile: (profileId: number, filters: any): any => {  
21 - return Promise.resolve({ data: { articles: [{ name: "article1" }] } });  
22 - }  
23 - }  
24 - }),  
25 - ].concat(provideFilters("truncateFilter", "stripTagsFilter"));  
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 - });  
53 -});  
54 \ No newline at end of file 0 \ No newline at end of file
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.ts
@@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
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 - documentsLoaded: boolean = false;  
18 -  
19 - constructor(private articleService: ArticleService, private $state: any) {  
20 - }  
21 -  
22 - ngOnInit() {  
23 - this.profile = this.owner;  
24 - this.documents = [];  
25 -  
26 - var limit = (this.block && this.block.settings) ? this.block.settings.limit : null || 5;  
27 - //FIXME get all text articles  
28 - this.articleService.getByProfile(this.profile.id, { content_type: 'TinyMceArticle', per_page: limit }).then((response: any) => {  
29 - this.documents = response.data.articles;  
30 - this.documentsLoaded = true;  
31 - });  
32 - }  
33 -  
34 - openDocument(article: any) {  
35 - this.$state.go("main.profile.page", { page: article.path, profile: article.profile.identifier });  
36 - }  
37 -  
38 -}  
src/app/components/noosfero-blocks/recent-documents/recent-documents.html
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
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">  
4 - <img ng-src="{{card.author.image.url}}" class="img-circle">  
5 - </div>  
6 - <div class="header media-body">  
7 - <h5 class="title media-heading" ng-bind="card.title"></h5>  
8 -  
9 - <div class="subheader">  
10 - <span class="time">  
11 - <i class="fa fa-clock-o"></i> <span am-time-ago="card.created_at | dateFormat"></span>  
12 - </span>  
13 - </div>  
14 - </div>  
15 - <img ng-show="card.image" ng-src="{{card.image.url}}" class="img-responsive article-image">  
16 - <div class="post-lead" ng-bind-html="card.body | stripTags | truncate: 100: '...': true"></div>  
17 - </div>  
18 -</div>