jordandobson-posterous 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,12 +1,12 @@
1
- === 1.0.1 / 2009-06-05
1
+ === 0.1.0 / 2009-05-19
2
2
 
3
3
  * 1 major enhancement
4
4
 
5
- * Added the ability to post and check account properties
6
-
7
- === 1.0.0 / 2009-05-28
5
+ * Birthday!
6
+
7
+ === 0.1.2 / 2009-05-29
8
8
 
9
9
  * 1 major enhancement
10
10
 
11
- * Birthday!
11
+ * Updated the class to accept date, private, autopost, tags
12
12
 
data/Manifest.txt CHANGED
@@ -2,6 +2,6 @@ History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
- bin/wordpress
6
- lib/wordpress.rb
7
- test/test_wordpress.rb
5
+ bin/posterous
6
+ lib/posterous.rb
7
+ test/test_posterous.rb
data/README.txt CHANGED
@@ -1,34 +1,36 @@
1
- = wordpress
1
+ = posterous
2
2
 
3
- * http://JordanDobson.com
3
+ http://github.com/jordandobson/Posterous/tree/master
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- The Wordpress gem provides posting to a Wordpress.com blog or a self hosted wordpress by provided your username, password, login url(if you host your blog) and your blog content. With this gem, you have access to add a text entry on Wordpress blug by providing these options: a title, body, and tags. You must include at least a title or body for your post.
7
+ 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.
8
8
 
9
- Posting images with posts, posting only images and pulling down your posts will be available very soon.
9
+ Posting images with posts, posting only images and pulling down your posts will be available soon. The Posterous API was unstable when this version of the gem was created.
10
10
 
11
11
  == FEATURES/PROBLEMS:
12
12
 
13
- * Either Title or Body is optional
14
- * Adding Images are not yet implemented
13
+ * All Fields are optional
14
+ * Media files are not yet implemented
15
15
  * Posting Only, Reading & Images are not yet included
16
- * Check if a username and password are valid
17
- * Check if a provided login_url is valid
18
- * Get the users blog url
19
- * This is very throughly tested
16
+ * Check if a users email and password are a valid account
17
+ * Check if a user has a valid site
18
+ * Check if a specified site_id is valid for their account
19
+ * Get their primary Site ID
20
+ * This is very well throughly tested
20
21
 
21
22
  == SYNOPSIS:
22
23
 
23
24
  1. Instantiate your account
24
25
 
25
- * You can provide just the username and password
26
+ * You can provide just the email and password
26
27
 
27
- account = Wordpress::Client.new('username', 'password')
28
+ account = Posterous.new('email_address', 'password')
28
29
 
29
30
  * Or you can provide the ID as a string or integer
30
31
 
31
- account = Wordpress::Client.new('username', 'password', 'http://blog.mysite.com/wp-login.php')
32
+ account = Posterous.new('email_address', 'password', 68710)
33
+ account = Posterous.new('email_address', 'password', '68710')
32
34
 
33
35
  2. Get more info about the user's account if you need it
34
36
 
@@ -36,25 +38,37 @@ Posting images with posts, posting only images and pulling down your posts will
36
38
 
37
39
  account.valid_user?
38
40
 
39
- * Check if the specified login page is valid
41
+ * Check if the user has a site and if they specified a Site ID check it's valid
40
42
 
41
- account.valid_login_page?
43
+ account.has_site?
42
44
 
43
- * Get the users blog page url
45
+ * Get the users primary site ID (In case they have two)
44
46
 
45
- account.blog_url
47
+ account.get_primary_site
46
48
 
47
49
  * Get a list of your sites and additional info
48
50
 
49
- account.account_info
51
+ account.get_account_info
50
52
 
51
- 3. Setup your post
53
+ 3. Setup your post with any or all of these optional fields
52
54
 
53
- * You must at least include the title or body
55
+ * You can set your id at this point or when it's instantiated
56
+
57
+ account.site_id = account.get_primary_site or specific site ID
58
+
59
+ * Set these optional fields
54
60
 
55
61
  account.title = "My Title"
56
62
  account.body = "My Body Text"
63
+ account.source = "Glue"
64
+ account.source_url = "http://GlueNow.com"
57
65
  account.tags = ["Glue", "Posterous", "Ruby", "Made By Squad"]
66
+ account.date = Time.now
67
+
68
+ * Call these methods to set them
69
+
70
+ account.set_to_private
71
+ account.set_to_autopost
58
72
 
59
73
  4. Add your post to Posterous.com
60
74
 
@@ -66,17 +80,40 @@ Posting images with posts, posting only images and pulling down your posts will
66
80
 
67
81
  * Your response should look something like this if successful
68
82
 
69
- response #=> { "rsp" => { "post" => { "title" => "My Title", "url" => "http://getglue.wordpress.com/2009/06/06/my-title/", "id" => "69" }, "stat" => "ok" } }
83
+ response #=> { "rsp" => { "post" => { "title" => "My Title", "url" => "http://post.ly/dFW", "id" => "848898", "longurl" => "http://glue.posterous.com/687985" }, "stat" => "ok" } }
70
84
 
71
85
  * See the tests for this gem for failure responses and responses for other methods
72
86
 
87
+
88
+ # MORE INFO
89
+
90
+ * URL
91
+
92
+ http://posterous.com/api/newpost
93
+
94
+ * IMPLEMENTED FIELDS - All are optional
95
+
96
+ "site_id" Optional. Id of the site to post to.
97
+ "title" Optional. Title of post
98
+ "body" Optional. Body of post
99
+ "source" Optional. The name of your application or website
100
+ "sourceLink" Optional. Link to your application or website
101
+ "date" Optional. In GMT. Any parsable format. Cannot be in the future.
102
+ "tags" Optional. Comma separate tags
103
+ "autopost" Optional. 0 or 1.
104
+ "private" Optional. 0 or 1.
105
+
106
+ * UNIMPLEMENTED FIELDS - These will likely be implemented in a future release
107
+
108
+ "media" Optional. File data. Multiple files OK
109
+
73
110
  == REQUIREMENTS:
74
111
 
75
- * mechanize, & Mocha (For Tests)
112
+ * HTTPparty, & Mocha (For Tests)
76
113
 
77
114
  == INSTALL:
78
115
 
79
- * sudo gem install wordpress -include-dependencies
116
+ * sudo gem install posterous -include-dependencies
80
117
 
81
118
  == LICENSE:
82
119
 
data/Rakefile CHANGED
@@ -2,12 +2,11 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
- require './lib/wordpress.rb'
5
+ require './lib/posterous.rb'
6
6
 
7
- Hoe.new('wordpress', Wordpress::VERSION) do |p|
8
- # p.rubyforge_name = 'wordpressx' # if different than lowercase project name
7
+ Hoe.new('posterous', Posterous::VERSION) do |p|
9
8
  p.developer('Jordan Dobson', 'jordan.dobson@madebysquad.com')
10
- p.extra_deps = ['mechanize', 'mocha']
9
+ p.extra_deps = ['httparty', 'mocha']
11
10
  end
12
11
 
13
12
  # vim: syntax=Ruby
data/bin/posterous ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+
data/lib/posterous.rb ADDED
@@ -0,0 +1,109 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+
4
+ class PosterousAuthError < StandardError; end
5
+ class PosterousTagError < StandardError; end
6
+ class PosterousSiteError < StandardError; end
7
+
8
+ ###
9
+ ### FUTURE PLANS
10
+ ###
11
+ # * Include media with your post
12
+ # * Post only a media file and get a url for it back
13
+ # * Allow reading in posterous posts
14
+ # * Include more usage examples outside of readme
15
+
16
+ class Posterous
17
+
18
+ VERSION = '0.1.2'
19
+ DOMAIN = 'posterous.com'
20
+ POST_PATH = '/api/newpost'
21
+ AUTH_PATH = '/api/getsites'
22
+
23
+ include HTTParty
24
+ base_uri DOMAIN
25
+
26
+ attr_accessor :title, :body, :source, :source_url, :date, :tags
27
+ attr_reader :site_id, :private_post, :autopost
28
+
29
+ def initialize user, pass, site_id = nil
30
+ raise PosterousAuthError, 'Either Username or Password is blank and/or not a string.' if \
31
+ !user.is_a?(String) || !pass.is_a?(String) || user == "" || pass == ""
32
+ self.class.basic_auth user, pass
33
+ @site_id = site_id ? site_id.to_s : site_id
34
+ @source = @body = @title = @source_url = @date = @media = @tags = nil
35
+ end
36
+
37
+ def site_id= id
38
+ @site_id = id.to_s
39
+ end
40
+ def tags= ary
41
+ raise PosterousTagError, 'Tags must add from be in an array' if !ary.is_a?(Array)
42
+ @tags = ary.join(", ")
43
+ end
44
+
45
+ def valid_user?
46
+ res = get_account_info
47
+ return false unless res.is_a?(Hash)
48
+ res["stat"] == "ok" ? true : false
49
+ end
50
+
51
+ def has_site?
52
+ res = get_account_info
53
+ return false unless res.is_a?(Hash)
54
+ if res["site"].is_a?(Hash)
55
+ @site_id && @site_id == res["site"]["id"] || !@site_id ? true : false
56
+ elsif res["site"].is_a?(Array)
57
+ res["site"].each do |site|
58
+ return true if @site_id && @site_id == site["id"]
59
+ end
60
+ false
61
+ else
62
+ false
63
+ end
64
+ end
65
+
66
+ def get_primary_site
67
+ res = get_account_info
68
+ raise PosterousSiteError, "Couldn't find a primary site. Check login and password is valid." \
69
+ unless res.is_a?(Hash) && res["stat"] == "ok" && res["site"]
70
+ site_list = res["site"].is_a?(Array) ? res["site"] : [res["site"]]
71
+ site_list.each do |site|
72
+ return site["id"] if site["primary"] == "true"
73
+ end
74
+ return nil
75
+ end
76
+
77
+ def set_to_private
78
+ @private_post = 1
79
+ end
80
+
81
+ def set_to_autopost
82
+ @autopost = 1
83
+ end
84
+
85
+ def build_query
86
+ options = { :site_id => @site_id,
87
+ :autopost => @autopost,
88
+ :private => @private_post,
89
+ :date => @date,
90
+ :tags => @tags }
91
+
92
+ query = { :title => @title,
93
+ :body => @body,
94
+ :source => @source,
95
+ :sourceLink => @source_url }
96
+
97
+ options.delete_if { |k,v| !v }
98
+ query.merge!(options)
99
+ end
100
+
101
+ def get_account_info
102
+ self.class.post(AUTH_PATH, :query => {})["rsp"]
103
+ end
104
+
105
+ def add_post
106
+ self.class.post(POST_PATH, :query => build_query)
107
+ end
108
+
109
+ end
@@ -0,0 +1,414 @@
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.new(@e, @p)
12
+ @new_obj_with_id = Posterous.new(@e, @p, "174966")
13
+ @new_obj_with_bad_id = Posterous.new(@e, @p, "badID")
14
+ @new_obj_with_invalid_id = Posterous.new(@e, @p, "666")
15
+
16
+ @private_url_path = /[.]posterous[.]com\/private\//
17
+
18
+ @resp_ok ={ "rsp" => {
19
+ "site" => {
20
+ "name" => "ruby-posterous's posterous",
21
+ "primary" => "true", "private"=>"false",
22
+ "url" => "http://ruby-posterous.posterous.com",
23
+ "id" => "174966" },
24
+ "stat" => "ok" }}
25
+
26
+ @resp_fail ={ "rsp" => {
27
+ "err" => {
28
+ "msg" => "Invalid Posterous email or password",
29
+ "code" => "3001" },
30
+ "stat" => "fail" }}
31
+
32
+ @resp_ok_2_sites ={ "rsp" => {
33
+ "site" => [{
34
+ "name" => "ruby-posterous's posterous",
35
+ "primary" => "false",
36
+ "private" => "false",
37
+ "url" => "http://ruby-posterous.posterous.com",
38
+ "id" => "174966"
39
+ }, {
40
+ "name" => "uw-ruby",
41
+ "primary" => "true",
42
+ "private" => "false",
43
+ "url" => "http://uwruby.posterous.com",
44
+ "id" => "175260" }],
45
+ "stat" => "ok" }}
46
+
47
+ @good_response ={ "site" => {
48
+ "name" => "ruby-posterous's posterous",
49
+ "primary" => "true",
50
+ "private" => "false",
51
+ "url" => "http://ruby-posterous.posterous.com",
52
+ "id" => "174966" },
53
+ "stat" => "ok" }
54
+
55
+ @good_response_2_sites ={ "rsp" => {
56
+ "site" => [{
57
+ "name" => "ruby-posterous's posterous",
58
+ "primary" => "true",
59
+ "private" => "false",
60
+ "url" => "http://ruby-posterous.posterous.com",
61
+ "id" => "174966"
62
+ }, {
63
+ "name" => "uw-ruby",
64
+ "primary" => "false",
65
+ "private" => "false",
66
+ "url" => "http://uwruby.posterous.com",
67
+ "id" => "175260" }],
68
+ "stat" => "ok" }}
69
+
70
+ @bad_response ={ "err" => {
71
+ "msg" => "Invalid Posterous email or password",
72
+ "code" => "3001" },
73
+ "stat" => "fail" }
74
+
75
+ @post_success ={ "rsp" => {
76
+ "post" => {
77
+ "title" => "Untitled",
78
+ "url" => "http://post.ly/dFW",
79
+ "id" => "848898",
80
+ "longurl" => "http://glue.posterous.com/687985" },
81
+ "stat" => "ok" }}
82
+
83
+ @post_title_success ={"rsp" => {
84
+ "post" => {
85
+ "title" => "My Title",
86
+ "url" => "http://post.ly/dFW",
87
+ "id" => "848898",
88
+ "longurl" => "http://glue.posterous.com/687985" },
89
+ "stat" => "ok" }}
90
+
91
+ @post_invalid_site ={ "rsp" => {
92
+ "err" => {
93
+ "msg" => "Invalid site id",
94
+ "code" => "3002" },
95
+ "stat" => "fail" }}
96
+
97
+ @post_access_error ={ "rsp" => {
98
+ "err" => {
99
+ "msg" => "User does not have access to this site",
100
+ "code" => "3003" },
101
+ "stat" => "fail" }}
102
+
103
+ @post_bad_account ={ "rsp" => {
104
+ "err" => {
105
+ "msg" => "Invalid Posterous email or password",
106
+ "code" => "3001" },
107
+ "stat" => "fail" }}
108
+
109
+ @post_private_good ={ "rsp" => {
110
+ "post" => {
111
+ "title" => "Posterous test",
112
+ "url" => "http://post.ly/gxK",
113
+ "id" => "891064",
114
+ "longurl" => "http://glue.posterous.com/private/tGIEAateBy" },
115
+ "stat" => "ok" }}
116
+ end
117
+
118
+ def test_raises_if_username_is_blank
119
+ assert_raise PosterousAuthError do
120
+ Posterous.new('', @p)
121
+ end
122
+ end
123
+
124
+ def test_raises_if_password_is_blank
125
+ assert_raise PosterousAuthError do
126
+ Posterous.new(@e, '')
127
+ end
128
+ end
129
+
130
+ def test_raises_if_password_is_not_srting
131
+ assert_raise PosterousAuthError do
132
+ Posterous.new(@e, 666)
133
+ end
134
+ end
135
+
136
+ def test_raises_if_username_is_not_srting
137
+ assert_raise PosterousAuthError do
138
+ Posterous.new(666, @p)
139
+ end
140
+ end
141
+
142
+ def test_site_id_can_be_witheld
143
+ actual = Posterous.new(@e, @p)
144
+ assert_equal nil, actual.site_id
145
+ end
146
+
147
+ def test_site_id_can_be_provided
148
+ actual = Posterous.new(@e, @p, '174966')
149
+ assert_equal '174966', actual.site_id
150
+ end
151
+
152
+ def test_site_id_is_converted_to_string
153
+ actual = Posterous.new(@e, @p, 174966)
154
+ assert_equal '174966', actual.site_id
155
+ end
156
+
157
+ def test_user_is_valid
158
+ Posterous.stubs(:post).returns(@resp_ok)
159
+ assert_equal true, @new_obj.valid_user?
160
+ end
161
+
162
+ def test_user_is_invalid
163
+ Posterous.stubs(:post).returns(@resp_fail)
164
+ assert_equal false, @new_obj.valid_user?
165
+ end
166
+
167
+ def test_user_is_invalid_when_response_isnt_hash
168
+ Posterous.stubs(:post).returns("666")
169
+ assert_equal false, @new_obj.valid_user?
170
+ end
171
+
172
+ def test_ping_success_hash_adjustment
173
+ Posterous.stubs(:post).returns(@resp_ok)
174
+ assert_equal @good_response, @new_obj.get_account_info
175
+ end
176
+
177
+ def test_ping_fail_hash_adjustment
178
+ Posterous.stubs(:post).returns(@resp_fail)
179
+ assert_equal @bad_response, @new_obj.get_account_info
180
+ end
181
+
182
+ def test_has_site_is_successful
183
+ Posterous.stubs(:post).returns(@resp_ok)
184
+ assert_equal true, @new_obj.has_site?
185
+ end
186
+
187
+ def test_has_site_successful_if_site_id_matches_only_result
188
+ Posterous.stubs(:post).returns(@resp_ok_2_sites)
189
+ assert_equal true, @new_obj_with_id.has_site?
190
+ end
191
+
192
+ def test_has_site_fails_if_site_id_doesnt_match_only_result
193
+ Posterous.stubs(:post).returns(@resp_ok)
194
+ assert_equal false, @new_obj_with_bad_id.has_site?
195
+ end
196
+
197
+ def test_has_site_is_successful_on_multiple_when_specified
198
+ Posterous.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.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.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.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.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_single_is_correctly
233
+ @new_obj.tags = ["Glue"]
234
+ assert_equal @new_obj.tags, "Glue"
235
+ end
236
+
237
+ def test_tags_single_is_correctly_joined
238
+ @new_obj.tags = ["Glue", "Posterous", "Ruby on Rails"]
239
+ assert_equal @new_obj.tags, "Glue, Posterous, Ruby on Rails"
240
+ end
241
+
242
+ def test_raises_if_tags_not_set_as_array
243
+ assert_raise PosterousTagError do
244
+ @new_obj.tags = "hello, "
245
+ end
246
+ end
247
+
248
+ def test_gets_primary_single_site
249
+ Posterous.stubs(:post).returns(@resp_ok)
250
+ assert_equal @resp_ok["rsp"]["site"]["id"], @new_obj.get_primary_site
251
+ end
252
+
253
+ def test_gets_primary_site_from_multiple_listing
254
+ Posterous.stubs(:post).returns(@resp_ok_2_sites)
255
+ assert_equal @resp_ok_2_sites["rsp"]["site"][1]["id"], @new_obj.get_primary_site
256
+ end
257
+
258
+ def test_gets_primary_site_raises_on_error
259
+ Posterous.stubs(:post).returns(@resp_fail)
260
+ assert_raise PosterousSiteError do
261
+ @new_obj.get_primary_site
262
+ end
263
+ end
264
+
265
+ def test_gets_primary_site_is_passed_to_overide_site_id
266
+ Posterous.stubs(:post).returns(@resp_ok_2_sites)
267
+ original = @new_obj_with_id.site_id
268
+ @new_obj_with_id.site_id = @new_obj_with_id.get_primary_site
269
+ updated = @new_obj_with_id.site_id
270
+ assert_not_equal original, updated
271
+ assert_equal @resp_ok_2_sites["rsp"]["site"][1]["id"], updated
272
+ end
273
+
274
+ def test_gets_primary_site_is_set_to_site_id
275
+ Posterous.stubs(:post).returns(@resp_ok)
276
+ original = @new_obj.site_id
277
+ @new_obj.site_id = @new_obj.get_primary_site
278
+ updated = @new_obj_with_id.site_id
279
+ assert_not_equal original, updated
280
+ assert_equal @resp_ok["rsp"]["site"]["id"], updated
281
+ end
282
+
283
+ def test_gets_primary_site_is_set_to_site_id
284
+ Posterous.stubs(:post).returns(@resp_ok)
285
+ original = @new_obj.site_id
286
+ @new_obj.site_id = @new_obj.get_primary_site
287
+ updated = @new_obj_with_id.site_id
288
+ assert_not_equal original, updated
289
+ assert_equal @resp_ok["rsp"]["site"]["id"], updated
290
+ end
291
+
292
+ def test_builds_query_without_site_id
293
+ expected = { :source => nil, :title => nil, :body => nil, :sourceLink => nil}
294
+ assert_equal expected, @new_obj.build_query
295
+ end
296
+
297
+ def test_builds_query_with_site_id
298
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :site_id => "174966", :title => nil }
299
+ assert_equal expected, @new_obj_with_id.build_query
300
+ end
301
+
302
+ def test_builds_query_with_all_fields_set_without_site_id
303
+ @new_obj.title = "My Title"
304
+ @new_obj.body = "My Body"
305
+ @new_obj.source = "The Tubes"
306
+ @new_obj.source_url = "http://TheTubes.com"
307
+ expected = { :source => "The Tubes", :body => "My Body", :sourceLink => "http://TheTubes.com", :title => "My Title" }
308
+ assert_equal expected, @new_obj.build_query
309
+ end
310
+
311
+ def test_builds_query_with_date_option
312
+ date = Time.now
313
+ @new_obj.date = date
314
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :title => nil, :date => date }
315
+ assert_equal expected, @new_obj.build_query
316
+ end
317
+
318
+ def test_builds_query_with_private_option
319
+ @new_obj.set_to_private
320
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :title => nil, :private => 1 }
321
+ assert_equal expected, @new_obj.build_query
322
+ end
323
+
324
+ def test_builds_query_with_autopost_option
325
+ @new_obj.set_to_autopost
326
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :title => nil, :autopost => 1 }
327
+ assert_equal expected, @new_obj.build_query
328
+ end
329
+
330
+ def test_builds_query_with_site_id
331
+ @new_obj.site_id = 20
332
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :site_id => "20", :title => nil }
333
+ assert_equal expected, @new_obj.build_query
334
+ end
335
+
336
+ def test_builds_query_with_all_options_set
337
+ date = Time.now
338
+ @new_obj.date = date
339
+ @new_obj.site_id = 20
340
+ @new_obj.set_to_private
341
+ expected = { :source => nil, :body => nil, :sourceLink => nil, :site_id => "20", :title => nil, :private => 1, :date => date }
342
+ assert_equal expected, @new_obj.build_query
343
+ end
344
+
345
+ def test_builds_query_with_all_fields_set_and_site_id
346
+ @new_obj_with_id.title = "My Title"
347
+ @new_obj_with_id.body = "My Body"
348
+ @new_obj_with_id.source = "The Tubes"
349
+ @new_obj_with_id.source_url = "http://TheTubes.com"
350
+ expected = { :source => "The Tubes", :body => "My Body", :sourceLink => "http://TheTubes.com", :site_id => "174966", :title => "My Title" }
351
+ assert_equal expected, @new_obj_with_id.build_query
352
+ end
353
+
354
+ def test_add_post_successful
355
+ Posterous.stubs(:post).returns(@post_success)
356
+ expected = @post_success
357
+ assert_equal expected, @new_obj.add_post
358
+ end
359
+
360
+ def test_add_post_successful_no_content
361
+ Posterous.stubs(:post).returns(@post_success)
362
+ actual = @new_obj.add_post
363
+ assert actual["rsp"]["post"].is_a?(Hash)
364
+ assert_equal "ok", actual["rsp"]["stat"]
365
+ assert_equal "Untitled", actual["rsp"]["post"]["title"]
366
+ end
367
+
368
+ def test_add_post_successful_with_title_content
369
+ Posterous.stubs(:post).returns(@post_title_success)
370
+ @new_obj.title = "My Title"
371
+ actual = @new_obj.add_post
372
+ assert_equal "My Title", actual["rsp"]["post"]["title"]
373
+ end
374
+
375
+ def test_add_post_invalid_site_id_fails
376
+ Posterous.stubs(:post).returns(@post_invalid_site)
377
+ actual = @new_obj_with_bad_id.add_post
378
+ assert_equal "fail", actual["rsp"]["stat"]
379
+ assert_equal nil, actual["rsp"]["post"]
380
+ assert_equal "Invalid site id", actual["rsp"]["err"]["msg"]
381
+ end
382
+
383
+ def test_add_post_no_access_fails
384
+ Posterous.stubs(:post).returns(@post_access_error)
385
+ actual = @new_obj_with_invalid_id.add_post
386
+ assert_equal "fail", actual["rsp"]["stat"]
387
+ assert_equal nil, actual["rsp"]["post"]
388
+ assert_match "not have access", actual["rsp"]["err"]["msg"]
389
+ end
390
+
391
+ def test_add_post_invalid_account_info
392
+ Posterous.stubs(:post).returns(@post_bad_account)
393
+ actual = Posterous.new("666", "666").add_post
394
+ assert_equal "fail", actual["rsp"]["stat"]
395
+ assert_equal nil, actual["rsp"]["post"]
396
+ assert_match "Invalid Posterous", actual["rsp"]["err"]["msg"]
397
+ end
398
+
399
+ def test_add_post_is_private_by_default
400
+ Posterous.stubs(:post).returns(@post_success)
401
+ actual = @new_obj.add_post
402
+ assert_equal "ok", actual["rsp"]["stat"]
403
+ assert_no_match @private_url_path, actual["rsp"]["post"]["longurl"]
404
+ end
405
+
406
+ def test_add_post_is_made_private
407
+ Posterous.stubs(:post).returns(@post_private_good)
408
+ @new_obj.set_to_private
409
+ actual = @new_obj.add_post
410
+ assert_equal "ok", actual["rsp"]["stat"]
411
+ assert_match @private_url_path, actual["rsp"]["post"]["longurl"]
412
+ end
413
+
414
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jordandobson-posterous
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Dobson
@@ -9,8 +9,8 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-05 00:00:00 -07:00
13
- default_executable: wordpress
12
+ date: 2009-05-29 00:00:00 -07:00
13
+ default_executable: posterous
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: hoe
@@ -22,7 +22,7 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.8.3
24
24
  version:
25
- description: The Wordpress gem provides posting to a Wordpress.com blog or a self hosted wordpress by provided your username, password, login url(if you host your blog) and your blog content.
25
+ description: The Posterous gem provides posting to Posterous.com using your email, password, site id(if you have multiple sites) and your blog content.
26
26
  email:
27
27
  - jordan.dobson@madebysquad.com
28
28
  executables: []
@@ -38,11 +38,11 @@ files:
38
38
  - Manifest.txt
39
39
  - README.txt
40
40
  - Rakefile
41
- - bin/wordpress
42
- - lib/wordpress.rb
43
- - test/test_wordpress.rb
44
- has_rdoc: false
45
- homepage: http://github.com/jordandobson/wordpress/tree/master
41
+ - bin/posterous
42
+ - lib/posterous.rb
43
+ - test/test_posterous.rb
44
+ has_rdoc: true
45
+ homepage: http://github.com/jordandobson/posterous/tree/master
46
46
  post_install_message:
47
47
  rdoc_options:
48
48
  - --main
@@ -63,10 +63,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
63
  version:
64
64
  requirements: []
65
65
 
66
- rubyforge_project: wordpress
66
+ rubyforge_project: posterous
67
67
  rubygems_version: 1.2.0
68
68
  signing_key:
69
69
  specification_version: 2
70
- summary: "The Wordpress gem provides posting to a Wordpress.com blog or a self hosted wordpress by provided your username, password, login url(if you host your blog) and your blog content. With this gem, you have access to add a text entry on Wordpress blug by providing these options: a title, body, and tags. You must include at least a title or body for your post."
70
+ 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 post a title, body text, posting source and a source link to Posterous. Posting images and pulling down your posts will be available soon. They were made available a day before this was completed.
71
71
  test_files:
72
- - test/test_wordpress.rb
72
+ - test/test_posterous.rb
data/bin/wordpress DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- abort "you need to write me"
data/lib/wordpress.rb DELETED
@@ -1,99 +0,0 @@
1
- require 'rubygems'
2
- require 'mechanize'
3
-
4
- module Wordpress
5
-
6
- VERSION = '0.1.1'
7
-
8
- class AuthError < StandardError; end
9
- class PostError < StandardError; end
10
-
11
- class Client
12
-
13
- DEFAULT_URL = 'http://wordpress.com/wp-login.php'
14
- LOGIN_FORM = 'loginform'
15
- POST_FORM = 'post'
16
- IS_ADMIN = 'body.wp-admin'
17
- IS_LOGIN = 'body.login'
18
-
19
- attr_accessor :title, :body
20
- attr_reader :login_url, :username, :password, :tags, :post_url
21
-
22
- def initialize usr, pwd, login_url = DEFAULT_URL
23
- raise AuthError, "Blank Username or Password or not a string." \
24
- if !usr.is_a?(String) || !pwd.is_a?(String) || usr == '' || pwd == ''
25
-
26
- raise AuthError, "Url should end with wp-login.php" \
27
- unless login_url =~ /\/wp-login[.]php$/
28
-
29
- @username = usr
30
- @password = pwd
31
- @login_url = login_url
32
- @agent = nil
33
- @post_url = nil
34
- end
35
-
36
- def tags= ary
37
- raise TagError, 'Tags must added using an array' if !ary.is_a?(Array)
38
- @tags = ary.join(", ")
39
- end
40
-
41
- def valid_login_page?
42
- lf = login_page.form(LOGIN_FORM)
43
- lf && lf.log ? true : false
44
- end
45
-
46
- def valid_user?
47
- logged_into? dashboard_page
48
- end
49
-
50
- def blog_url
51
- a = dashboard_page.search("#{IS_ADMIN} #wphead h1 a")
52
- return a.first['href'] if a.first && a.first['href']
53
- nil
54
- end
55
-
56
- def add_post
57
- post_form = dashboard_page.form(POST_FORM)
58
- raise PostError, "Missing QuickPress form on users dashboard page." unless post_form
59
- raise PostError, "A post requires a title or body." if !@title && !@body
60
- post_form = build_post(post_form)
61
- build_response @agent.submit(post_form, post_form.buttons.last)
62
- end
63
-
64
- private
65
-
66
- def login_page
67
- @agent = WWW::Mechanize.new #if !@agent
68
- @agent.get @login_url
69
- end
70
-
71
- def dashboard_page
72
- page = login_page
73
- login_form = page.form(LOGIN_FORM)
74
- if login_form
75
- login_form.log = @username
76
- login_form.pwd = @password
77
- page = @agent.submit login_form
78
- end
79
- page
80
- end
81
-
82
- def logged_into? page
83
- !page.search(IS_ADMIN).empty?
84
- end
85
-
86
- def build_post f
87
- f.post_title = @title
88
- f.content = @body
89
- f.tags_input = @tags
90
- f
91
- end
92
-
93
- def build_response page
94
- return true
95
- #get preview url & if it's not there send back error response
96
- end
97
-
98
- end
99
- end
@@ -1,133 +0,0 @@
1
- require "test/unit"
2
- require "wordpress"
3
- #
4
-
5
- ######
6
- # USED TO TEST PRIVATE METHODS
7
- class Class
8
- def private_methods
9
- m = self.private_instance_methods
10
- self.class_eval { public(*m) }
11
- yield
12
- self.class_eval { private(*m) }
13
- end
14
- end
15
-
16
-
17
- class TestWordpress < Test::Unit::TestCase
18
-
19
- def setup
20
- @u = 'jordandobson'
21
- @p = 'password'
22
-
23
- @account = Wordpress::Client.new @u, @p
24
- @account_bad = Wordpress::Client.new @u, 'x'
25
- @account_invalid_login_page = Wordpress::Client.new @u, @p, 'http://is.gd/wp-login.php'
26
-
27
- @admin_pg = Nokogiri::HTML( Nokogiri::HTML::Builder.new { html { body( :class => 'wp-admin') } }.to_html )
28
- @login_pg = Nokogiri::HTML( Nokogiri::HTML::Builder.new { html { body( :class => 'login' ) } }.to_html )
29
- end
30
-
31
- def test_sets_account_info_on_initialize
32
- actual = Wordpress::Client.new @u, @p
33
- assert_equal [@u, @p], [actual.username, actual.password]
34
- end
35
-
36
- def test_raises_if_username_is_blank
37
- assert_raise Wordpress::AuthError do
38
- Wordpress::Client.new "", @p
39
- end
40
- end
41
-
42
- def test_raises_if_password_is_blank
43
- assert_raise Wordpress::AuthError do
44
- Wordpress::Client.new @u, ""
45
- end
46
- end
47
-
48
- def test_raises_if_password_is_not_srting
49
- assert_raise Wordpress::AuthError do
50
- Wordpress::Client.new @u, 00
51
- end
52
- end
53
-
54
- def test_raises_if_username_is_not_srting
55
- assert_raise Wordpress::AuthError do
56
- Wordpress::Client.new 00, @p
57
- end
58
- end
59
-
60
- def test_login_url_uses_default_if_witheld
61
- assert_equal Wordpress::Client::DEFAULT_URL, @account.login_url
62
- end
63
-
64
- def test_uses_url_does_not_raise
65
- assert_equal 'http://is.gd/wp-login.php', @account_invalid_login_page.login_url
66
- end
67
-
68
- def test_raises_on_bad_login_url
69
- assert_raise Wordpress::AuthError do
70
- Wordpress::Client.new @u, @p, 'http://bad.login/url.php'
71
- end
72
- end
73
-
74
- def test_login_page_is_valid
75
- actual = Wordpress::Client.new @u, @p
76
- assert_equal true, actual.valid_login_page?
77
- end
78
-
79
- def test_login_page_is_invalid
80
- assert_equal false, @account_invalid_login_page.valid_login_page?
81
- end
82
-
83
- def test_is_a_valid_user
84
- assert_equal true, @account.valid_user?
85
- end
86
-
87
- def test_is_an_invalid_user
88
- assert_equal false, @account_bad.valid_user?
89
- end
90
-
91
- def test_is_a_valid_hosted_user
92
- account = Wordpress::Client.new('nonbreakablespace', 'Password1', 'http://blog.nonbreakablespace.com/wp-login.php')
93
- assert_equal true, account.valid_user?
94
- end
95
- def test_returns_blog_url
96
- expected = 'http://blog.nonbreakablespace.com/'
97
- account = Wordpress::Client.new('nonbreakablespace', 'Password1', "#{expected}wp-login.php")
98
- assert_equal expected, account.blog_url
99
- # Need to stub dashboard_page
100
- end
101
-
102
- def test_returns_blog_url_bad
103
- account = Wordpress::Client.new(@u, @p, 'http://is.gd/wp-login.php')
104
- assert_nil account.blog_url
105
- end
106
-
107
- def test_private_logged_in_is_true
108
- Wordpress::Client.private_methods { assert_equal true, @account.logged_into?(@admin_pg) }
109
- end
110
-
111
- def test_private_logged_in_is_false
112
- Wordpress::Client.private_methods { assert_equal false, @account.logged_into?(@login_pg) }
113
- end
114
-
115
- def test_add_post_raises_without_title_or_body
116
- assert_raise Wordpress::PostError do
117
- @account.add_post
118
- end
119
- end
120
-
121
- def test_add_post_raises_without_post_form
122
- assert_raise Wordpress::PostError do
123
- @account_bad.add_post
124
- end
125
- end
126
-
127
- def test_add_post_adds_post
128
- @account.title = Time.now
129
- @account.body = "updated next"
130
- @account.add_post
131
- end
132
-
133
- end