desk_api 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/.coveralls.yml +1 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/.yardopts +3 -0
- data/Gemfile +15 -0
- data/Guardfile +5 -0
- data/LICENSE +7 -0
- data/README.md +185 -0
- data/Rakefile +15 -0
- data/config.rb +7 -0
- data/desk_api.gemspec +36 -0
- data/lib/desk/action/create.rb +15 -0
- data/lib/desk/action/delete.rb +9 -0
- data/lib/desk/action/embedded.rb +12 -0
- data/lib/desk/action/field.rb +33 -0
- data/lib/desk/action/link.rb +29 -0
- data/lib/desk/action/resource.rb +14 -0
- data/lib/desk/action/search.rb +15 -0
- data/lib/desk/action/update.rb +12 -0
- data/lib/desk/client.rb +67 -0
- data/lib/desk/configuration.rb +132 -0
- data/lib/desk/default.rb +67 -0
- data/lib/desk/error/bad_gateway.rb +10 -0
- data/lib/desk/error/bad_request.rb +10 -0
- data/lib/desk/error/client_error.rb +9 -0
- data/lib/desk/error/configuration_error.rb +8 -0
- data/lib/desk/error/conflict.rb +10 -0
- data/lib/desk/error/forbidden.rb +10 -0
- data/lib/desk/error/gateway_timeout.rb +10 -0
- data/lib/desk/error/internal_server_error.rb +10 -0
- data/lib/desk/error/method_not_allowed.rb +10 -0
- data/lib/desk/error/method_not_supported.rb +9 -0
- data/lib/desk/error/not_acceptable.rb +10 -0
- data/lib/desk/error/not_found.rb +10 -0
- data/lib/desk/error/parse_error.rb +9 -0
- data/lib/desk/error/parser_error.rb +9 -0
- data/lib/desk/error/server_error.rb +9 -0
- data/lib/desk/error/service_unavailable.rb +10 -0
- data/lib/desk/error/too_many_requests.rb +10 -0
- data/lib/desk/error/unauthorized.rb +10 -0
- data/lib/desk/error/unprocessable_entity.rb +10 -0
- data/lib/desk/error/unsupported_media_type.rb +10 -0
- data/lib/desk/error.rb +61 -0
- data/lib/desk/rate_limit.rb +26 -0
- data/lib/desk/request/retry.rb +51 -0
- data/lib/desk/resource/article.rb +10 -0
- data/lib/desk/resource/article_translation.rb +8 -0
- data/lib/desk/resource/attachment.rb +8 -0
- data/lib/desk/resource/case.rb +9 -0
- data/lib/desk/resource/company.rb +8 -0
- data/lib/desk/resource/customer.rb +9 -0
- data/lib/desk/resource/integration_url.rb +9 -0
- data/lib/desk/resource/job.rb +7 -0
- data/lib/desk/resource/label.rb +9 -0
- data/lib/desk/resource/macro.rb +9 -0
- data/lib/desk/resource/macro_action.rb +7 -0
- data/lib/desk/resource/note.rb +7 -0
- data/lib/desk/resource/page.rb +81 -0
- data/lib/desk/resource/reply.rb +8 -0
- data/lib/desk/resource/topic.rb +9 -0
- data/lib/desk/resource/topic_translation.rb +9 -0
- data/lib/desk/resource/user_preference.rb +7 -0
- data/lib/desk/resource.rb +53 -0
- data/lib/desk/resources.json +76 -0
- data/lib/desk/response/raise_error.rb +34 -0
- data/lib/desk/version.rb +3 -0
- data/lib/desk.rb +35 -0
- data/spec/cassettes/Desk_Client/_delete/deletes_a_resource.yml +48 -0
- data/spec/cassettes/Desk_Client/_get/fetches_resources.yml +55 -0
- data/spec/cassettes/Desk_Client/_patch/updates_a_resource.yml +62 -0
- data/spec/cassettes/Desk_Client/_post/creates_a_resource.yml +58 -0
- data/spec/cassettes/Desk_Error/_from_response/can_be_created_from_a_faraday_response.yml +54 -0
- data/spec/cassettes/Desk_Error/_from_response/uses_the_body_message_if_present.yml +54 -0
- data/spec/cassettes/Desk_Resource/_by_url/finds_resources_by_url.yml +313 -0
- data/spec/cassettes/Desk_Resource/_create/creates_a_new_topic.yml +58 -0
- data/spec/cassettes/Desk_Resource/_delete/deletes_a_resource.yml +164 -0
- data/spec/cassettes/Desk_Resource/_delete/throws_an_error_deleting_a_non_deletalbe_resource.yml +56 -0
- data/spec/cassettes/Desk_Resource/_exec_/can_be_forced_to_reload.yml +313 -0
- data/spec/cassettes/Desk_Resource/_exec_/loads_the_current_resource.yml +313 -0
- data/spec/cassettes/Desk_Resource/_method_missing/loads_the_resource_to_find_a_suitable_method.yml +313 -0
- data/spec/cassettes/Desk_Resource/_method_missing/raises_an_error_if_method_does_not_exist.yml +313 -0
- data/spec/cassettes/Desk_Resource/_search/allows_searching_on_search_enabled_resources.yml +54 -0
- data/spec/cassettes/Desk_Resource/_update/throws_an_error_updating_a_user.yml +56 -0
- data/spec/cassettes/Desk_Resource/_update/updates_a_topic.yml +118 -0
- data/spec/cassettes/Desk_Resource_Page/_by_id/loads_the_requested_resource.yml +54 -0
- data/spec/cassettes/Desk_Resource_Page/_page/keeps_the_resource_as_loaded.yml +113 -0
- data/spec/cassettes/Desk_Resource_Page/_page/returns_the_current_page_and_loads_if_page_not_defined.yml +313 -0
- data/spec/cassettes/Desk_Resource_Page/_page/sets_the_resource_to_not_loaded.yml +113 -0
- data/spec/desk/client_spec.rb +133 -0
- data/spec/desk/configuration_spec.rb +183 -0
- data/spec/desk/default_spec.rb +69 -0
- data/spec/desk/error_spec.rb +23 -0
- data/spec/desk/rate_limit_spec.rb +42 -0
- data/spec/desk/request/retry_spec.rb +46 -0
- data/spec/desk/resource_spec.rb +119 -0
- data/spec/desk/resources/page_spec.rb +64 -0
- data/spec/desk_spec.rb +43 -0
- data/spec/spec_helper.rb +39 -0
- metadata +347 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Desk::Client do
|
4
|
+
subject do
|
5
|
+
@client ||= Desk::Client.new Desk::CONFIG
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
@topic_create_data = { name: 'Test Topic' }
|
10
|
+
@topic_update_data = { name: 'Test Updated Topic' }
|
11
|
+
end
|
12
|
+
|
13
|
+
context '#initialize' do
|
14
|
+
before do
|
15
|
+
@configuration = {
|
16
|
+
consumer_key: 'CK',
|
17
|
+
consumer_secret: 'CS',
|
18
|
+
token: 'TOK',
|
19
|
+
token_secret: 'TOKS',
|
20
|
+
username: 'UN',
|
21
|
+
password: 'PW',
|
22
|
+
subdomain: 'devel',
|
23
|
+
endpoint: 'https://devel.desk.com',
|
24
|
+
connection_options: {
|
25
|
+
request: { timeout: 10 }
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
after do
|
31
|
+
Desk.reset!
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with module configuration' do
|
35
|
+
before do
|
36
|
+
Desk.configure do |config|
|
37
|
+
Desk::Configuration.keys.each do |key|
|
38
|
+
config.send("#{key}=", @configuration[key])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'inherits the module configuration' do
|
44
|
+
client = Desk::Client.new
|
45
|
+
Desk::Configuration.keys.each do |key|
|
46
|
+
client.instance_variable_get(:"@#{key}").should eq(@configuration[key])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with class configuration' do
|
52
|
+
context "during initialization" do
|
53
|
+
it "overrides the module configuration" do
|
54
|
+
client = Desk::Client.new(@configuration)
|
55
|
+
Desk::Configuration.keys.each do |key|
|
56
|
+
client.instance_variable_get(:"@#{key}").should eq(@configuration[key])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "after initialization" do
|
62
|
+
it "overrides the module configuration after initialization" do
|
63
|
+
client = Desk::Client.new
|
64
|
+
client.configure do |config|
|
65
|
+
@configuration.each do |key, value|
|
66
|
+
config.send("#{key}=", value)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
Desk::Configuration.keys.each do |key|
|
71
|
+
client.instance_variable_get(:"@#{key}").should eq(@configuration[key])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'sets up default resources on client' do
|
78
|
+
subject.methods include(:articles, :cases, :companies, :custom_fields, :customers)
|
79
|
+
subject.methods include(:filters, :groups, :inbound_mailboxes, :integration_urls)
|
80
|
+
subject.methods include(:jobs, :labels, :macros, :rules, :site_settings)
|
81
|
+
subject.methods include(:system_message, :topics, :twitter_accounts, :users)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#get', :vcr do
|
86
|
+
it 'fetches resources' do
|
87
|
+
response = subject.get('/api/v2/cases/3014')
|
88
|
+
response.body.subject.should eq('Testing Quick Case')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#post', :vcr do
|
93
|
+
it 'creates a resource' do
|
94
|
+
response = subject.post('/api/v2/topics', @topic_create_data)
|
95
|
+
response.body.name.should eq(@topic_create_data[:name])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#patch', :vcr do
|
100
|
+
it 'updates a resource' do
|
101
|
+
subject.patch('/api/v2/topics/556402', @topic_update_data).body.name.should eq(@topic_update_data[:name])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#delete', :vcr do
|
106
|
+
it 'deletes a resource' do
|
107
|
+
subject.delete('/api/v2/topics/556401').status.should eq(204)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#connection' do
|
112
|
+
it 'looks like Faraday connection' do
|
113
|
+
subject.send(:connection).should be_an_instance_of(Faraday::Connection)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'memoizes the connection' do
|
117
|
+
c1, c2 = subject.send(:connection), subject.send(:connection)
|
118
|
+
c1.should equal(c2)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '#request' do
|
123
|
+
it 'catches Faraday errors' do
|
124
|
+
allow(subject).to receive(:connection).and_raise(Faraday::Error::ClientError.new('Oops'))
|
125
|
+
lambda { subject.send(:request, :get, '/path') }.should raise_error(Desk::Error::ClientError)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'catches JSON::ParserError errors' do
|
129
|
+
allow(subject).to receive(:connection).and_raise(JSON::ParserError.new('unexpected token'))
|
130
|
+
lambda { subject.send(:request, :get, '/path') }.should raise_error(Desk::Error::ParserError)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Desk::Configuration do
|
4
|
+
context '#keys' do
|
5
|
+
it 'returns an array of configuration keys' do
|
6
|
+
Desk::Configuration.keys.should eq([
|
7
|
+
:consumer_key,
|
8
|
+
:consumer_secret,
|
9
|
+
:token,
|
10
|
+
:token_secret,
|
11
|
+
:username,
|
12
|
+
:password,
|
13
|
+
:subdomain,
|
14
|
+
:endpoint,
|
15
|
+
:connection_options
|
16
|
+
])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context '#endpoint' do
|
21
|
+
after(:each) do
|
22
|
+
Desk.reset!
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns the endpoint if set' do
|
26
|
+
Desk.endpoint = 'https://devel.desk.com'
|
27
|
+
Desk.endpoint.should eq('https://devel.desk.com')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns the subdomain endpoint if subdomain is set' do
|
31
|
+
Desk.subdomain = 'devel'
|
32
|
+
Desk.endpoint.should eq('https://devel.desk.com')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'gives presidence to the endpoint' do
|
36
|
+
Desk.subdomain = 'subdomain'
|
37
|
+
Desk.endpoint = 'https://endpoint.desk.com'
|
38
|
+
Desk.endpoint.should eq('https://endpoint.desk.com')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context '#configure' do
|
43
|
+
before do
|
44
|
+
@configuration = {
|
45
|
+
consumer_key: 'CK',
|
46
|
+
consumer_secret: 'CS',
|
47
|
+
token: 'TOK',
|
48
|
+
token_secret: 'TOKS',
|
49
|
+
username: 'UN',
|
50
|
+
password: 'PW',
|
51
|
+
subdomain: 'devel',
|
52
|
+
endpoint: 'https://devel.desk.com',
|
53
|
+
connection_options: {
|
54
|
+
request: { timeout: 10 }
|
55
|
+
}
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'overrides the module configuration' do
|
60
|
+
client = Desk::Client.new
|
61
|
+
client.configure do |config|
|
62
|
+
@configuration.each do |key, value|
|
63
|
+
config.send("#{key}=", value)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
Desk::Configuration.keys.each do |key|
|
68
|
+
client.instance_variable_get(:"@#{key}").should eq(@configuration[key])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'throws an exception if credentials are not set' do
|
73
|
+
client = Desk::Client.new
|
74
|
+
lambda {
|
75
|
+
client.configure do |config|
|
76
|
+
@configuration.each do |key, value|
|
77
|
+
config.send("#{key}=", value)
|
78
|
+
end
|
79
|
+
config.username = nil
|
80
|
+
config.consumer_key = nil
|
81
|
+
end
|
82
|
+
}.should raise_error(Desk::Error::ConfigurationError)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'throws an exception if basic auth credentials are invalid' do
|
86
|
+
client = Desk::Client.new
|
87
|
+
lambda {
|
88
|
+
client.configure do |config|
|
89
|
+
@configuration.each do |key, value|
|
90
|
+
config.send("#{key}=", value)
|
91
|
+
end
|
92
|
+
config.username = 1
|
93
|
+
config.consumer_key = nil
|
94
|
+
end
|
95
|
+
}.should raise_error(Desk::Error::ConfigurationError)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'throws an exception if oauth credentials are invalid' do
|
99
|
+
client = Desk::Client.new
|
100
|
+
lambda {
|
101
|
+
client.configure do |config|
|
102
|
+
@configuration.each do |key, value|
|
103
|
+
config.send("#{key}=", value)
|
104
|
+
end
|
105
|
+
config.username = nil
|
106
|
+
config.consumer_key = 1
|
107
|
+
end
|
108
|
+
}.should raise_error(Desk::Error::ConfigurationError)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'throws an exception if endpoint is not a valid url' do
|
112
|
+
client = Desk::Client.new
|
113
|
+
lambda {
|
114
|
+
client.configure do |config|
|
115
|
+
@configuration.each do |key, value|
|
116
|
+
config.send("#{key}=", value)
|
117
|
+
end
|
118
|
+
config.endpoint = 'some_funky_endpoint'
|
119
|
+
end
|
120
|
+
}.should raise_error(Desk::Error::ConfigurationError)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context '#reset!' do
|
125
|
+
before do
|
126
|
+
@configuration = {
|
127
|
+
consumer_key: 'CK',
|
128
|
+
consumer_secret: 'CS',
|
129
|
+
token: 'TOK',
|
130
|
+
token_secret: 'TOKS',
|
131
|
+
username: 'UN',
|
132
|
+
password: 'PW',
|
133
|
+
subdomain: 'devel',
|
134
|
+
endpoint: 'https://devel.desk.com',
|
135
|
+
connection_options: {
|
136
|
+
request: { timeout: 10 }
|
137
|
+
}
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'resets the configuration to module defaults' do
|
142
|
+
client = Desk::Client.new
|
143
|
+
client.configure do |config|
|
144
|
+
@configuration.each do |key, value|
|
145
|
+
config.send("#{key}=", value)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
client.reset!
|
149
|
+
|
150
|
+
Desk::Configuration.keys.each do |key|
|
151
|
+
client.instance_variable_get(:"@#{key}").should_not eq(@configuration[key])
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context '#credentials?' do
|
157
|
+
before do
|
158
|
+
@client = Desk::Client.new
|
159
|
+
end
|
160
|
+
|
161
|
+
after do
|
162
|
+
@client.reset!
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'returns false if no authentication credentials are set' do
|
166
|
+
@client.credentials?.should be_false
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'returns true if basic auth credentials are set' do
|
170
|
+
@client.username = 'UN'
|
171
|
+
@client.password = 'PW'
|
172
|
+
@client.credentials?.should be_true
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'returns true if oauth credentials are set' do
|
176
|
+
@client.consumer_key = 'CK'
|
177
|
+
@client.consumer_secret = 'CS'
|
178
|
+
@client.token = 'TOK'
|
179
|
+
@client.token_secret = 'TOKS'
|
180
|
+
@client.credentials?.should be_true
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Desk::Default do
|
4
|
+
context '#options' do
|
5
|
+
it 'returns a hash with mostly nil values' do
|
6
|
+
Desk::Default.options.should eq({
|
7
|
+
consumer_key: nil,
|
8
|
+
consumer_secret: nil,
|
9
|
+
token: nil,
|
10
|
+
token_secret: nil,
|
11
|
+
username: nil,
|
12
|
+
password: nil,
|
13
|
+
subdomain: nil,
|
14
|
+
endpoint: nil,
|
15
|
+
connection_options: {
|
16
|
+
headers: {
|
17
|
+
accept: 'application/json',
|
18
|
+
user_agent: "desk.com Ruby Gem v#{Desk::VERSION}"
|
19
|
+
},
|
20
|
+
request: {
|
21
|
+
open_timeout: 5,
|
22
|
+
timeout: 10
|
23
|
+
}
|
24
|
+
}
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns a hash with environmental variables' do
|
29
|
+
ENV['DESK_CONSUMER_KEY'] = 'CK'
|
30
|
+
ENV['DESK_CONSUMER_SECRET'] = 'CS'
|
31
|
+
ENV['DESK_TOKEN'] = 'TOK'
|
32
|
+
ENV['DESK_TOKEN_SECRET'] = 'TOKS'
|
33
|
+
ENV['DESK_USERNAME'] = 'UN'
|
34
|
+
ENV['DESK_PASSWORD'] = 'PW'
|
35
|
+
ENV['DESK_SUBDOMAIN'] = 'SD'
|
36
|
+
ENV['DESK_ENDPOINT'] = 'EP'
|
37
|
+
|
38
|
+
Desk::Default.options.should eq({
|
39
|
+
consumer_key: 'CK',
|
40
|
+
consumer_secret: 'CS',
|
41
|
+
token: 'TOK',
|
42
|
+
token_secret: 'TOKS',
|
43
|
+
username: 'UN',
|
44
|
+
password: 'PW',
|
45
|
+
subdomain: 'SD',
|
46
|
+
endpoint: 'EP',
|
47
|
+
connection_options: {
|
48
|
+
headers: {
|
49
|
+
accept: 'application/json',
|
50
|
+
user_agent: "desk.com Ruby Gem v#{Desk::VERSION}"
|
51
|
+
},
|
52
|
+
request: {
|
53
|
+
open_timeout: 5,
|
54
|
+
timeout: 10
|
55
|
+
}
|
56
|
+
}
|
57
|
+
})
|
58
|
+
|
59
|
+
ENV['DESK_CONSUMER_KEY'] = nil
|
60
|
+
ENV['DESK_CONSUMER_SECRET'] = nil
|
61
|
+
ENV['DESK_TOKEN'] = nil
|
62
|
+
ENV['DESK_TOKEN_SECRET'] = nil
|
63
|
+
ENV['DESK_USERNAME'] = nil
|
64
|
+
ENV['DESK_PASSWORD'] = nil
|
65
|
+
ENV['DESK_SUBDOMAIN'] = nil
|
66
|
+
ENV['DESK_ENDPOINT'] = nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Desk::Error do
|
4
|
+
subject do
|
5
|
+
@client ||= Desk::Client.new Desk::CONFIG
|
6
|
+
end
|
7
|
+
|
8
|
+
context '.from_response' do
|
9
|
+
it 'can be created from a faraday response', :vcr do
|
10
|
+
lambda {
|
11
|
+
subject.articles.create({ subject: 'Testing', body: 'Testing' })
|
12
|
+
}.should raise_error(Desk::Error::UnprocessableEntity)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'uses the body message if present', :vcr do
|
16
|
+
begin
|
17
|
+
subject.articles.create({ subject: 'Testing', body: 'Testing' })
|
18
|
+
rescue Desk::Error::UnprocessableEntity => e
|
19
|
+
e.message.should eq('Validation Failed')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Desk::RateLimit do
|
4
|
+
context "#limit" do
|
5
|
+
it "returns an Integer when x-rate-limit-limit header is set" do
|
6
|
+
rate_limit = Desk::RateLimit.new("x-rate-limit-limit" => "150")
|
7
|
+
expect(rate_limit.limit).to be_an Integer
|
8
|
+
expect(rate_limit.limit).to eq 150
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns nil when x-rate-limit-limit header is not set" do
|
12
|
+
rate_limit = Desk::RateLimit.new
|
13
|
+
expect(rate_limit.limit).to be_nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "#remaining" do
|
18
|
+
it "returns an Integer when x-rate-limit-remaining header is set" do
|
19
|
+
rate_limit = Desk::RateLimit.new("x-rate-limit-remaining" => "149")
|
20
|
+
expect(rate_limit.remaining).to be_an Integer
|
21
|
+
expect(rate_limit.remaining).to eq 149
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns nil when x-rate-limit-remaining header is not set" do
|
25
|
+
rate_limit = Desk::RateLimit.new
|
26
|
+
expect(rate_limit.remaining).to be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "#reset_in" do
|
31
|
+
it "returns an Integer when x-rate-limit-reset header is set" do
|
32
|
+
rate_limit = Desk::RateLimit.new("x-rate-limit-reset" => "36")
|
33
|
+
expect(rate_limit.reset_in).to be_an Integer
|
34
|
+
expect(rate_limit.reset_in).to eq 36
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns nil when x-rate-limit-reset header is not set" do
|
38
|
+
rate_limit = Desk::RateLimit.new
|
39
|
+
expect(rate_limit.reset_in).to be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'desk/request/retry'
|
3
|
+
|
4
|
+
describe Desk::Request::Retry do
|
5
|
+
before do
|
6
|
+
@stubs = Faraday::Adapter::Test::Stubs.new
|
7
|
+
@conn = Faraday.new do |builder|
|
8
|
+
builder.request :retry, { interval: 0 }
|
9
|
+
builder.adapter :test, @stubs
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'retries three times', vcr: { record: :none } do
|
14
|
+
times_called = 0
|
15
|
+
|
16
|
+
@stubs.post('/echo') do
|
17
|
+
times_called += 1
|
18
|
+
raise Faraday::Error::TimeoutError, 'Timeout'
|
19
|
+
end
|
20
|
+
|
21
|
+
@conn.post('http://localhost/echo') rescue nil
|
22
|
+
times_called.should eq(3)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'retries once if we have too many requests', vcr: { record: :none } do
|
26
|
+
times_called = 0
|
27
|
+
|
28
|
+
@stubs.post('/echo') do
|
29
|
+
times_called += 1
|
30
|
+
raise Desk::Error::TooManyRequests.from_response({
|
31
|
+
body: '{"message":"Too Many Requests"}',
|
32
|
+
status: 429,
|
33
|
+
response_headers: {
|
34
|
+
'status' => 429,
|
35
|
+
'x-rate-limit-limit' => '60',
|
36
|
+
'x-rate-limit-remaining' => '0',
|
37
|
+
'x-rate-limit-reset' => '1',
|
38
|
+
'content-length' => '31'
|
39
|
+
}
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
43
|
+
@conn.post('http://localhost/echo') rescue nil
|
44
|
+
times_called.should eq(2)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Desk::Resource do
|
4
|
+
subject do
|
5
|
+
@client ||= Desk::Client.new Desk::CONFIG
|
6
|
+
end
|
7
|
+
|
8
|
+
context '#initialize' do
|
9
|
+
it 'stores the client' do
|
10
|
+
subject.articles.instance_variable_get(:@client).should eq(subject)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is not loaded initially' do
|
14
|
+
subject.articles.instance_variable_get(:@loaded).should be_false
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets up the link to self' do
|
18
|
+
subject.articles.instance_variable_get(:@_links).self.href.should_not be_nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context '#exec!', :vcr do
|
23
|
+
it 'loads the current resource' do
|
24
|
+
subject.articles.send(:exec!).instance_variable_get(:@loaded).should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can be forced to reload' do
|
28
|
+
subject.articles.instance_variable_set(:@loaded, true)
|
29
|
+
subject.should_receive(:get).and_call_original
|
30
|
+
subject.articles.send(:exec!, true)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context '#method_missing', :vcr do
|
35
|
+
it 'loads the resource to find a suitable method' do
|
36
|
+
subject.articles.instance_variable_set(:@loaded, false)
|
37
|
+
subject.articles.should_receive(:exec!).and_call_original
|
38
|
+
subject.articles.first_page
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'raises an error if method does not exist' do
|
42
|
+
lambda { subject.articles.some_other_method }.should raise_error(Desk::Error::MethodNotSupported)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context '#by_url', :vcr do
|
47
|
+
it 'finds resources by url' do
|
48
|
+
subject.articles.by_url('/api/v2/articles/1213277').should be_an_instance_of(Desk::Resource::Article)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context '#resource', :vcr do
|
53
|
+
it 'requires the specified resource' do
|
54
|
+
subject.send(:resource, 'article').should equal(Desk::Resource::Article)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns the generic resource on error' do
|
58
|
+
subject.send(:resource, 'something_crazy').should equal(Desk::Resource)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context '#search' do
|
63
|
+
it 'allows searching on search enabled resources', :vcr do
|
64
|
+
subject.articles.search(text: 'Lorem Ipsum').total_entries.should eq(0)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'throws an error if search is not enabled' do
|
68
|
+
lambda { subject.users.search(test: 'something') }.should raise_error(Desk::Error::MethodNotSupported)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context '#create' do
|
73
|
+
it 'creates a new topic', :vcr do
|
74
|
+
topic = subject.topics.create({
|
75
|
+
name: 'My new topic'
|
76
|
+
}).name.should eq('My new topic')
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'throws an error creating a user' do
|
80
|
+
lambda { subject.users.create(name: 'Some User') }.should raise_error(Desk::Error::MethodNotSupported)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context '#update' do
|
85
|
+
it 'updates a topic', :vcr do
|
86
|
+
topic = subject.topics.first
|
87
|
+
|
88
|
+
topic.description = 'Some new description'
|
89
|
+
topic.update({
|
90
|
+
name: 'Updated topic name'
|
91
|
+
})
|
92
|
+
|
93
|
+
topic.name.should eq('Updated topic name')
|
94
|
+
topic.description.should eq('Some new description')
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'throws an error updating a user', :vcr do
|
98
|
+
user = subject.users.first
|
99
|
+
lambda { user.update(name: 'Some User') }.should raise_error(Desk::Error::MethodNotSupported)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context '#delete' do
|
104
|
+
it 'deletes a resource', :vcr do
|
105
|
+
subject.articles.create({
|
106
|
+
subject: 'My subject',
|
107
|
+
body: 'Some text for this new article',
|
108
|
+
_links: {
|
109
|
+
topic: subject.topics.first.get_self
|
110
|
+
}
|
111
|
+
}).delete.should be_true
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'throws an error deleting a non deletalbe resource', :vcr do
|
115
|
+
user = subject.users.first
|
116
|
+
lambda { user.delete }.should raise_error(Desk::Error::MethodNotSupported)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'desk/resource/page'
|
3
|
+
|
4
|
+
describe Desk::Resource::Page do
|
5
|
+
subject do
|
6
|
+
@client ||= Desk::Client.new Desk::CONFIG
|
7
|
+
end
|
8
|
+
|
9
|
+
context '#query_params' do
|
10
|
+
before do
|
11
|
+
@page = Desk::Resource::Page.new(subject, Hashie::Mash.new({
|
12
|
+
_links: { self: { href: '/api/v2/cases?page=2&per_page=50' } }
|
13
|
+
}), true)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'allows to get query params from the current resource' do
|
17
|
+
@page.send(:query_params, 'page').should eq('2')
|
18
|
+
@page.send(:query_params, 'per_page').should eq('50')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns nil if param not found' do
|
22
|
+
@page.send(:query_params, 'blup').should be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context '#query_params=' do
|
27
|
+
before do
|
28
|
+
@page = Desk::Resource::Page.new(subject, Hashie::Mash.new({
|
29
|
+
_links: { self: { href: '/api/v2/cases' } }
|
30
|
+
}), true)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'sets query params on the current url' do
|
34
|
+
@page.send(:query_params=, { page: 5, per_page: 50 })
|
35
|
+
@page.instance_variable_get(:@_links).self.href.should eq('/api/v2/cases?page=5&per_page=50')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context '#page' do
|
40
|
+
it 'returns the current page and loads if page not defined', :vcr do
|
41
|
+
subject.articles.page.should eq(1)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'sets the page' do
|
45
|
+
subject.cases.page(5).page.should eq(5)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'sets the resource to not loaded', :vcr do
|
49
|
+
cases = subject.cases.send(:exec!)
|
50
|
+
cases.page(5).instance_variable_get(:@loaded).should be_false
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'keeps the resource as loaded', :vcr do
|
54
|
+
cases = subject.cases.send(:exec!)
|
55
|
+
cases.page(1).instance_variable_get(:@loaded).should be_true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context '#by_id' do
|
60
|
+
it 'loads the requested resource', :vcr do
|
61
|
+
subject.cases.by_id(3065).subject.should eq('Testing the Tank again')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|