gmoney 0.4.3 → 0.4.4
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/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
|
|