tipjoy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+ require 'rake/rdoctask'
7
+
8
+
9
+ begin
10
+ require 'jeweler'
11
+ Jeweler::Tasks.new do |gemspec|
12
+ gemspec.name = "tipjoy"
13
+ gemspec.summary = "ruby implementation of tipjoy API"
14
+ gemspec.email = "contact@pivotallabs.com"
15
+ gemspec.homepage = "http://github.com/pivotal/tipjoy"
16
+ gemspec.description = "ruby implementation of tipjoy API"
17
+ gemspec.authors = ["Parker Thompson", "Kelly Felkins", "John Pelly"]
18
+ end
19
+ rescue LoadError
20
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
21
+ end
22
+
23
+ Rake.application.options.trace = true
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/init.rb ADDED
@@ -0,0 +1,13 @@
1
+ dir = File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ require "#{dir}/lib/tipjoy/tipjoy_requestor.rb"
7
+ Dir["#{dir}/lib/*.rb"].each do |file|
8
+ require file
9
+ end
10
+
11
+ Dir["#{dir}/lib/**/*.rb"].each do |file|
12
+ require file
13
+ end
@@ -0,0 +1,39 @@
1
+ module Tipjoy
2
+ class Account
3
+ include Tipjoy::Requestor
4
+
5
+ EXISTS_PATH = "/api/user/exists/"
6
+
7
+ attr_accessor :username
8
+ attr_accessor :user_id
9
+ attr_accessor :date_joined
10
+ attr_accessor :is_private
11
+ attr_accessor :verified
12
+ attr_accessor :twitter_username
13
+ attr_accessor :twitter_user_id
14
+ attr_accessor :profile_image_url
15
+
16
+ def initialize(options)
17
+ assign_attributes(options)
18
+ end
19
+
20
+ def self.fetch_account_by_twitter_username(twitter_username)
21
+
22
+ json = tipjoy_request(:get, TIPJOY_BASE_URL + EXISTS_PATH + "?twitter_username=" + twitter_username)
23
+
24
+ if json['exists']
25
+ Account.new(json)
26
+ else
27
+ nil
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def assign_attributes(options)
34
+ options.each_key do |k|
35
+ self.send("#{k}=", options[k]) if respond_to?(k)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Tipjoy
2
+ class InvalidPaymentError < Exception; end
3
+ end
@@ -0,0 +1,43 @@
1
+ module Tipjoy
2
+ class Payment
3
+ include Tipjoy::Requestor
4
+
5
+ NOTIFY_PATH = "/api/tweetpayment/notify/"
6
+
7
+ attr_accessor :to_account, :amount, :client, :errors, :message, :tweet_id, :transaction_id
8
+
9
+ def initialize(client, to_account, amount, message="")
10
+ self.to_account, self.amount, self.client, self.message = to_account, amount, client, message
11
+ end
12
+
13
+ def pay
14
+ raise Tipjoy::InvalidPaymentError.new(errors.join(", ")) unless valid?
15
+
16
+ tweet_payment
17
+ notify_tipjoy
18
+ end
19
+
20
+ def valid?
21
+ self.errors = []
22
+
23
+ self.errors << "amount required" unless amount
24
+ self.errors << "to_account required" unless to_account
25
+ self.errors << "no client" unless client
26
+ self.errors << "amount not > 0 " unless amount.to_f > 0
27
+
28
+ self.errors.empty?
29
+ end
30
+
31
+ private
32
+
33
+ def tweet_payment
34
+ response = self.client.update("p $#{amount} @#{to_account.twitter_username} #{message}")
35
+ self.tweet_id = response["id"]
36
+ end
37
+
38
+ def notify_tipjoy
39
+ json = tipjoy_request(:post,"http://tipjoy.com/api/tweetpayment/notify/", { "tweet_id" => self.tweet_id })
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ module Tipjoy
2
+ class RequestError < Exception; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Tipjoy
2
+ class ResultError < Exception; end
3
+ end
@@ -0,0 +1,41 @@
1
+ module Tipjoy
2
+ module Requestor
3
+ def self.included(klass)
4
+ klass.send :include, InstanceMethods
5
+ klass.send :extend, ClassMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def tipjoy_request(method, url, data={})
10
+ self.class.tipjoy_request(method, url, data)
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def tipjoy_http_request(method, url, data={})
16
+ if method == :post
17
+ Net::HTTP.post_form URI.parse(url), data
18
+ else
19
+ Net::HTTP.get_response(URI.parse(url))
20
+ end
21
+ end
22
+
23
+ def tipjoy_request(method, url, data={})
24
+ response = tipjoy_http_request(method, url, data)
25
+
26
+ if !(200..299).include?(response.code.to_i)
27
+ raise RequestError.new('ah!')
28
+ end
29
+
30
+
31
+ json = JSON.parse(response.body)
32
+
33
+ if json['result'] != 'success'
34
+ raise ::Tipjoy::ResultError.new(json.inspect)
35
+ end
36
+
37
+ json
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/tipjoy.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Tipjoy
2
+ TIPJOY_BASE_URL = "http://tipjoy.com"
3
+ end
@@ -0,0 +1,76 @@
1
+ module Test
2
+ module TwitterOAuth
3
+ class Client
4
+ def initialize(props = {})
5
+ @props = defaults.merge(props)
6
+ self
7
+ end
8
+
9
+ def info
10
+ @props[:info]
11
+ end
12
+
13
+ def [](key)
14
+ @props[key]
15
+ end
16
+
17
+ def []=(key, value)
18
+ @props[key] = value
19
+ end
20
+
21
+ def request_token
22
+ RequestToken.new(self[:request_token][:token], self[:request_token][:secret])
23
+ end
24
+
25
+ def access_token
26
+ AccessToken.new(self[:access_token][:token], self[:access_token][:secret])
27
+ end
28
+
29
+ def authorize(t,s)
30
+ access_token
31
+ end
32
+
33
+ def update(msg)
34
+ {"user"=>
35
+ {"name"=>"fake",
36
+ "id"=>1,
37
+ "screen_name"=>"fake"
38
+ },
39
+ "text"=>"test",
40
+ "id"=>1,
41
+ "created_at"=>"Wed May 27 21:30:34 +0000 2009"
42
+ }
43
+ end
44
+
45
+ def user(page=1)
46
+ return @props[:users_tweets]
47
+ end
48
+
49
+ private
50
+
51
+ def defaults
52
+ {
53
+ :info => {},
54
+ :request_token => {:token => 'token', :secret => 'secret'},
55
+ :access_token => {:token => 'token', :secret => 'secret'}
56
+ }
57
+ end
58
+ end
59
+
60
+ class AccessToken
61
+ attr_accessor :token, :secret
62
+ def initialize(t,s)
63
+ self.token, self.secret = t,s
64
+ self
65
+ end
66
+ end
67
+
68
+ class RequestToken
69
+ attr_accessor :token, :secret
70
+ def initialize(t,s)
71
+ self.token, self.secret = t,s
72
+ self
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Tipjoy::Account do
4
+
5
+ describe "integration" do
6
+
7
+ describe ".fetch_account_by_twitter_username" do
8
+ it "should return an account when requested" do
9
+ account = Tipjoy::Account.fetch_account_by_twitter_username(EXISTING_ACCOUNT_USERNAME)
10
+ account.should_not be_nil
11
+ account.twitter_username.should == EXISTING_ACCOUNT_USERNAME
12
+ end
13
+
14
+ it "should return nil if the account is not found" do
15
+ account = Tipjoy::Account.fetch_account_by_twitter_username(NON_EXISTANT_ACCOUNT_USERNAME)
16
+ account.should be_nil
17
+ end
18
+
19
+ # it "should ?? if the account is not specified at all" do
20
+ # account = Tipjoy::Account.fetch_account_by_twitter_username(Test::TwitterOAuth::Client.new, '')
21
+ # account.should be_nil
22
+ # end
23
+ end
24
+ end
25
+
26
+ describe "failure" do
27
+ describe ".fetch_account_by_twitter_username" do
28
+ before do
29
+ @requestor = Tipjoy::Account
30
+ @request = Proc.new do
31
+ Tipjoy::Account.fetch_account_by_twitter_username(EXISTING_ACCOUNT_USERNAME)
32
+ end
33
+ end
34
+
35
+ it_should_behave_like "tipjoy request maker that might fail"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,105 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Tipjoy::Payment do
4
+ before do
5
+ @to_account = Tipjoy::Account.new(:twitter_username => "poopr112")
6
+ # @from_account = Tipjoy::Account.new(:twitter_username => "poopr111")
7
+ @amount = 1.25
8
+ @client = Test::TwitterOAuth::Client.new
9
+ @message = "for api test"
10
+ @payment = Tipjoy::Payment.new(@client, @to_account, @amount, @message)
11
+ end
12
+
13
+ describe ".new" do
14
+ it "should require 2 accounts, client, and amount" do
15
+ lambda{
16
+ Tipjoy::Payment.new
17
+ }.should raise_error
18
+ end
19
+
20
+ it "should assign to_account" do
21
+ @payment.to_account.should == @to_account
22
+ end
23
+
24
+ it "should assign amount" do
25
+ @payment.amount.should == @amount
26
+ end
27
+
28
+ it "should assign twitter client" do
29
+ @payment.client.should == @client
30
+ end
31
+
32
+ end
33
+
34
+ describe "#valid?" do
35
+ it "should require amount" do
36
+ @payment.amount = nil
37
+ @payment.should_not be_valid
38
+ end
39
+
40
+ it "should require amount to be a number" do
41
+ @payment.amount = "foo"
42
+ @payment.should_not be_valid
43
+ end
44
+
45
+ it "should require amount to be a positive number" do
46
+ @payment.amount = "-1"
47
+ @payment.should_not be_valid
48
+ end
49
+
50
+ it "should require to_account" do
51
+ @payment.to_account = nil
52
+ @payment.should_not be_valid
53
+ end
54
+
55
+ it "should require client" do
56
+ @payment.client = nil
57
+ @payment.should_not be_valid
58
+ end
59
+ end
60
+
61
+ describe "#pay" do
62
+ before do
63
+ @payment_tweet = {"user"=>
64
+ {"name"=>"poopr",
65
+ "id"=>42670876,
66
+ "screen_name"=>"poopr111"
67
+ },
68
+ "text"=>"p $1.25 @poopr112 for api test",
69
+ "id"=>1939894288,
70
+ "created_at"=>"Wed May 27 21:30:34 +0000 2009"
71
+ }
72
+ end
73
+
74
+
75
+ it "should raise if payment is invalid" do
76
+ @payment.client = nil
77
+ @payment.should_not be_valid
78
+ lambda{@payment.pay}.should raise_error(Tipjoy::InvalidPaymentError)
79
+ end
80
+
81
+ it "should tweet payment" do
82
+ @client.should_receive(:update).with("p $1.25 @poopr112 for api test").and_return(@payment_tweet)
83
+ @payment.pay
84
+ end
85
+
86
+ it "should fetch tipjoy payment id" do
87
+ @payment.transaction_id.should be_nil
88
+ @client.should_receive(:update).with("p $1.25 @poopr112 for api test").and_return(@payment_tweet)
89
+ @payment.pay
90
+ @payment.transaction_id.should_not be_nil
91
+ end
92
+
93
+ describe "failure" do
94
+ before do
95
+ @requestor = @payment.class
96
+ @request = Proc.new do
97
+ @payment.pay
98
+ end
99
+ end
100
+
101
+ it_should_behave_like "tipjoy request maker that might fail"
102
+
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,33 @@
1
+ dir = File.expand_path(File.dirname(__FILE__))
2
+ require "rubygems"
3
+ require 'spec/autorun'
4
+ #require 'mash'
5
+ require dir + '/../init'
6
+ require dir + '/doubles/fake_oauth_client'
7
+
8
+ EXISTING_ACCOUNT_USERNAME = 'poopr111'
9
+ NON_EXISTANT_ACCOUNT_USERNAME = 'poopr112'
10
+
11
+ share_examples_for "tipjoy request maker that might fail" do
12
+ it "should raise ResultError when result is failure" do
13
+ response = mock('http')
14
+ response.should_receive(:body).and_return('{"result":"failure"}')
15
+ response.should_receive(:code).and_return("200")
16
+
17
+ @requestor.should_receive(:tipjoy_http_request).and_return(response)
18
+
19
+ lambda{
20
+ @request.call
21
+ }.should raise_error(Tipjoy::ResultError)
22
+ end
23
+
24
+ it "should raise RequestError when http response is non-200" do
25
+ response = mock('http')
26
+ response.should_receive(:code).and_return("500")
27
+
28
+ @requestor.should_receive(:tipjoy_http_request).and_return(response)
29
+ lambda{
30
+ @request.call
31
+ }.should raise_error(Tipjoy::RequestError)
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ dir = File.dirname(__FILE__)
2
+
3
+ Dir["#{dir}/**/*.rb"].each do |file|
4
+ require file
5
+ end
data/tipjoy.gemspec ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tipjoy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Parker Thompson
8
+ - Kelly Felkins
9
+ - John Pelly
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-05-28 00:00:00 -07:00
15
+ default_executable:
16
+ dependencies: []
17
+
18
+ description: ruby implementation of tipjoy API
19
+ email: contact@pivotallabs.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files:
25
+ - README
26
+ files:
27
+ - README
28
+ - Rakefile
29
+ - VERSION
30
+ - init.rb
31
+ - lib/tipjoy.rb
32
+ - lib/tipjoy/account.rb
33
+ - lib/tipjoy/invalid_payment_error.rb
34
+ - lib/tipjoy/payment.rb
35
+ - lib/tipjoy/request_error.rb
36
+ - lib/tipjoy/result_error.rb
37
+ - lib/tipjoy/tipjoy_requestor.rb
38
+ - spec/doubles/fake_oauth_client.rb
39
+ - spec/lib/tipjoy/account_spec.rb
40
+ - spec/lib/tipjoy/payment_spec.rb
41
+ - spec/spec_helper.rb
42
+ - spec/spec_suite.rb
43
+ - tipjoy.gemspec
44
+ has_rdoc: true
45
+ homepage: http://github.com/pivotal/tipjoy
46
+ licenses:
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.5
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: ruby implementation of tipjoy API
71
+ test_files:
72
+ - spec/doubles/fake_oauth_client.rb
73
+ - spec/lib/tipjoy/account_spec.rb
74
+ - spec/lib/tipjoy/payment_spec.rb
75
+ - spec/spec_helper.rb
76
+ - spec/spec_suite.rb
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tipjoy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Parker Thompson
8
+ - Kelly Felkins
9
+ - John Pelly
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-05-28 00:00:00 -07:00
15
+ default_executable:
16
+ dependencies: []
17
+
18
+ description: ruby implementation of tipjoy API
19
+ email: contact@pivotallabs.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files:
25
+ - README
26
+ files:
27
+ - README
28
+ - Rakefile
29
+ - VERSION
30
+ - init.rb
31
+ - lib/tipjoy.rb
32
+ - lib/tipjoy/account.rb
33
+ - lib/tipjoy/invalid_payment_error.rb
34
+ - lib/tipjoy/payment.rb
35
+ - lib/tipjoy/request_error.rb
36
+ - lib/tipjoy/result_error.rb
37
+ - lib/tipjoy/tipjoy_requestor.rb
38
+ - spec/doubles/fake_oauth_client.rb
39
+ - spec/lib/tipjoy/account_spec.rb
40
+ - spec/lib/tipjoy/payment_spec.rb
41
+ - spec/spec_helper.rb
42
+ - spec/spec_suite.rb
43
+ - tipjoy.gemspec
44
+ has_rdoc: true
45
+ homepage: http://github.com/pivotal/tipjoy
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --charset=UTF-8
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.3.5
69
+ signing_key:
70
+ specification_version: 2
71
+ summary: ruby implementation of tipjoy API
72
+ test_files:
73
+ - spec/doubles/fake_oauth_client.rb
74
+ - spec/lib/tipjoy/account_spec.rb
75
+ - spec/lib/tipjoy/payment_spec.rb
76
+ - spec/spec_helper.rb
77
+ - spec/spec_suite.rb