website_agent_spec.rb 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. require 'spec_helper'
  2. describe Agents::WebsiteAgent do
  3. before do
  4. stub_request(:any, /xkcd/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/xkcd.html")), :status => 200)
  5. @site = {
  6. :name => "XKCD",
  7. :expected_update_period_in_days => 2,
  8. :type => "html",
  9. :url => "http://xkcd.com",
  10. :mode => :on_change,
  11. :extract => {
  12. :url => {:css => "#comic img", :attr => "src"},
  13. :title => {:css => "#comic img", :attr => "title"}
  14. }
  15. }
  16. @checker = Agents::WebsiteAgent.new(:name => "xkcd", :options => @site)
  17. @checker.user = users(:bob)
  18. @checker.save!
  19. end
  20. describe "#check" do
  21. it "should check for changes" do
  22. lambda { @checker.check }.should change { Event.count }.by(1)
  23. lambda { @checker.check }.should_not change { Event.count }
  24. end
  25. it "should always save events when in :all mode" do
  26. lambda {
  27. @site[:mode] = :all
  28. @checker.options = @site
  29. @checker.check
  30. @checker.check
  31. }.should change { Event.count }.by(2)
  32. end
  33. it "should log an error if the number of results for a set of extraction patterns differs" do
  34. @site[:extract][:url][:css] = "div"
  35. @checker.options = @site
  36. @checker.check
  37. @checker.logs.first.message.should =~ /Got an uneven number of matches/
  38. end
  39. end
  40. describe '#working?' do
  41. it 'checks if events have been received within the expected receive period' do
  42. stubbed_time = Time.now
  43. stub(Time).now { stubbed_time }
  44. @checker.should_not be_working # No events created
  45. @checker.check
  46. @checker.reload.should be_working # Just created events
  47. @checker.error "oh no!"
  48. @checker.reload.should_not be_working # There is a recent error
  49. stubbed_time = 20.minutes.from_now
  50. @checker.events.delete_all
  51. @checker.check
  52. @checker.reload.should be_working # There is a newer event now
  53. stubbed_time = 2.days.from_now
  54. @checker.reload.should_not be_working # Two days have passed without a new event having been created
  55. end
  56. end
  57. describe "parsing" do
  58. it "parses CSS" do
  59. @checker.check
  60. event = Event.last
  61. event.payload[:url].should == "http://imgs.xkcd.com/comics/evolving.png"
  62. event.payload[:title].should =~ /^Biologists play reverse/
  63. end
  64. it "should turn relative urls to absolute" do
  65. rel_site = {
  66. :name => "XKCD",
  67. :expected_update_period_in_days => 2,
  68. :type => "html",
  69. :url => "http://xkcd.com",
  70. :mode => :on_change,
  71. :extract => {
  72. :url => {:css => "#topLeft a", :attr => "href"},
  73. :title => {:css => "#topLeft a", :text => "true"}
  74. }
  75. }
  76. rel = Agents::WebsiteAgent.new(:name => "xkcd", :options => rel_site)
  77. rel.user = users(:bob)
  78. rel.save!
  79. rel.check
  80. event = Event.last
  81. event.payload[:url].should == "http://xkcd.com/about"
  82. end
  83. describe "JSON" do
  84. it "works with paths" do
  85. json = {
  86. :response => {
  87. :version => 2,
  88. :title => "hello!"
  89. }
  90. }
  91. stub_request(:any, /json-site/).to_return(:body => json.to_json, :status => 200)
  92. site = {
  93. :name => "Some JSON Response",
  94. :expected_update_period_in_days => 2,
  95. :type => "json",
  96. :url => "http://json-site.com",
  97. :mode => :on_change,
  98. :extract => {
  99. :version => { :path => "response.version" },
  100. :title => { :path => "response.title" }
  101. }
  102. }
  103. checker = Agents::WebsiteAgent.new(:name => "Weather Site", :options => site)
  104. checker.user = users(:bob)
  105. checker.save!
  106. checker.check
  107. event = Event.last
  108. event.payload[:version].should == 2
  109. event.payload[:title].should == "hello!"
  110. end
  111. it "can handle arrays" do
  112. json = {
  113. :response => {
  114. :data => [
  115. { :title => "first", :version => 2 },
  116. { :title => "second", :version => 2.5 }
  117. ]
  118. }
  119. }
  120. stub_request(:any, /json-site/).to_return(:body => json.to_json, :status => 200)
  121. site = {
  122. :name => "Some JSON Response",
  123. :expected_update_period_in_days => 2,
  124. :type => "json",
  125. :url => "http://json-site.com",
  126. :mode => :on_change,
  127. :extract => {
  128. :title => { :path => "response.data[*].title" },
  129. :version => { :path => "response.data[*].version" }
  130. }
  131. }
  132. checker = Agents::WebsiteAgent.new(:name => "Weather Site", :options => site)
  133. checker.user = users(:bob)
  134. checker.save!
  135. lambda {
  136. checker.check
  137. }.should change { Event.count }.by(2)
  138. event = Event.all[-1]
  139. event.payload[:version].should == 2.5
  140. event.payload[:title].should == "second"
  141. event = Event.all[-2]
  142. event.payload[:version].should == 2
  143. event.payload[:title].should == "first"
  144. end
  145. it "stores the whole object if :extract is not specified" do
  146. json = {
  147. :response => {
  148. :version => 2,
  149. :title => "hello!"
  150. }
  151. }
  152. stub_request(:any, /json-site/).to_return(:body => json.to_json, :status => 200)
  153. site = {
  154. :name => "Some JSON Response",
  155. :expected_update_period_in_days => 2,
  156. :type => "json",
  157. :url => "http://json-site.com",
  158. :mode => :on_change
  159. }
  160. checker = Agents::WebsiteAgent.new(:name => "Weather Site", :options => site)
  161. checker.user = users(:bob)
  162. checker.save!
  163. checker.check
  164. event = Event.last
  165. event.payload[:response][:version].should == 2
  166. event.payload[:response][:title].should == "hello!"
  167. end
  168. end
  169. end
  170. end