diff --git a/Gemfile b/Gemfile index 32151c451..7c62324c5 100644 --- a/Gemfile +++ b/Gemfile @@ -1,22 +1,28 @@ source 'http://rubygems.org' gem 'rails', '3.0.0.beta4' - -gem "mongoid", :git => "http://github.com/durran/mongoid.git" +gem 'mongrel' +gem 'thin' +gem 'em-http-request' +gem 'addressable' +gem "mongoid", :git => "git://github.com/durran/mongoid.git" gem "bson_ext", "1.0.1" gem "haml" gem "devise", :git => "git://github.com/plataformatec/devise.git" gem 'roxml', :git => "git://github.com/Empact/roxml.git" -gem "thin" + + +gem 'dm-core' #:( group :test do - gem 'rspec', '>= 2.0.0.beta.10' + gem 'rspec', '>= 2.0.0.beta.12' gem 'rspec-rails', ">= 2.0.0.beta.8" gem "mocha" gem 'webrat' gem 'redgreen' gem 'autotest' gem 'factory_girl_rails' + gem 'database_cleaner' end group :development do diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f2569b3a7..42dd80cd4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,6 @@ class ApplicationController < ActionController::Base - protect_from_forgery + protect_from_forgery :except => :receive layout 'application' + + end diff --git a/app/controllers/blogs_controller.rb b/app/controllers/blogs_controller.rb index e4bf80484..f39cecdbf 100644 --- a/app/controllers/blogs_controller.rb +++ b/app/controllers/blogs_controller.rb @@ -3,7 +3,7 @@ class BlogsController < ApplicationController def index - @blogs = Blog.all + @blogs = Blog.criteria.all.order_by( [:created_at, :desc] ) end def show diff --git a/app/controllers/bookmarks_controller.rb b/app/controllers/bookmarks_controller.rb index 8cfd3f066..6defe2f07 100644 --- a/app/controllers/bookmarks_controller.rb +++ b/app/controllers/bookmarks_controller.rb @@ -2,7 +2,7 @@ class BookmarksController < ApplicationController before_filter :authenticate_user! def index - @bookmarks = Bookmark.all + @bookmarks = Bookmark.criteria.all.order_by( [:created_at, :desc] ) end def edit diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index e534252b6..7196b7fb5 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,14 +1,15 @@ class DashboardController < ApplicationController - before_filter :authenticate_user! + + before_filter :authenticate_user!, :except => :receive + include ApplicationHelper def index - @posts = Post.all - - @bookmarks = Bookmark.all - @status_messages = StatusMessage.all - @blogs = Blog.all - #@status_messages = @posts.select{ |x| x._type == "StatusMessage"} - #@blogs = @posts.select{ |x| x._type == "Blog"} - #@bookmarks = @posts.select{ |x| x._type == "Bookmarks"} + @posts = Post.stream + end + + + def receive + store_posts_from_xml (params[:xml]) + render :nothing => true end end diff --git a/app/controllers/friends_controller.rb b/app/controllers/friends_controller.rb index 000185f6e..55778861f 100644 --- a/app/controllers/friends_controller.rb +++ b/app/controllers/friends_controller.rb @@ -2,7 +2,7 @@ class FriendsController < ApplicationController before_filter :authenticate_user! def index - @friends = Friend.all + @friends = Friend.criteria.all.order_by( [:created_at, :desc] ) end def show diff --git a/app/controllers/status_messages_controller.rb b/app/controllers/status_messages_controller.rb index beae57255..0d9e1b9d8 100644 --- a/app/controllers/status_messages_controller.rb +++ b/app/controllers/status_messages_controller.rb @@ -1,14 +1,13 @@ class StatusMessagesController < ApplicationController - #before_filter :authenticate_user! - include StatusMessagesHelper + before_filter :authenticate_user! def index - @status_messages = StatusMessage.all + @status_messages = StatusMessage.criteria.all.order_by( [:created_at, :desc] ) @friends = Friend.all respond_to do |format| format.html - format.xml {render :xml => StatusMessages.new(@status_messages).to_xml } + format.xml {render :xml => Post.build_xml_for(@status_messages)} format.json { render :json => @status_messages } end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index f029dc33d..da904fab0 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -3,7 +3,7 @@ class UsersController < ApplicationController before_filter :authenticate_user! def index - @users = User.all + @users = User.criteria.all.order_by( [:created_at, :desc] ) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index f58313c9b..efb413b32 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -6,4 +6,26 @@ module ApplicationHelper def object_fields(object) object.attributes.keys end + + def store_posts_from_xml(xml) + doc = Nokogiri::XML(xml) { |cfg| cfg.noblanks } + + #i need to check some sort of metadata field + + doc.xpath("/XML/posts/post").each do |post| #this is the post wrapper + post.children.each do|type| #now the text of post itself is the type + #type object to xml is the the thing we want to from_xml + check_and_save_post(type) + end + end + end + + def check_and_save_post(type) + begin + object = type.name.camelize.constantize.from_xml type.to_s + object.save if object.is_a? Post + rescue + puts "Not of type post" + end + end end diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index a94ddfc2e..d06bca135 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -1,2 +1,7 @@ module DashboardHelper + + + + + end diff --git a/app/helpers/status_messages_helper.rb b/app/helpers/status_messages_helper.rb index 5d1bcdc93..a2b81e2e3 100644 --- a/app/helpers/status_messages_helper.rb +++ b/app/helpers/status_messages_helper.rb @@ -9,14 +9,4 @@ module StatusMessagesHelper end end - class StatusMessages - include ROXML - - def initialize(messages=[]) - @statusmessages = messages - end - - xml_accessor :statusmessages, :as => [StatusMessage] - attr_accessor :statusmessages - end end diff --git a/app/models/bookmark.rb b/app/models/bookmark.rb index c6241931f..61f4697f7 100644 --- a/app/models/bookmark.rb +++ b/app/models/bookmark.rb @@ -9,4 +9,17 @@ class Bookmark < Post validates_presence_of :link + validates_format_of :link, :with => + /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix + + before_validation :clean_link + + protected + + def clean_link + if self.link + self.link = 'http://' + self.link unless self.link.match('http://' || 'https://') + self.link = self.link + '/' if self.link[-1,1] != '/' + end + end end diff --git a/app/models/friend.rb b/app/models/friend.rb index 061a2094b..69b60fd36 100644 --- a/app/models/friend.rb +++ b/app/models/friend.rb @@ -9,5 +9,17 @@ class Friend field :url validates_presence_of :username, :url - + validates_format_of :url, :with => + /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix + + before_validation :clean_url + + protected + + def clean_url + if self.url + self.url = 'http://' + self.url unless self.url.match('http://' || 'https://') + self.url = self.url + '/' if self.url[-1,1] != '/' + end + end end diff --git a/app/models/post.rb b/app/models/post.rb index 34af94757..95985d170 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,10 +1,13 @@ class Post - + require 'lib/common' + + # XML accessors must always preceed mongo field tags include Mongoid::Document include Mongoid::Timestamps include ROXML + include Diaspora::Webhooks xml_accessor :owner xml_accessor :snippet @@ -14,9 +17,24 @@ class Post field :source field :snippet - before_create :set_defaults - #after_update :notify_friends + + @@models = ["StatusMessage", "Bookmark", "Blog"] + + def self.stream + # Need to explicitly name each inherited model for dev environment + query = if Rails.env == "development" + Post.criteria.all(:_type => @@models) + else + Post.criteria.all + end + query.order_by( [:created_at, :desc] ) + end + + def each + yield self + end + protected @@ -26,14 +44,5 @@ class Post self.source ||= user_email self.snippet ||= user_email end - - - #def notify_friends - #friends = Permissions.get_list_for(self) - #xml = self.to_xml_to_s - #friends.each{|friend| ping friend :with => xml } - #end - end - diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 4aec011e6..0b58ee72b 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -2,6 +2,8 @@ class StatusMessage < Post include StatusMessagesHelper require 'lib/net/curl' + xml_name :status_message + xml_accessor :message field :message @@ -18,7 +20,7 @@ class StatusMessage < Post end def self.retrieve_from_friend(friend) - StatusMessages.from_xml Curl.curl(friend.url+"status_messages.xml") + StatusMessages.from_xml Curl.get(friend.url+"status_messages.xml") end def ==(other) diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml index 5a63f6b9f..1c60dc8e2 100644 --- a/app/views/dashboard/index.html.haml +++ b/app/views/dashboard/index.html.haml @@ -1,7 +1,9 @@ - title "Dashboard" + %ul#stream - for post in @posts %li = render "shared/post", :post =>post + /= post.inspect diff --git a/app/views/devise/shared/_links.haml b/app/views/devise/shared/_links.haml index a7547353f..5da9aab33 100644 --- a/app/views/devise/shared/_links.haml +++ b/app/views/devise/shared/_links.haml @@ -1,9 +1,9 @@ - if controller_name != 'sessions' = link_to "Sign in", new_session_path(resource_name) %br/ -- if devise_mapping.registerable? && controller_name != 'registrations' - = link_to "Sign up", new_registration_path(resource_name) - %br/ +/- if devise_mapping.registerable? && controller_name != 'registrations' +/= link_to "Sign up", new_registration_path(resource_name) +/%br/ - if devise_mapping.recoverable? && controller_name != 'passwords' = link_to "Forgot your password?", new_password_path(resource_name) %br/ diff --git a/config/environments/test.rb b/config/environments/test.rb index fab2538d4..1a9134407 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -5,7 +5,7 @@ Diaspora::Application.configure do # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! - config.cache_classes = false + config.cache_classes = true # Log error messages when you accidentally call methods on nil. config.whiny_nils = true @@ -29,4 +29,18 @@ Diaspora::Application.configure do # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql + # + # + # + + + +begin + require 'database_cleaner' + DatabaseCleaner.strategy = :truncation + DatabaseCleaner.orm = "mongoid" +rescue LoadError => ignore_if_database_cleaner_not_present + puts "Error on cleaner" +end + end diff --git a/config/mongoid.yml b/config/mongoid.yml index 2a97fd67c..e0df0977c 100644 --- a/config/mongoid.yml +++ b/config/mongoid.yml @@ -19,8 +19,8 @@ test: # set these environment variables on your prod server production: <<: *defaults - host: <%= ENV['MONGOID_HOST'] %> - port: <%= ENV['MONGOID_PORT'] %> - username: <%= ENV['MONGOID_USERNAME'] %> - password: <%= ENV['MONGOID_PASSWORD'] %> - database: <%= ENV['MONGOID_DATABASE'] %> + #host: <%= ENV['MONGOID_HOST'] %> + #port: <%= ENV['MONGOID_PORT'] %> + #username: <%= ENV['MONGOID_USERNAME'] %> + #password: <%= ENV['MONGOID_PASSWORD'] %> + #database: <%= ENV['MONGOID_DATABASE'] %> diff --git a/config/routes.rb b/config/routes.rb index 81cd16e47..7d6f2a0a0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,8 +12,9 @@ Diaspora::Application.routes.draw do |map| devise_for :users, :path_names => {:sign_up => "signup", :sign_in => "login", :sign_out => "logout"} match 'login', :to => 'devise/sessions#new', :as => "new_user_session" match 'logout', :to => 'devise/sessions#destroy', :as => "destroy_user_session" - match 'signup', :to => 'devise/registrations#new', :as => "new_user_registration" - + #match 'signup', :to => 'devise/registrations#new', :as => "new_user_registration" + + match 'receive', :to => 'dashboard#receive' resources :users resources :status_messages diff --git a/lib/common.rb b/lib/common.rb index a89072fc5..8e34b4591 100644 --- a/lib/common.rb +++ b/lib/common.rb @@ -1,18 +1,47 @@ -module CommonField +module Diaspora - def self.included(klass) - klass.class_eval do - include Mongoid::Document - include ROXML - include Mongoid::Timestamps + module Webhooks + def self.included(klass) + klass.class_eval do + after_save :notify_friends + @@queue = MessageHandler.new + + def notify_friends + if self.owner == User.first.email + xml = Post.build_xml_for(self) + @@queue.add_post_request( friends_with_permissions, xml ) + @@queue.process + end + end + + def prep_webhook + "#{self.to_xml.to_s}" + end - xml_accessor :owner - xml_accessor :snippet - xml_accessor :source + def friends_with_permissions + Friend.only(:url).map{|x| x = x.url + "receive/"} + end - field :owner - field :source - field :snippet + def self.build_xml_for(posts) + xml = "" + xml += Post.generate_header + xml += "" + posts.each {|x| xml << x.prep_webhook} + xml += "" + xml += "" + end + + + def self.generate_header + " + + #{User.first.email} + #{User.first.email} + + " + end + + end end end end diff --git a/lib/message_handler.rb b/lib/message_handler.rb new file mode 100644 index 000000000..de4368f09 --- /dev/null +++ b/lib/message_handler.rb @@ -0,0 +1,62 @@ +require 'addressable/uri' +require 'eventmachine' +require 'em-http' + +class MessageHandler + + NUM_TRIES = 3 + TIMEOUT = 5 #seconds + + def initialize + @queue = EM::Queue.new + end + + def add_get_request(destinations) + destinations.each{ |dest| @queue.push(Message.new(:get, dest))} + end + + + def add_post_request(destinations, body) + destinations.each{|dest| @queue.push(Message.new(:post, dest, body))} + end + + def process + @queue.pop{ |query| + case query.type + when :post + http = EventMachine::HttpRequest.new(query.destination).post :timeout => TIMEOUT, :body =>{:xml => query.body} + http.callback { process} + when :get + http = EventMachine::HttpRequest.new(query.destination).get :timeout => TIMEOUT + http.callback {send_to_seed(query, http.response); process} + else + raise "message is not a type I know!" + end + + http.errback { + query.try_count +=1 + @queue.push query unless query.try_count >= NUM_TRIES + process + } + } unless @queue.size == 0 + end + + + def send_to_seed(message, http_response) + #DO SOMETHING! + end + + def size + @queue.size + end + + class Message + attr_accessor :type, :destination, :body, :try_count + def initialize(type, dest, body= nil) + @type = type + @destination = dest + @body = body + @try_count = 0 + end + end +end diff --git a/lib/net/curl.rb b/lib/net/curl.rb index 410255146..4220a27f7 100644 --- a/lib/net/curl.rb +++ b/lib/net/curl.rb @@ -1,6 +1,10 @@ class Curl - def self.curl(s) - `curl #{s}` + def self.post(s) + `curl -X POST -d #{s}`;; + end + + def self.get(s) + `curl -X GET #{s}` end end diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb index 0b20b21ab..b6ad08b93 100644 --- a/spec/controllers/dashboard_controller_spec.rb +++ b/spec/controllers/dashboard_controller_spec.rb @@ -8,4 +8,5 @@ describe DashboardController do get :index response.should render_template(:index) end + end 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/helpers/parser_spec.rb b/spec/helpers/parser_spec.rb new file mode 100644 index 000000000..542a1aa0a --- /dev/null +++ b/spec/helpers/parser_spec.rb @@ -0,0 +1,41 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +include ApplicationHelper + +describe ApplicationHelper do + before do + Factory.create(:user) + end + + it "should store objects sent from xml" do + status_messages = [] + 10.times { status_messages << Factory.build(:status_message)} + + xml = Post.build_xml_for(status_messages) + + store_posts_from_xml(xml) + StatusMessage.count.should == 10 + end + + it 'should discard posts where it does not know the type' do + xml = " + \n Here is another message\n a@a.com\n a@a.com\n a@a.com\n + + \n HEY DUDE\n a@a.com\n a@a.com\n a@a.com\n + " + store_posts_from_xml(xml) + Post.count.should == 2 + end + + it 'should discard types which are not of type post' do + xml = " + \n Here is another message\n a@a.com\n a@a.com\n a@a.com\n + + \n HEY DUDE\n a@a.com\n a@a.com\n a@a.com\n + " + store_posts_from_xml(xml) + Post.count.should == 2 + end + +end + diff --git a/spec/lib/common_spec.rb b/spec/lib/common_spec.rb new file mode 100644 index 000000000..ec9433119 --- /dev/null +++ b/spec/lib/common_spec.rb @@ -0,0 +1,95 @@ +require File.dirname(__FILE__) + '/../spec_helper' + + +include Diaspora + +describe Diaspora do + + describe Webhooks do + before do + Factory.create(:user, :email => "bob@aol.com") + end + + describe "header" do + before do + Factory.create(:status_message) + Factory.create(:bookmark) + stream = Post.stream + @xml = Post.build_xml_for(stream) + end + + it "should generate" do + @xml.should include "" + @xml.should include "" + end + + it "should provide a sender" do + @xml.should include "" + @xml.should include "" + end + + it "should provide the owner's email" do + @xml.should include "bob@aol.com" + end + + it "should provide the owner's url" do + pending "user does not have url field" + end + end + + describe "body" do + before do + @post = Factory.create(:post) + end + + it "should add the following methods to Post on inclusion" do + @post.respond_to?(:notify_friends).should be true + @post.respond_to?(:prep_webhook).should be true + @post.respond_to?(:friends_with_permissions).should be true + end + + it "should convert an object to a proper webhook" do + @post.prep_webhook.should == "#{@post.to_xml.to_s}" + end + + it "should retrieve all valid friend endpoints" do + Factory.create(:friend, :url => "http://www.bob.com/") + Factory.create(:friend, :url => "http://www.alice.com/") + Factory.create(:friend, :url => "http://www.jane.com/") + + @post.friends_with_permissions.should include("http://www.bob.com/receive/") + @post.friends_with_permissions.should include("http://www.alice.com/receive/") + @post.friends_with_permissions.should include("http://www.jane.com/receive/") + end + + it "should send an owners post to their friends" do + Post.stub(:build_xml_for).and_return(true) + Post.should_receive(:build_xml_for).and_return true + @post.save + end + + it "should check that it does not send a friends post to an owners friends" do + Post.stub(:build_xml_for).and_return(true) + Post.should_not_receive(:build_xml_for) + Factory.create(:post, :owner => "nottheowner@post.com") + end + + it "should ensure one url is created for every friend" do + 5.times {Factory.create(:friend)} + @post.friends_with_permissions.size.should == 5 + end + + it "should build an xml object containing multiple Post types" do + Factory.create(:status_message) + Factory.create(:bookmark) + + stream = Post.stream + xml = Post.build_xml_for(stream) + xml.should include "" + xml.should include "" + end + end + + end + +end 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/bookmark_spec.rb b/spec/models/bookmark_spec.rb index 99cbbd2a5..f46b05dea 100644 --- a/spec/models/bookmark_spec.rb +++ b/spec/models/bookmark_spec.rb @@ -13,4 +13,66 @@ describe Bookmark do n = Factory.create(:bookmark) n.owner.should == "bob@aol.com" end + + it 'should validate its link' do + bookmark = Factory.build(:bookmark) + + #links changed valid + bookmark.link = "google.com" + bookmark.valid?.should == true + bookmark.link.should == "http://google.com/" + + bookmark.link = "www.google.com" + bookmark.valid?.should == true + bookmark.link.should == "http://www.google.com/" + + bookmark.link = "google.com/" + bookmark.valid?.should == true + bookmark.link.should == "http://google.com/" + + bookmark.link = "www.google.com/" + bookmark.valid?.should == true + bookmark.link.should == "http://www.google.com/" + + bookmark.link = "http://google.com" + bookmark.valid?.should == true + bookmark.link.should == "http://google.com/" + + bookmark.link = "http://www.google.com" + bookmark.valid?.should == true + + #invalid links + bookmark.link = "zsdvzxdg" + bookmark.valid?.should == false + bookmark.link = "sdfasfa.c" + bookmark.valid?.should == false + bookmark.link = "http://.com/" + bookmark.valid?.should == false + bookmark.link = "http://www..com/" + bookmark.valid?.should == false + bookmark.link = "http:/www.asodij.com/" + bookmark.valid?.should == false + bookmark.link = "https:/www.asodij.com/" + bookmark.valid?.should == false + bookmark.link = "http:///www.asodij.com/" + bookmark.valid?.should == false + end + + describe "XML" do + it 'should serialize to XML' do + Factory.create(:user) + message = Factory.create(:bookmark, :title => "Reddit", :link => "http://reddit.com") + message.to_xml.to_s.should include "Reddit" + message.to_xml.to_s.should include "http://reddit.com/" + end + + it 'should marshal serialized XML to object' do + xml = "Reddit</message><link>http://reddit.com/</link><owner>bob@aol.com</owner></bookmark>" + parsed = Bookmark.from_xml(xml) + parsed.title.should == "Reddit" + parsed.link.should == "http://reddit.com/" + parsed.owner.should == "bob@aol.com" + parsed.valid?.should be_true + end + end end diff --git a/spec/models/friend_spec.rb b/spec/models/friend_spec.rb index 7106e16ee..4ccf0ee7c 100644 --- a/spec/models/friend_spec.rb +++ b/spec/models/friend_spec.rb @@ -1,13 +1,59 @@ require File.dirname(__FILE__) + '/../spec_helper' describe Friend do + it 'should have a diaspora username and diaspora url' do - n = Factory.build(:friend, :url => nil) + n = Factory.build(:friend, :url => "") n.valid?.should be false n.url = "http://max.com/" n.valid?.should be true end + + it 'should validate its url' do + friend = Factory.build(:friend) + + #urls changed valid + friend.url = "google.com" + friend.valid?.should == true + friend.url.should == "http://google.com/" + + friend.url = "www.google.com" + friend.valid?.should == true + friend.url.should == "http://www.google.com/" + + friend.url = "google.com/" + friend.valid?.should == true + friend.url.should == "http://google.com/" + + friend.url = "www.google.com/" + friend.valid?.should == true + friend.url.should == "http://www.google.com/" + + friend.url = "http://google.com" + friend.valid?.should == true + friend.url.should == "http://google.com/" + + friend.url = "http://www.google.com" + friend.valid?.should == true + + #invalid urls + friend.url = "zsdvzxdg" + friend.valid?.should == false + friend.url = "sdfasfa.c" + friend.valid?.should == false + friend.url = "http://.com/" + friend.valid?.should == false + friend.url = "http://www..com/" + friend.valid?.should == false + friend.url = "http:/www.asodij.com/" + friend.valid?.should == false + friend.url = "https:/www.asodij.com/" + friend.valid?.should == false + friend.url = "http:///www.asodij.com/" + friend.valid?.should == false + end + describe "XML" do before do @f = Factory.build(:friend) 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..7bfa0af00 100644 --- a/spec/models/status_message_spec.rb +++ b/spec/models/status_message_spec.rb @@ -1,5 +1,4 @@ require File.dirname(__FILE__) + '/../spec_helper' -include StatusMessagesHelper describe StatusMessage do before do @@ -40,51 +39,12 @@ describe StatusMessage do end it 'should marshal serialized XML to object' do - xml = "<statusmessage>\n <message>I hate WALRUSES!</message><owner>Bob@rob.ert</owner></statusmessage>" + xml = "<statusmessage><message>I hate WALRUSES!</message><owner>Bob@rob.ert</owner></statusmessage>" parsed = StatusMessage.from_xml(xml) parsed.message.should == "I hate WALRUSES!" parsed.owner.should == "Bob@rob.ert" parsed.valid?.should be_true end end - - describe "retrieving" do - before do - @remote = Factory.create(:friend, :url => "fakeurl")#http://localhost:1254/") - Curl.stub!(:curl).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 - end - 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 - end end -@@remote_xml = -"<statusmessages> - <statusmessage> - <message>jimmy's 22 whales</message> - <owner>tester@yahoo.com</owner> - </statusmessage> - <statusmessage> - <message>jimmy's 23 whales</message> - <owner>tester@yahoo.com</owner> - </statusmessage> - <statusmessage> - <message>jimmy's 24 whales</message> - <owner>tester@yahoo.com</owner> - </statusmessage> - <statusmessage> - <message>jimmy's 25 whales</message> - <owner>tester@yahoo.com</owner> - </statusmessage> - <statusmessage> - <message>jimmy's 26 whales</message> - <owner>tester@yahoo.com</owner> - </statusmessage> -</statusmessages>" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dbfcae118..060511f9a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,7 @@ ENV["RAILS_ENV"] ||= 'test' require File.dirname(__FILE__) + "/../config/environment" unless defined?(Rails) require 'rspec/rails' +require 'database_cleaner' #require File.dirname(__FILE__) + "/factories" include Devise::TestHelpers @@ -20,11 +21,21 @@ Rspec.configure do |config| # config.mock_with :rr config.mock_with :rspec - config.fixture_path = "#{::Rails.root}/spec/fixtures" - config.before(:each) do - Mongoid.master.collections.select { |c| c.name != 'system.indexes' }.each(&:drop) + DatabaseCleaner.strategy = :truncation + DatabaseCleaner.orm = "mongoid" - end + config.before(:suite) do + DatabaseCleaner.strategy = :transaction + DatabaseCleaner.clean_with(:truncation) + end + + config.before(:each) do + DatabaseCleaner.start + end + + config.after(:each) do + DatabaseCleaner.clean + end # If you're not using ActiveRecord, or you'd prefer not to run each of your