Merge branch 'repost'
This commit is contained in:
commit
dfa6539ef2
57 changed files with 1052 additions and 151 deletions
|
|
@ -44,7 +44,7 @@ class AspectsController < ApplicationController
|
||||||
|
|
||||||
@aspect_ids = @aspects.map { |a| a.id }
|
@aspect_ids = @aspects.map { |a| a.id }
|
||||||
posts = current_user.visible_posts(:by_members_of => @aspect_ids,
|
posts = current_user.visible_posts(:by_members_of => @aspect_ids,
|
||||||
:type => ['StatusMessage','ActivityStreams::Photo'],
|
:type => ['StatusMessage','Reshare', 'ActivityStreams::Photo'],
|
||||||
:order => session[:sort_order] + ' DESC',
|
:order => session[:sort_order] + ' DESC',
|
||||||
:max_time => params[:max_time].to_i
|
:max_time => params[:max_time].to_i
|
||||||
).includes(:mentions => {:person => :profile})
|
).includes(:mentions => {:person => :profile})
|
||||||
|
|
|
||||||
|
|
@ -96,12 +96,11 @@ class PeopleController < ApplicationController
|
||||||
else
|
else
|
||||||
@commenting_disabled = false
|
@commenting_disabled = false
|
||||||
end
|
end
|
||||||
@posts = current_user.posts_from(@person).where(:type => ["StatusMessage", "ActivityStreams::Photo"]).includes(:comments).limit(15).where(StatusMessage.arel_table[:created_at].lt(max_time))
|
@posts = current_user.posts_from(@person).where(:type => ["StatusMessage", "Reshare", "ActivityStreams::Photo"]).includes(:comments).limit(15).where(StatusMessage.arel_table[:created_at].lt(max_time))
|
||||||
else
|
else
|
||||||
@commenting_disabled = true
|
@commenting_disabled = true
|
||||||
@posts = @person.posts.where(:type => ["StatusMessage", "ActivityStreams::Photo"], :public => true).includes(:comments).limit(15).where(StatusMessage.arel_table[:created_at].lt(max_time)).order('posts.created_at DESC')
|
@posts = @person.posts.where(:type => ["StatusMessage", "Reshare", "ActivityStreams::Photo"], :public => true).includes(:comments).limit(15).where(StatusMessage.arel_table[:created_at].lt(max_time)).order('posts.created_at DESC')
|
||||||
end
|
end
|
||||||
|
|
||||||
@posts = PostsFake.new(@posts)
|
@posts = PostsFake.new(@posts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ class PublicsController < ApplicationController
|
||||||
skip_before_filter :set_grammatical_gender
|
skip_before_filter :set_grammatical_gender
|
||||||
before_filter :allow_cross_origin, :only => [:hcard, :host_meta, :webfinger]
|
before_filter :allow_cross_origin, :only => [:hcard, :host_meta, :webfinger]
|
||||||
|
|
||||||
|
respond_to :html
|
||||||
|
respond_to :xml, :only => :post
|
||||||
|
|
||||||
def allow_cross_origin
|
def allow_cross_origin
|
||||||
headers["Access-Control-Allow-Origin"] = "*"
|
headers["Access-Control-Allow-Origin"] = "*"
|
||||||
end
|
end
|
||||||
|
|
@ -66,23 +69,31 @@ class PublicsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def post
|
def post
|
||||||
@post = Post.where(:id => params[:id], :public => true).includes(:author, :comments => :author).first
|
|
||||||
|
if params[:guid].to_s.length <= 8
|
||||||
|
@post = Post.where(:id => params[:guid], :public => true).includes(:author, :comments => :author).first
|
||||||
|
else
|
||||||
|
@post = Post.where(:guid => params[:guid], :public => true).includes(:author, :comments => :author).first
|
||||||
|
end
|
||||||
|
|
||||||
#hax to upgrade logged in users who can comment
|
#hax to upgrade logged in users who can comment
|
||||||
if @post
|
if @post
|
||||||
if user_signed_in? && current_user.find_visible_post_by_id(@post.id)
|
if user_signed_in? && current_user.find_visible_post_by_id(@post.id)
|
||||||
redirect_to post_path(@post)
|
redirect_to post_path(@post)
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
@landing_page = true
|
|
||||||
@person = @post.author
|
|
||||||
if @person.owner_id
|
|
||||||
I18n.locale = @person.owner.language
|
|
||||||
render "#{@post.class.to_s.underscore}", :layout => 'application'
|
|
||||||
else
|
else
|
||||||
flash[:error] = I18n.t('posts.show.not_found')
|
@landing_page = true
|
||||||
redirect_to root_url
|
@person = @post.author
|
||||||
|
if @person.owner_id
|
||||||
|
I18n.locale = @person.owner.language
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.all{ render "#{@post.class.to_s.underscore}", :layout => 'application'}
|
||||||
|
format.xml{ render :xml => @post.to_diaspora_xml }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
flash[:error] = I18n.t('posts.show.not_found')
|
||||||
|
redirect_to root_url
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
flash[:error] = I18n.t('posts.show.not_found')
|
flash[:error] = I18n.t('posts.show.not_found')
|
||||||
|
|
|
||||||
14
app/controllers/reshares_controller.rb
Normal file
14
app/controllers/reshares_controller.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
class ResharesController < ApplicationController
|
||||||
|
before_filter :authenticate_user!
|
||||||
|
respond_to :js
|
||||||
|
|
||||||
|
def create
|
||||||
|
@reshare = current_user.build_post(:reshare, :root_guid => params[:root_guid])
|
||||||
|
if @reshare.save
|
||||||
|
current_user.add_to_streams(@reshare, current_user.aspects)
|
||||||
|
current_user.dispatch_post(@reshare, :url => post_url(@reshare), :additional_subscribers => @reshare.root.author)
|
||||||
|
end
|
||||||
|
|
||||||
|
respond_with @reshare
|
||||||
|
end
|
||||||
|
end
|
||||||
13
app/helpers/reshares_helper.rb
Normal file
13
app/helpers/reshares_helper.rb
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
module ResharesHelper
|
||||||
|
def reshare_error_message(reshare)
|
||||||
|
if @reshare.errors[:root_guid].present?
|
||||||
|
escape_javascript(@reshare.errors[:root_guid].first)
|
||||||
|
else
|
||||||
|
escape_javascript(t('reshares.create.failure'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def reshare_link post
|
||||||
|
link_to t("reshares.reshare.reshare", :count => post.reshares.size), reshares_path(:root_guid => post.guid), :method => :post, :remote => true, :confirm => t('reshares.reshare.reshare_confirmation', :author => post.author.name, :text => post.text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -28,6 +28,7 @@ module SocketsHelper
|
||||||
post_hash = {:post => object,
|
post_hash = {:post => object,
|
||||||
:author => object.author,
|
:author => object.author,
|
||||||
:photos => object.photos,
|
:photos => object.photos,
|
||||||
|
:reshare => nil,
|
||||||
:comments => object.comments.map{|c|
|
:comments => object.comments.map{|c|
|
||||||
{:comment => c,
|
{:comment => c,
|
||||||
:author => c.author
|
:author => c.author
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,8 @@ module StreamHelper
|
||||||
def comments_expanded
|
def comments_expanded
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reshare?(post)
|
||||||
|
(defined?(post.model) && post.model.is_a?(Reshare)) || post.instance_of?(Reshare)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ require 'uri'
|
||||||
class AppConfig < Settingslogic
|
class AppConfig < Settingslogic
|
||||||
|
|
||||||
def self.source_file_name
|
def self.source_file_name
|
||||||
if Rails.env == 'test' || ENV["CI"]
|
if Rails.env == 'test' || ENV["CI"] || Rails.env.include?("integration")
|
||||||
File.join(Rails.root, "config", "application.yml.example")
|
File.join(Rails.root, "config", "application.yml.example")
|
||||||
else
|
else
|
||||||
File.join(Rails.root, "config", "application.yml")
|
File.join(Rails.root, "config", "application.yml")
|
||||||
|
|
@ -125,7 +125,7 @@ HELP
|
||||||
def self.pod_uri
|
def self.pod_uri
|
||||||
if @@pod_uri.nil?
|
if @@pod_uri.nil?
|
||||||
begin
|
begin
|
||||||
@@pod_uri = URI.parse(self.pod_url)
|
@@pod_uri = Addressable::URI.parse(self.pod_url)
|
||||||
rescue
|
rescue
|
||||||
puts "WARNING: pod url " + self.pod_url + " is not a legal URI"
|
puts "WARNING: pod url " + self.pod_url + " is not a legal URI"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,6 @@ class Person < ActiveRecord::Base
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def clean_url
|
def clean_url
|
||||||
self.url ||= "http://localhost:3000/" if self.class == User
|
|
||||||
if self.url
|
if self.url
|
||||||
self.url = 'http://' + self.url unless self.url.match(/https?:\/\//)
|
self.url = 'http://' + self.url unless self.url.match(/https?:\/\//)
|
||||||
self.url = self.url + '/' if self.url[-1, 1] != '/'
|
self.url = self.url + '/' if self.url[-1, 1] != '/'
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ class Post < ActiveRecord::Base
|
||||||
has_many :contacts, :through => :post_visibilities
|
has_many :contacts, :through => :post_visibilities
|
||||||
has_many :mentions, :dependent => :destroy
|
has_many :mentions, :dependent => :destroy
|
||||||
|
|
||||||
|
has_many :reshares, :class_name => "Reshare", :foreign_key => :root_guid, :primary_key => :guid
|
||||||
|
has_many :resharers, :class_name => 'Person', :through => :reshares, :source => :author
|
||||||
|
|
||||||
belongs_to :author, :class_name => 'Person'
|
belongs_to :author, :class_name => 'Person'
|
||||||
|
|
||||||
def diaspora_handle
|
def diaspora_handle
|
||||||
|
|
|
||||||
|
|
@ -2,81 +2,28 @@
|
||||||
# licensed under the Affero General Public License version 3 or later. See
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
class RelayableRetraction
|
class RelayableRetraction < SignedRetraction
|
||||||
include ROXML
|
|
||||||
include Diaspora::Webhooks
|
|
||||||
include Diaspora::Encryptable
|
|
||||||
|
|
||||||
xml_name :relayable_retraction
|
xml_name :relayable_retraction
|
||||||
xml_attr :target_guid
|
|
||||||
xml_attr :target_type
|
|
||||||
xml_attr :sender_handle
|
|
||||||
xml_attr :parent_author_signature
|
xml_attr :parent_author_signature
|
||||||
xml_attr :target_author_signature
|
|
||||||
|
|
||||||
attr_accessor :target_guid,
|
attr_accessor :parent_author_signature
|
||||||
:target_type,
|
|
||||||
:parent_author_signature,
|
|
||||||
:target_author_signature,
|
|
||||||
:sender
|
|
||||||
|
|
||||||
def signable_accessors
|
def signable_accessors
|
||||||
accessors = self.class.roxml_attrs.collect do |definition|
|
super - ['parent_author_signature']
|
||||||
definition.accessor
|
|
||||||
end
|
|
||||||
['target_author_signature', 'parent_author_signature'].each do |acc|
|
|
||||||
accessors.delete acc
|
|
||||||
end
|
|
||||||
accessors
|
|
||||||
end
|
|
||||||
|
|
||||||
def sender_handle= new_sender_handle
|
|
||||||
@sender = Person.where(:diaspora_handle => new_sender_handle).first
|
|
||||||
end
|
|
||||||
|
|
||||||
def sender_handle
|
|
||||||
@sender.diaspora_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
def diaspora_handle
|
|
||||||
self.sender_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
def subscribers(user)
|
|
||||||
self.target.subscribers(user)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.build(sender, target)
|
def self.build(sender, target)
|
||||||
retraction = self.new
|
retraction = super
|
||||||
retraction.sender = sender
|
retraction.parent_author_signature = retraction.sign_with_key(sender.encryption_key) if defined?(target.parent) && sender.person == target.parent.author
|
||||||
retraction.target = target
|
|
||||||
retraction.target_author_signature = retraction.sign_with_key(sender.encryption_key) if sender.person == target.author
|
|
||||||
retraction.parent_author_signature = retraction.sign_with_key(sender.encryption_key) if sender.person == target.parent.author
|
|
||||||
retraction
|
retraction
|
||||||
end
|
end
|
||||||
|
|
||||||
def target
|
|
||||||
@target ||= self.target_type.constantize.where(:guid => target_guid).first
|
|
||||||
end
|
|
||||||
|
|
||||||
def guid
|
|
||||||
target_guid
|
|
||||||
end
|
|
||||||
def target= new_target
|
|
||||||
@target = new_target
|
|
||||||
@target_type = new_target.class.to_s
|
|
||||||
@target_guid = new_target.guid
|
|
||||||
end
|
|
||||||
|
|
||||||
def parent
|
def parent
|
||||||
self.target.parent
|
self.target.parent
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform receiving_user
|
def diaspora_handle
|
||||||
Rails.logger.debug "Performing retraction for #{target_guid}"
|
self.sender_handle
|
||||||
self.target.unsocket_from_user receiving_user if target.respond_to? :unsocket_from_user
|
|
||||||
self.target.destroy
|
|
||||||
Rails.logger.info(:event => :retraction, :status => :complete, :target_type => self.target_type, :guid => self.target_guid)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def receive(recipient, sender)
|
def receive(recipient, sender)
|
||||||
|
|
@ -101,8 +48,4 @@ class RelayableRetraction
|
||||||
def parent_author_signature_valid?
|
def parent_author_signature_valid?
|
||||||
verify_signature(self.parent_author_signature, self.parent.author)
|
verify_signature(self.parent_author_signature, self.parent.author)
|
||||||
end
|
end
|
||||||
|
|
||||||
def target_author_signature_valid?
|
|
||||||
verify_signature(self.target_author_signature, self.target.author)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
67
app/models/reshare.rb
Normal file
67
app/models/reshare.rb
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
class Reshare < Post
|
||||||
|
|
||||||
|
belongs_to :root, :class_name => 'Post', :foreign_key => :root_guid, :primary_key => :guid
|
||||||
|
validate :root_must_be_public
|
||||||
|
attr_accessible :root_guid, :public
|
||||||
|
validates_presence_of :root, :on => :create
|
||||||
|
validates_uniqueness_of :root_guid, :scope => :author_id
|
||||||
|
|
||||||
|
xml_attr :root_diaspora_id
|
||||||
|
xml_attr :root_guid
|
||||||
|
|
||||||
|
before_validation do
|
||||||
|
self.public = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def root_diaspora_id
|
||||||
|
self.root.author.diaspora_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
def receive(recipient, sender)
|
||||||
|
local_reshare = Reshare.where(:guid => self.guid).first
|
||||||
|
if local_reshare && local_reshare.root.author_id == recipient.person.id
|
||||||
|
local_reshare.root.reshares << local_reshare
|
||||||
|
|
||||||
|
if recipient.contact_for(sender)
|
||||||
|
local_reshare.receive(recipient, sender)
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
super(recipient, sender)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def after_parse
|
||||||
|
root_author = Webfinger.new(@root_diaspora_id).fetch
|
||||||
|
root_author.save! unless root_author.persisted?
|
||||||
|
|
||||||
|
return if Post.exists?(:guid => self.root_guid)
|
||||||
|
|
||||||
|
fetched_post = self.class.fetch_post(root_author, self.root_guid)
|
||||||
|
|
||||||
|
#Why are we checking for this?
|
||||||
|
if root_author.diaspora_handle != fetched_post.diaspora_handle
|
||||||
|
raise "Diaspora ID (#{fetched_post.diaspora_handle}) in the root does not match the Diaspora ID (#{root_author.diaspora_handle}) specified in the reshare!"
|
||||||
|
end
|
||||||
|
|
||||||
|
fetched_post.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetch a remote public post, used for receiving reshares of unknown posts
|
||||||
|
# @param [Person] author the remote post's author
|
||||||
|
# @param [String] guid the remote post's guid
|
||||||
|
# @return [Post] an unsaved remote post
|
||||||
|
def self.fetch_post author, guid
|
||||||
|
response = Faraday.get(author.url + "/p/#{guid}.xml")
|
||||||
|
Diaspora::Parser.from_xml(response.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
def root_must_be_public
|
||||||
|
if self.root && !self.root.public
|
||||||
|
errors[:base] << "you must reshare public posts"
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -15,6 +15,8 @@ class Retraction
|
||||||
def subscribers(user)
|
def subscribers(user)
|
||||||
unless self.type == 'Person'
|
unless self.type == 'Person'
|
||||||
@subscribers ||= self.object.subscribers(user)
|
@subscribers ||= self.object.subscribers(user)
|
||||||
|
@subscribers -= self.object.resharers
|
||||||
|
@subscribers
|
||||||
else
|
else
|
||||||
raise 'HAX: you must set the subscribers manaully before unfriending' if @subscribers.nil?
|
raise 'HAX: you must set the subscribers manaully before unfriending' if @subscribers.nil?
|
||||||
@subscribers
|
@subscribers
|
||||||
|
|
|
||||||
97
app/models/signed_retraction.rb
Normal file
97
app/models/signed_retraction.rb
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
class SignedRetraction
|
||||||
|
include ROXML
|
||||||
|
include Diaspora::Webhooks
|
||||||
|
include Diaspora::Encryptable
|
||||||
|
|
||||||
|
xml_name :signed_retraction
|
||||||
|
xml_attr :target_guid
|
||||||
|
xml_attr :target_type
|
||||||
|
xml_attr :sender_handle
|
||||||
|
xml_attr :target_author_signature
|
||||||
|
|
||||||
|
attr_accessor :target_guid,
|
||||||
|
:target_type,
|
||||||
|
:target_author_signature,
|
||||||
|
:sender
|
||||||
|
|
||||||
|
def signable_accessors
|
||||||
|
accessors = self.class.roxml_attrs.collect do |definition|
|
||||||
|
definition.accessor
|
||||||
|
end
|
||||||
|
accessors - ['target_author_signature', 'sender_handle']
|
||||||
|
end
|
||||||
|
|
||||||
|
def sender_handle= new_sender_handle
|
||||||
|
@sender = Person.where(:diaspora_handle => new_sender_handle).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def sender_handle
|
||||||
|
@sender.diaspora_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
def diaspora_handle
|
||||||
|
self.sender_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
def subscribers(user)
|
||||||
|
self.target.subscribers(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.build(sender, target)
|
||||||
|
retraction = self.new
|
||||||
|
retraction.sender = sender
|
||||||
|
retraction.target = target
|
||||||
|
retraction.target_author_signature = retraction.sign_with_key(sender.encryption_key) if sender.person == target.author
|
||||||
|
retraction
|
||||||
|
end
|
||||||
|
|
||||||
|
def target
|
||||||
|
@target ||= self.target_type.constantize.where(:guid => target_guid).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def guid
|
||||||
|
target_guid
|
||||||
|
end
|
||||||
|
def target= new_target
|
||||||
|
@target = new_target
|
||||||
|
@target_type = new_target.class.to_s
|
||||||
|
@target_guid = new_target.guid
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform receiving_user
|
||||||
|
Rails.logger.debug "Performing retraction for #{target_guid}"
|
||||||
|
if reshare = Reshare.where(:author_id => receiving_user.person.id, :root_guid => target_guid).first
|
||||||
|
onward_retraction = self.dup
|
||||||
|
onward_retraction.sender = receiving_user.person
|
||||||
|
Postzord::Dispatch.new(receiving_user, onward_retraction).post
|
||||||
|
end
|
||||||
|
if target
|
||||||
|
self.target.unsocket_from_user receiving_user if target.respond_to? :unsocket_from_user
|
||||||
|
self.target.destroy
|
||||||
|
end
|
||||||
|
Rails.logger.info(:event => :retraction, :status => :complete, :target_type => self.target_type, :guid => self.target_guid)
|
||||||
|
end
|
||||||
|
|
||||||
|
def receive(recipient, sender)
|
||||||
|
if self.target.nil?
|
||||||
|
Rails.logger.info("event=retraction status=abort reason='no post found' sender=#{sender.diaspora_handle} target_guid=#{target_guid}")
|
||||||
|
return
|
||||||
|
elsif self.target_author_signature_valid?
|
||||||
|
#this is a retraction from the upstream owner
|
||||||
|
self.perform(recipient)
|
||||||
|
else
|
||||||
|
Rails.logger.info("event=receive status=abort reason='object signature not valid' recipient=#{recipient.diaspora_handle} sender=#{self.sender_handle} payload_type=#{self.class}")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def target_author_signature_valid?
|
||||||
|
verify_signature(self.target_author_signature, self.target.author)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
@ -136,7 +136,8 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def dispatch_post(post, opts = {})
|
def dispatch_post(post, opts = {})
|
||||||
mailman = Postzord::Dispatch.new(self, post)
|
additional_people = opts.delete(:additional_subscribers)
|
||||||
|
mailman = Postzord::Dispatch.new(self, post, :additional_subscribers => additional_people)
|
||||||
mailman.post(opts)
|
mailman.post(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -229,14 +230,20 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
######### Posts and Such ###############
|
######### Posts and Such ###############
|
||||||
def retract(target)
|
def retract(target, opts={})
|
||||||
if target.respond_to?(:relayable?) && target.relayable?
|
if target.respond_to?(:relayable?) && target.relayable?
|
||||||
retraction = RelayableRetraction.build(self, target)
|
retraction = RelayableRetraction.build(self, target)
|
||||||
|
elsif target.is_a? Post
|
||||||
|
retraction = SignedRetraction.build(self, target)
|
||||||
else
|
else
|
||||||
retraction = Retraction.for(target)
|
retraction = Retraction.for(target)
|
||||||
end
|
end
|
||||||
|
|
||||||
mailman = Postzord::Dispatch.new(self, retraction)
|
if target.is_a?(Post)
|
||||||
|
opts[:additional_subscribers] = target.resharers
|
||||||
|
end
|
||||||
|
|
||||||
|
mailman = Postzord::Dispatch.new(self, retraction, opts)
|
||||||
mailman.post
|
mailman.post
|
||||||
|
|
||||||
retraction.perform(self)
|
retraction.perform(self)
|
||||||
|
|
@ -326,7 +333,7 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
self.person = Person.new(opts[:person])
|
self.person = Person.new(opts[:person])
|
||||||
self.person.diaspora_handle = "#{opts[:username]}@#{AppConfig[:pod_uri].host}"
|
self.person.diaspora_handle = "#{opts[:username]}@#{AppConfig[:pod_uri].authority}"
|
||||||
self.person.url = AppConfig[:pod_url]
|
self.person.url = AppConfig[:pod_url]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
.span-20.append-2.prepend-2.last
|
.span-20.append-2.prepend-2.last
|
||||||
#main_stream.stream.status_message_show
|
#main_stream.stream.status_message_show
|
||||||
= render 'shared/stream_element', :post => @post, :all_aspects => @post.aspects
|
= render 'shared/stream_element', :post => @post, :commenting_disabled => defined?(@commenting_disabled)
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'
|
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'
|
||||||
xmlns:hm='http://host-meta.net/xrd/1.0'>
|
xmlns:hm='http://host-meta.net/xrd/1.0'>
|
||||||
<hm:Host><%= AppConfig[:pod_uri].host %></hm:Host>
|
<hm:Host><%= AppConfig[:pod_uri].authority %></hm:Host>
|
||||||
<Link rel='lrdd'
|
<Link rel='lrdd'
|
||||||
template='<%= AppConfig[:pod_url].chomp("/") %>/webfinger?q={uri}'>
|
template='<%= AppConfig[:pod_url].chomp("/") %>/webfinger?q={uri}'>
|
||||||
<Title>Resource Descriptor</Title>
|
<Title>Resource Descriptor</Title>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'
|
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'
|
||||||
xmlns:hm='http://host-meta.net/xrd/1.0'>
|
xmlns:hm='http://host-meta.net/xrd/1.0'>
|
||||||
<hm:Host><%= AppConfig[:pod_uri].host %></hm:Host>
|
<hm:Host><%= AppConfig[:pod_uri].authority %></hm:Host>
|
||||||
<Link rel='lrdd'
|
<Link rel='lrdd'
|
||||||
template='<%= AppConfig[:pod_url] %>webfinger?q={uri}'>
|
template='<%= AppConfig[:pod_url] %>webfinger?q={uri}'>
|
||||||
<Title>Resource Descriptor</Title>
|
<Title>Resource Descriptor</Title>
|
||||||
|
|
|
||||||
25
app/views/reshares/_reshare.haml
Normal file
25
app/views/reshares/_reshare.haml
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
-# Copyright (c) 2010, Diaspora Inc. This file is
|
||||||
|
-# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
-# the COPYRIGHT file.
|
||||||
|
|
||||||
|
|
||||||
|
.reshare
|
||||||
|
- if post
|
||||||
|
= person_image_link(post.author, :size => :thumb_small)
|
||||||
|
|
||||||
|
.content
|
||||||
|
.right
|
||||||
|
= link_to t("show_original"), post_path(post)
|
||||||
|
%span.from
|
||||||
|
= person_link(post.author, :class => "hovercardable")
|
||||||
|
|
||||||
|
- if post.activity_streams?
|
||||||
|
= link_to image_tag(post.image_url, 'data-small-photo' => post.image_url, 'data-full-photo' => post.image_url, :class => 'stream-photo'), post.object_url, :class => "stream-photo-link"
|
||||||
|
- else
|
||||||
|
= render 'status_messages/status_message', :post => post, :photos => post.photos
|
||||||
|
- if defined?(current_user) && current_user && (post.author_id != current_user.person.id) && (post.public?) && !reshare?(post)
|
||||||
|
%span.reshare_action
|
||||||
|
= reshare_link(post)
|
||||||
|
|
||||||
|
- else
|
||||||
|
= t('.deleted')
|
||||||
9
app/views/reshares/create.js.erb
Normal file
9
app/views/reshares/create.js.erb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<% if @reshare.persisted? %>
|
||||||
|
$('.stream_element#<%=params[:root_guid]%>').addClass('reshared');
|
||||||
|
ContentUpdater.addPostToStream(
|
||||||
|
"<%= escape_javascript(render(:partial => 'shared/stream_element', :locals => {:post => @reshare }))=%>"
|
||||||
|
);
|
||||||
|
<% else %>
|
||||||
|
Diaspora.widgets.flashes.render({success:false,
|
||||||
|
notice: "<%= reshare_error_message(@reshare) %>"});
|
||||||
|
<% end %>
|
||||||
|
|
@ -6,9 +6,11 @@
|
||||||
- if current_user && post.author.owner_id == current_user.id
|
- if current_user && post.author.owner_id == current_user.id
|
||||||
.right.controls
|
.right.controls
|
||||||
= link_to image_tag('deletelabel.png'), post_path(post), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete stream_element_delete", :title => t('delete')
|
= link_to image_tag('deletelabel.png'), post_path(post), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete stream_element_delete", :title => t('delete')
|
||||||
|
|
||||||
- else
|
- else
|
||||||
.right.controls
|
.right.controls
|
||||||
= link_to image_tag('deletelabel.png'), post_visibility_path(:id => "42", :post_id => post.id), :method => :put, :remote => true, :class => "delete stream_element_delete", :title => t('hide')
|
= link_to image_tag('deletelabel.png'), post_visibility_path(:id => "42", :post_id => post.id), :method => :put, :remote => true, :class => "delete stream_element_delete", :title => t('hide')
|
||||||
|
|
||||||
.undo_text.hidden
|
.undo_text.hidden
|
||||||
= t('post_visibilites.update.post_hidden', :name => post.author.name)
|
= t('post_visibilites.update.post_hidden', :name => post.author.name)
|
||||||
= link_to t('undo'), post_visibility_path(:id => "42", :post_id => post.id), :method => :put, :remote => true, :class => "delete stream_element_delete"
|
= link_to t('undo'), post_visibility_path(:id => "42", :post_id => post.id), :method => :put, :remote => true, :class => "delete stream_element_delete"
|
||||||
|
|
@ -20,6 +22,7 @@
|
||||||
%span.from
|
%span.from
|
||||||
= person_link(post.author, :class => 'hovercardable')
|
= person_link(post.author, :class => 'hovercardable')
|
||||||
%time.time.timeago{:datetime => post.created_at, :integer => time_for_sort(post).to_i}
|
%time.time.timeago{:datetime => post.created_at, :integer => time_for_sort(post).to_i}
|
||||||
|
|
||||||
%span.details
|
%span.details
|
||||||
–
|
–
|
||||||
%span.timeago
|
%span.timeago
|
||||||
|
|
@ -27,6 +30,8 @@
|
||||||
|
|
||||||
- if post.activity_streams?
|
- if post.activity_streams?
|
||||||
= link_to image_tag(post.image_url, 'data-small-photo' => post.image_url, 'data-full-photo' => post.image_url, :class => 'stream-photo'), post.object_url, :class => "stream-photo-link"
|
= link_to image_tag(post.image_url, 'data-small-photo' => post.image_url, 'data-full-photo' => post.image_url, :class => 'stream-photo'), post.object_url, :class => "stream-photo-link"
|
||||||
|
- elsif reshare?(post)
|
||||||
|
= render 'reshares/reshare', :reshare => post, :post => post.root
|
||||||
- else
|
- else
|
||||||
= render 'status_messages/status_message', :post => post, :photos => post.photos
|
= render 'status_messages/status_message', :post => post, :photos => post.photos
|
||||||
|
|
||||||
|
|
@ -52,7 +57,13 @@
|
||||||
- unless (defined?(@commenting_disabled) && @commenting_disabled)
|
- unless (defined?(@commenting_disabled) && @commenting_disabled)
|
||||||
%span.like_action
|
%span.like_action
|
||||||
= like_action(post, current_user)
|
= like_action(post, current_user)
|
||||||
|
|
||||||
|
- if (post.author_id != current_user.person.id) && (post.public?) && !reshare?(post)
|
||||||
|
·
|
||||||
|
%span.reshare_action
|
||||||
|
= reshare_link(post)
|
||||||
·
|
·
|
||||||
|
|
||||||
= link_to t('comments.new_comment.comment'), '#', :class => 'focus_comment_textarea'
|
= link_to t('comments.new_comment.comment'), '#', :class => 'focus_comment_textarea'
|
||||||
|
|
||||||
.likes.on_post
|
.likes.on_post
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
:author => @status_message.author,
|
:author => @status_message.author,
|
||||||
:photos => @status_message.photos,
|
:photos => @status_message.photos,
|
||||||
:comments => [],
|
:comments => [],
|
||||||
:all_aspects => current_user.aspects
|
:all_aspects => current_user.aspects,
|
||||||
|
:reshare => nil
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
:post_id => @status_message.guid}.to_json.html_safe%>
|
:post_id => @status_message.guid}.to_json.html_safe%>
|
||||||
|
|
|
||||||
|
|
@ -154,3 +154,12 @@ test:
|
||||||
open_invitations: false
|
open_invitations: false
|
||||||
|
|
||||||
|
|
||||||
|
integration_1:
|
||||||
|
<<: *defaults
|
||||||
|
pod_url: "http://localhost:45789"
|
||||||
|
enable_splunk_logging: false
|
||||||
|
|
||||||
|
integration_2:
|
||||||
|
<<: *defaults
|
||||||
|
pod_url: "http://localhost:34658"
|
||||||
|
enable_splunk_logging: false
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,12 @@ Diaspora::Application.configure do
|
||||||
|
|
||||||
# Show full error reports and disable caching
|
# Show full error reports and disable caching
|
||||||
config.consider_all_requests_local = true
|
config.consider_all_requests_local = true
|
||||||
config.action_view.debug_rjs = true
|
|
||||||
config.action_controller.perform_caching = false
|
config.action_controller.perform_caching = false
|
||||||
|
|
||||||
# Don't care if the mailer can't send
|
# Don't care if the mailer can't send
|
||||||
config.action_mailer.raise_delivery_errors = false
|
config.action_mailer.raise_delivery_errors = false
|
||||||
config.active_support.deprecation = :log
|
config.active_support.deprecation = :log
|
||||||
#config.threadsafe!
|
config.threadsafe!
|
||||||
|
|
||||||
# Monkeypatch around the nasty "2.5MB exception page" issue, caused by very large environment vars
|
# Monkeypatch around the nasty "2.5MB exception page" issue, caused by very large environment vars
|
||||||
# This snippet via: http://stackoverflow.com/questions/3114993/exception-pages-in-development-mode-take-upwards-of-15-30-seconds-to-render-why
|
# This snippet via: http://stackoverflow.com/questions/3114993/exception-pages-in-development-mode-take-upwards-of-15-30-seconds-to-render-why
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
Diaspora::Application.configure do
|
Diaspora::Application.configure do
|
||||||
config.action_mailer.default_url_options = {:host => AppConfig[:pod_uri].host}
|
config.action_mailer.default_url_options = {:host => AppConfig[:pod_uri].authority }
|
||||||
unless Rails.env == 'test' || AppConfig[:mailer_on] != true
|
unless Rails.env == 'test' || AppConfig[:mailer_on] != true
|
||||||
if AppConfig[:mailer_method] == "sendmail"
|
if AppConfig[:mailer_method] == "sendmail"
|
||||||
config.action_mailer.delivery_method = :sendmail
|
config.action_mailer.delivery_method = :sendmail
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,4 @@
|
||||||
attributes:
|
attributes:
|
||||||
from_id:
|
from_id:
|
||||||
taken: "is a duplicate of a pre-existing request."
|
taken: "is a duplicate of a pre-existing request."
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,10 @@ en:
|
||||||
attributes:
|
attributes:
|
||||||
from_id:
|
from_id:
|
||||||
taken: "is a duplicate of a pre-existing request."
|
taken: "is a duplicate of a pre-existing request."
|
||||||
|
reshare:
|
||||||
|
attributes:
|
||||||
|
root_guid:
|
||||||
|
taken: "You've already reshared that post!"
|
||||||
error_messages:
|
error_messages:
|
||||||
helper:
|
helper:
|
||||||
invalid_fields: "Invalid Fields"
|
invalid_fields: "Invalid Fields"
|
||||||
|
|
@ -579,7 +581,19 @@ en:
|
||||||
few: "%{count} new requests!"
|
few: "%{count} new requests!"
|
||||||
many: "%{count} new requests!"
|
many: "%{count} new requests!"
|
||||||
other: "%{count} new requests!"
|
other: "%{count} new requests!"
|
||||||
|
reshares:
|
||||||
|
reshare:
|
||||||
|
reshare:
|
||||||
|
zero: "Reshare"
|
||||||
|
one: "1 Reshare"
|
||||||
|
few: "%{count} Reshares"
|
||||||
|
many: "%{count} Reshares"
|
||||||
|
other: "%{count} Reshares"
|
||||||
|
show_original: "Show Original"
|
||||||
|
reshare_confirmation: "Reshare %{author} - %{text}?"
|
||||||
|
deleted: "Original post deleted by author."
|
||||||
|
create:
|
||||||
|
failure: "There was an error resharing this post."
|
||||||
services:
|
services:
|
||||||
index:
|
index:
|
||||||
logged_in_as: "logged in as"
|
logged_in_as: "logged in as"
|
||||||
|
|
|
||||||
|
|
@ -47,3 +47,5 @@ en:
|
||||||
comments:
|
comments:
|
||||||
show: "show all comments"
|
show: "show all comments"
|
||||||
hide: "hide comments"
|
hide: "hide comments"
|
||||||
|
reshares:
|
||||||
|
duplicate:"You've already reshared that post!"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ Diaspora::Application.routes.draw do
|
||||||
|
|
||||||
# Posting and Reading
|
# Posting and Reading
|
||||||
|
|
||||||
|
resources :reshares
|
||||||
|
|
||||||
resources :aspects do
|
resources :aspects do
|
||||||
put :toggle_contact_visibility
|
put :toggle_contact_visibility
|
||||||
end
|
end
|
||||||
|
|
@ -16,7 +18,7 @@ Diaspora::Application.routes.draw do
|
||||||
resources :likes, :only => [:create, :destroy, :index]
|
resources :likes, :only => [:create, :destroy, :index]
|
||||||
resources :comments, :only => [:create, :destroy, :index]
|
resources :comments, :only => [:create, :destroy, :index]
|
||||||
end
|
end
|
||||||
get 'p/:id' => 'publics#post', :as => 'public_post'
|
get 'p/:guid' => 'publics#post', :as => 'public_post'
|
||||||
|
|
||||||
# roll up likes into a nested resource above
|
# roll up likes into a nested resource above
|
||||||
resources :comments, :only => [:create, :destroy] do
|
resources :comments, :only => [:create, :destroy] do
|
||||||
|
|
|
||||||
9
db/migrate/20110525213325_add_root_id_to_posts.rb
Normal file
9
db/migrate/20110525213325_add_root_id_to_posts.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
class AddRootIdToPosts < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
add_column :posts, :root_guid, :string, :limit => 30
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
remove_column :posts, :root_guid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -268,6 +268,7 @@ ActiveRecord::Schema.define(:version => 20110707234802) do
|
||||||
t.string "provider_display_name"
|
t.string "provider_display_name"
|
||||||
t.string "actor_url"
|
t.string "actor_url"
|
||||||
t.integer "objectId"
|
t.integer "objectId"
|
||||||
|
t.string "root_guid", :limit => 30
|
||||||
t.string "status_message_guid"
|
t.string "status_message_guid"
|
||||||
t.integer "likes_count", :default => 0
|
t.integer "likes_count", :default => 0
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@javascript
|
@javascript
|
||||||
Feature: disconnecting users
|
Feature: disconnecting users
|
||||||
In order to deal with life
|
In order to help users feel secure on Diaspora
|
||||||
As a User
|
As a User
|
||||||
I want to be able to disconnect from others
|
I want to be able to disconnect from others
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ Feature: posting
|
||||||
And I am on "bob@bob.bob"'s page
|
And I am on "bob@bob.bob"'s page
|
||||||
|
|
||||||
And I hover over the ".stream_element"
|
And I hover over the ".stream_element"
|
||||||
|
And I preemptively confirm the alert
|
||||||
And I click to delete the first post
|
And I click to delete the first post
|
||||||
And I wait for the ajax to finish
|
And I wait for the ajax to finish
|
||||||
And I go to "bob@bob.bob"'s page
|
And I go to "bob@bob.bob"'s page
|
||||||
|
|
|
||||||
98
features/repost.feature
Normal file
98
features/repost.feature
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
@javascript
|
||||||
|
Feature: public repost
|
||||||
|
In order to make Diaspora more viral
|
||||||
|
As a User
|
||||||
|
I want to reshare my friends post
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given a user named "Bob Jones" with email "bob@bob.bob"
|
||||||
|
And a user named "Alice Smith" with email "alice@alice.alice"
|
||||||
|
And a user with email "bob@bob.bob" is connected with "alice@alice.alice"
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: does not show the reshare button on my own posts
|
||||||
|
And "bob@bob.bob" has a non public post with text "reshare this!"
|
||||||
|
And I sign in as "bob@bob.bob"
|
||||||
|
Then I should not see "Reshare"
|
||||||
|
|
||||||
|
Scenario: does not show a reshare button on other private pots
|
||||||
|
And "bob@bob.bob" has a non public post with text "reshare this!"
|
||||||
|
And I sign in as "alice@alice.alice"
|
||||||
|
Then I should not see "Reshare"
|
||||||
|
|
||||||
|
Scenario: does shows the reshare button on my own posts
|
||||||
|
And "bob@bob.bob" has a public post with text "reshare this!"
|
||||||
|
And I sign in as "alice@alice.alice"
|
||||||
|
Then I should see "Reshare"
|
||||||
|
|
||||||
|
Scenario: shows up on the profile page
|
||||||
|
And "bob@bob.bob" has a public post with text "reshare this!"
|
||||||
|
And I sign in as "alice@alice.alice"
|
||||||
|
|
||||||
|
And I preemptively confirm the alert
|
||||||
|
And I follow "Reshare"
|
||||||
|
And I wait for the ajax to finish
|
||||||
|
And I wait for 2 seconds
|
||||||
|
|
||||||
|
And I am on "alice@alice.alice"'s page
|
||||||
|
Then I should see "reshare this!"
|
||||||
|
Then I should see a ".reshare"
|
||||||
|
And I should see "Bob"
|
||||||
|
|
||||||
|
Scenario: shows up on the aspects page
|
||||||
|
And "bob@bob.bob" has a public post with text "reshare this!"
|
||||||
|
And I sign in as "alice@alice.alice"
|
||||||
|
And I preemptively confirm the alert
|
||||||
|
And I follow "Reshare"
|
||||||
|
And I wait for the ajax to finish
|
||||||
|
|
||||||
|
And I go to the home page
|
||||||
|
Then I should see a ".reshare"
|
||||||
|
And I follow "Your Aspects"
|
||||||
|
Then I should see "reshare this!"
|
||||||
|
Then I should see a ".reshare"
|
||||||
|
And I should see "Bob"
|
||||||
|
|
||||||
|
Scenario: can be retracted
|
||||||
|
And "bob@bob.bob" has a public post with text "reshare this!"
|
||||||
|
And I sign in as "alice@alice.alice"
|
||||||
|
And I preemptively confirm the alert
|
||||||
|
And I follow "Reshare"
|
||||||
|
And I wait for the ajax to finish
|
||||||
|
|
||||||
|
And I go to the home page
|
||||||
|
Then I should see a ".reshare"
|
||||||
|
And I follow "Your Aspects"
|
||||||
|
Then I should see "reshare this!"
|
||||||
|
Then I should see a ".reshare"
|
||||||
|
And I should see "Bob"
|
||||||
|
|
||||||
|
And I go to the destroy user session page
|
||||||
|
And I sign in as "bob@bob.bob"
|
||||||
|
|
||||||
|
And The user deletes their first post
|
||||||
|
|
||||||
|
And I go to the destroy user session page
|
||||||
|
And I sign in as "alice@alice.alice"
|
||||||
|
|
||||||
|
And I go to the home page
|
||||||
|
Then I should see "Original post deleted by author"
|
||||||
|
|
||||||
|
Scenario: Keeps track of the number of reshares
|
||||||
|
And "bob@bob.bob" has a public post with text "reshare this!"
|
||||||
|
And I sign in as "alice@alice.alice"
|
||||||
|
And I preemptively confirm the alert
|
||||||
|
And I follow "Reshare"
|
||||||
|
And I wait for the ajax to finish
|
||||||
|
|
||||||
|
And I go to the home page
|
||||||
|
Then I should see a ".reshare"
|
||||||
|
And I follow "Your Aspects"
|
||||||
|
Then I should see "reshare this!"
|
||||||
|
Then I should see a ".reshare"
|
||||||
|
And I should see "Bob"
|
||||||
|
And I go to the home page
|
||||||
|
|
||||||
|
And I should see "1 Reshare"
|
||||||
|
|
||||||
|
Scenario: Can have text
|
||||||
|
|
@ -44,6 +44,10 @@ When /^I click to delete the first post$/ do
|
||||||
page.execute_script('$(".stream_element").first().find(".stream_element_delete").first().click()')
|
page.execute_script('$(".stream_element").first().find(".stream_element_delete").first().click()')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
When /^I click to delete the ([\d])(nd|rd|st|th) post$/ do |number, stuff|
|
||||||
|
page.execute_script('$(".stream_element:nth-child('+ number +'").first().find(".stream_element_delete").first().click()')
|
||||||
|
end
|
||||||
|
|
||||||
When /^I click to delete the first comment$/ do
|
When /^I click to delete the first comment$/ do
|
||||||
page.execute_script('$(".comment.posted").first().find(".comment_delete").click()')
|
page.execute_script('$(".comment.posted").first().find(".comment_delete").click()')
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class Chubbies
|
||||||
|
|
||||||
def self.run
|
def self.run
|
||||||
@pid = fork do
|
@pid = fork do
|
||||||
Process.exec "cd #{Rails.root}/spec/chubbies/ && bundle exec rackup -p #{PORT} 2> /dev/null 1> /dev/null"
|
Process.exec "cd #{Rails.root}/spec/chubbies/ && bundle exec #{run_command} #{nullify}"
|
||||||
end
|
end
|
||||||
|
|
||||||
at_exit do
|
at_exit do
|
||||||
|
|
@ -71,6 +71,10 @@ class Chubbies
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.nullify
|
||||||
|
"2> /dev/null > /dev/null"
|
||||||
|
end
|
||||||
|
|
||||||
def self.kill
|
def self.kill
|
||||||
`kill -9 #{get_pid}`
|
`kill -9 #{get_pid}`
|
||||||
end
|
end
|
||||||
|
|
@ -94,9 +98,13 @@ class Chubbies
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.run_command
|
||||||
|
"rackup -p #{PORT}"
|
||||||
|
end
|
||||||
|
|
||||||
def self.get_pid
|
def self.get_pid
|
||||||
@pid ||= lambda {
|
@pid ||= lambda {
|
||||||
processes = `ps ax -o pid,command | grep "rackup -p #{PORT}"`.split("\n")
|
processes = `ps ax -o pid,command | grep "#{run_command}"`.split("\n")
|
||||||
processes = processes.select{|p| !p.include?("grep") }
|
processes = processes.select{|p| !p.include?("grep") }
|
||||||
processes.first.split(" ").first
|
processes.first.split(" ").first
|
||||||
}.call
|
}.call
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,17 @@ end
|
||||||
Then /^I should see an uploaded image within the photo drop zone$/ do
|
Then /^I should see an uploaded image within the photo drop zone$/ do
|
||||||
find("#photodropzone img")["src"].should include("uploads/images")
|
find("#photodropzone img")["src"].should include("uploads/images")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Given /^"([^"]*)" has a public post with text "([^"]*)"$/ do |email, text|
|
||||||
|
user = User.find_by_email(email)
|
||||||
|
user.post(:status_message, :text => text, :public => true, :to => user.aspects)
|
||||||
|
end
|
||||||
|
|
||||||
|
Given /^"([^"]*)" has a non public post with text "([^"]*)"$/ do |email, text|
|
||||||
|
user = User.find_by_email(email)
|
||||||
|
user.post(:status_message, :text => text, :public => false, :to => user.aspects)
|
||||||
|
end
|
||||||
|
|
||||||
|
When /^The user deletes their first post$/ do
|
||||||
|
@me.posts.first.destroy
|
||||||
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
class Postzord::Dispatch
|
class Postzord::Dispatch
|
||||||
def initialize(user, object)
|
|
||||||
|
# @note Takes :additional_subscribers param to add to subscribers to dispatch to
|
||||||
|
def initialize(user, object, opts={})
|
||||||
unless object.respond_to? :to_diaspora_xml
|
unless object.respond_to? :to_diaspora_xml
|
||||||
raise 'this object does not respond_to? to_diaspora xml. try including Diaspora::Webhooks into your object'
|
raise 'this object does not respond_to? to_diaspora xml. try including Diaspora::Webhooks into your object'
|
||||||
end
|
end
|
||||||
|
|
@ -12,6 +14,7 @@ class Postzord::Dispatch
|
||||||
@object = object
|
@object = object
|
||||||
@xml = @object.to_diaspora_xml
|
@xml = @object.to_diaspora_xml
|
||||||
@subscribers = @object.subscribers(@sender)
|
@subscribers = @object.subscribers(@sender)
|
||||||
|
@subscribers = @subscribers | [*opts[:additional_subscribers]] if opts[:additional_subscribers]
|
||||||
end
|
end
|
||||||
|
|
||||||
def salmon
|
def salmon
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
namespace :db do
|
namespace :db do
|
||||||
desc "rebuild and prepare test db"
|
desc "rebuild and prepare test db"
|
||||||
task :rebuild => [:drop, :create, :migrate, :seed,'db:test:prepare']
|
task :rebuild => [:drop, :drop_integration, :create, :migrate, :seed, 'db:test:prepare']
|
||||||
|
|
||||||
namespace :integration do
|
namespace :integration do
|
||||||
# desc 'Check for pending migrations and load the integration schema'
|
# desc 'Check for pending migrations and load the integration schema'
|
||||||
|
|
@ -81,6 +81,14 @@ namespace :db do
|
||||||
end
|
end
|
||||||
task :add_user => :environment
|
task :add_user => :environment
|
||||||
|
|
||||||
|
task :drop_integration do
|
||||||
|
ActiveRecord::Base.configurations.keys.select{ |k|
|
||||||
|
k.include?("integration")
|
||||||
|
}.each{ |k|
|
||||||
|
drop_database ActiveRecord::Base.configurations[k] rescue Mysql2::Error
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
task :fix_diaspora_handle do
|
task :fix_diaspora_handle do
|
||||||
puts "fixing the people in this seed"
|
puts "fixing the people in this seed"
|
||||||
require File.join(File.dirname(__FILE__), '..', '..', 'config', 'environment')
|
require File.join(File.dirname(__FILE__), '..', '..', 'config', 'environment')
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@ var View = {
|
||||||
});
|
});
|
||||||
|
|
||||||
Diaspora.widgets.subscribe("stream/scrolled", function() {
|
Diaspora.widgets.subscribe("stream/scrolled", function() {
|
||||||
$('#main_stream .comments label').inFieldLabels();
|
$('#main_stream label').inFieldLabels();
|
||||||
});
|
});
|
||||||
|
|
||||||
Diaspora.widgets.subscribe("stream/reloaded", function() {
|
Diaspora.widgets.subscribe("stream/reloaded", function() {
|
||||||
$('#main_stream .comments label').inFieldLabels();
|
$('#main_stream label').inFieldLabels();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -475,6 +475,7 @@ ul.as-selections
|
||||||
.from
|
.from
|
||||||
a
|
a
|
||||||
:color $blue
|
:color $blue
|
||||||
|
|
||||||
.status_message_show
|
.status_message_show
|
||||||
.stream_element
|
.stream_element
|
||||||
.content
|
.content
|
||||||
|
|
@ -554,7 +555,8 @@ ul.as-selections
|
||||||
|
|
||||||
ul.comments,
|
ul.comments,
|
||||||
ul.show_comments,
|
ul.show_comments,
|
||||||
.likes_container
|
.likes_container,
|
||||||
|
.stream_element .reshare
|
||||||
|
|
||||||
.avatar
|
.avatar
|
||||||
:width 30px
|
:width 30px
|
||||||
|
|
@ -589,18 +591,18 @@ ul.show_comments,
|
||||||
:height 250px
|
:height 250px
|
||||||
:width 400px
|
:width 400px
|
||||||
|
|
||||||
.content
|
.content
|
||||||
:margin
|
:margin
|
||||||
:top 0px
|
:top 0px
|
||||||
:bottom -2px
|
:bottom -2px
|
||||||
:padding
|
:padding
|
||||||
:left 36px
|
:left 36px
|
||||||
:right 10px
|
:right 10px
|
||||||
|
|
||||||
p
|
p
|
||||||
:margin
|
:margin
|
||||||
:bottom 0
|
:bottom 0
|
||||||
:top 0
|
:top 0
|
||||||
|
|
||||||
.right
|
.right
|
||||||
:right 4px
|
:right 4px
|
||||||
|
|
@ -609,6 +611,10 @@ ul.show_comments,
|
||||||
:position absolute
|
:position absolute
|
||||||
:display inline
|
:display inline
|
||||||
|
|
||||||
|
.stream_element .reshare
|
||||||
|
:padding 10px
|
||||||
|
:border 1px solid #eee
|
||||||
|
|
||||||
ul.show_comments
|
ul.show_comments
|
||||||
:padding
|
:padding
|
||||||
:bottom 6px
|
:bottom 6px
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,12 @@ describe AspectsController do
|
||||||
assigns(:posts).models.length.should == 2
|
assigns(:posts).models.length.should == 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "posts include reshares" do
|
||||||
|
reshare = alice.post(:reshare, :public => true, :root_guid => Factory(:status_message, :public => true).guid, :to => alice.aspects)
|
||||||
|
get :index
|
||||||
|
assigns[:posts].post_fakes.map{|x| x.id}.should include(reshare.id)
|
||||||
|
end
|
||||||
|
|
||||||
it "can filter to a single aspect" do
|
it "can filter to a single aspect" do
|
||||||
get :index, :a_ids => [@alices_aspect_2.id.to_s]
|
get :index, :a_ids => [@alices_aspect_2.id.to_s]
|
||||||
assigns(:posts).models.length.should == 1
|
assigns(:posts).models.length.should == 1
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ describe PeopleController do
|
||||||
response.body.match(profile.first_name).should be_false
|
response.body.match(profile.first_name).should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
context "when the person is the current user" do
|
context "when the person is the current user" do
|
||||||
it "succeeds" do
|
it "succeeds" do
|
||||||
get :show, :id => @user.person.to_param
|
get :show, :id => @user.person.to_param
|
||||||
|
|
@ -204,6 +205,12 @@ describe PeopleController do
|
||||||
@public_posts.first.save
|
@public_posts.first.save
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "posts include reshares" do
|
||||||
|
reshare = @user.post(:reshare, :public => true, :root_guid => Factory(:status_message, :public => true).guid, :to => alice.aspects)
|
||||||
|
get :show, :id => @user.person.id
|
||||||
|
assigns[:posts].post_fakes.map{|x| x.id}.should include(reshare.id)
|
||||||
|
end
|
||||||
|
|
||||||
it "assigns only public posts" do
|
it "assigns only public posts" do
|
||||||
get :show, :id => @person.id
|
get :show, :id => @person.id
|
||||||
assigns[:posts].models.should =~ @public_posts
|
assigns[:posts].models.should =~ @public_posts
|
||||||
|
|
@ -251,6 +258,12 @@ describe PeopleController do
|
||||||
assigns(:posts).models.should =~ posts_user_can_see
|
assigns(:posts).models.should =~ posts_user_can_see
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "posts include reshares" do
|
||||||
|
reshare = @user.post(:reshare, :public => true, :root_guid => Factory(:status_message, :public => true).guid, :to => alice.aspects)
|
||||||
|
get :show, :id => @user.person.id
|
||||||
|
assigns[:posts].post_fakes.map{|x| x.id}.should include(reshare.id)
|
||||||
|
end
|
||||||
|
|
||||||
it 'sets @commenting_disabled to true' do
|
it 'sets @commenting_disabled to true' do
|
||||||
get :show, :id => @person.id
|
get :show, :id => @person.id
|
||||||
assigns(:commenting_disabled).should == false
|
assigns(:commenting_disabled).should == false
|
||||||
|
|
@ -283,6 +296,12 @@ describe PeopleController do
|
||||||
assigns[:posts].models.should =~ [public_post]
|
assigns[:posts].models.should =~ [public_post]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "posts include reshares" do
|
||||||
|
reshare = @user.post(:reshare, :public => true, :root_guid => Factory(:status_message, :public => true).guid, :to => alice.aspects)
|
||||||
|
get :show, :id => @user.person.id
|
||||||
|
assigns[:posts].post_fakes.map{|x| x.id}.should include(reshare.id)
|
||||||
|
end
|
||||||
|
|
||||||
it 'sets @commenting_disabled to true' do
|
it 'sets @commenting_disabled to true' do
|
||||||
get :show, :id => @person.id
|
get :show, :id => @person.id
|
||||||
assigns(:commenting_disabled).should == true
|
assigns(:commenting_disabled).should == true
|
||||||
|
|
|
||||||
|
|
@ -65,22 +65,49 @@ describe PublicsController do
|
||||||
it 'shows a public post' do
|
it 'shows a public post' do
|
||||||
status = alice.post(:status_message, :text => "hello", :public => true, :to => 'all')
|
status = alice.post(:status_message, :text => "hello", :public => true, :to => 'all')
|
||||||
|
|
||||||
get :post, :id => status.id
|
get :post, :guid => status.id
|
||||||
response.status= 200
|
response.status= 200
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not show a private post' do
|
it 'does not show a private post' do
|
||||||
status = alice.post(:status_message, :text => "hello", :public => false, :to => 'all')
|
status = alice.post(:status_message, :text => "hello", :public => false, :to => 'all')
|
||||||
get :post, :id => status.id
|
get :post, :guid => status.id
|
||||||
response.status = 302
|
response.status = 302
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'redirects to the proper show page if the user has visibility of the post' do
|
it 'redirects to the proper show page if the user has visibility of the post' do
|
||||||
status = alice.post(:status_message, :text => "hello", :public => true, :to => 'all')
|
status = alice.post(:status_message, :text => "hello", :public => true, :to => 'all')
|
||||||
sign_in bob
|
sign_in bob
|
||||||
get :post, :id => status.id
|
get :post, :guid => status.id
|
||||||
response.should be_redirect
|
response.should be_redirect
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'responds with diaspora xml if format is xml' do
|
||||||
|
status = alice.post(:status_message, :text => "hello", :public => true, :to => 'all')
|
||||||
|
get :post, :guid => status.guid, :format => :xml
|
||||||
|
response.body.should == status.to_diaspora_xml
|
||||||
|
end
|
||||||
|
|
||||||
|
# We want to be using guids from now on for this post route, but do not want to break
|
||||||
|
# preexisiting permalinks. We can assume a guid is 8 characters long as we have
|
||||||
|
# guids set to hex(8) since we started using them.
|
||||||
|
context 'id/guid switch' do
|
||||||
|
before do
|
||||||
|
@status = alice.post(:status_message, :text => "hello", :public => true, :to => 'all')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'assumes guids less than 8 chars are ids and not guids' do
|
||||||
|
Post.should_receive(:where).with(hash_including(:id => @status.id)).and_return(Post)
|
||||||
|
get :post, :guid => @status.id
|
||||||
|
response.status= 200
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'assumes guids more than (or equal to) 8 chars are actually guids' do
|
||||||
|
Post.should_receive(:where).with(hash_including(:guid => @status.guid)).and_return(Post)
|
||||||
|
get :post, :guid => @status.guid
|
||||||
|
response.status= 200
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#hcard' do
|
describe '#hcard' do
|
||||||
|
|
|
||||||
39
spec/controllers/reshares_controller_spec.rb
Normal file
39
spec/controllers/reshares_controller_spec.rb
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
describe ResharesController do
|
||||||
|
|
||||||
|
describe '#create' do
|
||||||
|
it 'requires authentication' do
|
||||||
|
post :create, :format => :js
|
||||||
|
response.should_not be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with an authenticated user' do
|
||||||
|
before do
|
||||||
|
sign_in :user, bob
|
||||||
|
@post_guid = Factory(:status_message, :public => true).guid
|
||||||
|
@controller.stub(:current_user).and_return(bob)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds' do
|
||||||
|
post :create, :format => :js, :root_guid => @post_guid
|
||||||
|
response.should be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates a reshare' do
|
||||||
|
expect{
|
||||||
|
post :create, :format => :js, :root_guid => @post_guid
|
||||||
|
}.should change(Reshare, :count).by(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'after save, calls add to streams' do
|
||||||
|
bob.should_receive(:add_to_streams)
|
||||||
|
post :create, :format => :js, :root_guid => @post_guid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'calls dispatch' do
|
||||||
|
bob.should_receive(:dispatch_post).with(anything, hash_including(:additional_subscribers))
|
||||||
|
post :create, :format => :js, :root_guid => @post_guid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -19,7 +19,7 @@ end
|
||||||
|
|
||||||
Factory.define :person do |p|
|
Factory.define :person do |p|
|
||||||
p.sequence(:diaspora_handle) { |n| "bob-person-#{n}#{r_str}@aol.com" }
|
p.sequence(:diaspora_handle) { |n| "bob-person-#{n}#{r_str}@aol.com" }
|
||||||
p.sequence(:url) { |n| "http://google-#{n}#{r_str}.com/" }
|
p.sequence(:url) { |n| AppConfig[:pod_url] }
|
||||||
p.serialized_public_key OpenSSL::PKey::RSA.generate(1024).public_key.export
|
p.serialized_public_key OpenSSL::PKey::RSA.generate(1024).public_key.export
|
||||||
p.after_build do |person|
|
p.after_build do |person|
|
||||||
person.profile ||= Factory.build(:profile, :person => person)
|
person.profile ||= Factory.build(:profile, :person => person)
|
||||||
|
|
@ -41,6 +41,7 @@ Factory.define :like do |x|
|
||||||
end
|
end
|
||||||
|
|
||||||
Factory.define :user do |u|
|
Factory.define :user do |u|
|
||||||
|
u.getting_started false
|
||||||
u.sequence(:username) { |n| "bob#{n}#{r_str}" }
|
u.sequence(:username) { |n| "bob#{n}#{r_str}" }
|
||||||
u.sequence(:email) { |n| "bob#{n}#{r_str}@pivotallabs.com" }
|
u.sequence(:email) { |n| "bob#{n}#{r_str}@pivotallabs.com" }
|
||||||
u.password "bluepin7"
|
u.password "bluepin7"
|
||||||
|
|
@ -91,6 +92,11 @@ Factory.define(:photo) do |p|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Factory.define :reshare do |r|
|
||||||
|
r.association(:root, :public => true, :factory => :status_message)
|
||||||
|
r.association(:author, :factory => :person)
|
||||||
|
end
|
||||||
|
|
||||||
Factory.define :service do |service|
|
Factory.define :service do |service|
|
||||||
service.nickname "sirrobertking"
|
service.nickname "sirrobertking"
|
||||||
service.type "Services::Twitter"
|
service.type "Services::Twitter"
|
||||||
|
|
|
||||||
15
spec/helpers/reshares_helper_spec.rb
Normal file
15
spec/helpers/reshares_helper_spec.rb
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
# Specs in this file have access to a helper object that includes
|
||||||
|
# the ResharesHelper. For example:
|
||||||
|
#
|
||||||
|
# describe ResharesHelper do
|
||||||
|
# describe "string concat" do
|
||||||
|
# it "concats two strings with spaces" do
|
||||||
|
# helper.concat_strings("this","that").should == "this that"
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
describe ResharesHelper do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
||||||
|
|
@ -23,10 +23,20 @@ describe Postzord::Dispatch do
|
||||||
zord.instance_variable_get(:@object).should == @sm
|
zord.instance_variable_get(:@object).should == @sm
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets @subscribers from object' do
|
context 'setting @subscribers' do
|
||||||
@sm.should_receive(:subscribers).and_return(@subscribers)
|
it 'sets @subscribers from object' do
|
||||||
zord = Postzord::Dispatch.new(alice, @sm)
|
@sm.should_receive(:subscribers).and_return(@subscribers)
|
||||||
zord.instance_variable_get(:@subscribers).should == @subscribers
|
zord = Postzord::Dispatch.new(alice, @sm)
|
||||||
|
zord.instance_variable_get(:@subscribers).should == @subscribers
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'accepts additional subscribers from opts' do
|
||||||
|
new_person = Factory(:person)
|
||||||
|
|
||||||
|
@sm.should_receive(:subscribers).and_return(@subscribers)
|
||||||
|
zord = Postzord::Dispatch.new(alice, @sm, :additional_subscribers => new_person)
|
||||||
|
zord.instance_variable_get(:@subscribers).should == @subscribers | [new_person]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the @sender_person object' do
|
it 'sets the @sender_person object' do
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ describe Person do
|
||||||
context 'local people' do
|
context 'local people' do
|
||||||
it 'uses the pod config url to set the diaspora_handle' do
|
it 'uses the pod config url to set the diaspora_handle' do
|
||||||
new_person = User.build(:username => "foo123", :email => "foo123@example.com", :password => "password", :password_confirmation => "password").person
|
new_person = User.build(:username => "foo123", :email => "foo123@example.com", :password => "password", :password_confirmation => "password").person
|
||||||
new_person.diaspora_handle.should == "foo123@#{AppConfig[:pod_uri].host}"
|
new_person.diaspora_handle.should == "foo123@#{AppConfig[:pod_uri].authority}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
151
spec/models/reshare_spec.rb
Normal file
151
spec/models/reshare_spec.rb
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Reshare do
|
||||||
|
include ActionView::Helpers::UrlHelper
|
||||||
|
include Rails.application.routes.url_helpers
|
||||||
|
def controller
|
||||||
|
mock()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
it 'has a valid Factory' do
|
||||||
|
Factory(:reshare).should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'requires root' do
|
||||||
|
reshare = Factory.build(:reshare, :root => nil)
|
||||||
|
reshare.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'require public root' do
|
||||||
|
Factory.build(:reshare, :root => Factory.build(:status_message, :public => false)).should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'forces public' do
|
||||||
|
Factory(:reshare, :public => false).public.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#receive" do
|
||||||
|
before do
|
||||||
|
@reshare = Factory.create(:reshare, :root => Factory(:status_message, :author => bob.person, :public => true))
|
||||||
|
@root = @reshare.root
|
||||||
|
@reshare.receive(@root.author.owner, @reshare.author)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'increments the reshare count' do
|
||||||
|
@root.resharers.count.should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'adds the resharer to the re-sharers of the post' do
|
||||||
|
@root.resharers.should include(@reshare.author)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "XML" do
|
||||||
|
before do
|
||||||
|
@reshare = Factory(:reshare)
|
||||||
|
@xml = @reshare.to_xml.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'serialization' do
|
||||||
|
it 'serializes root_diaspora_id' do
|
||||||
|
@xml.should include("root_diaspora_id")
|
||||||
|
@xml.should include(@reshare.author.diaspora_handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'serializes root_guid' do
|
||||||
|
@xml.should include("root_guid")
|
||||||
|
@xml.should include(@reshare.root.guid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'marshalling' do
|
||||||
|
context 'local' do
|
||||||
|
before do
|
||||||
|
@original_author = @reshare.root.author
|
||||||
|
@root_object = @reshare.root
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'marshals the guid' do
|
||||||
|
Reshare.from_xml(@xml).root_guid.should == @root_object.guid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fetches the root post from root_guid' do
|
||||||
|
Reshare.from_xml(@xml).root.should == @root_object
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fetches the root author from root_diaspora_id' do
|
||||||
|
Reshare.from_xml(@xml).root.author.should == @original_author
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'remote' do
|
||||||
|
before do
|
||||||
|
@root_object = @reshare.root
|
||||||
|
@root_object.delete
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fetches the root author from root_diaspora_id' do
|
||||||
|
@original_profile = @reshare.root.author.profile.dup
|
||||||
|
@reshare.root.author.profile.delete
|
||||||
|
@original_author = @reshare.root.author.dup
|
||||||
|
@reshare.root.author.delete
|
||||||
|
|
||||||
|
@original_author.profile = @original_profile
|
||||||
|
|
||||||
|
wf_prof_mock = mock
|
||||||
|
wf_prof_mock.should_receive(:fetch).and_return(@original_author)
|
||||||
|
Webfinger.should_receive(:new).and_return(wf_prof_mock)
|
||||||
|
|
||||||
|
response = mock
|
||||||
|
response.stub(:body).and_return(@root_object.to_diaspora_xml)
|
||||||
|
|
||||||
|
Faraday.default_connection.should_receive(:get).with(@original_author.url + public_post_path(:guid => @root_object.guid, :format => "xml")).and_return(response)
|
||||||
|
Reshare.from_xml(@xml)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'saving the post' do
|
||||||
|
before do
|
||||||
|
response = mock
|
||||||
|
response.stub(:body).and_return(@root_object.to_diaspora_xml)
|
||||||
|
Faraday.default_connection.stub(:get).with(@reshare.root.author.url + public_post_path(:guid => @root_object.guid, :format => "xml")).and_return(response)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fetches the root post from root_guid' do
|
||||||
|
root = Reshare.from_xml(@xml).root
|
||||||
|
|
||||||
|
[:text, :guid, :diaspora_handle, :type, :public].each do |attr|
|
||||||
|
root.send(attr).should == @reshare.root.send(attr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'correctly saves the type' do
|
||||||
|
Reshare.from_xml(@xml).root.reload.type.should == "StatusMessage"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'correctly sets the author' do
|
||||||
|
@original_author = @reshare.root.author
|
||||||
|
Reshare.from_xml(@xml).root.reload.author.reload.should == @original_author
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'verifies that the author of the post received is the same as the author in the reshare xml' do
|
||||||
|
@original_author = @reshare.root.author.dup
|
||||||
|
@xml = @reshare.to_xml.to_s
|
||||||
|
|
||||||
|
different_person = Factory.create(:person)
|
||||||
|
|
||||||
|
wf_prof_mock = mock
|
||||||
|
wf_prof_mock.should_receive(:fetch).and_return(different_person)
|
||||||
|
Webfinger.should_receive(:new).and_return(wf_prof_mock)
|
||||||
|
|
||||||
|
different_person.stub(:url).and_return(@original_author.url)
|
||||||
|
|
||||||
|
lambda{
|
||||||
|
Reshare.from_xml(@xml)
|
||||||
|
}.should raise_error /^Diaspora ID \(.+\) in the root does not match the Diaspora ID \(.+\) specified in the reshare!$/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -8,7 +8,7 @@ describe Retraction do
|
||||||
before do
|
before do
|
||||||
@aspect = alice.aspects.first
|
@aspect = alice.aspects.first
|
||||||
alice.contacts.create(:person => eve.person, :aspects => [@aspect])
|
alice.contacts.create(:person => eve.person, :aspects => [@aspect])
|
||||||
@post = alice.post :status_message, :text => "Destroy!", :to => @aspect.id
|
@post = alice.post(:status_message, :public => true, :text => "Destroy!", :to => @aspect.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'serialization' do
|
describe 'serialization' do
|
||||||
|
|
@ -20,12 +20,24 @@ describe Retraction do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#subscribers' do
|
describe '#subscribers' do
|
||||||
it 'returns the subscribers to the post for all objects other than person' do
|
context 'posts' do
|
||||||
retraction = Retraction.for(@post)
|
before do
|
||||||
obj = retraction.instance_variable_get(:@object)
|
@retraction = Retraction.for(@post)
|
||||||
wanted_subscribers = obj.subscribers(alice)
|
@obj = @retraction.instance_variable_get(:@object)
|
||||||
obj.should_receive(:subscribers).with(alice).and_return(wanted_subscribers)
|
@wanted_subscribers = @obj.subscribers(alice)
|
||||||
retraction.subscribers(alice).map{|s| s.id}.should =~ wanted_subscribers.map{|s| s.id}
|
end
|
||||||
|
|
||||||
|
it 'returns the subscribers to the post for all objects other than person' do
|
||||||
|
@retraction.subscribers(alice).map(&:id).should =~ @wanted_subscribers.map(&:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not return the authors of reshares' do
|
||||||
|
@post.reshares << Factory.create(:reshare, :root => @post, :author => bob.person)
|
||||||
|
@post.save!
|
||||||
|
|
||||||
|
@wanted_subscribers -= [bob.person]
|
||||||
|
@retraction.subscribers(alice).map(&:id).should =~ @wanted_subscribers.map(&:id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'setting subscribers' do
|
context 'setting subscribers' do
|
||||||
|
|
|
||||||
47
spec/models/signed_retraction_spec.rb
Normal file
47
spec/models/signed_retraction_spec.rb
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe SignedRetraction do
|
||||||
|
before do
|
||||||
|
@post = Factory(:status_message, :author => bob.person, :public => true)
|
||||||
|
@resharer = Factory(:user)
|
||||||
|
@post.reshares << Factory.create(:reshare, :root => @post, :author => @resharer.person)
|
||||||
|
@post.save!
|
||||||
|
end
|
||||||
|
describe '#perform' do
|
||||||
|
it "dispatches the retraction onward to recipients of the recipient's reshare" do
|
||||||
|
retraction = SignedRetraction.build(bob, @post)
|
||||||
|
onward_retraction = retraction.dup
|
||||||
|
retraction.should_receive(:dup).and_return(onward_retraction)
|
||||||
|
|
||||||
|
dis = mock
|
||||||
|
Postzord::Dispatch.should_receive(:new).with(@resharer, onward_retraction).and_return(dis)
|
||||||
|
dis.should_receive(:post)
|
||||||
|
|
||||||
|
retraction.perform(@resharer)
|
||||||
|
end
|
||||||
|
it 'relays the retraction onward even if the post does not exist' do
|
||||||
|
remote_post = Factory(:status_message, :public => true)
|
||||||
|
bob.post(:reshare, :root_guid => remote_post.guid)
|
||||||
|
alice.post(:reshare, :root_guid => remote_post.guid)
|
||||||
|
|
||||||
|
remote_retraction = SignedRetraction.new.tap{|r|
|
||||||
|
r.target_type = remote_post.type
|
||||||
|
r.target_guid = remote_post.guid
|
||||||
|
r.sender = remote_post.author
|
||||||
|
r.stub!(:target_author_signature_valid?).and_return(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
remote_retraction.dup.perform(bob)
|
||||||
|
Post.exists?(:id => remote_post.id).should be_false
|
||||||
|
|
||||||
|
dis = mock
|
||||||
|
Postzord::Dispatch.should_receive(:new){ |sender, retraction|
|
||||||
|
sender.should == alice
|
||||||
|
retraction.sender.should == alice.person
|
||||||
|
dis
|
||||||
|
}
|
||||||
|
dis.should_receive(:post)
|
||||||
|
remote_retraction.perform(alice)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -114,13 +114,13 @@ describe User do
|
||||||
alice.email = eve.email
|
alice.email = eve.email
|
||||||
alice.should_not be_valid
|
alice.should_not be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
it "requires a vaild email address" do
|
it "requires a vaild email address" do
|
||||||
alice.email = "somebody@anywhere"
|
alice.email = "somebody@anywhere"
|
||||||
alice.should_not be_valid
|
alice.should_not be_valid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "of unconfirmed_email" do
|
describe "of unconfirmed_email" do
|
||||||
it "unconfirmed_email address can be nil/blank" do
|
it "unconfirmed_email address can be nil/blank" do
|
||||||
alice.unconfirmed_email = nil
|
alice.unconfirmed_email = nil
|
||||||
|
|
@ -134,7 +134,7 @@ describe User do
|
||||||
alice.unconfirmed_email = "new@email.com"
|
alice.unconfirmed_email = "new@email.com"
|
||||||
alice.should be_valid
|
alice.should be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
it "requires a vaild unconfirmed_email address" do
|
it "requires a vaild unconfirmed_email address" do
|
||||||
alice.unconfirmed_email = "somebody@anywhere"
|
alice.unconfirmed_email = "somebody@anywhere"
|
||||||
alice.should_not be_valid
|
alice.should_not be_valid
|
||||||
|
|
@ -679,7 +679,7 @@ describe User do
|
||||||
user.confirm_email_token.size.should eql(30)
|
user.confirm_email_token.size.should eql(30)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#mail_confirm_email' do
|
describe '#mail_confirm_email' do
|
||||||
it 'enqueues a mail job on user with unconfirmed email' do
|
it 'enqueues a mail job on user with unconfirmed email' do
|
||||||
user.update_attribute(:unconfirmed_email, "alice@newmail.com")
|
user.update_attribute(:unconfirmed_email, "alice@newmail.com")
|
||||||
|
|
@ -712,14 +712,14 @@ describe User do
|
||||||
user.unconfirmed_email.should_not eql(nil)
|
user.unconfirmed_email.should_not eql(nil)
|
||||||
user.confirm_email_token.should_not eql(nil)
|
user.confirm_email_token.should_not eql(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns false and does not change anything on blank token' do
|
it 'returns false and does not change anything on blank token' do
|
||||||
user.confirm_email("").should eql(false)
|
user.confirm_email("").should eql(false)
|
||||||
user.email.should_not eql("alice@newmail.com")
|
user.email.should_not eql("alice@newmail.com")
|
||||||
user.unconfirmed_email.should_not eql(nil)
|
user.unconfirmed_email.should_not eql(nil)
|
||||||
user.confirm_email_token.should_not eql(nil)
|
user.confirm_email_token.should_not eql(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns false and does not change anything on blank token' do
|
it 'returns false and does not change anything on blank token' do
|
||||||
user.confirm_email(nil).should eql(false)
|
user.confirm_email(nil).should eql(false)
|
||||||
user.email.should_not eql("alice@newmail.com")
|
user.email.should_not eql("alice@newmail.com")
|
||||||
|
|
@ -752,4 +752,43 @@ describe User do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#retract' do
|
||||||
|
before do
|
||||||
|
@retraction = mock
|
||||||
|
|
||||||
|
@post = Factory(:status_message, :author => bob.person, :public => true)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "posts" do
|
||||||
|
before do
|
||||||
|
SignedRetraction.stub(:build).and_return(@retraction)
|
||||||
|
@retraction.stub(:perform)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends a retraction' do
|
||||||
|
dispatcher = mock
|
||||||
|
Postzord::Dispatch.should_receive(:new).with(bob, @retraction, anything()).and_return(dispatcher)
|
||||||
|
dispatcher.should_receive(:post)
|
||||||
|
|
||||||
|
bob.retract(@post)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'adds resharers of target post as additional subsctibers' do
|
||||||
|
person = Factory(:person)
|
||||||
|
reshare = Factory(:reshare, :root => @post, :author => person)
|
||||||
|
@post.reshares << reshare
|
||||||
|
|
||||||
|
dispatcher = mock
|
||||||
|
Postzord::Dispatch.should_receive(:new).with(bob, @retraction, {:additional_subscribers => [person]}).and_return(dispatcher)
|
||||||
|
dispatcher.should_receive(:post)
|
||||||
|
|
||||||
|
bob.retract(@post)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'performs the retraction' do
|
||||||
|
pending
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
76
spec/multi_server/reshare_spec.rb
Normal file
76
spec/multi_server/reshare_spec.rb
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
|
||||||
|
unless Server.all.empty?
|
||||||
|
describe "reposting" do
|
||||||
|
before(:all) do
|
||||||
|
WebMock::Config.instance.allow_localhost = true
|
||||||
|
enable_typhoeus
|
||||||
|
#Server.all.each{|s| s.kill if s.running?}
|
||||||
|
#Server.all.each{|s| s.run}
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:all) do
|
||||||
|
disable_typhoeus
|
||||||
|
#Server.all.each{|s| s.kill if s.running?}
|
||||||
|
#sleep(1)
|
||||||
|
#Server.all.each{|s| puts "Server at port #{s.port} still running." if s.running?}
|
||||||
|
WebMock::Config.instance.allow_localhost = false
|
||||||
|
end
|
||||||
|
before do
|
||||||
|
Server.all.each{|s| s.truncate_database; }
|
||||||
|
@original_post = nil
|
||||||
|
Server[0].in_scope do
|
||||||
|
original_poster = Factory.create(:user_with_aspect, :username => "original_poster")
|
||||||
|
resharer = Factory.create(:user_with_aspect, :username => "resharer")
|
||||||
|
|
||||||
|
connect_users_with_aspects(original_poster, resharer)
|
||||||
|
|
||||||
|
@original_post = original_poster.post(:status_message,
|
||||||
|
:public => true,
|
||||||
|
:text => "Awesome Sauce!",
|
||||||
|
:to => 'all')
|
||||||
|
end
|
||||||
|
|
||||||
|
Server[1].in_scope do
|
||||||
|
recipient = Factory.create(:user_with_aspect, :username => "recipient")
|
||||||
|
end
|
||||||
|
|
||||||
|
Server[0].in_scope do
|
||||||
|
r = User.find_by_username("resharer")
|
||||||
|
person = Webfinger.new("recipient@localhost:#{Server[1].port}").fetch
|
||||||
|
r.share_with(person, r.aspects.first)
|
||||||
|
end
|
||||||
|
Server[1].in_scope do
|
||||||
|
r = User.find_by_username("recipient")
|
||||||
|
person = Webfinger.new("resharer@localhost:#{Server[0].port}").fetch
|
||||||
|
r.share_with(person, r.aspects.first)
|
||||||
|
end
|
||||||
|
|
||||||
|
Server[0].in_scope do
|
||||||
|
r = User.find_by_username("resharer")
|
||||||
|
r.post(:reshare, :root_guid => @original_post.guid, :to => 'all')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fetches the original post from the root server' do
|
||||||
|
Server[1].in_scope do
|
||||||
|
Post.exists?(:guid => @original_post.guid).should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'relays the retraction for the root post to recipients of the reshare' do
|
||||||
|
Server[0].in_scope do
|
||||||
|
poster = User.find_by_username 'original_poster'
|
||||||
|
fantasy_resque do
|
||||||
|
poster.retract @original_post
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Server[1].in_scope do
|
||||||
|
Post.exists?(:guid => @original_post.guid).should be_false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
#This is a spec for the class that runs the servers used in the other multi-server specs
|
#This is a spec for the class that runs the servers used in the other multi-server specs
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
WebMock::Config.instance.allow_localhost = true
|
unless Server.all.empty?
|
||||||
if Server.all && Server.all.first && Server.all.first.running?
|
|
||||||
describe Server do
|
describe Server do
|
||||||
before(:all) do
|
before(:all) do
|
||||||
WebMock::Config.instance.allow_localhost = true
|
WebMock::Config.instance.allow_localhost = true
|
||||||
|
#Server.all.each{|s| s.kill if s.running?}
|
||||||
|
#Server.all.each{|s| s.run}
|
||||||
end
|
end
|
||||||
|
|
||||||
after(:all) do
|
after(:all) do
|
||||||
|
#Server.all.each{|s| s.kill if s.running?}
|
||||||
|
#sleep(1)
|
||||||
|
#Server.all.each{|s| puts "Server at port #{s.port} still running." if s.running?}
|
||||||
WebMock::Config.instance.allow_localhost = false
|
WebMock::Config.instance.allow_localhost = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -25,12 +29,12 @@ if Server.all && Server.all.first && Server.all.first.running?
|
||||||
it 'takes an environment' do
|
it 'takes an environment' do
|
||||||
server = Server.new("integration_1")
|
server = Server.new("integration_1")
|
||||||
server.env.should == "integration_1"
|
server.env.should == "integration_1"
|
||||||
server.port.should == ActiveRecord::Base.configurations["integration_1"]["app_server_port"]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
describe "#running?" do
|
describe "#running?" do
|
||||||
it "verifies that the server is running" do
|
it "verifies that the server is running" do
|
||||||
Server.new("integration_1").running?.should be_true
|
server = Server.new("integration_1")
|
||||||
|
server.running?.should be_true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
describe '#db' do
|
describe '#db' do
|
||||||
|
|
@ -52,4 +56,3 @@ if Server.all && Server.all.first && Server.all.first.running?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
WebMock::Config.instance.allow_localhost = false
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
#This class is for running servers in the background during integration testing. This will not run on Windows.
|
#This class is for running servers in the background during integration testing. This will not run on Windows.
|
||||||
class Server
|
class Server
|
||||||
|
|
||||||
|
def self.[] index
|
||||||
|
self.all[index]
|
||||||
|
end
|
||||||
|
|
||||||
def self.all
|
def self.all
|
||||||
@servers ||= ActiveRecord::Base.configurations.keys.select{
|
@servers ||= ActiveRecord::Base.configurations.keys.select{
|
||||||
|k| k.include?("integration")
|
|k| k.include?("integration")
|
||||||
|
|
@ -8,9 +13,46 @@ class Server
|
||||||
|
|
||||||
attr_reader :port, :env
|
attr_reader :port, :env
|
||||||
def initialize(env)
|
def initialize(env)
|
||||||
@config = ActiveRecord::Base.configurations[env]
|
@db_config = ActiveRecord::Base.configurations[env]
|
||||||
@port = @config["app_server_port"]
|
@app_config = (YAML.load_file AppConfig.source)[env]
|
||||||
|
@port = URI::parse(@app_config["pod_url"]).port
|
||||||
@env = env
|
@env = env
|
||||||
|
ensure_database_setup
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_database_setup
|
||||||
|
`cd #{Rails.root} && RAILS_ENV=#{@env} bundle exec rake db:create`
|
||||||
|
tables_exist = self.db do
|
||||||
|
ActiveRecord::Base.connection.tables.include?("users")
|
||||||
|
end
|
||||||
|
if tables_exist
|
||||||
|
truncate_database
|
||||||
|
else
|
||||||
|
`cd #{Rails.root} && RAILS_ENV=#{@env} bundle exec rake db:schema:load`
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
@pid = fork do
|
||||||
|
Process.exec "cd #{Rails.root} && RAILS_ENV=#{@env} bundle exec #{run_command}"# 2> /dev/null"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def kill
|
||||||
|
puts "I am trying to kill the server"
|
||||||
|
`kill -9 #{get_pid}`
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_command
|
||||||
|
"rails s -p #{@port}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_pid
|
||||||
|
@pid = lambda {
|
||||||
|
processes = `ps ax -o pid,command | grep "#{run_command}"`.split("\n")
|
||||||
|
processes = processes.select{|p| !p.include?("grep") }
|
||||||
|
processes.first.split(" ").first
|
||||||
|
}.call
|
||||||
end
|
end
|
||||||
|
|
||||||
def running?
|
def running?
|
||||||
|
|
@ -25,8 +67,12 @@ class Server
|
||||||
def db
|
def db
|
||||||
former_env = Rails.env
|
former_env = Rails.env
|
||||||
ActiveRecord::Base.establish_connection(env)
|
ActiveRecord::Base.establish_connection(env)
|
||||||
yield
|
begin
|
||||||
ActiveRecord::Base.establish_connection(former_env)
|
result = yield
|
||||||
|
ensure
|
||||||
|
ActiveRecord::Base.establish_connection(former_env)
|
||||||
|
end
|
||||||
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def truncate_database
|
def truncate_database
|
||||||
|
|
@ -34,4 +80,18 @@ class Server
|
||||||
DatabaseCleaner.clean_with(:truncation)
|
DatabaseCleaner.clean_with(:truncation)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def in_scope
|
||||||
|
pod_url = "http://localhost:#{@port}/"
|
||||||
|
old_pod_url = AppConfig[:pod_url]
|
||||||
|
AppConfig[:pod_url] = pod_url
|
||||||
|
begin
|
||||||
|
result = db do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
AppConfig[:pod_url] = old_pod_url
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
class User
|
class User
|
||||||
|
include Rails.application.routes.url_helpers
|
||||||
|
def default_url_options
|
||||||
|
{:host => AppConfig[:pod_url]}
|
||||||
|
end
|
||||||
|
|
||||||
alias_method :share_with_original, :share_with
|
alias_method :share_with_original, :share_with
|
||||||
|
|
||||||
|
|
@ -16,7 +20,9 @@ class User
|
||||||
|
|
||||||
aspects = self.aspects_from_ids(opts[:to])
|
aspects = self.aspects_from_ids(opts[:to])
|
||||||
add_to_streams(p, aspects)
|
add_to_streams(p, aspects)
|
||||||
dispatch_post(p, :to => opts[:to])
|
dispatch_opts = {:url => post_url(p), :to => opts[:to]}
|
||||||
|
dispatch_opts.merge!(:additional_subscribers => p.root.author) if class_name == :reshare
|
||||||
|
dispatch_post(p, dispatch_opts)
|
||||||
end
|
end
|
||||||
unless opts[:created_at]
|
unless opts[:created_at]
|
||||||
p.created_at = Time.now - 1
|
p.created_at = Time.now - 1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue