agent_spec.rb 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. require 'spec_helper'
  2. describe Agent do
  3. describe ".run_schedule" do
  4. before do
  5. Agents::WeatherAgent.count.should > 0
  6. Agents::WebsiteAgent.count.should > 0
  7. end
  8. it "runs agents with the given schedule" do
  9. mock.any_instance_of(Agents::WeatherAgent).async_check.twice
  10. mock.any_instance_of(Agents::WebsiteAgent).async_check.once
  11. Agent.run_schedule("midnight")
  12. end
  13. it "groups agents by type" do
  14. mock(Agents::WeatherAgent).bulk_check("midnight").once
  15. mock(Agents::WebsiteAgent).bulk_check("midnight").once
  16. Agent.run_schedule("midnight")
  17. end
  18. it "only runs agents with the given schedule" do
  19. do_not_allow.any_instance_of(Agents::WebsiteAgent).async_check
  20. Agent.run_schedule("blah")
  21. end
  22. end
  23. describe "changes to type" do
  24. it "validates types" do
  25. source = Agent.new
  26. source.type = "Agents::WeatherAgent"
  27. source.should have(0).errors_on(:type)
  28. source.type = "Agents::WebsiteAgent"
  29. source.should have(0).errors_on(:type)
  30. source.type = "Agents::Fake"
  31. source.should have(1).error_on(:type)
  32. end
  33. it "disallows changes to type once a record has been saved" do
  34. source = agents(:bob_website_agent)
  35. source.type = "Agents::WeatherAgent"
  36. source.should have(1).error_on(:type)
  37. end
  38. it "should know about available types" do
  39. Agent.types.should include(Agents::WeatherAgent, Agents::WebsiteAgent)
  40. end
  41. end
  42. describe "with a mock source" do
  43. class Agents::SomethingSource < Agent
  44. default_schedule "2pm"
  45. def check
  46. create_event :payload => {}
  47. end
  48. def validate_options
  49. errors.add(:base, "bad is bad") if options[:bad]
  50. end
  51. end
  52. class Agents::CannotBeScheduled < Agent
  53. cannot_be_scheduled!
  54. end
  55. before do
  56. stub(Agents::SomethingSource).valid_type?("Agents::SomethingSource") { true }
  57. stub(Agents::CannotBeScheduled).valid_type?("Agents::CannotBeScheduled") { true }
  58. end
  59. describe ".default_schedule" do
  60. it "stores the default on the class" do
  61. Agents::SomethingSource.default_schedule.should == "2pm"
  62. Agents::SomethingSource.new.default_schedule.should == "2pm"
  63. end
  64. it "sets the default on new instances, allows setting new schedules, and prevents invalid schedules" do
  65. @checker = Agents::SomethingSource.new(:name => "something")
  66. @checker.user = users(:bob)
  67. @checker.schedule.should == "2pm"
  68. @checker.save!
  69. @checker.reload.schedule.should == "2pm"
  70. @checker.update_attribute :schedule, "5pm"
  71. @checker.reload.schedule.should == "5pm"
  72. @checker.reload.schedule.should == "5pm"
  73. @checker.schedule = "this_is_not_real"
  74. @checker.should have(1).errors_on(:schedule)
  75. end
  76. it "should have an empty schedule if it cannot_be_scheduled" do
  77. @checker = Agents::CannotBeScheduled.new(:name => "something")
  78. @checker.user = users(:bob)
  79. @checker.schedule.should be_nil
  80. @checker.should be_valid
  81. @checker.schedule = "5pm"
  82. @checker.save!
  83. @checker.schedule.should be_nil
  84. @checker.schedule = "5pm"
  85. @checker.should have(0).errors_on(:schedule)
  86. @checker.schedule.should be_nil
  87. end
  88. end
  89. describe "#create_event" do
  90. it "should use the checker's user" do
  91. @checker = Agents::SomethingSource.new(:name => "something")
  92. @checker.user = users(:bob)
  93. @checker.save!
  94. @checker.check
  95. Event.last.user.should == @checker.user
  96. end
  97. end
  98. describe "#async_check" do
  99. it "records last_check_at and calls check" do
  100. @checker = Agents::SomethingSource.new(:name => "something")
  101. @checker.user = users(:bob)
  102. @checker.save!
  103. @checker.options[:new] = true
  104. mock(@checker).check.once
  105. @checker.last_check_at.should be_nil
  106. @checker.async_check
  107. @checker.last_check_at.should be_within(2).of(Time.now)
  108. @checker.reload.options[:new].should be_true # Show that we save options
  109. end
  110. end
  111. describe ".receive!" do
  112. before do
  113. stub_request(:any, /wunderground/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
  114. stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }
  115. end
  116. it "should use available events" do
  117. mock.any_instance_of(Agents::TriggerAgent).receive(anything).once
  118. agents(:bob_weather_agent).async_check
  119. Agent.receive!
  120. end
  121. it "should track when events have been seen and not see them again" do
  122. mock.any_instance_of(Agents::TriggerAgent).receive(anything).once
  123. agents(:bob_weather_agent).async_check
  124. Agent.receive!
  125. Agent.receive!
  126. end
  127. it "should not run consumers that have nothing to do" do
  128. do_not_allow.any_instance_of(Agents::TriggerAgent).receive(anything)
  129. Agent.receive!
  130. end
  131. it "should group events" do
  132. mock.any_instance_of(Agents::TriggerAgent).receive(anything).twice { |events|
  133. events.map(&:user).map(&:username).uniq.length.should == 1
  134. }
  135. agents(:bob_weather_agent).async_check
  136. agents(:jane_weather_agent).async_check
  137. Agent.receive!
  138. end
  139. end
  140. describe "validations" do
  141. it "calls validate_options" do
  142. agent = Agents::SomethingSource.new(:name => "something")
  143. agent.user = users(:bob)
  144. agent.options[:bad] = true
  145. agent.should have(1).error_on(:base)
  146. agent.options[:bad] = false
  147. agent.should have(0).errors_on(:base)
  148. end
  149. it "symbolizes options before validating" do
  150. agent = Agents::SomethingSource.new(:name => "something")
  151. agent.user = users(:bob)
  152. agent.options["bad"] = true
  153. agent.should have(1).error_on(:base)
  154. agent.options["bad"] = false
  155. agent.should have(0).errors_on(:base)
  156. end
  157. it "symbolizes memory before validating" do
  158. agent = Agents::SomethingSource.new(:name => "something")
  159. agent.user = users(:bob)
  160. agent.memory["bad"] = :hello
  161. agent.save
  162. agent.memory[:bad].should == :hello
  163. end
  164. it "should not allow agents owned by other people" do
  165. agent = Agents::SomethingSource.new(:name => "something")
  166. agent.user = users(:bob)
  167. agent.source_ids = [agents(:bob_weather_agent).id]
  168. agent.should have(0).errors_on(:sources)
  169. agent.source_ids = [agents(:jane_weather_agent).id]
  170. agent.should have(1).errors_on(:sources)
  171. agent.user = users(:jane)
  172. agent.should have(0).errors_on(:sources)
  173. end
  174. end
  175. end
  176. describe "scopes" do
  177. describe "of_type" do
  178. it "should accept classes" do
  179. agents = Agent.of_type(Agents::WebsiteAgent)
  180. agents.should include(agents(:bob_website_agent))
  181. agents.should include(agents(:jane_website_agent))
  182. agents.should_not include(agents(:bob_weather_agent))
  183. end
  184. it "should accept strings" do
  185. agents = Agent.of_type("Agents::WebsiteAgent")
  186. agents.should include(agents(:bob_website_agent))
  187. agents.should include(agents(:jane_website_agent))
  188. agents.should_not include(agents(:bob_weather_agent))
  189. end
  190. it "should accept instances of an Agent" do
  191. agents = Agent.of_type(agents(:bob_website_agent))
  192. agents.should include(agents(:bob_website_agent))
  193. agents.should include(agents(:jane_website_agent))
  194. agents.should_not include(agents(:bob_weather_agent))
  195. end
  196. end
  197. end
  198. end