From 68045cec8c7a27ba4dc1f4d2ecb330ed3a5ed61a Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Tue, 30 Aug 2016 16:18:21 +0200 Subject: [PATCH 1/4] Remove unused feedback actions view --- app/assets/javascripts/app/views/feedback_actions.js | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 app/assets/javascripts/app/views/feedback_actions.js diff --git a/app/assets/javascripts/app/views/feedback_actions.js b/app/assets/javascripts/app/views/feedback_actions.js deleted file mode 100644 index 861bde76d..000000000 --- a/app/assets/javascripts/app/views/feedback_actions.js +++ /dev/null @@ -1,11 +0,0 @@ -// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later - -//=require "./feedback_view" -app.views.FeedbackActions = app.views.Feedback.extend({ - id : "user-controls", - templateName : "feedback-actions", - events: {}, - initialize: function(){} -}); -// @license-end - From 8faedd574d77830c8af08e89b92432fc4161db31 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Tue, 30 Aug 2016 16:21:10 +0200 Subject: [PATCH 2/4] Move post controls to a separate view --- .../app/views/post_controls_view.js | 78 +++++++ .../app/views/stream_post_views.js | 86 ++------ .../templates/post-controls_tpl.jst.hbs | 24 +++ .../templates/stream-element_tpl.jst.hbs | 29 +-- .../app/views/post_controls_view_spec.js | 200 ++++++++++++++++++ 5 files changed, 317 insertions(+), 100 deletions(-) create mode 100644 app/assets/javascripts/app/views/post_controls_view.js create mode 100644 app/assets/templates/post-controls_tpl.jst.hbs create mode 100644 spec/javascripts/app/views/post_controls_view_spec.js diff --git a/app/assets/javascripts/app/views/post_controls_view.js b/app/assets/javascripts/app/views/post_controls_view.js new file mode 100644 index 000000000..796e8565a --- /dev/null +++ b/app/assets/javascripts/app/views/post_controls_view.js @@ -0,0 +1,78 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later + +app.views.PostControls = app.views.Base.extend({ + templateName: "post-controls", + className: "control-icons", + + events: { + "click .remove_post": "destroyModel", + "click .hide_post": "hidePost", + "click .post_report": "report", + "click .block_user": "blockUser", + "click .create_participation": "createParticipation", + "click .destroy_participation": "destroyParticipation" + }, + + tooltipSelector: [".post_report", + ".block_user", + ".delete", + ".create_participation", + ".destroy_participation"].join(", "), + + initialize: function(opts) { + this.model.bind("change", this.render, this); + this.post = opts.post; + }, + + presenter: function() { + return _.extend(this.defaultPresenter(), { + authorIsCurrentUser: app.currentUser.isAuthorOf(this.model) + }); + }, + + blockUser: function(evt) { + if (evt) { evt.preventDefault(); } + if (!confirm(Diaspora.I18n.t("ignore_user"))) { return; } + + this.model.blockAuthor().fail(function() { + app.flashMessages.error(Diaspora.I18n.t("ignore_failed")); + }); + }, + + hidePost: function(evt) { + if (evt) { evt.preventDefault(); } + if (!confirm(Diaspora.I18n.t("confirm_dialog"))) { return; } + + var self = this; + $.ajax({ + url: Routes.shareVisibility(42), + type: "PUT", + data: { + /* eslint-disable camelcase */ + post_id: this.model.id + /* eslint-enable camelcase */ + } + }).done(function() { + self.post.remove(); + }).fail(function() { + app.flashMessages.error(Diaspora.I18n.t("hide_post_failed")); + }); + }, + + createParticipation: function(evt) { + if (evt) { evt.preventDefault(); } + var that = this; + $.post(Routes.postParticipation(this.model.get("id")), {}, function() { + that.model.set({participation: true}); + }); + }, + + destroyParticipation: function(evt) { + if (evt) { evt.preventDefault(); } + var that = this; + $.post(Routes.postParticipation(this.model.get("id")), {_method: "delete"}, function() { + that.model.set({participation: false}); + }); + } +}); +// @license-end diff --git a/app/assets/javascripts/app/views/stream_post_views.js b/app/assets/javascripts/app/views/stream_post_views.js index b298cd0ad..60812f6b9 100644 --- a/app/assets/javascripts/app/views/stream_post_views.js +++ b/app/assets/javascripts/app/views/stream_post_views.js @@ -5,38 +5,26 @@ app.views.StreamPost = app.views.Post.extend({ className : "stream_element loaded", subviews : { - ".feedback" : "feedbackView", - ".likes" : "likesInfoView", - ".reshares" : "resharesInfoView", - ".comments" : "commentStreamView", - ".post-content" : "postContentView", - ".oembed" : "oEmbedView", - ".opengraph" : "openGraphView", - ".poll" : "pollView", - ".status-message-location" : "postLocationStreamView" + ".feedback": "feedbackView", + ".comments": "commentStreamView", + ".likes": "likesInfoView", + ".reshares": "resharesInfoView", + ".post-controls": "postControlsView", + ".post-content": "postContentView", + ".oembed": "oEmbedView", + ".opengraph": "openGraphView", + ".poll": "pollView", + ".status-message-location": "postLocationStreamView" }, events: { "click .focus_comment_textarea": "focusCommentTextarea", "click .show_nsfw_post": "removeNsfwShield", - "click .toggle_nsfw_state": "toggleNsfwState", - - "click .remove_post": "destroyModel", - "click .hide_post": "hidePost", - "click .post_report": "report", - "click .block_user": "blockUser", - - "click .create_participation": "createParticipation", - "click .destroy_participation": "destroyParticipation" + "click .toggle_nsfw_state": "toggleNsfwState" }, tooltipSelector : [".timeago", ".post_scope", - ".post_report", - ".block_user", - ".delete", - ".create_participation", - ".destroy_participation", ".permalink"].join(", "), initialize : function(){ @@ -51,6 +39,9 @@ app.views.StreamPost = app.views.Post.extend({ this.pollView = new app.views.Poll({model : this.model}); }, + postControlsView: function() { + return new app.views.PostControls({model: this.model, post: this}); + }, likesInfoView : function(){ return new app.views.LikesInfo({model : this.model}); @@ -87,60 +78,12 @@ app.views.StreamPost = app.views.Post.extend({ app.currentUser.toggleNsfwState(); }, - - blockUser: function(evt){ - if(evt) { evt.preventDefault(); } - if(!confirm(Diaspora.I18n.t("ignore_user"))) { return } - - this.model.blockAuthor() - .fail(function() { - app.flashMessages.error(Diaspora.I18n.t("ignore_failed")); - }); - }, - remove : function() { $(this.el).slideUp(400, _.bind(function(){this.$el.remove()}, this)); app.stream.remove(this.model); return this; }, - hidePost : function(evt) { - if(evt) { evt.preventDefault(); } - if(!confirm(Diaspora.I18n.t("confirm_dialog"))) { return } - - var self = this; - $.ajax({ - url : "/share_visibilities/42", - type : "PUT", - data : { - post_id : this.model.id - } - }).done(function() { - self.remove(); - }) - .fail(function() { - app.flashMessages.error(Diaspora.I18n.t("hide_post_failed")); - }); - }, - - createParticipation: function (evt) { - if(evt) { evt.preventDefault(); } - var that = this; - $.post(Routes.postParticipation(this.model.get("id")), {}, function () { - that.model.set({participation: true}); - that.render(); - }); - }, - - destroyParticipation: function (evt) { - if(evt) { evt.preventDefault(); } - var that = this; - $.post(Routes.postParticipation(this.model.get("id")), { _method: "delete" }, function () { - that.model.set({participation: false}); - that.render(); - }); - }, - focusCommentTextarea: function(evt){ evt.preventDefault(); this.$(".new-comment-form-wrapper").removeClass("hidden"); @@ -148,6 +91,5 @@ app.views.StreamPost = app.views.Post.extend({ return this; } - }); // @license-end diff --git a/app/assets/templates/post-controls_tpl.jst.hbs b/app/assets/templates/post-controls_tpl.jst.hbs new file mode 100644 index 000000000..560f366f4 --- /dev/null +++ b/app/assets/templates/post-controls_tpl.jst.hbs @@ -0,0 +1,24 @@ +{{#if authorIsCurrentUser}} + + + +{{else}} + + + + + + + {{#if participation}} + + + + {{else}} + + + + {{/if}} + + + +{{/if}} diff --git a/app/assets/templates/stream-element_tpl.jst.hbs b/app/assets/templates/stream-element_tpl.jst.hbs index 2520c1e67..2c65c427a 100644 --- a/app/assets/templates/stream-element_tpl.jst.hbs +++ b/app/assets/templates/stream-element_tpl.jst.hbs @@ -7,34 +7,7 @@
{{#if loggedIn}} -
- {{#unless preview}} - {{#if authorIsCurrentUser}} - - - - {{else}} - - - - - - - {{#if participation}} - - - - {{else}} - - - - {{/if}} - - - - {{/if}} - {{/unless}} -
+
{{/if}}
diff --git a/spec/javascripts/app/views/post_controls_view_spec.js b/spec/javascripts/app/views/post_controls_view_spec.js new file mode 100644 index 000000000..01a5385cd --- /dev/null +++ b/spec/javascripts/app/views/post_controls_view_spec.js @@ -0,0 +1,200 @@ +describe("app.views.PostControls", function() { + describe("render", function() { + beforeEach(function() { + this.model = factory.post(); + this.view = new app.views.PostControls({model: this.model}); + }); + + context("in a post of the current user", function() { + beforeEach(function() { + app.currentUser = new app.models.User(this.model.attributes.author); + this.view.render(); + }); + + it("shows a delete button", function() { + expect(this.view.$(".delete.remove_post").length).toBe(1); + }); + + it("doesn't show a report button", function() { + expect(this.view.$(".post_report").length).toBe(0); + }); + + it("doesn't show an ignore button", function() { + expect(this.view.$(".block_user").length).toBe(0); + }); + + it("doesn't show participation buttons", function() { + expect(this.view.$(".create_participation").length).toBe(0); + expect(this.view.$(".destroy_participation").length).toBe(0); + }); + + it("doesn't show a hide button", function() { + expect(this.view.$(".delete.hide_post").length).toBe(0); + }); + }); + + context("in a post of another user", function() { + beforeEach(function() { + this.view.render(); + }); + + it("doesn't show a delete button", function() { + expect(this.view.$(".delete.remove_post").length).toBe(0); + }); + + it("shows a report button", function() { + expect(this.view.$(".post_report").length).toBe(1); + }); + + it("shows an ignore button", function() { + expect(this.view.$(".block_user").length).toBe(1); + }); + + it("shows a create participation button", function() { + expect(this.view.$(".create_participation").length).toBe(1); + expect(this.view.$(".destroy_participation").length).toBe(0); + }); + + it("shows a destroy participation button if the user participated", function() { + this.model.set({participation: true}); + this.view.render(); + expect(this.view.$(".create_participation").length).toBe(0); + expect(this.view.$(".destroy_participation").length).toBe(1); + }); + + it("shows a hide button", function() { + expect(this.view.$(".delete.hide_post").length).toBe(1); + }); + }); + }); + + describe("events", function() { + beforeEach(function() { + this.model = factory.post(); + }); + + it("calls destroyModel when removing a post", function() { + spyOn(app.views.PostControls.prototype, "destroyModel"); + app.currentUser = new app.models.User(this.model.attributes.author); + this.view = new app.views.PostControls({model: this.model}); + this.view.render(); + this.view.$(".remove_post.delete").click(); + expect(app.views.PostControls.prototype.destroyModel).toHaveBeenCalled(); + }); + + it("calls hidePost when hiding a post", function() { + spyOn(app.views.PostControls.prototype, "hidePost"); + this.view = new app.views.PostControls({model: this.model}); + this.view.render(); + this.view.$(".hide_post.delete").click(); + expect(app.views.PostControls.prototype.hidePost).toHaveBeenCalled(); + }); + + it("calls report when reporting a post", function() { + spyOn(app.views.PostControls.prototype, "report"); + this.view = new app.views.PostControls({model: this.model}); + this.view.render(); + this.view.$(".post_report").click(); + expect(app.views.PostControls.prototype.report).toHaveBeenCalled(); + }); + + it("calls blockUser when blocking the user", function() { + spyOn(app.views.PostControls.prototype, "blockUser"); + this.view = new app.views.PostControls({model: this.model}); + this.view.render(); + this.view.$(".block_user").click(); + expect(app.views.PostControls.prototype.blockUser).toHaveBeenCalled(); + }); + + it("calls createParticipation when creating a participation", function() { + spyOn(app.views.PostControls.prototype, "createParticipation"); + this.view = new app.views.PostControls({model: this.model}); + this.view.render(); + this.view.$(".create_participation").click(); + expect(app.views.PostControls.prototype.createParticipation).toHaveBeenCalled(); + }); + + it("calls destroyParticipation when destroying a participation", function() { + spyOn(app.views.PostControls.prototype, "destroyParticipation"); + this.model.set({participation: true}); + this.view = new app.views.PostControls({model: this.model}); + this.view.render(); + this.view.$(".destroy_participation").click(); + expect(app.views.PostControls.prototype.destroyParticipation).toHaveBeenCalled(); + }); + }); + + describe("initialize", function() { + it("rerenders the view when the model has been changed", function() { + spyOn(app.views.PostControls.prototype, "render"); + this.model = factory.post(); + this.view = new app.views.PostControls({model: this.model}); + expect(app.views.PostControls.prototype.render).not.toHaveBeenCalled(); + this.model.trigger("change"); + expect(app.views.PostControls.prototype.render).toHaveBeenCalled(); + }); + }); + + describe("blockUser", function() { + beforeEach(function() { + spyOn(window, "confirm").and.returnValue(true); + this.model = factory.post(); + this.view = new app.views.PostControls({model: this.model}); + this.view.render(); + }); + + it("asks for a confirmation", function() { + this.view.blockUser(); + expect(window.confirm).toHaveBeenCalledWith(Diaspora.I18n.t("ignore_user")); + }); + + it("calls blockAuthor", function() { + spyOn(this.model, "blockAuthor").and.callThrough(); + this.view.blockUser(); + expect(this.model.blockAuthor).toHaveBeenCalled(); + }); + + it("shows a flash message when errors occur", function() { + spyOn(app.flashMessages, "error"); + this.view.blockUser(); + jasmine.Ajax.requests.mostRecent().respondWith({status: 422}); + expect(app.flashMessages.error).toHaveBeenCalledWith(Diaspora.I18n.t("ignore_failed")); + }); + }); + + describe("hidePost", function() { + beforeEach(function() { + spyOn(window, "confirm").and.returnValue(true); + this.postView = {remove: function() { return; }}; + this.model = factory.post(); + this.view = new app.views.PostControls({model: this.model, post: this.postView}); + this.view.render(); + }); + + it("asks for a confirmation", function() { + this.view.hidePost(); + expect(window.confirm).toHaveBeenCalledWith(Diaspora.I18n.t("confirm_dialog")); + }); + + it("sends an ajax request with the correct post id", function() { + this.view.hidePost(); + expect(jasmine.Ajax.requests.mostRecent().url).toBe(Routes.shareVisibility(42)); + expect(jasmine.Ajax.requests.mostRecent().data().post_id).toEqual(["" + this.model.get("id")]); + expect(jasmine.Ajax.requests.mostRecent().method).toBe("PUT"); + }); + + it("removes the post on success", function() { + spyOn(this.view.post, "remove"); + this.view.hidePost(); + jasmine.Ajax.requests.mostRecent().respondWith({status: 204}); + expect(this.view.post.remove).toHaveBeenCalled(); + }); + + it("shows a flash message when errors occur", function() { + spyOn(app.flashMessages, "error"); + this.view.hidePost(); + jasmine.Ajax.requests.mostRecent().respondWith({status: 422}); + expect(app.flashMessages.error).toHaveBeenCalledWith(Diaspora.I18n.t("hide_post_failed")); + }); + }); +}); From 02742a4a8fc38be7e22614d10dde575f4e22d4f4 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Tue, 30 Aug 2016 16:33:29 +0200 Subject: [PATCH 3/4] Use post controls view for single post moderation --- .../javascripts/app/views/feedback_view.js | 37 ---------------- .../app/views/post_controls_view.js | 23 +++++----- .../single_post_moderation.js | 43 +------------------ .../app/views/post_controls_view_spec.js | 27 ++++++++++++ 4 files changed, 42 insertions(+), 88 deletions(-) diff --git a/app/assets/javascripts/app/views/feedback_view.js b/app/assets/javascripts/app/views/feedback_view.js index 70bf4ca6d..81d8d03e8 100644 --- a/app/assets/javascripts/app/views/feedback_view.js +++ b/app/assets/javascripts/app/views/feedback_view.js @@ -8,10 +8,6 @@ app.views.Feedback = app.views.Base.extend({ events: { "click .like" : "toggleLike", "click .reshare" : "resharePost", - - "click .post_report" : "report", - "click .block_user" : "blockUser", - "click .hide_post" : "hidePost" }, tooltipSelector : ".label", @@ -43,39 +39,6 @@ app.views.Feedback = app.views.Base.extend({ if(evt) { evt.preventDefault(); } if(!window.confirm(Diaspora.I18n.t("reshares.post", {name: this.model.reshareAuthor().name}))) { return } this.model.interactions.reshare(); - }, - - blockUser: function(evt) { - if(evt) { evt.preventDefault(); } - if(!confirm(Diaspora.I18n.t("ignore_user"))) { return; } - - this.model.blockAuthor() - .done(function() { - // return to stream - document.location.href = "/stream"; - }) - .fail(function() { - app.flashMessages.error(Diaspora.I18n.t("hide_post_failed")); - }); - }, - - hidePost : function(evt) { - if(evt) { evt.preventDefault(); } - if(!confirm(Diaspora.I18n.t("hide_post"))) { return; } - - $.ajax({ - url : "/share_visibilities/42", - type : "PUT", - data : { - post_id : this.model.id - } - }).done(function() { - // return to stream - document.location.href = "/stream"; - }) - .fail(function() { - app.flashMessages.error(Diaspora.I18n.t("ignore_post_failed")); - }); } }); // @license-end diff --git a/app/assets/javascripts/app/views/post_controls_view.js b/app/assets/javascripts/app/views/post_controls_view.js index 796e8565a..78c0ee3df 100644 --- a/app/assets/javascripts/app/views/post_controls_view.js +++ b/app/assets/javascripts/app/views/post_controls_view.js @@ -34,7 +34,9 @@ app.views.PostControls = app.views.Base.extend({ if (evt) { evt.preventDefault(); } if (!confirm(Diaspora.I18n.t("ignore_user"))) { return; } - this.model.blockAuthor().fail(function() { + this.model.blockAuthor().done(function() { + if (this.singlePost) { app._changeLocation(Routes.stream()); } + }.bind(this)).fail(function() { app.flashMessages.error(Diaspora.I18n.t("ignore_failed")); }); }, @@ -43,7 +45,6 @@ app.views.PostControls = app.views.Base.extend({ if (evt) { evt.preventDefault(); } if (!confirm(Diaspora.I18n.t("confirm_dialog"))) { return; } - var self = this; $.ajax({ url: Routes.shareVisibility(42), type: "PUT", @@ -53,26 +54,28 @@ app.views.PostControls = app.views.Base.extend({ /* eslint-enable camelcase */ } }).done(function() { - self.post.remove(); - }).fail(function() { + if (this.singlePost) { + app._changeLocation(Routes.stream()); + } else { + this.post.remove(); + } + }.bind(this)).fail(function() { app.flashMessages.error(Diaspora.I18n.t("hide_post_failed")); }); }, createParticipation: function(evt) { if (evt) { evt.preventDefault(); } - var that = this; $.post(Routes.postParticipation(this.model.get("id")), {}, function() { - that.model.set({participation: true}); - }); + this.model.set({participation: true}); + }.bind(this)); }, destroyParticipation: function(evt) { if (evt) { evt.preventDefault(); } - var that = this; $.post(Routes.postParticipation(this.model.get("id")), {_method: "delete"}, function() { - that.model.set({participation: false}); - }); + this.model.set({participation: false}); + }.bind(this)); } }); // @license-end diff --git a/app/assets/javascripts/app/views/single-post-viewer/single_post_moderation.js b/app/assets/javascripts/app/views/single-post-viewer/single_post_moderation.js index 823783da3..3599da357 100644 --- a/app/assets/javascripts/app/views/single-post-viewer/single_post_moderation.js +++ b/app/assets/javascripts/app/views/single-post-viewer/single_post_moderation.js @@ -1,31 +1,12 @@ -app.views.SinglePostModeration = app.views.Feedback.extend({ +app.views.SinglePostModeration = app.views.PostControls.extend({ templateName: "single-post-viewer/single-post-moderation", - - className: "control-icons", - - events: function() { - return _.defaults({ - "click .remove_post": "destroyModel", - "click .create_participation": "createParticipation", - "click .destroy_participation": "destroyParticipation" - }, app.views.Feedback.prototype.events); - }, - - presenter: function() { - return _.extend(this.defaultPresenter(), { - authorIsCurrentUser : this.authorIsCurrentUser() - }); - }, + singlePost: true, renderPluginWidgets : function() { app.views.Base.prototype.renderPluginWidgets.apply(this); this.$("a").tooltip({placement: "bottom"}); }, - authorIsCurrentUser: function() { - return app.currentUser.authenticated() && this.model.get("author").id === app.user().id; - }, - destroyModel: function(evt) { if(evt) { evt.preventDefault(); } var url = this.model.urlRoot + "/" + this.model.id; @@ -41,24 +22,4 @@ app.views.SinglePostModeration = app.views.Feedback.extend({ }); } }, - - createParticipation: function (evt) { - if(evt) { evt.preventDefault(); } - var self = this; - $.post(Routes.postParticipation(this.model.get("id")), {}, function () { - self.model.set({participation: true}); - self.render(); - }); - }, - - destroyParticipation: function (evt) { - if(evt) { evt.preventDefault(); } - var self = this; - $.post(Routes.postParticipation(this.model.get("id")), { _method: "delete" }, function () { - self.model.set({participation: false}); - self.render(); - }); - }, - - participation: function(){ return this.model.get("participation"); } }); diff --git a/spec/javascripts/app/views/post_controls_view_spec.js b/spec/javascripts/app/views/post_controls_view_spec.js index 01a5385cd..e85cf571f 100644 --- a/spec/javascripts/app/views/post_controls_view_spec.js +++ b/spec/javascripts/app/views/post_controls_view_spec.js @@ -154,6 +154,21 @@ describe("app.views.PostControls", function() { expect(this.model.blockAuthor).toHaveBeenCalled(); }); + it("doesn't redirect to the stream page on success", function() { + spyOn(app, "_changeLocation"); + this.view.blockUser(); + jasmine.Ajax.requests.mostRecent().respondWith({status: 204}); + expect(app._changeLocation).not.toHaveBeenCalled(); + }); + + it("redirects to the stream page on success from the single post view", function() { + spyOn(app, "_changeLocation"); + this.view.singlePost = true; + this.view.blockUser(); + jasmine.Ajax.requests.mostRecent().respondWith({status: 204}); + expect(app._changeLocation).toHaveBeenCalledWith(Routes.stream()); + }); + it("shows a flash message when errors occur", function() { spyOn(app.flashMessages, "error"); this.view.blockUser(); @@ -185,9 +200,21 @@ describe("app.views.PostControls", function() { it("removes the post on success", function() { spyOn(this.view.post, "remove"); + spyOn(app, "_changeLocation"); this.view.hidePost(); jasmine.Ajax.requests.mostRecent().respondWith({status: 204}); expect(this.view.post.remove).toHaveBeenCalled(); + expect(app._changeLocation).not.toHaveBeenCalled(); + }); + + it("redirects to the stream page on success from the single post view", function() { + spyOn(this.view.post, "remove"); + spyOn(app, "_changeLocation"); + this.view.singlePost = true; + this.view.hidePost(); + jasmine.Ajax.requests.mostRecent().respondWith({status: 204}); + expect(this.view.post.remove).not.toHaveBeenCalled(); + expect(app._changeLocation).toHaveBeenCalledWith(Routes.stream()); }); it("shows a flash message when errors occur", function() { From 9a2cb1517a9f35f700f50a3870287b55bf97f87d Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Tue, 30 Aug 2016 16:34:06 +0200 Subject: [PATCH 4/4] Set participations client side when changing post interactions closes #7040 --- Changelog.md | 5 +++-- .../app/models/post/interactions.js | 3 +++ features/desktop/likes.feature | 6 +++++- .../step_definitions/notifications_steps.rb | 11 ++++++++++ .../app/models/post/interacations_spec.js | 21 ++++++++++++++++--- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index f8d6cea31..9b85d004e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,10 +6,11 @@ * Make the session cookies HttpOnly again [#7041](https://github.com/diaspora/diaspora/pull/7041) ## Bug fixes -* Post comments no longer get collapsed when interacting with a post [#7045](https://github.com/diaspora/diaspora/pull/7045) +* Post comments no longer get collapsed when interacting with a post [#7040](https://github.com/diaspora/diaspora/pull/7040) ## Features -* The "subscribe" indicator on a post now gets toggled when you like or rehsare a post [#7045](https://github.com/diaspora/diaspora/pull/7045) +* Deleted comments will be removed when loading more comments [#7045](https://github.com/diaspora/diaspora/pull/7045) +* The "subscribe" indicator on a post now gets toggled when you like or rehsare a post [#7040](https://github.com/diaspora/diaspora/pull/7040) # 0.6.0.0 diff --git a/app/assets/javascripts/app/models/post/interactions.js b/app/assets/javascripts/app/models/post/interactions.js index e837f96bc..28d6f3a57 100644 --- a/app/assets/javascripts/app/models/post/interactions.js +++ b/app/assets/javascripts/app/models/post/interactions.js @@ -67,6 +67,7 @@ app.models.Post.Interactions = Backbone.Model.extend({ var self = this; this.likes.create({}, { success: function() { + self.post.set({participation: true}); self.trigger("change"); self.set({"likes_count" : self.get("likes_count") + 1}); }, @@ -94,6 +95,7 @@ app.models.Post.Interactions = Backbone.Model.extend({ this.comments.make(text).fail(function () { app.flashMessages.error(Diaspora.I18n.t("failed_to_comment")); }).done(function() { + self.post.set({participation: true}); self.trigger('change'); //updates after sync }); @@ -109,6 +111,7 @@ app.models.Post.Interactions = Backbone.Model.extend({ .done(function(reshare) { app.flashMessages.success(Diaspora.I18n.t("reshares.successful")); interactions.reshares.add(reshare); + interactions.post.set({participation: true}); if (app.stream && /^\/(?:stream|activity|aspects)/.test(app.stream.basePath())) { app.stream.addNow(reshare); } diff --git a/features/desktop/likes.feature b/features/desktop/likes.feature index 3fff3ce56..b32c7af62 100644 --- a/features/desktop/likes.feature +++ b/features/desktop/likes.feature @@ -14,9 +14,11 @@ Feature: Liking posts And I sign in as "alice@alice.alice" Scenario: Liking and unliking a post from the stream + Then I should not have activated notifications for the post When I like the post "I like unicorns" in the stream Then I should see "Unlike" within ".stream_element .feedback" And I should see a ".likes .media" within "#main_stream .stream_element" + And I should have activated notifications for the post When I unlike the post "I like unicorns" in the stream Then I should see "Like" within ".stream_element .feedback" @@ -25,8 +27,10 @@ Feature: Liking posts Scenario: Liking and unliking a post from a single post page When I open the show page of the "I like unicorns" post - And I click to like the post + Then I should not have activated notifications for the post in the single post view + When I click to like the post Then I should see a ".count" within "#single-post-interactions" + And I should have activated notifications for the post in the single post view When I click to unlike the post Then I should not see a ".count" within "#single-post-interactions" diff --git a/features/step_definitions/notifications_steps.rb b/features/step_definitions/notifications_steps.rb index c61fbf567..ba12d3403 100644 --- a/features/step_definitions/notifications_steps.rb +++ b/features/step_definitions/notifications_steps.rb @@ -5,3 +5,14 @@ end When /^I filter notifications by mentions$/ do step %(I follow "Mentioned" within "#notifications_container .list-group") end + +Then /^I should( not)? have activated notifications for the post( in the single post view)?$/ do |negate, spv| + selector = spv ? "#single-post-moderation" : "#main_stream .stream_element" + if negate + expect(find(selector, match: :first)).to have_no_css(".destroy_participation", visible: false) + expect(find(selector, match: :first)).to have_css(".create_participation", visible: false) + else + expect(find(selector, match: :first)).to have_css(".destroy_participation", visible: false) + expect(find(selector, match: :first)).to have_no_css(".create_participation", visible: false) + end +end diff --git a/spec/javascripts/app/models/post/interacations_spec.js b/spec/javascripts/app/models/post/interacations_spec.js index fe5eda94b..6b2b66e37 100644 --- a/spec/javascripts/app/models/post/interacations_spec.js +++ b/spec/javascripts/app/models/post/interacations_spec.js @@ -1,6 +1,9 @@ describe("app.models.Post.Interactions", function(){ + var ajaxSuccess = {status: 200, responseText: "{\"id\": 1}"}; + beforeEach(function(){ - this.interactions = factory.post().interactions; + this.post = factory.post(); + this.interactions = this.post.interactions; this.author = factory.author({guid: "loggedInAsARockstar"}); loginAs({guid: "loggedInAsARockstar"}); @@ -30,6 +33,13 @@ describe("app.models.Post.Interactions", function(){ this.interactions.like(); expect(this.interactions.likes.length).toEqual(1); }); + + it("sets the participation flag for the post", function() { + expect(this.post.get("participation")).toBeFalsy(); + this.interactions.like(); + jasmine.Ajax.requests.mostRecent().respondWith(ajaxSuccess); + expect(this.post.get("participation")).toBeTruthy(); + }); }); describe("unlike", function(){ @@ -42,8 +52,6 @@ describe("app.models.Post.Interactions", function(){ }); describe("reshare", function() { - var ajaxSuccess = { status: 200, responseText: "{\"id\": 1}" }; - beforeEach(function(){ this.reshare = this.interactions.post.reshare(); }); @@ -81,6 +89,13 @@ describe("app.models.Post.Interactions", function(){ expect(app.stream.addNow).not.toHaveBeenCalled(); }); }); + + it("sets the participation flag for the post", function() { + expect(this.post.get("participation")).toBeFalsy(); + this.interactions.reshare(); + jasmine.Ajax.requests.mostRecent().respondWith(ajaxSuccess); + expect(this.post.get("participation")).toBeTruthy(); + }); }); describe("userLike", function(){