Permalink
Browse files

Merge remote-tracking branch 'geihsler/issue_448'

  • Loading branch information...
carols10cents committed Feb 8, 2012
2 parents 2c4c14d + 848421b commit efb83b921430c027051bbe4b475a2675e089c92f
@@ -67,33 +67,7 @@ def create
require_login! :return => request.referrer
# Find or create the Feed
- subscribe_to_feed = Feed.first(:id => params[:subscribe_to])
-
- unless subscribe_to_feed
- # Allow for a variety of feed addresses
- case params[:subscribe_to]
- when /^feed:\/\//
- # SAFARI!!!!1 /me shakes his first at the sky
- feed_url = "http" + params[:subscribe_to][4..-1]
- when /@/
- # XXX: ensure caching of finger lookup.
- redfinger_lookup = Redfinger.finger(params[:subscribe_to])
- feed_url = redfinger_lookup.links.find { |l| l['rel'] == 'http://schemas.google.com/g/2010#updates-from' }.to_s
- else
- feed_url = params[:subscribe_to]
- end
-
- # See if we already have a local feed for this remote
- subscribe_to_feed = Feed.first(:remote_url => feed_url)
-
- unless subscribe_to_feed
- # create a feed
- subscribe_to_feed = Feed.create(:remote_url => feed_url)
- # Populate the Feed with Updates and Author from the remote site
- # Pass along the redfinger information to build the Author if available
- subscribe_to_feed.populate redfinger_lookup
- end
- end
+ subscribe_to_feed = Feed.find_or_create(params[:subscribe_to])
# Stop and return a nice message if already following this feed
if current_user.following_feed? subscribe_to_feed
View
@@ -1,3 +1,5 @@
+require_relative '../../lib/finds_or_creates_feeds'
+
# Feeds are pretty central to everything. They're a representation of a PuSH
# enabled Atom feed. Every user has a feed of their updates, we keep feeds
# for remote users that our users are subscribed to, and maybe even other
@@ -32,13 +34,23 @@ class Feed
after_create :default_hubs
+ def self.find_or_create(subscribe_to)
+ FindsOrCreatesFeeds.find_or_create(subscribe_to)
+ end
+
+ def self.create_from_feed_data(feed_data)
+ feed = Feed.create(:remote_url => feed_data.url)
+ feed.populate(feed_data.finger_data)
+ feed
+ end
+
# This is because sometimes the mongomapper association returns nil
# even though there is an author_id and the Author exists; see Issue #421
def author
Author.find(author_id)
end
- def populate(xrd = nil)
+ def populate(finger_data)
# TODO: More entropy would be nice
self.verify_token = Digest::MD5.hexdigest(rand.to_s)
self.secret = Digest::MD5.hexdigest(rand.to_s)
@@ -61,15 +73,11 @@ def populate(xrd = nil)
:bio => a.portable_contacts.note,
:image_url => avatar_url)
- if xrd
- # Retrieve the public key
- public_key = xrd.links.find { |l| l['rel'].downcase == 'magic-public-key' }
- public_key = public_key.href[/^.*?,(.*)$/,1]
- self.author.public_key = public_key
+ if(finger_data)
+ self.author.public_key = finger_data.public_key
self.author.reset_key_lease
- # Salmon URL
- self.author.salmon_url = xrd.links.find { |l| l['rel'].downcase == 'salmon' }
+ self.author.salmon_url = finger_data.salmon_url
self.author.save
end
@@ -0,0 +1,36 @@
+require_relative 'finger'
+
+class FindsOrCreatesFeeds
+ def self.find_or_create(subscribe_to)
+ feed = Feed.first(:id => subscribe_to)
+
+ unless feed
+ feed_data = ConvertsSubscriberToFeedData.get_feed_data(subscribe_to)
+ feed = Feed.first(:remote_url => feed_data.url) || Feed.create_from_feed_data(feed_data)
+ end
+
+ feed
+ end
+end
+
+FeedData = Struct.new(:url, :finger_data)
+
+class ConvertsSubscriberToFeedData
+ def self.get_feed_data(subscriber_url)
+ feed_data = FeedData.new
+
+ case subscriber_url
+ when /^feed:\/\//
+ # SAFARI!!!!1 /me shakes his first at the sky
+ feed_data.url = "http" + subscriber_url[4..-1]
+ when /@/
+ finger_data = QueriesWebFinger.query(subscriber_url)
+ feed_data.url = finger_data.url
+ feed_data.finger_data = finger_data
+ else
+ feed_data.url = subscriber_url
+ end
+
+ feed_data
+ end
+end
View
@@ -0,0 +1,26 @@
+class FingerData
+ def initialize(xrd)
+ @xrd = xrd
+ end
+
+ def url
+ @xrd.links.find { |l| l['rel'] == 'http://schemas.google.com/g/2010#updates-from' }.to_s
+ end
+
+ def public_key
+ public_key_href = @xrd.links.find { |l| l['rel'].downcase == 'magic-public-key' }.href
+ public_key_href[/^.*?,(.*)$/,1]
+ end
+
+ def salmon_url
+ @xrd.links.find { |l| l['rel'].downcase == 'salmon' }.href
+ end
+end
+
+class QueriesWebFinger
+ def self.query(email)
+ # XXX: ensure caching of finger lookup.
+ xrd = Redfinger.finger(email)
+ FingerData.new(xrd)
+ end
+end
@@ -0,0 +1,39 @@
+require 'minitest/autorun'
+require 'mocha'
+
+require_relative '../../lib/finds_or_creates_feeds'
+
+FakeFingerData = Struct.new(:url)
+
+describe "converting subscriber to feed data" do
+ describe "when the subscriber url has feed in it" do
+ it "should replace the feed with http" do
+ feed_data = ConvertsSubscriberToFeedData.get_feed_data("feed://stuff")
+
+ assert_equal "http://stuff", feed_data.url
+ end
+ end
+
+ describe "when the subscriber info is an email address " do
+ it "should finger the user" do
+ email = "somebody@somewhere.com"
+ finger_data = FakeFingerData.new("url")
+ QueriesWebFinger.expects(:query).with(email).returns(finger_data)
+
+ new_feed_data = ConvertsSubscriberToFeedData.get_feed_data(email)
+
+ assert_equal "url", new_feed_data.url
+ assert_equal finger_data, new_feed_data.finger_data
+ end
+ end
+
+ describe "when the subscriber is an http url " do
+ it "should use the subscriber url as the feed url" do
+ feed_url = "http://feed.me"
+
+ feed_data = ConvertsSubscriberToFeedData.get_feed_data(feed_url)
+
+ assert_equal feed_url, feed_data.url
+ end
+ end
+end
@@ -0,0 +1,59 @@
+require 'minitest/autorun'
+require 'mocha'
+
+require_relative '../../lib/finds_or_creates_feeds'
+
+class Feed
+end
+
+describe "finding or creating a new feed" do
+ before do
+ @feed = Feed.new
+ @subscriber_id = "id"
+ end
+
+ describe "when feed exists with the subscriber id" do
+ it "should return the feed" do
+ Feed.expects(:first).with(:id => @subscriber_id).returns(@feed)
+
+ feed = FindsOrCreatesFeeds.find_or_create(@subscriber_id)
+
+ assert_equal @feed, feed
+ end
+ end
+
+ describe "when feed does not have the subscriber id" do
+
+ before do
+ Feed.expects(:first).with(:id => @subscriber_id).returns(nil)
+
+ @feed_url = "http://some.url"
+ @feed_data = FeedData.new(@feed_url, nil)
+
+ ConvertsSubscriberToFeedData.expects(:get_feed_data)
+ .with(@subscriber_id)
+ .returns(@feed_data)
+ end
+
+ describe "when a feed exists with the remote url" do
+ it "should return the feed with the remote url " do
+ Feed.expects(:first).with(:remote_url => @feed_url).returns(@feed)
+
+ feed = FindsOrCreatesFeeds.find_or_create(@subscriber_id)
+
+ assert_equal @feed, feed
+ end
+ end
+
+ describe "when a feed does not exist with the remote url" do
+ it "should create a new feed from the data" do
+ Feed.expects(:first).with(:remote_url => @feed_url).returns(nil)
+ Feed.expects(:create_from_feed_data).with(@feed_data).returns(@feed)
+
+ feed = FindsOrCreatesFeeds.find_or_create(@subscriber_id)
+
+ assert_equal @feed, feed
+ end
+ end
+ end
+end
View
@@ -0,0 +1,52 @@
+require 'minitest/autorun'
+require 'mocha'
+
+require_relative '../../lib/finger'
+
+describe "when querying web finger" do
+
+ Xrd = Struct.new(:links)
+
+ class Link < Hash
+ def initialize(rel, href)
+ self['rel'] = rel
+ self['href'] = href
+ end
+
+ def to_s
+ self['href']
+ end
+
+ def href
+ self['href']
+ end
+ end
+
+ module Redfinger
+ end
+
+ before do
+ url_link = Link.new('http://schemas.google.com/g/2010#updates-from', 'http://feed.url')
+ public_key_link = Link.new('magic-public-key', 'ignored,key')
+ salmon_link = Link.new('salmon', 'http://salmon.url')
+ xrd = Xrd.new([ url_link, public_key_link, salmon_link ])
+
+ @email = "someone@somewhere.com"
+
+ Redfinger.expects(:finger).with(@email).returns(xrd)
+
+ @finger_data = QueriesWebFinger.query(@email)
+ end
+
+ it "should get the remote url" do
+ assert_equal "http://feed.url", @finger_data.url
+ end
+
+ it "should get public key " do
+ assert_equal "key", @finger_data.public_key
+ end
+
+ it "should get salmon url" do
+ assert_equal "http://salmon.url", @finger_data.salmon_url
+ end
+end

0 comments on commit efb83b9

Please sign in to comment.