desk_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|