PageRenderTime 27ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/spec/lib/postzord/dispatch_spec.rb

https://github.com/geekt/diaspora
Ruby | 338 lines | 301 code | 34 blank | 3 comment | 5 complexity | fbb7db414b4de01b666619e249f0687a MD5 | raw file
  1. # Copyright (c) 2010, Diaspora Inc. This file is
  2. # licensed under the Affero General Public License version 3 or later. See
  3. # the COPYRIGHT file.
  4. require 'spec_helper'
  5. require File.join(Rails.root, 'lib/postzord')
  6. require File.join(Rails.root, 'lib/postzord/dispatch')
  7. describe Postzord::Dispatch do
  8. before do
  9. @sm = Factory(:status_message, :public => true, :author => alice.person)
  10. @subscribers = []
  11. 5.times{@subscribers << Factory(:person)}
  12. @sm.stub!(:subscribers)
  13. @xml = @sm.to_diaspora_xml
  14. end
  15. describe '.initialize' do
  16. it 'takes an sender(User) and object (responds_to #subscibers) and sets then to @sender and @object' do
  17. zord = Postzord::Dispatch.new(alice, @sm)
  18. zord.instance_variable_get(:@sender).should == alice
  19. zord.instance_variable_get(:@object).should == @sm
  20. end
  21. context 'setting @subscribers' do
  22. it 'sets @subscribers from object' do
  23. @sm.should_receive(:subscribers).and_return(@subscribers)
  24. zord = Postzord::Dispatch.new(alice, @sm)
  25. zord.instance_variable_get(:@subscribers).should == @subscribers
  26. end
  27. it 'accepts additional subscribers from opts' do
  28. new_person = Factory(:person)
  29. @sm.should_receive(:subscribers).and_return(@subscribers)
  30. zord = Postzord::Dispatch.new(alice, @sm, :additional_subscribers => new_person)
  31. zord.instance_variable_get(:@subscribers).should == @subscribers | [new_person]
  32. end
  33. end
  34. it 'sets the @sender_person object' do
  35. zord = Postzord::Dispatch.new(alice, @sm)
  36. zord.instance_variable_get(:@sender_person).should == alice.person
  37. end
  38. it 'raises and gives you a helpful message if the object can not federate' do
  39. proc{ Postzord::Dispatch.new(alice, [])
  40. }.should raise_error /Diaspora::Webhooks/
  41. end
  42. end
  43. it 'creates a salmon base object' do
  44. zord = Postzord::Dispatch.new(alice, @sm)
  45. zord.salmon.should_not be nil
  46. end
  47. context 'instance methods' do
  48. before do
  49. @subscribers << bob.person
  50. @remote_people, @local_people = @subscribers.partition{ |person| person.owner_id.nil? }
  51. @sm.stub!(:subscribers).and_return @subscribers
  52. @zord = Postzord::Dispatch.new(alice, @sm)
  53. end
  54. describe '#post' do
  55. before do
  56. @zord.stub!(:socket_and_notify_users)
  57. end
  58. it 'calls Array#partition on subscribers' do
  59. @subscribers.should_receive(:partition).and_return([@remote_people, @local_people])
  60. @zord.post
  61. end
  62. it 'calls #deliver_to_local with local people' do
  63. @zord.should_receive(:deliver_to_local).with(@local_people)
  64. @zord.post
  65. end
  66. it 'calls #deliver_to_remote with remote people' do
  67. @zord.should_receive(:deliver_to_remote).with(@remote_people)
  68. @zord.post
  69. end
  70. end
  71. context "comments" do
  72. before do
  73. @local_luke, @local_leia, @remote_raphael = set_up_friends
  74. end
  75. context "local luke's post is commented on by" do
  76. before do
  77. @post = @local_luke.post(:status_message, :text => "hello", :to => @local_luke.aspects.first)
  78. end
  79. context "local leia" do
  80. before do
  81. @comment = @local_leia.build_comment :text => "yo", :post => @post
  82. @comment.save
  83. end
  84. context "local leia's mailman" do
  85. before do
  86. @mailman = Postzord::Dispatch.new(@local_leia, @comment)
  87. end
  88. it 'calls deliver_to_local with local_luke' do
  89. @mailman.should_receive(:deliver_to_local).with([@local_luke.person])
  90. @mailman.post
  91. end
  92. it 'calls deliver_to_remote with nobody' do
  93. @mailman.should_receive(:deliver_to_remote).with([])
  94. @mailman.post
  95. end
  96. it 'does not call socket_to_users' do
  97. @mailman.should_not_receive(:socket_to_users)
  98. @mailman.post
  99. end
  100. it 'does not call notify_users' do
  101. @mailman.should_not_receive(:notify_users)
  102. @mailman.post
  103. end
  104. end
  105. context "local luke's mailman" do
  106. before do
  107. @mailman = Postzord::Dispatch.new(@local_luke, @comment)
  108. end
  109. it 'does not call deliver_to_local' do
  110. @mailman.should_not_receive(:deliver_to_local)
  111. @mailman.post
  112. end
  113. it 'calls deliver_to_remote with remote raphael' do
  114. @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
  115. @mailman.post
  116. end
  117. it 'calls socket_to_users' do
  118. @mailman.should_receive(:socket_to_users).with([@local_leia, @local_luke])
  119. @mailman.post
  120. end
  121. it 'calls notify_users' do
  122. @mailman.should_receive(:notify_users).with([@local_leia])
  123. @mailman.post
  124. end
  125. end
  126. end
  127. context "remote raphael" do
  128. before do
  129. @comment = Factory.build(:comment, :author => @remote_raphael, :post => @post)
  130. @comment.save
  131. @mailman = Postzord::Dispatch.new(@local_luke, @comment)
  132. end
  133. it 'does not call deliver_to_local' do
  134. @mailman.should_not_receive(:deliver_to_local)
  135. @mailman.post
  136. end
  137. it 'calls deliver_to_remote with remote_raphael' do
  138. @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
  139. @mailman.post
  140. end
  141. it 'calls socket_to_users' do
  142. @mailman.should_receive(:socket_to_users).with([@local_leia])
  143. @mailman.post
  144. end
  145. it 'calls notify_users' do
  146. @mailman.should_receive(:notify_users).with([@local_leia])
  147. @mailman.post
  148. end
  149. end
  150. context "local luke" do
  151. before do
  152. @comment = @local_luke.build_comment :text => "yo", :post => @post
  153. @comment.save
  154. @mailman = Postzord::Dispatch.new(@local_luke, @comment)
  155. end
  156. it 'does not call deliver_to_local' do
  157. @mailman.should_not_receive(:deliver_to_local)
  158. @mailman.post
  159. end
  160. it 'calls deliver_to_remote with remote_raphael' do
  161. @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
  162. @mailman.post
  163. end
  164. it 'calls socket_to_users' do
  165. @mailman.should_receive(:socket_to_users).with([@local_leia, @local_luke])
  166. @mailman.post
  167. end
  168. it 'calls notify_users' do
  169. @mailman.should_receive(:notify_users).with([@local_leia])
  170. @mailman.post
  171. end
  172. end
  173. end
  174. context "remote raphael's post is commented on by local luke" do
  175. before do
  176. @post = Factory(:status_message, :author => @remote_raphael)
  177. @comment = @local_luke.build_comment :text => "yo", :post => @post
  178. @comment.save
  179. @mailman = Postzord::Dispatch.new(@local_luke, @comment)
  180. end
  181. it 'calls deliver_to_remote with remote_raphael' do
  182. @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
  183. @mailman.post
  184. end
  185. it 'calls deliver_to_local with nobody' do
  186. @mailman.should_receive(:deliver_to_local).with([])
  187. @mailman.post
  188. end
  189. it 'does not call socket_to_users' do
  190. @mailman.should_not_receive(:socket_to_users)
  191. @mailman.post
  192. end
  193. it 'does not call notify_users' do
  194. @mailman.should_not_receive(:notify_users)
  195. @mailman.post
  196. end
  197. end
  198. end
  199. describe '#deliver_to_remote' do
  200. before do
  201. @remote_people = []
  202. @remote_people << alice.person
  203. @mailman = Postzord::Dispatch.new(alice, @sm)
  204. @hydra = mock()
  205. Typhoeus::Hydra.stub!(:new).and_return(@hydra)
  206. end
  207. it 'should queue an HttpPost job for each remote person' do
  208. Resque.should_receive(:enqueue).with(Job::HttpMulti, alice.id, anything, @remote_people.map{|p| p.id}).once
  209. @mailman.send(:deliver_to_remote, @remote_people)
  210. end
  211. it 'calls salmon_for each remote person' do
  212. salmon = @mailman.salmon
  213. Salmon::SalmonSlap.stub(:create).and_return(salmon)
  214. salmon.should_receive(:xml_for).with(alice.person).and_return('what')
  215. @hydra.stub!(:queue)
  216. @hydra.stub!(:run)
  217. fantasy_resque do
  218. @mailman.send(:deliver_to_remote, @remote_people)
  219. end
  220. end
  221. end
  222. describe '#deliver_to_local' do
  223. before do
  224. @mailman = Postzord::Dispatch.new(alice, @sm)
  225. end
  226. it 'queues a batch receive' do
  227. local_people = []
  228. local_people << alice.person
  229. Resque.should_receive(:enqueue).with(Job::ReceiveLocalBatch, @sm.id, [alice.id]).once
  230. @mailman.send(:deliver_to_local, local_people)
  231. end
  232. it 'returns if people are empty' do
  233. Resque.should_not_receive(:enqueue)
  234. @mailman.send(:deliver_to_local, [])
  235. end
  236. it 'returns if the object is a profile' do
  237. @mailman.instance_variable_set(:@object, Profile.new)
  238. Resque.should_not_receive(:enqueue)
  239. @mailman.send(:deliver_to_local, [1])
  240. end
  241. end
  242. describe '#deliver_to_services' do
  243. before do
  244. alice.aspects.create(:name => "whatever")
  245. @service = Services::Facebook.new(:access_token => "yeah")
  246. alice.services << @service
  247. end
  248. it 'queues a job to notify the hub' do
  249. Resque.stub!(:enqueue).with(Job::PostToService, anything, anything, anything)
  250. Resque.should_receive(:enqueue).with(Job::PublishToHub, alice.public_url)
  251. @zord.send(:deliver_to_services, nil, [])
  252. end
  253. it 'does not push to hub for non-public posts' do
  254. @sm = Factory(:status_message)
  255. mailman = Postzord::Dispatch.new(alice, @sm)
  256. mailman.should_not_receive(:deliver_to_hub)
  257. mailman.post(:url => "http://joindiaspora.com/p/123")
  258. end
  259. it 'only pushes to specified services' do
  260. @s1 = Factory.create(:service, :user_id => alice.id)
  261. alice.services << @s1
  262. @s2 = Factory.create(:service, :user_id => alice.id)
  263. alice.services << @s2
  264. mailman = Postzord::Dispatch.new(alice, Factory(:status_message))
  265. Resque.stub!(:enqueue).with(Job::PublishToHub, anything)
  266. Resque.stub!(:enqueue).with(Job::HttpMulti, anything, anything, anything)
  267. Resque.should_receive(:enqueue).with(Job::PostToService, @s1.id, anything, anything)
  268. mailman.post(:url => "http://joindiaspora.com/p/123", :services => [@s1])
  269. end
  270. it 'does not push to services if none are specified' do
  271. mailman = Postzord::Dispatch.new(alice, Factory(:status_message))
  272. Resque.stub!(:enqueue).with(Job::PublishToHub, anything)
  273. Resque.should_not_receive(:enqueue).with(Job::PostToService, anything, anything, anything)
  274. mailman.post(:url => "http://joindiaspora.com/p/123")
  275. end
  276. end
  277. describe '#socket_and_notify_users' do
  278. it 'should call object#socket_to_user for each local user' do
  279. sc = mock()
  280. SocketsController.should_receive(:new).and_return(sc)
  281. sc.should_receive(:outgoing).with(bob,
  282. @zord.instance_variable_get(:@object),
  283. :aspect_ids => bob.contact_for(alice.person).aspect_memberships.map{|a| postgres? ? a.aspect_id.to_s : a.aspect_id })
  284. @zord.send(:socket_and_notify_users, [bob])
  285. end
  286. it 'only tries to socket when the object responds to #socket_to_user' do
  287. f = Request.new
  288. f.stub!(:subscribers)
  289. f.stub!(:to_diaspora_xml)
  290. users = [bob]
  291. z = Postzord::Dispatch.new(alice, f)
  292. z.instance_variable_get(:@object).should_receive(:socket_to_user).once
  293. z.send(:socket_to_users, users)
  294. end
  295. it 'queues Job::NotifyLocalUsers jobs' do
  296. @zord.instance_variable_get(:@object).should_receive(:socket_to_user).and_return(false)
  297. Resque.should_receive(:enqueue).with(Job::NotifyLocalUsers, [bob.id], @sm.class.to_s, @sm.id, @sm.author.id)
  298. @zord.send(:socket_and_notify_users, [bob])
  299. end
  300. end
  301. end
  302. end