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.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +5 -0
  5. data/.yardopts +3 -0
  6. data/Gemfile +15 -0
  7. data/Guardfile +5 -0
  8. data/LICENSE +7 -0
  9. data/README.md +185 -0
  10. data/Rakefile +15 -0
  11. data/config.rb +7 -0
  12. data/desk_api.gemspec +36 -0
  13. data/lib/desk/action/create.rb +15 -0
  14. data/lib/desk/action/delete.rb +9 -0
  15. data/lib/desk/action/embedded.rb +12 -0
  16. data/lib/desk/action/field.rb +33 -0
  17. data/lib/desk/action/link.rb +29 -0
  18. data/lib/desk/action/resource.rb +14 -0
  19. data/lib/desk/action/search.rb +15 -0
  20. data/lib/desk/action/update.rb +12 -0
  21. data/lib/desk/client.rb +67 -0
  22. data/lib/desk/configuration.rb +132 -0
  23. data/lib/desk/default.rb +67 -0
  24. data/lib/desk/error/bad_gateway.rb +10 -0
  25. data/lib/desk/error/bad_request.rb +10 -0
  26. data/lib/desk/error/client_error.rb +9 -0
  27. data/lib/desk/error/configuration_error.rb +8 -0
  28. data/lib/desk/error/conflict.rb +10 -0
  29. data/lib/desk/error/forbidden.rb +10 -0
  30. data/lib/desk/error/gateway_timeout.rb +10 -0
  31. data/lib/desk/error/internal_server_error.rb +10 -0
  32. data/lib/desk/error/method_not_allowed.rb +10 -0
  33. data/lib/desk/error/method_not_supported.rb +9 -0
  34. data/lib/desk/error/not_acceptable.rb +10 -0
  35. data/lib/desk/error/not_found.rb +10 -0
  36. data/lib/desk/error/parse_error.rb +9 -0
  37. data/lib/desk/error/parser_error.rb +9 -0
  38. data/lib/desk/error/server_error.rb +9 -0
  39. data/lib/desk/error/service_unavailable.rb +10 -0
  40. data/lib/desk/error/too_many_requests.rb +10 -0
  41. data/lib/desk/error/unauthorized.rb +10 -0
  42. data/lib/desk/error/unprocessable_entity.rb +10 -0
  43. data/lib/desk/error/unsupported_media_type.rb +10 -0
  44. data/lib/desk/error.rb +61 -0
  45. data/lib/desk/rate_limit.rb +26 -0
  46. data/lib/desk/request/retry.rb +51 -0
  47. data/lib/desk/resource/article.rb +10 -0
  48. data/lib/desk/resource/article_translation.rb +8 -0
  49. data/lib/desk/resource/attachment.rb +8 -0
  50. data/lib/desk/resource/case.rb +9 -0
  51. data/lib/desk/resource/company.rb +8 -0
  52. data/lib/desk/resource/customer.rb +9 -0
  53. data/lib/desk/resource/integration_url.rb +9 -0
  54. data/lib/desk/resource/job.rb +7 -0
  55. data/lib/desk/resource/label.rb +9 -0
  56. data/lib/desk/resource/macro.rb +9 -0
  57. data/lib/desk/resource/macro_action.rb +7 -0
  58. data/lib/desk/resource/note.rb +7 -0
  59. data/lib/desk/resource/page.rb +81 -0
  60. data/lib/desk/resource/reply.rb +8 -0
  61. data/lib/desk/resource/topic.rb +9 -0
  62. data/lib/desk/resource/topic_translation.rb +9 -0
  63. data/lib/desk/resource/user_preference.rb +7 -0
  64. data/lib/desk/resource.rb +53 -0
  65. data/lib/desk/resources.json +76 -0
  66. data/lib/desk/response/raise_error.rb +34 -0
  67. data/lib/desk/version.rb +3 -0
  68. data/lib/desk.rb +35 -0
  69. data/spec/cassettes/Desk_Client/_delete/deletes_a_resource.yml +48 -0
  70. data/spec/cassettes/Desk_Client/_get/fetches_resources.yml +55 -0
  71. data/spec/cassettes/Desk_Client/_patch/updates_a_resource.yml +62 -0
  72. data/spec/cassettes/Desk_Client/_post/creates_a_resource.yml +58 -0
  73. data/spec/cassettes/Desk_Error/_from_response/can_be_created_from_a_faraday_response.yml +54 -0
  74. data/spec/cassettes/Desk_Error/_from_response/uses_the_body_message_if_present.yml +54 -0
  75. data/spec/cassettes/Desk_Resource/_by_url/finds_resources_by_url.yml +313 -0
  76. data/spec/cassettes/Desk_Resource/_create/creates_a_new_topic.yml +58 -0
  77. data/spec/cassettes/Desk_Resource/_delete/deletes_a_resource.yml +164 -0
  78. data/spec/cassettes/Desk_Resource/_delete/throws_an_error_deleting_a_non_deletalbe_resource.yml +56 -0
  79. data/spec/cassettes/Desk_Resource/_exec_/can_be_forced_to_reload.yml +313 -0
  80. data/spec/cassettes/Desk_Resource/_exec_/loads_the_current_resource.yml +313 -0
  81. data/spec/cassettes/Desk_Resource/_method_missing/loads_the_resource_to_find_a_suitable_method.yml +313 -0
  82. data/spec/cassettes/Desk_Resource/_method_missing/raises_an_error_if_method_does_not_exist.yml +313 -0
  83. data/spec/cassettes/Desk_Resource/_search/allows_searching_on_search_enabled_resources.yml +54 -0
  84. data/spec/cassettes/Desk_Resource/_update/throws_an_error_updating_a_user.yml +56 -0
  85. data/spec/cassettes/Desk_Resource/_update/updates_a_topic.yml +118 -0
  86. data/spec/cassettes/Desk_Resource_Page/_by_id/loads_the_requested_resource.yml +54 -0
  87. data/spec/cassettes/Desk_Resource_Page/_page/keeps_the_resource_as_loaded.yml +113 -0
  88. data/spec/cassettes/Desk_Resource_Page/_page/returns_the_current_page_and_loads_if_page_not_defined.yml +313 -0
  89. data/spec/cassettes/Desk_Resource_Page/_page/sets_the_resource_to_not_loaded.yml +113 -0
  90. data/spec/desk/client_spec.rb +133 -0
  91. data/spec/desk/configuration_spec.rb +183 -0
  92. data/spec/desk/default_spec.rb +69 -0
  93. data/spec/desk/error_spec.rb +23 -0
  94. data/spec/desk/rate_limit_spec.rb +42 -0
  95. data/spec/desk/request/retry_spec.rb +46 -0
  96. data/spec/desk/resource_spec.rb +119 -0
  97. data/spec/desk/resources/page_spec.rb +64 -0
  98. data/spec/desk_spec.rb +43 -0
  99. data/spec/spec_helper.rb +39 -0
  100. 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