diff --git a/src/app/hotspot/hotspot.decorator.ts b/src/app/hotspot/hotspot.decorator.ts index 21d1e16..dd31215 100644 --- a/src/app/hotspot/hotspot.decorator.ts +++ b/src/app/hotspot/hotspot.decorator.ts @@ -1,5 +1,5 @@ export function Hotspot(hotspotName: string) { return (target: any) => { target['hotspot'] = hotspotName; - } + }; } diff --git a/src/plugins/comment_paragraph/allow-comment/allow-comment.component.spec.ts b/src/plugins/comment_paragraph/allow-comment/allow-comment.component.spec.ts new file mode 100644 index 0000000..559dc5d --- /dev/null +++ b/src/plugins/comment_paragraph/allow-comment/allow-comment.component.spec.ts @@ -0,0 +1,78 @@ +import {AllowCommentComponent} from "./allow-comment.component"; +import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; +import * as helpers from "../../../spec/helpers"; +import {Provider} from 'ng-forward'; +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; + +let htmlTemplate = ''; + +describe("Components", () => { + describe("Allow Comment Component", () => { + + let serviceMock = { + commentParagraphCount: () => { + return Promise.resolve(5); + } + }; + let functionToggleCommentParagraph: Function; + let eventServiceMock = { + // toggleCommentParagraph + subscribeToggleCommentParagraph: (fn: Function) => { + functionToggleCommentParagraph = fn; + } + }; + + let providers = [ + new Provider('CommentParagraphService', { useValue: serviceMock }), + new Provider('CommentParagraphEventService', { useValue: eventServiceMock }) + ]; + let helper: ComponentTestHelper; + + beforeEach(angular.mock.module("templates")); + + beforeEach((done) => { + let cls = createClass({ + template: htmlTemplate, + directives: [AllowCommentComponent], + providers: providers, + properties: { + content: "", + paragraphUuid: "uuid", + article: { + setting: { + comment_paragraph_plugin_activate: true + } + } + } + }); + helper = new ComponentTestHelper(cls, done); + }); + + it('update comments count', () => { + expect(helper.component.commentsCount).toEqual(5); + }); + + it('display paragraph content', () => { + expect(helper.all(".paragraph .paragraph-content").length).toEqual(1); + }); + + it('display button to side comments', () => { + expect(helper.all(".paragraph .actions a").length).toEqual(1); + }); + + it('set display to true when click in show paragraph', () => { + helper.component.showParagraphComments(); + expect(helper.component.display).toBeTruthy(); + }); + + it('set display to false when click in hide paragraph', () => { + helper.component.hideParagraphComments(); + expect(helper.component.display).toBeFalsy(); + }); + + it('update article when receive a toogle paragraph event', () => { + functionToggleCommentParagraph({ id: 2 }); + expect(helper.component.article.id).toEqual(2); + }); + }); +}); diff --git a/src/plugins/comment_paragraph/allow-comment/allow-comment.component.ts b/src/plugins/comment_paragraph/allow-comment/allow-comment.component.ts index 2a4d25b..556d8c3 100644 --- a/src/plugins/comment_paragraph/allow-comment/allow-comment.component.ts +++ b/src/plugins/comment_paragraph/allow-comment/allow-comment.component.ts @@ -26,13 +26,13 @@ export class AllowCommentComponent { this.article = article; this.$scope.$apply(); }); - this.commentParagraphService.commentParagraphCount(this.article, this.paragraphUuid).then((count: any) => { + this.commentParagraphService.commentParagraphCount(this.article, this.paragraphUuid).then((count: number) => { this.commentsCount = count; }); } isActivated() { - return this.article.setting.comment_paragraph_plugin_activate; + return this.article && this.article.setting && this.article.setting.comment_paragraph_plugin_activate; } showParagraphComments() { diff --git a/src/plugins/comment_paragraph/events/comment-paragraph-event.service.spec.ts b/src/plugins/comment_paragraph/events/comment-paragraph-event.service.spec.ts new file mode 100644 index 0000000..79b89b1 --- /dev/null +++ b/src/plugins/comment_paragraph/events/comment-paragraph-event.service.spec.ts @@ -0,0 +1,28 @@ +import {CommentParagraphEventService} from "./comment-paragraph-event.service"; +import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; +import * as helpers from "../../../spec/helpers"; +import {Provider} from 'ng-forward'; +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; + +describe("Services", () => { + describe("Comment Paragraph Event Service", () => { + let eventService: CommentParagraphEventService; + + beforeEach(() => { + eventService = new CommentParagraphEventService(); + eventService['toggleCommentParagraphEmitter'] = jasmine.createSpyObj("toggleCommentParagraphEmitter", ["next", "subscribe"]); + }); + + it('subscribe to toggle comment paragraph event', () => { + eventService['toggleCommentParagraphEmitter'].subscribe = jasmine.createSpy("subscribe"); + eventService.subscribeToggleCommentParagraph(() => { }); + expect(eventService['toggleCommentParagraphEmitter'].subscribe).toHaveBeenCalled(); + }); + + it('emit event when toggle comment paragraph', () => { + eventService['toggleCommentParagraphEmitter'].subscribe = jasmine.createSpy("next"); + eventService.toggleCommentParagraph({}); + expect(eventService['toggleCommentParagraphEmitter'].next).toHaveBeenCalled(); + }); + }); +}); diff --git a/src/plugins/comment_paragraph/hotspot/comment-paragraph-article-button.component.spec.ts b/src/plugins/comment_paragraph/hotspot/comment-paragraph-article-button.component.spec.ts new file mode 100644 index 0000000..16b7fb2 --- /dev/null +++ b/src/plugins/comment_paragraph/hotspot/comment-paragraph-article-button.component.spec.ts @@ -0,0 +1,85 @@ +import {CommentParagraphArticleButtonHotspotComponent} from "./comment-paragraph-article-button.component"; +import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; +import * as helpers from "../../../spec/helpers"; +import {Provider} from 'ng-forward'; +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; + +let htmlTemplate = ''; + +describe("Components", () => { + describe("Comment Paragraph Article Button Hotspot Component", () => { + + let serviceMock = jasmine.createSpyObj("CommentParagraphService", ["deactivateCommentParagraph", "activateCommentParagraph"]); + let eventServiceMock = jasmine.createSpyObj("CommentParagraphEventService", ["toggleCommentParagraph"]); + + let providers = [ + new Provider('CommentParagraphService', { useValue: serviceMock }), + new Provider('CommentParagraphEventService', { useValue: eventServiceMock }) + ].concat(helpers.provideFilters('translateFilter')); + let helper: ComponentTestHelper; + + beforeEach(angular.mock.module("templates")); + + beforeEach((done) => { + let cls = createClass({ + template: htmlTemplate, + directives: [CommentParagraphArticleButtonHotspotComponent], + providers: providers, + properties: { + article: {} + } + }); + helper = new ComponentTestHelper(cls, done); + }); + + it('emit event when deactivate comment paragraph in an article', () => { + serviceMock.deactivateCommentParagraph = jasmine.createSpy("deactivateCommentParagraph").and.returnValue( + { then: (fn: Function) => { fn({ data: {} }); } } + ); + eventServiceMock.toggleCommentParagraph = jasmine.createSpy("toggleCommentParagraph"); + helper.component.deactivateCommentParagraph(); + + expect(serviceMock.deactivateCommentParagraph).toHaveBeenCalled(); + expect(eventServiceMock.toggleCommentParagraph).toHaveBeenCalled(); + }); + + it('emit event when activate comment paragraph in an article', () => { + serviceMock.activateCommentParagraph = jasmine.createSpy("activateCommentParagraph").and.returnValue( + { then: (fn: Function) => { fn({ data: {} }); } } + ); + eventServiceMock.toggleCommentParagraph = jasmine.createSpy("toggleCommentParagraph"); + helper.component.activateCommentParagraph(); + + expect(serviceMock.activateCommentParagraph).toHaveBeenCalled(); + expect(eventServiceMock.toggleCommentParagraph).toHaveBeenCalled(); + }); + + it('return true when comment paragraph is active', () => { + helper.component.article = { setting: { comment_paragraph_plugin_activate: true } }; + helper.detectChanges(); + expect(helper.component.isActivated()).toBeTruthy(); + }); + + it('return false when comment paragraph is not active', () => { + expect(helper.component.isActivated()).toBeFalsy(); + }); + + it('return false when article has no setting attribute', () => { + helper.component.article = {}; + helper.detectChanges(); + expect(helper.component.isActivated()).toBeFalsy(); + }); + + it('display activate button when comment paragraph is not active', () => { + expect(helper.all('.comment-paragraph-activate').length).toEqual(1); + expect(helper.all('.comment-paragraph-deactivate').length).toEqual(0); + }); + + it('display deactivate button when comment paragraph is active', () => { + helper.component.article = { setting: { comment_paragraph_plugin_activate: true } }; + helper.detectChanges(); + expect(helper.all('.comment-paragraph-deactivate').length).toEqual(1); + expect(helper.all('.comment-paragraph-activate').length).toEqual(0); + }); + }); +}); diff --git a/src/plugins/comment_paragraph/hotspot/comment-paragraph-article-button.component.ts b/src/plugins/comment_paragraph/hotspot/comment-paragraph-article-button.component.ts index 78e3023..dfb4b15 100644 --- a/src/plugins/comment_paragraph/hotspot/comment-paragraph-article-button.component.ts +++ b/src/plugins/comment_paragraph/hotspot/comment-paragraph-article-button.component.ts @@ -18,14 +18,19 @@ export class CommentParagraphArticleButtonHotspotComponent { private commentParagraphEventService: CommentParagraphEventService) { } deactivateCommentParagraph() { - this.commentParagraphService.deactivateCommentParagraph(this.article).then((result: noosfero.RestResult) => { - this.article = result.data; - this.commentParagraphEventService.toggleCommentParagraph(this.article); - }); + this.toggleCommentParagraph(this.commentParagraphService.deactivateCommentParagraph(this.article)); } activateCommentParagraph() { - this.commentParagraphService.activateCommentParagraph(this.article).then((result: noosfero.RestResult) => { + this.toggleCommentParagraph(this.commentParagraphService.activateCommentParagraph(this.article)); + } + + isActivated() { + return this.article && this.article.setting && this.article.setting.comment_paragraph_plugin_activate; + } + + private toggleCommentParagraph(promise: ng.IPromise>) { + promise.then((result: noosfero.RestResult) => { this.article = result.data; this.commentParagraphEventService.toggleCommentParagraph(this.article); }); diff --git a/src/plugins/comment_paragraph/http/comment-paragraph.service.spec.ts b/src/plugins/comment_paragraph/http/comment-paragraph.service.spec.ts new file mode 100644 index 0000000..ad00d25 --- /dev/null +++ b/src/plugins/comment_paragraph/http/comment-paragraph.service.spec.ts @@ -0,0 +1,90 @@ +import {CommentParagraphService} from "./comment-paragraph.service"; + + +describe("Services", () => { + + describe("Comment Paragraph Service", () => { + + let $httpBackend: ng.IHttpBackendService; + let commentParagraphService: CommentParagraphService; + + beforeEach(angular.mock.module("noosferoApp", ($translateProvider: angular.translate.ITranslateProvider) => { + $translateProvider.translations('en', {}); + })); + + beforeEach(inject((_$httpBackend_: ng.IHttpBackendService, _CommentParagraphService_: CommentParagraphService) => { + $httpBackend = _$httpBackend_; + commentParagraphService = _CommentParagraphService_; + })); + + + describe("Succesfull requests", () => { + + it("should return paragraph comments by article", (done) => { + let articleId = 1; + $httpBackend.expectGET(`/api/v1/articles/${articleId}/comment_paragraph_plugin/comments?without_reply=true`).respond(200, { comments: [{ body: "comment1" }] }); + commentParagraphService.getByArticle({ id: articleId }).then((result: noosfero.RestResult) => { + expect(result.data).toEqual([{ body: "comment1" }]); + done(); + }); + $httpBackend.flush(); + }); + + it("should create a paragraph comment", (done) => { + let articleId = 1; + $httpBackend.expectPOST(`/api/v1/articles/${articleId}/comment_paragraph_plugin/comments`).respond(200, { comment: { body: "comment1" } }); + commentParagraphService.createInArticle({ id: articleId }, { body: "comment1" }).then((result: noosfero.RestResult) => { + expect(result.data).toEqual({ body: "comment1" }); + done(); + }); + $httpBackend.flush(); + }); + + it("activate paragraph comments for an article", (done) => { + let articleId = 1; + $httpBackend.expectPOST(`/api/v1/articles/${articleId}/comment_paragraph_plugin/activate`).respond(200, { article: { title: "article1" } }); + commentParagraphService.activateCommentParagraph({ id: articleId }).then((result: noosfero.RestResult) => { + expect(result.data).toEqual({ title: "article1" }); + done(); + }); + $httpBackend.flush(); + }); + + it("deactivate paragraph comments for an article", (done) => { + let articleId = 1; + $httpBackend.expectPOST(`/api/v1/articles/${articleId}/comment_paragraph_plugin/deactivate`).respond(200, { article: { title: "article1" } }); + commentParagraphService.deactivateCommentParagraph({ id: articleId }).then((result: noosfero.RestResult) => { + expect(result.data).toEqual({ title: "article1" }); + done(); + }); + $httpBackend.flush(); + }); + + it("return counts for paragraph comments", (done) => { + let articleId = 1; + $httpBackend.expectGET(`/api/v1/articles/${articleId}/comment_paragraph_plugin/comments/count`).respond(200, { '1': 5, '2': 6 }); + commentParagraphService.commentParagraphCount({ id: articleId }, '1').then((count: number) => { + expect(count).toEqual(5); + done(); + }); + $httpBackend.flush(); + }); + + it("reset promise when comment paragraph counts fails", (done) => { + let articleId = 1; + commentParagraphService['articleService'] = jasmine.createSpyObj("articleService", ["getElement"]); + commentParagraphService['articleService'].getElement = jasmine.createSpy("getElement").and.returnValue( + { + customGET: (path: string) => { + return Promise.reject({}); + } + } + ); + commentParagraphService.commentParagraphCount({ id: articleId }, '1').catch(() => { + expect(commentParagraphService['commentParagraphCountsPromise']).toBeNull(); + done(); + }); + }); + }); + }); +}); diff --git a/src/plugins/comment_paragraph/side-comments/side-comments.component.spec.ts b/src/plugins/comment_paragraph/side-comments/side-comments.component.spec.ts new file mode 100644 index 0000000..f684cad --- /dev/null +++ b/src/plugins/comment_paragraph/side-comments/side-comments.component.spec.ts @@ -0,0 +1,50 @@ +import {SideCommentsComponent} from "./side-comments.component"; +import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; +import * as helpers from "../../../spec/helpers"; +import {Provider} from 'ng-forward'; +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder'; + +let htmlTemplate = ''; + +describe("Components", () => { + describe("Side Comments Component", () => { + + let serviceMock = jasmine.createSpyObj("CommentParagraphService", ["getByArticle"]); + serviceMock.getByArticle = jasmine.createSpy("getByArticle").and.returnValue(Promise.resolve({ data: {} })); + + let commentServiceMock = {}; + let postCommentEventService = jasmine.createSpyObj("postCommentEventService", ["emit", "subscribe"]); + postCommentEventService.subscribe = jasmine.createSpy("subscribe"); + + let providers = [ + new Provider('CommentParagraphService', { useValue: serviceMock }), + new Provider('CommentService', { useValue: commentServiceMock }), + new Provider('PostCommentEventService', { useValue: postCommentEventService }) + ]; + let helper: ComponentTestHelper; + + beforeEach(angular.mock.module("templates")); + + beforeEach((done) => { + let cls = createClass({ + template: htmlTemplate, + directives: [SideCommentsComponent], + providers: providers, + properties: { + paragraphUuid: "uuid", + article: {} + } + }); + helper = new ComponentTestHelper(cls, done); + }); + + it('call service to load paragraph comments', () => { + helper.component.loadComments(); + expect(serviceMock.getByArticle).toHaveBeenCalled(); + }); + + it('set paragraph uuid in new comment object', () => { + expect(helper.component.newComment['paragraph_uuid']).toEqual('uuid'); + }); + }); +}); diff --git a/src/plugins/comment_paragraph/side-comments/side-comments.component.ts b/src/plugins/comment_paragraph/side-comments/side-comments.component.ts index 8ed147c..95c93dd 100644 --- a/src/plugins/comment_paragraph/side-comments/side-comments.component.ts +++ b/src/plugins/comment_paragraph/side-comments/side-comments.component.ts @@ -2,19 +2,23 @@ import {Component, Inject, Input, Output} from "ng-forward"; import {CommentsComponent} from "../../../app/article/comment/comments.component"; import {CommentService} from "../../../lib/ng-noosfero-api/http/comment.service"; import {CommentParagraphService} from "../http/comment-paragraph.service"; +import { PostCommentEventService } from "../../../app/article/comment/post-comment/post-comment-event.service"; @Component({ selector: "comment-paragraph-side-comments", templateUrl: 'app/article/comment/comments.html', }) -@Inject(CommentService, "$rootScope", CommentParagraphService) +@Inject(CommentService, PostCommentEventService, "$scope", CommentParagraphService) export class SideCommentsComponent extends CommentsComponent { @Input() article: noosfero.Article; @Input() paragraphUuid: string; - constructor(commentService: CommentService, $rootScope: ng.IScope, private commentParagraphService: CommentParagraphService) { - super(commentService, $rootScope); + constructor(commentService: CommentService, + postCommentEventService: PostCommentEventService, + $scope: ng.IScope, + private commentParagraphService: CommentParagraphService) { + super(commentService, postCommentEventService, $scope); } ngOnInit() { diff --git a/src/spec/component-test-helper.ts b/src/spec/component-test-helper.ts index 75b8474..1dee80a 100644 --- a/src/spec/component-test-helper.ts +++ b/src/spec/component-test-helper.ts @@ -68,6 +68,8 @@ export class ComponentTestHelper { this.init(done); } + fixture: any; + /** * @ngdoc method * @name init @@ -79,7 +81,8 @@ export class ComponentTestHelper { let promisse = this.tcb.createAsync(this.mockComponent) as Promise; return promisse.then((fixture: any) => { // Fire all angular events and parsing - fixture.detectChanges(); + this.fixture = fixture; + this.detectChanges(); // The main debug element this.debugElement = fixture.debugElement; this.component = this.debugElement.componentViewChildren[0].componentInstance; @@ -96,6 +99,17 @@ export class ComponentTestHelper { /** * @ngdoc method + * @name detectChanges + * @methodOf spec.ComponentTestHelper + * @description + * Detect changes in component + */ + detectChanges() { + this.fixture.detectChanges(); + } + + /** + * @ngdoc method * @name all * @methodOf spec.ComponentTestHelper * @description -- libgit2 0.21.2