chewy 7.6.0 → 8.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/.github/CODEOWNERS +1 -1
- data/.github/dependabot.yml +2 -2
- data/.github/workflows/ruby.yml +11 -10
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +132 -39
- data/CHANGELOG.md +18 -1
- data/CONTRIBUTING.md +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +50 -1125
- data/chewy.gemspec +3 -2
- data/docker-compose.yml +14 -0
- data/docs/README.md +16 -0
- data/docs/configuration.md +440 -0
- data/docs/import.md +122 -0
- data/docs/indexing.md +329 -0
- data/docs/querying.md +72 -0
- data/docs/rake_tasks.md +108 -0
- data/docs/testing.md +41 -0
- data/docs/troubleshooting.md +101 -0
- data/gemfiles/base.gemfile +3 -3
- data/gemfiles/{rails.6.1.activerecord.gemfile → rails.7.2.activerecord.gemfile} +3 -3
- data/gemfiles/{rails.7.0.activerecord.gemfile → rails.8.0.activerecord.gemfile} +3 -3
- data/lib/chewy/config.rb +2 -2
- data/lib/chewy/errors.rb +3 -0
- data/lib/chewy/fields/root.rb +1 -1
- data/lib/chewy/index/actions.rb +5 -5
- data/lib/chewy/index/aliases.rb +1 -1
- data/lib/chewy/index/syncer.rb +5 -5
- data/lib/chewy/minitest/helpers.rb +1 -1
- data/lib/chewy/search/request.rb +4 -4
- data/lib/chewy/search/response.rb +7 -0
- data/lib/chewy/search/scrolling.rb +2 -1
- data/lib/chewy/strategy/delayed_sidekiq/worker.rb +1 -1
- data/lib/chewy/version.rb +1 -1
- data/lib/chewy.rb +4 -0
- data/migration_guide.md +1 -1
- data/spec/chewy/config_spec.rb +13 -14
- data/spec/chewy/elastic_client_spec.rb +1 -1
- data/spec/chewy/fields/base_spec.rb +2 -2
- data/spec/chewy/fields/time_fields_spec.rb +1 -1
- data/spec/chewy/index/actions_spec.rb +9 -70
- data/spec/chewy/index/aliases_spec.rb +1 -1
- data/spec/chewy/index/import/bulk_builder_spec.rb +2 -2
- data/spec/chewy/index/import/bulk_request_spec.rb +1 -1
- data/spec/chewy/index/import/routine_spec.rb +1 -1
- data/spec/chewy/index/import_spec.rb +15 -15
- data/spec/chewy/index/observe/callback_spec.rb +1 -1
- data/spec/chewy/index/specification_spec.rb +1 -4
- data/spec/chewy/index/syncer_spec.rb +1 -1
- data/spec/chewy/index_spec.rb +1 -1
- data/spec/chewy/journal_spec.rb +2 -2
- data/spec/chewy/minitest/helpers_spec.rb +2 -6
- data/spec/chewy/multi_search_spec.rb +1 -1
- data/spec/chewy/rake_helper_spec.rb +1 -1
- data/spec/chewy/repository_spec.rb +4 -4
- data/spec/chewy/rspec/update_index_spec.rb +2 -2
- data/spec/chewy/runtime_spec.rb +2 -2
- data/spec/chewy/search/loader_spec.rb +1 -1
- data/spec/chewy/search/pagination/kaminari_examples.rb +1 -1
- data/spec/chewy/search/query_proxy_spec.rb +0 -24
- data/spec/chewy/search/request_spec.rb +7 -3
- data/spec/chewy/search/response_spec.rb +2 -24
- data/spec/chewy/search/scrolling_spec.rb +1 -1
- data/spec/chewy/search_spec.rb +1 -1
- data/spec/chewy/stash_spec.rb +1 -1
- data/spec/chewy/strategy/delayed_sidekiq_spec.rb +27 -10
- data/spec/chewy/strategy_spec.rb +1 -1
- data/spec/chewy_spec.rb +5 -22
- data/spec/spec_helper.rb +26 -0
- data/spec/support/active_record.rb +35 -4
- metadata +22 -17
- data/gemfiles/rails.7.1.activerecord.gemfile +0 -14
data/spec/chewy/journal_spec.rb
CHANGED
|
@@ -21,7 +21,7 @@ describe Chewy::Journal do
|
|
|
21
21
|
default_import_options journal: true
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
drop_indices
|
|
25
25
|
Chewy.settings[:prefix] = 'some_prefix'
|
|
26
26
|
Timecop.freeze(time)
|
|
27
27
|
end
|
|
@@ -145,7 +145,7 @@ describe Chewy::Journal do
|
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
context do
|
|
148
|
-
before {
|
|
148
|
+
before { drop_indices }
|
|
149
149
|
before do
|
|
150
150
|
stub_model(:city) do
|
|
151
151
|
update_index 'cities', :self
|
|
@@ -17,7 +17,7 @@ describe :minitest_helper do
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
before do
|
|
20
|
-
|
|
20
|
+
drop_indices
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
before do
|
|
@@ -121,13 +121,9 @@ describe :minitest_helper do
|
|
|
121
121
|
}
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
let(:unexpected_query_error_message) do
|
|
125
|
-
'got {:index=>["dummies"], :body=>{:query=>{:bool=>{:filter=>{:bool=>{:must=>{:match=>{:foo=>"bar"}}, :should=>{:multi_match=>{:foo=>"bar"}}}}}}}} instead of expected query.'
|
|
126
|
-
end
|
|
127
|
-
|
|
128
124
|
specify do
|
|
129
125
|
expect { assert_elasticsearch_query(query, unexpected_query) }
|
|
130
|
-
.to raise_error(RuntimeError,
|
|
126
|
+
.to raise_error(RuntimeError, /instead of expected query\./)
|
|
131
127
|
end
|
|
132
128
|
end
|
|
133
129
|
end
|
|
@@ -3,10 +3,10 @@ require 'spec_helper'
|
|
|
3
3
|
describe Chewy::Repository do
|
|
4
4
|
subject { described_class.send(:new) }
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
specify { expect(subject.analyzers).to eq({}) }
|
|
7
|
+
specify { expect(subject.tokenizers).to eq({}) }
|
|
8
|
+
specify { expect(subject.filters).to eq({}) }
|
|
9
|
+
specify { expect(subject.char_filters).to eq({}) }
|
|
10
10
|
|
|
11
11
|
describe '#analyzer' do
|
|
12
12
|
specify { expect(subject.analyzer(:name)).to be_nil }
|
|
@@ -9,7 +9,7 @@ describe :update_index do
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
before do
|
|
12
|
-
|
|
12
|
+
drop_indices
|
|
13
13
|
DummiesIndex.create!
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -262,7 +262,7 @@ describe :update_index do
|
|
|
262
262
|
|
|
263
263
|
specify { expectation.to fail_matching 'Expected document with id `43` to be reindexed' }
|
|
264
264
|
specify { expectation.to fail_matching '2 times, but was reindexed 1 times' }
|
|
265
|
-
specify { expectation.to fail_matching '
|
|
265
|
+
specify { expectation.to fail_matching 'but it was reindexed with' }
|
|
266
266
|
end
|
|
267
267
|
end
|
|
268
268
|
end
|
data/spec/chewy/runtime_spec.rb
CHANGED
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
|
3
3
|
describe Chewy::Runtime do
|
|
4
4
|
describe '.version' do
|
|
5
5
|
specify { expect(described_class.version).to be_a(described_class::Version) }
|
|
6
|
-
specify { expect(described_class.version).to be >= '
|
|
7
|
-
specify { expect(described_class.version).to be < '
|
|
6
|
+
specify { expect(described_class.version).to be >= '8.0' }
|
|
7
|
+
specify { expect(described_class.version).to be < '9.0' }
|
|
8
8
|
end
|
|
9
9
|
end
|
|
@@ -12,10 +12,6 @@ describe Chewy::Search::QueryProxy do
|
|
|
12
12
|
expect(subject.must(multi_match: {foo: 'bar'}).render[:body])
|
|
13
13
|
.to eq(query: {bool: {must: [{match: {foo: 'bar'}}, {multi_match: {foo: 'bar'}}]}})
|
|
14
14
|
end
|
|
15
|
-
specify do
|
|
16
|
-
expect(subject.must(multi_match: {foo: 'bar'}).render[:body])
|
|
17
|
-
.to eq(query: {bool: {must: [{match: {foo: 'bar'}}, {multi_match: {foo: 'bar'}}]}})
|
|
18
|
-
end
|
|
19
15
|
end
|
|
20
16
|
|
|
21
17
|
describe '#should' do
|
|
@@ -24,10 +20,6 @@ describe Chewy::Search::QueryProxy do
|
|
|
24
20
|
expect(subject.should(multi_match: {foo: 'bar'}).render[:body])
|
|
25
21
|
.to eq(query: {bool: {must: {match: {foo: 'bar'}}, should: {multi_match: {foo: 'bar'}}}})
|
|
26
22
|
end
|
|
27
|
-
specify do
|
|
28
|
-
expect(subject.should(multi_match: {foo: 'bar'}).render[:body])
|
|
29
|
-
.to eq(query: {bool: {must: {match: {foo: 'bar'}}, should: {multi_match: {foo: 'bar'}}}})
|
|
30
|
-
end
|
|
31
23
|
end
|
|
32
24
|
|
|
33
25
|
describe '#must_not' do
|
|
@@ -36,10 +28,6 @@ describe Chewy::Search::QueryProxy do
|
|
|
36
28
|
expect(subject.must_not(multi_match: {foo: 'bar'}).render[:body])
|
|
37
29
|
.to eq(query: {bool: {must: {match: {foo: 'bar'}}, must_not: {multi_match: {foo: 'bar'}}}})
|
|
38
30
|
end
|
|
39
|
-
specify do
|
|
40
|
-
expect(subject.must_not(multi_match: {foo: 'bar'}).render[:body])
|
|
41
|
-
.to eq(query: {bool: {must: {match: {foo: 'bar'}}, must_not: {multi_match: {foo: 'bar'}}}})
|
|
42
|
-
end
|
|
43
31
|
end
|
|
44
32
|
|
|
45
33
|
describe '#and' do
|
|
@@ -48,10 +36,6 @@ describe Chewy::Search::QueryProxy do
|
|
|
48
36
|
expect(subject.and(multi_match: {foo: 'bar'}).render[:body])
|
|
49
37
|
.to eq(query: {bool: {must: [{match: {foo: 'bar'}}, {multi_match: {foo: 'bar'}}]}})
|
|
50
38
|
end
|
|
51
|
-
specify do
|
|
52
|
-
expect(subject.and(multi_match: {foo: 'bar'}).render[:body])
|
|
53
|
-
.to eq(query: {bool: {must: [{match: {foo: 'bar'}}, {multi_match: {foo: 'bar'}}]}})
|
|
54
|
-
end
|
|
55
39
|
specify do
|
|
56
40
|
expect(subject.and(scope).render[:body])
|
|
57
41
|
.to eq(query: {bool: {must: [{match: {foo: 'bar'}}, {bool: {must_not: {match: {foo: 'bar'}}}}]}})
|
|
@@ -64,10 +48,6 @@ describe Chewy::Search::QueryProxy do
|
|
|
64
48
|
expect(subject.or(multi_match: {foo: 'bar'}).render[:body])
|
|
65
49
|
.to eq(query: {bool: {should: [{match: {foo: 'bar'}}, {multi_match: {foo: 'bar'}}]}})
|
|
66
50
|
end
|
|
67
|
-
specify do
|
|
68
|
-
expect(subject.or(multi_match: {foo: 'bar'}).render[:body])
|
|
69
|
-
.to eq(query: {bool: {should: [{match: {foo: 'bar'}}, {multi_match: {foo: 'bar'}}]}})
|
|
70
|
-
end
|
|
71
51
|
specify do
|
|
72
52
|
expect(subject.or(scope).render[:body])
|
|
73
53
|
.to eq(query: {bool: {should: [{match: {foo: 'bar'}}, {bool: {must_not: {match: {foo: 'bar'}}}}]}})
|
|
@@ -80,10 +60,6 @@ describe Chewy::Search::QueryProxy do
|
|
|
80
60
|
expect(subject.not(multi_match: {foo: 'bar'}).render[:body])
|
|
81
61
|
.to eq(query: {bool: {must: {match: {foo: 'bar'}}, must_not: {multi_match: {foo: 'bar'}}}})
|
|
82
62
|
end
|
|
83
|
-
specify do
|
|
84
|
-
expect(subject.not(multi_match: {foo: 'bar'}).render[:body])
|
|
85
|
-
.to eq(query: {bool: {must: {match: {foo: 'bar'}}, must_not: {multi_match: {foo: 'bar'}}}})
|
|
86
|
-
end
|
|
87
63
|
specify do
|
|
88
64
|
expect(subject.not(scope).render[:body])
|
|
89
65
|
.to eq(query: {bool: {must: {match: {foo: 'bar'}}, must_not: {bool: {must_not: {match: {foo: 'bar'}}}}}})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Chewy::Search::Request do
|
|
4
|
-
before {
|
|
4
|
+
before { drop_indices }
|
|
5
5
|
|
|
6
6
|
before do
|
|
7
7
|
stub_index(:products) do
|
|
@@ -54,11 +54,15 @@ describe Chewy::Search::Request do
|
|
|
54
54
|
describe '#inspect' do
|
|
55
55
|
specify do
|
|
56
56
|
expect(described_class.new(ProductsIndex).inspect)
|
|
57
|
-
.to
|
|
57
|
+
.to match(/\A<Chewy::Search::Request/)
|
|
58
|
+
.and include('"products"')
|
|
58
59
|
end
|
|
59
60
|
specify do
|
|
60
61
|
expect(ProductsIndex.limit(10).inspect)
|
|
61
|
-
.to
|
|
62
|
+
.to match(/\A<ProductsIndex::Query/)
|
|
63
|
+
.and include('"products"')
|
|
64
|
+
.and include('size')
|
|
65
|
+
.and include('10')
|
|
62
66
|
end
|
|
63
67
|
end
|
|
64
68
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Chewy::Search::Response, :orm do
|
|
4
|
-
before {
|
|
4
|
+
before { drop_indices }
|
|
5
5
|
|
|
6
6
|
before do
|
|
7
7
|
stub_model(:city)
|
|
@@ -39,7 +39,7 @@ describe Chewy::Search::Response, :orm do
|
|
|
39
39
|
specify { expect(subject.hits).to all be_a(Hash) }
|
|
40
40
|
specify do
|
|
41
41
|
expect(subject.hits.flat_map(&:keys).uniq)
|
|
42
|
-
.to match_array(%w[_id _index
|
|
42
|
+
.to match_array(%w[_id _index _score _source sort])
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
context do
|
|
@@ -68,32 +68,10 @@ describe Chewy::Search::Response, :orm do
|
|
|
68
68
|
|
|
69
69
|
describe '#took' do
|
|
70
70
|
specify { expect(subject.took).to be >= 0 }
|
|
71
|
-
|
|
72
|
-
context do
|
|
73
|
-
let(:request) do
|
|
74
|
-
Chewy::Search::Request.new(CitiesIndex)
|
|
75
|
-
.query(script: {script: {inline: 'sleep(100); true', lang: 'groovy'}})
|
|
76
|
-
end
|
|
77
|
-
specify do
|
|
78
|
-
pending
|
|
79
|
-
expect(subject.took).to be > 100
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
71
|
end
|
|
83
72
|
|
|
84
73
|
describe '#timed_out?' do
|
|
85
74
|
specify { expect(subject.timed_out?).to eq(false) }
|
|
86
|
-
|
|
87
|
-
context do
|
|
88
|
-
let(:request) do
|
|
89
|
-
Chewy::Search::Request.new(CitiesIndex)
|
|
90
|
-
.query(script: {script: {inline: 'sleep(100); true', lang: 'groovy'}}).timeout('10ms')
|
|
91
|
-
end
|
|
92
|
-
specify do
|
|
93
|
-
pending
|
|
94
|
-
expect(subject.timed_out?).to eq(true)
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
75
|
end
|
|
98
76
|
|
|
99
77
|
describe '#suggest' do
|
data/spec/chewy/search_spec.rb
CHANGED
data/spec/chewy/stash_spec.rb
CHANGED
|
@@ -21,13 +21,23 @@ if defined?(Sidekiq)
|
|
|
21
21
|
update_index('cities') { self }
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
stub_uuid_model(:user) do
|
|
25
|
+
update_index('users') { self }
|
|
26
|
+
end
|
|
27
|
+
|
|
24
28
|
stub_index(:cities) do
|
|
25
29
|
index_scope City
|
|
26
30
|
end
|
|
31
|
+
|
|
32
|
+
stub_index(:users) do
|
|
33
|
+
index_scope User
|
|
34
|
+
end
|
|
27
35
|
end
|
|
28
36
|
|
|
29
37
|
let(:city) { City.create!(name: 'hello') }
|
|
30
38
|
let(:other_city) { City.create!(name: 'world') }
|
|
39
|
+
let(:user) { User.create!(name: 'John') }
|
|
40
|
+
let(:other_user) { User.create!(name: 'Jane') }
|
|
31
41
|
|
|
32
42
|
it 'does not trigger immediate reindex due to it`s async nature' do
|
|
33
43
|
expect { [city, other_city].map(&:save!) }
|
|
@@ -36,12 +46,19 @@ if defined?(Sidekiq)
|
|
|
36
46
|
|
|
37
47
|
it "respects 'refresh: false' options" do
|
|
38
48
|
allow(Chewy).to receive(:disable_refresh_async).and_return(true)
|
|
39
|
-
expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id]), refresh: false)
|
|
49
|
+
expect(CitiesIndex).to receive(:import!).with(match_array([city.id.to_s, other_city.id.to_s]), refresh: false)
|
|
40
50
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id, other_city.id])
|
|
41
51
|
scheduler.postpone
|
|
42
52
|
Chewy::Strategy::DelayedSidekiq::Worker.drain
|
|
43
53
|
end
|
|
44
54
|
|
|
55
|
+
it 'works with models with string primary key' do
|
|
56
|
+
expect(UsersIndex).to receive(:import!).with(match_array([user.id, other_user.id]))
|
|
57
|
+
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(UsersIndex, [user.id, other_user.id])
|
|
58
|
+
scheduler.postpone
|
|
59
|
+
Chewy::Strategy::DelayedSidekiq::Worker.drain
|
|
60
|
+
end
|
|
61
|
+
|
|
45
62
|
context 'with default config' do
|
|
46
63
|
it 'does schedule a job that triggers reindex with default options' do
|
|
47
64
|
Timecop.freeze do
|
|
@@ -109,7 +126,7 @@ if defined?(Sidekiq)
|
|
|
109
126
|
context 'two reindex call within the timewindow' do
|
|
110
127
|
it 'accumulates all ids does the reindex one time' do
|
|
111
128
|
Timecop.freeze do
|
|
112
|
-
expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id])).once
|
|
129
|
+
expect(CitiesIndex).to receive(:import!).with(match_array([city.id.to_s, other_city.id.to_s])).once
|
|
113
130
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id])
|
|
114
131
|
scheduler.postpone
|
|
115
132
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [other_city.id])
|
|
@@ -121,7 +138,7 @@ if defined?(Sidekiq)
|
|
|
121
138
|
context 'one call with update_fields another one without update_fields' do
|
|
122
139
|
it 'does reindex of all fields' do
|
|
123
140
|
Timecop.freeze do
|
|
124
|
-
expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id])).once
|
|
141
|
+
expect(CitiesIndex).to receive(:import!).with(match_array([city.id.to_s, other_city.id.to_s])).once
|
|
125
142
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id], update_fields: ['name'])
|
|
126
143
|
scheduler.postpone
|
|
127
144
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [other_city.id])
|
|
@@ -134,7 +151,7 @@ if defined?(Sidekiq)
|
|
|
134
151
|
context 'both calls with different update fields' do
|
|
135
152
|
it 'deos reindex with union of fields' do
|
|
136
153
|
Timecop.freeze do
|
|
137
|
-
expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id]), update_fields: %w[name description]).once
|
|
154
|
+
expect(CitiesIndex).to receive(:import!).with(match_array([city.id.to_s, other_city.id.to_s]), update_fields: match_array(%w[name description])).once
|
|
138
155
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id], update_fields: ['name'])
|
|
139
156
|
scheduler.postpone
|
|
140
157
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [other_city.id], update_fields: ['description'])
|
|
@@ -148,8 +165,8 @@ if defined?(Sidekiq)
|
|
|
148
165
|
context 'two calls within different timewindows' do
|
|
149
166
|
it 'does two separate reindexes' do
|
|
150
167
|
Timecop.freeze do
|
|
151
|
-
expect(CitiesIndex).to receive(:import!).with([city.id]).once
|
|
152
|
-
expect(CitiesIndex).to receive(:import!).with([other_city.id]).once
|
|
168
|
+
expect(CitiesIndex).to receive(:import!).with([city.id.to_s]).once
|
|
169
|
+
expect(CitiesIndex).to receive(:import!).with([other_city.id.to_s]).once
|
|
153
170
|
Timecop.travel(20.seconds.ago) do
|
|
154
171
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id])
|
|
155
172
|
scheduler.postpone
|
|
@@ -164,8 +181,8 @@ if defined?(Sidekiq)
|
|
|
164
181
|
context 'first call has update_fields' do
|
|
165
182
|
it 'does first reindex with the expected update_fields and second without update_fields' do
|
|
166
183
|
Timecop.freeze do
|
|
167
|
-
expect(CitiesIndex).to receive(:import!).with([city.id], update_fields: ['name']).once
|
|
168
|
-
expect(CitiesIndex).to receive(:import!).with([other_city.id]).once
|
|
184
|
+
expect(CitiesIndex).to receive(:import!).with([city.id.to_s], update_fields: ['name']).once
|
|
185
|
+
expect(CitiesIndex).to receive(:import!).with([other_city.id.to_s]).once
|
|
169
186
|
Timecop.travel(20.seconds.ago) do
|
|
170
187
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id], update_fields: ['name'])
|
|
171
188
|
scheduler.postpone
|
|
@@ -180,8 +197,8 @@ if defined?(Sidekiq)
|
|
|
180
197
|
context 'both calls have update_fields option' do
|
|
181
198
|
it 'does both reindexes with their expected update_fields option' do
|
|
182
199
|
Timecop.freeze do
|
|
183
|
-
expect(CitiesIndex).to receive(:import!).with([city.id], update_fields: ['name']).once
|
|
184
|
-
expect(CitiesIndex).to receive(:import!).with([other_city.id], update_fields: ['description']).once
|
|
200
|
+
expect(CitiesIndex).to receive(:import!).with([city.id.to_s], update_fields: ['name']).once
|
|
201
|
+
expect(CitiesIndex).to receive(:import!).with([other_city.id.to_s], update_fields: ['description']).once
|
|
185
202
|
Timecop.travel(20.seconds.ago) do
|
|
186
203
|
scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id], update_fields: ['name'])
|
|
187
204
|
scheduler.postpone
|
data/spec/chewy/strategy_spec.rb
CHANGED
data/spec/chewy_spec.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Chewy do
|
|
4
|
-
it '
|
|
5
|
-
expect(Chewy::VERSION).not_to
|
|
4
|
+
it 'has a version number' do
|
|
5
|
+
expect(Chewy::VERSION).not_to be_nil
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
describe '.derive_name' do
|
|
@@ -31,24 +31,6 @@ describe Chewy do
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
describe '.massacre' do
|
|
35
|
-
before { Chewy.massacre }
|
|
36
|
-
|
|
37
|
-
before do
|
|
38
|
-
allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix1'))
|
|
39
|
-
stub_index(:admins).create!
|
|
40
|
-
allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix2'))
|
|
41
|
-
stub_index(:developers).create!
|
|
42
|
-
|
|
43
|
-
Chewy.massacre
|
|
44
|
-
|
|
45
|
-
allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix1'))
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
specify { expect(AdminsIndex.exists?).to eq(true) }
|
|
49
|
-
specify { expect(DevelopersIndex.exists?).to eq(false) }
|
|
50
|
-
end
|
|
51
|
-
|
|
52
34
|
describe '.client' do
|
|
53
35
|
let!(:initial_client) { Chewy.current[:chewy_client] }
|
|
54
36
|
let(:faraday_block) { proc {} }
|
|
@@ -84,7 +66,8 @@ describe Chewy do
|
|
|
84
66
|
# To avoid flaky issues when previous specs were run
|
|
85
67
|
allow(Chewy::Index).to receive(:descendants).and_return([CitiesIndex, PlacesIndex])
|
|
86
68
|
|
|
87
|
-
|
|
69
|
+
CitiesIndex.delete
|
|
70
|
+
PlacesIndex.delete
|
|
88
71
|
end
|
|
89
72
|
|
|
90
73
|
specify do
|
|
@@ -111,7 +94,7 @@ describe Chewy do
|
|
|
111
94
|
expect(CitiesIndex.exists?).to eq true
|
|
112
95
|
expect(PlacesIndex.exists?).to eq true
|
|
113
96
|
|
|
114
|
-
expect { Chewy.create_indices! }.to raise_error(
|
|
97
|
+
expect { Chewy.create_indices! }.to raise_error(Elastic::Transport::Transport::Errors::BadRequest)
|
|
115
98
|
end
|
|
116
99
|
end
|
|
117
100
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -28,6 +28,32 @@ Chewy.settings = {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
# To work with security enabled:
|
|
32
|
+
#
|
|
33
|
+
# user = ENV['ES_USER'] || 'elastic'
|
|
34
|
+
# password = ENV['ES_PASSWORD'] || ''
|
|
35
|
+
# ca_cert = ENV['ES_CA_CERT'] || './tmp/http_ca.crt'
|
|
36
|
+
#
|
|
37
|
+
# Chewy.settings.merge!(
|
|
38
|
+
# user: user,
|
|
39
|
+
# password: password,
|
|
40
|
+
# transport_options: {
|
|
41
|
+
# ssl: {
|
|
42
|
+
# ca_file: ca_cert
|
|
43
|
+
# }
|
|
44
|
+
# }
|
|
45
|
+
# )
|
|
46
|
+
|
|
47
|
+
# Low-level substitute for now-obsolete drop_indices
|
|
48
|
+
def drop_indices
|
|
49
|
+
response = Chewy.client.cat.indices
|
|
50
|
+
indices = response.body.lines.map { |line| line.split[2] }
|
|
51
|
+
return if indices.blank?
|
|
52
|
+
|
|
53
|
+
Chewy.client.indices.delete(index: indices)
|
|
54
|
+
Chewy.wait_for_status
|
|
55
|
+
end
|
|
56
|
+
|
|
31
57
|
# Chewy.transport_logger = Logger.new(STDERR)
|
|
32
58
|
|
|
33
59
|
RSpec.configure do |config|
|
|
@@ -6,17 +6,16 @@ if ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks)
|
|
|
6
6
|
ActiveRecord::Base.raise_in_transactional_callbacks = true
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'cities'")
|
|
11
|
-
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'locations'")
|
|
12
|
-
ActiveRecord::Schema.define do
|
|
9
|
+
def create_countries_table
|
|
13
10
|
create_table :countries do |t|
|
|
14
11
|
t.column :name, :string
|
|
15
12
|
t.column :country_code, :string
|
|
16
13
|
t.column :rating, :integer
|
|
17
14
|
t.column :updated_at, :datetime
|
|
18
15
|
end
|
|
16
|
+
end
|
|
19
17
|
|
|
18
|
+
def create_cities_table
|
|
20
19
|
create_table :cities do |t|
|
|
21
20
|
t.column :country_id, :integer
|
|
22
21
|
t.column :name, :string
|
|
@@ -25,13 +24,17 @@ ActiveRecord::Schema.define do
|
|
|
25
24
|
t.column :rating, :integer
|
|
26
25
|
t.column :updated_at, :datetime
|
|
27
26
|
end
|
|
27
|
+
end
|
|
28
28
|
|
|
29
|
+
def create_locations_table
|
|
29
30
|
create_table :locations do |t|
|
|
30
31
|
t.column :city_id, :integer
|
|
31
32
|
t.column :lat, :string
|
|
32
33
|
t.column :lon, :string
|
|
33
34
|
end
|
|
35
|
+
end
|
|
34
36
|
|
|
37
|
+
def create_comments_table
|
|
35
38
|
create_table :comments do |t|
|
|
36
39
|
t.column :content, :string
|
|
37
40
|
t.column :comment_type, :string
|
|
@@ -40,6 +43,26 @@ ActiveRecord::Schema.define do
|
|
|
40
43
|
end
|
|
41
44
|
end
|
|
42
45
|
|
|
46
|
+
def create_users_table
|
|
47
|
+
create_table :users, id: false do |t|
|
|
48
|
+
t.column :id, :string
|
|
49
|
+
t.column :name, :string
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'countries'")
|
|
54
|
+
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'cities'")
|
|
55
|
+
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'locations'")
|
|
56
|
+
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'comments'")
|
|
57
|
+
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'users'")
|
|
58
|
+
ActiveRecord::Schema.define do
|
|
59
|
+
create_countries_table
|
|
60
|
+
create_cities_table
|
|
61
|
+
create_locations_table
|
|
62
|
+
create_comments_table
|
|
63
|
+
create_users_table
|
|
64
|
+
end
|
|
65
|
+
|
|
43
66
|
module ActiveRecordClassHelpers
|
|
44
67
|
extend ActiveSupport::Concern
|
|
45
68
|
|
|
@@ -73,6 +96,14 @@ module ActiveRecordClassHelpers
|
|
|
73
96
|
def stub_model(name, superclass = nil, &block)
|
|
74
97
|
stub_class(name, superclass || ActiveRecord::Base, &block)
|
|
75
98
|
end
|
|
99
|
+
|
|
100
|
+
def stub_uuid_model(name, superclass = nil, &block)
|
|
101
|
+
stub_class(name, superclass || ActiveRecord::Base) do
|
|
102
|
+
before_create { self.id = SecureRandom.uuid }
|
|
103
|
+
define_singleton_method(:primary_key, -> { 'id' })
|
|
104
|
+
class_eval(&block)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
76
107
|
end
|
|
77
108
|
|
|
78
109
|
RSpec.configure do |config|
|