first round of specs and code cleanups/fixes

This commit is contained in:
Florian Staudacher 2014-09-10 03:33:43 +02:00
parent e4ee28885a
commit 89d468cdcc
14 changed files with 277 additions and 189 deletions

View file

@ -2,9 +2,10 @@
//= require ../collections/photos
app.models.Stream = Backbone.Collection.extend({
initialize : function(models, options){
var collectionClass = app.collections.Posts
if( options ) {
var collectionClass = options.collection || app.collections.Posts;
this.streamPath = options.basePath;
options.collection && (collectionClass = options.collection);
options.basePath && (this.streamPath = options.basePath);
}
this.items = new collectionClass([], this.collectionOptions());
},

View file

@ -37,6 +37,7 @@ app.pages.Profile = app.views.Base.extend({
var id = this.model.get('id');
app.events.on('person:block:'+id, this.reload, this);
app.events.on('person:unblock:'+id, this.reload, this);
app.events.on('aspect:create', this.reload, this);
app.events.on('aspect_membership:update', this.reload, this);
},

View file

@ -2,6 +2,10 @@
app.views.ProfileHeader = app.views.Base.extend({
templateName: 'profile_header',
initialize: function() {
app.events.on('aspect:create', this.postRenderTemplate, this);
},
presenter: function() {
return _.extend({}, this.defaultPresenter(), {
is_blocked: this.model.isBlocked(),
@ -25,6 +29,9 @@ app.views.ProfileHeader = app.views.Base.extend({
$.get(href, function(resp) {
dropdownEl.html(resp);
new app.views.AspectMembership({el: dropdownEl});
})
// UGLY (re-)attach the facebox
self.$('a[rel*=facebox]').facebox();
});
}
});

View file

@ -3,8 +3,8 @@
# the COPYRIGHT file.
class PeopleController < ApplicationController
before_action :authenticate_user!, except: [:show, :last_post]
before_action :find_person, only: [:show, :stream]
before_action :authenticate_user!, except: [:show, :stream, :last_post]
before_action :find_person, only: [:show, :stream, :hovercard]
use_bootstrap_for :index
@ -78,23 +78,10 @@ class PeopleController < ApplicationController
mark_corresponding_notifications_read if user_signed_in?
@aspect = :profile # let aspect dropdown create new aspects
@post_type = :all # for mobile
@person_json = PersonPresenter.new(@person, current_user).full_hash_with_profile
respond_to do |format|
format.all do
@profile = @person.profile
if current_user
@block = current_user.blocks.where(:person_id => @person.id).first
@contact = current_user.contact_for(@person)
if @contact && !params[:only_posts]
@contacts_of_contact_count = contact_contacts.count(:all)
@contacts_of_contact = contact_contacts.limit(8)
else
@contact ||= Contact.new
end
end
gon.preloads[:person] = @person_json
gon.preloads[:photos] = {
count: photos_from(@person).count(:all),
@ -104,29 +91,31 @@ class PeopleController < ApplicationController
count: contact_contacts.count(:all),
items: PersonPresenter.as_collection(contact_contacts.limit(8), :full_hash_with_avatar, current_user)
}
respond_with @person, :locals => {:post_type => :all}
respond_with @person
end
format.json { render :json => @person_json }
format.mobile do
@post_type = :all
person_stream
respond_with @person
end
format.json { render json: @person_json }
end
end
def stream
respond_to do |format|
format.all { redirect_to person_path(@person) }
format.json do
@stream = Stream::Person.new(current_user, @person, max_time: max_time)
render json: @stream.stream_posts.map { |p| LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user)) }
end
format.json {
render json: person_stream.stream_posts.map { |p| LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user)) }
}
end
end
# hovercards fetch some the persons public profile data via json and display
# it next to the avatar image in a nice box
def hovercard
@person = Person.find_from_guid_or_username({:id => params[:person_id]})
raise Diaspora::AccountClosed if @person.closed_account?
respond_to do |format|
format.all do
redirect_to :action => "show", :id => params[:person_id]
@ -220,7 +209,6 @@ class PeopleController < ApplicationController
end
def photos_from(person)
return Photo.none unless user_signed_in?
@photos ||= if user_signed_in?
current_user.photos_from(person)
else
@ -247,4 +235,8 @@ class PeopleController < ApplicationController
n.set_read_state( true )
end
end
def person_stream
@stream ||= Stream::Person.new(current_user, @person, max_time: max_time)
end
end

View file

@ -51,4 +51,20 @@ LISTITEM
end
options
end
def publisher_aspects_for(stream=nil)
if stream
aspects = stream.aspects
aspect = stream.aspect
aspect_ids = stream.aspect_ids
elsif current_user
aspects = current_user.aspects
aspect = aspects.first
aspect_ids = current_user.aspect_ids
else
return {}
end
{ aspects: aspects, aspect: aspect, aspect_ids: aspect_ids }
end
end

View file

@ -104,6 +104,11 @@ module User::Querying
contact_for_person_id(person.id)
end
def block_for(person)
return nil unless person
self.blocks.where(person_id: person.id).limit(1).first
end
def aspects_with_shareable(base_class_name_or_class, shareable_id)
base_class_name = base_class_name_or_class
base_class_name = base_class_name_or_class.base_class.to_s if base_class_name_or_class.is_a?(Class)

View file

@ -67,7 +67,7 @@ class PersonPresenter < BasePresenter
private
def current_user_person_block
@block ||= (current_user ? current_user.blocks.where(person_id: id).limit(1).first : Block.none)
@block ||= (current_user ? current_user.block_for(@presentable) : Block.none)
end
def current_user_person_contact

View file

@ -6,18 +6,7 @@
%h3#aspect_stream_header.stream_title
= stream.title
- aspects = current_user.aspects
- aspect = aspects.first
- aspect_ids = aspects.map { |a| a.id }
- if stream
- aspects = stream.aspects
- aspect = stream.aspect
- aspect_ids = stream.aspect_ids
= render 'publisher/publisher',
selected_aspects: aspects,
aspect_ids: aspect_ids,
aspect: aspect
= render 'publisher/publisher', publisher_aspects_for(stream)
= render 'aspects/no_posts_message'
#gs-shim{:title => popover_with_close_html("3. #{t('.stay_updated')}"), 'data-content' => t('.stay_updated_explanation')}

View file

@ -12,6 +12,8 @@ if( app.aspectMemberships ) {
app.aspectMemberships.dropdown = dropdown;
app.aspectMemberships.updateSummary();
$.facebox.close();
$('#profile .dropdown').toggleClass("active");
}
$.facebox.close();
app.events.trigger('aspect:create', "<%= escape_javascript(@aspect.id) =>");

View file

@ -2,7 +2,7 @@
-# licensed under the Affero General Public License version 3 or later. See
-# the COPYRIGHT file.
#profile
.badge
.profile_photo
= person_image_link(person, :size => :thumb_large, :to => :photos)

View file

@ -12,7 +12,8 @@
= @person.name
.span-6
= render :partial => 'people/profile_sidebar', :locals => {:person => @person, :contact => @contact }
#profile
-# = render :partial => 'people/profile_sidebar', :locals => {:person => @person, :contact => @contact }
.span-18.last
.profile_header

View file

@ -13,7 +13,7 @@
.clear
.bottom_bar
- if !@person.tag_string.blank? && user_signed_in?
= Diaspora::Taggable.format_tags(@person.profile.tag_string)
= Diaspora::Taggable.format_tags(@person.tag_string)
.span12.profile_stream
- if @stream.stream_posts.length > 0
@ -29,6 +29,8 @@
- else
#main_stream
.dull
- if user_signed_in? && (current_user.person != @person)
- if @block.present?
= t('.ignoring', :name => @person.first_name)
- elsif user_signed_in? && (current_user.person != @person)
= t('.has_not_shared_with_you_yet', :name => @person.first_name)

View file

@ -193,10 +193,12 @@ describe PeopleController, :type => :controller do
it "doesn't leak photos in the sidebar" do
private_photo = @user.post(:photo, user_file: uploaded_photo, to: @aspect.id, public: false)
public_photo = @user.post(:photo, user_file: uploaded_photo, to: @aspect.id, public: true)
allow(@user.person).to receive(:remote?) { false }
sign_out :user
get :show, id: @user.person.to_param
expect(response).to be_success
expect(assigns(:photos)).not_to include private_photo
expect(assigns(:photos)).to include public_photo
end
@ -216,23 +218,6 @@ describe PeopleController, :type => :controller do
get :show, :id => @user.person.to_param
expect(assigns(:person)).to eq(@user.person)
end
it "assigns all the user's posts" do
expect(@user.posts).to be_empty
@user.post(:status_message, :text => "to one aspect", :to => @aspect.id)
@user.post(:status_message, :text => "to all aspects", :to => 'all')
@user.post(:status_message, :text => "public", :to => 'all', :public => true)
expect(@user.reload.posts.length).to eq(3)
get :show, :id => @user.person.to_param
expect(assigns(:stream).posts.map(&:id)).to match_array(@user.posts.map(&:id))
end
it "renders the comments on the user's posts" do
message = @user.post :status_message, :text => 'test more', :to => @aspect.id
@user.comment!(message, 'I mean it')
get :show, :id => @user.person.to_param
expect(response).to be_success
end
end
context "with no user signed in" do
@ -251,34 +236,6 @@ describe PeopleController, :type => :controller do
expect(response).to be_success
end
context 'with posts' do
before do
@public_posts = []
@public_posts << bob.post(:status_message, :text => "first public ", :to => bob.aspects[0].id, :public => true)
bob.post(:status_message, :text => "to an aspect @user is not in", :to => bob.aspects[1].id)
bob.post(:status_message, :text => "to all aspects", :to => 'all')
@public_posts << bob.post(:status_message, :text => "public", :to => 'all', :public => true)
@public_posts.first.created_at -= 1000
@public_posts.first.save
end
it "posts include reshares" do
reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids)
get :show, :id => @user.person.to_param
expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id)
end
it "assigns only public posts" do
get :show, :id => @person.to_param
expect(assigns[:stream].posts.map(&:id)).to match_array(@public_posts.map(&:id))
end
it 'is sorted by created_at desc' do
get :show, :id => @person.to_param
expect(assigns[:stream].stream_posts).to eq(@public_posts.sort_by { |p| p.created_at }.reverse)
end
end
it 'forces to sign in if the person is remote' do
p = FactoryGirl.create(:person)
@ -303,27 +260,6 @@ describe PeopleController, :type => :controller do
expect(response).to be_success
end
it "assigns only the posts the current user can see" do
expect(bob.posts).to be_empty
posts_user_can_see = []
aspect_user_is_in = bob.aspects.where(:name => "generic").first
aspect_user_is_not_in = bob.aspects.where(:name => "empty").first
posts_user_can_see << bob.post(:status_message, :text => "to an aspect @user is in", :to => aspect_user_is_in.id)
bob.post(:status_message, :text => "to an aspect @user is not in", :to => aspect_user_is_not_in.id)
posts_user_can_see << bob.post(:status_message, :text => "to all aspects", :to => 'all')
posts_user_can_see << bob.post(:status_message, :text => "public", :to => 'all', :public => true)
expect(bob.reload.posts.length).to eq(4)
get :show, :id => @person.to_param
expect(assigns(:stream).posts.map(&:id)).to match_array(posts_user_can_see.map(&:id))
end
it "posts include reshares" do
reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids)
get :show, :id => @user.person.to_param
expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id)
end
it 'marks a corresponding notifications as read' do
note = FactoryGirl.create(:notification, :recipient => @user, :target => @person, :unread => true)
@ -348,6 +284,67 @@ describe PeopleController, :type => :controller do
get :show, :id => @person.to_param, :format => :mobile
expect(response).to be_success
end
end
end
describe '#stream' do
it "redirects non-json requests" do
get :stream, person_id: @user.person.to_param
expect(response).to be_redirect
end
context "person is current user" do
it "assigns all the user's posts" do
expect(@user.posts).to be_empty
@user.post(:status_message, :text => "to one aspect", :to => @aspect.id)
@user.post(:status_message, :text => "to all aspects", :to => 'all')
@user.post(:status_message, :text => "public", :to => 'all', :public => true)
expect(@user.reload.posts.length).to eq(3)
get :stream, person_id: @user.person.to_param, format: :json
expect(assigns(:stream).posts.map(&:id)).to match_array(@user.posts.map(&:id))
end
it "renders the comments on the user's posts" do
cmmt = 'I mean it'
message = @user.post :status_message, :text => 'test more', :to => @aspect.id
@user.comment!(message, cmmt)
get :stream, person_id: @user.person.to_param, format: :json
expect(response).to be_success
expect(response.body).to include(cmmt)
end
end
context "person is contact of current user" do
before do
@person = bob.person
end
it "includes reshares" do
reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids)
get :stream, person_id: @user.person.to_param, format: :json
expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id)
end
it "assigns only the posts the current user can see" do
expect(bob.posts).to be_empty
posts_user_can_see = []
aspect_user_is_in = bob.aspects.where(:name => "generic").first
aspect_user_is_not_in = bob.aspects.where(:name => "empty").first
posts_user_can_see << bob.post(:status_message, :text => "to an aspect @user is in", :to => aspect_user_is_in.id)
bob.post(:status_message, :text => "to an aspect @user is not in", :to => aspect_user_is_not_in.id)
posts_user_can_see << bob.post(:status_message, :text => "to all aspects", :to => 'all')
posts_user_can_see << bob.post(:status_message, :text => "public", :to => 'all', :public => true)
expect(bob.reload.posts.length).to eq(4)
get :stream, person_id: @person.to_param, format: :json
expect(assigns(:stream).posts.map(&:id)).to match_array(posts_user_can_see.map(&:id))
end
end
context "person is not contact of current user" do
before do
@person = eve.person
end
it "assigns only public posts" do
expect(eve.posts).to be_empty
@ -356,16 +353,51 @@ describe PeopleController, :type => :controller do
public_post = eve.post(:status_message, :text => "public", :to => 'all', :public => true)
expect(eve.reload.posts.length).to eq(3)
get :show, :id => @person.to_param
get :stream, person_id: @person.to_param, format: :json
expect(assigns[:stream].posts.map(&:id)).to match_array([public_post].map(&:id))
end
it "posts include reshares" do
reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids)
get :show, :id => @user.person.to_param
get :stream, person_id: @user.person.to_param, format: :json
expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id)
end
end
context "logged out" do
before do
sign_out :user
@person = bob.person
end
context 'with posts' do
before do
@public_posts = []
@public_posts << bob.post(:status_message, :text => "first public ", :to => bob.aspects[0].id, :public => true)
bob.post(:status_message, :text => "to an aspect @user is not in", :to => bob.aspects[1].id)
bob.post(:status_message, :text => "to all aspects", :to => 'all')
@public_posts << bob.post(:status_message, :text => "public", :to => 'all', :public => true)
@public_posts.first.created_at -= 1000
@public_posts.first.save
end
it "posts include reshares" do
reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids)
get :stream, person_id: @user.person.to_param, format: :json
expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id)
end
it "assigns only public posts" do
get :stream, person_id: @person.to_param, format: :json
expect(assigns[:stream].posts.map(&:id)).to match_array(@public_posts.map(&:id))
end
it 'is sorted by created_at desc' do
get :stream, person_id: @person.to_param, format: :json
expect(assigns[:stream].stream_posts).to eq(@public_posts.sort_by { |p| p.created_at }.reverse)
end
end
end
end
describe '#hovercard' do

View file

@ -7,7 +7,7 @@ describe PersonPresenter do
describe "#as_json" do
context "with no current_user" do
it "returns the user's public information if a user is not logged in" do
expect(PersonPresenter.new(person, nil).as_json).to include(person.as_api_response(:backbone))
expect(PersonPresenter.new(person, nil).as_json).to include(person.as_api_response(:backbone).reject { |k,v| k == :avatar })
end
end
@ -29,4 +29,44 @@ describe PersonPresenter do
end
end
end
describe "#full_hash" do
let(:current_user) { FactoryGirl.create(:user) }
let(:m_contact) { double(:id => 1, :mutual? => true, :sharing? => true, :receiving? => true ) }
let(:r_contact) { double(:id => 1, :mutual? => false, :sharing? => false, :receiving? => true) }
let(:s_contact) { double(:id => 1, :mutual? => false, :sharing? => true, :receiving? => false) }
let(:n_contact) { double(:id => 1, :mutual? => false, :sharing? => false, :receiving? => false) }
before do
@p = PersonPresenter.new(person, current_user)
end
context "relationship" do
it "is blocked?" do
allow(current_user).to receive(:block_for) { double(id: 1) }
allow(current_user).to receive(:contact_for) { n_contact }
expect(@p.full_hash[:relationship]).to be(:blocked)
end
it "is mutual?" do
allow(current_user).to receive(:contact_for) { m_contact }
expect(@p.full_hash[:relationship]).to be(:mutual)
end
it "is receiving?" do
allow(current_user).to receive(:contact_for) { r_contact }
expect(@p.full_hash[:relationship]).to be(:receiving)
end
it "is sharing?" do
allow(current_user).to receive(:contact_for) { s_contact }
expect(@p.full_hash[:relationship]).to be(:sharing)
end
it "isn't sharing?" do
allow(current_user).to receive(:contact_for) { n_contact }
expect(@p.full_hash[:relationship]).to be(:not_sharing)
end
end
end
end