Commit a944f06af9883d338e0a3432e12ab6db4f62d594

Authored by Victor Costa
1 parent a5c48faf

Display replies of comments

src/app/article/comment/comment.component.spec.ts
... ... @@ -30,12 +30,11 @@ describe("Components", () => {
30 30 });
31 31 });
32 32  
33   - it("render a post comment tag when click in reply", done => {
  33 + it("set show reply to true when click reply", done => {
34 34 helpers.createComponentFromClass(ContainerComponent).then(fixture => {
35 35 let component: CommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
36 36 component.reply();
37   - fixture.debugElement.getLocal("$rootScope").$apply();
38   - expect(fixture.debugElement.queryAll("noosfero-post-comment").length).toEqual(1);
  37 + expect(component.showReply).toBeTruthy(1);
39 38 done();
40 39 });
41 40 });
... ...
src/app/article/comment/comment.component.ts
1   -import { Input, Component } from 'ng-forward';
  1 +import { Inject, Input, Component } from 'ng-forward';
  2 +import { PostCommentComponent } from "./post-comment/post-comment.component";
2 3  
3 4 @Component({
4 5 selector: 'noosfero-comment',
5 6 templateUrl: 'app/article/comment/comment.html'
6 7 })
  8 +@Inject("$scope")
7 9 export class CommentComponent {
8 10  
9 11 @Input() comment: noosfero.Comment;
... ... @@ -11,6 +13,12 @@ export class CommentComponent {
11 13  
12 14 showReply: boolean = false;
13 15  
  16 + constructor(private $scope: ng.IScope) {
  17 + $scope.$on(PostCommentComponent.EVENT_COMMENT_RECEIVED, (event: ng.IAngularEvent, comment: noosfero.Comment) => {
  18 + this.showReply = false;
  19 + });
  20 + }
  21 +
14 22 reply() {
15 23 this.showReply = true;
16 24 }
... ...
src/app/article/comment/comment.html
... ... @@ -19,7 +19,5 @@
19 19 <div class="title">{{ctrl.comment.title}}</div>
20 20 <div class="body">{{ctrl.comment.body}}</div>
21 21 </div>
22   -
23   - <noosfero-post-comment ng-if="ctrl.showReply" [article]="ctrl.article" [reply-of]="ctrl.comment"></noosfero-post-comment>
24   -
  22 + <noosfero-comments [show-form]="ctrl.showReply" [article]="ctrl.article" [parent]="ctrl.comment"></noosfero-comments>
25 23 </div>
... ...
src/app/article/comment/comments.component.spec.ts
... ... @@ -22,33 +22,39 @@ describe(&quot;Components&quot;, () =&gt; {
22 22 new Provider('NotificationService', { useValue: helpers.mocks.notificationService })
23 23 ].concat(helpers.provideFilters("translateFilter"));
24 24  
25   - @Component({ selector: 'test-container-component', directives: [CommentsComponent], template: htmlTemplate, providers: providers })
26   - class ContainerComponent {
27   - article = { id: 1 };
  25 + let properties = { article: { id: 1 }, parent: null };
  26 + function createComponent() {
  27 + return helpers.quickCreateComponent({
  28 + providers: providers,
  29 + directives: [CommentsComponent],
  30 + template: htmlTemplate,
  31 + properties: properties
  32 + });
28 33 }
29 34  
  35 +
30 36 it("render comments associated to an article", done => {
31   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
  37 + createComponent().then(fixture => {
32 38 expect(fixture.debugElement.queryAll("noosfero-comment").length).toEqual(2);
33 39 done();
34 40 });
35 41 });
36 42  
37 43 it("render a post comment tag", done => {
38   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
  44 + createComponent().then(fixture => {
39 45 expect(fixture.debugElement.queryAll("noosfero-post-comment").length).toEqual(1);
40 46 done();
41 47 });
42 48 });
43 49  
44   - it("update comments list when receive an event", done => {
45   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
46   - fixture.debugElement.getLocal("$rootScope").$emit(PostCommentComponent.EVENT_COMMENT_RECEIVED, { id: 1 });
  50 + it("update comments list when receive an reply", done => {
  51 + properties.parent = { id: 2 };
  52 + createComponent().then(fixture => {
  53 + fixture.debugElement.getLocal("$rootScope").$emit(PostCommentComponent.EVENT_COMMENT_RECEIVED, { id: 1, reply_of: properties.parent });
47 54 fixture.debugElement.getLocal("$rootScope").$apply();
48 55 expect(fixture.debugElement.queryAll("noosfero-comment").length).toEqual(3);
49 56 done();
50 57 });
51 58 });
52   -
53 59 });
54 60 });
... ...
src/app/article/comment/comments.component.ts
... ... @@ -12,17 +12,26 @@ import { CommentComponent } from &quot;./comment.component&quot;;
12 12 export class CommentsComponent {
13 13  
14 14 comments: noosfero.Comment[] = [];
  15 + @Input() showForm = true;
15 16 @Input() article: noosfero.Article;
  17 + @Input() parent: noosfero.Comment;
16 18  
17 19 constructor(private commentService: CommentService, private $rootScope: ng.IScope) {
18 20 $rootScope.$on(PostCommentComponent.EVENT_COMMENT_RECEIVED, (event: ng.IAngularEvent, comment: noosfero.Comment) => {
19   - this.comments.push(comment);
  21 + if ((!this.parent && !comment.reply_of) || (comment.reply_of && this.parent && comment.reply_of.id === this.parent.id)) {
  22 + if (!this.comments) this.comments = [];
  23 + this.comments.push(comment);
  24 + }
20 25 });
21 26 }
22 27  
23 28 ngOnInit() {
24   - this.commentService.getByArticle(this.article).then((result: noosfero.RestResult<noosfero.Comment[]>) => {
25   - this.comments = result.data;
26   - });
  29 + if (this.parent) {
  30 + this.comments = this.parent.replies;
  31 + } else {
  32 + this.commentService.getByArticle(this.article).then((result: noosfero.RestResult<noosfero.Comment[]>) => {
  33 + this.comments = result.data;
  34 + });
  35 + }
27 36 }
28 37 }
... ...
src/app/article/comment/comments.html
1 1 <div class="comments">
2   - <noosfero-post-comment [article]="ctrl.article"></noosfero-post-comment>
  2 + <noosfero-post-comment ng-if="ctrl.showForm" [article]="ctrl.article" [parent]="ctrl.parent"></noosfero-post-comment>
3 3  
4 4 <div class="comments-list">
5 5 <noosfero-comment ng-repeat="comment in ctrl.comments" [comment]="comment" [article]="ctrl.article"></noosfero-comment>
... ...
src/app/article/comment/post-comment/post-comment.component.spec.ts
... ... @@ -33,9 +33,9 @@ describe(&quot;Components&quot;, () =&gt; {
33 33 helpers.createComponentFromClass(ContainerComponent).then(fixture => {
34 34 let component: PostCommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
35 35 commentService.createInArticle = jasmine.createSpy("createInArticle").and.returnValue(helpers.mocks.promiseResultTemplate({ data: {} }));
36   - component["$rootScope"].$emit = jasmine.createSpy("$emit");
  36 + component["$scope"].$emit = jasmine.createSpy("$emit");
37 37 component.save();
38   - expect(component["$rootScope"].$emit).toHaveBeenCalledWith(PostCommentComponent.EVENT_COMMENT_RECEIVED, jasmine.any(Object));
  38 + expect(component["$scope"].$emit).toHaveBeenCalledWith(PostCommentComponent.EVENT_COMMENT_RECEIVED, jasmine.any(Object));
39 39 done();
40 40 });
41 41 });
... ... @@ -55,9 +55,9 @@ describe(&quot;Components&quot;, () =&gt; {
55 55 helpers.createComponentFromClass(ContainerComponent).then(fixture => {
56 56 let component: PostCommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
57 57 component.comment = <any>{ reply_of_id: null };
58   - component.replyOf = <any>{ id: 10 };
  58 + component.parent = <any>{ id: 10 };
59 59 component.save();
60   - expect(component.comment.reply_of_id).toEqual(component.replyOf.id);
  60 + expect(component.comment.reply_of_id).toEqual(component.parent.id);
61 61 done();
62 62 });
63 63 });
... ...
src/app/article/comment/post-comment/post-comment.component.ts
... ... @@ -6,24 +6,25 @@ import { NotificationService } from &quot;../../../shared/services/notification.servi
6 6 selector: 'noosfero-post-comment',
7 7 templateUrl: 'app/article/comment/post-comment/post-comment.html'
8 8 })
9   -@Inject(CommentService, NotificationService, "$rootScope")
  9 +@Inject(CommentService, NotificationService, "$scope")
10 10 export class PostCommentComponent {
11 11  
12 12 public static EVENT_COMMENT_RECEIVED = "comment.received";
13 13  
14 14 @Input() article: noosfero.Article;
15   - @Input() replyOf: noosfero.Comment;
  15 + @Input() parent: noosfero.Comment;
16 16  
17   - comment: noosfero.Comment;
  17 + comment = <noosfero.Comment>{};
18 18  
19   - constructor(private commentService: CommentService, private notificationService: NotificationService, private $rootScope: ng.IScope) { }
  19 + constructor(private commentService: CommentService, private notificationService: NotificationService, private $scope: ng.IScope) { }
20 20  
21 21 save() {
22   - if (this.replyOf && this.comment) {
23   - this.comment.reply_of_id = this.replyOf.id;
  22 + if (this.parent && this.comment) {
  23 + this.comment.reply_of_id = this.parent.id;
24 24 }
25 25 this.commentService.createInArticle(this.article, this.comment).then((result: noosfero.RestResult<noosfero.Comment>) => {
26   - this.$rootScope.$emit(PostCommentComponent.EVENT_COMMENT_RECEIVED, result.data);
  26 + this.$scope.$emit(PostCommentComponent.EVENT_COMMENT_RECEIVED, result.data);
  27 + this.comment.body = "";
27 28 this.notificationService.success({ title: "Good job!", message: "Comment saved!" });
28 29 });
29 30 }
... ...
src/lib/ng-noosfero-api/http/comment.service.spec.ts
... ... @@ -22,8 +22,8 @@ describe(&quot;Services&quot;, () =&gt; {
22 22  
23 23 it("should return comments by article", (done) => {
24 24 let articleId = 1;
25   - $httpBackend.expectGET(`/api/v1/articles/${articleId}/comments`).respond(200, { comments: [{ name: "comment1" }] });
26   - commentService.getByArticle(<noosfero.Article>{id: articleId}).then((result: noosfero.RestResult<noosfero.Comment[]>) => {
  25 + $httpBackend.expectGET(`/api/v1/articles/${articleId}/comments?without_reply=true`).respond(200, { comments: [{ name: "comment1" }] });
  26 + commentService.getByArticle(<noosfero.Article>{ id: articleId }).then((result: noosfero.RestResult<noosfero.Comment[]>) => {
27 27 expect(result.data).toEqual([{ name: "comment1" }]);
28 28 done();
29 29 });
... ... @@ -32,9 +32,9 @@ describe(&quot;Services&quot;, () =&gt; {
32 32  
33 33 it("should create a comment in an article", (done) => {
34 34 let articleId = 1;
35   - let comment: noosfero.Comment = <any>{ id: null};
36   - $httpBackend.expectPOST(`/api/v1/articles/${articleId}/comments`, comment ).respond(200, {comment: { id: 2 }});
37   - commentService.createInArticle(<noosfero.Article>{id: articleId}, comment).then((result: noosfero.RestResult<noosfero.Comment>) => {
  35 + let comment: noosfero.Comment = <any>{ id: null };
  36 + $httpBackend.expectPOST(`/api/v1/articles/${articleId}/comments`, comment).respond(200, { comment: { id: 2 } });
  37 + commentService.createInArticle(<noosfero.Article>{ id: articleId }, comment).then((result: noosfero.RestResult<noosfero.Comment>) => {
38 38 expect(result.data).toEqual({ id: 2 });
39 39 done();
40 40 });
... ...
src/lib/ng-noosfero-api/http/comment.service.ts
... ... @@ -21,9 +21,10 @@ export class CommentService extends RestangularService&lt;noosfero.Comment&gt; {
21 21 };
22 22 }
23 23  
24   - getByArticle(article: noosfero.Article, params?: any): ng.IPromise<noosfero.RestResult<noosfero.Comment[]>> {
  24 + getByArticle(article: noosfero.Article, params: any = {}): ng.IPromise<noosfero.RestResult<noosfero.Comment[]>> {
  25 + params['without_reply'] = true;
25 26 let articleElement = this.articleService.getElement(<number>article.id);
26   - return this.list(articleElement);
  27 + return this.list(articleElement, params);
27 28 }
28 29  
29 30 createInArticle(article: noosfero.Article, comment: noosfero.Comment): ng.IPromise<noosfero.RestResult<noosfero.Comment>> {
... ...
src/lib/ng-noosfero-api/interfaces/comment.ts
1 1 namespace noosfero {
2 2 export interface Comment extends RestModel {
3 3 reply_of_id: number;
  4 + reply_of: Comment;
  5 + replies: Comment[];
  6 + body: string;
4 7 }
5 8 }
... ...