tipjoy 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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