social_net 0.2.19 → 0.2.20
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 +4 -4
- data/README.md +103 -2
- data/lib/social_net/byte/api/configuration.rb +13 -0
- data/lib/social_net/byte/api/request.rb +71 -0
- data/lib/social_net/byte/config.rb +16 -0
- data/lib/social_net/byte/errors/response_error.rb +14 -0
- data/lib/social_net/byte/errors/unknown_post.rb +11 -0
- data/lib/social_net/byte/errors/unknown_user.rb +11 -0
- data/lib/social_net/byte/errors.rb +3 -0
- data/lib/social_net/byte/models/post.rb +66 -0
- data/lib/social_net/byte/models/user.rb +99 -0
- data/lib/social_net/byte/models.rb +2 -0
- data/lib/social_net/byte.rb +11 -0
- data/lib/social_net/version.rb +1 -1
- data/lib/social_net.rb +1 -0
- data/spec/social_net/byte/post_spec.rb +53 -0
- data/spec/social_net/byte/user_spec.rb +105 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_find_by_/given_an_existing_case-sensitive_username/returns_an_object_representing_that_user.yml +46 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_find_by_/given_an_unknown_username/.yml +45 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_find_by_id/given_an_existing_case-sensitive_ID/returns_an_object_representing_that_user.yml +46 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_find_by_id/given_an_unknown_ID/.yml +45 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_find_by_username/given_an_existing_case-insensitive_username/returns_an_object_representing_that_user.yml +46 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_find_by_username/given_an_unknown_username/.yml +45 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_posts/given_an_existing_user_with_no_posts/returns_an_empty_array_from_the_user.yml +129 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_posts/given_an_existing_user_with_paginated_posts/returns_an_array_of_video_posts_from_the_user.yml +175 -0
- data/spec/support/cassettes/SocialNet_Byte_Models_User/_posts/given_an_existing_user_with_posts/returns_an_array_of_video_posts_from_the_user.yml +132 -0
- metadata +35 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8f46909af7e663139816f04602accdab974ff58f69f2a12dbc0f070b43de3d2
|
4
|
+
data.tar.gz: a5045b140e87e1aedac869ce985ca80e6e694cdff52a9c9e4c6c513c0d0282e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e744faaf31d17afaca10e52e588609d63a9554c41fac6716bec42f9af0dd3a602aee7a94ba51c85774125f7ed138594aa49637afca5faa2fa606e52d1cbc956
|
7
|
+
data.tar.gz: 0ad5e30ada6dc472a0c91cdded05584d58c54b0e451656bc4c0ab3867cb8d78aef001f4b165177c131083c886aefffe5fb14187fbcf86bcceabbdf90cd7103e3
|
data/README.md
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
SocialNet - a Ruby client for social networks API
|
2
2
|
===========================================
|
3
3
|
|
4
|
-
SocialNet helps you write apps that need to interact with Twitter,
|
4
|
+
SocialNet helps you write apps that need to interact with Instagram, Byte, Twitter, and Facebook.
|
5
5
|
|
6
|
-
## Note: Only Instagram works at the moment
|
6
|
+
## Note: Only Instagram and Byte works at the moment
|
7
|
+
|
8
|
+
After [configuring your Byte app](#configuring-your-byte-app), you can run commands like:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
user = SocialNet::Byte::User.find_by username: 'ollie'
|
12
|
+
user.username #=> "ollie"
|
13
|
+
user.follower_count #=> 300
|
14
|
+
```
|
7
15
|
|
8
16
|
After [configuring your Twitter app](#configuring-your-twitter-app), you can run commands like:
|
9
17
|
|
@@ -115,6 +123,65 @@ video.link #=> 'https://www.instagram.com/p/BW-nC7xg8ZX/'
|
|
115
123
|
video.file #=> 'https://scontent.cdninstagram.com/t50.2886-16/20372137_156190564936990_2601958215176421376_n.mp4'
|
116
124
|
```
|
117
125
|
|
126
|
+
SocialNet::Byte::User
|
127
|
+
--------------------
|
128
|
+
|
129
|
+
Use [SocialNet::Byte::User]() to:
|
130
|
+
|
131
|
+
* retrieve a Byte user by username
|
132
|
+
* retrieve a Byte user by id
|
133
|
+
* retrieve posts of a Byte user
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
user = SocialNet::Byte::User.find_by username: 'ollie'
|
137
|
+
user.follower_count #=> 0
|
138
|
+
|
139
|
+
user = SocialNet::Byte::User.find_by id: 'PUEMKGYDBFAZ3HSRSAFGBAI5HA'
|
140
|
+
user.follower_count #=> 0
|
141
|
+
|
142
|
+
user.posts #=>
|
143
|
+
# {:posts=>
|
144
|
+
# [#<SocialNet::Byte::Models::Post:0x00007fb71b8705a8
|
145
|
+
# @author_id="PUEMKGYDBFAZ3HSRSAFGBAI5HA",
|
146
|
+
# @caption="i’m in ya house (ft. @Tishsimmonds)",
|
147
|
+
# @category="comedy",
|
148
|
+
# @comment_count=110,
|
149
|
+
# @date=1580391236,
|
150
|
+
# @id="WZPPQ5LQJZAAHP4BWFLM6PRBNM",
|
151
|
+
# @like_count=2439,
|
152
|
+
# @loop_count=34891,
|
153
|
+
# @thumb_src="https://e6k9t9a9.stackpathcdn.com/videos/5VVTQ4TTZBCRRHWDUPIZNUWDKM.jpg",
|
154
|
+
# @video_src="https://e6k9t9a9.stackpathcdn.com/videos/5VVTQ4TTZBCRRHWDUPIZNUWDKM-h264.mp4">],
|
155
|
+
# :next_page=>"CXWZB7CTMYLTA"}
|
156
|
+
|
157
|
+
user.posts(next_page: 'CXWZB7CTMYLTA') #=>
|
158
|
+
# {:posts=>
|
159
|
+
# [#<SocialNet::Byte::Models::Post:0x00007fb718468788
|
160
|
+
# @author_id="PUEMKGYDBFAZ3HSRSAFGBAI5HA",
|
161
|
+
# @caption="pov of a hungry person thinking byte is a delivery food app",
|
162
|
+
# @category="comedy",
|
163
|
+
# @comment_count=95,
|
164
|
+
# @date=1580043689,
|
165
|
+
# @id="PNHNHKO3RZF2HJVHSD64V4X3LE",
|
166
|
+
# @like_count=2605,
|
167
|
+
# @loop_count=23982,
|
168
|
+
# @share_url="https://byte.co/b/B69eUGbPcDM",
|
169
|
+
# @thumb_src="https://e6k9t9a9.stackpathcdn.com/videos/XRIRCMQZGBAUDLCWUJQPHGYYEE.jpg",
|
170
|
+
# @video_src="https://e6k9t9a9.stackpathcdn.com/videos/XRIRCMQZGBAUDLCWUJQPHGYYEE-h264.mp4">,
|
171
|
+
# :next_page=>"CXWPROPUQCCNQ"}
|
172
|
+
```
|
173
|
+
|
174
|
+
Use [SocialNet::Byte::Post]() to:
|
175
|
+
|
176
|
+
* retrieve a Byte post by id
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
post = SocialNet::Byte::Post.find_by id: 'WZPPQ5LQJZAAHP4BWFLM6PRBNM'
|
180
|
+
|
181
|
+
post.caption #=> "i’m in ya house (ft. @Tishsimmonds)"
|
182
|
+
post.video_src #=> "https://e6k9t9a9.stackpathcdn.com/videos/5VVTQ4TTZBCRRHWDUPIZNUWDKM-h264.mp4"
|
183
|
+
```
|
184
|
+
|
118
185
|
SocialNet::Facebook::Page
|
119
186
|
--------------------
|
120
187
|
|
@@ -223,6 +290,40 @@ end
|
|
223
290
|
so use the approach that you prefer.
|
224
291
|
If a variable is set in both places, then `SocialNet::Instagram.configure` takes precedence.
|
225
292
|
|
293
|
+
Configuring your Byte app
|
294
|
+
============================
|
295
|
+
|
296
|
+
Once the app is created, copy your access token and add it to your
|
297
|
+
code with the following snippet of code (replacing with your own access token)
|
298
|
+
:
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
SocialNet::Byte.configure do |config|
|
302
|
+
config.access_token = 'abcdefg'
|
303
|
+
end
|
304
|
+
```
|
305
|
+
|
306
|
+
Configuring with environment variables
|
307
|
+
--------------------------------------
|
308
|
+
|
309
|
+
As an alternative to the approach above, you can configure your app with
|
310
|
+
a variable. Setting the following environment variable:
|
311
|
+
|
312
|
+
```bash
|
313
|
+
export BYTE_ACCESS_TOKEN='abcdefg'
|
314
|
+
```
|
315
|
+
|
316
|
+
is equivalent to configuring your app with the initializer:
|
317
|
+
|
318
|
+
```ruby
|
319
|
+
SocialNet::Byte.configure do |config|
|
320
|
+
config.access_token = 'abcdefg'
|
321
|
+
end
|
322
|
+
```
|
323
|
+
|
324
|
+
so use the approach that you prefer.
|
325
|
+
If a variable is set in both places, then `SocialNet::Byte.configure` takes precedence.
|
326
|
+
|
226
327
|
Configuring your Facebook app
|
227
328
|
============================
|
228
329
|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'social_net/byte/errors/response_error'
|
2
|
+
require 'social_net/byte/errors/unknown_user'
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/core_ext'
|
5
|
+
|
6
|
+
module SocialNet
|
7
|
+
module Byte
|
8
|
+
module Api
|
9
|
+
class Request
|
10
|
+
def initialize(attrs = {})
|
11
|
+
@host = 'api.byte.co'
|
12
|
+
@username = attrs[:username]
|
13
|
+
@endpoint = attrs.fetch :endpoint, "/account/id/#{@username}/posts"
|
14
|
+
@block = attrs.fetch :block, -> (request) {add_access_token_and_cursor! request}
|
15
|
+
@next_page = attrs[:next_page] if attrs[:next_page]
|
16
|
+
@method = attrs.fetch :method, :get
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
print "#{as_curl}\n"
|
21
|
+
case response = run_http_request
|
22
|
+
when Net::HTTPOK
|
23
|
+
JSON response.body
|
24
|
+
else
|
25
|
+
raise Errors::ResponseError, response
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def run_http_request
|
32
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
33
|
+
http.request http_request
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def http_request
|
38
|
+
http_class = "Net::HTTP::#{@method.capitalize}".constantize
|
39
|
+
@http_request ||= http_class.new(uri.request_uri).tap do |request|
|
40
|
+
@block.call request
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def uri
|
45
|
+
@uri ||= URI::HTTPS.build host: @host, path: @endpoint, query: query
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_access_token_and_cursor!(request)
|
49
|
+
request.add_field 'Authorization', SocialNet::Byte.configuration.access_token
|
50
|
+
end
|
51
|
+
|
52
|
+
def query
|
53
|
+
{}.tap do |query|
|
54
|
+
query.merge! cursor: @next_page if @next_page
|
55
|
+
end.to_param
|
56
|
+
end
|
57
|
+
|
58
|
+
def as_curl
|
59
|
+
'curl'.tap do |curl|
|
60
|
+
curl << " -X #{http_request.method}"
|
61
|
+
http_request.each_header do |name, value|
|
62
|
+
curl << %Q{ -H "#{name}: #{value}"}
|
63
|
+
end
|
64
|
+
curl << %Q{ -d '#{http_request.body}'} if http_request.body
|
65
|
+
curl << %Q{ "#{@uri.to_s}"}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'social_net/byte/api/configuration'
|
2
|
+
|
3
|
+
module SocialNet
|
4
|
+
module Byte
|
5
|
+
module Config
|
6
|
+
def configure
|
7
|
+
yield configuration if block_given?
|
8
|
+
end
|
9
|
+
|
10
|
+
def configuration
|
11
|
+
@configuration ||= Api::Configuration.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'social_net/byte/api/request'
|
2
|
+
require 'social_net/byte/errors'
|
3
|
+
|
4
|
+
module SocialNet
|
5
|
+
module Byte
|
6
|
+
module Models
|
7
|
+
class Post
|
8
|
+
attr_reader :id,
|
9
|
+
:author_id,
|
10
|
+
:caption,
|
11
|
+
:category,
|
12
|
+
:mentions,
|
13
|
+
:date,
|
14
|
+
:video_src,
|
15
|
+
:thumb_src,
|
16
|
+
:comment_count,
|
17
|
+
:comments,
|
18
|
+
:like_count,
|
19
|
+
:loop_count
|
20
|
+
|
21
|
+
def initialize(attrs = {})
|
22
|
+
attrs.each{|k, v| instance_variable_set("@#{k}", v) unless v.nil?}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the existing Byte post matching the provided attributes or
|
26
|
+
# nil when the post is not found.
|
27
|
+
#
|
28
|
+
# @return [SocialNet::Byte::Models::post] when the post is found.
|
29
|
+
# @return [nil] when the post is not found.
|
30
|
+
# @param [Hash] params the attributes to find a post by.
|
31
|
+
# @option params [String] :id The Byte post’s id
|
32
|
+
# (case-insensitive).
|
33
|
+
def self.find_by(params = {})
|
34
|
+
find_by! params
|
35
|
+
rescue Errors::UnknownPost
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the existing Byte post matching the provided attributes or
|
40
|
+
# nil when the post is not found, and raises an error when the post is not found.
|
41
|
+
#
|
42
|
+
# @return [SocialNet::Byte::Models::Post] the Byte post.
|
43
|
+
# @param [Hash] params the attributes to find a post by.
|
44
|
+
# @option params [String] :id The Byte post id
|
45
|
+
# (case-sensitive).
|
46
|
+
# @raise [SocialNet::Errors::UnknownPost] if the post is unknown.
|
47
|
+
def self.find_by!(params = {})
|
48
|
+
if params[:id]
|
49
|
+
find_by_id! params[:id]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def self.find_by_id!(id)
|
56
|
+
request = Api::Request.new endpoint: "/post/id/#{id}"
|
57
|
+
if post = request.run['data']
|
58
|
+
new post.deep_transform_keys { |key| key.underscore.to_sym }
|
59
|
+
else
|
60
|
+
raise Errors::UnknownPost
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'social_net/byte/api/request'
|
2
|
+
require 'social_net/byte/errors'
|
3
|
+
|
4
|
+
module SocialNet
|
5
|
+
module Byte
|
6
|
+
module Models
|
7
|
+
class User
|
8
|
+
attr_reader :id,
|
9
|
+
:avatar_url,
|
10
|
+
:bio,
|
11
|
+
:display_name,
|
12
|
+
:follower_count,
|
13
|
+
:following_count,
|
14
|
+
:username,
|
15
|
+
:registration_date
|
16
|
+
|
17
|
+
def initialize(attrs = {})
|
18
|
+
attrs.each{|k, v| instance_variable_set("@#{k}", v) unless v.nil?}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the existing Byte user's most recent posts
|
22
|
+
#
|
23
|
+
# @return [SocialNet::Byte::Models::Post] when the posts are found.
|
24
|
+
# @ param [Hash] params the attributes to find paginated posts by.
|
25
|
+
# @option params [String] :next_page The next page of paginated posts.
|
26
|
+
def posts(opts={})
|
27
|
+
params = {endpoint: "/account/id/#{@id}/posts"}.merge! opts
|
28
|
+
request = Api::Request.new params
|
29
|
+
posts_data = request.run
|
30
|
+
{}.tap do |k,v|
|
31
|
+
k[:posts] = posts_data['data']['posts'].map{|post| Post.new post.deep_transform_keys { |key| key.underscore.to_sym }}
|
32
|
+
k[:next_page] = posts_data['data']['cursor']
|
33
|
+
end
|
34
|
+
rescue Errors::ResponseError => error
|
35
|
+
case error.response
|
36
|
+
when Net::HTTPBadRequest then raise Errors::UnknownUser
|
37
|
+
when Net::HTTPNotFound then raise Errors::UnknownUser
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the existing Byte user matching the provided attributes or
|
42
|
+
# nil when the user is not found.
|
43
|
+
#
|
44
|
+
# @return [SocialNet::Byte::Models::User] when the user is found.
|
45
|
+
# @return [nil] when the user is not found.
|
46
|
+
# @param [Hash] params the attributes to find a user by.
|
47
|
+
# @option params [String] :username The Byte user’s username
|
48
|
+
# (case-insensitive).
|
49
|
+
# @option params [String] :id The Byte user’s id
|
50
|
+
# (case-insensitive).
|
51
|
+
def self.find_by(params = {})
|
52
|
+
find_by! params
|
53
|
+
rescue Errors::UnknownUser
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the existing Byte user matching the provided attributes or
|
58
|
+
# nil when the user is not found, and raises an error when the user account is private.
|
59
|
+
#
|
60
|
+
# @return [SocialNet::Byte::Models::User] the Byte user.
|
61
|
+
# @param [Hash] params the attributes to find a user by.
|
62
|
+
# @option params [String] :username The Byte user’s username
|
63
|
+
# (case-insensitive).
|
64
|
+
# @option params [String] :id The Byte user’s id
|
65
|
+
# (case-insensitive).
|
66
|
+
# @raise [SocialNet::Errors::UnknownUser] if the user account is unknown.
|
67
|
+
def self.find_by!(params = {})
|
68
|
+
if params[:username]
|
69
|
+
find_by_username! params[:username]
|
70
|
+
elsif params[:id]
|
71
|
+
find_by_id! params[:id]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def self.find_by_username!(username)
|
78
|
+
request = Api::Request.new endpoint: "/account/prefix/#{username}"
|
79
|
+
response = request.run
|
80
|
+
users = response['data']['accounts']
|
81
|
+
if user = users.find{|u| u['username'].casecmp(username).zero?}
|
82
|
+
new user.transform_keys { |key| key.underscore.to_sym }
|
83
|
+
else
|
84
|
+
raise Errors::UnknownUser
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.find_by_id!(id)
|
89
|
+
request = Api::Request.new endpoint: "/account/id/#{id}"
|
90
|
+
if user = request.run['data']
|
91
|
+
new user.transform_keys { |key| key.underscore.to_sym }
|
92
|
+
else
|
93
|
+
raise Errors::UnknownUser
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/social_net/version.rb
CHANGED
data/lib/social_net.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'social_net/byte'
|
3
|
+
|
4
|
+
describe SocialNet::Byte::Post, :vcr do
|
5
|
+
before :all do
|
6
|
+
SocialNet::Byte.configure do |config|
|
7
|
+
if config.access_token.blank?
|
8
|
+
config.access_token = 'ACCESS_TOKEN'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:existing_post_id) { 'WZPPQ5LQJZAAHP4BWFLM6PRBNM' }
|
14
|
+
let(:nonexistant_post_id) { 'XAMM45LQJZNHHP4EWFLM6PMKIO' }
|
15
|
+
|
16
|
+
describe '.find_by id' do
|
17
|
+
subject(:post) { SocialNet::Byte::Post.find_by id: id }
|
18
|
+
|
19
|
+
context 'given an existing (case-sensitive) post id' do
|
20
|
+
let(:id) { existing_post_id }
|
21
|
+
|
22
|
+
it 'returns an object representing that post' do
|
23
|
+
expect(post.id).to eq 'WZPPQ5LQJZAAHP4BWFLM6PRBNM'
|
24
|
+
expect(post.comment_count).to be_an Integer
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'given a non-existant post id' do
|
29
|
+
let(:id) { nonexistant_post_id }
|
30
|
+
|
31
|
+
it { expect(post).to be_nil }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.find_by!' do
|
36
|
+
subject(:post) { SocialNet::Byte::Post.find_by! id: id }
|
37
|
+
|
38
|
+
context 'given an existing (case-sensitive) post id' do
|
39
|
+
let(:id) { existing_post_id }
|
40
|
+
|
41
|
+
it 'returns an object representing that post' do
|
42
|
+
expect(post.id).to eq 'WZPPQ5LQJZAAHP4BWFLM6PRBNM'
|
43
|
+
expect(post.comment_count).to be_an Integer
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'given a non-existant post id' do
|
48
|
+
let(:id) { nonexistant_post_id }
|
49
|
+
|
50
|
+
it { expect{post}.to raise_error SocialNet::Byte::UnknownPost }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'social_net/byte'
|
3
|
+
|
4
|
+
describe SocialNet::Byte::User, :vcr do
|
5
|
+
before :all do
|
6
|
+
SocialNet::Byte.configure do |config|
|
7
|
+
if config.access_token.blank?
|
8
|
+
config.access_token = 'ACCESS_TOKEN'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:existing_username) { 'ollie' }
|
14
|
+
let(:unknown_username) { '01LjqweoojkjR' }
|
15
|
+
let(:existing_user_id_with_no_posts) { 'EGDL2NQ6WRFQRBSY6Q5D5HWKHQ' }
|
16
|
+
let(:existing_id) { 'PUEMKGYDBFAZ3HSRSAFGBAI5HA' }
|
17
|
+
let(:unknown_id) { '123456' }
|
18
|
+
let(:existing_cursor) { 'CXWZB7CTMYLTA' }
|
19
|
+
|
20
|
+
describe '.find_by username' do
|
21
|
+
subject(:user) { SocialNet::Byte::User.find_by username: username }
|
22
|
+
|
23
|
+
context 'given an existing (case-insensitive) username' do
|
24
|
+
let(:username) { existing_username }
|
25
|
+
|
26
|
+
it 'returns an object representing that user' do
|
27
|
+
expect(user.username).to eq 'ollie'
|
28
|
+
expect(user.follower_count).to be_an Integer
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'given an unknown username' do
|
33
|
+
let(:username) { unknown_username }
|
34
|
+
it { expect(user).to be_nil }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '.find_by id' do
|
39
|
+
subject(:user) { SocialNet::Byte::User.find_by id: id }
|
40
|
+
|
41
|
+
context 'given an existing (case-sensitive) ID' do
|
42
|
+
let(:id) { existing_id }
|
43
|
+
|
44
|
+
it 'returns an object representing that user' do
|
45
|
+
expect(user.username).to eq 'ollie'
|
46
|
+
expect(user.follower_count).to be_an Integer
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'given an unknown ID' do
|
51
|
+
let(:id) { unknown_id }
|
52
|
+
it { expect(user).to be_nil }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '.find_by!' do
|
57
|
+
subject(:user) { SocialNet::Byte::User.find_by! username: username }
|
58
|
+
|
59
|
+
context 'given an existing (case-sensitive) username' do
|
60
|
+
let(:username) { existing_username }
|
61
|
+
|
62
|
+
it 'returns an object representing that user' do
|
63
|
+
expect(user.username).to eq 'ollie'
|
64
|
+
expect(user.follower_count).to be_an Integer
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'given an unknown username' do
|
69
|
+
let(:username) { unknown_username }
|
70
|
+
it { expect{user}.to raise_error SocialNet::Byte::UnknownUser }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '.posts' do
|
75
|
+
subject(:user) { SocialNet::Byte::User.find_by id: id }
|
76
|
+
context 'given an existing user with posts' do
|
77
|
+
let(:id) { existing_id }
|
78
|
+
|
79
|
+
it 'returns an array of video posts from the user' do
|
80
|
+
expect(user.posts[:posts]).to be_an Array
|
81
|
+
expect(user.posts[:posts].first).to be_an_instance_of SocialNet::Byte::Post
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'given an existing user with no posts' do
|
86
|
+
let(:id) { existing_user_id_with_no_posts }
|
87
|
+
|
88
|
+
it 'returns an empty array from the user' do
|
89
|
+
expect(user.posts[:posts]).to be_an Array
|
90
|
+
expect(user.posts[:posts]).to be_empty
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'given an existing user with paginated posts' do
|
95
|
+
let(:id) { existing_id }
|
96
|
+
let(:next_page) { existing_cursor }
|
97
|
+
|
98
|
+
it 'returns an array of video posts from the user' do
|
99
|
+
expect(user.posts({next_page: next_page})[:posts]).to be_an Array
|
100
|
+
expect(user.posts({next_page: next_page})[:posts].first).to be_an_instance_of SocialNet::Byte::Post
|
101
|
+
expect(user.posts({next_page: next_page})[:next_page]).not_to eq next_page
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|