event_spec.rb 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. require 'rails_helper'
  2. describe Event do
  3. describe ".with_location" do
  4. it "selects events with location" do
  5. event = events(:bob_website_agent_event)
  6. event.lat = 2
  7. event.lng = 3
  8. event.save!
  9. expect(Event.with_location.pluck(:id)).to eq([event.id])
  10. event.lat = nil
  11. event.save!
  12. expect(Event.with_location).to be_empty
  13. end
  14. end
  15. describe "#location" do
  16. it "returns a default hash when an event does not have a location" do
  17. event = events(:bob_website_agent_event)
  18. expect(event.location).to eq(Location.new(
  19. lat: nil,
  20. lng: nil,
  21. radius: 0.0,
  22. speed: nil,
  23. course: nil
  24. ))
  25. end
  26. it "returns a hash containing location information" do
  27. event = events(:bob_website_agent_event)
  28. event.lat = 2
  29. event.lng = 3
  30. event.payload = {
  31. radius: 300,
  32. speed: 0.5,
  33. course: 90.0,
  34. }
  35. event.save!
  36. expect(event.location).to eq(Location.new(
  37. lat: 2.0,
  38. lng: 3.0,
  39. radius: 0.0,
  40. speed: 0.5,
  41. course: 90.0
  42. ))
  43. end
  44. end
  45. describe "#reemit" do
  46. it "creates a new event identical to itself" do
  47. events(:bob_website_agent_event).lat = 2
  48. events(:bob_website_agent_event).lng = 3
  49. events(:bob_website_agent_event).created_at = 2.weeks.ago
  50. expect {
  51. events(:bob_website_agent_event).reemit!
  52. }.to change { Event.count }.by(1)
  53. expect(Event.last.payload).to eq(events(:bob_website_agent_event).payload)
  54. expect(Event.last.agent).to eq(events(:bob_website_agent_event).agent)
  55. expect(Event.last.lat).to eq(2)
  56. expect(Event.last.lng).to eq(3)
  57. expect(Event.last.created_at.to_i).to be_within(2).of(Time.now.to_i)
  58. end
  59. end
  60. describe ".cleanup_expired!" do
  61. it "removes any Events whose expired_at date is non-null and in the past, updating Agent counter caches" do
  62. half_hour_event = agents(:jane_weather_agent).create_event expires_at: 20.minutes.from_now
  63. one_hour_event = agents(:bob_weather_agent).create_event expires_at: 1.hours.from_now
  64. two_hour_event = agents(:jane_weather_agent).create_event expires_at: 2.hours.from_now
  65. three_hour_event = agents(:jane_weather_agent).create_event expires_at: 3.hours.from_now
  66. non_expiring_event = agents(:bob_weather_agent).create_event({})
  67. initial_bob_count = agents(:bob_weather_agent).reload.events_count
  68. initial_jane_count = agents(:jane_weather_agent).reload.events_count
  69. current_time = Time.now
  70. allow(Time).to receive(:now) { current_time }
  71. Event.cleanup_expired!
  72. expect(Event.find_by_id(half_hour_event.id)).not_to be_nil
  73. expect(Event.find_by_id(one_hour_event.id)).not_to be_nil
  74. expect(Event.find_by_id(two_hour_event.id)).not_to be_nil
  75. expect(Event.find_by_id(three_hour_event.id)).not_to be_nil
  76. expect(Event.find_by_id(non_expiring_event.id)).not_to be_nil
  77. expect(agents(:bob_weather_agent).reload.events_count).to eq(initial_bob_count)
  78. expect(agents(:jane_weather_agent).reload.events_count).to eq(initial_jane_count)
  79. current_time = 119.minutes.from_now # move almost 2 hours into the future
  80. Event.cleanup_expired!
  81. expect(Event.find_by_id(half_hour_event.id)).to be_nil
  82. expect(Event.find_by_id(one_hour_event.id)).to be_nil
  83. expect(Event.find_by_id(two_hour_event.id)).not_to be_nil
  84. expect(Event.find_by_id(three_hour_event.id)).not_to be_nil
  85. expect(Event.find_by_id(non_expiring_event.id)).not_to be_nil
  86. expect(agents(:bob_weather_agent).reload.events_count).to eq(initial_bob_count - 1)
  87. expect(agents(:jane_weather_agent).reload.events_count).to eq(initial_jane_count - 1)
  88. current_time = 2.minutes.from_now # move 2 minutes further into the future
  89. Event.cleanup_expired!
  90. expect(Event.find_by_id(two_hour_event.id)).to be_nil
  91. expect(Event.find_by_id(three_hour_event.id)).not_to be_nil
  92. expect(Event.find_by_id(non_expiring_event.id)).not_to be_nil
  93. expect(agents(:bob_weather_agent).reload.events_count).to eq(initial_bob_count - 1)
  94. expect(agents(:jane_weather_agent).reload.events_count).to eq(initial_jane_count - 2)
  95. end
  96. it "doesn't touch Events with no expired_at" do
  97. event = Event.new
  98. event.agent = agents(:jane_weather_agent)
  99. event.expires_at = nil
  100. event.save!
  101. current_time = Time.now
  102. allow(Time).to receive(:now) { current_time }
  103. Event.cleanup_expired!
  104. expect(Event.find_by_id(event.id)).not_to be_nil
  105. current_time = 2.days.from_now
  106. Event.cleanup_expired!
  107. expect(Event.find_by_id(event.id)).not_to be_nil
  108. end
  109. it "always keeps the latest Event regardless of its expires_at value only if the database is MySQL" do
  110. Event.delete_all
  111. event1 = agents(:jane_weather_agent).create_event expires_at: 1.minute.ago
  112. event2 = agents(:bob_weather_agent).create_event expires_at: 1.minute.ago
  113. Event.cleanup_expired!
  114. case ActiveRecord::Base.connection.adapter_name
  115. when /\Amysql/i
  116. expect(Event.all.pluck(:id)).to eq([event2.id])
  117. else
  118. expect(Event.all.pluck(:id)).to be_empty
  119. end
  120. end
  121. end
  122. describe "after destroy" do
  123. it "nullifies any dependent AgentLogs" do
  124. expect(agent_logs(:log_for_jane_website_agent).outbound_event_id).to be_present
  125. expect(agent_logs(:log_for_bob_website_agent).outbound_event_id).to be_present
  126. agent_logs(:log_for_bob_website_agent).outbound_event.destroy
  127. expect(agent_logs(:log_for_jane_website_agent).reload.outbound_event_id).to be_present
  128. expect(agent_logs(:log_for_bob_website_agent).reload.outbound_event_id).to be_nil
  129. end
  130. end
  131. describe "caches" do
  132. describe "when an event is created" do
  133. it "updates a counter cache on agent" do
  134. expect {
  135. agents(:jane_weather_agent).events.create!(user: users(:jane))
  136. }.to change { agents(:jane_weather_agent).reload.events_count }.by(1)
  137. end
  138. it "updates last_event_at on agent" do
  139. expect {
  140. agents(:jane_weather_agent).events.create!(user: users(:jane))
  141. }.to change { agents(:jane_weather_agent).reload.last_event_at }
  142. end
  143. end
  144. describe "when an event is updated" do
  145. it "does not touch the last_event_at on the agent" do
  146. event = agents(:jane_weather_agent).events.create!(user: users(:jane))
  147. agents(:jane_weather_agent).update_attribute :last_event_at, 2.days.ago
  148. expect {
  149. event.update_attribute :payload, { 'hello' => 'world' }
  150. }.not_to change { agents(:jane_weather_agent).reload.last_event_at }
  151. end
  152. end
  153. end
  154. end
  155. describe Event::Drop do
  156. def interpolate(string, event)
  157. event.agent.interpolate_string(string, event.to_liquid)
  158. end
  159. before do
  160. @event = Event.new
  161. @event.agent = agents(:jane_weather_agent)
  162. @event.created_at = Time.now
  163. @event.payload = {
  164. 'title' => 'some title',
  165. 'url' => 'http://some.site.example.org/',
  166. }
  167. @event.lat = 2
  168. @event.lng = 3
  169. @event.save!
  170. end
  171. it 'should be created via Agent#to_liquid' do
  172. expect(@event.to_liquid.class).to be(Event::Drop)
  173. end
  174. it 'should have attributes of its payload' do
  175. t = '{{title}}: {{url}}'
  176. expect(interpolate(t, @event)).to eq('some title: http://some.site.example.org/')
  177. end
  178. it 'should use created_at from the payload if it exists' do
  179. created_at = @event.created_at - 86400
  180. # Avoid timezone issue by using %s
  181. @event.payload['created_at'] = created_at.strftime("%s")
  182. @event.save!
  183. t = '{{created_at | date:"%s" }}'
  184. expect(interpolate(t, @event)).to eq(created_at.strftime("%s"))
  185. end
  186. it 'should be iteratable' do
  187. # to_liquid returns self
  188. t = "{% for pair in to_liquid %}{{pair | join:':' }}\n{% endfor %}"
  189. expect(interpolate(t, @event)).to eq("title:some title\nurl:http://some.site.example.org/\n")
  190. end
  191. it 'should have agent' do
  192. t = '{{agent.name}}'
  193. expect(interpolate(t, @event)).to eq('SF Weather')
  194. end
  195. it 'should have created_at' do
  196. t = '{{created_at | date:"%FT%T%z" }}'
  197. expect(interpolate(t, @event)).to eq(@event.created_at.strftime("%FT%T%z"))
  198. end
  199. it 'should have _location_' do
  200. t = '{{_location_.lat}},{{_location_.lng}}'
  201. expect(interpolate(t, @event)).to eq("2.0,3.0")
  202. end
  203. end