testrail 0.0.1

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.
@@ -0,0 +1,68 @@
1
+ require 'httparty'
2
+
3
+ module Testrail
4
+ class Request
5
+ include HTTParty
6
+ extend Testrail::CommandHelper
7
+
8
+ base_uri Testrail.config.server
9
+ format :json
10
+
11
+ def self.get(*args)
12
+ command, ids, opts = parse_args(*args)
13
+ url = build_command(command, ids)
14
+ attempts = 0
15
+ begin
16
+ attempts += 1
17
+ response = Testrail::Response.new(super(url, opts))
18
+ rescue TimeoutError => error
19
+ retry if attempts < 3
20
+ unless Testrail.logger.nil?
21
+ Testrail.logger.error "Timeout connecting to GET #{url}"
22
+ Testrail.logger.error error
23
+ end
24
+ raise error
25
+ rescue Exception => error
26
+ unless Testrail.logger.nil?
27
+ Testrail.logger.error "Unexpected exception intercepted calling TestRail"
28
+ Testrail.logger.error error
29
+ end
30
+ raise error
31
+ end
32
+ response
33
+ end
34
+
35
+ def self.post(*args)
36
+ command, ids, opts = parse_args(*args)
37
+ url = build_command(command, ids)
38
+ attempts = 0
39
+ begin
40
+ attempts += 1
41
+ response = Testrail::Response.new(super(url, opts))
42
+ rescue TimeoutError => error
43
+ retry if attempts < 3
44
+ unless Testrail.logger.nil?
45
+ Testrail.logger.error "Timeout connecting to POST #{url}"
46
+ Testrail.logger.error error
47
+ end
48
+ raise error
49
+ rescue Exception => error
50
+ unless Testrail.logger.nil?
51
+ Testrail.logger.error "Unexpected exception intercepted calling TestRail"
52
+ Testrail.logger.error error
53
+ end
54
+ raise error
55
+ end
56
+ response
57
+ end
58
+
59
+ private
60
+ def self.parse_args(*args)
61
+ opts = args.last.instance_of?(Hash) ? args.pop : {}
62
+ opts[:headers] = opts[:headers] ? Testrail.config.headers.merge(opts[:headers]) : Testrail.config.headers
63
+ command = args.shift
64
+ ids = args.empty? ? nil : args
65
+ [command, ids, opts]
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,35 @@
1
+ require 'forwardable'
2
+ require 'json'
3
+
4
+ module Testrail
5
+ class Response
6
+ attr_reader :http_response
7
+ attr_accessor :success, :payload, :error
8
+
9
+ extend Forwardable
10
+
11
+ def_delegators :http_response, :request, :response, :code
12
+
13
+ def initialize(http_response = nil)
14
+ @http_response = http_response
15
+ parse_payload if http_response.respond_to?(:body) && !http_response.body.nil?
16
+ parse_error if Integer(http_response.code) >= 400
17
+ end
18
+
19
+ private
20
+ def parse_payload
21
+ result_body = JSON.parse(http_response.body)
22
+ @success = result_body.key?('result') ? result_body.delete('result') : nil
23
+ @payload = @success ? result_body : nil
24
+ @error = result_body.key?('error') ? result_body.delete('error') : nil
25
+ rescue JSON::ParserError
26
+ @success = false
27
+ @error = "Malformed JSON response.\n Received #{http_response.body}"
28
+ end
29
+
30
+ def parse_error
31
+ @success = false
32
+ @error = ::Net::HTTPResponse::CODE_TO_OBJ[http_response.code.to_s].name.gsub!(/Net::HTTP/, '')
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Testrail
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,367 @@
1
+ require 'spec_helper'
2
+
3
+ describe Testrail::Client do
4
+ subject { Testrail::Client.new }
5
+
6
+ describe "initialize" do
7
+ it "assigns Testrail::Request to @request" do
8
+ subject.request.should eq(Testrail::Request)
9
+ end
10
+ end
11
+
12
+ shared_examples_for "an api call" do
13
+ before do
14
+ @parsed_ids = ids.empty? ? '' : '/' + [ids].flatten.join('/')
15
+ stub_request(expected_method, url_prefix(command.to_s) + @parsed_ids + key).
16
+ with(body: opts[:body],
17
+ headers: opts[:headers]).
18
+ to_return(status: 200, body: JSON.generate({result: true, an_object: 'abc'}, headers: {}))
19
+ args = []
20
+ args << ids unless ids.empty?
21
+ args << opts unless opts.empty?
22
+ @response = subject.send(command, *args.flatten)
23
+ end
24
+
25
+ it "returns a Testrail::Response object" do
26
+ @response.should be_instance_of(Testrail::Response)
27
+ end
28
+
29
+
30
+ context "successful interaction" do
31
+ it "calls WebMock with the appropriate method " do
32
+ WebMock.should have_requested(expected_method, url_prefix(command.to_s) + @parsed_ids + key).with(opts)
33
+ end
34
+
35
+ it "should return Testrail::Response with success set to true" do
36
+ @response.success.should be_true
37
+ end
38
+
39
+ it "should return Testrail::Response with a nil @error" do
40
+ @response.error.should be_nil
41
+ end
42
+
43
+ it "should return Testrail::Response with a valid body hash" do
44
+ @response.payload.should eq({"an_object" => "abc"})
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#add_result" do
50
+ describe "shared behavior" do
51
+ it_should_behave_like "an api call" do
52
+ let(:command) { :add_result }
53
+ let(:ids) { 'test_id' }
54
+ let(:opts) { post_options }
55
+ let(:expected_method) { :post }
56
+ end
57
+ end
58
+ end
59
+
60
+ describe "#add_result_for_case" do
61
+ describe "shared behavior" do
62
+ it_should_behave_like "an api call" do
63
+ let(:command) { :add_result_for_case }
64
+ let(:ids) { ['run_id', 'case_id'] }
65
+ let(:opts) { post_options }
66
+ let(:expected_method) { :post }
67
+ end
68
+ end
69
+ end
70
+
71
+ describe "#get_test" do
72
+ describe "shared behavior" do
73
+ it_should_behave_like "an api call" do
74
+ let(:command) { :get_test }
75
+ let(:ids) { 'test_id' }
76
+ let(:opts) { get_options }
77
+ let(:expected_method) { :get }
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "#get_tests" do
83
+ describe "shared behavior" do
84
+ it_should_behave_like "an api call" do
85
+ let(:command) { :get_tests }
86
+ let(:ids) { 'run_id' }
87
+ let(:opts) { get_options }
88
+ let(:expected_method) { :get }
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#get_case" do
94
+ describe "shared behavior" do
95
+ it_should_behave_like "an api call" do
96
+ let(:command) { :get_case }
97
+ let(:ids) { 'case_id' }
98
+ let(:opts) { get_options }
99
+ let(:expected_method) { :get }
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "#get_cases" do
105
+ describe "shared behavior" do
106
+ it_should_behave_like "an api call" do
107
+ let(:command) { :get_cases }
108
+ let(:ids) { ['suite_id', 'section_id'] }
109
+ let(:opts) { get_options }
110
+ let(:expected_method) { :get }
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "#add_case" do
116
+ describe "shared behavior" do
117
+ it_should_behave_like "an api call" do
118
+ let(:command) { :add_case }
119
+ let(:ids) { 'section_id' }
120
+ let(:opts) { post_options }
121
+ let(:expected_method) { :post }
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#update_case" do
127
+ describe "shared behavior" do
128
+ it_should_behave_like "an api call" do
129
+ let(:command) { :update_case }
130
+ let(:ids) { 'case_id' }
131
+ let(:opts) { post_options }
132
+ let(:expected_method) { :post }
133
+ end
134
+ end
135
+ end
136
+
137
+ describe "#delete_case" do
138
+ describe "shared behavior" do
139
+ it_should_behave_like "an api call" do
140
+ let(:command) { :delete_case }
141
+ let(:ids) { 'case_id' }
142
+ let(:opts) { get_options }
143
+ let(:expected_method) { :post }
144
+ end
145
+ end
146
+ end
147
+
148
+ describe "#get_suite" do
149
+ describe "shared behavior" do
150
+ it_should_behave_like "an api call" do
151
+ let(:command) { :get_suite }
152
+ let(:ids) { 'suite_id' }
153
+ let(:opts) { get_options }
154
+ let(:expected_method) { :get }
155
+ end
156
+ end
157
+ end
158
+
159
+ describe "#get_suites" do
160
+ describe "shared behavior" do
161
+ it_should_behave_like "an api call" do
162
+ let(:command) { :get_suites }
163
+ let(:ids) { 'project_id' }
164
+ let(:opts) { get_options }
165
+ let(:expected_method) { :get }
166
+ end
167
+ end
168
+ end
169
+
170
+ describe "#get_section" do
171
+ describe "shared behavior" do
172
+ it_should_behave_like "an api call" do
173
+ let(:command) { :get_section }
174
+ let(:ids) { 'section_id' }
175
+ let(:opts) { get_options }
176
+ let(:expected_method) { :get }
177
+ end
178
+ end
179
+ end
180
+
181
+ describe "#get_sections" do
182
+ describe "shared behavior" do
183
+ it_should_behave_like "an api call" do
184
+ let(:command) { :get_sections }
185
+ let(:ids) { 'suite_id' }
186
+ let(:opts) { get_options }
187
+ let(:expected_method) { :get }
188
+ end
189
+ end
190
+ end
191
+
192
+ describe "#add_suite" do
193
+ describe "shared behavior" do
194
+ it_should_behave_like "an api call" do
195
+ let(:command) { :add_suite }
196
+ let(:ids) { 'project_id' }
197
+ let(:opts) { post_options }
198
+ let(:expected_method) { :post }
199
+ end
200
+ end
201
+ end
202
+
203
+ describe "#add_section" do
204
+ describe "shared behavior" do
205
+ it_should_behave_like "an api call" do
206
+ let(:command) { :add_section }
207
+ let(:ids) { 'suite_id' }
208
+ let(:opts) { post_options }
209
+ let(:expected_method) { :post }
210
+ end
211
+ end
212
+ end
213
+
214
+ describe "#get_run" do
215
+ describe "shared behavior" do
216
+ it_should_behave_like "an api call" do
217
+ let(:command) { :get_run }
218
+ let(:ids) { 'run_id' }
219
+ let(:opts) { get_options }
220
+ let(:expected_method) { :get }
221
+ end
222
+ end
223
+ end
224
+
225
+ describe "#get_runs" do
226
+ describe "shared behavior" do
227
+ it_should_behave_like "an api call" do
228
+ let(:command) { :get_runs }
229
+ let(:ids) { ['project_id', 'plan_id'] }
230
+ let(:opts) { get_options }
231
+ let(:expected_method) { :get }
232
+ end
233
+ end
234
+ end
235
+
236
+ describe "#add_run" do
237
+ describe "shared behavior" do
238
+ it_should_behave_like "an api call" do
239
+ let(:command) { :add_run }
240
+ let(:ids) { 'suite_id' }
241
+ let(:opts) { post_options }
242
+ let(:expected_method) { :post }
243
+ end
244
+ end
245
+ end
246
+
247
+ describe "#close_run" do
248
+ describe "shared behavior" do
249
+ it_should_behave_like "an api call" do
250
+ let(:command) { :close_run }
251
+ let(:ids) { 'run_id' }
252
+ let(:opts) { get_options }
253
+ let(:expected_method) { :post }
254
+ end
255
+ end
256
+ end
257
+
258
+ describe "#get_plan" do
259
+ describe "shared behavior" do
260
+ it_should_behave_like "an api call" do
261
+ let(:command) { :get_plan }
262
+ let(:ids) { 'plan_id' }
263
+ let(:opts) { get_options }
264
+ let(:expected_method) { :get }
265
+ end
266
+ end
267
+ end
268
+
269
+ describe "#get_plans" do
270
+ describe "shared behavior" do
271
+ it_should_behave_like "an api call" do
272
+ let(:command) { :get_plans }
273
+ let(:ids) { 'project_id' }
274
+ let(:opts) { get_options }
275
+ let(:expected_method) { :get }
276
+ end
277
+ end
278
+ end
279
+
280
+ describe "#add_plan" do
281
+ describe "shared behavior" do
282
+ it_should_behave_like "an api call" do
283
+ let(:command) { :add_plan }
284
+ let(:ids) { 'project_id' }
285
+ let(:opts) { post_options }
286
+ let(:expected_method) { :post }
287
+ end
288
+ end
289
+ end
290
+
291
+ describe "#add_plan_entries" do
292
+ describe "shared behavior" do
293
+ it_should_behave_like "an api call" do
294
+ let(:command) { :add_plan_entries }
295
+ let(:ids) { 'plan_id' }
296
+ let(:opts) { post_options }
297
+ let(:expected_method) { :post }
298
+ end
299
+ end
300
+ end
301
+
302
+ describe "#close_plan" do
303
+ describe "shared behavior" do
304
+ it_should_behave_like "an api call" do
305
+ let(:command) { :close_plan }
306
+ let(:ids) { 'plan_id' }
307
+ let(:opts) { get_options }
308
+ let(:expected_method) { :post }
309
+ end
310
+ end
311
+ end
312
+
313
+ describe "#get_milestone" do
314
+ describe "shared behavior" do
315
+ it_should_behave_like "an api call" do
316
+ let(:command) { :get_milestone }
317
+ let(:ids) { 'milestone_id' }
318
+ let(:opts) { get_options }
319
+ let(:expected_method) { :get }
320
+ end
321
+ end
322
+ end
323
+
324
+ describe "#get_milestones" do
325
+ describe "shared behavior" do
326
+ it_should_behave_like "an api call" do
327
+ let(:command) { :get_milestones }
328
+ let(:ids) { 'project_id' }
329
+ let(:opts) { get_options }
330
+ let(:expected_method) { :get }
331
+ end
332
+ end
333
+ end
334
+
335
+ describe "#add_milestone" do
336
+ describe "shared behavior" do
337
+ it_should_behave_like "an api call" do
338
+ let(:command) { :add_milestone }
339
+ let(:ids) { 'project_id' }
340
+ let(:opts) { post_options }
341
+ let(:expected_method) { :post }
342
+ end
343
+ end
344
+ end
345
+
346
+ describe "#get_project" do
347
+ describe "shared behavior" do
348
+ it_should_behave_like "an api call" do
349
+ let(:command) { :get_project }
350
+ let(:ids) { 'project_id' }
351
+ let(:opts) { get_options }
352
+ let(:expected_method) { :get }
353
+ end
354
+ end
355
+ end
356
+
357
+ describe "#get_projects" do
358
+ describe "shared behavior" do
359
+ it_should_behave_like "an api call" do
360
+ let(:command) { :get_projects }
361
+ let(:ids) { '' }
362
+ let(:opts) { get_options }
363
+ let(:expected_method) { :get }
364
+ end
365
+ end
366
+ end
367
+ end