Merge branch 'next-minor' into develop

This commit is contained in:
Benjamin Neff 2016-11-02 23:03:36 +01:00
commit 694d4cbc0f
15 changed files with 131 additions and 32 deletions

View file

@ -11,6 +11,7 @@
## Refactor
## Bug fixes
* Fix fetching comments after fetching likes [#7167](https://github.com/diaspora/diaspora/pull/7167)
## Features

View file

@ -2,6 +2,9 @@
app.collections.Reshares = Backbone.Collection.extend({
model: app.models.Reshare,
url : "/reshares"
initialize: function(models, options) {
this.url = "/posts/" + options.post.id + "/reshares";
}
});
// @license-end

View file

@ -70,6 +70,7 @@ app.models.Post.Interactions = Backbone.Model.extend({
self.post.set({participation: true});
self.trigger("change");
self.set({"likes_count" : self.get("likes_count") + 1});
self.likes.trigger("change");
},
error: function() {
app.flashMessages.error(Diaspora.I18n.t("failed_to_like"));
@ -84,6 +85,7 @@ app.models.Post.Interactions = Backbone.Model.extend({
this.userLike().destroy({success : function() {
self.trigger('change');
self.set({"likes_count" : self.get("likes_count") - 1});
self.likes.trigger("change");
}});
app.instrument("track", "Unlike");
@ -116,6 +118,8 @@ app.models.Post.Interactions = Backbone.Model.extend({
app.stream.addNow(reshare);
}
interactions.trigger("change");
interactions.set({"reshares_count": interactions.get("reshares_count") + 1});
interactions.reshares.trigger("change");
})
.fail(function(){
app.flashMessages.error(Diaspora.I18n.t("reshares.duplicate"));

View file

@ -11,7 +11,7 @@ app.views.LikesInfo = app.views.Base.extend({
tooltipSelector : ".avatar",
initialize : function() {
this.model.interactions.bind('change', this.render, this);
this.model.interactions.likes.on("change", this.render, this);
this.displayAvatars = false;
},
@ -19,18 +19,16 @@ app.views.LikesInfo = app.views.Base.extend({
return _.extend(this.defaultPresenter(), {
likes : this.model.interactions.likes.toJSON(),
likesCount : this.model.interactions.likesCount(),
displayAvatars : this.model.interactions.get("fetched") && this.displayAvatars
displayAvatars: this.displayAvatars
});
},
showAvatars : function(evt){
if(evt) { evt.preventDefault() }
this.displayAvatars = true;
if(!this.model.interactions.get("fetched")){
this.model.interactions.fetch();
} else {
this.model.interactions.trigger("change");
}
this.model.interactions.likes.fetch({success: function() {
this.model.interactions.likes.trigger("change");
}.bind(this)});
}
});
// @license-end

View file

@ -11,7 +11,7 @@ app.views.ResharesInfo = app.views.Base.extend({
tooltipSelector : ".avatar",
initialize : function() {
this.model.interactions.bind("change", this.render, this);
this.model.interactions.reshares.bind("change", this.render, this);
this.displayAvatars = false;
},
@ -19,18 +19,16 @@ app.views.ResharesInfo = app.views.Base.extend({
return _.extend(this.defaultPresenter(), {
reshares : this.model.interactions.reshares.toJSON(),
resharesCount : this.model.interactions.resharesCount(),
displayAvatars : this.model.interactions.get("fetched") && this.displayAvatars
displayAvatars: this.displayAvatars
});
},
showAvatars : function(evt){
if(evt) { evt.preventDefault() }
this.displayAvatars = true;
if(!this.model.interactions.get("fetched")){
this.model.interactions.fetch();
} else {
this.model.interactions.trigger("change");
}
this.model.interactions.reshares.fetch({success: function() {
this.model.interactions.reshares.trigger("change");
}.bind(this)});
}
});
// @license-end

View file

@ -17,4 +17,16 @@ class ResharesController < ApplicationController
render :nothing => true, :status => 422
end
end
def index
@reshares = target.reshares.includes(author: :profile)
render json: @reshares.as_api_response(:backbone)
end
private
def target
@target ||= current_user.find_visible_shareable_by_id(Post, params[:post_id]) ||
raise(ActiveRecord::RecordNotFound.new)
end
end

View file

@ -21,6 +21,14 @@ class Reshare < Post
self.root.update_reshares_counter if self.root.present?
end
acts_as_api
api_accessible :backbone do |t|
t.add :id
t.add :guid
t.add :author
t.add :created_at
end
def root_diaspora_id
root.try(:author).try(:diaspora_handle)
end

View file

@ -38,6 +38,7 @@ Diaspora::Application.routes.draw do
resources :poll_participations, only: :create
resources :likes, only: %i(create destroy index)
resources :comments, only: %i(new create destroy index)
resources :reshares, only: :index
end
get 'p/:id' => 'posts#show', :as => 'short_post'

View file

@ -73,3 +73,16 @@ Feature: commenting
When I follow "less than a minute ago" within ".comments .comment:last-child"
Then I should see "I think thats a cat" within ".comments .comment .highlighted"
And I should have scrolled down
Scenario: Show more comments after loading likes
When "alice@alice.alice" has commented a lot on "Look at this dog"
And "alice@alice.alice" has liked the post "Look at this dog"
And I am on "alice@alice.alice"'s page
Then I should see "Look at this dog"
And I should not see "Comment 2"
When I follow "1 Like"
Then I should not see "1 Like"
When I click on selector ".toggle_post_comments"
Then I should see "Comment 2"

View file

@ -0,0 +1,5 @@
Given /^"([^"]*)" has liked the post "([^"]*)"$/ do |email, post_text|
user = User.find_by(email: email)
post = StatusMessage.find_by(text: post_text)
user.like!(post)
end

View file

@ -101,12 +101,6 @@ describe LikesController, :type => :controller do
@message = alice.comment!(@message, "hey") if class_const == Comment
end
it 'generates a jasmine fixture', :fixture => true do
get :index, id_field => @message.id
save_fixture(response.body, "ajax_likes_on_#{class_const.to_s.underscore}")
end
it 'returns a 404 for a post not visible to the user' do
sign_in eve
expect{get :index, id_field => @message.id}.to raise_error(ActiveRecord::RecordNotFound)

View file

@ -64,4 +64,44 @@ describe ResharesController, :type => :controller do
end
end
end
describe "#index" do
context "with a private post" do
before do
@alices_aspect = alice.aspects.where(name: "generic").first
@post = alice.post(:status_message, text: "hey", to: @alices_aspect.id)
end
it "returns a 404 for a post not visible to the user" do
sign_in(eve, scope: :user)
expect {
get :index, post_id: @post.id, format: :json
}.to raise_error(ActiveRecord::RecordNotFound)
end
it "returns an empty array for a post visible to the user" do
sign_in(bob, scope: :user)
get :index, post_id: @post.id, format: :json
expect(JSON.parse(response.body)).to eq([])
end
end
context "with a public post" do
before do
sign_in(alice, scope: :user)
@post = alice.post(:status_message, text: "hey", public: true)
end
it "returns an array of reshares for a post" do
bob.reshare!(@post)
get :index, post_id: @post.id, format: :json
expect(JSON.parse(response.body).map {|h| h["id"] }).to eq(@post.reshares.map(&:id))
end
it "returns an empty array for a post with no reshares" do
get :index, post_id: @post.id, format: :json
expect(JSON.parse(response.body)).to eq([])
end
end
end
end

View file

@ -40,6 +40,13 @@ describe("app.models.Post.Interactions", function(){
jasmine.Ajax.requests.mostRecent().respondWith(ajaxSuccess);
expect(this.post.get("participation")).toBeTruthy();
});
it("triggers a change on the likes collection", function() {
spyOn(this.interactions.likes, "trigger");
this.interactions.like();
jasmine.Ajax.requests.mostRecent().respondWith(ajaxSuccess);
expect(this.interactions.likes.trigger).toHaveBeenCalledWith("change");
});
});
describe("unlike", function(){
@ -56,7 +63,7 @@ describe("app.models.Post.Interactions", function(){
this.reshare = this.interactions.post.reshare();
});
it("triggers a change on the model", function() {
it("triggers a change on the interactions model", function() {
spyOn(this.interactions, "trigger");
this.interactions.reshare();
@ -65,6 +72,13 @@ describe("app.models.Post.Interactions", function(){
expect(this.interactions.trigger).toHaveBeenCalledWith("change");
});
it("triggers a change on the reshares collection", function() {
spyOn(this.interactions.reshares, "trigger");
this.interactions.reshare();
jasmine.Ajax.requests.mostRecent().respondWith(ajaxSuccess);
expect(this.interactions.reshares.trigger).toHaveBeenCalledWith("change");
});
it("adds the reshare to the default, activity and aspects stream", function() {
app.stream = { addNow: $.noop };
spyOn(app.stream, "addNow");

View file

@ -21,19 +21,23 @@ describe("app.views.LikesInfo", function(){
it("fires on a model change", function(){
spyOn(this.view, "postRenderTemplate");
this.view.model.interactions.trigger('change');
this.view.model.interactions.likes.trigger("change");
expect(this.view.postRenderTemplate).toHaveBeenCalled();
});
});
describe("showAvatars", function(){
beforeEach(function(){
spyOn(this.post.interactions, "fetch").and.callThrough();
it("calls fetch on the model's like collection", function() {
spyOn(this.post.interactions.likes, "fetch").and.callThrough();
this.view.showAvatars();
expect(this.post.interactions.likes.fetch).toHaveBeenCalled();
});
it("calls fetch on the model's like collection", function(){
it("triggers 'change' on the likes collection", function() {
spyOn(this.post.interactions.likes, "trigger");
this.view.showAvatars();
expect(this.post.interactions.fetch).toHaveBeenCalled();
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, responseText: "{\"id\": 1}"});
expect(this.post.interactions.likes.trigger).toHaveBeenCalledWith("change");
});
it("sets 'displayAvatars' to true", function(){

View file

@ -22,19 +22,23 @@ describe("app.views.ResharesInfo", function(){
it("fires on a model change", function(){
spyOn(this.view, "postRenderTemplate");
this.view.model.interactions.trigger("change");
this.view.model.interactions.reshares.trigger("change");
expect(this.view.postRenderTemplate).toHaveBeenCalled();
});
});
describe("showAvatars", function(){
beforeEach(function(){
spyOn(this.post.interactions, "fetch").and.callThrough();
it("calls fetch on the model's reshare collection", function() {
spyOn(this.post.interactions.reshares, "fetch").and.callThrough();
this.view.showAvatars();
expect(this.post.interactions.reshares.fetch).toHaveBeenCalled();
});
it("calls fetch on the model's reshare collection", function(){
it("triggers 'change' on the reshares collection", function() {
spyOn(this.post.interactions.reshares, "trigger");
this.view.showAvatars();
expect(this.post.interactions.fetch).toHaveBeenCalled();
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, responseText: "{\"id\": 1}"});
expect(this.post.interactions.reshares.trigger).toHaveBeenCalledWith("change");
});
it("sets 'displayAvatars' to true", function(){