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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/dependabot.yml +2 -2
  4. data/.github/workflows/ruby.yml +11 -10
  5. data/.rubocop.yml +1 -1
  6. data/.rubocop_todo.yml +132 -39
  7. data/CHANGELOG.md +18 -1
  8. data/CONTRIBUTING.md +1 -1
  9. data/LICENSE.txt +1 -1
  10. data/README.md +50 -1125
  11. data/chewy.gemspec +3 -2
  12. data/docker-compose.yml +14 -0
  13. data/docs/README.md +16 -0
  14. data/docs/configuration.md +440 -0
  15. data/docs/import.md +122 -0
  16. data/docs/indexing.md +329 -0
  17. data/docs/querying.md +72 -0
  18. data/docs/rake_tasks.md +108 -0
  19. data/docs/testing.md +41 -0
  20. data/docs/troubleshooting.md +101 -0
  21. data/gemfiles/base.gemfile +3 -3
  22. data/gemfiles/{rails.6.1.activerecord.gemfile → rails.7.2.activerecord.gemfile} +3 -3
  23. data/gemfiles/{rails.7.0.activerecord.gemfile → rails.8.0.activerecord.gemfile} +3 -3
  24. data/lib/chewy/config.rb +2 -2
  25. data/lib/chewy/errors.rb +3 -0
  26. data/lib/chewy/fields/root.rb +1 -1
  27. data/lib/chewy/index/actions.rb +5 -5
  28. data/lib/chewy/index/aliases.rb +1 -1
  29. data/lib/chewy/index/syncer.rb +5 -5
  30. data/lib/chewy/minitest/helpers.rb +1 -1
  31. data/lib/chewy/search/request.rb +4 -4
  32. data/lib/chewy/search/response.rb +7 -0
  33. data/lib/chewy/search/scrolling.rb +2 -1
  34. data/lib/chewy/strategy/delayed_sidekiq/worker.rb +1 -1
  35. data/lib/chewy/version.rb +1 -1
  36. data/lib/chewy.rb +4 -0
  37. data/migration_guide.md +1 -1
  38. data/spec/chewy/config_spec.rb +13 -14
  39. data/spec/chewy/elastic_client_spec.rb +1 -1
  40. data/spec/chewy/fields/base_spec.rb +2 -2
  41. data/spec/chewy/fields/time_fields_spec.rb +1 -1
  42. data/spec/chewy/index/actions_spec.rb +9 -70
  43. data/spec/chewy/index/aliases_spec.rb +1 -1
  44. data/spec/chewy/index/import/bulk_builder_spec.rb +2 -2
  45. data/spec/chewy/index/import/bulk_request_spec.rb +1 -1
  46. data/spec/chewy/index/import/routine_spec.rb +1 -1
  47. data/spec/chewy/index/import_spec.rb +15 -15
  48. data/spec/chewy/index/observe/callback_spec.rb +1 -1
  49. data/spec/chewy/index/specification_spec.rb +1 -4
  50. data/spec/chewy/index/syncer_spec.rb +1 -1
  51. data/spec/chewy/index_spec.rb +1 -1
  52. data/spec/chewy/journal_spec.rb +2 -2
  53. data/spec/chewy/minitest/helpers_spec.rb +2 -6
  54. data/spec/chewy/multi_search_spec.rb +1 -1
  55. data/spec/chewy/rake_helper_spec.rb +1 -1
  56. data/spec/chewy/repository_spec.rb +4 -4
  57. data/spec/chewy/rspec/update_index_spec.rb +2 -2
  58. data/spec/chewy/runtime_spec.rb +2 -2
  59. data/spec/chewy/search/loader_spec.rb +1 -1
  60. data/spec/chewy/search/pagination/kaminari_examples.rb +1 -1
  61. data/spec/chewy/search/query_proxy_spec.rb +0 -24
  62. data/spec/chewy/search/request_spec.rb +7 -3
  63. data/spec/chewy/search/response_spec.rb +2 -24
  64. data/spec/chewy/search/scrolling_spec.rb +1 -1
  65. data/spec/chewy/search_spec.rb +1 -1
  66. data/spec/chewy/stash_spec.rb +1 -1
  67. data/spec/chewy/strategy/delayed_sidekiq_spec.rb +27 -10
  68. data/spec/chewy/strategy_spec.rb +1 -1
  69. data/spec/chewy_spec.rb +5 -22
  70. data/spec/spec_helper.rb +26 -0
  71. data/spec/support/active_record.rb +35 -4
  72. metadata +22 -17
  73. data/gemfiles/rails.7.1.activerecord.gemfile +0 -14
@@ -21,7 +21,7 @@ describe Chewy::Journal do
21
21
  default_import_options journal: true
22
22
  end
23
23
 
24
- Chewy.massacre
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 { Chewy.massacre }
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
- Chewy.massacre
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, unexpected_query_error_message)
126
+ .to raise_error(RuntimeError, /instead of expected query\./)
131
127
  end
132
128
  end
133
129
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'chewy/multi_search'
3
3
 
4
4
  describe Chewy::MultiSearch do
5
- before { Chewy.massacre }
5
+ before { drop_indices }
6
6
 
7
7
  before do
8
8
  stub_model(:city)
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'rake'
3
3
 
4
4
  describe Chewy::RakeHelper, :orm do
5
- before { Chewy.massacre }
5
+ before { drop_indices }
6
6
 
7
7
  before do
8
8
  described_class.instance_variable_set(:@journal_exists, journal_exists)
@@ -3,10 +3,10 @@ require 'spec_helper'
3
3
  describe Chewy::Repository do
4
4
  subject { described_class.send(:new) }
5
5
 
6
- its(:analyzers) { should == {} }
7
- its(:tokenizers) { should == {} }
8
- its(:filters) { should == {} }
9
- its(:char_filters) { should == {} }
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
- Chewy.massacre
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 'with {:a=>2}, but it was reindexed with {:a=>"1"}' }
265
+ specify { expectation.to fail_matching 'but it was reindexed with' }
266
266
  end
267
267
  end
268
268
  end
@@ -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.0' }
7
- specify { expect(described_class.version).to be < '8.0' }
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
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search::Loader do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_model(:city)
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  shared_examples :kaminari do |request_base_class|
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_index(:products) do
@@ -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 { Chewy.massacre }
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 eq('<Chewy::Search::Request {:index=>["products"], :body=>{}}>')
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 eq('<ProductsIndex::Query {:index=>["products"], :body=>{:size=>10}}>')
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 { Chewy.massacre }
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 _type _score _source sort])
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
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search::Scrolling, :orm do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_model(:city)
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_index(:products)
@@ -5,7 +5,7 @@ describe Chewy::Stash::Journal, :orm do
5
5
  response['deleted'] || response['_indices']['_all']['deleted']
6
6
  end
7
7
 
8
- before { Chewy.massacre }
8
+ before { drop_indices }
9
9
 
10
10
  before do
11
11
  stub_model(:city)
@@ -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
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Strategy do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
  subject(:strategy) { Chewy::Strategy.new }
6
6
 
7
7
  describe '#current' do
data/spec/chewy_spec.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy do
4
- it 'should have a version number' do
5
- expect(Chewy::VERSION).not_to be nil
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
- Chewy.massacre
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(Elasticsearch::Transport::Transport::Errors::BadRequest)
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
- ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'countries'")
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|