From 628af0372fc31341b63662bdb49123fcaf18aead Mon Sep 17 00:00:00 2001 From: danielvincent Date: Thu, 17 Jun 2010 14:29:41 -0700 Subject: [PATCH] DG MS; completed event-queue intergration. --- app/controllers/dashboard_controller.rb | 2 +- app/models/post.rb | 3 +- lib/message_handler.rb | 2 +- lib/net/curl.rb | 1 - spec/factories.rb | 1 + spec/lib/message_handler_spec.rb | 152 ++++++++++++++++++++++++ spec/models/post_spec.rb | 25 +++- spec/models/status_message_spec.rb | 4 +- 8 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 spec/lib/message_handler_spec.rb diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index c9d082015..62911ac1c 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -2,6 +2,6 @@ class DashboardController < ApplicationController before_filter :authenticate_user! def index - @posts = Post.recent_ordered_posts + @posts = Post.stream end end diff --git a/app/models/post.rb b/app/models/post.rb index a72520074..926545c1c 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,6 +1,5 @@ class Post require 'lib/common' - require 'lib/message_handler' # XML accessors must always preceed mongo field tags @@ -22,7 +21,7 @@ class Post @@models = ["StatusMessage", "Bookmark", "Blog"] - def self.recent_ordered_posts + def self.stream # Need to explicitly name each inherited model for dev environment query = if Rails.env == "development" Post.criteria.all(:_type => @@models) diff --git a/lib/message_handler.rb b/lib/message_handler.rb index 27480f400..428d88942 100644 --- a/lib/message_handler.rb +++ b/lib/message_handler.rb @@ -25,7 +25,7 @@ class MessageHandler case query.type when :post http = EventMachine::HttpRequest.new(query.destination).post :timeout => TIMEOUT, :body => query.body - http.callback {puts "YAR"; process} + http.callback { process} when :get http = EventMachine::HttpRequest.new(query.destination).get :timeout => TIMEOUT http.callback {send_to_seed(query, http.response); process} diff --git a/lib/net/curl.rb b/lib/net/curl.rb index 6ccc409b1..4220a27f7 100644 --- a/lib/net/curl.rb +++ b/lib/net/curl.rb @@ -1,7 +1,6 @@ class Curl def self.post(s) `curl -X POST -d #{s}`;; - true end def self.get(s) diff --git a/spec/factories.rb b/spec/factories.rb index a63f32c31..5997c11e5 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,6 +1,7 @@ #For Guidance #http://github.com/thoughtbot/factory_girl #http://railscasts.com/episodes/158-factories-not-fixtures + Factory.define :friend do |f| f.username 'max' f.url 'http://max.com/' diff --git a/spec/lib/message_handler_spec.rb b/spec/lib/message_handler_spec.rb new file mode 100644 index 000000000..3ec0a6e2c --- /dev/null +++ b/spec/lib/message_handler_spec.rb @@ -0,0 +1,152 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe MessageHandler do + before do + @handler = MessageHandler.new + @message_body = "I want to pump you up" + @message_urls = ["http://www.google.com/", "http://yahoo.com/", "http://foo.com/"] + end + + describe 'GET messages' do + describe 'creating a GET query' do + it 'should be able to add a GET query to the queue with required destinations' do + EventMachine.run{ + @handler.add_get_request(@message_urls) + @handler.size.should == @message_urls.size + EventMachine.stop + } + end + + end + + describe 'processing a GET query' do + it 'should remove sucessful http requests from the queue' do + request = FakeHttpRequest.new(:success) + request.should_receive(:get).and_return(request) + EventMachine::HttpRequest.stub!(:new).and_return(request) + + EventMachine.run { + @handler.add_get_request("http://www.google.com/") + @handler.size.should == 1 + @handler.process + @handler.size.should == 0 + EventMachine.stop + } + end + + + it 'should only retry a bad request three times ' do + request = FakeHttpRequest.new(:failure) + request.should_receive(:get).exactly(MessageHandler::NUM_TRIES).times.and_return(request) + EventMachine::HttpRequest.stub!(:new).and_return(request) + + EventMachine.run { + @handler.add_get_request("http://asdfsdajfsdfbasdj.com/") + @handler.size.should == 1 + @handler.process + @handler.size.should == 0 + + EventMachine.stop + } + end + end + end + + describe 'POST messages' do + + + it 'should be able to add a post message to the queue' do + EventMachine.run { + @handler.size.should ==0 + @handler.add_post_request(@message_urls.first, @message_body) + @handler.size.should == 1 + + EventMachine.stop + } + end + + it 'should be able to insert many posts into the queue' do + EventMachine.run { + @handler.size.should == 0 + @handler.add_post_request(@message_urls, @message_body) + @handler.size.should == @message_urls.size + EventMachine.stop + } + end + + it 'should post a single message to a given URL' do + request = FakeHttpRequest.new(:success) + request.should_receive(:post).and_return(request) + EventMachine::HttpRequest.stub!(:new).and_return(request) + EventMachine.run{ + + @handler.add_post_request(@message_urls.first, @message_body) + @handler.size.should == 1 + @handler.process + @handler.size.should == 0 + + EventMachine.stop + + } + end + end + + describe "Mixed Queries" do + + it 'should process both POST and GET requests in the same queue' do + request = FakeHttpRequest.new(:success) + request.should_receive(:get).exactly(3).times.and_return(request) + request.should_receive(:post).exactly(3).times.and_return(request) + EventMachine::HttpRequest.stub!(:new).and_return(request) + + EventMachine.run{ + @handler.add_post_request(@message_urls,@message_body) + @handler.size.should == 3 + @handler.add_get_request(@message_urls) + @handler.size.should == 6 + @handler.process + timer = EventMachine::Timer.new(1) do + @handler.size.should == 0 + EventMachine.stop + end + } + end + + it 'should be able to have seperate POST and GET have different callbacks' do + request = FakeHttpRequest.new(:success) + request.should_receive(:get).exactly(1).times.and_return(request) + request.should_receive(:post).exactly(1).times.and_return(request) + @handler.should_receive(:send_to_seed).once + + EventMachine::HttpRequest.stub!(:new).and_return(request) + + EventMachine.run{ + @handler.add_post_request(@message_urls.first,@message_body) + @handler.add_get_request(@message_urls.first) + @handler.process + + EventMachine.stop + } + + end + end +end + +class FakeHttpRequest + def initialize(callback_wanted) + @callback = callback_wanted + end + def response + "NOTE YOU ARE IN FAKE HTTP" + end + + def post; end + def get; end + def callback(&b) + b.call if @callback == :success + end + def errback(&b) + b.call if @callback == :failure + end +end + diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 313956825..79457ab03 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -3,13 +3,15 @@ require File.dirname(__FILE__) + '/../spec_helper' describe Post do before do Factory.create(:user, :email => "bob@aol.com") - @post = Factory.create(:post, :owner => nil, :source => nil, :snippet => nil) end describe 'requirements' do end describe 'defaults' do + before do + @post = Factory.create(:post, :owner => nil, :source => nil, :snippet => nil) + end it "should add an owner if none is present" do @post.owner.should == "bob@aol.com" @@ -23,10 +25,21 @@ describe Post do @post.snippet.should == "bob@aol.com" end end + + it "should list child types in reverse chronological order" do + Factory.create(:status_message, :message => "puppies", :created_at => Time.now+1) + Factory.create(:bookmark, :title => "Reddit", :link => "http://reddit.com", :created_at => Time.now+2) + Factory.create(:status_message, :message => "kittens", :created_at => Time.now+3) + Factory.create(:blog, :title => "Bears", :body => "Bear's body", :created_at => Time.now+4) + Factory.create(:bookmark, :title => "Google", :link => "http://google.com", :created_at => Time.now+5) + + stream = Post.stream + stream.count.should == 5 + stream[0].class.should == Bookmark + stream[1].class.should == Blog + stream[2].class.should == StatusMessage + stream[3].class.should == Bookmark + stream[4].class.should == StatusMessage + end end -#question! -#STI ? do i need to call mongoid doc on child? -# validations inherit? -# type param. -# inheriting snippet builder method diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb index 899a43484..67e9f4dbb 100644 --- a/spec/models/status_message_spec.rb +++ b/spec/models/status_message_spec.rb @@ -51,7 +51,7 @@ describe StatusMessage do describe "retrieving" do before do @remote = Factory.create(:friend, :url => "fakeurl")#http://localhost:1254/") - Curl.stub!(:curl).and_return(@@remote_xml) + Curl.stub!(:get).and_return(@@remote_xml) end it "should marshal xml and serialize it without error" do StatusMessages.from_xml(@@remote_xml).to_xml.to_s.should == @@remote_xml @@ -59,6 +59,8 @@ describe StatusMessage do it "marshal retrieved xml" do remote_msgs = StatusMessage.retrieve_from_friend(@remote) local_msgs = StatusMessages.from_xml(@@remote_xml) + + remote_msgs.statusmessages.each{ |m| local_msgs.statusmessages.include?(m).should be_true} local_msgs.statusmessages.each{ |m| remote_msgs.statusmessages.include?(m).should be_true} end