kalibro_client 1.4.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -6
  3. data/features/kalibro_range/find.feature +1 -1
  4. data/features/kalibro_range/update.feature +1 -2
  5. data/features/metric_result/hotspot_related_results.feature +17 -0
  6. data/features/metric_result/{descendant_values.feature → tree/descendant_values.feature} +0 -0
  7. data/features/metric_result/{history_of.feature → tree/history_of.feature} +0 -0
  8. data/features/step_definitions/hotspot_metric_result_step.rb +15 -0
  9. data/features/step_definitions/metric_result_steps.rb +3 -3
  10. data/features/step_definitions/processing_steps.rb +5 -7
  11. data/features/step_definitions/repository_steps.rb +5 -0
  12. data/lib/kalibro_client/entities.rb +3 -1
  13. data/lib/kalibro_client/entities/base.rb +45 -44
  14. data/lib/kalibro_client/entities/configurations/metric_configuration.rb +7 -3
  15. data/lib/kalibro_client/entities/processor/hotspot_metric_result.rb +41 -0
  16. data/lib/kalibro_client/entities/processor/metric_result.rb +12 -32
  17. data/lib/kalibro_client/entities/processor/module_result.rb +20 -2
  18. data/lib/kalibro_client/entities/processor/tree_metric_result.rb +54 -0
  19. data/lib/kalibro_client/errors.rb +3 -1
  20. data/lib/kalibro_client/errors/record_invalid.rb +19 -0
  21. data/lib/kalibro_client/errors/record_not_found.rb +2 -2
  22. data/lib/kalibro_client/errors/request_error.rb +27 -0
  23. data/lib/kalibro_client/helpers/aggregation_options.rb +1 -1
  24. data/lib/kalibro_client/version.rb +1 -1
  25. data/spec/entities/base_spec.rb +292 -201
  26. data/spec/entities/configurations/metric_configuration_spec.rb +1 -1
  27. data/spec/entities/processor/hotspot_metric_result_spec.rb +49 -0
  28. data/spec/entities/processor/metric_result_spec.rb +31 -89
  29. data/spec/entities/processor/module_result_spec.rb +90 -61
  30. data/spec/entities/processor/tree_metric_result_spec.rb +128 -0
  31. data/spec/errors/record_invalid_spec.rb +45 -0
  32. data/spec/factories/hotspot_metric_results.rb +24 -0
  33. data/spec/factories/metric_configurations.rb +1 -1
  34. data/spec/factories/metric_results.rb +0 -1
  35. data/spec/factories/tree_metric_results.rb +24 -0
  36. data/spec/helpers/aggregation_options_spec.rb +1 -1
  37. metadata +24 -6
@@ -0,0 +1,54 @@
1
+ # This file is part of KalibroClient
2
+ # Copyright (C) 2013 it's respectives authors (please see the AUTHORS file)
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module KalibroClient
18
+ module Entities
19
+ module Processor
20
+ class TreeMetricResult < KalibroClient::Entities::Processor::MetricResult
21
+ attr_accessor :aggregated_value
22
+
23
+ def initialize(attributes={}, persisted=false)
24
+ value = attributes["value"]
25
+ @value = (value == "NaN") ? attributes["aggregated_value"].to_f : value.to_f
26
+ attributes.each do |field, value|
27
+ if field!= "value" and field!= "aggregated_value" and self.class.is_valid?(field)
28
+ send("#{field}=", value)
29
+ end
30
+ end
31
+ @kalibro_errors = []
32
+ @persisted = persisted
33
+ end
34
+
35
+ def aggregated_value=(value)
36
+ @aggregated_value = value.to_f
37
+ end
38
+
39
+ def descendant_values
40
+ descendant_values = self.class.request(':id/descendant_values', {id: id}, :get)['descendant_values']
41
+ descendant_values.map {|descendant_value| descendant_value.to_f}
42
+ end
43
+
44
+ def self.history_of(metric_name, kalibro_module_id, repository_id)
45
+ response = Repository.request(':id/metric_result_history_of', {metric_name: metric_name,
46
+ kalibro_module_id: kalibro_module_id,
47
+ id: repository_id})['metric_result_history_of']
48
+ response.map { |date_metric_result|
49
+ KalibroClient::Entities::Miscellaneous::DateMetricResult.new date_metric_result }
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -5,7 +5,7 @@
5
5
  # it under the terms of the GNU General Public License as published by
6
6
  # the Free Software Foundation, either version 3 of the License, or
7
7
  # (at your option) any later version.
8
- #
8
+ #
9
9
  # This program is distributed in the hope that it will be useful,
10
10
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -15,4 +15,6 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
  require 'kalibro_client/errors/standard'
18
+ require 'kalibro_client/errors/request_error'
18
19
  require 'kalibro_client/errors/record_not_found'
20
+ require 'kalibro_client/errors/record_invalid'
@@ -0,0 +1,19 @@
1
+ module KalibroClient
2
+ module Errors
3
+ class RecordInvalid < Standard
4
+ attr_reader :record
5
+
6
+ def initialize(record = nil)
7
+ if record
8
+ @record = record
9
+ errors = @record.kalibro_errors.join(', ')
10
+ message = "Record invalid: #{errors}"
11
+ else
12
+ message = 'Record invalid'
13
+ end
14
+
15
+ super(message)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -5,7 +5,7 @@
5
5
  # it under the terms of the GNU General Public License as published by
6
6
  # the Free Software Foundation, either version 3 of the License, or
7
7
  # (at your option) any later version.
8
- #
8
+ #
9
9
  # This program is distributed in the hope that it will be useful,
10
10
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -16,7 +16,7 @@
16
16
 
17
17
  module KalibroClient
18
18
  module Errors
19
- class RecordNotFound < Standard
19
+ class RecordNotFound < RequestError
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,27 @@
1
+ # This file is part of KalibroClient
2
+ # Copyright (C) 2013 it's respectives authors (please see the AUTHORS file)
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module KalibroClient
18
+ module Errors
19
+ class RequestError < Standard
20
+ attr_reader :response
21
+
22
+ def initialize(attributes={})
23
+ @response = attributes[:response]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -18,7 +18,7 @@ module AggregationOptions
18
18
  #TODO: internationalization
19
19
  def all_with_label
20
20
  [
21
- ["Average","AVERAGE"], ["Median", "MEDIAN"], ["Maximum", "MAXIMUM"], ["Minimum", "MINIMUM"],
21
+ ["Mean","mean"], ["Median", "MEDIAN"], ["Maximum", "max"], ["Minimum", "min"],
22
22
  ["Count", "COUNT"], ["Standard Deviation", "STANDARD_DEVIATION"]
23
23
  ]
24
24
  end
@@ -15,5 +15,5 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
  module KalibroClient
18
- VERSION = "1.4.1"
18
+ VERSION = "2.0.0"
19
19
  end
@@ -16,242 +16,399 @@
16
16
 
17
17
  require 'spec_helper'
18
18
 
19
+ # Create a class that has the attribute assignment methods, since some methods expect they exist
20
+ # (and usually the subclasses do that).
21
+
22
+ class BaseTest < KalibroClient::Entities::Base
23
+ attr_accessor :id, :created_at, :updated_at
24
+ end
25
+
19
26
  describe KalibroClient::Entities::Base do
20
- subject { FactoryGirl.build(:model) }
27
+ subject { BaseTest.new }
21
28
 
22
29
  describe 'new' do
23
- it 'should create a model from an empty hash' do
24
- subject = KalibroClient::Entities::Base.new {}
30
+ subject { described_class.new({}) }
31
+
32
+ it 'is expected to create a model from an empty hash' do
25
33
  expect(subject.kalibro_errors).to eq([])
26
34
  end
27
35
  end
28
36
 
29
37
  describe 'entity_name' do
30
- it 'should be a String' do
38
+ it 'is expected to be a String' do
31
39
  expect(subject.class.entity_name).to be_a(String)
32
40
  end
33
41
 
34
- it 'should return Base' do
42
+ it 'is expected to return Base' do
35
43
  expect(subject.class.entity_name).to eq('base')
36
44
  end
37
45
  end
38
46
 
39
47
  describe 'endpoint' do
40
- it 'should return the entity_name' do
48
+ it 'is expected to return the entity_name' do
41
49
  endpoint = 'tests'
42
- KalibroClient::Entities::Base.expects(:entity_name).returns(endpoint)
43
- expect(KalibroClient::Entities::Base.endpoint).to eq(endpoint)
50
+ described_class.expects(:entity_name).returns(endpoint)
51
+ expect(described_class.endpoint).to eq(endpoint)
44
52
  end
45
53
  end
46
54
 
47
55
  describe 'client' do
48
56
  it 'returns a Faraday::Connection' do
49
- expect { KalibroClient::Entities::Base.client }.to raise_error(NotImplementedError)
57
+ expect { described_class.client }.to raise_error(NotImplementedError)
50
58
  end
51
59
  end
52
60
 
53
61
  describe 'request' do
54
- let(:fixture) { File.read("spec/savon/fixtures/project/does_not_exists.xml") }
55
- let(:client) { mock('client') }
56
- let(:response) { mock('response') }
57
- let(:request) { mock('request') }
58
- let(:options) { mock('options') }
62
+ context 'with successful responses' do
63
+ let(:exists_response) { { 'exists' => false } }
64
+ let(:bases_response) { { 'bases' => { 'id' => 1 } } }
65
+ let(:prefix_bases_response) { { 'bases' => { 'id' => 2 } } }
66
+ let(:faraday_stubs) { Faraday::Adapter::Test::Stubs.new }
67
+ let(:connection) { Faraday.new { |builder| builder.adapter :test, faraday_stubs } }
59
68
 
60
- before :each do
61
- options.expects(:timeout=)
62
- options.expects(:open_timeout=)
63
- request.expects(:url).with('/bases/exists')
64
- request.expects(:body=).with({id: 1})
65
- request.expects(:options).twice.returns(options)
69
+ before :each do
70
+ subject.class.expects(:client).at_least_once.returns(connection)
71
+ subject.class.expects(:endpoint).at_least_once.returns('bases')
72
+ end
73
+
74
+ after :each do
75
+ faraday_stubs.verify_stubbed_calls
76
+ end
77
+
78
+ context 'without an id parameter' do
79
+ context 'without a prefix' do
80
+ it 'is expected to make the request without the prefix' do
81
+ # stub.get receives arguments: path, headers, block
82
+ # The block should be a Array [status, headers, body]
83
+ faraday_stubs.get('/bases/') { [200, {}, bases_response] }
84
+ response = subject.class.request('', {}, :get)
85
+ expect(response).to eq(bases_response)
86
+ end
87
+ end
88
+
89
+ context 'with a prefix' do
90
+ it 'is expected to make the request with the prefix' do
91
+ # stub.get receives arguments: path, headers, block
92
+ # The block should be a Array [status, headers, body]
93
+ faraday_stubs.get('/prefix/bases/') { [200, {}, prefix_bases_response] }
94
+ response = subject.class.request('', {}, :get, 'prefix')
95
+ expect(response).to eq(prefix_bases_response)
96
+ end
97
+ end
98
+ end
99
+
100
+ context 'with an id parameter' do
101
+ it 'is expected to make the request with the id included' do
102
+ # stub.get receives arguments: path, headers, block
103
+ # The block should be a Array [status, headers, body]
104
+ faraday_stubs.get('/bases/1/exists') { [200, {}, exists_response] }
105
+ response = subject.class.request(':id/exists', { id: 1 }, :get)
106
+ expect(response).to eq(exists_response)
107
+ end
108
+ end
66
109
  end
67
110
 
68
- context 'for the KalibroClient::Entities module' do
69
- it 'should successfully get the Kalibro version' do
70
- response.expects(:body).returns({exists: false})
71
- client.expects(:post).yields(request).returns(response)
72
- KalibroClient::Entities::Base.expects(:client).with(any_parameters).returns(client)
73
- expect(KalibroClient::Entities::Base.request('exists', {id: 1})[:exists]).to eq(false)
111
+ context 'when the record was not found' do
112
+ context 'and or the status is 404' do
113
+ let!(:faraday_stubs) do
114
+ Faraday::Adapter::Test::Stubs.new do |stub|
115
+ # stub.get receives arguments: path, headers, block
116
+ # The block should be a Array [status, headers, body]
117
+ stub.get('/bases/1') { [404, {}, {}] }
118
+ end
119
+ end
120
+ let!(:connection) { Faraday.new { |builder| builder.adapter :test, faraday_stubs } }
121
+
122
+ before :each do
123
+ described_class.expects(:client).at_least_once.returns(connection)
124
+ end
125
+
126
+ it 'is expected to raise a RecordNotFound error' do
127
+ expect { described_class.request(':id', { id: 1 }, :get) }.to raise_error(KalibroClient::Errors::RecordNotFound)
128
+ faraday_stubs.verify_stubbed_calls
129
+ end
130
+ end
131
+
132
+ context 'and or the response has a NotFound error message' do
133
+ let!(:faraday_stubs) do
134
+ Faraday::Adapter::Test::Stubs.new do |stub|
135
+ # stub.get receives arguments: path, headers, block
136
+ # The block should be a Array [status, headers, body]
137
+ stub.get('/bases/1') { [422, {}, { 'errors' => 'RecordNotFound' }] }
138
+ end
139
+ end
140
+ let!(:connection) { Faraday.new { |builder| builder.adapter :test, faraday_stubs } }
141
+
142
+ before :each do
143
+ described_class.expects(:client).at_least_once.returns(connection)
144
+ end
145
+
146
+ it 'is expected to raise a RecordNotFound error' do
147
+ expect { described_class.request(':id', { id: 1 }, :get) }.to raise_error(KalibroClient::Errors::RecordNotFound)
148
+ faraday_stubs.verify_stubbed_calls
149
+ end
74
150
  end
75
151
  end
76
152
 
77
- context 'with a children class from outside' do
78
- class Child < KalibroClient::Entities::Base; end
153
+ context 'with an unsuccessful request' do
154
+ let!(:stubs) { Faraday::Adapter::Test::Stubs.new { |stub| stub.get('/bases/1/exists') { [500, {}, {}] } } }
155
+ let(:connection) { Faraday.new { |builder| builder.adapter :test, stubs } }
79
156
 
80
- it 'should successfully get the Kalibro version' do
81
- response.expects(:body).returns({exists: false})
82
- client.expects(:post).yields(request).returns(response)
83
- Child.expects(:client).with(any_parameters).returns(client)
84
- expect(Child.request('exists', {id: 1})[:exists]).to eq(false)
157
+ before :each do
158
+ subject.class.expects(:client).at_least_once.returns(connection)
159
+ end
160
+
161
+ it 'is expected to raise a RequestError with the response' do
162
+ expect { subject.class.request(':id/exists', { id: 1 }, :get) }.to raise_error do |error|
163
+ expect(error).to be_a(KalibroClient::Errors::RequestError)
164
+ expect(error.response.status).to eq(500)
165
+ expect(error.response.body).to eq({})
166
+ end
167
+ stubs.verify_stubbed_calls
85
168
  end
86
169
  end
87
170
  end
88
171
 
89
172
  describe 'to_hash' do
90
- it 'should return an empty hash' do
173
+ it 'is expected to return an empty hash' do
91
174
  expect(subject.to_hash).to be_empty
92
175
  end
93
176
  end
94
177
 
95
178
  describe 'to_object' do
96
- it 'should return an Object with an empty hash' do
97
- expect(KalibroClient::Entities::Base.to_object({})).to eq(FactoryGirl.build(:model))
179
+ it 'is expected to return an Object with an empty hash' do
180
+ expect(described_class.to_object({})).to eq(FactoryGirl.build(:model))
98
181
  end
99
182
 
100
- it "should remain an object if it isn't a Hash" do
101
- expect(KalibroClient::Entities::Base.to_object(Object.new)).to be_an(Object)
183
+ it "is expected to remain an object if it isn't a Hash" do
184
+ expect(described_class.to_object(Object.new)).to be_an(Object)
102
185
  end
103
186
  end
104
187
 
105
188
  describe 'to_objects_array' do
106
- it 'should convert [{}] to [Model]' do
107
- expect(KalibroClient::Entities::Base.to_objects_array({})).to eq([FactoryGirl.build(:model)])
189
+ it 'is expected to convert [{}] to [Model]' do
190
+ expect(described_class.to_objects_array({})).to eq([FactoryGirl.build(:model)])
108
191
  end
109
192
 
110
- it 'should remain an array if it already is one' do
193
+ it 'is expected to remain an array if it already is one' do
111
194
  object = Object.new
112
- expect(KalibroClient::Entities::Base.to_objects_array([object])).to eq([object])
195
+ expect(described_class.to_objects_array([object])).to eq([object])
113
196
  end
114
197
  end
115
198
 
116
- describe 'save' do
117
- context "when it is not persisted" do
118
- context "when it doesn't have the method id=" do
119
- before :each do
120
- KalibroClient::Entities::Base.
121
- expects(:request).
122
- with('', {base: {}}, :post, '').returns({"base" => {'id' => 42, 'kalibro_errors' => []}})
199
+ shared_examples 'persistence method' do |method_name, http_method, has_id = true|
200
+ before :each do
201
+ subject.id = 42 if has_id
202
+ end
203
+
204
+ let(:url) { has_id ? ':id' : '' }
205
+ let(:params) { has_id ? has_entry(id: 42) : anything }
206
+
207
+ context 'when a record does not exist with given id' do
208
+ before :each do
209
+ subject.class.expects(:request).with(url, params, http_method, '').
210
+ raises(KalibroClient::Errors::RecordNotFound)
211
+ end
212
+
213
+ it 'is expected to raise a RecordNotFound error' do
214
+ expect { subject.send(method_name) }.to raise_error(KalibroClient::Errors::RecordNotFound)
215
+ end
216
+ end
217
+
218
+ context 'when a server error is returned' do
219
+ before :each do
220
+ error = KalibroClient::Errors::RequestError.new(response: mock(status: 500))
221
+
222
+ subject.class.expects(:request).with(url, params, http_method, '').raises(error)
223
+ end
224
+
225
+ it 'is expected to raise a RequestError error' do
226
+ expect { subject.send(method_name) }.to raise_error(KalibroClient::Errors::RequestError)
227
+ end
228
+ end
229
+
230
+ context 'when a regular kind of error is returned' do
231
+ before :each do
232
+ error = KalibroClient::Errors::RequestError.new(response: mock(status: 422, body: { 'errors' => errors }))
233
+
234
+ subject.class.expects(:request).with(url, params, http_method, '').raises(error)
235
+ end
236
+
237
+ context 'with a single error' do
238
+ let(:errors) { "error" }
239
+
240
+ it 'is expected to set the kalibro_errors field' do
241
+ expect(subject.send(method_name)).to eq(false)
242
+ expect(subject.kalibro_errors).to eq([errors])
123
243
  end
244
+ end
245
+
246
+ context 'with an array of errors' do
247
+ let(:errors) { ["error_1", "error_2"] }
248
+
249
+ it 'is expected to set the kalibro_errors field' do
250
+ expect(subject.send(method_name)).to eq(false)
251
+ expect(subject.kalibro_errors).to eq(errors)
252
+ end
253
+ end
124
254
 
125
- it 'should make a request to save model with id returning false and an error' do
126
- expect(subject.save).to be(false)
127
- expect(subject.kalibro_errors[0]).to be_a(NoMethodError)
255
+ context 'with no error message at all' do
256
+ let(:errors) { nil }
257
+
258
+ it 'is expected to set the kalibro_errors field' do
259
+ expect(subject.send(method_name)).to eq(false)
260
+ expect(subject.kalibro_errors.first).to be_a(KalibroClient::Errors::RequestError)
128
261
  end
129
262
  end
263
+ end
264
+ end
265
+
266
+ describe 'save' do
267
+ it_behaves_like 'persistence method', :save, :post, false # false means Don't use ids in URLs
130
268
 
131
- context 'when it has the method id=' do
269
+ context 'with a successful response' do
270
+ context 'when it is not persisted' do
132
271
  before :each do
133
- KalibroClient::Entities::Base.
134
- expects(:request).
135
- with('', {base: {}}, :post, '').returns({"base" => {'id' => 42, 'kalibro_errors' => []}})
136
- KalibroClient::Entities::Base.any_instance.expects(:id=).with(42).returns(42)
272
+ subject.class.expects(:request).at_least_once.with('', anything, :post, '').
273
+ returns({ "base" => { 'id' => 42, 'errors' => [] } })
137
274
  end
138
275
 
139
- it 'should make a request to save model with id and return true without errors' do
276
+ it 'is expected to make a request to save model with id and return true without errors' do
140
277
  expect(subject.save).to be(true)
278
+ expect(subject.id).to eq(42)
141
279
  expect(subject.kalibro_errors).to be_empty
142
280
  end
143
281
  end
144
282
 
145
- context "when it returns with a kalibro processor error" do
283
+ context 'when it is persisted' do
146
284
  before :each do
147
- KalibroClient::Entities::Base.
148
- expects(:request).
149
- with('', {base: {}}, :post, '').returns({"errors" => ["Name has already been taken"]})
285
+ subject.expects(:persisted?).at_least_once.returns(true)
150
286
  end
151
287
 
152
- it 'should make a request to save model returning false and a kalibro error' do
153
- expect(subject.save).to be(false)
154
- expect(subject.kalibro_errors[0]).to eq("Name has already been taken")
288
+ it 'is expected to call the update method' do
289
+ subject.expects(:update).returns(true)
290
+ expect(subject.save).to eq(true)
155
291
  end
156
292
  end
157
293
  end
294
+ end
295
+
296
+ describe 'update' do
297
+ it_behaves_like 'persistence method', :update, :put
158
298
 
159
- context 'when it is persisted' do
299
+ context 'with valid parameters' do
160
300
  before :each do
161
- subject.persisted = true
162
- end
301
+ id = 42
163
302
 
164
- it 'is expected to call the update method' do
165
- subject.expects(:update)
303
+ subject.expects(:id).at_least_once.returns(id)
304
+ described_class.expects(:request).with(':id', has_entry(id: id), :put, '').
305
+ returns({ "base" => { 'id' => id, 'errors' => [] }})
306
+ end
166
307
 
167
- subject.save
308
+ it 'is expected to return true' do
309
+ expect(subject.update).to eq(true)
168
310
  end
169
311
  end
170
312
  end
171
313
 
172
- describe 'update' do
173
- let!(:id) { 42 }
314
+ describe 'create' do
315
+ before :each do
316
+ subject.expects(:save)
317
+ described_class.
318
+ expects(:new).
319
+ with({}).
320
+ returns(subject)
321
+ end
174
322
 
175
- context 'with valid parameters' do
323
+ it 'is expected to instantiate and save the model' do
324
+ expect(described_class.create {}).to eq(subject)
325
+ end
326
+ end
327
+
328
+ describe 'find' do
329
+ context 'with an inexistent id' do
176
330
  before :each do
177
- KalibroClient::Entities::Base.
178
- expects(:request).
179
- with(':id', {base: {}, id: id}, :put, '').returns({"base" => {'id' => id, 'kalibro_errors' => []}})
180
- subject.expects(:id).returns(id)
181
- subject.expects(:to_hash).returns({})
331
+ subject.class.expects(:request).at_least_once.with(':id', has_entry(id: 0), :get).
332
+ raises(KalibroClient::Errors::RecordNotFound)
182
333
  end
183
334
 
184
- it 'is expect to return true' do
185
- expect(subject.update).to be_truthy
335
+ it 'is expected to raise a RecordNotFound error' do
336
+ expect { subject.class.find(0) }.to raise_error(KalibroClient::Errors::RecordNotFound)
186
337
  end
187
338
  end
188
339
 
189
- context 'with invalid parameters' do
340
+ context 'with an existent id' do
190
341
  before :each do
191
- KalibroClient::Entities::Base.
192
- expects(:request).
193
- with(':id', {base: {}, id: id}, :put, '').returns({"errors" => ["Error"]})
194
- subject.expects(:id).returns(id)
195
- subject.expects(:to_hash).returns({})
342
+ subject.class.expects(:request).with(':id', has_entry(id: 42), :get).
343
+ returns("base" => { 'id' => 42 })
196
344
  end
197
345
 
198
- it 'is expect to return false' do
199
- expect(subject.update).to be_falsey
346
+ it 'is expected to return an empty model' do
347
+ expect(subject.class.find(42).id).to eq(42)
200
348
  end
349
+ end
350
+ end
201
351
 
202
- it 'is expect fill the errors' do
203
- subject.update
352
+ describe 'destroy' do
353
+ it_behaves_like 'persistence method', :destroy, :delete
204
354
 
205
- expect(subject.kalibro_errors).to_not be_empty
355
+ context 'when it gets successfully destroyed' do
356
+ before :each do
357
+ subject.expects(:id).at_least_once.returns(42)
358
+ described_class.expects(:request).with(':id', { id: subject.id }, :delete, '').returns({})
359
+ end
360
+
361
+ it 'is expected to remain with the errors array empty and not persisted' do
362
+ subject.destroy
363
+ expect(subject.kalibro_errors).to be_empty
364
+ expect(subject.persisted?).to eq(false)
206
365
  end
207
366
  end
208
367
  end
209
368
 
210
369
  describe 'save!' do
211
- subject { FactoryGirl.build(:project) }
212
-
213
- it 'should call save' do
214
- subject.expects(:save)
215
- subject.save!
370
+ it 'is expected to call save and not raise when saving works' do
371
+ subject.expects(:save).returns(true)
372
+ expect { subject.save! }.not_to raise_error
216
373
  end
217
- end
218
374
 
219
- describe 'create' do
220
- before :each do
221
- subject.expects(:save)
222
- KalibroClient::Entities::Base.
223
- expects(:new).
224
- with({}).
225
- returns(subject)
226
- end
375
+ it 'is expected to call save and raise RecordInvalid when saving fails' do
376
+ subject.expects(:kalibro_errors).returns(['test1', 'test2'])
377
+ subject.expects(:save).returns(false)
227
378
 
228
- it 'should instantiate and save the model' do
229
- expect(KalibroClient::Entities::Base.create {}).to eq(subject)
379
+ expect { subject.save! }.to raise_error { |error|
380
+ expect(error).to be_a(KalibroClient::Errors::RecordInvalid)
381
+ expect(error.record).to be(subject)
382
+ expect(error.message).to eq('Record invalid: test1, test2')
383
+ }
230
384
  end
231
385
  end
232
386
 
233
387
  describe '==' do
388
+ subject { FactoryGirl.build(:model) }
389
+
234
390
  context 'comparing objects from different classes' do
235
- it 'should return false' do
391
+ it 'is expected to return false' do
236
392
  expect(subject).not_to eq(Object.new)
237
393
  end
238
394
  end
239
395
 
240
396
  context 'with two models with different attribute values' do
241
397
  let(:another_model) { FactoryGirl.build(:model) }
398
+
242
399
  before :each do
243
400
  subject.expects(:variable_names).returns(["answer"])
244
401
  subject.expects(:send).with("answer").returns(42)
245
402
  another_model.expects(:send).with("answer").returns(41)
246
403
  end
247
404
 
248
- it 'should return false' do
405
+ it 'is expected to return false' do
249
406
  expect(subject).not_to eq(another_model)
250
407
  end
251
408
  end
252
409
 
253
410
  context 'with two empty models' do
254
- it 'should return true' do
411
+ it 'is expected to return true' do
255
412
  expect(subject).to eq(FactoryGirl.build(:model))
256
413
  end
257
414
  end
@@ -260,135 +417,69 @@ describe KalibroClient::Entities::Base do
260
417
  describe 'exists?' do
261
418
  context 'with an inexistent id' do
262
419
  before :each do
263
- KalibroClient::Entities::Base.
264
- expects(:request).
265
- with(':id/exists', {id: 0}, :get).
266
- returns({'exists' => false})
267
- end
268
-
269
- it 'should return false' do
270
- expect(KalibroClient::Entities::Base.exists?(0)).to eq(false)
271
- end
272
- end
273
-
274
- context 'with an existent id' do
275
- before :each do
276
- KalibroClient::Entities::Base.
420
+ described_class.
277
421
  expects(:request).
278
- with(':id/exists', {id: 42}, :get).
279
- returns({'exists' => true})
280
- end
281
-
282
- it 'should return false' do
283
- expect(KalibroClient::Entities::Base.exists?(42)).to eq(true)
284
- end
285
- end
286
- end
287
-
288
- describe 'find' do
289
- context 'with an inexistent id' do
290
- before :each do
291
- KalibroClient::Entities::Base.expects(:exists?).with(0).returns(false)
422
+ with(':id/exists', { id: 0 }, :get).
423
+ returns({ 'exists' => false })
292
424
  end
293
425
 
294
- it 'should raise a RecordNotFound error' do
295
- expect { KalibroClient::Entities::Base.find(0)}.to raise_error(KalibroClient::Errors::RecordNotFound)
426
+ it 'is expected to return false' do
427
+ expect(described_class.exists?(0)).to eq(false)
296
428
  end
297
429
  end
298
430
 
299
431
  context 'with an existent id' do
300
432
  before :each do
301
- KalibroClient::Entities::Base.
302
- expects(:exists?).with(42).
303
- returns(true)
304
- KalibroClient::Entities::Base.
433
+ described_class.
305
434
  expects(:request).
306
- with(':id',{id: 42}, :get).returns("base" => {})
435
+ with(':id/exists', { id: 42 }, :get).
436
+ returns({ 'exists' => true })
307
437
  end
308
438
 
309
- it 'should return an empty model' do
310
- expect(KalibroClient::Entities::Base.find(42)).to eq(subject)
311
- end
312
- end
313
- end
314
-
315
- describe 'destroy' do
316
- context 'when it gets successfully destroyed' do
317
- before :each do
318
- subject.expects(:id).at_least_once.returns(42)
319
- KalibroClient::Entities::Base.expects(:request).with(':id',{id: subject.id}, :delete, '').returns({})
320
- end
321
-
322
- it 'should remain with the errors array empty and not persisted' do
323
- subject.destroy
324
- expect(subject.kalibro_errors).to be_empty
325
- expect(subject.persisted?).to be_falsey
326
- end
327
- end
328
-
329
- context 'when the destruction fails' do
330
- context 'raising a exception' do
331
- before :each do
332
- subject.expects(:id).at_least_once.returns(42)
333
- KalibroClient::Entities::Base.expects(:request).with(':id',{id: subject.id}, :delete, '').raises(Exception.new)
334
- end
335
-
336
- it "should have an exception inside it's errors" do
337
- subject.destroy
338
-
339
- expect(subject.kalibro_errors[0]).to be_an(Exception)
340
- end
341
- end
342
-
343
- context 'returning kalibro_errors' do
344
- before :each do
345
- subject.expects(:id).at_least_once.returns(42)
346
- KalibroClient::Entities::Base.expects(:request).with(':id',{id: subject.id}, :delete, '').returns({'errors' => ['Error']})
347
- end
348
-
349
- it 'is expected to return false' do
350
- expect(subject.destroy).to be_falsey
351
- end
439
+ it 'is expected to return false' do
440
+ expect(described_class.exists?(42)).to eq(true)
352
441
  end
353
442
  end
354
443
  end
355
444
 
356
445
  describe 'create_objects_array_from_hash' do
446
+ subject { FactoryGirl.build(:model) }
447
+
357
448
  context 'with nil' do
358
- it 'should return an empty array' do
359
- expect(KalibroClient::Entities::Base.create_objects_array_from_hash("bases" => [])).to eq([])
449
+ it 'is expected to return an empty array' do
450
+ expect(described_class.create_objects_array_from_hash("bases" => [])).to eq([])
360
451
  end
361
452
  end
362
453
 
363
454
  context 'with a Hash' do
364
- it 'should return the correspondent object to the given hash inside of an Array' do
365
- expect(KalibroClient::Entities::Base.create_objects_array_from_hash("bases" => {})).to eq([subject])
455
+ it 'is expected to return the correspondent object to the given hash inside of an Array' do
456
+ expect(described_class.create_objects_array_from_hash("bases" => {})).to eq([subject])
366
457
  end
367
458
  end
368
459
  end
369
460
 
370
461
  describe 'is_valid?' do
371
462
  context 'with a global var' do
372
- it 'should return false' do
373
- expect(KalibroClient::Entities::Base.is_valid?('@test')).to be_falsey
463
+ it 'is expected to return false' do
464
+ expect(described_class.is_valid?('@test')).to be_falsey
374
465
  end
375
466
  end
376
467
 
377
468
  context 'with the attributes var' do
378
- it 'should return false' do
379
- expect(KalibroClient::Entities::Base.is_valid?(:attributes!)).to be_falsey
469
+ it 'is expected to return false' do
470
+ expect(described_class.is_valid?(:attributes!)).to be_falsey
380
471
  end
381
472
  end
382
473
 
383
474
  context 'with a xsi var' do
384
- it 'should return false' do
385
- expect(KalibroClient::Entities::Base.is_valid?('test_xsi')).to be_falsey
475
+ it 'is expected to return false' do
476
+ expect(described_class.is_valid?('test_xsi')).to be_falsey
386
477
  end
387
478
  end
388
479
 
389
480
  context 'with a valid var' do
390
- it 'should return true' do
391
- expect(KalibroClient::Entities::Base.is_valid?('test')).to be_truthy
481
+ it 'is expected to return true' do
482
+ expect(described_class.is_valid?('test')).to be_truthy
392
483
  end
393
484
  end
394
485
  end