glennr-posterous 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +30 -0
- data/Manifest.txt +7 -0
- data/README.txt +158 -0
- data/Rakefile +13 -0
- data/bin/posterous +2 -0
- data/lib/posterous.rb +146 -0
- data/test/test_posterous.rb +400 -0
- metadata +75 -0
data/History.txt
ADDED
@@ -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
|
+
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -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.
|
data/Rakefile
ADDED
@@ -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
|
data/bin/posterous
ADDED
data/lib/posterous.rb
ADDED
@@ -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
|