files.com 1.0.90
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTORS +4 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +82 -0
- data/LICENSE +21 -0
- data/README.md +119 -0
- data/Rakefile +12 -0
- data/SECURITY.md +24 -0
- data/_VERSION +1 -0
- data/bin/files +8 -0
- data/bin/files-console +16 -0
- data/docs/account_line_item.md +41 -0
- data/docs/action.md +37 -0
- data/docs/api_key.md +202 -0
- data/docs/app.md +57 -0
- data/docs/as2_key.md +133 -0
- data/docs/auto.md +11 -0
- data/docs/automation.md +190 -0
- data/docs/behavior.md +208 -0
- data/docs/bundle.md +252 -0
- data/docs/bundle_download.md +35 -0
- data/docs/clickwrap.md +143 -0
- data/docs/dns_record.md +35 -0
- data/docs/errors.md +17 -0
- data/docs/file.md +204 -0
- data/docs/file_action.md +126 -0
- data/docs/file_comment.md +116 -0
- data/docs/file_comment_reaction.md +62 -0
- data/docs/file_part_upload.md +37 -0
- data/docs/file_utils.md +4 -0
- data/docs/folder.md +90 -0
- data/docs/group.md +153 -0
- data/docs/group_user.md +124 -0
- data/docs/history.md +171 -0
- data/docs/history_export.md +174 -0
- data/docs/image.md +13 -0
- data/docs/invoice.md +72 -0
- data/docs/invoice_line_item.md +27 -0
- data/docs/ip_address.md +55 -0
- data/docs/lock.md +98 -0
- data/docs/message.md +147 -0
- data/docs/message_comment.md +132 -0
- data/docs/message_comment_reaction.md +94 -0
- data/docs/message_reaction.md +94 -0
- data/docs/notification.md +177 -0
- data/docs/payment.md +72 -0
- data/docs/payment_line_item.md +19 -0
- data/docs/permission.md +95 -0
- data/docs/preview.md +19 -0
- data/docs/project.md +121 -0
- data/docs/public_ip_address.md +13 -0
- data/docs/public_key.md +133 -0
- data/docs/remote_server.md +356 -0
- data/docs/request.md +100 -0
- data/docs/session.md +78 -0
- data/docs/site.md +448 -0
- data/docs/sso_strategy.md +114 -0
- data/docs/status.md +21 -0
- data/docs/style.md +93 -0
- data/docs/usage_daily_snapshot.md +45 -0
- data/docs/usage_snapshot.md +53 -0
- data/docs/user.md +535 -0
- data/docs/user_cipher_use.md +41 -0
- data/docs/user_request.md +93 -0
- data/files.com.gemspec +22 -0
- data/lib/files.com.rb +184 -0
- data/lib/files.com/api.rb +38 -0
- data/lib/files.com/api_client.rb +340 -0
- data/lib/files.com/errors.rb +41 -0
- data/lib/files.com/list.rb +95 -0
- data/lib/files.com/models/account_line_item.rb +82 -0
- data/lib/files.com/models/action.rb +77 -0
- data/lib/files.com/models/api_key.rb +270 -0
- data/lib/files.com/models/app.rb +101 -0
- data/lib/files.com/models/as2_key.rb +179 -0
- data/lib/files.com/models/auto.rb +17 -0
- data/lib/files.com/models/automation.rb +304 -0
- data/lib/files.com/models/behavior.rb +266 -0
- data/lib/files.com/models/bundle.rb +371 -0
- data/lib/files.com/models/bundle_download.rb +49 -0
- data/lib/files.com/models/clickwrap.rb +197 -0
- data/lib/files.com/models/dir.rb +3 -0
- data/lib/files.com/models/dns_record.rb +51 -0
- data/lib/files.com/models/errors.rb +22 -0
- data/lib/files.com/models/file.rb +968 -0
- data/lib/files.com/models/file_action.rb +126 -0
- data/lib/files.com/models/file_comment.rb +146 -0
- data/lib/files.com/models/file_comment_reaction.rb +100 -0
- data/lib/files.com/models/file_part_upload.rb +82 -0
- data/lib/files.com/models/file_utils.rb +118 -0
- data/lib/files.com/models/folder.rb +357 -0
- data/lib/files.com/models/group.rb +208 -0
- data/lib/files.com/models/group_user.rb +171 -0
- data/lib/files.com/models/history.rb +228 -0
- data/lib/files.com/models/history_export.rb +353 -0
- data/lib/files.com/models/image.rb +22 -0
- data/lib/files.com/models/invoice.rb +117 -0
- data/lib/files.com/models/invoice_line_item.rb +57 -0
- data/lib/files.com/models/ip_address.rb +66 -0
- data/lib/files.com/models/lock.rb +173 -0
- data/lib/files.com/models/message.rb +201 -0
- data/lib/files.com/models/message_comment.rb +165 -0
- data/lib/files.com/models/message_comment_reaction.rb +128 -0
- data/lib/files.com/models/message_reaction.rb +128 -0
- data/lib/files.com/models/notification.rb +263 -0
- data/lib/files.com/models/payment.rb +117 -0
- data/lib/files.com/models/payment_line_item.rb +37 -0
- data/lib/files.com/models/permission.rb +172 -0
- data/lib/files.com/models/preview.rb +37 -0
- data/lib/files.com/models/project.rb +140 -0
- data/lib/files.com/models/public_ip_address.rb +22 -0
- data/lib/files.com/models/public_key.rb +179 -0
- data/lib/files.com/models/remote_server.rb +680 -0
- data/lib/files.com/models/request.rb +179 -0
- data/lib/files.com/models/session.rb +247 -0
- data/lib/files.com/models/site.rb +733 -0
- data/lib/files.com/models/sso_strategy.rb +227 -0
- data/lib/files.com/models/status.rb +37 -0
- data/lib/files.com/models/style.rb +131 -0
- data/lib/files.com/models/usage_daily_snapshot.rb +66 -0
- data/lib/files.com/models/usage_snapshot.rb +96 -0
- data/lib/files.com/models/user.rb +876 -0
- data/lib/files.com/models/user_cipher_use.rb +63 -0
- data/lib/files.com/models/user_request.rb +127 -0
- data/lib/files.com/response.rb +25 -0
- data/lib/files.com/sizable_io.rb +32 -0
- data/lib/files.com/system_profiler.rb +56 -0
- data/lib/files.com/util.rb +106 -0
- data/lib/files.com/version.rb +5 -0
- data/spec/list_spec.rb +214 -0
- data/spec/models/file_spec.rb +68 -0
- data/spec/models/folder_spec.rb +40 -0
- data/spec/spec_helper.rb +36 -0
- data/test.sh +8 -0
- data/test/test.rb +75 -0
- metadata +235 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Files
|
4
|
+
class UserCipherUse
|
5
|
+
attr_reader :options, :attributes
|
6
|
+
|
7
|
+
def initialize(attributes = {}, options = {})
|
8
|
+
@attributes = attributes || {}
|
9
|
+
@options = options || {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# int64 - UserCipherUse ID
|
13
|
+
def id
|
14
|
+
@attributes[:id]
|
15
|
+
end
|
16
|
+
|
17
|
+
# string - The protocol and cipher employed
|
18
|
+
def protocol_cipher
|
19
|
+
@attributes[:protocol_cipher]
|
20
|
+
end
|
21
|
+
|
22
|
+
# date-time - The earliest recorded use of this combination of interface and protocol and cipher (for this user)
|
23
|
+
def created_at
|
24
|
+
@attributes[:created_at]
|
25
|
+
end
|
26
|
+
|
27
|
+
# string - The interface accessed
|
28
|
+
def interface
|
29
|
+
@attributes[:interface]
|
30
|
+
end
|
31
|
+
|
32
|
+
# date-time - The most recent use of this combination of interface and protocol and cipher (for this user)
|
33
|
+
def updated_at
|
34
|
+
@attributes[:updated_at]
|
35
|
+
end
|
36
|
+
|
37
|
+
# int64 - ID of the user who performed this access
|
38
|
+
def user_id
|
39
|
+
@attributes[:user_id]
|
40
|
+
end
|
41
|
+
|
42
|
+
# Parameters:
|
43
|
+
# user_id - int64 - User ID. Provide a value of `0` to operate the current session's user.
|
44
|
+
# page - int64 - Current page number.
|
45
|
+
# per_page - int64 - Number of records to show per page. (Max: 10,000, 1,000 or less is recommended).
|
46
|
+
# action - string - Deprecated: If set to `count` returns a count of matching records rather than the records themselves.
|
47
|
+
def self.list(params = {}, options = {})
|
48
|
+
raise InvalidParameterError.new("Bad parameter: user_id must be an Integer") if params.dig(:user_id) and !params.dig(:user_id).is_a?(Integer)
|
49
|
+
raise InvalidParameterError.new("Bad parameter: page must be an Integer") if params.dig(:page) and !params.dig(:page).is_a?(Integer)
|
50
|
+
raise InvalidParameterError.new("Bad parameter: per_page must be an Integer") if params.dig(:per_page) and !params.dig(:per_page).is_a?(Integer)
|
51
|
+
raise InvalidParameterError.new("Bad parameter: action must be an String") if params.dig(:action) and !params.dig(:action).is_a?(String)
|
52
|
+
|
53
|
+
response, options = Api.send_request("/user_cipher_uses", :get, params, options)
|
54
|
+
response.data.map do |entity_data|
|
55
|
+
UserCipherUse.new(entity_data, options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.all(params = {}, options = {})
|
60
|
+
list(params, options)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Files
|
4
|
+
class UserRequest
|
5
|
+
attr_reader :options, :attributes
|
6
|
+
|
7
|
+
def initialize(attributes = {}, options = {})
|
8
|
+
@attributes = attributes || {}
|
9
|
+
@options = options || {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# string - User's full name
|
13
|
+
def name
|
14
|
+
@attributes[:name]
|
15
|
+
end
|
16
|
+
|
17
|
+
def name=(value)
|
18
|
+
@attributes[:name] = value
|
19
|
+
end
|
20
|
+
|
21
|
+
# email - User email address
|
22
|
+
def email
|
23
|
+
@attributes[:email]
|
24
|
+
end
|
25
|
+
|
26
|
+
def email=(value)
|
27
|
+
@attributes[:email] = value
|
28
|
+
end
|
29
|
+
|
30
|
+
# string - Details of the user's request
|
31
|
+
def details
|
32
|
+
@attributes[:details]
|
33
|
+
end
|
34
|
+
|
35
|
+
def details=(value)
|
36
|
+
@attributes[:details] = value
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete(params = {})
|
40
|
+
params ||= {}
|
41
|
+
params[:id] = @attributes[:id]
|
42
|
+
raise MissingParameterError.new("Current object doesn't have a id") unless @attributes[:id]
|
43
|
+
raise InvalidParameterError.new("Bad parameter: id must be an Integer") if params.dig(:id) and !params.dig(:id).is_a?(Integer)
|
44
|
+
raise MissingParameterError.new("Parameter missing: id") unless params.dig(:id)
|
45
|
+
|
46
|
+
Api.send_request("/user_requests/#{@attributes[:id]}", :delete, params, @options)
|
47
|
+
end
|
48
|
+
|
49
|
+
def destroy(params = {})
|
50
|
+
delete(params)
|
51
|
+
end
|
52
|
+
|
53
|
+
def save
|
54
|
+
if @attributes[:id]
|
55
|
+
raise NotImplementedError.new("The UserRequest object doesn't support updates.")
|
56
|
+
else
|
57
|
+
new_obj = UserRequest.create(@attributes, @options)
|
58
|
+
@attributes = new_obj.attributes
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Parameters:
|
63
|
+
# page - int64 - Current page number.
|
64
|
+
# per_page - int64 - Number of records to show per page. (Max: 10,000, 1,000 or less is recommended).
|
65
|
+
# action - string - Deprecated: If set to `count` returns a count of matching records rather than the records themselves.
|
66
|
+
def self.list(params = {}, options = {})
|
67
|
+
raise InvalidParameterError.new("Bad parameter: page must be an Integer") if params.dig(:page) and !params.dig(:page).is_a?(Integer)
|
68
|
+
raise InvalidParameterError.new("Bad parameter: per_page must be an Integer") if params.dig(:per_page) and !params.dig(:per_page).is_a?(Integer)
|
69
|
+
raise InvalidParameterError.new("Bad parameter: action must be an String") if params.dig(:action) and !params.dig(:action).is_a?(String)
|
70
|
+
|
71
|
+
response, options = Api.send_request("/user_requests", :get, params, options)
|
72
|
+
response.data.map do |entity_data|
|
73
|
+
UserRequest.new(entity_data, options)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.all(params = {}, options = {})
|
78
|
+
list(params, options)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Parameters:
|
82
|
+
# id (required) - int64 - User Request ID.
|
83
|
+
def self.find(id, params = {}, options = {})
|
84
|
+
params ||= {}
|
85
|
+
params[:id] = id
|
86
|
+
raise InvalidParameterError.new("Bad parameter: id must be an Integer") if params.dig(:id) and !params.dig(:id).is_a?(Integer)
|
87
|
+
raise MissingParameterError.new("Parameter missing: id") unless params.dig(:id)
|
88
|
+
|
89
|
+
response, options = Api.send_request("/user_requests/#{params[:id]}", :get, params, options)
|
90
|
+
UserRequest.new(response.data, options)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.get(id, params = {}, options = {})
|
94
|
+
find(id, params, options)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Parameters:
|
98
|
+
# name (required) - string - Name of user requested
|
99
|
+
# email (required) - string - Email of user requested
|
100
|
+
# details (required) - string - Details of the user request
|
101
|
+
def self.create(params = {}, options = {})
|
102
|
+
raise InvalidParameterError.new("Bad parameter: name must be an String") if params.dig(:name) and !params.dig(:name).is_a?(String)
|
103
|
+
raise InvalidParameterError.new("Bad parameter: email must be an String") if params.dig(:email) and !params.dig(:email).is_a?(String)
|
104
|
+
raise InvalidParameterError.new("Bad parameter: details must be an String") if params.dig(:details) and !params.dig(:details).is_a?(String)
|
105
|
+
raise MissingParameterError.new("Parameter missing: name") unless params.dig(:name)
|
106
|
+
raise MissingParameterError.new("Parameter missing: email") unless params.dig(:email)
|
107
|
+
raise MissingParameterError.new("Parameter missing: details") unless params.dig(:details)
|
108
|
+
|
109
|
+
response, options = Api.send_request("/user_requests", :post, params, options)
|
110
|
+
UserRequest.new(response.data, options)
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.delete(id, params = {}, options = {})
|
114
|
+
params ||= {}
|
115
|
+
params[:id] = id
|
116
|
+
raise InvalidParameterError.new("Bad parameter: id must be an Integer") if params.dig(:id) and !params.dig(:id).is_a?(Integer)
|
117
|
+
raise MissingParameterError.new("Parameter missing: id") unless params.dig(:id)
|
118
|
+
|
119
|
+
response, _options = Api.send_request("/user_requests/#{params[:id]}", :delete, params, options)
|
120
|
+
response.data
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.destroy(id, params = {}, options = {})
|
124
|
+
delete(id, params, options)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Files
|
4
|
+
class Response
|
5
|
+
attr_accessor :data, :http_body, :http_headers, :http_status
|
6
|
+
|
7
|
+
def self.from_faraday_hash(http_resp)
|
8
|
+
resp = new
|
9
|
+
resp.data = JSON.parse(http_resp[:body], symbolize_names: true) if http_resp[:status] != 204
|
10
|
+
resp.http_body = http_resp[:body]
|
11
|
+
resp.http_headers = http_resp[:headers]
|
12
|
+
resp.http_status = http_resp[:status]
|
13
|
+
resp
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_faraday_response(http_resp)
|
17
|
+
resp = new
|
18
|
+
resp.data = JSON.parse(http_resp.body, symbolize_names: true) if http_resp.status != 204
|
19
|
+
resp.http_body = http_resp.body
|
20
|
+
resp.http_headers = http_resp.headers
|
21
|
+
resp.http_status = http_resp.status
|
22
|
+
resp
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Files
|
2
|
+
class SizableIO < IO
|
3
|
+
def self.pipe
|
4
|
+
r, w = super
|
5
|
+
|
6
|
+
w.instance_variable_set(:@read_io, r)
|
7
|
+
|
8
|
+
[ r, w ]
|
9
|
+
end
|
10
|
+
|
11
|
+
def size
|
12
|
+
read_io.content_length_promise.wait.value
|
13
|
+
end
|
14
|
+
|
15
|
+
def fulfill_content_length(length)
|
16
|
+
read_io.content_length = length
|
17
|
+
read_io.content_length_promise.execute
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
attr_accessor :content_length
|
23
|
+
|
24
|
+
def content_length_promise
|
25
|
+
@content_length_promise ||= Concurrent::Promise.new { content_length }
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_io
|
29
|
+
@read_io || self
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Files
|
4
|
+
class SystemProfiler
|
5
|
+
def self.uname
|
6
|
+
if ::File.exist?("/proc/version")
|
7
|
+
::File.read("/proc/version").strip
|
8
|
+
else
|
9
|
+
case RbConfig::CONFIG["host_os"]
|
10
|
+
when /linux|darwin|bsd|sunos|solaris|cygwin/i
|
11
|
+
uname_from_system
|
12
|
+
when /mswin|mingw/i
|
13
|
+
uname_from_system_ver
|
14
|
+
else
|
15
|
+
"unknown platform"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.uname_from_system
|
21
|
+
(`uname -a 2>/dev/null` || "").strip
|
22
|
+
rescue Errno::ENOENT
|
23
|
+
"uname executable not found"
|
24
|
+
rescue Errno::ENOMEM # couldn't create subprocess
|
25
|
+
"uname lookup failed"
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.uname_from_system_ver
|
29
|
+
(`ver` || "").strip
|
30
|
+
rescue Errno::ENOENT
|
31
|
+
"ver executable not found"
|
32
|
+
rescue Errno::ENOMEM # couldn't create subprocess
|
33
|
+
"uname lookup failed"
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
@uname = self.class.uname
|
38
|
+
end
|
39
|
+
|
40
|
+
def user_agent
|
41
|
+
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
|
42
|
+
|
43
|
+
{
|
44
|
+
application: Files.app_info,
|
45
|
+
bindings_version: Files::VERSION,
|
46
|
+
lang: "ruby",
|
47
|
+
lang_version: lang_version,
|
48
|
+
platform: RUBY_PLATFORM,
|
49
|
+
engine: defined?(RUBY_ENGINE) ? RUBY_ENGINE : "",
|
50
|
+
publisher: "Action Verb LLC",
|
51
|
+
uname: @uname,
|
52
|
+
hostname: Socket.gethostname,
|
53
|
+
}.delete_if { |_k, v| v.nil? }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Files
|
4
|
+
module Util
|
5
|
+
OPTS = Set[:api_key, :client, :session_id].freeze
|
6
|
+
COLOR_CODES = {
|
7
|
+
black: 0, light_black: 60,
|
8
|
+
red: 1, light_red: 61,
|
9
|
+
green: 2, light_green: 62,
|
10
|
+
yellow: 3, light_yellow: 63,
|
11
|
+
blue: 4, light_blue: 64,
|
12
|
+
magenta: 5, light_magenta: 65,
|
13
|
+
cyan: 6, light_cyan: 66,
|
14
|
+
white: 7, light_white: 67,
|
15
|
+
default: 9,
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def self.colorize(val, color, isatty)
|
19
|
+
return val unless isatty
|
20
|
+
|
21
|
+
mode = 0 # default
|
22
|
+
foreground = 30 + COLOR_CODES.fetch(color)
|
23
|
+
background = 40 + COLOR_CODES.fetch(:default)
|
24
|
+
|
25
|
+
"\033[#{mode};#{foreground};#{background}m#{val}\033[0m"
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.level_name(level)
|
29
|
+
case level
|
30
|
+
when LEVEL_DEBUG then "debug"
|
31
|
+
when LEVEL_ERROR then "error"
|
32
|
+
when LEVEL_INFO then "info"
|
33
|
+
else level
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.log_error(message, data = {})
|
38
|
+
if !Files.logger.nil? ||
|
39
|
+
!Files.log_level.nil? && Files.log_level <= Files::LEVEL_ERROR
|
40
|
+
log_internal(message, data, color: :cyan, level: Files::LEVEL_ERROR,
|
41
|
+
logger: Files.logger, out: $stderr
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.log_info(message, data = {})
|
47
|
+
if !Files.logger.nil? ||
|
48
|
+
!Files.log_level.nil? && Files.log_level <= Files::LEVEL_INFO
|
49
|
+
log_internal(message, data, color: :cyan, level: Files::LEVEL_INFO,
|
50
|
+
logger: Files.logger, out: $stdout
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.log_debug(message, data = {})
|
56
|
+
if !Files.logger.nil? ||
|
57
|
+
!Files.log_level.nil? && Files.log_level <= Files::LEVEL_DEBUG
|
58
|
+
log_internal(message, data, color: :blue, level: Files::LEVEL_DEBUG,
|
59
|
+
logger: Files.logger, out: $stdout
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.log_internal(message, data = {}, color: nil, level: nil,
|
65
|
+
logger: nil, out: nil)
|
66
|
+
data_str = data.reject { |_k, v| v.nil? }
|
67
|
+
.map do |(k, v)|
|
68
|
+
format("%<key>s=%<value>s",
|
69
|
+
key: colorize(k, color, logger.nil? && !out.nil? && out.isatty),
|
70
|
+
value: v
|
71
|
+
)
|
72
|
+
end.join(" ")
|
73
|
+
|
74
|
+
if !logger.nil?
|
75
|
+
# the library's log levels are mapped to the same values as the
|
76
|
+
# standard library's logger
|
77
|
+
logger.log(level,
|
78
|
+
format("message=%<message>s %<data_str>s",
|
79
|
+
message: message,
|
80
|
+
data_str: data_str
|
81
|
+
)
|
82
|
+
)
|
83
|
+
elsif out.isatty
|
84
|
+
out.puts format("%<level>s %<message>s %<data_str>s",
|
85
|
+
level: colorize(level_name(level)[0, 4].upcase,
|
86
|
+
color, out.isatty
|
87
|
+
),
|
88
|
+
message: message,
|
89
|
+
data_str: data_str
|
90
|
+
)
|
91
|
+
else
|
92
|
+
out.puts format("message=%<message>s level=%<level>s %<data_str>s",
|
93
|
+
message: message,
|
94
|
+
level: level_name(level),
|
95
|
+
data_str: data_str
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.check_api_key!(key)
|
101
|
+
raise TypeError, "api_key must be a string" unless key.is_a?(String)
|
102
|
+
|
103
|
+
key
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/spec/list_spec.rb
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Files::List do
|
4
|
+
ResourceWrapper = Struct.new(:object, :options)
|
5
|
+
let(:options) { { client: client } }
|
6
|
+
let(:client) { instance_double(Files::ApiClient, cursor: nil) }
|
7
|
+
let(:params) { {} }
|
8
|
+
|
9
|
+
describe "#auto_paging_each" do
|
10
|
+
context "when per_page is set" do
|
11
|
+
let(:params) { { per_page: per_page } }
|
12
|
+
let(:per_page) { 3 }
|
13
|
+
|
14
|
+
context "when response includes a cursor" do
|
15
|
+
let(:client) { instance_double(Files::ApiClient) }
|
16
|
+
let(:stubbed_cursors) {
|
17
|
+
[
|
18
|
+
'3',
|
19
|
+
'6',
|
20
|
+
nil
|
21
|
+
]
|
22
|
+
}
|
23
|
+
|
24
|
+
before do
|
25
|
+
allow(client).to receive(:cursor).and_return(*stubbed_cursors)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "does not call the API until out of responses" do
|
29
|
+
server_results = ('a'..'h').to_a
|
30
|
+
times_block_yielded = 0
|
31
|
+
request_cursor = nil
|
32
|
+
response_cursor = nil
|
33
|
+
|
34
|
+
list = described_class.new(ResourceWrapper, params) {
|
35
|
+
times_block_yielded += 1
|
36
|
+
request_cursor = params[:cursor]
|
37
|
+
range_start = params[:cursor] ? params[:cursor].to_i : 0
|
38
|
+
|
39
|
+
response_data = server_results[range_start, per_page]
|
40
|
+
response_cursor = (range_start + per_page).to_s
|
41
|
+
[
|
42
|
+
instance_double(Files::Response, data: response_data, http_status: 200, http_headers: { "x-files-cursor" => response_cursor }),
|
43
|
+
options
|
44
|
+
]
|
45
|
+
}
|
46
|
+
results = list.auto_paging_each
|
47
|
+
expect(results.class).to eq(Enumerator::Lazy)
|
48
|
+
expect(times_block_yielded).to eq(0)
|
49
|
+
expect(results.next.object).to eq('a')
|
50
|
+
expect(times_block_yielded).to eq(1)
|
51
|
+
expect(request_cursor).to eq(nil)
|
52
|
+
expect(results.next.object).to eq('b')
|
53
|
+
expect(results.next.object).to eq('c')
|
54
|
+
expect(results.next.object).to eq('d')
|
55
|
+
expect(times_block_yielded).to eq(2)
|
56
|
+
expect(request_cursor).to eq("3")
|
57
|
+
expect(results.next.object).to eq('e')
|
58
|
+
expect(results.next.object).to eq('f')
|
59
|
+
expect(results.next.object).to eq('g')
|
60
|
+
expect(results.next.object).to eq('h')
|
61
|
+
expect(times_block_yielded).to eq(3)
|
62
|
+
expect(request_cursor).to eq("6")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "stops calling the API once there is an error" do
|
66
|
+
server_results = ('a'..'h').to_a
|
67
|
+
times_block_yielded = 0
|
68
|
+
list = described_class.new(ResourceWrapper, params) {
|
69
|
+
times_block_yielded += 1
|
70
|
+
[
|
71
|
+
instance_double(Files::Response, data: server_results.shift(per_page), http_status: 400),
|
72
|
+
options
|
73
|
+
]
|
74
|
+
}
|
75
|
+
results = list.auto_paging_each
|
76
|
+
expect(results.count).to eq(0)
|
77
|
+
expect(times_block_yielded).to eq(1)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when response does not include a cursor" do
|
82
|
+
let(:client) { instance_double(Files::ApiClient, cursor: nil) }
|
83
|
+
|
84
|
+
it "stops requesting any more results after the first try" do
|
85
|
+
server_results = ('a'..'h').to_a
|
86
|
+
times_block_yielded = 0
|
87
|
+
list = described_class.new(ResourceWrapper, params) {
|
88
|
+
times_block_yielded += 1
|
89
|
+
[
|
90
|
+
instance_double(Files::Response, data: server_results.shift(per_page), http_status: 200),
|
91
|
+
options
|
92
|
+
]
|
93
|
+
}
|
94
|
+
results = list.auto_paging_each
|
95
|
+
expect(results.count).to eq(3)
|
96
|
+
expect(times_block_yielded).to eq(1)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns all results at once" do
|
102
|
+
server_results = ('a'..'h').to_a
|
103
|
+
times_block_yielded = 0
|
104
|
+
list = described_class.new(ResourceWrapper, params) {
|
105
|
+
times_block_yielded += 1
|
106
|
+
[
|
107
|
+
instance_double(Files::Response, data: server_results, http_status: 200),
|
108
|
+
options
|
109
|
+
]
|
110
|
+
}
|
111
|
+
results = list.auto_paging_each
|
112
|
+
expect(results.count).to eq(8)
|
113
|
+
expect(times_block_yielded).to eq(1)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#each" do
|
118
|
+
it "returns all results at once" do
|
119
|
+
server_results = ('a'..'h').to_a
|
120
|
+
times_block_yielded = 0
|
121
|
+
results = described_class.new(ResourceWrapper, params) {
|
122
|
+
times_block_yielded += 1
|
123
|
+
[
|
124
|
+
instance_double(Files::Response, data: server_results, http_status: 200),
|
125
|
+
options
|
126
|
+
]
|
127
|
+
}
|
128
|
+
expect(results.count).to eq(8)
|
129
|
+
expect(times_block_yielded).to eq(1)
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when per_page is set" do
|
133
|
+
let(:params) { { per_page: per_page } }
|
134
|
+
let(:per_page) { 3 }
|
135
|
+
|
136
|
+
context "when response includes a cursor" do
|
137
|
+
let(:client) { instance_double(Files::ApiClient, cursor: "XXX-XXX") }
|
138
|
+
|
139
|
+
it "does not call the API until out of responses" do
|
140
|
+
server_results = ('a'..'h').to_a
|
141
|
+
times_block_yielded = 0
|
142
|
+
list = described_class.new(ResourceWrapper, params) {
|
143
|
+
times_block_yielded += 1
|
144
|
+
[
|
145
|
+
instance_double(Files::Response, data: server_results.shift(per_page), http_status: 200),
|
146
|
+
options
|
147
|
+
]
|
148
|
+
}
|
149
|
+
results = list.enum_for(:each)
|
150
|
+
expect(times_block_yielded).to eq(0)
|
151
|
+
expect(results.next.object).to eq('a')
|
152
|
+
expect(times_block_yielded).to eq(1)
|
153
|
+
expect(results.next.object).to eq('b')
|
154
|
+
expect(results.next.object).to eq('c')
|
155
|
+
next_results = list.next_page.enum_for(:each)
|
156
|
+
expect(times_block_yielded).to eq(2)
|
157
|
+
expect(next_results.next.object).to eq('d')
|
158
|
+
expect(next_results.next.object).to eq('e')
|
159
|
+
expect(next_results.next.object).to eq('f')
|
160
|
+
next_results = list.next_page.enum_for(:each)
|
161
|
+
expect(times_block_yielded).to eq(3)
|
162
|
+
expect(next_results.next.object).to eq('g')
|
163
|
+
expect(next_results.next.object).to eq('h')
|
164
|
+
next_results = list.next_page.enum_for(:each)
|
165
|
+
expect(next_results.count).to eq(0)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "return the same data when call more than once" do
|
169
|
+
server_results = ('a'..'h').to_a
|
170
|
+
list = described_class.new(ResourceWrapper, params) {
|
171
|
+
[
|
172
|
+
instance_double(Files::Response, data: server_results.shift(per_page), http_status: 200),
|
173
|
+
options
|
174
|
+
]
|
175
|
+
}
|
176
|
+
expect(list.to_a).to eq(list.to_a)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "stops calling the API once there is an error" do
|
180
|
+
server_results = ('a'..'h').to_a
|
181
|
+
times_block_yielded = 0
|
182
|
+
results = described_class.new(ResourceWrapper, params) {
|
183
|
+
times_block_yielded += 1
|
184
|
+
[
|
185
|
+
instance_double(Files::Response, data: server_results, http_status: 400),
|
186
|
+
options
|
187
|
+
]
|
188
|
+
}
|
189
|
+
expect(results.count).to eq(0)
|
190
|
+
expect(times_block_yielded).to eq(1)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "when response does not include a cursor" do
|
195
|
+
let(:client) { instance_double(Files::ApiClient, cursor: nil) }
|
196
|
+
|
197
|
+
it "stops requesting any more results after the first try" do
|
198
|
+
server_results = ('a'..'h').to_a
|
199
|
+
times_block_yielded = 0
|
200
|
+
list = described_class.new(ResourceWrapper, params) {
|
201
|
+
times_block_yielded += 1
|
202
|
+
[
|
203
|
+
instance_double(Files::Response, data: server_results, http_status: 200),
|
204
|
+
options
|
205
|
+
]
|
206
|
+
}
|
207
|
+
results = list.enum_for(:each)
|
208
|
+
expect(results.count).to eq(8)
|
209
|
+
expect(times_block_yielded).to eq(1)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|