Commit 7044b1ae115fc6d86408eeb89aa97a8e2b356ebc
1 parent
5ef3ec06
Exists in
master
and in
1 other branch
refactory of the folder structure and file name convention
Showing
232 changed files
with
3197 additions
and
3132 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 232 files displayed.
.vscode/settings.json
... | ... | @@ -0,0 +1 @@ |
1 | +/* Module Index Entry - generated using the script npm run generate-index */ | ... | ... |
... | ... | @@ -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 | 109 | \ No newline at end of file | ... | ... |
... | ... | @@ -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 | +} | ... | ... |
... | ... | @@ -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> | ... | ... |
... | ... | @@ -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 | +}); | ... | ... |
... | ... | @@ -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 | +} | ... | ... |
... | ... | @@ -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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 | +} | ... | ... |
... | ... | @@ -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> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<noosfero-article ng-if="vm.article" [article]="vm.article" [profile]="vm.profile"></noosfero-article> | ... | ... |
... | ... | @@ -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 | 130 | \ No newline at end of file | ... | ... |
... | ... | @@ -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 | +} | ... | ... |
... | ... | @@ -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> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +/* Module Index Entry - generated using the script npm run generate-index */ | ... | ... |
src/app/cms/cms.component.spec.ts
... | ... | @@ -1,56 +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 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: Cms = new Cms(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: Cms = new Cms(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 | - }); | |
56 | -}); |
src/app/cms/cms.component.ts
... | ... | @@ -1,35 +0,0 @@ |
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 {Notification} from "../components/notification/notification.component"; | |
5 | - | |
6 | -@Component({ | |
7 | - selector: 'cms', | |
8 | - templateUrl: "app/cms/cms.html", | |
9 | - providers: [ | |
10 | - provide('articleService', { useClass: ArticleService }), | |
11 | - provide('profileService', { useClass: ProfileService }), | |
12 | - provide('notification', { useClass: Notification }) | |
13 | - ] | |
14 | -}) | |
15 | -@Inject(ArticleService, ProfileService, "$state", Notification) | |
16 | -export class Cms { | |
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: Notification) { } | |
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/cms/cms.html
... | ... | @@ -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
src/app/components/auth/auth_controller.spec.ts
... | ... | @@ -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,20 +0,0 @@ |
1 | -import {AuthService} from "./auth_service"; | |
2 | - | |
3 | -export class AuthController { | |
4 | - | |
5 | - static $inject = ["$log", "$stateParams", "AuthService"]; | |
6 | - | |
7 | - constructor( | |
8 | - private $log: ng.ILogService, | |
9 | - private $stateParams: any, | |
10 | - private AuthService: AuthService | |
11 | - ) { | |
12 | - | |
13 | - } | |
14 | - | |
15 | - credentials: noosfero.Credentials; | |
16 | - | |
17 | - login() { | |
18 | - this.AuthService.login(this.credentials); | |
19 | - } | |
20 | -} |
src/app/components/auth/auth_events.ts
... | ... | @@ -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 | 0 | \ No newline at end of file |
src/app/components/auth/auth_service.spec.ts
... | ... | @@ -1,81 +0,0 @@ |
1 | - | |
2 | - | |
3 | -import {AuthService, AUTH_EVENTS} from "./"; | |
4 | - | |
5 | -describe("Services", () => { | |
6 | - | |
7 | - | |
8 | - describe("Auth Service", () => { | |
9 | - | |
10 | - let $httpBackend: ng.IHttpBackendService; | |
11 | - let authService: AuthService; | |
12 | - let credentials: noosfero.Credentials; | |
13 | - let $rootScope: ng.IRootScopeService; | |
14 | - let user: noosfero.User; | |
15 | - | |
16 | - beforeEach(angular.mock.module("noosferoApp", ($translateProvider: angular.translate.ITranslateProvider) => { | |
17 | - $translateProvider.translations('en', {}); | |
18 | - })); | |
19 | - | |
20 | - beforeEach(inject((_$httpBackend_: ng.IHttpBackendService, _$rootScope_: ng.IRootScopeService, _AuthService_: AuthService) => { | |
21 | - $httpBackend = _$httpBackend_; | |
22 | - authService = _AuthService_; | |
23 | - $rootScope = _$rootScope_; | |
24 | - | |
25 | - user = <noosfero.User>{ | |
26 | - id: 1, | |
27 | - login: "user" | |
28 | - }; | |
29 | - })); | |
30 | - | |
31 | - | |
32 | - describe("Succesffull login", () => { | |
33 | - | |
34 | - beforeEach(() => { | |
35 | - credentials = { username: "user", password: "password" }; | |
36 | - | |
37 | - $httpBackend.expectPOST("/api/v1/login", "login=user&password=password").respond(200, { user: user }); | |
38 | - }); | |
39 | - | |
40 | - it("should return loggedUser", (done) => { | |
41 | - authService.login(credentials).then((loggedUser) => { | |
42 | - expect(loggedUser).toBeDefined(); | |
43 | - done(); | |
44 | - }); | |
45 | - $httpBackend.flush(); | |
46 | - expect($httpBackend.verifyNoOutstandingRequest()); | |
47 | - }); | |
48 | - | |
49 | - | |
50 | - it("should emit event loggin successful with user logged data", () => { | |
51 | - | |
52 | - authService.login(credentials); | |
53 | - | |
54 | - let eventEmmited: boolean = false; | |
55 | - $rootScope.$on(AUTH_EVENTS.loginSuccess, (event: ng.IAngularEvent, userThroughEvent: noosfero.User) => { | |
56 | - eventEmmited = true; | |
57 | - expect(userThroughEvent).toEqual(user); | |
58 | - }); | |
59 | - | |
60 | - $httpBackend.flush(); | |
61 | - | |
62 | - expect(eventEmmited).toBeTruthy(AUTH_EVENTS.loginSuccess + " was not emmited!"); | |
63 | - }); | |
64 | - | |
65 | - it("should return the current logged in user", () => { | |
66 | - authService.login(credentials); | |
67 | - $httpBackend.flush(); | |
68 | - let actual: noosfero.User = authService.currentUser(); | |
69 | - expect(actual).toEqual(user, "The returned user must be present"); | |
70 | - }); | |
71 | - | |
72 | - it("should not return the current user after logout", () => { | |
73 | - authService.logout(); | |
74 | - let actual: any = authService.currentUser(); | |
75 | - expect(actual).toEqual(undefined, "The returned user must not be defined"); | |
76 | - }); | |
77 | - }); | |
78 | - | |
79 | - | |
80 | - }); | |
81 | -}); |
src/app/components/auth/auth_service.ts
... | ... | @@ -1,69 +0,0 @@ |
1 | -import {Injectable, Inject} from "ng-forward"; | |
2 | - | |
3 | -import {NoosferoRootScope, 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: noosfero.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: noosfero.Credentials): ng.IPromise<noosfero.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(): noosfero.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 | 0 | \ No newline at end of file |
src/app/components/auth/index.ts
src/app/components/auth/login.html
... | ... | @@ -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 | -import {Injectable, Inject} from "ng-forward"; | |
2 | -import {UserResponse, 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): noosfero.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(): noosfero.User { | |
24 | - return this.$localStorage.currentUser; | |
25 | - }; | |
26 | - | |
27 | -} | |
28 | 0 | \ No newline at end of file |
src/app/components/auth/session_spec.ts
... | ... | @@ -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, 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 | 0 | \ No newline at end of file |
src/app/components/index.ts
... | ... | @@ -1 +0,0 @@ |
1 | -/* Module Index Entry - generated using the script npm run generate-index */ |
src/app/components/language-selector/language-selector.component.ts
... | ... | @@ -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 | -<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
src/app/components/navbar/navbar.directive.spec.js
... | ... | @@ -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 | -<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 | -.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,187 +0,0 @@ |
1 | -import * as helpers from "./../../../spec/helpers"; | |
2 | -import {Navbar} from "./navbar"; | |
3 | -import {AUTH_EVENTS} from "./../auth"; | |
4 | -import {Injectable, Provider, provide} from "ng-forward"; | |
5 | - | |
6 | -import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; | |
7 | - | |
8 | -import {Session, AuthService, AuthController, IAuthEvents} from "./../auth"; | |
9 | - | |
10 | - | |
11 | -describe("Components", () => { | |
12 | - | |
13 | - describe("Navbar Component", () => { | |
14 | - | |
15 | - let user: noosfero.User = null; | |
16 | - let scope: any; | |
17 | - let $rootScope: ng.IRootScopeService; | |
18 | - | |
19 | - let modalInstance: any; | |
20 | - let $modal: any; | |
21 | - let authService: any; | |
22 | - let stateService: any; | |
23 | - let sessionService: Session; | |
24 | - | |
25 | - let provideFunc = provide; | |
26 | - | |
27 | - // before Each -> loading mocks on locals variables | |
28 | - beforeEach(() => { | |
29 | - user = <noosfero.User>{ | |
30 | - id: 1, | |
31 | - login: "user" | |
32 | - }; | |
33 | - scope = helpers.mocks.scopeWithEvents; | |
34 | - modalInstance = helpers.mocks.modalInstance; | |
35 | - $modal = helpers.mocks.$modal; | |
36 | - authService = helpers.mocks.authService; | |
37 | - stateService = jasmine.createSpyObj("$state", ["go"]); | |
38 | - sessionService = <any>helpers.mocks.sessionWithCurrentUser(user); | |
39 | - }); | |
40 | - | |
41 | - | |
42 | - // loading the templates | |
43 | - beforeEach(angular.mock.module("templates")); | |
44 | - | |
45 | - | |
46 | - // this function allow build the fixture of the container component | |
47 | - // and is reused in each test | |
48 | - // The main idea behing not prebuild it on a general beforeEach block is | |
49 | - // to allow tests configure the mock services accordilly their own needs | |
50 | - let buildComponent = (): Promise<ComponentFixture> => { | |
51 | - return helpers.quickCreateComponent({ | |
52 | - providers: [ | |
53 | - provide('$modal', { | |
54 | - useValue: $modal | |
55 | - }), | |
56 | - provide('AuthService', { | |
57 | - useValue: authService | |
58 | - }), | |
59 | - helpers.provideEmptyObjects('moment'), | |
60 | - provide('$state', { | |
61 | - useValue: stateService | |
62 | - }), | |
63 | - provide("$scope", { | |
64 | - useValue: scope | |
65 | - }), | |
66 | - provide('Session', { | |
67 | - useValue: sessionService | |
68 | - }), | |
69 | - provide('AUTH_EVENTS', { | |
70 | - useValue: { | |
71 | - AUTH_EVENTS | |
72 | - } | |
73 | - }), | |
74 | - provide('TranslatorService', { | |
75 | - useValue: helpers.mocks.translatorService | |
76 | - }) | |
77 | - ].concat(helpers.provideFilters("translateFilter")), | |
78 | - directives: [Navbar], | |
79 | - template: '<acme-navbar></acme-navbar>' | |
80 | - }); | |
81 | - }; | |
82 | - | |
83 | - | |
84 | - it('should get the loggedIn user', (done: Function) => { | |
85 | - buildComponent().then((fixture: ComponentFixture) => { | |
86 | - let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; | |
87 | - expect(navbarInstance).toBeDefined(); | |
88 | - expect(navbarInstance["currentUser"]).toEqual(user); | |
89 | - done(); | |
90 | - }); | |
91 | - }); | |
92 | - | |
93 | - it('should open on click', (done: Function) => { | |
94 | - spyOn($modal, "open"); | |
95 | - buildComponent().then((fixture: ComponentFixture) => { | |
96 | - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance; | |
97 | - navbarComp.openLogin(); | |
98 | - expect($modal.open).toHaveBeenCalled(); | |
99 | - expect($modal.open).toHaveBeenCalledWith({ | |
100 | - templateUrl: 'app/components/auth/login.html', | |
101 | - controller: AuthController, | |
102 | - controllerAs: 'vm', | |
103 | - bindToController: true | |
104 | - }); | |
105 | - done(); | |
106 | - }); | |
107 | - }); | |
108 | - | |
109 | - it('should logout', (done: Function) => { | |
110 | - buildComponent().then((fixture: ComponentFixture) => { | |
111 | - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance; | |
112 | - spyOn(authService, "logout"); | |
113 | - try { | |
114 | - navbarComp.logout(); | |
115 | - expect(authService.logout).toHaveBeenCalled(); | |
116 | - done(); | |
117 | - } catch (e) { | |
118 | - console.error(e); | |
119 | - fail(e.message); | |
120 | - done(); | |
121 | - } | |
122 | - }); | |
123 | - }); | |
124 | - | |
125 | - | |
126 | - it('should not activate user when logged in', (done: Function) => { | |
127 | - buildComponent().then((fixture: ComponentFixture) => { | |
128 | - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance; | |
129 | - spyOn(navbarComp, "openLogin"); | |
130 | - navbarComp.activate(); | |
131 | - expect((<any>navbarComp.openLogin).calls.count()).toBe(0); | |
132 | - done(); | |
133 | - }); | |
134 | - }); | |
135 | - | |
136 | - it('should activate when user not logged in', (done: Function) => { | |
137 | - spyOn(sessionService, 'currentUser').and.returnValue(null); | |
138 | - buildComponent().then((fixture: ComponentFixture) => { | |
139 | - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance; | |
140 | - spyOn(navbarComp, "openLogin"); | |
141 | - navbarComp.activate(); | |
142 | - expect(navbarComp.openLogin).toHaveBeenCalled(); | |
143 | - done(); | |
144 | - }); | |
145 | - }); | |
146 | - | |
147 | - | |
148 | - it('closes the modal after login', (done: Function) => { | |
149 | - modalInstance = jasmine.createSpyObj("modalInstance", ["close"]); | |
150 | - modalInstance.close = jasmine.createSpy("close"); | |
151 | - | |
152 | - $modal.open = () => { | |
153 | - return modalInstance; | |
154 | - }; | |
155 | - | |
156 | - buildComponent().then((fixture: ComponentFixture) => { | |
157 | - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance; | |
158 | - let localScope: ng.IScope = navbarComp["$scope"]; | |
159 | - | |
160 | - navbarComp.openLogin(); | |
161 | - localScope.$emit(AUTH_EVENTS.loginSuccess); | |
162 | - expect(modalInstance.close).toHaveBeenCalled(); | |
163 | - done(); | |
164 | - }); | |
165 | - }); | |
166 | - | |
167 | - it('updates current user on logout', (done: Function) => { | |
168 | - buildComponent().then((fixture: ComponentFixture) => { | |
169 | - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance; | |
170 | - let localScope: ng.IScope = navbarComp["$scope"]; | |
171 | - | |
172 | - // init navbar currentUser with some user | |
173 | - navbarComp["currentUser"] = user; | |
174 | - | |
175 | - // changes the current User to return null, | |
176 | - // and emmit the 'logoutSuccess' event | |
177 | - // just what happens when user logsout | |
178 | - sessionService.currentUser = () => { return null; }; | |
179 | - localScope.$emit(AUTH_EVENTS.logoutSuccess); | |
180 | - expect(navbarComp["currentUser"]).toBeNull(); | |
181 | - done(); | |
182 | - }); | |
183 | - }); | |
184 | - | |
185 | - | |
186 | - }); | |
187 | -}); |
src/app/components/navbar/navbar.ts
... | ... | @@ -1,66 +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 | - | |
7 | -@Component({ | |
8 | - selector: "acme-navbar", | |
9 | - templateUrl: "app/components/navbar/navbar.html", | |
10 | - directives: [LanguageSelector], | |
11 | - providers: [AuthService, Session] | |
12 | -}) | |
13 | -@Inject("$modal", AuthService, "Session", "$scope", "$state") | |
14 | -export class Navbar { | |
15 | - | |
16 | - private currentUser: noosfero.User; | |
17 | - private modalInstance: any = null; | |
18 | - /** | |
19 | - * | |
20 | - */ | |
21 | - constructor( | |
22 | - private $modal: any, | |
23 | - private authService: AuthService, | |
24 | - private session: Session, | |
25 | - private $scope: ng.IScope, | |
26 | - private $state: ng.ui.IStateService | |
27 | - ) { | |
28 | - this.currentUser = this.session.currentUser(); | |
29 | - | |
30 | - this.$scope.$on(AUTH_EVENTS.loginSuccess, () => { | |
31 | - if (this.modalInstance) { | |
32 | - this.modalInstance.close(); | |
33 | - this.modalInstance = null; | |
34 | - } | |
35 | - | |
36 | - this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth | |
37 | - }); | |
38 | - | |
39 | - this.$scope.$on(AUTH_EVENTS.logoutSuccess, () => { | |
40 | - this.currentUser = this.session.currentUser(); | |
41 | - }); | |
42 | - } | |
43 | - | |
44 | - openLogin() { | |
45 | - this.modalInstance = this.$modal.open({ | |
46 | - templateUrl: 'app/components/auth/login.html', | |
47 | - controller: AuthController, | |
48 | - controllerAs: 'vm', | |
49 | - bindToController: true | |
50 | - }); | |
51 | - }; | |
52 | - | |
53 | - logout() { | |
54 | - this.authService.logout(); | |
55 | - this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth | |
56 | - }; | |
57 | - | |
58 | - | |
59 | - | |
60 | - activate() { | |
61 | - if (!this.currentUser) { | |
62 | - this.openLogin(); | |
63 | - } | |
64 | - } | |
65 | - | |
66 | -} |
src/app/components/noosfero-activities/activities.component.spec.ts
... | ... | @@ -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 | -import {Component, Input} from "ng-forward"; | |
2 | -import {NoosferoActivity} from "./activity/activity.component"; | |
3 | - | |
4 | -/** | |
5 | - * @ngdoc controller | |
6 | - * @name NoosferoActivities | |
7 | - * @description | |
8 | - * The controller responsible to retreive profile activities. | |
9 | - */ | |
10 | - | |
11 | -@Component({ | |
12 | - selector: "noosfero-activities", | |
13 | - templateUrl: 'app/components/noosfero-activities/activities.html', | |
14 | - directives: [NoosferoActivity] | |
15 | -}) | |
16 | -export class NoosferoActivities { | |
17 | - | |
18 | - /** | |
19 | - * @ngdoc property | |
20 | - * @propertyOf NoosferoActivities | |
21 | - * @name activities | |
22 | - * @returns {Activity[]} An array of {@link Activity}. | |
23 | - */ | |
24 | - @Input() activities: noosfero.Activity[]; | |
25 | - | |
26 | - | |
27 | -} |
src/app/components/noosfero-activities/activities.html
src/app/components/noosfero-activities/activities.scss
src/app/components/noosfero-activities/activity/activity.component.spec.ts
... | ... | @@ -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,15 +0,0 @@ |
1 | -import {Component, Input} from "ng-forward"; | |
2 | - | |
3 | -@Component({ | |
4 | - selector: "noosfero-activity", | |
5 | - templateUrl: 'app/components/noosfero-activities/activity/activity.html' | |
6 | -}) | |
7 | -export class NoosferoActivity { | |
8 | - | |
9 | - @Input() activity: noosfero.Activity; | |
10 | - | |
11 | - getActivityTemplate() { | |
12 | - return 'app/components/noosfero-activities/activity/' + this.activity.verb + '.html'; | |
13 | - } | |
14 | - | |
15 | -} |
src/app/components/noosfero-activities/activity/activity.html
src/app/components/noosfero-activities/activity/add_member_in_community.html
... | ... | @@ -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 | -<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 | -/* 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 | -<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 | -/* Module Index Entry - generated using the script npm run generate-index */ |
src/app/components/noosfero-articles/article/article.html
... | ... | @@ -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
src/app/components/noosfero-articles/article/article_view.spec.ts
... | ... | @@ -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 | 0 | \ No newline at end of file |
src/app/components/noosfero-articles/article/article_view.ts
... | ... | @@ -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: 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: [ArticleDefaultView, ArticleBlog] | |
33 | -}) | |
34 | -@Inject("$element", "$scope", "$injector", "$compile") | |
35 | -export class ArticleView { | |
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/components/noosfero-articles/article/index.ts
src/app/components/noosfero-articles/blog/blog.component.spec.ts
... | ... | @@ -1,129 +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 | - 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 | -}); | |
130 | 0 | \ No newline at end of file |
src/app/components/noosfero-articles/blog/blog.component.ts
... | ... | @@ -1,47 +0,0 @@ |
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/components/noosfero-articles/blog/blog.html" | |
14 | -}) | |
15 | -@Inject(ArticleService) | |
16 | -export class ArticleBlog { | |
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/components/noosfero-articles/blog/blog.html
... | ... | @@ -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
src/app/components/noosfero-articles/blog/index.ts
src/app/components/noosfero-articles/index.ts
... | ... | @@ -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 | -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 | 0 | \ No newline at end of file |
src/app/components/noosfero-blocks/block.component.ts
... | ... | @@ -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
src/app/components/noosfero-blocks/index.ts
src/app/components/noosfero-blocks/link-list/index.ts
src/app/components/noosfero-blocks/link-list/link-list.component.spec.ts
... | ... | @@ -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 | 0 | \ No newline at end of file |
src/app/components/noosfero-blocks/link-list/link-list.component.ts
... | ... | @@ -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
src/app/components/noosfero-blocks/link-list/link-list.scss
... | ... | @@ -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 | -/* Module Index Entry - generated using the script npm run generate-index */ |
src/app/components/noosfero-blocks/main-block/main-block.component.spec.ts
... | ... | @@ -1,40 +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 | 0 | \ No newline at end of file |
src/app/components/noosfero-blocks/main-block/main-block.component.ts
src/app/components/noosfero-blocks/main-block/main-block.html
... | ... | @@ -1 +0,0 @@ |
1 | -<div ui-view="mainBlockContent" autoscroll></div> |
src/app/components/noosfero-blocks/members-block/index.ts
... | ... | @@ -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 | -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 | 0 | \ No newline at end of file |
src/app/components/noosfero-blocks/members-block/members-block.component.ts
... | ... | @@ -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: noosfero.Block; | |
12 | - @Input() owner: noosfero.Profile; | |
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
src/app/components/noosfero-blocks/members-block/members-block.scss
... | ... | @@ -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 | -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 | - let 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 | - let 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 | -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: noosfero.Block; | |
12 | - @Input() owner: noosfero.Profile; | |
13 | - | |
14 | -} |
src/app/components/noosfero-blocks/profile-image-block/profile-image-block.html
... | ... | @@ -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
src/app/components/noosfero-blocks/raw-html/raw-html.component.spec.ts
... | ... | @@ -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 | -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
src/app/components/noosfero-blocks/recent-documents/index.ts
... | ... | @@ -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,80 +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 | - let settingsObj = {}; | |
14 | - let mockedArticleService = { | |
15 | - getByProfile: (profile: noosfero.Profile, filters: any): any => { | |
16 | - return Promise.resolve({ data: [{ name: "article1" }], headers: (name: string) => { return name; } }); | |
17 | - } | |
18 | - }; | |
19 | - let profile = { name: 'profile-name' }; | |
20 | - beforeEach(angular.mock.module("templates")); | |
21 | - | |
22 | - let state = jasmine.createSpyObj("state", ["go"]); | |
23 | - | |
24 | - | |
25 | - function getProviders() { | |
26 | - return [ | |
27 | - new Provider('$state', { useValue: state }), | |
28 | - new Provider('ArticleService', { | |
29 | - useValue: mockedArticleService | |
30 | - }), | |
31 | - ].concat(provideFilters("truncateFilter", "stripTagsFilter")); | |
32 | - } | |
33 | - let componentClass: any = null; | |
34 | - | |
35 | - function getComponent() { | |
36 | - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [RecentDocumentsBlock], providers: getProviders() }) | |
37 | - class BlockContainerComponent { | |
38 | - block = { type: 'Block', settings: settingsObj }; | |
39 | - owner = profile; | |
40 | - constructor() { | |
41 | - } | |
42 | - } | |
43 | - return BlockContainerComponent; | |
44 | - } | |
45 | - | |
46 | - | |
47 | - it("get recent documents from the article service", done => { | |
48 | - tcb.createAsync(getComponent()).then(fixture => { | |
49 | - let recentDocumentsBlock: RecentDocumentsBlock = fixture.debugElement.componentViewChildren[0].componentInstance; | |
50 | - expect(recentDocumentsBlock.documents).toEqual([{ name: "article1" }]); | |
51 | - done(); | |
52 | - }); | |
53 | - }); | |
54 | - | |
55 | - it("go to article page when open a document", done => { | |
56 | - tcb.createAsync(getComponent()).then(fixture => { | |
57 | - let recentDocumentsBlock: RecentDocumentsBlock = fixture.debugElement.componentViewChildren[0].componentInstance; | |
58 | - recentDocumentsBlock.openDocument({ path: "path", profile: { identifier: "identifier" } }); | |
59 | - expect(state.go).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "identifier" }); | |
60 | - done(); | |
61 | - }); | |
62 | - }); | |
63 | - | |
64 | - it("it uses default limit 5 if not defined on block", done => { | |
65 | - settingsObj = null; | |
66 | - mockedArticleService = jasmine.createSpyObj("mockedArticleService", ["getByProfile"]); | |
67 | - (<any>mockedArticleService).mocked = true; | |
68 | - let thenMocked = jasmine.createSpy("then"); | |
69 | - mockedArticleService.getByProfile = jasmine.createSpy("getByProfile").and.returnValue({then: thenMocked}); | |
70 | - let getByProfileFunct = mockedArticleService.getByProfile; | |
71 | - tcb.createAsync(getComponent()).then(fixture => { | |
72 | - let recentDocumentsBlock: RecentDocumentsBlock = fixture.debugElement.componentViewChildren[0].componentInstance; | |
73 | - recentDocumentsBlock.openDocument({ path: "path", profile: { identifier: "identifier" } }); | |
74 | - expect(getByProfileFunct).toHaveBeenCalledWith(profile, { content_type: 'TinyMceArticle', per_page: 5 }); | |
75 | - done(); | |
76 | - }); | |
77 | - }); | |
78 | - | |
79 | - }); | |
80 | -}); | |
81 | 0 | \ No newline at end of file |
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.ts
... | ... | @@ -1,41 +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 | - let limit = ((this.block && this.block.settings) ? this.block.settings.limit : null) || 5; | |
27 | - // FIXME get all text articles | |
28 | - // FIXME make the getByProfile a generic method where we tell the type passing a class TinyMceArticle | |
29 | - // and the promise should be of type TinyMceArticle[], per example | |
30 | - this.articleService.getByProfile(this.profile, { content_type: 'TinyMceArticle', per_page: limit }) | |
31 | - .then((result: noosfero.RestResult<noosfero.Article[]>) => { | |
32 | - this.documents = <noosfero.Article[]>result.data; | |
33 | - this.documentsLoaded = true; | |
34 | - }); | |
35 | - } | |
36 | - | |
37 | - openDocument(article: any) { | |
38 | - this.$state.go("main.profile.page", { page: article.path, profile: article.profile.identifier }); | |
39 | - } | |
40 | - | |
41 | -} |
src/app/components/noosfero-blocks/recent-documents/recent-documents.html
... | ... | @@ -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> |
src/app/components/noosfero-blocks/recent-documents/recent-documents.scss
... | ... | @@ -1,65 +0,0 @@ |
1 | -.block.recentdocumentsblock { | |
2 | - .deckgrid[deckgrid]::before { | |
3 | - font-size: 0; /* See https://github.com/akoenig/angular-deckgrid/issues/14#issuecomment-35728861 */ | |
4 | - visibility: hidden; | |
5 | - } | |
6 | - .author { | |
7 | - img { | |
8 | - width: 30px; | |
9 | - height: 30px; | |
10 | - } | |
11 | - } | |
12 | - .header { | |
13 | - .subheader { | |
14 | - color: #C1C1C1; | |
15 | - font-size: 10px; | |
16 | - } | |
17 | - } | |
18 | - .post-lead { | |
19 | - color: #8E8E8E; | |
20 | - font-size: 14px; | |
21 | - } | |
22 | - .article-image { | |
23 | - margin: 10px 0; | |
24 | - } | |
25 | -} | |
26 | - | |
27 | -.col-md-2-5 { | |
28 | - .deckgrid[deckgrid]::before { | |
29 | - content: '1 .deck-column'; | |
30 | - } | |
31 | -} | |
32 | - | |
33 | -.col-md-7 { | |
34 | - .block.recentdocumentsblock { | |
35 | - background-color: transparent; | |
36 | - border: 0; | |
37 | - | |
38 | - .deckgrid[deckgrid]::before { | |
39 | - content: '3 .deck-column'; | |
40 | - } | |
41 | - | |
42 | - .panel-heading { | |
43 | - display: none; | |
44 | - } | |
45 | - .panel-body { | |
46 | - padding: 0; | |
47 | - } | |
48 | - | |
49 | - .deckgrid { | |
50 | - .column { | |
51 | - float: left; | |
52 | - } | |
53 | - | |
54 | - .deck-column { | |
55 | - @extend .col-md-4; | |
56 | - padding: 0; | |
57 | - | |
58 | - .a-card { | |
59 | - padding: 10px; | |
60 | - margin: 3px; | |
61 | - } | |
62 | - } | |
63 | - } | |
64 | - } | |
65 | -} |
src/app/components/noosfero-boxes/box.html
... | ... | @@ -1,10 +0,0 @@ |
1 | -<div ng-class="{'col-md-2-5': box.position!=1, 'col-md-7': box.position==1}"> | |
2 | - <div ng-repeat="block in box.blocks | orderBy: 'position'" class="panel panel-default block {{block.type | lowercase}}" > | |
3 | - <div class="panel-heading" ng-show="block.title"> | |
4 | - <h3 class="panel-title">{{block.title}}</h3> | |
5 | - </div> | |
6 | - <div class="panel-body"> | |
7 | - <noosfero-block [block]="block" [owner]="ctrl.owner"></noosfero-block> | |
8 | - </div> | |
9 | - </div> | |
10 | -</div> |
src/app/components/noosfero-boxes/boxes.component.spec.ts
... | ... | @@ -1,65 +0,0 @@ |
1 | -import {Component} from 'ng-forward'; | |
2 | - | |
3 | -import {Boxes} from './boxes.component'; | |
4 | - | |
5 | -import { | |
6 | - createComponentFromClass, | |
7 | - quickCreateComponent, | |
8 | - provideEmptyObjects, | |
9 | - createProviderToValue, | |
10 | - getAngularServiceFactory, | |
11 | - provideFilters | |
12 | -} from "../../../spec/helpers"; | |
13 | - | |
14 | -// this htmlTemplate will be re-used between the container components in this spec file | |
15 | -const htmlTemplate: string = '<noosfero-boxes [boxes]="ctrl.boxes" [owner]="ctrl.profile"></noosfero-blog>'; | |
16 | - | |
17 | - | |
18 | -describe("Boxes Component", () => { | |
19 | - | |
20 | - beforeEach(() => { | |
21 | - angular.mock.module("templates"); | |
22 | - }); | |
23 | - | |
24 | - @Component({ | |
25 | - selector: 'test-container-component', | |
26 | - template: htmlTemplate, | |
27 | - directives: [Boxes], | |
28 | - providers: [] | |
29 | - }) | |
30 | - class BoxesContainerComponent { | |
31 | - boxes: noosfero.Box[] = [ | |
32 | - { id: 1, position: 1 }, | |
33 | - { id: 2, position: 2 } | |
34 | - ]; | |
35 | - | |
36 | - owner: noosfero.Profile = <noosfero.Profile> { | |
37 | - id: 1, | |
38 | - identifier: 'profile-name', | |
39 | - type: 'Person' | |
40 | - }; | |
41 | - } | |
42 | - | |
43 | - it("renders boxes into a container", (done: Function) => { | |
44 | - createComponentFromClass(BoxesContainerComponent).then((fixture) => { | |
45 | - let boxesHtml = fixture.debugElement; | |
46 | - expect(boxesHtml.query('div.col-md-7').length).toEqual(1); | |
47 | - expect(boxesHtml.query('div.col-md-2-5').length).toEqual(1); | |
48 | - | |
49 | - done(); | |
50 | - }); | |
51 | - }); | |
52 | - | |
53 | - it("check the boxes order", (done: Function) => { | |
54 | - createComponentFromClass(BoxesContainerComponent).then((fixture) => { | |
55 | - | |
56 | - let boxesComponent: Boxes = fixture.debugElement.componentViewChildren[0].componentInstance; | |
57 | - let boxesContainer: BoxesContainerComponent = fixture.componentInstance; | |
58 | - | |
59 | - expect(boxesComponent.boxesOrder(boxesContainer.boxes[0])).toEqual(1); | |
60 | - expect(boxesComponent.boxesOrder(boxesContainer.boxes[1])).toEqual(0); | |
61 | - | |
62 | - done(); | |
63 | - }); | |
64 | - }); | |
65 | -}); |