journaled 4.3.0 → 5.0.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.
- checksums.yaml +4 -4
- data/README.md +18 -0
- data/app/jobs/journaled/delivery_job.rb +17 -28
- data/app/models/journaled/writer.rb +30 -18
- data/lib/journaled/connection.rb +48 -0
- data/lib/journaled/engine.rb +5 -0
- data/lib/journaled/errors.rb +3 -0
- data/lib/journaled/transaction_ext.rb +31 -0
- data/lib/journaled/version.rb +1 -1
- data/lib/journaled.rb +15 -11
- metadata +26 -84
- data/spec/dummy/README.rdoc +0 -28
- data/spec/dummy/Rakefile +0 -6
- data/spec/dummy/bin/bundle +0 -3
- data/spec/dummy/bin/rails +0 -4
- data/spec/dummy/bin/rake +0 -4
- data/spec/dummy/config/application.rb +0 -25
- data/spec/dummy/config/boot.rb +0 -5
- data/spec/dummy/config/database.yml +0 -6
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -24
- data/spec/dummy/config/environments/test.rb +0 -37
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/dummy/config/initializers/inflections.rb +0 -16
- data/spec/dummy/config/initializers/mime_types.rb +0 -4
- data/spec/dummy/config/initializers/session_store.rb +0 -3
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/en.yml +0 -23
- data/spec/dummy/config/routes.rb +0 -56
- data/spec/dummy/config/secrets.yml +0 -22
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/db/schema.rb +0 -18
- data/spec/dummy/public/404.html +0 -67
- data/spec/dummy/public/422.html +0 -67
- data/spec/dummy/public/500.html +0 -66
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/jobs/journaled/delivery_job_spec.rb +0 -276
- data/spec/lib/journaled_spec.rb +0 -89
- data/spec/models/concerns/journaled/actor_spec.rb +0 -47
- data/spec/models/concerns/journaled/changes_spec.rb +0 -106
- data/spec/models/database_change_protection_spec.rb +0 -109
- data/spec/models/journaled/actor_uri_provider_spec.rb +0 -42
- data/spec/models/journaled/change_writer_spec.rb +0 -281
- data/spec/models/journaled/event_spec.rb +0 -236
- data/spec/models/journaled/json_schema_model/validator_spec.rb +0 -133
- data/spec/models/journaled/writer_spec.rb +0 -212
- data/spec/rails_helper.rb +0 -19
- data/spec/spec_helper.rb +0 -24
- data/spec/support/environment_spec_helper.rb +0 -16
@@ -1,236 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
RSpec.describe Journaled::Event do
|
4
|
-
let(:sample_journaled_event_class_name) { 'SomeClassName' }
|
5
|
-
let(:sample_journaled_event_class) do
|
6
|
-
Class.new do
|
7
|
-
include Journaled::Event
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
before do
|
12
|
-
stub_const(sample_journaled_event_class_name, sample_journaled_event_class)
|
13
|
-
end
|
14
|
-
|
15
|
-
let(:sample_journaled_event) { sample_journaled_event_class.new }
|
16
|
-
|
17
|
-
describe '#journal!' do
|
18
|
-
let(:mock_journaled_writer) { instance_double(Journaled::Writer, journal!: nil) }
|
19
|
-
|
20
|
-
before do
|
21
|
-
allow(Journaled::Writer).to receive(:new).and_return(mock_journaled_writer)
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when no app job priority is set' do
|
25
|
-
it 'creates a Journaled::Writer with this event and journals it with the default priority' do
|
26
|
-
sample_journaled_event.journal!
|
27
|
-
expect(Journaled::Writer).to have_received(:new)
|
28
|
-
.with(journaled_event: sample_journaled_event)
|
29
|
-
expect(mock_journaled_writer).to have_received(:journal!)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe '#journaled_schema_name' do
|
35
|
-
it 'returns the underscored version on the class name' do
|
36
|
-
expect(sample_journaled_event.journaled_schema_name).to eq 'some_class_name'
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'when the class is modularized' do
|
40
|
-
let(:sample_journaled_event_class_name) { 'SomeModule::SomeClassName' }
|
41
|
-
|
42
|
-
it 'returns the underscored version on the class name' do
|
43
|
-
expect(sample_journaled_event.journaled_schema_name).to eq 'some_module/some_class_name'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '#event_type' do
|
49
|
-
it 'returns the underscored version on the class name' do
|
50
|
-
expect(sample_journaled_event.event_type).to eq 'some_class_name'
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'when the class is modularized' do
|
54
|
-
let(:sample_journaled_event_class_name) { 'SomeModule::SomeClassName' }
|
55
|
-
|
56
|
-
it 'returns the underscored version on the class name, with slashes replaced with underscores' do
|
57
|
-
expect(sample_journaled_event.event_type).to eq 'some_module_some_class_name'
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe '#journaled_partition_key' do
|
63
|
-
it 'returns the #event_type' do
|
64
|
-
expect(sample_journaled_event.journaled_partition_key).to eq 'some_class_name'
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe '#journaled_stream_name' do
|
69
|
-
it 'returns nil in the base class so it can be set explicitly in apps spanning multiple app domains' do
|
70
|
-
expect(sample_journaled_event.journaled_stream_name).to be_nil
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'returns the journaled default if set' do
|
74
|
-
allow(Journaled).to receive(:default_stream_name).and_return("my_app_events")
|
75
|
-
expect(sample_journaled_event.journaled_stream_name).to eq("my_app_events")
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe '#journaled_attributes' do
|
80
|
-
let(:fake_uuid) { 'FAKE_UUID' }
|
81
|
-
let(:frozen_time) { Time.zone.parse('15/2/2017 13:00') }
|
82
|
-
before do
|
83
|
-
allow(SecureRandom).to receive(:uuid).and_return(fake_uuid).once
|
84
|
-
end
|
85
|
-
around do |example|
|
86
|
-
Timecop.freeze(frozen_time) { example.run }
|
87
|
-
end
|
88
|
-
|
89
|
-
context 'when no additional attributes have been defined' do
|
90
|
-
it 'returns the base attributes, and memoizes them after the first call' do
|
91
|
-
expect(sample_journaled_event.journaled_attributes)
|
92
|
-
.to eq id: fake_uuid, created_at: frozen_time, event_type: 'some_class_name'
|
93
|
-
expect(sample_journaled_event.journaled_attributes)
|
94
|
-
.to eq id: fake_uuid, created_at: frozen_time, event_type: 'some_class_name'
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
context 'when there are additional attributes specified, but not defined' do
|
99
|
-
let(:sample_journaled_event_class) do
|
100
|
-
Class.new do
|
101
|
-
include Journaled::Event
|
102
|
-
|
103
|
-
journal_attributes :foo
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'raises a no method error' do
|
108
|
-
expect { sample_journaled_event.journaled_attributes }.to raise_error NoMethodError
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context 'when there are additional attributes specified and defined' do
|
113
|
-
let(:sample_journaled_event_class) do
|
114
|
-
Class.new do
|
115
|
-
include Journaled::Event
|
116
|
-
|
117
|
-
journal_attributes :foo, :bar
|
118
|
-
|
119
|
-
def foo
|
120
|
-
'foo_return'
|
121
|
-
end
|
122
|
-
|
123
|
-
def bar
|
124
|
-
'bar_return'
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'returns the specified attributes plus the base ones' do
|
130
|
-
expect(sample_journaled_event.journaled_attributes).to eq(
|
131
|
-
id: fake_uuid,
|
132
|
-
created_at: frozen_time,
|
133
|
-
event_type: 'some_class_name',
|
134
|
-
foo: 'foo_return',
|
135
|
-
bar: 'bar_return',
|
136
|
-
)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
context 'tagged: true' do
|
141
|
-
before do
|
142
|
-
sample_journaled_event_class.journal_attributes tagged: true
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'adds a "tags" attribute' do
|
146
|
-
expect(sample_journaled_event.journaled_attributes).to include(tags: {})
|
147
|
-
end
|
148
|
-
|
149
|
-
context 'when tags are specified' do
|
150
|
-
around do |example|
|
151
|
-
Journaled.tag!(foo: 'bar')
|
152
|
-
Journaled.tagged(baz: 'bat') { example.run }
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'adds them to the journaled attributes' do
|
156
|
-
expect(sample_journaled_event.journaled_attributes).to include(
|
157
|
-
tags: { foo: 'bar', baz: 'bat' },
|
158
|
-
)
|
159
|
-
end
|
160
|
-
|
161
|
-
context 'when even more tags are nested' do
|
162
|
-
it 'merges them in and then resets them' do
|
163
|
-
Journaled.tagged(oh_no: 'even more tags') do
|
164
|
-
expect(sample_journaled_event.journaled_attributes).to include(
|
165
|
-
tags: { foo: 'bar', baz: 'bat', oh_no: 'even more tags' },
|
166
|
-
)
|
167
|
-
end
|
168
|
-
|
169
|
-
allow(SecureRandom).to receive(:uuid).and_return(fake_uuid).once
|
170
|
-
expect(sample_journaled_event_class.new.journaled_attributes).to include(
|
171
|
-
tags: { foo: 'bar', baz: 'bat' },
|
172
|
-
)
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
context 'when custom event tags are also specified and merged' do
|
177
|
-
let(:sample_journaled_event_class) do
|
178
|
-
Class.new do
|
179
|
-
include Journaled::Event
|
180
|
-
|
181
|
-
def tags
|
182
|
-
super.merge(abc: '123')
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'combines all tags' do
|
188
|
-
expect(sample_journaled_event.journaled_attributes).to include(
|
189
|
-
tags: { foo: 'bar', baz: 'bat', abc: '123' },
|
190
|
-
)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
context 'when custom event tags are also specified but not merged' do
|
195
|
-
let(:sample_journaled_event_class) do
|
196
|
-
Class.new do
|
197
|
-
include Journaled::Event
|
198
|
-
|
199
|
-
def tags
|
200
|
-
{ bananas: 'are great', but_not_actually: 'the best source of potassium' } # it's true
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'adds them to the journaled attributes' do
|
206
|
-
expect(sample_journaled_event.journaled_attributes).to include(
|
207
|
-
tags: { bananas: 'are great', but_not_actually: 'the best source of potassium' },
|
208
|
-
)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
describe '#journaled_enqueue_opts, .journaled_enqueue_opts' do
|
216
|
-
it 'defaults to an empty hash' do
|
217
|
-
expect(sample_journaled_event.journaled_enqueue_opts).to eq({})
|
218
|
-
expect(sample_journaled_event_class.journaled_enqueue_opts).to eq({})
|
219
|
-
end
|
220
|
-
|
221
|
-
context 'when there are custom opts provided' do
|
222
|
-
let(:sample_journaled_event_class) do
|
223
|
-
Class.new do
|
224
|
-
include Journaled::Event
|
225
|
-
|
226
|
-
journal_attributes :foo, enqueue_with: { priority: 34, foo: 'bar' }
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
it 'merges in the custom opts' do
|
231
|
-
expect(sample_journaled_event.journaled_enqueue_opts).to eq(priority: 34, foo: 'bar')
|
232
|
-
expect(sample_journaled_event_class.journaled_enqueue_opts).to eq(priority: 34, foo: 'bar')
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
@@ -1,133 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
RSpec.describe Journaled::JsonSchemaModel::Validator do
|
4
|
-
subject { described_class.new schema_name }
|
5
|
-
|
6
|
-
describe '#validate!' do
|
7
|
-
let(:json_to_validate) { attributes_to_validate.to_json }
|
8
|
-
let(:attributes_to_validate) do
|
9
|
-
{
|
10
|
-
some_string: some_string_value,
|
11
|
-
some_decimal: BigDecimal('0.1'),
|
12
|
-
some_time: Time.zone.parse('2017-01-20 15:16:17 -05:00'),
|
13
|
-
some_int: some_int_value,
|
14
|
-
some_optional_string: some_optional_string_value,
|
15
|
-
some_nullable_field: some_nullable_field,
|
16
|
-
}
|
17
|
-
end
|
18
|
-
let(:some_int_value) { 3 }
|
19
|
-
let(:some_string_value) { 'SOME_STRING' }
|
20
|
-
let(:some_optional_string_value) { 'SOME_OPTIONAL_STRING' }
|
21
|
-
let(:some_nullable_field) { 'VALUE' }
|
22
|
-
|
23
|
-
subject { described_class.new schema_name }
|
24
|
-
|
25
|
-
context 'when the schema name matches a schema in journaled' do
|
26
|
-
let(:schema_name) { :fake_json_schema_name }
|
27
|
-
let(:gem_path) { Journaled::Engine.root.join "journaled_schemas/#{schema_name}.json" }
|
28
|
-
let(:schema_path) { Rails.root.join "journaled_schemas", "#{schema_name}.json" }
|
29
|
-
let(:schema_file_contents) do
|
30
|
-
<<-JSON
|
31
|
-
{
|
32
|
-
"title": "Person",
|
33
|
-
"type": "object",
|
34
|
-
"properties": {
|
35
|
-
"some_string": {
|
36
|
-
"type": "string"
|
37
|
-
},
|
38
|
-
"some_decimal": {
|
39
|
-
"type": "string"
|
40
|
-
},
|
41
|
-
"some_time": {
|
42
|
-
"type": "string"
|
43
|
-
},
|
44
|
-
"some_int": {
|
45
|
-
"type": "integer"
|
46
|
-
},
|
47
|
-
"some_optional_string": {
|
48
|
-
"type": "string"
|
49
|
-
},
|
50
|
-
"some_nullable_field": {
|
51
|
-
"type": ["string", "null"]
|
52
|
-
}
|
53
|
-
},
|
54
|
-
"required": ["some_string", "some_decimal", "some_time", "some_int", "some_nullable_field"]
|
55
|
-
}
|
56
|
-
JSON
|
57
|
-
end
|
58
|
-
|
59
|
-
before do
|
60
|
-
allow(File).to receive(:exist?).and_call_original
|
61
|
-
allow(File).to receive(:exist?).with(gem_path).and_return(false)
|
62
|
-
allow(File).to receive(:exist?).with(schema_path).and_return(true)
|
63
|
-
allow(File).to receive(:read).with(schema_path).and_return(schema_file_contents)
|
64
|
-
end
|
65
|
-
|
66
|
-
context 'when all the required fields are provided' do
|
67
|
-
context 'when all the fields are provided' do
|
68
|
-
it 'is valid' do
|
69
|
-
expect(subject.validate!(json_to_validate)).to be true
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'when an optional field is missing' do
|
74
|
-
let(:attributes_to_validate) do
|
75
|
-
{
|
76
|
-
some_string: some_string_value,
|
77
|
-
some_decimal: BigDecimal('0.1'),
|
78
|
-
some_time: Time.zone.parse('2017-01-20 15:16:17 -05:00'),
|
79
|
-
some_int: some_int_value,
|
80
|
-
some_nullable_field: some_nullable_field,
|
81
|
-
}
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'is valid' do
|
85
|
-
expect(subject.validate!(json_to_validate)).to be true
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
context 'when a nullable field is nil' do
|
90
|
-
let(:some_nullable_optional_field) { nil }
|
91
|
-
|
92
|
-
it 'is valid' do
|
93
|
-
expect(subject.validate!(json_to_validate)).to be true
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
context 'but one of the required fields is of the wrong type' do
|
98
|
-
let(:some_int_value) { 'NOT_AN_INTEGER' }
|
99
|
-
|
100
|
-
it 'is NOT valid' do
|
101
|
-
expect { subject.validate! json_to_validate }.to raise_error JSON::Schema::ValidationError
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
context 'when not all the required fields are provided' do
|
107
|
-
let(:attributes_to_validate) do
|
108
|
-
{
|
109
|
-
some_string: some_string_value,
|
110
|
-
some_decimal: BigDecimal('0.1'),
|
111
|
-
some_time: Time.zone.parse('2017-01-20 15:16:17 -05:00'),
|
112
|
-
}
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'is NOT valid' do
|
116
|
-
expect { subject.validate! json_to_validate }.to raise_error JSON::Schema::ValidationError
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'when the schema name does not match a schema in journaled' do
|
122
|
-
let(:schema_name) { :nonexistent_avro_scehma }
|
123
|
-
|
124
|
-
before do
|
125
|
-
allow(File).to receive(:exist?).and_return(false)
|
126
|
-
end
|
127
|
-
|
128
|
-
it 'raises an error loading the schema' do
|
129
|
-
expect { subject.validate! json_to_validate }.to raise_error(/not found in any of Journaled::Engine.root,/)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
@@ -1,212 +0,0 @@
|
|
1
|
-
require 'rails_helper'
|
2
|
-
|
3
|
-
RSpec.describe Journaled::Writer do
|
4
|
-
let(:event_class) { Class.new { include Journaled::Event } }
|
5
|
-
subject { described_class.new journaled_event: journaled_event }
|
6
|
-
|
7
|
-
describe '#initialize' do
|
8
|
-
context 'when the Journaled Event does not implement all the necessary methods' do
|
9
|
-
let(:journaled_event) { instance_double(event_class) }
|
10
|
-
|
11
|
-
it 'raises on initialization' do
|
12
|
-
expect { subject }.to raise_error RuntimeError, /An enqueued event must respond to/
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'when the Journaled Event returns non-present values for some of the required methods' do
|
17
|
-
let(:journaled_event) do
|
18
|
-
instance_double(
|
19
|
-
event_class,
|
20
|
-
journaled_schema_name: nil,
|
21
|
-
journaled_attributes: {},
|
22
|
-
journaled_partition_key: '',
|
23
|
-
journaled_stream_name: nil,
|
24
|
-
journaled_enqueue_opts: {},
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'raises on initialization' do
|
29
|
-
expect { subject }.to raise_error RuntimeError, /An enqueued event must have a non-nil response to/
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'when the Journaled Event complies with the API' do
|
34
|
-
let(:journaled_event) do
|
35
|
-
instance_double(
|
36
|
-
event_class,
|
37
|
-
journaled_schema_name: :fake_schema_name,
|
38
|
-
journaled_attributes: { foo: :bar },
|
39
|
-
journaled_partition_key: 'fake_partition_key',
|
40
|
-
journaled_stream_name: nil,
|
41
|
-
journaled_enqueue_opts: {},
|
42
|
-
)
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'does not raise on initialization' do
|
46
|
-
expect { subject }.not_to raise_error
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe '#journal!' do
|
52
|
-
let(:schema_path) { Journaled::Engine.root.join "journaled_schemas/fake_schema_name.json" }
|
53
|
-
let(:schema_file_contents) do
|
54
|
-
<<-JSON
|
55
|
-
{
|
56
|
-
"title": "Foo",
|
57
|
-
"type": "object",
|
58
|
-
"properties": {
|
59
|
-
"foo": {
|
60
|
-
"type": "string"
|
61
|
-
}
|
62
|
-
},
|
63
|
-
"required": ["foo"]
|
64
|
-
}
|
65
|
-
JSON
|
66
|
-
end
|
67
|
-
|
68
|
-
before do
|
69
|
-
allow(File).to receive(:exist?).and_call_original
|
70
|
-
allow(File).to receive(:exist?).with(schema_path).and_return(true)
|
71
|
-
allow(File).to receive(:read).and_call_original
|
72
|
-
allow(File).to receive(:read).with(schema_path).and_return(schema_file_contents)
|
73
|
-
end
|
74
|
-
|
75
|
-
let(:journaled_enqueue_opts) { {} }
|
76
|
-
let(:journaled_event) do
|
77
|
-
instance_double(
|
78
|
-
event_class,
|
79
|
-
journaled_schema_name: 'fake_schema_name',
|
80
|
-
journaled_attributes: journaled_event_attributes,
|
81
|
-
journaled_partition_key: 'fake_partition_key',
|
82
|
-
journaled_stream_name: 'my_app_events',
|
83
|
-
journaled_enqueue_opts: journaled_enqueue_opts,
|
84
|
-
tagged?: false,
|
85
|
-
)
|
86
|
-
end
|
87
|
-
|
88
|
-
context 'when the journaled event does NOT comply with the base_event schema' do
|
89
|
-
let(:journaled_event_attributes) { { foo: 1 } }
|
90
|
-
|
91
|
-
it 'raises an error and does not enqueue anything' do
|
92
|
-
expect { subject.journal! }
|
93
|
-
.to raise_error(JSON::Schema::ValidationError)
|
94
|
-
.and not_journal_event_including(anything)
|
95
|
-
expect(enqueued_jobs.count).to eq 0
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
context 'when the event complies with the base_event schema' do
|
100
|
-
context 'when the specific json schema is NOT valid' do
|
101
|
-
let(:journaled_event_attributes) { { id: 'FAKE_UUID', event_type: 'fake_event', created_at: Time.zone.now, foo: 1 } }
|
102
|
-
|
103
|
-
it 'raises an error and does not enqueue anything' do
|
104
|
-
expect { subject.journal! }
|
105
|
-
.to raise_error(JSON::Schema::ValidationError)
|
106
|
-
.and not_journal_event_including(anything)
|
107
|
-
expect(enqueued_jobs.count).to eq 0
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context 'when the specific json schema is also valid' do
|
112
|
-
let(:journaled_event_attributes) { { id: 'FAKE_UUID', event_type: 'fake_event', created_at: Time.zone.now, foo: :bar } }
|
113
|
-
|
114
|
-
it 'creates a delivery with the app name passed through' do
|
115
|
-
expect { subject.journal! }
|
116
|
-
.to change { enqueued_jobs.count }.from(0).to(1)
|
117
|
-
.and journal_event_including(journaled_event_attributes)
|
118
|
-
.with_schema_name('fake_schema_name')
|
119
|
-
.with_partition_key('fake_partition_key')
|
120
|
-
.with_stream_name('my_app_events')
|
121
|
-
.with_enqueue_opts({})
|
122
|
-
expect(enqueued_jobs.first[:args].first).to include('stream_name' => 'my_app_events')
|
123
|
-
end
|
124
|
-
|
125
|
-
context 'when there is no job priority specified in the enqueue opts' do
|
126
|
-
around do |example|
|
127
|
-
old_priority = Journaled.job_priority
|
128
|
-
Journaled.job_priority = 999
|
129
|
-
example.run
|
130
|
-
Journaled.job_priority = old_priority
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'defaults to the global default' do
|
134
|
-
expect { subject.journal! }.to change {
|
135
|
-
if Rails::VERSION::MAJOR < 6
|
136
|
-
enqueued_jobs.count { |j| j[:job] == Journaled::DeliveryJob }
|
137
|
-
else
|
138
|
-
enqueued_jobs.count { |j| j['job_class'] == 'Journaled::DeliveryJob' && j['priority'] == 999 }
|
139
|
-
end
|
140
|
-
}.from(0).to(1)
|
141
|
-
.and journal_event_including(journaled_event_attributes)
|
142
|
-
.with_schema_name('fake_schema_name')
|
143
|
-
.with_partition_key('fake_partition_key')
|
144
|
-
.with_stream_name('my_app_events')
|
145
|
-
.with_priority(999)
|
146
|
-
.and not_journal_event_including(anything)
|
147
|
-
.with_enqueue_opts(priority: 999) # with_enqueue_opts looks at event itself
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
context 'when there is a job priority specified in the enqueue opts' do
|
152
|
-
let(:journaled_enqueue_opts) { { priority: 13 } }
|
153
|
-
|
154
|
-
it 'enqueues a Journaled::DeliveryJob with the given priority' do
|
155
|
-
expect { subject.journal! }.to change {
|
156
|
-
if Rails::VERSION::MAJOR < 6
|
157
|
-
enqueued_jobs.count { |j| j[:job] == Journaled::DeliveryJob }
|
158
|
-
else
|
159
|
-
enqueued_jobs.count { |j| j['job_class'] == 'Journaled::DeliveryJob' && j['priority'] == 13 }
|
160
|
-
end
|
161
|
-
}.from(0).to(1)
|
162
|
-
.and journal_event_including(journaled_event_attributes)
|
163
|
-
.with_schema_name('fake_schema_name')
|
164
|
-
.with_partition_key('fake_partition_key')
|
165
|
-
.with_stream_name('my_app_events')
|
166
|
-
.with_priority(13)
|
167
|
-
.with_enqueue_opts(priority: 13)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
context 'when the event is tagged' do
|
174
|
-
before do
|
175
|
-
allow(journaled_event).to receive(:tagged?).and_return(true)
|
176
|
-
end
|
177
|
-
|
178
|
-
context 'and the "tags" attribute is not present' do
|
179
|
-
let(:journaled_event_attributes) do
|
180
|
-
{ id: 'FAKE_UUID', event_type: 'fake_event', created_at: Time.zone.now, foo: 'bar' }
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'raises an error and does not enqueue anything' do
|
184
|
-
expect { subject.journal! }
|
185
|
-
.to not_journal_events_including(anything)
|
186
|
-
.and raise_error JSON::Schema::ValidationError
|
187
|
-
expect(enqueued_jobs.count).to eq 0
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
context 'and the "tags" attribute is present' do
|
192
|
-
let(:journaled_event_attributes) do
|
193
|
-
{ id: 'FAKE_UUID', event_type: 'fake_event', created_at: Time.zone.now, foo: 'bar', tags: { baz: 'bat' } }
|
194
|
-
end
|
195
|
-
|
196
|
-
it 'creates a delivery with the app name passed through' do
|
197
|
-
expect { subject.journal! }
|
198
|
-
.to change { enqueued_jobs.count }.from(0).to(1)
|
199
|
-
.and journal_event_including(journaled_event_attributes)
|
200
|
-
.with_schema_name('fake_schema_name')
|
201
|
-
.with_partition_key('fake_partition_key')
|
202
|
-
.with_stream_name('my_app_events')
|
203
|
-
.with_enqueue_opts({})
|
204
|
-
.with_priority(Journaled.job_priority)
|
205
|
-
.and not_journal_event_including(anything)
|
206
|
-
.with_enqueue_opts(priority: Journaled.job_priority)
|
207
|
-
expect(enqueued_jobs.first[:args].first).to include('stream_name' => 'my_app_events')
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
data/spec/rails_helper.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
-
ENV['RAILS_ENV'] ||= 'test'
|
3
|
-
require 'spec_helper'
|
4
|
-
require File.expand_path('../spec/dummy/config/environment', __dir__)
|
5
|
-
require 'rspec/rails'
|
6
|
-
require 'timecop'
|
7
|
-
require 'webmock/rspec'
|
8
|
-
require 'journaled/rspec'
|
9
|
-
|
10
|
-
Dir[Rails.root.join('../support/**/*.rb')].sort.each { |f| require f }
|
11
|
-
|
12
|
-
RSpec.configure do |config|
|
13
|
-
config.use_transactional_fixtures = true
|
14
|
-
|
15
|
-
config.infer_spec_type_from_file_location!
|
16
|
-
|
17
|
-
config.include ActiveJob::TestHelper
|
18
|
-
config.include EnvironmentSpecHelper
|
19
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
rails_env = ENV['RAILS_ENV'] ||= 'test'
|
2
|
-
require 'uncruft'
|
3
|
-
require File.expand_path('dummy/config/environment.rb', __dir__)
|
4
|
-
|
5
|
-
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true if Rails::VERSION::MAJOR < 6
|
6
|
-
Rails.application.config.active_record.legacy_connection_handling = false if Rails::VERSION::MAJOR >= 7
|
7
|
-
|
8
|
-
Rails.configuration.database_configuration[rails_env].tap do |c|
|
9
|
-
ActiveRecord::Tasks::DatabaseTasks.create(c)
|
10
|
-
ActiveRecord::Base.establish_connection(c)
|
11
|
-
load File.expand_path('dummy/db/schema.rb', __dir__)
|
12
|
-
end
|
13
|
-
|
14
|
-
RSpec.configure do |config|
|
15
|
-
config.expect_with :rspec do |expectations|
|
16
|
-
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
17
|
-
end
|
18
|
-
|
19
|
-
config.mock_with :rspec do |mocks|
|
20
|
-
mocks.verify_partial_doubles = true
|
21
|
-
end
|
22
|
-
|
23
|
-
config.order = :random
|
24
|
-
end
|