conjur-api 4.10.1 → 4.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile +0 -4
- data/conjur-api.gemspec +3 -1
- data/lib/conjur-api/version.rb +1 -1
- data/lib/conjur/base.rb +21 -4
- data/lib/conjur/configuration.rb +1 -6
- data/lib/conjur/resource.rb +1 -11
- data/spec/api/authn_spec.rb +11 -11
- data/spec/api/hosts_spec.rb +3 -3
- data/spec/api/layer_spec.rb +1 -1
- data/spec/api/pubkeys_spec.rb +4 -4
- data/spec/api/resources_spec.rb +5 -5
- data/spec/api/roles_spec.rb +6 -2
- data/spec/api/users_spec.rb +4 -4
- data/spec/api/variables_spec.rb +10 -10
- data/spec/lib/annotations_spec.rb +17 -17
- data/spec/lib/api_spec.rb +118 -59
- data/spec/lib/asset_spec.rb +11 -11
- data/spec/lib/audit_spec.rb +4 -4
- data/spec/lib/build_from_response_spec.rb +7 -7
- data/spec/lib/configuration_spec.rb +109 -49
- data/spec/lib/deputy_spec.rb +19 -6
- data/spec/lib/exists_spec.rb +15 -13
- data/spec/lib/host_spec.rb +10 -3
- data/spec/lib/log_source_spec.rb +1 -1
- data/spec/lib/log_spec.rb +5 -5
- data/spec/lib/resource_spec.rb +23 -53
- data/spec/lib/role_grant_spec.rb +3 -3
- data/spec/lib/role_spec.rb +54 -34
- data/spec/lib/standard_methods_spec.rb +15 -15
- data/spec/lib/user_spec.rb +32 -12
- data/spec/spec_helper.rb +9 -10
- data/spec/standard_methods_helper.rb +6 -6
- data/spec/variable_spec.rb +12 -7
- metadata +36 -14
- data/.rspec +0 -2
data/spec/lib/api_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'timecop'
|
2
3
|
|
3
4
|
shared_examples_for "API endpoint" do
|
4
5
|
before { Conjur.configuration = Conjur::Configuration.new }
|
@@ -6,30 +7,42 @@ shared_examples_for "API endpoint" do
|
|
6
7
|
let(:service_name) { api.name.split('::')[-2].downcase }
|
7
8
|
context "in development" do
|
8
9
|
before(:each) do
|
9
|
-
Conjur::Configuration.
|
10
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "development"
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#host' do
|
14
|
+
subject { super().host }
|
15
|
+
it do
|
16
|
+
is_expected.to eq("http://localhost:#{Conjur.configuration.service_base_port + port_offset}")
|
10
17
|
end
|
11
|
-
its "host" do
|
12
|
-
should == "http://localhost:#{Conjur.configuration.service_base_port + port_offset}"
|
13
18
|
end
|
14
19
|
end
|
15
20
|
context "'ci' account" do
|
16
21
|
before {
|
17
|
-
Conjur::Configuration.
|
22
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:account).and_return 'ci'
|
18
23
|
}
|
19
24
|
context "in stage" do
|
20
25
|
before(:each) do
|
21
|
-
Conjur::Configuration.
|
26
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "stage"
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#host' do
|
30
|
+
subject { super().host }
|
31
|
+
it do
|
32
|
+
is_expected.to eq("https://#{service_name}-ci-conjur.herokuapp.com")
|
22
33
|
end
|
23
|
-
its "host" do
|
24
|
-
should == "https://#{service_name}-ci-conjur.herokuapp.com"
|
25
34
|
end
|
26
35
|
end
|
27
36
|
context "in ci" do
|
28
37
|
before(:each) do
|
29
|
-
Conjur::Configuration.
|
38
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "ci"
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#host' do
|
42
|
+
subject { super().host }
|
43
|
+
it do
|
44
|
+
is_expected.to eq("https://#{service_name}-ci-conjur.herokuapp.com")
|
30
45
|
end
|
31
|
-
its "host" do
|
32
|
-
should == "https://#{service_name}-ci-conjur.herokuapp.com"
|
33
46
|
end
|
34
47
|
end
|
35
48
|
end
|
@@ -58,39 +71,39 @@ describe Conjur::API do
|
|
58
71
|
context "for short id (2 tokens)" do
|
59
72
|
let(:id) { "token#1:token#2" }
|
60
73
|
let(:current_account) { "current_account" }
|
61
|
-
before(:each) { Conjur::Core::API.
|
74
|
+
before(:each) { allow(Conjur::Core::API).to receive(:conjur_account).and_return current_account }
|
62
75
|
|
63
76
|
it "account: current account" do
|
64
|
-
subject[0].
|
77
|
+
expect(subject[0]).to eq(current_account)
|
65
78
|
end
|
66
79
|
|
67
80
|
it "kind: passed kind" do
|
68
|
-
subject[1].
|
81
|
+
expect(subject[1]).to eq(kind)
|
69
82
|
end
|
70
83
|
|
71
84
|
it "subkind: token #1 (escaped)" do
|
72
|
-
subject[2].
|
85
|
+
expect(subject[2]).to eq(escaped("token#1"))
|
73
86
|
end
|
74
87
|
|
75
88
|
it "id: token #2 (escaped)" do
|
76
|
-
subject[3].
|
89
|
+
expect(subject[3]).to eq(escaped("token#2"))
|
77
90
|
end
|
78
91
|
end
|
79
92
|
|
80
93
|
context "for long ids (3+ tokens)" do
|
81
94
|
let(:id) { "token#1:token#2:token#3:token#4" }
|
82
95
|
it "account: token #1 (escaped)" do
|
83
|
-
subject[0].
|
96
|
+
expect(subject[0]).to eq(escaped("token#1"))
|
84
97
|
end
|
85
98
|
|
86
99
|
it "kind: passed kind" do
|
87
|
-
subject[1].
|
100
|
+
expect(subject[1]).to eq(kind)
|
88
101
|
end
|
89
102
|
it "subkind: token #2 (escaped)" do
|
90
|
-
subject[2].
|
103
|
+
expect(subject[2]).to eq(escaped("token#2"))
|
91
104
|
end
|
92
105
|
it "id: tail of id starting from token#3" do
|
93
|
-
subject[3].
|
106
|
+
expect(subject[3]).to eq(escaped("token#3:token#4"))
|
94
107
|
end
|
95
108
|
end
|
96
109
|
|
@@ -101,12 +114,12 @@ describe Conjur::API do
|
|
101
114
|
let(:id) { :input_id }
|
102
115
|
|
103
116
|
it "#parse_role_id(id): calls parse_id(id, 'roles') and returns result" do
|
104
|
-
Conjur::API.
|
105
|
-
Conjur::API.parse_role_id(id).
|
117
|
+
expect(Conjur::API).to receive(:parse_id).with(id, 'roles').and_return(result)
|
118
|
+
expect(Conjur::API.parse_role_id(id)).to eq(result)
|
106
119
|
end
|
107
120
|
it "#parse_resource_id(id): calls parse_id(id, 'resources') and returns result" do
|
108
|
-
Conjur::API.
|
109
|
-
Conjur::API.parse_resource_id(id).
|
121
|
+
expect(Conjur::API).to receive(:parse_id).with(id, 'resources').and_return(result)
|
122
|
+
expect(Conjur::API.parse_resource_id(id)).to eq(result)
|
110
123
|
end
|
111
124
|
end
|
112
125
|
end
|
@@ -124,57 +137,81 @@ describe Conjur::API do
|
|
124
137
|
subject { api }
|
125
138
|
context "'ci' account" do
|
126
139
|
before {
|
127
|
-
Conjur::Configuration.
|
140
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:account).and_return 'ci'
|
128
141
|
}
|
129
142
|
context "in stage" do
|
130
143
|
before(:each) do
|
131
|
-
Conjur::Configuration.
|
144
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "stage"
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#host' do
|
148
|
+
subject { super().host }
|
149
|
+
it do
|
150
|
+
is_expected.to eq("https://authz-stage-conjur.herokuapp.com")
|
132
151
|
end
|
133
|
-
its "host" do
|
134
|
-
should == "https://authz-stage-conjur.herokuapp.com"
|
135
152
|
end
|
136
153
|
end
|
137
154
|
context "in ci" do
|
138
155
|
before(:each) do
|
139
156
|
# Looks at "ENV['CONJUR_STACK']" first, stub this out
|
140
|
-
ENV.
|
141
|
-
Conjur::Configuration.
|
157
|
+
allow(ENV).to receive(:[]).with('CONJUR_STACK').and_return nil
|
158
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "ci"
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '#host' do
|
162
|
+
subject { super().host }
|
163
|
+
it do
|
164
|
+
is_expected.to eq("https://authz-ci-conjur.herokuapp.com")
|
142
165
|
end
|
143
|
-
its "host" do
|
144
|
-
should == "https://authz-ci-conjur.herokuapp.com"
|
145
166
|
end
|
146
167
|
end
|
147
168
|
context "when ENV['CONJUR_STACK'] is set to 'v12'" do
|
148
169
|
before do
|
149
|
-
Conjur::Configuration.
|
150
|
-
Conjur::Configuration.
|
170
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:stack).and_return "v12"
|
171
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "ci"
|
172
|
+
end
|
173
|
+
|
174
|
+
describe '#host' do
|
175
|
+
subject { super().host }
|
176
|
+
it { is_expected.to eq("https://authz-v12-conjur.herokuapp.com")}
|
151
177
|
end
|
152
|
-
its(:host){ should == "https://authz-v12-conjur.herokuapp.com"}
|
153
178
|
end
|
154
179
|
end
|
155
180
|
context "in production" do
|
156
181
|
before(:each) do
|
157
|
-
Conjur::Configuration.
|
182
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "production"
|
183
|
+
end
|
184
|
+
|
185
|
+
describe '#host' do
|
186
|
+
subject { super().host }
|
187
|
+
it do
|
188
|
+
is_expected.to eq("https://authz-v4-conjur.herokuapp.com")
|
158
189
|
end
|
159
|
-
its "host" do
|
160
|
-
should == "https://authz-v4-conjur.herokuapp.com"
|
161
190
|
end
|
162
191
|
end
|
163
192
|
context "in appliance" do
|
164
193
|
before(:each) do
|
165
|
-
Conjur::Configuration.
|
194
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "appliance"
|
195
|
+
end
|
196
|
+
|
197
|
+
describe '#host' do
|
198
|
+
subject { super().host }
|
199
|
+
it do
|
200
|
+
is_expected.to eq("http://localhost:5100")
|
166
201
|
end
|
167
|
-
its "host" do
|
168
|
-
should == "http://localhost:5100"
|
169
202
|
end
|
170
203
|
end
|
171
204
|
context "in named production version" do
|
172
205
|
before(:each) do
|
173
|
-
Conjur::Configuration.
|
174
|
-
Conjur::Configuration.
|
206
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:env).and_return "production"
|
207
|
+
allow_any_instance_of(Conjur::Configuration).to receive(:stack).and_return "waffle"
|
208
|
+
end
|
209
|
+
|
210
|
+
describe '#host' do
|
211
|
+
subject { super().host }
|
212
|
+
it do
|
213
|
+
is_expected.to eq("https://authz-waffle-conjur.herokuapp.com")
|
175
214
|
end
|
176
|
-
its "host" do
|
177
|
-
should == "https://authz-waffle-conjur.herokuapp.com"
|
178
215
|
end
|
179
216
|
end
|
180
217
|
end
|
@@ -187,49 +224,71 @@ describe Conjur::API do
|
|
187
224
|
|
188
225
|
shared_context logged_in: true do
|
189
226
|
let(:login) { "bob" }
|
190
|
-
let(:token) { { 'data' => login, 'timestamp' =>
|
191
|
-
let(:elapsed) { 0 }
|
227
|
+
let(:token) { { 'data' => login, 'timestamp' => Time.now.to_s } }
|
192
228
|
subject { api }
|
193
229
|
let(:api) { Conjur::API.new_from_token(token) }
|
194
230
|
let(:account) { 'some-account' }
|
195
|
-
before { Conjur::Core::API.
|
231
|
+
before { allow(Conjur::Core::API).to receive_messages conjur_account: account }
|
196
232
|
end
|
197
233
|
|
198
234
|
context "credential handling", logged_in: true do
|
199
235
|
context "from token" do
|
200
|
-
|
201
|
-
|
236
|
+
describe '#token' do
|
237
|
+
subject { super().token }
|
238
|
+
it { is_expected.to eq(token) }
|
239
|
+
end
|
240
|
+
|
241
|
+
describe '#credentials' do
|
242
|
+
subject { super().credentials }
|
243
|
+
it { is_expected.to eq({ headers: { authorization: "Token token=\"#{Base64.strict_encode64(token.to_json)}\"" }, username: login }) }
|
244
|
+
end
|
202
245
|
end
|
246
|
+
|
203
247
|
context "from api key", logged_in: true do
|
204
248
|
let(:api_key) { "theapikey" }
|
205
249
|
let(:api) { Conjur::API.new_from_key(login, api_key) }
|
206
250
|
subject { api }
|
251
|
+
|
207
252
|
it("should authenticate to get a token") do
|
208
|
-
Conjur::API.
|
253
|
+
expect(Conjur::API).to receive(:authenticate).with(login, api_key).and_return token
|
209
254
|
|
210
|
-
api.instance_variable_get("@token").
|
211
|
-
api.token.
|
212
|
-
api.credentials.
|
255
|
+
expect(api.instance_variable_get("@token")).to eq(nil)
|
256
|
+
expect(api.token).to eq(token)
|
257
|
+
expect(api.credentials).to eq({ headers: { authorization: "Token token=\"#{Base64.strict_encode64(token.to_json)}\"" }, username: login })
|
258
|
+
end
|
259
|
+
|
260
|
+
context "with an expired token" do
|
261
|
+
it "fetches a new one" do
|
262
|
+
allow(Conjur::API).to receive(:authenticate).with(login, api_key).and_return token
|
263
|
+
expect(Time.parse(api.token['timestamp'])).to be_within(5.seconds).of(Time.now)
|
264
|
+
|
265
|
+
Timecop.travel Time.now + 6.minutes
|
266
|
+
new_token = token.merge "timestamp" => Time.now.to_s
|
267
|
+
|
268
|
+
expect(Conjur::API).to receive(:authenticate).with(login, api_key).and_return new_token
|
269
|
+
expect(api.token).to eq(new_token)
|
270
|
+
end
|
213
271
|
end
|
214
272
|
end
|
273
|
+
|
215
274
|
context "from logged-in RestClient::Resource" do
|
216
275
|
let(:token_encoded) { Base64.strict_encode64(token.to_json) }
|
217
276
|
let(:resource) { RestClient::Resource.new("http://example.com", { headers: { authorization: "Token token=\"#{token_encoded}\"" } })}
|
218
277
|
it "can construct a new API instance" do
|
219
278
|
api = resource.conjur_api
|
220
|
-
api.credentials[:headers][:authorization].
|
221
|
-
api.credentials[:username].
|
279
|
+
expect(api.credentials[:headers][:authorization]).to eq("Token token=\"#{token_encoded}\"")
|
280
|
+
expect(api.credentials[:username]).to eq("bob")
|
222
281
|
end
|
223
282
|
end
|
224
283
|
end
|
225
284
|
|
226
285
|
describe "#role_from_username", logged_in: true do
|
227
286
|
it "returns a user role when username is plain" do
|
228
|
-
api.role_from_username("plain-username").roleid.
|
287
|
+
expect(api.role_from_username("plain-username").roleid).to eq("#{account}:user:plain-username")
|
229
288
|
end
|
230
289
|
|
231
290
|
it "returns an appropriate role kind when username is qualified" do
|
232
|
-
api.role_from_username("host/foo/bar").roleid.
|
291
|
+
expect(api.role_from_username("host/foo/bar").roleid).to eq("#{account}:host:foo/bar")
|
233
292
|
end
|
234
293
|
end
|
235
294
|
|
@@ -237,7 +296,7 @@ describe Conjur::API do
|
|
237
296
|
context "when logged in as user" do
|
238
297
|
let(:login) { 'joerandom' }
|
239
298
|
it "returns a user role" do
|
240
|
-
api.current_role.roleid.
|
299
|
+
expect(api.current_role.roleid).to eq("#{account}:user:joerandom")
|
241
300
|
end
|
242
301
|
end
|
243
302
|
|
@@ -245,7 +304,7 @@ describe Conjur::API do
|
|
245
304
|
let(:host) { "somehost" }
|
246
305
|
let(:login) { "host/#{host}" }
|
247
306
|
it "returns a host role" do
|
248
|
-
api.current_role.roleid.
|
307
|
+
expect(api.current_role.roleid).to eq("#{account}:host:somehost")
|
249
308
|
end
|
250
309
|
end
|
251
310
|
end
|
data/spec/lib/asset_spec.rb
CHANGED
@@ -23,10 +23,10 @@ describe Conjur::ActsAsAsset do
|
|
23
23
|
|
24
24
|
shared_context "asset with role" do
|
25
25
|
before(:each) {
|
26
|
-
asset.
|
27
|
-
asset.
|
28
|
-
asset.
|
29
|
-
Conjur::Role.
|
26
|
+
allow(asset).to receive(:core_conjur_account).and_return(ACCOUNT)
|
27
|
+
allow(asset).to receive(:resource_kind).and_return(KIND)
|
28
|
+
allow(asset).to receive(:resource_id).and_return(ID)
|
29
|
+
allow(Conjur::Role).to receive(:new).and_return(role_base)
|
30
30
|
}
|
31
31
|
let(:role_base) {
|
32
32
|
double(:"[]" => role_instance)
|
@@ -38,21 +38,21 @@ describe Conjur::ActsAsAsset do
|
|
38
38
|
|
39
39
|
shared_examples_for "it obtains role via asset" do
|
40
40
|
it "account=asset.core_conjur_account" do
|
41
|
-
asset.
|
41
|
+
expect(asset).to receive(:core_conjur_account)
|
42
42
|
invoke
|
43
43
|
end
|
44
44
|
it "kind=asset.resource_kind" do
|
45
|
-
asset.
|
45
|
+
expect(asset).to receive(:resource_kind)
|
46
46
|
invoke
|
47
47
|
end
|
48
48
|
it "id=asset.resource_id" do
|
49
|
-
asset.
|
49
|
+
expect(asset).to receive(:resource_id)
|
50
50
|
invoke
|
51
51
|
end
|
52
52
|
|
53
53
|
it "obtains role as #{ACCOUNT}:@:#{KIND}/#{ID}/#{ROLE}" do
|
54
|
-
Conjur::Role.
|
55
|
-
role_base.
|
54
|
+
expect(Conjur::Role).to receive(:new).with("http://localhost:5100", {}).and_return role_base
|
55
|
+
expect(role_base).to receive(:[]).with("#{CGI.escape ACCOUNT}/roles/@/#{KIND}/#{ID}/#{CGI.escape ROLE}").and_return role_instance
|
56
56
|
|
57
57
|
invoke
|
58
58
|
end
|
@@ -63,7 +63,7 @@ describe Conjur::ActsAsAsset do
|
|
63
63
|
include_context "asset with role"
|
64
64
|
it_behaves_like "it obtains role via asset"
|
65
65
|
it 'calls role.grant_to(member,...)' do
|
66
|
-
role_instance.
|
66
|
+
expect(role_instance).to receive(:grant_to).with(MEMBER, anything)
|
67
67
|
invoke
|
68
68
|
end
|
69
69
|
end
|
@@ -73,7 +73,7 @@ describe Conjur::ActsAsAsset do
|
|
73
73
|
include_context "asset with role"
|
74
74
|
it_behaves_like "it obtains role via asset"
|
75
75
|
it 'calls role.revoke_from(member)' do
|
76
|
-
role_instance.
|
76
|
+
expect(role_instance).to receive(:revoke_from).with(MEMBER)
|
77
77
|
invoke
|
78
78
|
end
|
79
79
|
end
|
data/spec/lib/audit_spec.rb
CHANGED
@@ -12,7 +12,7 @@ describe Conjur::API, api: :dummy do
|
|
12
12
|
let(:expected_url){ "#{Conjur::Audit::API.host}/#{expected_path}#{query}" }
|
13
13
|
|
14
14
|
def expect_request
|
15
|
-
RestClient::Request.
|
15
|
+
expect(RestClient::Request).to receive(:execute).with(
|
16
16
|
headers: credentials[:headers],
|
17
17
|
url: expected_url,
|
18
18
|
method: :get
|
@@ -28,7 +28,7 @@ describe Conjur::API, api: :dummy do
|
|
28
28
|
shared_examples_for "gets all visible events" do
|
29
29
|
it "GETs /" do
|
30
30
|
expect_request
|
31
|
-
api.audit(*full_args).
|
31
|
+
expect(api.audit(*full_args)).to eq(response)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -52,7 +52,7 @@ describe Conjur::API, api: :dummy do
|
|
52
52
|
shared_examples_for "gets roles feed" do
|
53
53
|
it "GETs roles/:role_id" do
|
54
54
|
expect_request
|
55
|
-
api.audit_role(*full_args).
|
55
|
+
expect(api.audit_role(*full_args)).to eq(response)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -83,7 +83,7 @@ describe Conjur::API, api: :dummy do
|
|
83
83
|
shared_examples_for "gets the resource feed" do
|
84
84
|
it "GETS resources/:resource_id" do
|
85
85
|
expect_request
|
86
|
-
api.audit_resource(*full_args).
|
86
|
+
expect(api.audit_resource(*full_args)).to eq(response)
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -13,11 +13,11 @@ describe Conjur::BuildFromResponse do
|
|
13
13
|
|
14
14
|
before do
|
15
15
|
subject.extend Conjur::BuildFromResponse
|
16
|
-
subject.
|
17
|
-
constructed.
|
16
|
+
expect(subject).to receive(:new).with(location, credentials).and_return constructed
|
17
|
+
expect(constructed).to receive(:attributes=).with attrs
|
18
18
|
|
19
19
|
constructed.extend Conjur::LogSource
|
20
|
-
constructed.
|
20
|
+
allow(constructed).to receive_messages username: 'whatever'
|
21
21
|
end
|
22
22
|
|
23
23
|
it "passes the location credentials and attributes" do
|
@@ -26,23 +26,23 @@ describe Conjur::BuildFromResponse do
|
|
26
26
|
|
27
27
|
context "with a resource(-ish) class" do
|
28
28
|
before do
|
29
|
-
constructed.
|
29
|
+
allow(constructed).to receive_messages resource_kind: 'chunky', resource_id: 'bacon'
|
30
30
|
end
|
31
31
|
|
32
32
|
it "logs creation correctly" do
|
33
33
|
subject.build_from_response response, credentials
|
34
|
-
log.
|
34
|
+
expect(log).to match(/Created chunky bacon/)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
context "with a id(-ish) class" do
|
39
39
|
before do
|
40
|
-
constructed.
|
40
|
+
allow(constructed).to receive_messages id: 'bacon'
|
41
41
|
end
|
42
42
|
|
43
43
|
it "logs creation correctly" do
|
44
44
|
subject.build_from_response response, credentials
|
45
|
-
log.
|
45
|
+
expect(log).to match(/Created some bacon/)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|