journaled 2.0.0.alpha1 → 2.0.0.rc1
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/README.md +95 -25
- data/app/models/concerns/journaled/changes.rb +41 -0
- data/app/models/journaled/actor_uri_provider.rb +22 -0
- data/app/models/journaled/change_definition.rb +17 -1
- data/app/models/journaled/change_writer.rb +3 -22
- data/app/models/journaled/event.rb +0 -4
- data/config/initializers/change_protection.rb +3 -0
- data/lib/journaled.rb +9 -1
- data/lib/journaled/relation_change_protection.rb +27 -0
- data/lib/journaled/rspec.rb +18 -0
- data/lib/journaled/version.rb +1 -1
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +21 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +78 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/migrate/20180606205114_create_delayed_jobs.rb +18 -0
- data/spec/dummy/db/schema.rb +31 -0
- data/spec/dummy/log/development.log +34 -0
- data/spec/dummy/log/test.log +34540 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/lib/journaled_spec.rb +51 -0
- data/spec/models/concerns/journaled/actor_spec.rb +46 -0
- data/spec/models/concerns/journaled/changes_spec.rb +94 -0
- data/spec/models/database_change_protection_spec.rb +106 -0
- data/spec/models/journaled/actor_uri_provider_spec.rb +41 -0
- data/spec/models/journaled/change_writer_spec.rb +276 -0
- data/spec/models/journaled/delivery_spec.rb +156 -0
- data/spec/models/journaled/event_spec.rb +145 -0
- data/spec/models/journaled/json_schema_model/validator_spec.rb +133 -0
- data/spec/models/journaled/writer_spec.rb +129 -0
- data/spec/rails_helper.rb +20 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/delayed_job_spec_helper.rb +11 -0
- data/spec/support/environment_spec_helper.rb +16 -0
- metadata +113 -4
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe Journaled::ActorUriProvider do
|
4
|
+
describe "#actor_uri" do
|
5
|
+
let(:request_store) { double(:[] => nil) }
|
6
|
+
let(:actor) { double(to_global_id: actor_gid) }
|
7
|
+
let(:actor_gid) { double(to_s: "my_fancy_gid") }
|
8
|
+
let(:program_name) { "/usr/local/bin/puma_or_something" }
|
9
|
+
|
10
|
+
subject { described_class.instance }
|
11
|
+
|
12
|
+
around do |example|
|
13
|
+
orig_program_name = $PROGRAM_NAME
|
14
|
+
$PROGRAM_NAME = program_name
|
15
|
+
example.run
|
16
|
+
$PROGRAM_NAME = orig_program_name
|
17
|
+
end
|
18
|
+
|
19
|
+
before do
|
20
|
+
allow(RequestStore).to receive(:store).and_return(request_store)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns the global ID of the entity returned by RequestStore.store[:journaled_actor_proc].call if set" do
|
24
|
+
allow(request_store).to receive(:[]).and_return(-> { actor })
|
25
|
+
expect(subject.actor_uri).to eq("my_fancy_gid")
|
26
|
+
expect(request_store).to have_received(:[]).with(:journaled_actor_proc)
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when running in rake" do
|
30
|
+
let(:program_name) { "rake" }
|
31
|
+
it "slurps up command line username if available" do
|
32
|
+
allow(Etc).to receive(:getlogin).and_return("my_unix_username")
|
33
|
+
expect(subject.actor_uri).to eq("gid://local/my_unix_username")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "falls back to printing out a GID of bare app name" do
|
38
|
+
expect(subject.actor_uri).to eq("gid://dummy")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,276 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe Journaled::ChangeWriter do
|
4
|
+
let(:model) do
|
5
|
+
now = Time.zone.now
|
6
|
+
double(
|
7
|
+
"Soldier",
|
8
|
+
id: 28_473,
|
9
|
+
class: model_class,
|
10
|
+
attributes: {
|
11
|
+
"name" => "bob",
|
12
|
+
"rank" => "first lieutenant",
|
13
|
+
"serial_number" => "foobar",
|
14
|
+
"last_sign_in_at" => now
|
15
|
+
},
|
16
|
+
saved_changes: {
|
17
|
+
"name" => %w(bill bob),
|
18
|
+
"last_sign_in_at" => now
|
19
|
+
}
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:model_class) do
|
24
|
+
double(
|
25
|
+
"SoldierClass",
|
26
|
+
table_name: "soldiers",
|
27
|
+
attribute_names: %w(id name rank serial_number last_sign_in_at)
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:change_definition) do
|
32
|
+
Journaled::ChangeDefinition.new(
|
33
|
+
attribute_names: %i(name rank serial_number),
|
34
|
+
logical_operation: "identity_change"
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:faulty_change_definition) do
|
39
|
+
Journaled::ChangeDefinition.new(
|
40
|
+
attribute_names: %i(name rank serial_number nonexistent_thingie),
|
41
|
+
logical_operation: "identity_change"
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
subject { described_class.new(model: model, change_definition: change_definition) }
|
46
|
+
|
47
|
+
it "fails to instantiate with an undefined attribute_name" do
|
48
|
+
expect { described_class.new(model: model, change_definition: faulty_change_definition) }.to raise_error(/\bnonexistent_thingie\n/)
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#relevant_attributes" do
|
52
|
+
let(:model) do
|
53
|
+
double(
|
54
|
+
"Soldier",
|
55
|
+
id: 28_473,
|
56
|
+
class: model_class,
|
57
|
+
attributes: {
|
58
|
+
"name" => "bill",
|
59
|
+
"rank" => "first lieutenant",
|
60
|
+
"serial_number" => "foobar",
|
61
|
+
"last_sign_in_at" => Time.zone.now
|
62
|
+
},
|
63
|
+
saved_changes: {}
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns all relevant attributes regardless of saved changes" do
|
68
|
+
expect(subject.relevant_attributes).to eq(
|
69
|
+
"name" => "bill",
|
70
|
+
"rank" => "first lieutenant",
|
71
|
+
"serial_number" => "foobar"
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#relevant_unperturbed_attributes" do
|
77
|
+
let(:model) do
|
78
|
+
double(
|
79
|
+
"Soldier",
|
80
|
+
id: 28_473,
|
81
|
+
class: model_class,
|
82
|
+
attributes: {
|
83
|
+
"name" => "bill",
|
84
|
+
"rank" => "first lieutenant",
|
85
|
+
"serial_number" => "foobar",
|
86
|
+
"last_sign_in_at" => Time.zone.now
|
87
|
+
},
|
88
|
+
changes: {
|
89
|
+
"name" => %w(bob bill)
|
90
|
+
}
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "returns the pre-change value of the attributes, regardless of whether they changed" do
|
95
|
+
expect(subject.relevant_unperturbed_attributes).to eq(
|
96
|
+
"name" => "bob",
|
97
|
+
"rank" => "first lieutenant",
|
98
|
+
"serial_number" => "foobar"
|
99
|
+
)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "#relevant_changed_attributes" do
|
104
|
+
it "returns only relevant changes" do
|
105
|
+
expect(subject.relevant_changed_attributes).to eq("name" => "bob")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "#actor_uri" do
|
110
|
+
it "delegates to ActorUriProvider" do
|
111
|
+
allow(Journaled::ActorUriProvider).to receive(:instance).and_return(double(actor_uri: "my actor uri"))
|
112
|
+
expect(Journaled.actor_uri).to eq "my actor uri"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#journaled_change_for" do
|
117
|
+
it "stores passed changes serialized to json" do
|
118
|
+
expect(subject.journaled_change_for("update", "name" => "bob").changes).to eq('{"name":"bob"}')
|
119
|
+
end
|
120
|
+
|
121
|
+
it "stores the model's table_name" do
|
122
|
+
expect(subject.journaled_change_for("update", {}).table_name).to eq("soldiers")
|
123
|
+
end
|
124
|
+
|
125
|
+
it "converts the model's record_id to a string" do
|
126
|
+
expect(subject.journaled_change_for("update", {}).record_id).to eq("28473")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "stuffs the database operation directly" do
|
130
|
+
expect(subject.journaled_change_for("update", {}).database_operation).to eq("update")
|
131
|
+
expect(subject.journaled_change_for("delete", {}).database_operation).to eq("delete")
|
132
|
+
end
|
133
|
+
|
134
|
+
it "includes logical_operation" do
|
135
|
+
expect(subject.journaled_change_for("update", {}).logical_operation).to eq("identity_change")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "doesn't set journaled_app_name if model class doesn't respond to it" do
|
139
|
+
expect(subject.journaled_change_for("update", {}).journaled_app_name).to eq(nil)
|
140
|
+
end
|
141
|
+
|
142
|
+
context "with journaled default app name set" do
|
143
|
+
around do |example|
|
144
|
+
orig_app_name = Journaled.default_app_name
|
145
|
+
Journaled.default_app_name = "foo"
|
146
|
+
example.run
|
147
|
+
Journaled.default_app_name = orig_app_name
|
148
|
+
end
|
149
|
+
|
150
|
+
it "passes through default" do
|
151
|
+
expect(subject.journaled_change_for("update", {}).journaled_app_name).to eq("foo")
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "when model class defines journaled_app_name" do
|
156
|
+
before do
|
157
|
+
allow(model_class).to receive(:journaled_app_name).and_return("my_app")
|
158
|
+
end
|
159
|
+
|
160
|
+
it "sets journaled_app_name if model_class responds to it" do
|
161
|
+
expect(subject.journaled_change_for("update", {}).journaled_app_name).to eq("my_app")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "with journaling stubbed" do
|
167
|
+
let(:journaled_change) { instance_double(Journaled::Change, journal!: true) }
|
168
|
+
|
169
|
+
before do
|
170
|
+
allow(Journaled::Change).to receive(:new).and_return(nil) # must be restubbed to work in context
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "#create" do
|
174
|
+
let(:model) do
|
175
|
+
double(
|
176
|
+
"Soldier",
|
177
|
+
id: 28_473,
|
178
|
+
class: model_class,
|
179
|
+
attributes: {
|
180
|
+
"name" => "bill",
|
181
|
+
"rank" => "first lieutenant",
|
182
|
+
"serial_number" => "foobar",
|
183
|
+
"last_sign_in_at" => Time.zone.now
|
184
|
+
},
|
185
|
+
saved_changes: {}
|
186
|
+
)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "always journals all relevant attributes, even if unchanged" do
|
190
|
+
allow(Journaled::Change).to receive(:new) do |opts|
|
191
|
+
expect(opts[:changes]).to eq '{"name":"bill","rank":"first lieutenant","serial_number":"foobar"}'
|
192
|
+
journaled_change
|
193
|
+
end
|
194
|
+
|
195
|
+
subject.create
|
196
|
+
|
197
|
+
expect(Journaled::Change).to have_received(:new)
|
198
|
+
expect(journaled_change).to have_received(:journal!)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "#update" do
|
203
|
+
it "journals only relevant changes" do
|
204
|
+
allow(Journaled::Change).to receive(:new) do |opts|
|
205
|
+
expect(opts[:changes]).to eq '{"name":"bob"}'
|
206
|
+
journaled_change
|
207
|
+
end
|
208
|
+
|
209
|
+
subject.update
|
210
|
+
|
211
|
+
expect(Journaled::Change).to have_received(:new)
|
212
|
+
expect(journaled_change).to have_received(:journal!)
|
213
|
+
end
|
214
|
+
|
215
|
+
context "with no changes" do
|
216
|
+
let(:model) do
|
217
|
+
double(
|
218
|
+
"Soldier",
|
219
|
+
id: 28_473,
|
220
|
+
class: model_class,
|
221
|
+
attributes: {
|
222
|
+
"name" => "bill",
|
223
|
+
"rank" => "first lieutenant",
|
224
|
+
"serial_number" => "foobar",
|
225
|
+
"last_sign_in_at" => Time.zone.now
|
226
|
+
},
|
227
|
+
saved_changes: {}
|
228
|
+
)
|
229
|
+
end
|
230
|
+
|
231
|
+
it "doesn't journal" do
|
232
|
+
subject.update
|
233
|
+
|
234
|
+
expect(Journaled::Change).not_to have_received(:new)
|
235
|
+
expect(journaled_change).not_to have_received(:journal!)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "#delete" do
|
241
|
+
let(:model) do
|
242
|
+
now = Time.zone.now
|
243
|
+
double(
|
244
|
+
"Soldier",
|
245
|
+
id: 28_473,
|
246
|
+
class: model_class,
|
247
|
+
attributes: {
|
248
|
+
"name" => "bob",
|
249
|
+
"rank" => "first lieutenant",
|
250
|
+
"serial_number" => "foobar",
|
251
|
+
"last_sign_in_at" => now
|
252
|
+
},
|
253
|
+
changes: {
|
254
|
+
"name" => %w(bill bob)
|
255
|
+
}
|
256
|
+
)
|
257
|
+
end
|
258
|
+
|
259
|
+
it "journals the unperturbed values of all relevant attributes" do
|
260
|
+
allow(Journaled::Change).to receive(:new) do |opts|
|
261
|
+
expect(JSON.parse(opts[:changes])).to eq(
|
262
|
+
"name" => "bill",
|
263
|
+
"rank" => "first lieutenant",
|
264
|
+
"serial_number" => "foobar"
|
265
|
+
)
|
266
|
+
journaled_change
|
267
|
+
end
|
268
|
+
|
269
|
+
subject.delete
|
270
|
+
|
271
|
+
expect(Journaled::Change).to have_received(:new)
|
272
|
+
expect(journaled_change).to have_received(:journal!)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe Journaled::Delivery do
|
4
|
+
let(:stream_name) { 'test_events' }
|
5
|
+
let(:partition_key) { 'fake_partition_key' }
|
6
|
+
let(:serialized_event) { '{"foo":"bar"}' }
|
7
|
+
|
8
|
+
around do |example|
|
9
|
+
with_env(JOURNALED_STREAM_NAME: stream_name) { example.run }
|
10
|
+
end
|
11
|
+
|
12
|
+
subject { described_class.new serialized_event: serialized_event, partition_key: partition_key, app_name: nil }
|
13
|
+
|
14
|
+
describe '#perform' do
|
15
|
+
let!(:stubbed_request) do
|
16
|
+
stub_request(:post, 'https://kinesis.us-east-1.amazonaws.com').to_return(status: return_status_code, body: return_status_body)
|
17
|
+
end
|
18
|
+
let(:return_status_code) { 200 }
|
19
|
+
let(:return_status_body) { return_status_body_hash.to_json }
|
20
|
+
let(:return_status_body_hash) { { RecordId: '101' } }
|
21
|
+
|
22
|
+
let(:stubbed_body) do
|
23
|
+
{
|
24
|
+
'StreamName' => stream_name,
|
25
|
+
'Data' => Base64.encode64(serialized_event).strip,
|
26
|
+
'PartitionKey' => 'fake_partition_key'
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
before do
|
31
|
+
allow(Journaled).to receive(:enabled?).and_return(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'makes requests to AWS to put the event on the Kinesis with the correct body' do
|
35
|
+
subject.perform
|
36
|
+
|
37
|
+
expect(stubbed_request.with(body: stubbed_body.to_json)).to have_been_requested.once
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when the stream name env var is NOT set' do
|
41
|
+
let(:stream_name) { nil }
|
42
|
+
|
43
|
+
it 'raises an KeyError error' do
|
44
|
+
expect { subject.perform }.to raise_error KeyError
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when Amazon responds with an InternalFailure' do
|
49
|
+
let(:return_status_code) { 500 }
|
50
|
+
let(:return_status_body_hash) { { __type: 'InternalFailure' } }
|
51
|
+
|
52
|
+
it 'catches the error and re-raises a subclass of NotTrulyExceptionalError and logs about the failure' do
|
53
|
+
expect(Rails.logger).to receive(:error).with("Kinesis Error - Server Error occurred - Aws::Kinesis::Errors::InternalFailure").once
|
54
|
+
expect { subject.perform }.to raise_error described_class::KinesisTemporaryFailure
|
55
|
+
expect(stubbed_request).to have_been_requested.once
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when Amazon responds with a ServiceUnavailable' do
|
60
|
+
let(:return_status_code) { 503 }
|
61
|
+
let(:return_status_body_hash) { { __type: 'ServiceUnavailable' } }
|
62
|
+
|
63
|
+
it 'catches the error and re-raises a subclass of NotTrulyExceptionalError and logs about the failure' do
|
64
|
+
allow(Rails.logger).to receive(:error)
|
65
|
+
expect { subject.perform }.to raise_error described_class::KinesisTemporaryFailure
|
66
|
+
expect(stubbed_request).to have_been_requested.once
|
67
|
+
expect(Rails.logger).to have_received(:error).with(/\AKinesis Error/).once
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when we receive a 504 Gateway timeout' do
|
72
|
+
let(:return_status_code) { 504 }
|
73
|
+
let(:return_status_body) { nil }
|
74
|
+
|
75
|
+
it 'raises an error that subclasses Aws::Kinesis::Errors::ServiceError' do
|
76
|
+
expect { subject.perform }.to raise_error Aws::Kinesis::Errors::ServiceError
|
77
|
+
expect(stubbed_request).to have_been_requested.once
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when the IAM user does not have permission to put_record to the specified stream' do
|
82
|
+
let(:return_status_code) { 400 }
|
83
|
+
let(:return_status_body_hash) { { __type: 'AccessDeniedException' } }
|
84
|
+
|
85
|
+
it 'raises an AccessDeniedException error' do
|
86
|
+
expect { subject.perform }.to raise_error Aws::Kinesis::Errors::AccessDeniedException
|
87
|
+
expect(stubbed_request).to have_been_requested.once
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when the request timesout' do
|
92
|
+
let!(:stubbed_request) do
|
93
|
+
stub_request(:post, 'https://kinesis.us-east-1.amazonaws.com').to_timeout
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'catches the error and re-raises a subclass of NotTrulyExceptionalError and logs about the failure' do
|
97
|
+
expect(Rails.logger).to receive(:error).with("Kinesis Error - Networking Error occurred - Seahorse::Client::NetworkingError").once
|
98
|
+
expect { subject.perform }.to raise_error described_class::KinesisTemporaryFailure
|
99
|
+
expect(stubbed_request).to have_been_requested.once
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#stream_name" do
|
105
|
+
context "when app_name is unspecified" do
|
106
|
+
subject { described_class.new serialized_event: serialized_event, partition_key: partition_key, app_name: nil }
|
107
|
+
|
108
|
+
it "is fetched from a prefixed ENV var if specified" do
|
109
|
+
allow(ENV).to receive(:fetch).and_return("expected_stream_name")
|
110
|
+
expect(subject.stream_name).to eq("expected_stream_name")
|
111
|
+
expect(ENV).to have_received(:fetch).with("JOURNALED_STREAM_NAME")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when app_name is specified" do
|
116
|
+
subject { described_class.new serialized_event: serialized_event, partition_key: partition_key, app_name: "my_funky_app_name" }
|
117
|
+
|
118
|
+
it "is fetched from a prefixed ENV var if specified" do
|
119
|
+
allow(ENV).to receive(:fetch).and_return("expected_stream_name")
|
120
|
+
expect(subject.stream_name).to eq("expected_stream_name")
|
121
|
+
expect(ENV).to have_received(:fetch).with("MY_FUNKY_APP_NAME_JOURNALED_STREAM_NAME")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#kinesis_client_config" do
|
127
|
+
it "is in us-east-1 by default" do
|
128
|
+
with_env(AWS_DEFAULT_REGION: nil) do
|
129
|
+
expect(subject.kinesis_client_config).to include(region: 'us-east-1')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it "respects AWS_DEFAULT_REGION env var" do
|
134
|
+
with_env(AWS_DEFAULT_REGION: 'us-west-2') do
|
135
|
+
expect(subject.kinesis_client_config).to include(region: 'us-west-2')
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it "doesn't limit retry" do
|
140
|
+
expect(subject.kinesis_client_config).to include(retry_limit: 0)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "provides no AWS credentials by default" do
|
144
|
+
with_env(RUBY_AWS_ACCESS_KEY_ID: nil, RUBY_AWS_SECRET_ACCESS_KEY: nil) do
|
145
|
+
expect(subject.kinesis_client_config).not_to have_key(:access_key_id)
|
146
|
+
expect(subject.kinesis_client_config).not_to have_key(:secret_access_key)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
it "will use legacy credentials if specified" do
|
151
|
+
with_env(RUBY_AWS_ACCESS_KEY_ID: 'key_id', RUBY_AWS_SECRET_ACCESS_KEY: 'secret') do
|
152
|
+
expect(subject.kinesis_client_config).to include(access_key_id: 'key_id', secret_access_key: 'secret')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|