Add Chubbies, the oauth sample app, and a cucumber feature for part of an oauth flow
This commit is contained in:
parent
8841f62cf0
commit
381b85189d
24 changed files with 356 additions and 404 deletions
6
Gemfile
6
Gemfile
|
|
@ -19,6 +19,8 @@ gem 'devise_invitable', '0.5.0'
|
|||
gem 'omniauth', '0.2.6'
|
||||
gem 'twitter', '1.5.0'
|
||||
|
||||
gem 'oauth2-provider', '~> 0.0.0'
|
||||
|
||||
#Views
|
||||
gem 'haml', '3.0.25'
|
||||
gem 'will_paginate', '3.0.pre2'
|
||||
|
|
@ -91,4 +93,8 @@ group :test do
|
|||
gem 'mongrel', :require => false if RUBY_VERSION.include? '1.8'
|
||||
gem 'rspec-instafail', '>= 0.1.7', :require => false
|
||||
gem 'fuubar'
|
||||
|
||||
#For Chubbies
|
||||
gem 'sinatra', :require => false
|
||||
gem 'httparty', :require => false
|
||||
end
|
||||
|
|
|
|||
10
Gemfile.lock
10
Gemfile.lock
|
|
@ -153,7 +153,7 @@ GEM
|
|||
faraday (0.6.1)
|
||||
addressable (~> 2.2.4)
|
||||
multipart-post (~> 1.1.0)
|
||||
rack (>= 1.1.0, < 2)
|
||||
rack (< 2, >= 1.1.0)
|
||||
faraday_middleware (0.6.3)
|
||||
faraday (~> 0.6.0)
|
||||
fastercsv (1.5.4)
|
||||
|
|
@ -183,6 +183,8 @@ GEM
|
|||
hashie (1.0.0)
|
||||
highline (1.6.2)
|
||||
http_connection (1.4.1)
|
||||
httparty (0.7.4)
|
||||
crack (= 0.1.8)
|
||||
i18n (0.6.0)
|
||||
i18n-inflector (2.5.1)
|
||||
i18n (>= 0.4.1)
|
||||
|
|
@ -267,6 +269,9 @@ GEM
|
|||
oauth2 (0.4.1)
|
||||
faraday (~> 0.6.1)
|
||||
multi_json (>= 0.0.5)
|
||||
oauth2-provider (0.0.16)
|
||||
activesupport (~> 3.0.1)
|
||||
addressable (~> 2.2)
|
||||
ohai (0.5.8)
|
||||
extlib
|
||||
json (<= 1.4.6, >= 1.4.4)
|
||||
|
|
@ -421,6 +426,7 @@ DEPENDENCIES
|
|||
fuubar
|
||||
haml (= 3.0.25)
|
||||
http_accept_language!
|
||||
httparty
|
||||
i18n-inflector-rails (~> 1.0)
|
||||
jammit (= 0.5.4)
|
||||
jasmine (= 1.0.2.1)
|
||||
|
|
@ -431,6 +437,7 @@ DEPENDENCIES
|
|||
mysql2 (= 0.2.6)
|
||||
newrelic_rpm
|
||||
nokogiri
|
||||
oauth2-provider (~> 0.0.0)
|
||||
ohai (= 0.5.8)
|
||||
omniauth (= 0.2.6)
|
||||
rails (= 3.0.3)
|
||||
|
|
@ -445,6 +452,7 @@ DEPENDENCIES
|
|||
ruby-debug
|
||||
selenium-webdriver (= 0.1.3)
|
||||
settingslogic (= 2.0.6)
|
||||
sinatra
|
||||
sod!
|
||||
thin (= 1.2.11)
|
||||
twitter (= 1.5.0)
|
||||
|
|
|
|||
|
|
@ -1,115 +1,15 @@
|
|||
class ApisController < ApplicationController #We should start with this versioned, V0ApisController BEES
|
||||
before_filter :authenticate_user!, :only => [:home_timeline]
|
||||
class ApisController < ApplicationController
|
||||
authenticate_with_oauth
|
||||
before_filter :set_user_from_oauth
|
||||
respond_to :json
|
||||
|
||||
#posts
|
||||
def public_timeline
|
||||
set_defaults
|
||||
timeline = StatusMessage.where(:public => true).includes(:photos, :author => :profile).paginate(:page => params[:page], :per_page => params[:per_page], :order => "#{params[:order]} DESC")
|
||||
respond_with timeline do |format|
|
||||
format.json{ render :json => timeline.to_json(:format => :twitter) }
|
||||
end
|
||||
def me
|
||||
@person = @user.person
|
||||
render :json => {:birthday => @person.profile.birthday, :name => @person.name}
|
||||
end
|
||||
|
||||
def user_timeline
|
||||
set_defaults
|
||||
|
||||
if person = Person.where(:guid => params[:user_id]).first
|
||||
if user_signed_in?
|
||||
timeline = current_user.posts_from(person)
|
||||
else
|
||||
timeline = StatusMessage.where(:public => true, :author_id => person.id).includes(:photos).paginate(:page => params[:page], :per_page => params[:per_page], :order => "#{params[:order]} DESC")
|
||||
end
|
||||
respond_with timeline do |format|
|
||||
format.json{ render :json => timeline.to_json(:format => :twitter) }
|
||||
end
|
||||
else
|
||||
render :json => {:status => 'failed', :reason => 'user not found'}, :status => 404
|
||||
end
|
||||
end
|
||||
|
||||
def home_timeline
|
||||
set_defaults
|
||||
timeline = current_user.visible_posts(:max_time => params[:max_time],
|
||||
:limit => params[:per_page],
|
||||
:order => "#{params[:order]} DESC").includes(:comments, :photos, :likes, :dislikes)
|
||||
respond_with timeline do |format|
|
||||
format.json{ render :json => timeline.to_json(:format => :twitter) }
|
||||
end
|
||||
end
|
||||
|
||||
def statuses
|
||||
status = StatusMessage.where(:guid => params[:guid], :public => true).includes(:photos, :author => :profile).first
|
||||
if status
|
||||
respond_with status do |format|
|
||||
format.json{ render :json => status.to_json(:format => :twitter) }
|
||||
end
|
||||
else
|
||||
render(:nothing => true, :status => 404)
|
||||
end
|
||||
end
|
||||
|
||||
#people
|
||||
def users
|
||||
if params[:user_id]
|
||||
person = Person.where(:guid => params[:user_id]).first
|
||||
elsif params[:screen_name]
|
||||
person = Person.where(:diaspora_handle => params[:screen_name]).first
|
||||
end
|
||||
|
||||
if person && !person.remote?
|
||||
respond_with person do |format|
|
||||
format.json{ render :json => person.to_json(:format => :twitter) }
|
||||
end
|
||||
else
|
||||
render(:nothing => true, :status => 404)
|
||||
end
|
||||
end
|
||||
|
||||
def users_search
|
||||
set_defaults
|
||||
|
||||
if params[:q]
|
||||
people = Person.public_search(params[:q]).paginate(:page => params[:page], :per_page => params[:per_page], :order => "#{params[:order]} DESC")
|
||||
end
|
||||
|
||||
if people
|
||||
respond_with people do |format|
|
||||
format.json{ render :json => people.to_json(:format => :twitter) }
|
||||
end
|
||||
else
|
||||
render(:nothing => true, :status => 404)
|
||||
end
|
||||
end
|
||||
|
||||
def users_profile_image
|
||||
if person = Person.where(:diaspora_handle => params[:screen_name]).first
|
||||
redirect_to person.profile.image_url
|
||||
else
|
||||
render(:nothing => true, :status => 404)
|
||||
end
|
||||
end
|
||||
|
||||
#tags
|
||||
def tag_posts
|
||||
set_defaults
|
||||
posts = StatusMessage.where(:public => true, :pending => false)
|
||||
posts = posts.tagged_with(params[:tag])
|
||||
posts = posts.includes(:comments, :photos).paginate(:page => params[:page], :per_page => params[:per_page], :order => "#{params[:order]} DESC")
|
||||
render :json => posts.as_json(:format => :twitter)
|
||||
end
|
||||
|
||||
def tag_people
|
||||
set_defaults
|
||||
profiles = Profile.tagged_with(params[:tag]).where(:searchable => true).select('profiles.id, profiles.person_id')
|
||||
people = Person.where(:id => profiles.map{|p| p.person_id}).paginate(:page => params[:page], :per_page => params[:per_page], :order => "#{params[:order]} DESC")
|
||||
render :json => people.as_json(:format => :twitter)
|
||||
end
|
||||
|
||||
protected
|
||||
def set_defaults
|
||||
params[:per_page] = 20 if params[:per_page].nil? || params[:per_page] > 100
|
||||
params[:order] = 'created_at' unless ['created_at', 'updated_at'].include?(params[:order])
|
||||
params[:page] ||= 1
|
||||
private
|
||||
def set_user_from_oauth
|
||||
@user = request.env['oauth2'].resource_owner
|
||||
end
|
||||
end
|
||||
|
|
|
|||
18
app/controllers/authorizations_controller.rb
Normal file
18
app/controllers/authorizations_controller.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
class AuthorizationsController < ApplicationController
|
||||
include OAuth2::Provider::Rack::AuthorizationCodesSupport
|
||||
before_filter :authenticate_user!
|
||||
before_filter :block_invalid_authorization_code_requests
|
||||
|
||||
def new
|
||||
@client = oauth2_authorization_request.client
|
||||
end
|
||||
|
||||
def create
|
||||
if params[:commit] == "Yes"
|
||||
grant_authorization_code(current_user)
|
||||
else
|
||||
deny_authorization_code
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -192,29 +192,6 @@ class Person < ActiveRecord::Base
|
|||
!remote?
|
||||
end
|
||||
|
||||
def as_json(opts={})
|
||||
opts ||= {}
|
||||
if(opts[:format] == :twitter)
|
||||
{
|
||||
:id => self.guid,
|
||||
:screen_name => self.diaspora_handle,
|
||||
:name => self.name,
|
||||
:created_at => self.created_at,
|
||||
:profile_image_url => self.profile.image_url(:thumb_small),
|
||||
:profile => self.profile.as_json(opts)
|
||||
}
|
||||
else
|
||||
{:id => self.guid,
|
||||
:name => self.name,
|
||||
:avatar => self.profile.image_url(:thumb_small),
|
||||
:handle => self.diaspora_handle,
|
||||
:url => "/people/#{self.id}"}
|
||||
end
|
||||
end
|
||||
|
||||
def to_twitter(format=:json)
|
||||
end
|
||||
|
||||
def has_photos?
|
||||
self.posts.where(:type => "Photo").exists?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -98,17 +98,6 @@ class Photo < Post
|
|||
true
|
||||
end
|
||||
|
||||
def as_json(opts={})
|
||||
{
|
||||
:photo => {
|
||||
:id => self.id,
|
||||
:url => self.url,
|
||||
:thumb_small => self.url(:thumb_small),
|
||||
:text => self.text
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
scope :on_statuses, lambda { |post_guids|
|
||||
where(:status_message_guid => post_guids)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,15 +54,6 @@ class Post < ActiveRecord::Base
|
|||
new_post
|
||||
end
|
||||
|
||||
def as_json(opts={})
|
||||
{
|
||||
:post => {
|
||||
:id => self.guid,
|
||||
:author => self.author.as_json,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def mutable?
|
||||
false
|
||||
end
|
||||
|
|
|
|||
|
|
@ -108,26 +108,6 @@ class StatusMessage < Post
|
|||
XML
|
||||
end
|
||||
|
||||
def as_json(opts={})
|
||||
opts ||= {}
|
||||
if(opts[:format] == :twitter)
|
||||
{
|
||||
:id => self.guid,
|
||||
:text => self.formatted_message(:plain_text => true),
|
||||
:entities => {
|
||||
:urls => [],
|
||||
:hashtags => self.tag_list,
|
||||
:user_mentions => self.mentioned_people.map{|p| p.diaspora_handle},
|
||||
},
|
||||
:source => 'diaspora',
|
||||
:created_at => self.created_at,
|
||||
:user => self.author.as_json(opts)
|
||||
}
|
||||
else
|
||||
super(opts)
|
||||
end
|
||||
end
|
||||
|
||||
def socket_to_user(user_or_id, opts={})
|
||||
unless opts[:aspect_ids]
|
||||
user_id = user_or_id.instance_of?(Fixnum) ? user_or_id : user_or_id.id
|
||||
|
|
|
|||
7
app/views/authorizations/new.html.haml
Normal file
7
app/views/authorizations/new.html.haml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
= form_for :authorization,
|
||||
:url => oauth_authorize_path(params.slice(:redirect_uri, :client_id, :client_secret)) do |form|
|
||||
%h2
|
||||
= "Authorize #{@client.name}?"
|
||||
|
||||
= form.submit "Fuck Yeah!", :value => "Yes"
|
||||
= form.submit "Hell No.", :value => "No"
|
||||
|
|
@ -34,7 +34,7 @@ Diaspora::Application.routes.draw do
|
|||
|
||||
resources :tags, :only => [:index]
|
||||
get 'tags/:name' => 'tags#show', :as => 'tag'
|
||||
|
||||
|
||||
resources :apps, :only => [:show]
|
||||
# Users and people
|
||||
|
||||
|
|
@ -68,6 +68,9 @@ Diaspora::Application.routes.draw do
|
|||
resources :photos, :controller => "photos", :only => [:create, :show, :destroy]
|
||||
end
|
||||
|
||||
get "/oauth/authorize" => "authorizations#new"
|
||||
post "/oauth/authorize" => "authorizations#create"
|
||||
|
||||
#Temporary token_authenticable route
|
||||
resource :token, :only => [:show, :create]
|
||||
|
||||
|
|
@ -125,17 +128,7 @@ Diaspora::Application.routes.draw do
|
|||
end
|
||||
|
||||
scope 'api/v0', :controller => :apis do
|
||||
match 'statuses/public_timeline' => :public_timeline
|
||||
match 'statuses/home_timeline' => :home_timeline
|
||||
match 'statuses/show/:guid' => :statuses
|
||||
match 'statuses/user_timeline' => :user_timeline
|
||||
|
||||
match 'users/show' => :users
|
||||
match 'users/search' => :users_search
|
||||
match 'users/profile_image' => :users_profile_image
|
||||
|
||||
match 'tags_posts/:tag' => :tag_posts
|
||||
match 'tags_people/:tag' => :tag_people
|
||||
get 'me' => :me
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
42
db/migrate/20110526184644_add_oauth2_tables.rb
Normal file
42
db/migrate/20110526184644_add_oauth2_tables.rb
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
class AddOauth2Tables < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table 'oauth_clients', :force => true do |t|
|
||||
t.string 'name'
|
||||
t.string 'oauth_identifier', :limit => 32, :null => false
|
||||
t.string 'oauth_secret', :limit => 32, :null => false
|
||||
end
|
||||
|
||||
create_table 'oauth_authorization_codes', :force => true do |t|
|
||||
t.integer 'authorization_id', :null => false
|
||||
t.string 'code', :limit => 32, :null => false
|
||||
t.datetime 'expires_at'
|
||||
t.datetime 'created_at'
|
||||
t.datetime 'updated_at'
|
||||
t.string 'redirect_uri'
|
||||
end
|
||||
|
||||
create_table 'oauth_authorizations', :force => true do |t|
|
||||
t.integer 'client_id', :null => false
|
||||
t.integer 'resource_owner_id'
|
||||
t.string 'resource_owner_type', :limit => 32
|
||||
t.string 'scope'
|
||||
t.datetime 'expires_at'
|
||||
end
|
||||
|
||||
create_table 'oauth_access_tokens', :force => true do |t|
|
||||
t.integer 'authorization_id', :null => false
|
||||
t.string 'access_token', :limit => 32, :null => false
|
||||
t.string 'refresh_token', :limit => 32
|
||||
t.datetime 'expires_at'
|
||||
t.datetime 'created_at'
|
||||
t.datetime 'updated_at'
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table 'oauth_access_tokens'
|
||||
drop_table 'oauth_authorizations'
|
||||
drop_table 'oauth_authorization_codes'
|
||||
drop_table 'oauth_clients'
|
||||
end
|
||||
end
|
||||
32
db/schema.rb
32
db/schema.rb
|
|
@ -195,6 +195,38 @@ ActiveRecord::Schema.define(:version => 20110603212633) do
|
|||
add_index "notifications", ["target_id"], :name => "index_notifications_on_target_id"
|
||||
add_index "notifications", ["target_type", "target_id"], :name => "index_notifications_on_target_type_and_target_id"
|
||||
|
||||
create_table "oauth_access_tokens", :force => true do |t|
|
||||
t.integer "authorization_id", :null => false
|
||||
t.string "access_token", :limit => 32, :null => false
|
||||
t.string "refresh_token", :limit => 32
|
||||
t.datetime "expires_at"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "oauth_authorization_codes", :force => true do |t|
|
||||
t.integer "authorization_id", :null => false
|
||||
t.string "code", :limit => 32, :null => false
|
||||
t.datetime "expires_at"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "redirect_uri"
|
||||
end
|
||||
|
||||
create_table "oauth_authorizations", :force => true do |t|
|
||||
t.integer "client_id", :null => false
|
||||
t.integer "resource_owner_id"
|
||||
t.string "resource_owner_type", :limit => 32
|
||||
t.string "scope"
|
||||
t.datetime "expires_at"
|
||||
end
|
||||
|
||||
create_table "oauth_clients", :force => true do |t|
|
||||
t.string "name"
|
||||
t.string "oauth_identifier", :limit => 32, :null => false
|
||||
t.string "oauth_secret", :limit => 32, :null => false
|
||||
end
|
||||
|
||||
create_table "people", :force => true do |t|
|
||||
t.string "guid", :null => false
|
||||
t.text "url", :null => false
|
||||
|
|
|
|||
29
features/oauth.feature
Normal file
29
features/oauth.feature
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
@javascript
|
||||
Feature: oauth
|
||||
Exchanging oauth credentials
|
||||
|
||||
Background:
|
||||
Given Chubbies is running
|
||||
And a user with username "bob" and password "secret"
|
||||
|
||||
Scenario: Authorize Chubbies
|
||||
Given Chubbies is registered on my pod
|
||||
When I visit "/" on Chubbies
|
||||
And I try to authorize Chubbies
|
||||
Then I should see "Authorize Chubbies?"
|
||||
|
||||
When I press "Yes"
|
||||
Then I should be on "/account" on Chubbies
|
||||
And I should see my "profile.birthday"
|
||||
And I should see my "name"
|
||||
|
||||
Scenario: Not authorize Chubbies
|
||||
Given Chubbies is registered on my pod
|
||||
When I visit "/" on Chubbies
|
||||
And I try to authorize Chubbies
|
||||
Then I should see "Authorize Chubbies?"
|
||||
|
||||
When I press "No"
|
||||
Then I should be on "/callback" on Chubbies
|
||||
Then I should see "What is your major malfunction?"
|
||||
|
||||
70
features/step_definitions/oauth_steps.rb
Normal file
70
features/step_definitions/oauth_steps.rb
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
Given /^Chubbies is running$/ do
|
||||
if Chubbies.running?
|
||||
puts "Chubbies is already running. Killing it."
|
||||
Chubbies.kill
|
||||
end
|
||||
Chubbies.run
|
||||
at_exit do
|
||||
Chubbies.kill
|
||||
end
|
||||
end
|
||||
|
||||
Given /^Chubbies is registered on my pod$/ do
|
||||
OAuth2::Provider.client_class.create! :name => 'Chubbies',
|
||||
:oauth_identifier => 'abcdefgh12345678',
|
||||
:oauth_secret => 'secret'
|
||||
end
|
||||
|
||||
And /^I should see my "([^"]+)"/ do |code|
|
||||
page.should have_content(@me.person.instance_eval(code).to_s)
|
||||
end
|
||||
|
||||
When /^I try to authorize Chubbies$/ do
|
||||
And 'I follow "Log in with Diaspora"'
|
||||
Then 'I should be on the new user session page'
|
||||
And "I fill in \"Username\" with \"#{@me.username}\""
|
||||
And "I fill in \"Password\" with \"#{@me.password}\""
|
||||
And 'I press "Sign in"'
|
||||
Then 'I should be on the oauth authorize page'
|
||||
end
|
||||
|
||||
When /^I visit "([^"]+)" on Chubbies$/ do |path|
|
||||
former_host = Capybara.app_host
|
||||
Capybara.app_host = "localhost:#{Chubbies::PORT}"
|
||||
visit(path)
|
||||
Capybara.app_host = former_host
|
||||
end
|
||||
|
||||
class Chubbies
|
||||
PORT = 9292
|
||||
|
||||
def self.run
|
||||
@pid = fork do
|
||||
Process.exec "cd #{Rails.root}/spec/support/chubbies/ && DIASPORA_PORT=9887 bundle exec rackup -p #{PORT} 2> /dev/null"
|
||||
end
|
||||
while(!running?) do
|
||||
sleep(1)
|
||||
end
|
||||
end
|
||||
|
||||
def self.kill
|
||||
`kill -9 #{get_pid}`
|
||||
end
|
||||
|
||||
def self.running?
|
||||
begin
|
||||
RestClient.get("localhost:#{PORT}")
|
||||
true
|
||||
rescue Errno::ECONNREFUSED
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_pid
|
||||
@pid ||= lambda {
|
||||
processes = `ps -ax -o pid,command | grep "rackup -p #{PORT}"`.split("\n")
|
||||
processes = processes.select{|p| !p.include?("grep") }
|
||||
processes.first.split(" ").first
|
||||
}.call
|
||||
end
|
||||
end
|
||||
|
|
@ -3,6 +3,7 @@ Given /^a user with username "([^\"]*)" and password "([^\"]*)"$/ do |username,
|
|||
:password_confirmation => password, :getting_started => false)
|
||||
@me.aspects.create(:name => "Besties")
|
||||
@me.aspects.create(:name => "Unicorns")
|
||||
@me.reload
|
||||
end
|
||||
|
||||
Given /^that I am a rock star$/ do
|
||||
|
|
|
|||
|
|
@ -5,223 +5,4 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ApisController do
|
||||
before do
|
||||
@status_message1 = Factory(:status_message, :text => '#bobby #flay #sux', :public => true, :updated_at => Time.now + 20)
|
||||
|
||||
@status_message2 = Factory(:status_message, :text => '#aobby', :public => true, :created_at => Time.now + 10)
|
||||
@status_message3 = Factory(:status_message, :created_at => Time.now + 15)
|
||||
@person = Factory(:person, :profile => Factory.build(:profile,:first_name => 'bobby', :searchable => true, :tag_string => '#zord'))
|
||||
@person.profile.save
|
||||
end
|
||||
|
||||
describe '#public_timeline' do
|
||||
it 'returns all of the public posts' do
|
||||
get :public_timeline, :format => :json
|
||||
@posts = JSON.parse(response.body)
|
||||
@posts.map{|p| p['id']}.should == [@status_message2.guid, @status_message1.guid]
|
||||
@posts.count.should == 2
|
||||
end
|
||||
|
||||
it 'accepts an order paramater' do
|
||||
get :public_timeline, :format => :json, :order => 'updated_at'
|
||||
@posts = JSON.parse(response.body)
|
||||
@posts.map{|p| p['id']}.should == [@status_message1.guid, @status_message2.guid]
|
||||
end
|
||||
|
||||
it 'does not allow arbitrary orders' do
|
||||
get :public_timeline, :format => :json, :order => 'text'
|
||||
@posts = JSON.parse(response.body)
|
||||
@posts.map{|p| p['id']}.should == [@status_message2.guid, @status_message1.guid]
|
||||
end
|
||||
|
||||
it 'accepts a page paramater' do
|
||||
get :public_timeline, :format => :json, :per_page=> 1, :page => 2
|
||||
JSON.parse(response.body).first['id'].should == @status_message1.guid
|
||||
end
|
||||
|
||||
it 'accepts a per_page param' do
|
||||
get :public_timeline, :format => :json, :per_page=> 1
|
||||
JSON.parse(response.body).count.should == 1
|
||||
end
|
||||
end
|
||||
|
||||
context 'protected timelines' do
|
||||
let(:authenticate){
|
||||
sign_in(:user, @user);
|
||||
@controller.stub(:current_user).and_return(@user)
|
||||
}
|
||||
|
||||
before do
|
||||
@message1 = alice.post(:status_message, :text=> "hello", :to => alice.aspects.first)
|
||||
@message2 = eve.post(:status_message, :text=> "hello", :to => eve.aspects.first)
|
||||
end
|
||||
|
||||
describe '#home_timeline' do
|
||||
it 'authenticates' do
|
||||
get :home_timeline, :format => :json
|
||||
response.code.should == '401'
|
||||
end
|
||||
|
||||
it 'shows posts for alice' do
|
||||
@user = alice
|
||||
authenticate
|
||||
|
||||
get :home_timeline, :format => :json
|
||||
p = JSON.parse(response.body)
|
||||
|
||||
p.length.should == 1
|
||||
p[0]['id'].should == @message1.guid
|
||||
end
|
||||
|
||||
it 'shows posts for eve' do
|
||||
@user = eve
|
||||
authenticate
|
||||
|
||||
get :home_timeline, :format => :json
|
||||
p = JSON.parse(response.body)
|
||||
|
||||
p.length.should == 1
|
||||
p[0]['id'].should == @message2.guid
|
||||
end
|
||||
|
||||
it 'shows posts for bob' do
|
||||
@user = bob
|
||||
authenticate
|
||||
|
||||
get :home_timeline, :format => :json
|
||||
p = JSON.parse(response.body)
|
||||
|
||||
p.length.should == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe '#user_timeline' do
|
||||
context 'unauthenticated' do
|
||||
it 'shows public posts' do
|
||||
get :user_timeline, :format => :json, :user_id => @status_message1.author.guid
|
||||
posts = JSON.parse(response.body)
|
||||
posts.first['id'].should == @status_message1.guid
|
||||
posts.length.should == 1
|
||||
end
|
||||
it 'does not show non-public posts' do
|
||||
get :user_timeline, :format => :json, :user_id => alice.person.guid
|
||||
posts = JSON.parse(response.body)
|
||||
posts.should be_empty
|
||||
end
|
||||
end
|
||||
context 'authenticated' do
|
||||
context 'with bob logged in' do
|
||||
before do
|
||||
@user = bob
|
||||
authenticate
|
||||
end
|
||||
|
||||
it 'shows alice' do
|
||||
get :user_timeline, :format => :json, :user_id => alice.person.guid
|
||||
p = JSON.parse(response.body)
|
||||
|
||||
p.length.should == 1
|
||||
p[0]['id'].should == @message1.guid
|
||||
end
|
||||
|
||||
it 'shows eve' do
|
||||
get :user_timeline, :format => :json, :user_id => eve.person.guid
|
||||
p = JSON.parse(response.body)
|
||||
|
||||
p.length.should == 1
|
||||
p[0]['id'].should == @message2.guid
|
||||
end
|
||||
|
||||
it 'shows bob' do
|
||||
get :user_timeline, :format => :json, :user_id => bob.person.guid
|
||||
p = JSON.parse(response.body)
|
||||
p.length.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
context 'with alice logged in' do
|
||||
before do
|
||||
@user = alice
|
||||
authenticate
|
||||
end
|
||||
|
||||
it 'shows alice' do
|
||||
get :user_timeline, :format => :json, :user_id => alice.person.guid
|
||||
p = JSON.parse(response.body)
|
||||
|
||||
p.length.should == 1
|
||||
p[0]['id'].should == @message1.guid
|
||||
end
|
||||
|
||||
it 'shows eve' do
|
||||
get :user_timeline, :format => :json, :user_id => eve.person.guid
|
||||
p = JSON.parse(response.body)
|
||||
p.length.should == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#users_profile_image' do
|
||||
it 'redirects on success' do
|
||||
get :users_profile_image, :screen_name => bob.diaspora_handle, :format => :json
|
||||
response.should redirect_to(bob.person.profile.image_url)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#statuses' do
|
||||
it 'returns a post' do
|
||||
get :statuses, :guid => @status_message1.guid, :format => :json
|
||||
p = JSON.parse(response.body)
|
||||
p['id'].should == @status_message1.guid
|
||||
p['text'].should == @status_message1.formatted_message(:plain_text => true)
|
||||
p['entities'].class.should == Hash
|
||||
p['source'].should == 'diaspora'
|
||||
p['user'].should == JSON.parse(@status_message1.author.to_json(:format => :twitter))
|
||||
p['created_at'].should_not be_nil
|
||||
end
|
||||
|
||||
it 'returns a 404 if does not exsist' do
|
||||
get :statuses, :guid => '999'
|
||||
response.code.should == '404'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#users' do
|
||||
it 'succeeds' do
|
||||
get :users, :user_id => alice.person.guid, :format => :json
|
||||
p = JSON.parse(response.body)
|
||||
p['id'].should == alice.person.guid
|
||||
p['name'].should == alice.person.name
|
||||
p['screen_name'].should == alice.person.diaspora_handle
|
||||
p['profile_image_url'].should == alice.person.profile.image_url(:thumb_small)
|
||||
p['created_at'].should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#users_search' do
|
||||
it 'searches' do
|
||||
get :users_search, :q => @person.name, :format => :json
|
||||
p = JSON.parse(response.body)
|
||||
response.code.should == '200'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#tag_posts' do
|
||||
it 'succeeds' do
|
||||
get :tag_posts, :tag => 'flay'
|
||||
p = JSON.parse(response.body).first
|
||||
p['id'].should == @status_message1.guid
|
||||
p['user']['id'].should == @status_message1.author.guid
|
||||
end
|
||||
end
|
||||
|
||||
describe '#tag_people' do
|
||||
it 'succeeds' do
|
||||
get :tag_people, :tag => 'zord'
|
||||
p = JSON.parse(response.body).first
|
||||
p['id'].should == @person.guid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ end
|
|||
Factory.define :profile do |p|
|
||||
p.sequence(:first_name) { |n| "Robert#{n}#{r_str}" }
|
||||
p.sequence(:last_name) { |n| "Grimm#{n}#{r_str}" }
|
||||
p.birthday Date.today
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
6
spec/support/chubbies/Gemfile
Normal file
6
spec/support/chubbies/Gemfile
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
source :rubygems
|
||||
|
||||
gem 'sinatra'
|
||||
gem 'haml'
|
||||
|
||||
gem 'httparty'
|
||||
20
spec/support/chubbies/Gemfile.lock
Normal file
20
spec/support/chubbies/Gemfile.lock
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
crack (0.1.8)
|
||||
haml (3.0.18)
|
||||
httparty (0.7.4)
|
||||
crack (= 0.1.8)
|
||||
rack (1.2.2)
|
||||
sinatra (1.2.6)
|
||||
rack (~> 1.1)
|
||||
tilt (>= 1.2.2, < 2.0)
|
||||
tilt (1.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
haml
|
||||
httparty
|
||||
sinatra
|
||||
8
spec/support/chubbies/README
Normal file
8
spec/support/chubbies/README
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
This is a (very very) simple OAuth2 client, designed to work with the Diaspora tests. To get it running, cd to the client folder, then run:
|
||||
|
||||
1) bundle install
|
||||
2) bundle exec rackup
|
||||
|
||||
This should start the client on port 9292
|
||||
|
||||
Assuming an example server is running (such as the one in examples/rails3-example), visit http://localhost:9292. To read content from the server you'll be asked to login (tomafro/secret) and then authorize the client. Finally some very simple content from the server will be shown.
|
||||
75
spec/support/chubbies/app.rb
Normal file
75
spec/support/chubbies/app.rb
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
require 'sinatra'
|
||||
require 'haml'
|
||||
require 'httparty'
|
||||
|
||||
def resource_host
|
||||
url = "http://localhost:"
|
||||
if ENV["DIASPORA_PORT"]
|
||||
url << ENV["DIASPORA_PORT"]
|
||||
else
|
||||
url << "3000"
|
||||
end
|
||||
url
|
||||
end
|
||||
|
||||
CLIENT_ID = 'abcdefgh12345678'
|
||||
CLIENT_SECRET = 'secret'
|
||||
RESOURCE_HOST = resource_host
|
||||
|
||||
enable :sessions
|
||||
|
||||
helpers do
|
||||
def redirect_uri
|
||||
"http://" + request.host_with_port + "/callback"
|
||||
end
|
||||
|
||||
def access_token
|
||||
session[:access_token]
|
||||
end
|
||||
|
||||
def get_with_access_token(path)
|
||||
HTTParty.get(RESOURCE_HOST + path, :query => {:oauth_token => access_token})
|
||||
end
|
||||
|
||||
def authorize_url
|
||||
RESOURCE_HOST + "/oauth/authorize?client_id=#{CLIENT_ID}&client_secret=#{CLIENT_SECRET}&redirect_uri=#{redirect_uri}"
|
||||
end
|
||||
|
||||
def access_token_url
|
||||
RESOURCE_HOST + "/oauth/access_token"
|
||||
end
|
||||
end
|
||||
|
||||
get '/' do
|
||||
haml :home
|
||||
end
|
||||
|
||||
get '/callback' do
|
||||
unless params["error"]
|
||||
response = HTTParty.post(access_token_url, :body => {
|
||||
:client_id => CLIENT_ID,
|
||||
:client_secret => CLIENT_SECRET,
|
||||
:redirect_uri => redirect_uri,
|
||||
:code => params["code"],
|
||||
:grant_type => 'authorization_code'}
|
||||
)
|
||||
|
||||
session[:access_token] = response["access_token"]
|
||||
redirect '/account'
|
||||
else
|
||||
"What is your major malfunction?"
|
||||
end
|
||||
end
|
||||
|
||||
get '/account' do
|
||||
if access_token
|
||||
@resource_server = RESOURCE_HOST
|
||||
@url = "/api/v0/me.json"
|
||||
@resource_response = get_with_access_token(@url)
|
||||
haml :response
|
||||
else
|
||||
redirect authorize_url
|
||||
end
|
||||
end
|
||||
3
spec/support/chubbies/config.ru
Normal file
3
spec/support/chubbies/config.ru
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
require 'app'
|
||||
|
||||
run Sinatra::Application
|
||||
2
spec/support/chubbies/views/home.haml
Normal file
2
spec/support/chubbies/views/home.haml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
%a{:href => '/account'}
|
||||
Log in with Diaspora
|
||||
13
spec/support/chubbies/views/response.haml
Normal file
13
spec/support/chubbies/views/response.haml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
%div
|
||||
The response from #{@resource_server} at path #{@url}:
|
||||
|
||||
%h2
|
||||
Headers
|
||||
%pre
|
||||
=@resource_response.headers.inspect
|
||||
|
||||
%h2
|
||||
Body
|
||||
%pre
|
||||
=@resource_response.body.inspect
|
||||
|
||||
Loading…
Reference in a new issue