glennr-posterous 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
1
+ === 0.1.6 / 2009-06-11
2
+
3
+ * 1 fix
4
+
5
+ * Fixed issue where specifying site ID while only having one site cause has_site? to fail
6
+
7
+ === 0.1.5 / 2009-06-03
8
+
9
+ * 1 major enhancement
10
+
11
+ * Moved Everything into a module and updated tests
12
+
13
+ === 0.1.3 / 2009-06-01
14
+
15
+ * 1 major enhancement
16
+
17
+ * Updated Readme and DRYed up a method to use symbols
18
+
19
+ === 0.1.2 / 2009-05-29
20
+
21
+ * 1 major enhancement
22
+
23
+ * Updated the class to accept date, private, autopost, tags
24
+
25
+ === 0.1.0 / 2009-05-19
26
+
27
+ * 1 major enhancement
28
+
29
+ * Birthday!
30
+
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/posterous
6
+ lib/posterous.rb
7
+ test/test_posterous.rb
@@ -0,0 +1,158 @@
1
+ = posterous
2
+
3
+ http://github.com/jordandobson/Posterous/tree/master
4
+
5
+ == DESCRIPTION:
6
+
7
+ The Posterous gem provides reading from and posting to Posterous.com, including (optional) authentication using email/password/[site id].
8
+
9
+ With this gem, you
10
+ 1. Read entries from Posterous (added by Glenn Roberts)
11
+ 2. Post an entry on posterous by providing these options a title, body text, date, tags, set to autopost, set private, posted by source name and a posted by source link to Posterous. You can include no options, all options or anything in between.
12
+
13
+ == INSTALL:
14
+
15
+ * sudo gem install posterous -include-dependencies
16
+
17
+ == TODO
18
+
19
+ * Media files are not yet implemented
20
+ * Images are not yet included
21
+ * Check if a users email and password are a valid account
22
+ * Check if a user has a valid site
23
+ * Check if a specified site_id is valid for their account
24
+ * Get their primary Site ID
25
+
26
+ == SYNOPSIS:
27
+
28
+ === READING
29
+
30
+ Here is a contrived example;
31
+
32
+ require 'posterous'
33
+
34
+ reader = Posterous::Reader.new("siyelo", nil, 2)
35
+
36
+ reader.response.each do |post|
37
+ puts post['url']
38
+ puts post['link']
39
+ puts post['title']
40
+ puts post['body']
41
+ puts post['commentCount']
42
+ end
43
+
44
+ === POSTING
45
+
46
+ 1. Instantiate your account
47
+
48
+ * You can provide just the email and password
49
+
50
+ account = Posterous::Client.new('email_address', 'password')
51
+
52
+ * Or you can provide the ID as a string or integer
53
+
54
+ account = Posterous::Client.new('email_address', 'password', 68710)
55
+ account = Posterous::Client.new('email_address', 'password', '68710')
56
+
57
+ 2. Get more info about the user's account if you need it
58
+
59
+ * Check if the user is valid
60
+
61
+ account.valid_user?
62
+
63
+ * Check if the user has a site AND if you've entered a Site ID, check it's valid too
64
+
65
+ account.has_site?
66
+
67
+ * Get the users primary site ID (In case they have multiple sites)
68
+
69
+ account.primary_site
70
+
71
+ * Get a list of your sites and additional info
72
+
73
+ account.account_info
74
+
75
+ 3. Setup your post with any or all of these optional fields
76
+
77
+ * You can set your id at this point or at the begining when it's instantiated
78
+
79
+ account.site_id = account.get_primary_site or specific site ID
80
+
81
+ * Set these optional fields
82
+
83
+ account.title = "My Title"
84
+ account.body = "My Body Text"
85
+ account.source = "Glue"
86
+ account.source_url = "http://GlueNow.com"
87
+ account.tags = ["Glue", "Posterous", "Ruby", "Made By Squad"]
88
+ account.date = Time.now
89
+
90
+ * Call the set_to method with either :private or :autopost to apply that setting
91
+
92
+ account.set_to :private
93
+ account.set_to :autopost
94
+
95
+ 4. Add your post to Posterous.com
96
+
97
+ * Set this to a variable to work with the response
98
+
99
+ response = account.add_post
100
+
101
+ 5. You get a success or error hash back or nil
102
+
103
+ * Your response should look something like this if successful
104
+
105
+ response #=> { "rsp" => { "post" => { "title" => "My Title", "url" => "http://post.ly/dFW", "id" => "848898", "longurl" => "http://glue.posterous.com/687985" }, "stat" => "ok" } }
106
+
107
+ * See the tests for this gem for failure responses and responses for other methods
108
+
109
+
110
+ == MORE INFO
111
+
112
+ * Posting URL
113
+
114
+ http://posterous.com/api/newpost
115
+
116
+ * IMPLEMENTED FIELDS
117
+ "site_id" Optional. Id of the site to post to.
118
+ "title" Optional. Title of post
119
+ "body" Optional. Body of post
120
+ "source" Optional. The name of your application or website
121
+ "sourceLink" Optional. Link to your application or website
122
+ "date" Optional. In GMT. Any parsable format. Cannot be in the future.
123
+ "tags" Optional. Comma separate tags
124
+ "autopost" Optional. 0 or 1.
125
+ "private" Optional. 0 or 1.
126
+
127
+ * UNIMPLEMENTED FIELDS - These will likely be implemented in a future release
128
+ "media" Optional. File data. Multiple files OK
129
+
130
+ == REQUIREMENTS:
131
+
132
+ * HTTPparty
133
+ * Mocha (For Tests)
134
+
135
+ == LICENSE:
136
+
137
+ (The MIT License)
138
+
139
+ Copyright (c) 2009 Jordan Dobson
140
+
141
+ Permission is hereby granted, free of charge, to any person obtaining
142
+ a copy of this software and associated documentation files (the
143
+ 'Software'), to deal in the Software without restriction, including
144
+ without limitation the rights to use, copy, modify, merge, publish,
145
+ distribute, sublicense, and/or sell copies of the Software, and to
146
+ permit persons to whom the Software is furnished to do so, subject to
147
+ the following conditions:
148
+
149
+ The above copyright notice and this permission notice shall be
150
+ included in all copies or substantial portions of the Software.
151
+
152
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
153
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
154
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
155
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
156
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
157
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
158
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/posterous.rb'
6
+
7
+ Hoe.new('posterous', Posterous::VERSION) do |p|
8
+ p.developer('Jordan Dobson', 'jordan.dobson@madebysquad.com')
9
+ p.extra_deps = ['httparty']
10
+ p.extra_dev_deps = ['mocha']
11
+ end
12
+
13
+ # vim: syntax=Ruby
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+
@@ -0,0 +1,146 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+
4
+ module Posterous
5
+
6
+ VERSION = '0.1.7'
7
+
8
+ class AuthError < StandardError; end
9
+ class TagError < StandardError; end
10
+ class SiteError < StandardError; end
11
+
12
+
13
+ DOMAIN = 'posterous.com'
14
+ POST_PATH = '/api/newpost'
15
+ AUTH_PATH = '/api/getsites'
16
+ READ_PATH = '/api/readposts'
17
+
18
+ # TODO: Include media with your post
19
+ # TODO: Post only a media file and get a url for it back
20
+
21
+ # Posterous reader
22
+ # http://posterous.com/api/reading
23
+ class Reader
24
+
25
+ include HTTParty
26
+ base_uri DOMAIN
27
+
28
+ attr_reader :response
29
+
30
+ ### Non-authenticated initialization
31
+ def initialize hostname = "", site_id = nil, num_posts = nil, page = nil, tag = nil
32
+ raise AuthError, 'Either Site Id or Hostname must be supplied if not using authentication.' if \
33
+ (hostname == "" && !site_id.is_a?(Integer)) || (!hostname.is_a?(String) && site_id == nil)
34
+ @site_id = site_id ? site_id.to_s : site_id
35
+ @hostname = hostname
36
+ @num_posts = num_posts ? num_posts.to_s : num_posts
37
+ @page = page ? page.to_s : page
38
+ @tag = tag ? tag.to_s : tag
39
+ @response = read_posts
40
+ self
41
+ end
42
+
43
+ def read_posts
44
+ self.class.get(READ_PATH, :query => build_query)["rsp"]["post"]
45
+ end
46
+
47
+ def build_query
48
+ query = { :site_id => @site_id,
49
+ :hostname => @hostname,
50
+ :num_posts => @num_posts,
51
+ :page => @page,
52
+ :tag => @tag }
53
+ query.delete_if { |k,v| !v }
54
+ query
55
+ end
56
+ end
57
+
58
+
59
+ class Client
60
+
61
+ include HTTParty
62
+ base_uri DOMAIN
63
+
64
+ attr_accessor :title, :body, :source, :source_url, :date
65
+ attr_reader :private_post, :autopost, :site_id, :tags
66
+
67
+ ### Authenticated initialization
68
+ def initialize user, pass, site_id = nil, hostname = ""
69
+ raise AuthError, 'Either Username or Password is blank and/or not a string.' if \
70
+ !user.is_a?(String) || !pass.is_a?(String) || user == "" || pass == ""
71
+ self.class.basic_auth user, pass
72
+ @site_id = site_id ? site_id.to_s : site_id
73
+ @source = @body = @title = @source_url = @date = @media = @tags = @autopost = @private_post = nil
74
+ end
75
+
76
+ def site_id= id
77
+ @site_id = id.to_s
78
+ end
79
+
80
+ def tags= ary
81
+ raise TagError, 'Tags must added using an array' if !ary.is_a?(Array)
82
+ @tags = ary.join(", ")
83
+ end
84
+
85
+ def valid_user?
86
+ res = account_info
87
+ return false unless res.is_a?(Hash)
88
+ res["stat"] == "ok"
89
+ end
90
+
91
+ def has_site?
92
+ res = account_info
93
+ return false unless res.is_a?(Hash)
94
+
95
+ case res["site"]
96
+ when Hash
97
+ return true unless @site_id
98
+ return @site_id == res["site"]["id"]
99
+ when Array
100
+ res["site"].each do |site|
101
+ return true if @site_id && @site_id == site["id"]
102
+ end
103
+ end
104
+ false
105
+ end
106
+
107
+ def primary_site
108
+ res = account_info
109
+ raise SiteError, "Couldn't find a primary site. Check login and password is valid." \
110
+ unless res.is_a?(Hash) && res["stat"] == "ok" && res["site"]
111
+ [res["site"]].flatten.each do |site|
112
+ return site["id"] if site["primary"] == "true"
113
+ end
114
+ nil
115
+ end
116
+
117
+ def set_to on
118
+ @private_post = 1 if on == :private
119
+ @autopost = 1 if on == :autopost
120
+ end
121
+
122
+ def build_query
123
+ options = { :site_id => @site_id,
124
+ :autopost => @autopost,
125
+ :private => @private_post,
126
+ :date => @date,
127
+ :tags => @tags }
128
+
129
+ query = { :title => @title,
130
+ :body => @body,
131
+ :source => @source,
132
+ :sourceLink => @source_url }
133
+
134
+ options.delete_if { |k,v| !v }
135
+ query.merge!(options)
136
+ end
137
+
138
+ def account_info
139
+ self.class.post(AUTH_PATH, :query => {})["rsp"]
140
+ end
141
+
142
+ def add_post
143
+ self.class.post(POST_PATH, :query => build_query)
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,400 @@
1
+ require 'test/unit'
2
+ require 'posterous'
3
+ require 'mocha'
4
+
5
+ class TestPosterous < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @e = "email"
9
+ @p = "password"
10
+
11
+ @new_obj = Posterous::Client.new(@e, @p)
12
+ @new_obj_with_id = Posterous::Client.new(@e, @p, "174966")
13
+ @new_obj_with_bad_id = Posterous::Client.new(@e, @p, "badID")
14
+ @new_obj_with_invalid_id = Posterous::Client.new(@e, @p, "666")
15
+
16
+
17
+ @private_url_path = /[.]posterous[.]com\/private\//
18
+
19
+ @resp_ok ={ "rsp" => {
20
+ "site" => {
21
+ "name" => "ruby-posterous's posterous",
22
+ "primary" => "true", "private"=>"false",
23
+ "url" => "http://ruby-posterous.posterous.com",
24
+ "id" => "174966" },
25
+ "stat" => "ok" }}
26
+
27
+ @resp_fail ={ "rsp" => {
28
+ "err" => {
29
+ "msg" => "Invalid Posterous email or password",
30
+ "code" => "3001" },
31
+ "stat" => "fail" }}
32
+
33
+ @resp_ok_2_sites ={ "rsp" => {
34
+ "site" => [{
35
+ "name" => "ruby-posterous's posterous",
36
+ "primary" => "false",
37
+ "private" => "false",
38
+ "url" => "http://ruby-posterous.posterous.com",
39
+ "id" => "174966"
40
+ }, {
41
+ "name" => "uw-ruby",
42
+ "primary" => "true",
43
+ "private" => "false",
44
+ "url" => "http://uwruby.posterous.com",
45
+ "id" => "175260" }],
46
+ "stat" => "ok" }}
47
+
48
+ @good_response ={ "site" => {
49
+ "name" => "ruby-posterous's posterous",
50
+ "primary" => "true",
51
+ "private" => "false",
52
+ "url" => "http://ruby-posterous.posterous.com",
53
+ "id" => "174966" },
54
+ "stat" => "ok" }
55
+
56
+ @bad_response ={ "err" => {
57
+ "msg" => "Invalid Posterous email or password",
58
+ "code" => "3001" },
59
+ "stat" => "fail" }
60
+
61
+ @post_success ={ "rsp" => {
62
+ "post" => {
63
+ "title" => "Untitled",
64
+ "url" => "http://post.ly/dFW",
65
+ "id" => "848898",
66
+ "longurl" => "http://glue.posterous.com/687985" },
67
+ "stat" => "ok" }}
68
+
69
+ @post_title_success ={"rsp" => {
70
+ "post" => {
71
+ "title" => "My Title",
72
+ "url" => "http://post.ly/dFW",
73
+ "id" => "848898",
74
+ "longurl" => "http://glue.posterous.com/687985" },
75
+ "stat" => "ok" }}
76
+
77
+ @post_invalid_site ={ "rsp" => {
78
+ "err" => {
79
+ "msg" => "Invalid site id",
80
+ "code" => "3002" },
81
+ "stat" => "fail" }}
82
+
83
+ @post_access_error ={ "rsp" => {
84
+ "err" => {
85
+ "msg" => "User does not have access to this site",
86
+ "code" => "3003" },
87
+ "stat" => "fail" }}
88
+
89
+ @post_bad_account ={ "rsp" => {
90
+ "err" => {
91
+ "msg" => "Invalid Posterous email or password",
92
+ "code" => "3001" },
93
+ "stat" => "fail" }}
94
+
95
+ @post_private_good ={ "rsp" => {
96
+ "post" => {
97
+ "title" => "Posterous test",
98
+ "url" => "http://post.ly/gxK",
99
+ "id" => "891064",
100
+ "longurl" => "http://glue.posterous.com/private/tGIEAateBy" },
101
+ "stat" => "ok" }}
102
+
103
+ @get_read_success ={ "rsp" => {
104
+ "post" => {
105
+ "title" => "Get My Title",
106
+ "url" => "http://post.ly/dFW",
107
+ "id" => "848898",
108
+ "longurl" => "http://glue.posterous.com/687985" },
109
+ "stat" => "ok" }}
110
+
111
+ end
112
+
113
+ def test_raises_if_username_is_blank
114
+ assert_raise Posterous::AuthError do
115
+ Posterous::Client.new('', @p)
116
+ end
117
+ end
118
+
119
+ def test_raises_if_password_is_blank
120
+ assert_raise Posterous::AuthError do
121
+ Posterous::Client.new(@e, '')
122
+ end
123
+ end
124
+
125
+ def test_raises_if_password_is_not_srting
126
+ assert_raise Posterous::AuthError do
127
+ Posterous::Client.new(@e, 666)
128
+ end
129
+ end
130
+
131
+ def test_raises_if_username_is_not_srting
132
+ assert_raise Posterous::AuthError do
133
+ Posterous::Client.new(666, @p)
134
+ end
135
+ end
136
+
137
+ def test_site_id_can_be_witheld
138
+ actual = Posterous::Client.new(@e, @p)
139
+ assert_equal nil, actual.site_id
140
+ end
141
+
142
+ def test_site_id_can_be_provided
143
+ actual = Posterous::Client.new(@e, @p, '174966')
144
+ assert_equal '174966', actual.site_id
145
+ end
146
+
147
+ def test_site_id_is_converted_to_string
148
+ actual = Posterous::Client.new(@e, @p, 174966)
149
+ assert_equal '174966', actual.site_id
150
+ end
151
+
152
+ def test_user_is_valid
153
+ Posterous::Client.stubs(:post).returns(@resp_ok)
154
+ assert_equal true, @new_obj.valid_user?
155
+ end
156
+
157
+ def test_user_is_invalid
158
+ Posterous::Client.stubs(:post).returns(@resp_fail)
159
+ assert_equal false, @new_obj.valid_user?
160
+ end
161
+
162
+ def test_user_is_invalid_when_response_isnt_hash
163
+ Posterous::Client.stubs(:post).returns("666")
164
+ assert_equal false, @new_obj.valid_user?
165
+ end
166
+
167
+ def test_ping_success_hash_adjustment
168
+ Posterous::Client.stubs(:post).returns(@resp_ok)
169
+ assert_equal @good_response, @new_obj.account_info
170
+ end
171
+
172
+ def test_ping_fail_hash_adjustment
173
+ Posterous::Client.stubs(:post).returns(@resp_fail)
174
+ assert_equal @bad_response, @new_obj.account_info
175
+ end
176
+
177
+ def test_has_site_is_successful
178
+ Posterous::Client.stubs(:post).returns(@resp_ok)
179
+ assert_equal true, @new_obj.has_site?
180
+ end
181
+
182
+ def test_has_site_successful_if_site_id_matches_only_result
183
+ Posterous::Client.stubs(:post).returns(@resp_ok_2_sites)
184
+ assert_equal true, @new_obj_with_id.has_site?
185
+ end
186
+
187
+ def test_has_site_fails_if_site_id_doesnt_match_only_result
188
+ Posterous::Client.stubs(:post).returns(@resp_ok)
189
+ assert_equal false, @new_obj_with_bad_id.has_site?
190
+ end
191
+
192
+ def test_has_site_successful_that_site_id_matches_response
193
+ Posterous::Client.stubs(:post).returns(@resp_ok)
194
+ assert_equal true, @new_obj_with_id.has_site?
195
+ end
196
+
197
+ def test_has_site_is_successful_on_multiple_when_specified
198
+ Posterous::Client.stubs(:post).returns(@resp_ok_2_sites)
199
+ assert_equal true, @new_obj_with_id.has_site?
200
+ end
201
+
202
+ def test_has_site_fails_if_specified_and_site_id_not_listed
203
+ Posterous::Client.stubs(:post).returns(@resp_ok_2_sites)
204
+ assert_equal false, @new_obj_with_bad_id.has_site?
205
+ end
206
+
207
+ def test_has_site_fails_when_multiple_and_site_not_specified
208
+ Posterous::Client.stubs(:post).returns(@resp_ok_2_sites)
209
+ assert_equal false, @new_obj.has_site?
210
+ end
211
+
212
+ def test_has_site_fails_with_error_response
213
+ Posterous::Client.stubs(:post).returns(@resp_fail)
214
+ assert_equal false, @new_obj.has_site?
215
+ end
216
+
217
+ def test_has_site_fails_if_response_isnt_hash
218
+ Posterous::Client.stubs(:post).returns("666")
219
+ assert_equal false, @new_obj.has_site?
220
+ end
221
+
222
+ def test_tags_are_added_correctly
223
+ @new_obj.tags = []
224
+ assert_equal @new_obj.tags, ""
225
+ end
226
+
227
+ def test_tags_single_is_correctly
228
+ @new_obj.tags = ["Glue"]
229
+ assert_equal @new_obj.tags, "Glue"
230
+ end
231
+
232
+ def test_tags_multiple_is_correctly_joined
233
+ @new_obj.tags = ["Glue", "Posterous", "Ruby on Rails"]
234
+ assert_equal @new_obj.tags, "Glue, Posterous, Ruby on Rails"
235
+ end
236
+
237
+ def test_raises_if_tags_not_set_as_array
238
+ assert_raise Posterous::TagError do
239
+ @new_obj.tags = "hello, "
240
+ end
241
+ end
242
+
243
+ def test_gets_primary_single_site
244
+ Posterous::Client.stubs(:post).returns(@resp_ok)
245
+ assert_equal @resp_ok["rsp"]["site"]["id"], @new_obj.primary_site
246
+ end
247
+
248
+ def test_gets_primary_site_from_multiple_listing
249
+ Posterous::Client.stubs(:post).returns(@resp_ok_2_sites)
250
+ assert_equal @resp_ok_2_sites["rsp"]["site"][1]["id"], @new_obj.primary_site
251
+ end
252
+
253
+ def test_gets_primary_site_raises_on_error
254
+ Posterous::Client.stubs(:post).returns(@resp_fail)
255
+ assert_raise Posterous::SiteError do
256
+ @new_obj.primary_site
257
+ end
258
+ end
259
+
260
+ def test_gets_primary_site_is_passed_to_overide_site_id
261
+ Posterous::Client.stubs(:post).returns(@resp_ok_2_sites)
262
+ original = @new_obj_with_id.site_id
263
+ @new_obj_with_id.site_id = @new_obj_with_id.primary_site
264
+ updated = @new_obj_with_id.site_id
265
+ assert_not_equal original, updated
266
+ assert_equal @resp_ok_2_sites["rsp"]["site"][1]["id"], updated
267
+ end
268
+
269
+ def test_gets_primary_site_is_set_to_site_id
270
+ Posterous::Client.stubs(:post).returns(@resp_ok)
271
+ original = @new_obj.site_id
272
+ @new_obj.site_id = @new_obj.primary_site
273
+ updated = @new_obj_with_id.site_id
274
+ assert_not_equal original, updated
275
+ assert_equal @resp_ok["rsp"]["site"]["id"], updated
276
+ end
277
+
278
+ def test_builds_query_without_site_id
279
+ expected = { :source => nil, :title => nil, :body => nil, :sourceLink => nil}
280
+ assert_equal expected, @new_obj.build_query
281
+ end
282
+
283
+ def test_builds_query_with_site_id
284
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :site_id => "174966", :title => nil }
285
+ assert_equal expected, @new_obj_with_id.build_query
286
+ end
287
+
288
+ def test_builds_query_with_all_fields_set_without_site_id
289
+ @new_obj.title = "My Title"
290
+ @new_obj.body = "My Body"
291
+ @new_obj.source = "The Tubes"
292
+ @new_obj.source_url = "http://TheTubes.com"
293
+ expected = { :source => "The Tubes", :body => "My Body", :sourceLink => "http://TheTubes.com", :title => "My Title" }
294
+ assert_equal expected, @new_obj.build_query
295
+ end
296
+
297
+ def test_builds_query_with_date_option
298
+ date = Time.now
299
+ @new_obj.date = date
300
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :title => nil, :date => date }
301
+ assert_equal expected, @new_obj.build_query
302
+ end
303
+
304
+ def test_builds_query_with_private_option
305
+ @new_obj.set_to :private
306
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :title => nil, :private => 1 }
307
+ assert_equal expected, @new_obj.build_query
308
+ end
309
+
310
+ def test_builds_query_with_autopost_option
311
+ @new_obj.set_to :autopost
312
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :title => nil, :autopost => 1 }
313
+ assert_equal expected, @new_obj.build_query
314
+ end
315
+
316
+ def test_builds_query_with_integer_set_as_site_id
317
+ @new_obj.site_id = 20
318
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :site_id => "20", :title => nil }
319
+ assert_equal expected, @new_obj.build_query
320
+ end
321
+
322
+ def test_builds_query_with_all_options_set
323
+ date = Time.now
324
+ @new_obj.date = date
325
+ @new_obj.site_id = 20
326
+ @new_obj.set_to :private
327
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :site_id => "20", :title => nil, :private => 1, :date => date }
328
+ assert_equal expected, @new_obj.build_query
329
+ end
330
+
331
+ def test_builds_query_with_all_fields_set_and_site_id
332
+ @new_obj_with_id.title = "My Title"
333
+ @new_obj_with_id.body = "My Body"
334
+ @new_obj_with_id.source = "The Tubes"
335
+ @new_obj_with_id.source_url = "http://TheTubes.com"
336
+ expected = { :source => "The Tubes", :body => "My Body", :sourceLink => "http://TheTubes.com", :site_id => "174966", :title => "My Title" }
337
+ assert_equal expected, @new_obj_with_id.build_query
338
+ end
339
+
340
+ def test_add_post_successful
341
+ Posterous::Client.stubs(:post).returns(@post_success)
342
+ expected = @post_success
343
+ assert_equal expected, @new_obj.add_post
344
+ end
345
+
346
+ def test_add_post_successful_no_content
347
+ Posterous::Client.stubs(:post).returns(@post_success)
348
+ actual = @new_obj.add_post
349
+ assert actual["rsp"]["post"].is_a?(Hash)
350
+ assert_equal "ok", actual["rsp"]["stat"]
351
+ assert_equal "Untitled", actual["rsp"]["post"]["title"]
352
+ end
353
+
354
+ def test_add_post_successful_with_title_content
355
+ Posterous::Client.stubs(:post).returns(@post_title_success)
356
+ @new_obj.title = "My Title"
357
+ actual = @new_obj.add_post
358
+ assert_equal "My Title", actual["rsp"]["post"]["title"]
359
+ end
360
+
361
+ def test_add_post_invalid_site_id_fails
362
+ Posterous::Client.stubs(:post).returns(@post_invalid_site)
363
+ actual = @new_obj_with_bad_id.add_post
364
+ assert_equal "fail", actual["rsp"]["stat"]
365
+ assert_equal nil, actual["rsp"]["post"]
366
+ assert_equal "Invalid site id", actual["rsp"]["err"]["msg"]
367
+ end
368
+
369
+ def test_add_post_no_access_fails
370
+ Posterous::Client.stubs(:post).returns(@post_access_error)
371
+ actual = @new_obj_with_invalid_id.add_post
372
+ assert_equal "fail", actual["rsp"]["stat"]
373
+ assert_equal nil, actual["rsp"]["post"]
374
+ assert_match "not have access", actual["rsp"]["err"]["msg"]
375
+ end
376
+
377
+ def test_add_post_invalid_account_info
378
+ Posterous::Client.stubs(:post).returns(@post_bad_account)
379
+ actual = Posterous::Client.new("666", "666").add_post
380
+ assert_equal "fail", actual["rsp"]["stat"]
381
+ assert_equal nil, actual["rsp"]["post"]
382
+ assert_match "Invalid Posterous", actual["rsp"]["err"]["msg"]
383
+ end
384
+
385
+ def test_add_post_is_private_by_default
386
+ Posterous::Client.stubs(:post).returns(@post_success)
387
+ actual = @new_obj.add_post
388
+ assert_equal "ok", actual["rsp"]["stat"]
389
+ assert_no_match @private_url_path, actual["rsp"]["post"]["longurl"]
390
+ end
391
+
392
+ def test_add_post_is_made_private
393
+ Posterous::Client.stubs(:post).returns(@post_private_good)
394
+ @new_obj.set_to :private
395
+ actual = @new_obj.add_post
396
+ assert_equal "ok", actual["rsp"]["stat"]
397
+ assert_match @private_url_path, actual["rsp"]["post"]["longurl"]
398
+ end
399
+
400
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: glennr-posterous
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.7
5
+ platform: ruby
6
+ authors:
7
+ - Jordan Dobson
8
+ - Glenn Roberts
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-11-26 00:00:00 +02:00
14
+ default_executable: posterous
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: hoe
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.8.3
25
+ version:
26
+ description: The Posterous gem provides reading & posting from/to Posterous.com using your email, password, site id(if you have multiple sites) and your blog content.
27
+ email:
28
+ - g@glenn-roberts.com
29
+ executables: []
30
+
31
+ extensions: []
32
+
33
+ extra_rdoc_files:
34
+ - History.txt
35
+ - Manifest.txt
36
+ - README.txt
37
+ files:
38
+ - History.txt
39
+ - Manifest.txt
40
+ - README.txt
41
+ - Rakefile
42
+ - bin/posterous
43
+ - lib/posterous.rb
44
+ - test/test_posterous.rb
45
+ has_rdoc: true
46
+ homepage: http://github.com/glennr/Posterous
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --main
52
+ - README.txt
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project: posterous
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 2
73
+ summary: The Posterous gem provides posting to Posterous.com using your email, password, site id(if you have multiple sites) and your blog content. With this gem, you have access to add an entry on posterous by providing these options a title, body text, date, tags, set to autopost, set private, posted by source name and a posted by source link to Posterous. You can include no options or all options.
74
+ test_files:
75
+ - test/test_posterous.rb