buffer 0.0.1 → 0.1.0
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.
- checksums.yaml +7 -0
- data/.bufferapprc.template +23 -0
- data/.gitignore +6 -0
- data/.rubocop.yml +18 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/API_COVERAGE.md +19 -0
- data/Gemfile +1 -1
- data/Guardfile +10 -0
- data/{LICENSE → LICENSE.txt} +1 -1
- data/README.md +62 -80
- data/Rakefile +25 -1
- data/TODO.md +3 -0
- data/bin/buffer +35 -0
- data/buffer.gemspec +26 -16
- data/lib/buffer/client.rb +26 -0
- data/lib/buffer/core.rb +64 -0
- data/lib/buffer/datastructure.rb +18 -0
- data/lib/buffer/encode.rb +33 -0
- data/lib/buffer/error.rb +10 -0
- data/lib/buffer/info.rb +10 -0
- data/lib/buffer/link.rb +10 -0
- data/lib/buffer/profile.rb +27 -0
- data/lib/buffer/update.rb +75 -0
- data/lib/buffer/user.rb +9 -0
- data/lib/buffer/version.rb +1 -1
- data/lib/buffer.rb +16 -102
- data/spec/fixtures/destroy.txt +10 -0
- data/spec/fixtures/info.txt +10 -0
- data/spec/fixtures/interactions_by_update_id.txt +10 -0
- data/spec/fixtures/link.txt +12 -0
- data/spec/fixtures/profile_authenticated.txt +11 -0
- data/spec/fixtures/profile_schedules_by_id.txt +10 -0
- data/spec/fixtures/profiles_by_id.txt +10 -0
- data/spec/fixtures/update_by_id.txt +10 -0
- data/spec/fixtures/update_by_id_non_auth.txt +9 -0
- data/spec/fixtures/updates_by_profile_id.txt +10 -0
- data/spec/fixtures/updates_by_profile_id_pending.txt +10 -0
- data/spec/fixtures/user_authenticated.txt +19 -0
- data/spec/lib/buffer/encode_spec.rb +42 -0
- data/spec/lib/buffer/link_spec.rb +22 -0
- data/spec/lib/buffer/profile_spec.rb +87 -0
- data/spec/lib/buffer/schedule_spec.rb +80 -0
- data/spec/lib/buffer/update_spec.rb +227 -0
- data/spec/lib/buffer/user_spec.rb +26 -0
- data/spec/lib/buffer_spec.rb +30 -0
- data/spec/lib/core_spec.rb +60 -0
- data/spec/spec_helper.rb +171 -0
- metadata +215 -67
- data/spec/buffer_spec.rb +0 -354
- data/spec/fixtures/create_body.txt +0 -1
- data/spec/fixtures/success.json +0 -1
- data/spec/fixtures/user.json +0 -1
- data/spec/helper.rb +0 -43
@@ -0,0 +1,75 @@
|
|
1
|
+
module Buffer
|
2
|
+
class Client
|
3
|
+
module Update
|
4
|
+
def update_by_id(id, options = {})
|
5
|
+
check_id(id)
|
6
|
+
response = get("/updates/#{id}.json")
|
7
|
+
Buffer::Update.new(response)
|
8
|
+
end
|
9
|
+
|
10
|
+
def updates_by_profile_id(id, options = {})
|
11
|
+
status = options.fetch(:status) do
|
12
|
+
raise Buffer::Error::MissingStatus, "Include :pending or :sent in args"
|
13
|
+
end
|
14
|
+
options.delete(:status)
|
15
|
+
response = get("/profiles/#{id}/updates/#{status.to_s}.json", options)
|
16
|
+
updates = response['updates'].map { |r| Buffer::Update.new(r) }
|
17
|
+
Buffer::Updates.new (
|
18
|
+
{ total: response['total'],
|
19
|
+
updates: updates }
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def interactions_by_update_id(id, options = {})
|
24
|
+
check_id(id)
|
25
|
+
response = get("/updates/#{id}/interactions.json", options)
|
26
|
+
interactions = response['interactions'].map do |r|
|
27
|
+
Buffer::Interaction.new(r)
|
28
|
+
end
|
29
|
+
Buffer::Interactions.new(
|
30
|
+
{ total: response['total'], interactions: interactions }
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def reorder_updates(profile_id, options = {})
|
35
|
+
options.fetch(:order) { raise ArgumentError }
|
36
|
+
post("/profiles/#{profile_id}/updates/reorder.json", body: options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def shuffle_updates(profile_id, options = {})
|
40
|
+
post("/profiles/#{profile_id}/updates/shuffle.json",
|
41
|
+
body: options)
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_update(options = {})
|
45
|
+
options[:body].fetch(:text) do
|
46
|
+
raise ArgumentError, "Must include text for update"
|
47
|
+
end
|
48
|
+
options[:body].fetch(:profile_ids) do
|
49
|
+
raise ArgumentError, "Must include array of profile_ids"
|
50
|
+
end
|
51
|
+
post("/updates/create.json", options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def modify_update_text(update_id, options = {})
|
55
|
+
options[:body].fetch(:text) do
|
56
|
+
raise ArgumentError, "Must include updated text"
|
57
|
+
end
|
58
|
+
post("/updates/#{update_id}/update.json", options)
|
59
|
+
end
|
60
|
+
|
61
|
+
def share_update(update_id)
|
62
|
+
post("/updates/#{update_id}/share.json")
|
63
|
+
end
|
64
|
+
|
65
|
+
def destroy_update(update_id)
|
66
|
+
post("/updates/#{update_id}/destroy.json")
|
67
|
+
end
|
68
|
+
|
69
|
+
def check_id(id)
|
70
|
+
raise Buffer::Error::InvalidIdLength unless id.length == 24
|
71
|
+
raise Buffer::Error::InvalidIdContent unless id[/^[a-f0-9]+$/i]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/buffer/user.rb
ADDED
data/lib/buffer/version.rb
CHANGED
data/lib/buffer.rb
CHANGED
@@ -1,107 +1,21 @@
|
|
1
|
-
require 'buffer/version'
|
2
1
|
require 'faraday'
|
3
|
-
require '
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require 'json'
|
4
|
+
require 'hashie/mash'
|
4
5
|
require 'addressable/uri'
|
5
|
-
require '
|
6
|
-
|
7
|
-
module Buffer
|
8
|
-
class Client
|
9
|
-
|
10
|
-
attr_reader :token
|
11
|
-
|
12
|
-
# Initialize a new Buffer::Client
|
13
|
-
#
|
14
|
-
# Also sets up a Faraday connection object
|
15
|
-
#
|
16
|
-
# token - string access token for use with all API requests
|
17
|
-
def initialize(token)
|
18
|
-
if token.kind_of? String
|
19
|
-
@token = token
|
20
|
-
else
|
21
|
-
raise ArgumentError, "token must be a string"
|
22
|
-
end
|
23
|
-
|
24
|
-
@conn = Faraday.new :url => 'https://api.bufferapp.com/1/'
|
25
|
-
@addr = Addressable::URI.new
|
26
|
-
end
|
27
|
-
|
28
|
-
# get is a shorthand method for api :get
|
29
|
-
#
|
30
|
-
# uri - string endpoint uri
|
31
|
-
def get(uri)
|
32
|
-
api :get, uri
|
33
|
-
end
|
34
|
-
|
35
|
-
# post is a shorthand method for api :post
|
36
|
-
#
|
37
|
-
# uri - string endpoint uri
|
38
|
-
# data - hash or array for POST body
|
39
|
-
def post(uri, data = {})
|
40
|
-
api :post, uri, data
|
41
|
-
end
|
42
|
-
|
43
|
-
# api is the root method of the Client, handling all requests.
|
44
|
-
#
|
45
|
-
# type - HTTP verb, :get or :post
|
46
|
-
# url - enpoint uri, with or without .json
|
47
|
-
# data - hash or array of data to be sent in POST body
|
48
|
-
def api(type, uri, data = {})
|
49
|
-
uri << '.json' unless uri =~ /\.json$/
|
50
|
-
res = if type == :get
|
51
|
-
@conn.get uri, :access_token => @token
|
52
|
-
elsif type == :post
|
53
|
-
@conn.post do |req|
|
54
|
-
req.url uri, :access_token => @token
|
55
|
-
req.body = data.to_query
|
56
|
-
end
|
57
|
-
end
|
58
|
-
# Return nil if the body is less that 2 characters long,
|
59
|
-
# ie. '{}' is the minimum valid JSON, or if the decoder
|
60
|
-
# raises an exception when passed mangled JSON
|
61
|
-
begin
|
62
|
-
MultiJson.load res.body if res.body && res.body.length >= 2
|
63
|
-
rescue
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
6
|
+
require 'environs'
|
68
7
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
#
|
81
|
-
# Returns a hash of user data.
|
82
|
-
def user
|
83
|
-
@cache[:user] ||= get 'user'
|
84
|
-
end
|
85
|
-
|
86
|
-
public
|
87
|
-
|
88
|
-
# invalidate wipes the cache so that future requests
|
89
|
-
# rebuild it from server data
|
90
|
-
def invalidate
|
91
|
-
@cache = {}
|
92
|
-
end
|
93
|
-
|
94
|
-
# method_missing steps in to enable the helper methods
|
95
|
-
# by trying to get a particular key from self.user
|
96
|
-
#
|
97
|
-
# Returns the user data or the result of super
|
98
|
-
def method_missing(method, *args, &block)
|
99
|
-
user[method.to_s] || super
|
100
|
-
end
|
101
|
-
|
102
|
-
def respond_to?(name)
|
103
|
-
user.key_exist? name
|
104
|
-
end
|
8
|
+
require 'buffer/version'
|
9
|
+
require 'buffer/core'
|
10
|
+
require 'buffer/user'
|
11
|
+
require 'buffer/profile'
|
12
|
+
require 'buffer/update'
|
13
|
+
require 'buffer/link'
|
14
|
+
require 'buffer/error'
|
15
|
+
require 'buffer/encode'
|
16
|
+
require 'buffer/datastructure'
|
17
|
+
require 'buffer/info'
|
18
|
+
require 'buffer/client'
|
105
19
|
|
106
|
-
|
20
|
+
module Buffer
|
107
21
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Wed, 15 May 2013 01:43:34 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 828
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
{"success":true,"message":"Update deleted successfully"}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Thu, 16 May 2013 22:05:18 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 2820
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
{"services":{"twitter":{"types":{"profile":{"name":"Twitter","character_limit":140,"schedule_limit":288,"icons":{"16":"http:\/\/static.bufferapp.com\/images\/services\/twitter-16x16.png","32":"http:\/\/static.bufferapp.com\/images\/services\/twitter-32x32.png","64":"http:\/\/static.bufferapp.com\/images\/services\/twitter-64x64.png"},"supported_interactions":["favorites","favorite","mentions","mention","retweets","retweet"]}},"urls":{"user":"https:\/\/twitter.com\/","hashtag":"https:\/\/twitter.com\/#!\/search?q=%23","cashtag":"https:\/\/twitter.com\/#!\/search?q=%24"}},"facebook":{"types":{"profile":{"name":"Facebook","character_limit":5000,"schedule_limit":5,"icons":{"16":"http:\/\/static.bufferapp.com\/images\/services\/facebook-16x16.png","32":"http:\/\/static.bufferapp.com\/images\/services\/facebook-32x32.png","64":"http:\/\/static.bufferapp.com\/images\/services\/facebook-64x64.png"},"supported_interactions":["likes","like","comments","comment"]},"page":{"name":"Facebook Page","character_limit":5000,"schedule_limit":5,"icons":{"16":"http:\/\/static.bufferapp.com\/images\/services\/facebook-16x16.png","32":"http:\/\/static.bufferapp.com\/images\/services\/facebook-32x32.png","64":"http:\/\/static.bufferapp.com\/images\/services\/facebook-64x64.png"},"supported_interactions":["likes","like","comments","comment"]}},"urls":{"user":"https:\/\/www.facebook.com\/"}},"linkedin":{"types":{"profile":{"name":"LinkedIn","character_limit":700,"schedule_limit":25,"icons":{"16":"http:\/\/static.bufferapp.com\/images\/services\/linkedin-16x16.png","32":"http:\/\/static.bufferapp.com\/images\/services\/linkedin-32x32.png","64":"http:\/\/static.bufferapp.com\/images\/services\/linkedin-64x64.png"},"supported_interactions":["comments","comment","likes","like"]},"group":{"name":"LinkedIn Group","character_limit":200,"schedule_limit":100,"icons":{"16":"http:\/\/static.bufferapp.com\/images\/services\/linkedin-16x16.png","32":"http:\/\/static.bufferapp.com\/images\/services\/linkedin-32x32.png","64":"http:\/\/static.bufferapp.com\/images\/services\/linkedin-64x64.png"},"supported_interactions":["comments","comment","likes","like"]}},"urls":{"user":"http:\/\/www.linkedin.com\/search\/fpsearch?type=people&keywords="}},"appdotnet":{"types":{"profile":{"name":"App.net","character_limit":256,"schedule_limit":288,"icons":{"16":"http:\/\/static.bufferapp.com\/images\/services\/appdotnet-alpha-16x16.png","32":"http:\/\/static.bufferapp.com\/images\/services\/appdotnet-alpha2-32x32.png","64":"http:\/\/static.bufferapp.com\/images\/services\/appdotnet-alpha-64x64.png"},"supported_interactions":[]}},"urls":{"user":"https:\/\/alpha.app.net\/","hashtag":"https:\/\/alpha.app.net\/hashtags\/"}}},"media":{"picture_size_min":0,"picture_size_max":5242880,"picture_filetypes":["jpeg","jpg","gif","png"]}}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Fri, 17 May 2013 04:21:13 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 29
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
{"total":0,"interactions":[]}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Wed, 15 May 2013 01:43:34 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 828
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
{
|
11
|
+
"shares":47348
|
12
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Tue, 14 May 2013 05:02:18 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
X-Cache: Awwww Yea
|
7
|
+
x-frame-options: SAMEORIGIN
|
8
|
+
Content-Length: 845
|
9
|
+
Connection: keep-alive
|
10
|
+
|
11
|
+
[{"_id":"5160746d13f04a5e3a00000f","avatar":"http:\/\/a0.twimg.com\/profile_images\/3604112130.jpeg","avatar_https":"https:\/\/twimg0-a.akamaihd.net\/profile_images\/3604112130.jpeg","counts":{"pending":1,"sent":40},"created_at":1365275757,"default":true,"disconnected":null,"formatted_service":"Twitter","formatted_username":"@example","id":"5160746d13d04a5e3a00000f","quick_signin":true,"schedules":[{"days":["mon","tue","wed","thu","fri","sat","sun"],"times":["06:13","09:10","11:58","12:17","13:49","18:07","21:04","22:13"]}],"service":"twitter","service_id":"737649619","service_type":"profile","service_username":"example","statistics":{"followers":179},"timezone":"America\/New_York","user_id":"5160746d13d04a5e3a00000d","utm_tracking":"enabled","verb":"tweet"}]
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Wed, 15 May 2013 01:53:50 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 128
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
[{"days":["mon","tue","wed","thu","fri","sat","sun"],"times":["06:13","09:10","11:58","12:17","13:49","18:07","21:04","22:13"]}]
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Wed, 15 May 2013 01:43:34 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 828
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
{"_id":"5160746d13d04a5e3a00000f","avatar":"http:\/\/a0.twimg.com\/profile_images\/3604112130.jpeg","avatar_https":"https:\/\/twimg0-a.akamaihd.net\/profile_images\/3604112130.jpeg","counts":{"pending":1,"sent":46},"created_at":1365275757,"disconnected":null,"formatted_service":"Twitter","formatted_username":"@example","id":"5160746d13d04a5e3a00000f","quick_signin":true,"schedules":[{"days":["mon","tue","wed","thu","fri","sat","sun"],"times":["06:13","09:10","11:58","12:17","13:49","18:07","21:04","22:13"]}],"service":"twitter","service_id":"737649619","service_type":"profile","service_username":"example","statistics":{"followers":179},"timezone":"America\/New_York","user_id":"5160746d13d04a5e3a00000d","utm_tracking":"enabled","verb":"tweet"}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Wed, 15 May 2013 01:43:34 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 828
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
{"id":"4eb8565e0acb04bb82000004","created_at":1320703582,"day":"Monday 7th November","due_at":1320742680,"due_time":"10:09 pm","profile_id":"4eb854340acb04e870000010","profile_service":"twitter","sent_at":1320744001,"service_update_id":"133667319959392256","statistics":{"reach":2460,"clicks":56,"retweets":20,"favorites":1,"mentions":1},"status":"sent","text":"This is just the beginning, the very beginning, of the transfor...","text_formatted":"This is just the beginning, the very beginning, of th...","user_id":"4eb9276e0acb04bb81000067","via":"chrome"}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
HTTP/1.1 401 Authorization Required
|
2
|
+
Content-Type: text/html; charset=UTF-8
|
3
|
+
Date: Fri, 17 May 2013 02:46:37 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
WWW-Authenticate: OAuth realm='Service', error='invalid_request', error_description='The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed.'
|
7
|
+
Content-Length: 0
|
8
|
+
Connection: keep-alive
|
9
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Wed, 15 May 2013 01:43:34 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 828
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
{"total":8,"updates":[{"id":"4ec93ae4512f7e6307000002","created_at":1320703582,"day":"Monday 7th November","due_at":1320543480,"due_time":"07:01 pm","profile_id":"4eb854340acb04e870000010","profile_service":"twitter","status":"buffer","text":"This is me in an alternate life where i can breakdance j.mp/w...","text_formatted":"This is me in an alternate life where i can breakda...","user_id":"4eb9276e0acb04bb81000067","via":"firefox"},] }
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 Awesome
|
2
|
+
Content-Type: application/json;charset=UTF-8
|
3
|
+
Date: Thu, 16 May 2013 04:48:14 GMT
|
4
|
+
Server: Apache
|
5
|
+
Vary: Accept-Encoding,User-Agent
|
6
|
+
x-frame-options: SAMEORIGIN
|
7
|
+
Content-Length: 737
|
8
|
+
Connection: keep-alive
|
9
|
+
|
10
|
+
{"total":1,"updates":[{"_id":"519464f2872cad3734000028","created_at":1368679666,"day":"Today","due_at":1368699180,"due_time":"6:13 am","id":"519464f2872cad3734000028","profile_id":"5160746d13d04a5e3a00000f","profile_service":"twitter","shared_now":false,"status":"buffer","text":"Exciting to have even 1 person fork my fork of a repo :) jaysonlane\/buffer-ruby \u00b7 GitHub http:\/\/bit.ly\/15OS4ap","text_formatted":"Exciting to have even 1 person fork my fork of a repo :) jaysonlane\/buffer-ruby \u00b7 GitHub <a class=\"url\" href=\"http:\/\/bit.ly\/15OS4ap\" rel=\"external nofollow\" target=\"_blank\">http:\/\/bit.ly\/15OS4ap<\/a>","type":"link","updated_at":1368679666,"user_id":"5160746d54f04a5e3a00000d","via":"bookmarklet"}]}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Server: nginx/0.7.65
|
3
|
+
Date: Thu, 03 Mar 2011 19:25:34 GMT
|
4
|
+
Content-Type: application/json
|
5
|
+
Connection: keep-alive
|
6
|
+
Keep-Alive: timeout=20
|
7
|
+
Content-Length: 380
|
8
|
+
|
9
|
+
{
|
10
|
+
"_id":"4f0c0a06512f7ef214000000",
|
11
|
+
"activity_at":1343654640,
|
12
|
+
"created_at":1326189062,
|
13
|
+
"id":"4f0c0a06512f7ef214000000",
|
14
|
+
"plan":"free",
|
15
|
+
"referral_link":"http:\/\/bufferapp.com\/r\/abcde",
|
16
|
+
"referral_token":"abcde",
|
17
|
+
"secret_email":"supersecret@to.bufferapp.com",
|
18
|
+
"timezone":"Asia\/Tel_Aviv"
|
19
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Buffer::Encode do
|
4
|
+
|
5
|
+
context "successful code" do
|
6
|
+
|
7
|
+
let(:schedule_first) { { :days => ["mon", "tue", "wed", "thu"], :times => ["12:00", "13:00"]} }
|
8
|
+
let(:schedule_second) { { :days => ["sun", "sat"], :times => ["09:00", "24:00"]} }
|
9
|
+
let(:schedules_hash) { { schedules: [schedule_first, schedule_second] } }
|
10
|
+
let(:short_schedule) { { days: ["mon", "tue", "wed"], times: ["12:00", "17:00", "18:00"]} }
|
11
|
+
let(:short_schedule_encoded) { "[days][]=mon&[days][]=tue&[times][]=12%3A00&[times][]=13%3A00" }
|
12
|
+
let(:schedules_encoded) { "schedules[0][days][]=mon&schedules[0][days][]=tue&schedules[0][days][]=wed&schedules[0][times][]=12:00&schedules[0][times][]=17:00&schedules[0][times][]=18:00" }
|
13
|
+
let(:very_short_schedule) { { :days => ["sun", "sat"], :times => ["09:00", "24:00"]} }
|
14
|
+
|
15
|
+
|
16
|
+
describe "#encode"
|
17
|
+
it "converts to match Buffer API specs encoding" do
|
18
|
+
Buffer::Encode.encode([short_schedule]).
|
19
|
+
should eq(schedules_encoded.gsub(/:/, '%3A'))
|
20
|
+
end
|
21
|
+
|
22
|
+
it "processes an input array of schedules" do
|
23
|
+
Buffer::Encode.encode([very_short_schedule, very_short_schedule]).
|
24
|
+
should eq("schedules[0][days][]=sun&schedules[0][days][]=sat&schedules[0][times][]=09%3A00&schedules[0][times][]=24%3A00&schedules[1][days][]=sun&schedules[1][days][]=sat&schedules[1][times][]=09%3A00&schedules[1][times][]=24%3A00")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "includes index in conversion when multiple schedules present" do
|
28
|
+
Buffer::Encode.encode([very_short_schedule, very_short_schedule, very_short_schedule]).
|
29
|
+
should eq("schedules[0][days][]=sun&schedules[0][days][]=sat&schedules[0][times][]=09%3A00&schedules[0][times][]=24%3A00&schedules[1][days][]=sun&schedules[1][days][]=sat&schedules[1][times][]=09%3A00&schedules[1][times][]=24%3A00&schedules[2][days][]=sun&schedules[2][days][]=sat&schedules[2][times][]=09%3A00&schedules[2][times][]=24%3A00")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "processes an input hash" do
|
33
|
+
Buffer::Encode.encode({ schedules: [very_short_schedule, very_short_schedule, very_short_schedule] }).
|
34
|
+
should eq("schedules[0][days][]=sun&schedules[0][days][]=sat&schedules[0][times][]=09%3A00&schedules[0][times][]=24%3A00&schedules[1][days][]=sun&schedules[1][days][]=sat&schedules[1][times][]=09%3A00&schedules[1][times][]=24%3A00&schedules[2][days][]=sun&schedules[2][days][]=sat&schedules[2][times][]=09%3A00&schedules[2][times][]=24%3A00")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#encode_schedule_primary" do
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Buffer::Client do
|
4
|
+
describe "#link" do
|
5
|
+
let(:client) { Buffer::Client.new("some_token") }
|
6
|
+
let(:url) { %q{http://bufferapp.com} }
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_request(:get, "#{ base_path }/links/shares.json?#{ access_token_param }&url=http://bufferapp.com").
|
10
|
+
to_return(fixture('link.txt'))
|
11
|
+
end
|
12
|
+
|
13
|
+
it "connects to the correct endpoint" do
|
14
|
+
client.link({url: url})
|
15
|
+
end
|
16
|
+
|
17
|
+
it "parses the shares of a link" do
|
18
|
+
client.link({url: url}).shares.should eq(47348)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Buffer::Client::Profile do
|
4
|
+
let(:id) { "5160746d54f04a5e3a00000f" }
|
5
|
+
|
6
|
+
subject do
|
7
|
+
Buffer::Client.new("some_token")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#profiles" do
|
11
|
+
let(:rash) { Buffer::Client.new("some_token").profiles }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
url = "#{ base_path }/profiles.json"
|
15
|
+
stub_with_to_return(:get, url, 'profile_authenticated.txt')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "makes the correct url request" do
|
19
|
+
subject.profiles
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns a Rash collection object" do
|
23
|
+
rash[0].class.should eq(Buffer::Profile)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "provides an accessor for plan" do
|
27
|
+
rash[0].service.should eq("twitter")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#profile_by_id" do
|
32
|
+
let(:id) { "5160746d54f04a5e3a00000f" }
|
33
|
+
before(:each) do
|
34
|
+
url = "#{base_path}/profiles/#{id}.json"
|
35
|
+
fixture_name = "profiles_by_id.txt"
|
36
|
+
stub_with_to_return(:get, url, fixture_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:rash) { Buffer::Client.new("some_token").profile_by_id(id) }
|
40
|
+
|
41
|
+
it "returns a rash collection" do
|
42
|
+
rash.class.should eq(Buffer::Profile)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "accesses formatted service" do
|
46
|
+
rash.formatted_service.should eq("Twitter")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#schedules_by_profile_id" do
|
51
|
+
before(:each) do
|
52
|
+
url = "#{base_path}/profiles/#{id}/schedules.json"
|
53
|
+
fixture_name = 'profile_schedules_by_id.txt'
|
54
|
+
stub_with_to_return(:get, url, fixture_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:rash) { Buffer::Client.new("some_token").schedules_by_profile_id(id) }
|
58
|
+
|
59
|
+
it "returns a rash collection" do
|
60
|
+
rash[0].class.should eq(Buffer::Schedule)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "accesses days" do
|
64
|
+
expect(rash[0].days).to include("mon")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "accesses times" do
|
68
|
+
expect(rash[0].times).to include("06:13")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
describe "#info" do
|
74
|
+
before do
|
75
|
+
stub_request(:get, "#{base_path}/info/configuration.json?access_token=some_token").
|
76
|
+
to_return(fixture("info.txt"))
|
77
|
+
end
|
78
|
+
|
79
|
+
it "connects to the correct endpoint" do
|
80
|
+
subject.info
|
81
|
+
end
|
82
|
+
|
83
|
+
it "retrieves the correct name" do
|
84
|
+
subject.info.services.twitter.types.profile.name.should eq("Twitter")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Buffer::Schedules do
|
4
|
+
before do
|
5
|
+
@schedule = JSON.parse <<EOF
|
6
|
+
{
|
7
|
+
"days" : [
|
8
|
+
"mon",
|
9
|
+
"tue",
|
10
|
+
"wed",
|
11
|
+
"thu",
|
12
|
+
"fri"
|
13
|
+
],
|
14
|
+
"times" : [
|
15
|
+
"12:00",
|
16
|
+
"17:00",
|
17
|
+
"18:00"
|
18
|
+
]
|
19
|
+
}
|
20
|
+
EOF
|
21
|
+
|
22
|
+
@sample_schedules = JSON.parse <<EOF
|
23
|
+
{ "schedules" : [{
|
24
|
+
"days" : [
|
25
|
+
"mon",
|
26
|
+
"tue",
|
27
|
+
"wed",
|
28
|
+
"thu",
|
29
|
+
"fri"
|
30
|
+
],
|
31
|
+
"times" : [
|
32
|
+
"12:00",
|
33
|
+
"17:00",
|
34
|
+
"18:00"
|
35
|
+
]
|
36
|
+
},
|
37
|
+
{
|
38
|
+
"days" : [
|
39
|
+
"mon",
|
40
|
+
"tue",
|
41
|
+
"wed",
|
42
|
+
"thu",
|
43
|
+
"fri"
|
44
|
+
],
|
45
|
+
"times" : [
|
46
|
+
"12:00",
|
47
|
+
"17:00",
|
48
|
+
"18:00"
|
49
|
+
]
|
50
|
+
}]
|
51
|
+
}
|
52
|
+
EOF
|
53
|
+
end
|
54
|
+
|
55
|
+
it "accepts an array of days" do
|
56
|
+
lambda {
|
57
|
+
schedules = Buffer::Schedules.new
|
58
|
+
schedules << Buffer::Schedule.new
|
59
|
+
}.should_not raise_error
|
60
|
+
end
|
61
|
+
|
62
|
+
it "dumping a double schedule yields correct json" do
|
63
|
+
schedules = Buffer::Schedules.new
|
64
|
+
schedules << @schedule << @schedule
|
65
|
+
@sample_schedules = @sample_schedules.to_json
|
66
|
+
|
67
|
+
schedules.dump.should eq(@sample_schedules)
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#set_schedules" do
|
71
|
+
let(:id) { "5160746d54f04a5e3a00000f" }
|
72
|
+
it "throw error if schedules is empty" do
|
73
|
+
lambda {
|
74
|
+
Buffer::Client.new("some_token").set_schedules(id) }.
|
75
|
+
should raise_error(ArgumentError)
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|