twitter_action_agent_spec.rb 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. require 'rails_helper'
  2. describe Agents::TwitterActionAgent do
  3. describe '#receive' do
  4. before do
  5. @event1 = Event.new
  6. @event1.agent = agents(:bob_twitter_user_agent)
  7. @event1.payload = { id: 123, text: 'So awesome.. gotta retweet' }
  8. @event1.save!
  9. @tweet1 = Twitter::Tweet.new(
  10. id: @event1.payload[:id],
  11. text: @event1.payload[:text]
  12. )
  13. @event2 = Event.new
  14. @event2.agent = agents(:bob_twitter_user_agent)
  15. @event2.payload = { id: 456, text: 'Something Justin Bieber said' }
  16. @event2.save!
  17. @tweet2 = Twitter::Tweet.new(
  18. id: @event2.payload[:id],
  19. text: @event2.payload[:text]
  20. )
  21. end
  22. context 'when set up to retweet' do
  23. before do
  24. @agent = build_agent(
  25. 'favorite' => 'false',
  26. 'retweet' => 'true',
  27. 'emit_error_events' => 'true'
  28. )
  29. @agent.save!
  30. end
  31. context 'when the twitter client succeeds retweeting' do
  32. it 'should retweet the tweets from the payload' do
  33. expect(@agent.twitter).to receive(:retweet).with([@tweet1, @tweet2])
  34. @agent.receive([@event1, @event2])
  35. end
  36. end
  37. context 'when the twitter client fails retweeting' do
  38. it 'creates an event with tweet info and the error message' do
  39. allow(@agent.twitter).to receive(:retweet).with(anything) {
  40. raise Twitter::Error.new('uh oh')
  41. }
  42. @agent.receive([@event1, @event2])
  43. failure_event = @agent.events.last
  44. expect(failure_event.payload[:error]).to eq('uh oh')
  45. expect(failure_event.payload[:tweets]).to eq(
  46. {
  47. @event1.payload[:id].to_s => @event1.payload[:text],
  48. @event2.payload[:id].to_s => @event2.payload[:text]
  49. }
  50. )
  51. expect(failure_event.payload[:agent_ids]).to match_array(
  52. [@event1.agent_id, @event2.agent_id]
  53. )
  54. expect(failure_event.payload[:event_ids]).to match_array(
  55. [@event2.id, @event1.id]
  56. )
  57. end
  58. end
  59. end
  60. context 'when set up to favorite' do
  61. before do
  62. @agent = build_agent(
  63. 'favorite' => 'true',
  64. 'retweet' => 'false',
  65. 'emit_error_events' => 'true'
  66. )
  67. @agent.save!
  68. end
  69. context 'when the twitter client succeeds favoriting' do
  70. it 'should favorite the tweets from the payload' do
  71. expect(@agent.twitter).to receive(:favorite).with([@tweet1, @tweet2])
  72. @agent.receive([@event1, @event2])
  73. end
  74. end
  75. context 'when the twitter client fails retweeting' do
  76. it 'creates an event with tweet info and the error message' do
  77. allow(@agent.twitter).to receive(:favorite).with(anything) {
  78. raise Twitter::Error.new('uh oh')
  79. }
  80. @agent.receive([@event1, @event2])
  81. failure_event = @agent.events.last
  82. expect(failure_event.payload[:error]).to eq('uh oh')
  83. expect(failure_event.payload[:tweets]).to eq(
  84. {
  85. @event1.payload[:id].to_s => @event1.payload[:text],
  86. @event2.payload[:id].to_s => @event2.payload[:text]
  87. }
  88. )
  89. expect(failure_event.payload[:agent_ids]).to match_array(
  90. [@event1.agent_id, @event2.agent_id]
  91. )
  92. expect(failure_event.payload[:event_ids]).to match_array(
  93. [@event2.id, @event1.id]
  94. )
  95. end
  96. end
  97. end
  98. context 'with emit_error_events set to false' do
  99. let(:agent) { build_agent.tap(&:save!) }
  100. it 're-raises the exception on failure' do
  101. allow(agent.twitter).to receive(:retweet).with(anything) {
  102. raise Twitter::Error.new('uh oh')
  103. }
  104. expect { agent.receive([@event1]) }.to raise_error(StandardError, /uh oh/)
  105. end
  106. it 'does not re-raise the exception on "already retweeted" error' do
  107. allow(agent.twitter).to receive(:retweet).with(anything) {
  108. raise Twitter::Error::AlreadyRetweeted.new('You have already retweeted this tweet.')
  109. }
  110. expect { agent.receive([@event1]) }.not_to raise_error
  111. end
  112. it 'does not re-raise the exception on "already favorited" error' do
  113. allow(agent.twitter).to receive(:retweet).with(anything) {
  114. raise Twitter::Error::AlreadyFavorited.new('You have already favorited this status.')
  115. }
  116. expect { agent.receive([@event1]) }.not_to raise_error
  117. end
  118. end
  119. end
  120. describe "#validate_options" do
  121. it 'the default options are valid' do
  122. agent = build_agent(described_class.new.default_options)
  123. expect(agent).to be_valid
  124. end
  125. context 'emit_error_events' do
  126. it 'can be set to true' do
  127. agent = build_agent(described_class.new.default_options.merge('emit_error_events' => 'true'))
  128. expect(agent).to be_valid
  129. end
  130. it 'must be a boolean' do
  131. agent = build_agent(described_class.new.default_options.merge('emit_error_events' => 'notbolean'))
  132. expect(agent).not_to be_valid
  133. end
  134. end
  135. it 'expected_receive_period_in_days must be set' do
  136. agent = build_agent(described_class.new.default_options.merge('expected_receive_period_in_days' => ''))
  137. expect(agent).not_to be_valid
  138. end
  139. context 'when set up to neither favorite or retweet' do
  140. it 'is invalid' do
  141. agent = build_agent(
  142. 'favorite' => 'false',
  143. 'retweet' => 'false',
  144. )
  145. expect(agent).not_to be_valid
  146. end
  147. end
  148. end
  149. describe '#working?' do
  150. before do
  151. allow_any_instance_of(Twitter::REST::Client).to receive(:retweet)
  152. end
  153. it 'checks if events have been received within the expected time period' do
  154. agent = build_agent
  155. agent.save!
  156. expect(agent).not_to be_working # No events received
  157. described_class.async_receive(agent.id, [events(:bob_website_agent_event)])
  158. expect(agent.reload).to be_working # Just received events
  159. two_days_from_now = 2.days.from_now
  160. allow(Time).to receive(:now) { two_days_from_now }
  161. expect(agent.reload).not_to be_working # Too much time has passed
  162. end
  163. end
  164. def build_agent(options = {})
  165. described_class.new do |agent|
  166. agent.name = 'twitter stuff'
  167. agent.options = agent.default_options.merge(options)
  168. agent.service = services(:generic)
  169. agent.user = users(:bob)
  170. end
  171. end
  172. end