gmoney 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/gmoney.gemspec +2 -2
- data/lib/extensions/fixnum.rb +2 -0
- data/lib/extensions/nil_class.rb +2 -0
- data/lib/extensions/string.rb +25 -6
- data/lib/gmoney.rb +3 -5
- data/lib/gmoney/authentication_request.rb +9 -0
- data/lib/gmoney/feed_parser.rb +5 -0
- data/lib/gmoney/gf_request.rb +5 -0
- data/lib/gmoney/gf_response.rb +4 -0
- data/lib/gmoney/gf_service.rb +4 -0
- data/lib/gmoney/gf_session.rb +11 -0
- data/lib/gmoney/portfolio.rb +22 -5
- data/lib/gmoney/portfolio_feed_parser.rb +4 -0
- data/lib/gmoney/position.rb +15 -1
- data/lib/gmoney/position_feed_parser.rb +4 -0
- data/lib/gmoney/transaction.rb +38 -12
- data/lib/gmoney/transaction_feed_parser.rb +4 -0
- data/spec/portfolio_spec.rb +7 -13
- data/spec/position_spec.rb +1 -3
- data/spec/request_spec.rb +1 -1
- data/spec/service_spec.rb +2 -1
- data/spec/session_spec.rb +19 -0
- data/spec/transaction_spec.rb +14 -8
- metadata +2 -2
data/gmoney.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{gmoney}
|
5
|
-
s.version = "0.4.
|
5
|
+
s.version = "0.4.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Justin Spradlin"]
|
9
|
-
s.date = %q{2010-
|
9
|
+
s.date = %q{2010-04-13}
|
10
10
|
s.description = %q{A gem for interacting with the Google Finance API}
|
11
11
|
s.email = %q{jspradlin@gmail.com}
|
12
12
|
s.extra_rdoc_files = ["README.rdoc", "lib/extensions/fixnum.rb", "lib/extensions/nil_class.rb", "lib/extensions/string.rb", "lib/gmoney.rb", "lib/gmoney/authentication_request.rb", "lib/gmoney/feed_parser.rb", "lib/gmoney/gf_request.rb", "lib/gmoney/gf_response.rb", "lib/gmoney/gf_service.rb", "lib/gmoney/gf_session.rb", "lib/gmoney/portfolio.rb", "lib/gmoney/portfolio_feed_parser.rb", "lib/gmoney/position.rb", "lib/gmoney/position_feed_parser.rb", "lib/gmoney/transaction.rb", "lib/gmoney/transaction_feed_parser.rb"]
|
data/lib/extensions/fixnum.rb
CHANGED
data/lib/extensions/nil_class.rb
CHANGED
data/lib/extensions/string.rb
CHANGED
@@ -1,7 +1,20 @@
|
|
1
|
+
# = String
|
2
|
+
# GMoney String Extensions
|
1
3
|
class String
|
4
|
+
# = ParseError
|
5
|
+
# Incorrect id/url parsing
|
2
6
|
class ParseError < StandardError; end
|
7
|
+
|
8
|
+
# = PortfolioParseError
|
9
|
+
# Incorrect portfolio id/url parsing
|
3
10
|
class PortfolioParseError < ParseError; end
|
11
|
+
|
12
|
+
# = PositionParseError
|
13
|
+
# Incorrect position id/url parsing
|
4
14
|
class PositionParseError < ParseError; end
|
15
|
+
|
16
|
+
# = TransactionParseError
|
17
|
+
# Incorrect transaction id/url parsing
|
5
18
|
class TransactionParseError < ParseError; end
|
6
19
|
|
7
20
|
@@portfolio_re = /\d+/
|
@@ -11,7 +24,6 @@ class String
|
|
11
24
|
@@transaction_re = /\d+\/[a-zA-Z]+:[a-zA-Z]+\/\d+/
|
12
25
|
@@transaction_re_in = /^\d+\/[a-zA-Z]+:[a-zA-Z]+\/\d+$/
|
13
26
|
|
14
|
-
|
15
27
|
def camel_to_us
|
16
28
|
add_us = gsub(/(.)([A-Z][a-z]+)/, '\1_\2')
|
17
29
|
add_us.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase
|
@@ -26,17 +38,17 @@ class String
|
|
26
38
|
end
|
27
39
|
|
28
40
|
def position_feed_id
|
29
|
-
portfolio =
|
41
|
+
portfolio = finance_feed_id_helper('portfolios', 11)
|
30
42
|
position = self[rindex('/')+1..-1]
|
31
43
|
"#{portfolio}/#{position}"
|
32
44
|
end
|
33
45
|
|
34
46
|
def transaction_feed_id
|
35
|
-
portfolio =
|
36
|
-
position =
|
47
|
+
portfolio = finance_feed_id_helper('portfolios', 11)
|
48
|
+
position = finance_feed_id_helper('positions', 10)
|
37
49
|
transaction = self[rindex('/')+1..-1]
|
38
50
|
"#{portfolio}/#{position}/#{transaction}"
|
39
|
-
end
|
51
|
+
end
|
40
52
|
|
41
53
|
def portfolio_id
|
42
54
|
if self[@@transaction_re_in] || self[@@position_re_in] || self[@@portfolio_re_in]
|
@@ -70,5 +82,12 @@ class String
|
|
70
82
|
|
71
83
|
def blank?
|
72
84
|
respond_to?(:empty?) ? self.strip.empty? : !self
|
73
|
-
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def finance_feed_id_helper(finance_object, offset)
|
90
|
+
f_objs = finance_object == 'portfolios' ? ['portfolios/', '/positions'] : ['positions/', '/transactions']
|
91
|
+
self[self.rindex(f_objs[0])+offset..index(f_objs[1])-1]
|
92
|
+
end
|
74
93
|
end
|
data/lib/gmoney.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Justin Spradlin
|
2
|
-
# www.
|
2
|
+
# www.justinspradlin.com
|
3
3
|
# (C) 2010
|
4
4
|
|
5
|
-
|
6
5
|
$:.unshift File.expand_path(File.dirname(__FILE__))
|
7
6
|
|
8
7
|
require 'date'
|
@@ -28,7 +27,7 @@ require 'gmoney/transaction'
|
|
28
27
|
require 'gmoney/transaction_feed_parser'
|
29
28
|
|
30
29
|
module GMoney
|
31
|
-
VERSION = '0.4.
|
30
|
+
VERSION = '0.4.4'
|
32
31
|
GF_URL = "http://finance.google.com/finance"
|
33
32
|
GF_FEED_URL = "#{GF_URL}/feeds/default"
|
34
33
|
GF_PORTFOLIO_FEED_URL = "#{GF_FEED_URL}/portfolios"
|
@@ -40,8 +39,7 @@ module GMoney
|
|
40
39
|
BUY = 'Buy'
|
41
40
|
SELL = 'Sell'
|
42
41
|
SELL_SHORT = 'Sell Short'
|
43
|
-
BUY_TO_COVER = 'Buy to Cover'
|
44
|
-
|
42
|
+
BUY_TO_COVER = 'Buy to Cover'
|
45
43
|
|
46
44
|
def self.version
|
47
45
|
VERSION
|
@@ -1,5 +1,14 @@
|
|
1
1
|
module GMoney
|
2
|
+
# = AuthenticationRequest
|
3
|
+
#
|
4
|
+
# Authenticates the user's account with Google
|
5
|
+
#
|
2
6
|
class AuthenticationRequest
|
7
|
+
|
8
|
+
# = AuthError
|
9
|
+
#
|
10
|
+
# Thrown when there is a network or Authentication error.
|
11
|
+
#
|
3
12
|
class AuthError < StandardError;end
|
4
13
|
|
5
14
|
AUTH_URL = 'https://www.google.com/accounts/ClientLogin'
|
data/lib/gmoney/feed_parser.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
module GMoney
|
2
|
+
# = FeedParser
|
3
|
+
#
|
4
|
+
# Parses Atom feeds that are returned from the Google Finance API
|
5
|
+
# and converts its data into Ruby objects.
|
6
|
+
#
|
2
7
|
class FeedParser
|
3
8
|
def self.parse_feed(feed, feed_class, options = {:feed_link => true, :symbol => false})
|
4
9
|
doc = REXML::Document.new(feed)
|
data/lib/gmoney/gf_request.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
module GMoney
|
2
|
+
# = GFRequest
|
3
|
+
#
|
4
|
+
# Wraps Requests that are sent to Google via GMoney
|
5
|
+
#
|
2
6
|
class GFRequest
|
3
7
|
attr_accessor :url, :body, :method, :headers
|
4
8
|
|
@@ -11,6 +15,7 @@ module GMoney
|
|
11
15
|
@method ||= :get
|
12
16
|
@headers ||= {}
|
13
17
|
@headers['GData-Version'] = GF_GOOGLE_DATA_VERSION
|
18
|
+
@headers['Authorization'] = "GoogleLogin auth=#{GFSession.auth_token}"
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
data/lib/gmoney/gf_response.rb
CHANGED
data/lib/gmoney/gf_service.rb
CHANGED
data/lib/gmoney/gf_session.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
module GMoney
|
2
|
+
|
3
|
+
# = GFSession
|
4
|
+
#
|
5
|
+
# Holds the authenicated user's token which is need
|
6
|
+
# for each request sent to Google
|
7
|
+
#
|
2
8
|
class GFSession
|
3
9
|
|
4
10
|
def self.login(email, password, opts={})
|
@@ -14,5 +20,10 @@ module GMoney
|
|
14
20
|
def self.email
|
15
21
|
@email
|
16
22
|
end
|
23
|
+
|
24
|
+
def self.logout
|
25
|
+
@email = nil
|
26
|
+
@auth_token = nil
|
27
|
+
end
|
17
28
|
end
|
18
29
|
end
|
data/lib/gmoney/portfolio.rb
CHANGED
@@ -1,7 +1,24 @@
|
|
1
1
|
module GMoney
|
2
|
+
# = Portfolio
|
3
|
+
#
|
4
|
+
# A Google Finace API Portfolio holds a collection of Positions
|
5
|
+
# and their associated Transactions
|
6
|
+
#
|
7
|
+
# > portfolio = GMoney::Portfolio.new
|
8
|
+
# > portfolio.title = "My New Portfolio"
|
9
|
+
# > portfolio.save #returns portfolio object
|
10
|
+
#
|
2
11
|
class Portfolio
|
3
|
-
|
12
|
+
# = PortfolioRequestError
|
13
|
+
# Invalid request actions or identifiers
|
14
|
+
class PortfolioRequestError < StandardError;end
|
15
|
+
|
16
|
+
# = PortfolioDeleteError
|
17
|
+
# Invalid delete action or identifier
|
4
18
|
class PortfolioDeleteError < StandardError;end
|
19
|
+
|
20
|
+
# = PortfolioSaveError
|
21
|
+
# Invalid save action or identifier
|
5
22
|
class PortfolioSaveError < StandardError;end
|
6
23
|
|
7
24
|
attr_accessor :title, :currency_code
|
@@ -51,7 +68,7 @@ module GMoney
|
|
51
68
|
url += "?returns=true" if options[:returns]
|
52
69
|
portfolios = []
|
53
70
|
|
54
|
-
response = GFService.send_request(GFRequest.new(url
|
71
|
+
response = GFService.send_request(GFRequest.new(url))
|
55
72
|
|
56
73
|
if response.status_code == HTTPOK
|
57
74
|
portfolios = PortfolioFeedParser.parse_portfolio_feed(response.body)
|
@@ -59,7 +76,7 @@ module GMoney
|
|
59
76
|
raise PortfolioRequestError, response.body
|
60
77
|
end
|
61
78
|
|
62
|
-
portfolios.each { |
|
79
|
+
portfolios.each { |port| port.instance_variable_set("@positions", port.positions(options))} if options[:eager]
|
63
80
|
|
64
81
|
return portfolios[0] if portfolios.size == 1
|
65
82
|
|
@@ -77,7 +94,7 @@ module GMoney
|
|
77
94
|
|
78
95
|
#Some firewalls block HTTP PUT messages. To get around this, you can include a
|
79
96
|
#X-HTTP-Method-Override: PUT header in a POST request
|
80
|
-
headers = {"
|
97
|
+
headers = {"Content-Type" => "application/atom+xml"}
|
81
98
|
headers["X-HTTP-Method-Override"] = "PUT" if @id #if there is already an @id defined then we are updating a portfolio
|
82
99
|
|
83
100
|
request = GFRequest.new(url, :method => :post, :body => atom_string, :headers => headers)
|
@@ -97,7 +114,7 @@ module GMoney
|
|
97
114
|
#X-HTTP-Method-Override: DELETE header in a POST request
|
98
115
|
def self.delete_portfolio(id)
|
99
116
|
url = "#{GF_PORTFOLIO_FEED_URL}/#{id}"
|
100
|
-
response = GFService.send_request(GFRequest.new(url, :method => :post, :headers => {"
|
117
|
+
response = GFService.send_request(GFRequest.new(url, :method => :post, :headers => {"X-HTTP-Method-Override" => "DELETE"}))
|
101
118
|
raise PortfolioDeleteError, response.body if response.status_code != HTTPOK
|
102
119
|
end
|
103
120
|
|
data/lib/gmoney/position.rb
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
module GMoney
|
2
|
+
# = Position
|
3
|
+
#
|
4
|
+
# The Google Finace API allows users to view position information
|
5
|
+
# for the securities (i.e. Positions) in their portfolios.
|
6
|
+
# To read a position use the following code:
|
7
|
+
#
|
8
|
+
# > positions = GMoney::Position.find(9) #returns all of a user's positions within a given portfolio, i.e. Portfolio "9"
|
9
|
+
# > position = GMoney::Position.find("9/NASDAQ:GOOG") #returns a specific position within a given portfolio
|
10
|
+
#
|
2
11
|
class Position
|
12
|
+
# = PositionRequestError
|
13
|
+
# Invalid request actions or identifiers
|
3
14
|
class PositionRequestError < StandardError; end
|
15
|
+
|
16
|
+
# = PositionDeleteError
|
17
|
+
# Invalid delete actions or identifiers
|
4
18
|
class PositionDeleteError < StandardError; end
|
5
19
|
|
6
20
|
attr_reader :id, :updated, :title, :feed_link, :exchange, :symbol, :shares,
|
@@ -39,7 +53,7 @@ module GMoney
|
|
39
53
|
positions = []
|
40
54
|
url += "?returns=true" if options[:returns]
|
41
55
|
|
42
|
-
response = GFService.send_request(GFRequest.new(url
|
56
|
+
response = GFService.send_request(GFRequest.new(url))
|
43
57
|
|
44
58
|
if response.status_code == HTTPOK
|
45
59
|
positions = PositionFeedParser.parse_position_feed(response.body) if response.status_code == 200
|
@@ -1,4 +1,8 @@
|
|
1
1
|
module GMoney
|
2
|
+
# = PositionFeedParser
|
3
|
+
#
|
4
|
+
# Parses Position feeds returned from the Google Finance API
|
5
|
+
#
|
2
6
|
class PositionFeedParser < FeedParser
|
3
7
|
def self.parse_position_feed(position_feed)
|
4
8
|
parse_feed(position_feed, Position, {:feed_link => true, :symbol => true})
|
data/lib/gmoney/transaction.rb
CHANGED
@@ -1,8 +1,31 @@
|
|
1
1
|
module GMoney
|
2
|
+
# = Transaction
|
3
|
+
#
|
4
|
+
# The Google Finace API allows for the buying and selling
|
5
|
+
# of securities (i.e. Positions) through Transactions. To
|
6
|
+
# create a valid Transaction use the following code:
|
7
|
+
#
|
8
|
+
# > transaction.portfolio = 9 #Must be a valid portfolio id
|
9
|
+
# > transaction.ticker = 'nyse:c' #Must be a valid ticker symbol
|
10
|
+
# > transaction.type = GMoney::BUY #Must be one of the following: Buy, Sell, Sell Short, Buy to Cover
|
11
|
+
# > transaction.save #returns transaction object
|
12
|
+
#
|
2
13
|
class Transaction
|
3
|
-
|
4
|
-
|
14
|
+
# = TransactionRequestError
|
15
|
+
# Invalid request actions or identifiers
|
16
|
+
class TransactionRequestError < StandardError; end
|
17
|
+
|
18
|
+
# = TransactionDeleteError
|
19
|
+
# Invalid delete action or identifier
|
20
|
+
class TransactionDeleteError < StandardError;end
|
21
|
+
|
22
|
+
# = TransactionSaveError
|
23
|
+
# Invalid save action or identifier
|
5
24
|
class TransactionSaveError < StandardError;end
|
25
|
+
|
26
|
+
# = TransactionIdError
|
27
|
+
# Don't allow users to modify the portfolio or position of
|
28
|
+
# a transaction that has already been created.
|
6
29
|
class TransactionIdError < StandardError;end
|
7
30
|
|
8
31
|
attr_reader :id, :updated, :title
|
@@ -28,18 +51,18 @@ module GMoney
|
|
28
51
|
end
|
29
52
|
end
|
30
53
|
|
31
|
-
def portfolio=(
|
54
|
+
def portfolio=(port)
|
32
55
|
raise TransactionIdError, "You can't modify the portfolio for a Transaction that already has an id" if @id
|
33
|
-
@portfolio =
|
56
|
+
@portfolio = port
|
34
57
|
end
|
35
58
|
|
36
|
-
def ticker=(
|
59
|
+
def ticker=(tick)
|
37
60
|
raise TransactionIdError, "You can't modify the ticker for a Transaction that already has an id" if @id
|
38
|
-
@ticker =
|
61
|
+
@ticker = tick
|
39
62
|
end
|
40
63
|
|
41
64
|
def self.find(id, options={})
|
42
|
-
find_by_url(
|
65
|
+
find_by_url(transaction_url(id), options)
|
43
66
|
end
|
44
67
|
|
45
68
|
def save
|
@@ -58,7 +81,7 @@ module GMoney
|
|
58
81
|
def self.find_by_url(url, options={})
|
59
82
|
transactions = []
|
60
83
|
|
61
|
-
response = GFService.send_request(GFRequest.new(url
|
84
|
+
response = GFService.send_request(GFRequest.new(url))
|
62
85
|
|
63
86
|
if response.status_code == HTTPOK
|
64
87
|
transactions = TransactionFeedParser.parse_transaction_feed(response.body)
|
@@ -75,8 +98,7 @@ module GMoney
|
|
75
98
|
#To overcome this problem the google doc say to use a post request with
|
76
99
|
#the X-HTTP-Method-Override set to "DELETE"
|
77
100
|
def self.delete_transaction(id)
|
78
|
-
|
79
|
-
response = GFService.send_request(GFRequest.new(url, :method => :post, :headers => {"Authorization" => "GoogleLogin auth=#{GFSession.auth_token}", "X-HTTP-Method-Override" => "DELETE"}))
|
101
|
+
response = GFService.send_request(GFRequest.new(transaction_url(id), :method => :post, :headers => {"X-HTTP-Method-Override" => "DELETE"}))
|
80
102
|
raise TransactionDeleteError, response.body if response.status_code != HTTPOK
|
81
103
|
end
|
82
104
|
|
@@ -101,7 +123,7 @@ module GMoney
|
|
101
123
|
|
102
124
|
#Some firewalls block HTTP PUT messages. To get around this, you can include a
|
103
125
|
#X-HTTP-Method-Override: PUT header in a POST request
|
104
|
-
headers = {"
|
126
|
+
headers = {"Content-Type" => "application/atom+xml"}
|
105
127
|
headers["X-HTTP-Method-Override"] = "PUT" if @id #if there is already an @id defined then we are updating a transaction
|
106
128
|
|
107
129
|
request = GFRequest.new(url, :method => :post, :body => atom_string, :headers => headers)
|
@@ -125,7 +147,11 @@ module GMoney
|
|
125
147
|
[BUY, SELL, SELL_SHORT, BUY_TO_COVER].include?(@type)
|
126
148
|
end
|
127
149
|
|
128
|
-
|
150
|
+
def transaction_url(id)
|
151
|
+
"#{GF_PORTFOLIO_FEED_URL}/#{id.portfolio_id}/positions/#{id.position_id}/transactions/#{id.transaction_id}"
|
152
|
+
end
|
153
|
+
|
154
|
+
private :save_transaction, :is_valid_transaction?, :is_valid_transaction_type?, :transaction_url
|
129
155
|
private_class_method :find_by_url, :delete_transaction
|
130
156
|
end
|
131
157
|
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
module GMoney
|
2
|
+
# = TransactionFeedParser
|
3
|
+
#
|
4
|
+
# Parses Transaction feeds returned from the Google Finance API
|
5
|
+
#
|
2
6
|
class TransactionFeedParser < FeedParser
|
3
7
|
def self.parse_transaction_feed(transaction_feed)
|
4
8
|
parse_feed(transaction_feed, Transaction, {:feed_link => false})
|
data/spec/portfolio_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe GMoney::Portfolio do
|
|
14
14
|
@url = "#{GMoney::GF_URL}/feeds/default/portfolios"
|
15
15
|
|
16
16
|
@gf_request = GMoney::GFRequest.new(@url)
|
17
|
-
@gf_request.method = :get
|
17
|
+
@gf_request.method = :get
|
18
18
|
|
19
19
|
@gf_response = GMoney::GFResponse.new
|
20
20
|
@gf_response.status_code = 200
|
@@ -198,10 +198,8 @@ describe GMoney::Portfolio do
|
|
198
198
|
lambda { portfolio.save }.should raise_error(GMoney::Portfolio::PortfolioSaveError, 'A Portfolio with this name already exists.')
|
199
199
|
end
|
200
200
|
|
201
|
-
def portfolio_helper(url, id = nil, options = {})
|
202
|
-
GMoney::
|
203
|
-
|
204
|
-
GMoney::GFRequest.should_receive(:new).with(url, :headers => {"Authorization" => "GoogleLogin auth=toke"}).and_return(@gf_request)
|
201
|
+
def portfolio_helper(url, id = nil, options = {})
|
202
|
+
GMoney::GFRequest.should_receive(:new).with(url).and_return(@gf_request)
|
205
203
|
|
206
204
|
GMoney::GFService.should_receive(:send_request).with(@gf_request).and_return(@gf_response)
|
207
205
|
|
@@ -215,10 +213,8 @@ describe GMoney::Portfolio do
|
|
215
213
|
portfolios = id ? GMoney::Portfolio.find(id, options) : GMoney::Portfolio.all(options)
|
216
214
|
end
|
217
215
|
|
218
|
-
def portfolio_delete_helper(url)
|
219
|
-
GMoney::
|
220
|
-
|
221
|
-
GMoney::GFRequest.should_receive(:new).with(url, :method => :post, :headers => {"Authorization" => "GoogleLogin auth=toke", "X-HTTP-Method-Override" => "DELETE"}).and_return(@gf_request)
|
216
|
+
def portfolio_delete_helper(url)
|
217
|
+
GMoney::GFRequest.should_receive(:new).with(url, :method => :post, :headers => {"X-HTTP-Method-Override" => "DELETE"}).and_return(@gf_request)
|
222
218
|
|
223
219
|
GMoney::GFService.should_receive(:send_request).with(@gf_request).and_return(@gf_response)
|
224
220
|
end
|
@@ -229,11 +225,9 @@ describe GMoney::Portfolio do
|
|
229
225
|
|
230
226
|
atom_string = "<?xml version='1.0'?><entry xmlns='http://www.w3.org/2005/Atom' xmlns:gf='http://schemas.google.com/finance/2007' xmlns:gd='http://schemas.google.com/g/2005'><title type='text'>#{title}</title> <gf:portfolioData currencyCode='#{currency_code}'/></entry>"
|
231
227
|
|
232
|
-
url = portfolio.id ? portfolio.id : GMoney::GF_PORTFOLIO_FEED_URL
|
233
|
-
|
234
|
-
GMoney::GFSession.should_receive(:auth_token).and_return('toke')
|
228
|
+
url = portfolio.id ? portfolio.id : GMoney::GF_PORTFOLIO_FEED_URL
|
235
229
|
|
236
|
-
headers = {"
|
230
|
+
headers = {"Content-Type" => "application/atom+xml"}
|
237
231
|
headers["X-HTTP-Method-Override"] = "PUT" if portfolio.id
|
238
232
|
|
239
233
|
GMoney::GFRequest.should_receive(:new).with(url, :method => :post, :body => atom_string, :headers => headers).and_return(@gf_request)
|
data/spec/position_spec.rb
CHANGED
@@ -144,12 +144,10 @@ describe GMoney::Position do
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def position_helper(id, options = {})
|
147
|
-
GMoney::GFSession.should_receive(:auth_token).and_return('toke')
|
148
|
-
|
149
147
|
url = "#{GMoney::GF_PORTFOLIO_FEED_URL}/#{id.portfolio_id}/positions/#{id.position_id}"
|
150
148
|
send_url = options[:returns] ? (url + '?returns=true') : url
|
151
149
|
|
152
|
-
GMoney::GFRequest.should_receive(:new).with(send_url
|
150
|
+
GMoney::GFRequest.should_receive(:new).with(send_url).and_return(@gf_request)
|
153
151
|
|
154
152
|
GMoney::GFService.should_receive(:send_request).with(@gf_request).and_return(@gf_response)
|
155
153
|
|
data/spec/request_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe GMoney::GFRequest do
|
|
18
18
|
|
19
19
|
it "should be able to take header parameters as a Hash" do
|
20
20
|
gfrequest_with_header_hash = GMoney::GFRequest.new('http://someurl.com', {:headers => {:header1 => 'some header'}})
|
21
|
-
gfrequest_with_header_hash.headers.should == {:header1 => 'some header', "GData-Version" => 2}
|
21
|
+
gfrequest_with_header_hash.headers.should == {:header1 => 'some header', "GData-Version" => 2, "Authorization" => "GoogleLogin auth="}
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should not accept random options" do
|
data/spec/service_spec.rb
CHANGED
@@ -123,6 +123,7 @@ describe GMoney::GFService do
|
|
123
123
|
def set_header_expectations(req)
|
124
124
|
req.should_receive(:[]=).with(:h1, "header 1").any_number_of_times
|
125
125
|
req.should_receive(:[]=).with(:h2, "header 2").any_number_of_times
|
126
|
-
req.should_receive(:[]=).with("GData-Version", 2).any_number_of_times
|
126
|
+
req.should_receive(:[]=).with("GData-Version", 2).any_number_of_times
|
127
|
+
req.should_receive(:[]=).with("Authorization", "GoogleLogin auth=").any_number_of_times
|
127
128
|
end
|
128
129
|
end
|
data/spec/session_spec.rb
CHANGED
@@ -29,4 +29,23 @@ describe GMoney::GFSession do
|
|
29
29
|
GMoney::GFSession.login('email@example.com', 'password')
|
30
30
|
GMoney::GFSession.email.should be_eql('email@example.com')
|
31
31
|
end
|
32
|
+
|
33
|
+
it "should allow users to logout" do
|
34
|
+
@auth_request.should_receive(:auth_token).with({}).and_return('toke')
|
35
|
+
|
36
|
+
GMoney::AuthenticationRequest.should_receive(:new).with('email@example.com', 'password').once.and_return(@auth_request)
|
37
|
+
GMoney::GFSession.login('email@example.com', 'password')
|
38
|
+
|
39
|
+
GMoney::GFSession.email.should be_eql('email@example.com')
|
40
|
+
GMoney::GFSession.auth_token.should be_eql('toke')
|
41
|
+
|
42
|
+
GMoney::GFSession.logout
|
43
|
+
|
44
|
+
GMoney::GFSession.email.should be_nil
|
45
|
+
GMoney::GFSession.auth_token.should be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
after(:all) do
|
49
|
+
GMoney::GFSession.logout
|
50
|
+
end
|
32
51
|
end
|
data/spec/transaction_spec.rb
CHANGED
@@ -268,13 +268,21 @@ describe GMoney::Transaction do
|
|
268
268
|
lambda { transaction.save }.should raise_error(GMoney::Transaction::TransactionSaveError, "Some of the values submitted are not valid and have been ignored.")
|
269
269
|
|
270
270
|
end
|
271
|
+
|
272
|
+
it "should create a url out of a Portfolio id" do
|
273
|
+
#Set methods to public visibility for testing
|
274
|
+
GMoney::Transaction.send(:public, *GMoney::Transaction.private_instance_methods)
|
275
|
+
trans = GMoney::Transaction.new
|
276
|
+
transaction_string = trans.transaction_url("123/NASDAQ:GOOG/23")
|
277
|
+
transaction_string.should be_eql("#{GMoney::GF_PORTFOLIO_FEED_URL}/123/positions/NASDAQ:GOOG/transactions/23")
|
278
|
+
end
|
271
279
|
|
272
280
|
def transaction_helper(id, options={})
|
273
|
-
GMoney::GFSession.should_receive(:auth_token).and_return('toke')
|
274
|
-
|
275
281
|
url = "#{GMoney::GF_PORTFOLIO_FEED_URL}/#{id.portfolio_id}/positions/#{id.position_id}/transactions/#{id.transaction_id}"
|
276
282
|
|
277
|
-
GMoney::
|
283
|
+
GMoney::Transaction.should_receive(:transaction_url).with(id).and_return(url)
|
284
|
+
|
285
|
+
GMoney::GFRequest.should_receive(:new).with(url).and_return(@gf_request)
|
278
286
|
|
279
287
|
GMoney::GFService.should_receive(:send_request).with(@gf_request).and_return(@gf_response)
|
280
288
|
|
@@ -282,9 +290,9 @@ describe GMoney::Transaction do
|
|
282
290
|
end
|
283
291
|
|
284
292
|
def transaction_delete_helper(url)
|
285
|
-
GMoney::
|
293
|
+
GMoney::Transaction.should_receive(:transaction_url).and_return(url)
|
286
294
|
|
287
|
-
GMoney::GFRequest.should_receive(:new).with(url, :method => :post, :headers => {"
|
295
|
+
GMoney::GFRequest.should_receive(:new).with(url, :method => :post, :headers => {"X-HTTP-Method-Override" => "DELETE"}).and_return(@gf_request)
|
288
296
|
|
289
297
|
GMoney::GFService.should_receive(:send_request).with(@gf_request).and_return(@gf_response)
|
290
298
|
end
|
@@ -304,9 +312,7 @@ describe GMoney::Transaction do
|
|
304
312
|
|
305
313
|
url = transaction.id ? transaction.id : "#{GMoney::GF_PORTFOLIO_FEED_URL}/#{transaction.portfolio}/positions/#{transaction.ticker}/transactions"
|
306
314
|
|
307
|
-
|
308
|
-
|
309
|
-
headers = {"Authorization" => "GoogleLogin auth=toke", "Content-Type" => "application/atom+xml"}
|
315
|
+
headers = {"Content-Type" => "application/atom+xml"}
|
310
316
|
headers["X-HTTP-Method-Override"] = "PUT" if transaction.id
|
311
317
|
|
312
318
|
GMoney::GFRequest.should_receive(:new).with(url, :method => :post, :body => atom_string, :headers => headers).and_return(@gf_request)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmoney
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Spradlin
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-04-13 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|