chewy 6.0.0 → 7.6.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 (188) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
  6. data/.github/dependabot.yml +42 -0
  7. data/.github/workflows/ruby.yml +60 -0
  8. data/.rubocop.yml +16 -8
  9. data/.rubocop_todo.yml +110 -22
  10. data/CHANGELOG.md +396 -105
  11. data/CODE_OF_CONDUCT.md +14 -0
  12. data/CONTRIBUTING.md +63 -0
  13. data/Gemfile +4 -10
  14. data/Guardfile +3 -1
  15. data/README.md +497 -275
  16. data/chewy.gemspec +5 -20
  17. data/gemfiles/base.gemfile +12 -0
  18. data/gemfiles/rails.6.1.activerecord.gemfile +10 -15
  19. data/gemfiles/rails.7.0.activerecord.gemfile +14 -0
  20. data/gemfiles/rails.7.1.activerecord.gemfile +14 -0
  21. data/lib/chewy/config.rb +60 -52
  22. data/lib/chewy/elastic_client.rb +31 -0
  23. data/lib/chewy/errors.rb +7 -10
  24. data/lib/chewy/fields/base.rb +79 -13
  25. data/lib/chewy/fields/root.rb +4 -14
  26. data/lib/chewy/index/actions.rb +54 -37
  27. data/lib/chewy/{type → index}/adapter/active_record.rb +30 -6
  28. data/lib/chewy/{type → index}/adapter/base.rb +2 -3
  29. data/lib/chewy/{type → index}/adapter/object.rb +27 -31
  30. data/lib/chewy/{type → index}/adapter/orm.rb +17 -18
  31. data/lib/chewy/index/aliases.rb +14 -5
  32. data/lib/chewy/index/crutch.rb +40 -0
  33. data/lib/chewy/index/import/bulk_builder.rb +311 -0
  34. data/lib/chewy/{type → index}/import/bulk_request.rb +6 -7
  35. data/lib/chewy/{type → index}/import/journal_builder.rb +11 -12
  36. data/lib/chewy/{type → index}/import/routine.rb +18 -17
  37. data/lib/chewy/{type → index}/import.rb +76 -32
  38. data/lib/chewy/{type → index}/mapping.rb +29 -34
  39. data/lib/chewy/index/observe/active_record_methods.rb +87 -0
  40. data/lib/chewy/index/observe/callback.rb +34 -0
  41. data/lib/chewy/index/observe.rb +17 -0
  42. data/lib/chewy/index/specification.rb +1 -0
  43. data/lib/chewy/{type → index}/syncer.rb +59 -59
  44. data/lib/chewy/{type → index}/witchcraft.rb +11 -7
  45. data/lib/chewy/{type → index}/wrapper.rb +2 -2
  46. data/lib/chewy/index.rb +67 -94
  47. data/lib/chewy/journal.rb +25 -14
  48. data/lib/chewy/log_subscriber.rb +5 -1
  49. data/lib/chewy/minitest/helpers.rb +86 -13
  50. data/lib/chewy/minitest/search_index_receiver.rb +24 -26
  51. data/lib/chewy/railtie.rb +6 -20
  52. data/lib/chewy/rake_helper.rb +169 -113
  53. data/lib/chewy/rspec/build_query.rb +12 -0
  54. data/lib/chewy/rspec/helpers.rb +55 -0
  55. data/lib/chewy/rspec/update_index.rb +55 -44
  56. data/lib/chewy/rspec.rb +2 -0
  57. data/lib/chewy/runtime/version.rb +1 -1
  58. data/lib/chewy/runtime.rb +1 -1
  59. data/lib/chewy/search/loader.rb +19 -41
  60. data/lib/chewy/search/parameters/collapse.rb +16 -0
  61. data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
  62. data/lib/chewy/search/parameters/ignore_unavailable.rb +27 -0
  63. data/lib/chewy/search/parameters/indices.rb +13 -58
  64. data/lib/chewy/search/parameters/knn.rb +16 -0
  65. data/lib/chewy/search/parameters/order.rb +6 -19
  66. data/lib/chewy/search/parameters/source.rb +5 -1
  67. data/lib/chewy/search/parameters/storage.rb +1 -1
  68. data/lib/chewy/search/parameters/track_total_hits.rb +16 -0
  69. data/lib/chewy/search/parameters.rb +6 -4
  70. data/lib/chewy/search/query_proxy.rb +9 -2
  71. data/lib/chewy/search/request.rb +169 -134
  72. data/lib/chewy/search/response.rb +5 -5
  73. data/lib/chewy/search/scoping.rb +7 -8
  74. data/lib/chewy/search/scrolling.rb +13 -13
  75. data/lib/chewy/search.rb +9 -19
  76. data/lib/chewy/stash.rb +19 -30
  77. data/lib/chewy/strategy/active_job.rb +1 -1
  78. data/lib/chewy/strategy/atomic_no_refresh.rb +18 -0
  79. data/lib/chewy/strategy/base.rb +10 -0
  80. data/lib/chewy/strategy/delayed_sidekiq/scheduler.rb +168 -0
  81. data/lib/chewy/strategy/delayed_sidekiq/worker.rb +76 -0
  82. data/lib/chewy/strategy/delayed_sidekiq.rb +30 -0
  83. data/lib/chewy/strategy/lazy_sidekiq.rb +64 -0
  84. data/lib/chewy/strategy/sidekiq.rb +2 -1
  85. data/lib/chewy/strategy.rb +6 -19
  86. data/lib/chewy/version.rb +1 -1
  87. data/lib/chewy.rb +39 -86
  88. data/lib/generators/chewy/install_generator.rb +1 -1
  89. data/lib/tasks/chewy.rake +36 -32
  90. data/migration_guide.md +46 -8
  91. data/spec/chewy/config_spec.rb +16 -41
  92. data/spec/chewy/elastic_client_spec.rb +26 -0
  93. data/spec/chewy/fields/base_spec.rb +432 -147
  94. data/spec/chewy/fields/root_spec.rb +20 -28
  95. data/spec/chewy/fields/time_fields_spec.rb +5 -5
  96. data/spec/chewy/index/actions_spec.rb +368 -59
  97. data/spec/chewy/{type → index}/adapter/active_record_spec.rb +156 -40
  98. data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
  99. data/spec/chewy/index/aliases_spec.rb +3 -3
  100. data/spec/chewy/index/import/bulk_builder_spec.rb +494 -0
  101. data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -12
  102. data/spec/chewy/{type → index}/import/journal_builder_spec.rb +9 -19
  103. data/spec/chewy/{type → index}/import/routine_spec.rb +19 -19
  104. data/spec/chewy/{type → index}/import_spec.rb +164 -98
  105. data/spec/chewy/index/mapping_spec.rb +135 -0
  106. data/spec/chewy/index/observe/active_record_methods_spec.rb +68 -0
  107. data/spec/chewy/index/observe/callback_spec.rb +139 -0
  108. data/spec/chewy/index/observe_spec.rb +143 -0
  109. data/spec/chewy/index/settings_spec.rb +3 -1
  110. data/spec/chewy/index/specification_spec.rb +20 -30
  111. data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
  112. data/spec/chewy/{type → index}/witchcraft_spec.rb +20 -22
  113. data/spec/chewy/index/wrapper_spec.rb +100 -0
  114. data/spec/chewy/index_spec.rb +60 -105
  115. data/spec/chewy/journal_spec.rb +25 -74
  116. data/spec/chewy/minitest/helpers_spec.rb +123 -15
  117. data/spec/chewy/minitest/search_index_receiver_spec.rb +28 -30
  118. data/spec/chewy/multi_search_spec.rb +4 -5
  119. data/spec/chewy/rake_helper_spec.rb +315 -55
  120. data/spec/chewy/rspec/build_query_spec.rb +34 -0
  121. data/spec/chewy/rspec/helpers_spec.rb +61 -0
  122. data/spec/chewy/rspec/update_index_spec.rb +74 -71
  123. data/spec/chewy/runtime_spec.rb +2 -2
  124. data/spec/chewy/search/loader_spec.rb +19 -53
  125. data/spec/chewy/search/pagination/kaminari_examples.rb +4 -6
  126. data/spec/chewy/search/pagination/kaminari_spec.rb +2 -2
  127. data/spec/chewy/search/parameters/collapse_spec.rb +5 -0
  128. data/spec/chewy/search/parameters/ignore_unavailable_spec.rb +67 -0
  129. data/spec/chewy/search/parameters/indices_spec.rb +26 -117
  130. data/spec/chewy/search/parameters/knn_spec.rb +5 -0
  131. data/spec/chewy/search/parameters/order_spec.rb +18 -11
  132. data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
  133. data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
  134. data/spec/chewy/search/parameters/source_spec.rb +8 -2
  135. data/spec/chewy/search/parameters/track_total_hits_spec.rb +5 -0
  136. data/spec/chewy/search/parameters_spec.rb +18 -4
  137. data/spec/chewy/search/query_proxy_spec.rb +68 -17
  138. data/spec/chewy/search/request_spec.rb +292 -110
  139. data/spec/chewy/search/response_spec.rb +12 -12
  140. data/spec/chewy/search/scrolling_spec.rb +10 -17
  141. data/spec/chewy/search_spec.rb +40 -34
  142. data/spec/chewy/stash_spec.rb +9 -21
  143. data/spec/chewy/strategy/active_job_spec.rb +16 -16
  144. data/spec/chewy/strategy/atomic_no_refresh_spec.rb +60 -0
  145. data/spec/chewy/strategy/atomic_spec.rb +9 -10
  146. data/spec/chewy/strategy/delayed_sidekiq_spec.rb +208 -0
  147. data/spec/chewy/strategy/lazy_sidekiq_spec.rb +214 -0
  148. data/spec/chewy/strategy/sidekiq_spec.rb +12 -12
  149. data/spec/chewy/strategy_spec.rb +19 -15
  150. data/spec/chewy_spec.rb +24 -107
  151. data/spec/spec_helper.rb +3 -22
  152. data/spec/support/active_record.rb +25 -7
  153. metadata +78 -339
  154. data/.circleci/config.yml +0 -240
  155. data/Appraisals +0 -81
  156. data/gemfiles/rails.5.2.activerecord.gemfile +0 -17
  157. data/gemfiles/rails.5.2.mongoid.6.4.gemfile +0 -17
  158. data/gemfiles/rails.6.0.activerecord.gemfile +0 -17
  159. data/gemfiles/sequel.4.45.gemfile +0 -11
  160. data/lib/chewy/backports/deep_dup.rb +0 -46
  161. data/lib/chewy/backports/duplicable.rb +0 -91
  162. data/lib/chewy/search/pagination/will_paginate.rb +0 -43
  163. data/lib/chewy/search/parameters/types.rb +0 -20
  164. data/lib/chewy/strategy/resque.rb +0 -27
  165. data/lib/chewy/strategy/shoryuken.rb +0 -40
  166. data/lib/chewy/type/actions.rb +0 -43
  167. data/lib/chewy/type/adapter/mongoid.rb +0 -67
  168. data/lib/chewy/type/adapter/sequel.rb +0 -93
  169. data/lib/chewy/type/crutch.rb +0 -32
  170. data/lib/chewy/type/import/bulk_builder.rb +0 -122
  171. data/lib/chewy/type/observe.rb +0 -82
  172. data/lib/chewy/type.rb +0 -120
  173. data/lib/sequel/plugins/chewy_observe.rb +0 -63
  174. data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
  175. data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
  176. data/spec/chewy/search/parameters/types_spec.rb +0 -5
  177. data/spec/chewy/strategy/resque_spec.rb +0 -46
  178. data/spec/chewy/strategy/shoryuken_spec.rb +0 -70
  179. data/spec/chewy/type/actions_spec.rb +0 -50
  180. data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
  181. data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
  182. data/spec/chewy/type/import/bulk_builder_spec.rb +0 -194
  183. data/spec/chewy/type/mapping_spec.rb +0 -175
  184. data/spec/chewy/type/observe_spec.rb +0 -137
  185. data/spec/chewy/type/wrapper_spec.rb +0 -100
  186. data/spec/chewy/type_spec.rb +0 -55
  187. data/spec/support/mongoid.rb +0 -93
  188. data/spec/support/sequel.rb +0 -80
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Index::Mapping do
4
+ let(:product) { ProductsIndex }
5
+ let(:review) { ReviewsIndex }
6
+
7
+ before do
8
+ stub_index(:products) do
9
+ root do
10
+ field :name, 'surname'
11
+ field :title, type: 'text' do
12
+ field :subfield1
13
+ end
14
+ field 'price', type: 'float' do
15
+ field :subfield2
16
+ end
17
+ agg :named_agg do
18
+ {avg: {field: 'title.subfield1'}}
19
+ end
20
+ end
21
+ end
22
+ stub_index(:reviews) do
23
+ field :title, :body
24
+ field :comments do
25
+ field :message
26
+ field :rating, type: 'long'
27
+ end
28
+ agg :named_agg do
29
+ {avg: {field: 'comments.rating'}}
30
+ end
31
+ end
32
+ end
33
+
34
+ context 'no root element call' do
35
+ before do
36
+ stub_index(:products) do
37
+ field :title, type: 'text' do
38
+ field :subfield1
39
+ end
40
+ end
41
+ end
42
+
43
+ specify { expect(product.root.children.map(&:name)).to eq([:title]) }
44
+ specify { expect(product.root.children.map(&:parent)).to eq([product.root]) }
45
+ specify { expect(product.root.children[0].children.map(&:name)).to eq([:subfield1]) }
46
+ specify { expect(product.root.children[0].children.map(&:parent)).to eq([product.root.children[0]]) }
47
+
48
+ context 'default root options are set' do
49
+ around do |example|
50
+ previous_options = Chewy.default_root_options
51
+ Chewy.default_root_options = {_all: {enabled: false}}
52
+ example.run
53
+ Chewy.default_root_options = previous_options
54
+ end
55
+
56
+ specify { expect(product.mappings_hash[:mappings]).to include(_all: {enabled: false}) }
57
+ end
58
+ end
59
+
60
+ describe '.agg' do
61
+ specify { expect(product._agg_defs[:named_agg].call).to eq(avg: {field: 'title.subfield1'}) }
62
+ specify { expect(review._agg_defs[:named_agg].call).to eq(avg: {field: 'comments.rating'}) }
63
+ end
64
+
65
+ describe '.field' do
66
+ specify { expect(product.root.children.map(&:name)).to eq(%i[name surname title price]) }
67
+ specify { expect(product.root.children.map(&:parent)).to eq([product.root] * 4) }
68
+
69
+ specify { expect(product.root.children[0].children.map(&:name)).to eq([]) }
70
+ specify { expect(product.root.children[1].children.map(&:name)).to eq([]) }
71
+
72
+ specify { expect(product.root.children[2].children.map(&:name)).to eq([:subfield1]) }
73
+ specify { expect(product.root.children[2].children.map(&:parent)).to eq([product.root.children[2]]) }
74
+
75
+ specify { expect(product.root.children[3].children.map(&:name)).to eq([:subfield2]) }
76
+ specify { expect(product.root.children[3].children.map(&:parent)).to eq([product.root.children[3]]) }
77
+ end
78
+
79
+ describe '.mappings_hash' do
80
+ specify { expect(product.mappings_hash[:mappings]).to eq(product.root.mappings_hash) }
81
+
82
+ context 'root merging' do
83
+ context do
84
+ before do
85
+ stub_index(:products) do
86
+ root other_option: 'nothing' do
87
+ field :name do
88
+ field :last_name # will be redefined in the following root flock
89
+ end
90
+ end
91
+ root other_option: 'option_value' do
92
+ field :identifier
93
+ field :name, type: 'integer'
94
+ end
95
+ end
96
+ end
97
+
98
+ specify do
99
+ expect(product.mappings_hash).to eq(
100
+ mappings: {
101
+ properties: {
102
+ name: {type: 'integer'},
103
+ identifier: {type: Chewy.default_field_type}
104
+ },
105
+ other_option: 'option_value'
106
+ }
107
+ )
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ describe '.supports_outdated_sync?' do
114
+ def index(&block)
115
+ stub_index(:cities, &block)
116
+ CitiesIndex
117
+ end
118
+
119
+ specify { expect(index.supports_outdated_sync?).to eq(false) }
120
+ specify { expect(index { field :updated_at }.supports_outdated_sync?).to eq(true) }
121
+ specify { expect(index { field :updated_at, value: -> {} }.supports_outdated_sync?).to eq(false) }
122
+ specify do
123
+ expect(index do
124
+ self.outdated_sync_field = :version
125
+ field :updated_at
126
+ end.supports_outdated_sync?).to eq(false)
127
+ end
128
+ specify do
129
+ expect(index do
130
+ self.outdated_sync_field = :version
131
+ field :version
132
+ end.supports_outdated_sync?).to eq(true)
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Index::Observe::ActiveRecordMethods do
4
+ describe '.update_index' do
5
+ before { stub_model(:city) }
6
+
7
+ it 'initializes chewy callbacks when first update_index is evaluated' do
8
+ expect(City).to receive(:initialize_chewy_callbacks).once
9
+ City.update_index 'cities', :self
10
+ City.update_index 'countries', -> {}
11
+ end
12
+
13
+ it 'adds chewy callbacks to model' do
14
+ expect(City.chewy_callbacks.count).to eq(0)
15
+
16
+ City.update_index 'cities', :self
17
+ City.update_index 'countries', -> {}
18
+
19
+ expect(City.chewy_callbacks.count).to eq(2)
20
+ end
21
+ end
22
+
23
+ describe 'callbacks' do
24
+ before { stub_model(:city) { update_index 'cities', :self } }
25
+ before { stub_index(:cities) { index_scope City } }
26
+ before { allow(Chewy).to receive(:use_after_commit_callbacks).and_return(use_after_commit_callbacks) }
27
+
28
+ let(:city) do
29
+ Chewy.strategy(:bypass) do
30
+ City.create!
31
+ end
32
+ end
33
+
34
+ shared_examples 'handles callbacks correctly' do
35
+ it 'handles callbacks with strategy for possible lazy evaluation on save!' do
36
+ Chewy.strategy(:urgent) do
37
+ expect(city).to receive(:update_chewy_indices).and_call_original
38
+ expect(Chewy.strategy.current).to receive(:update_chewy_indices).with(city)
39
+ expect(city).not_to receive(:run_chewy_callbacks)
40
+
41
+ city.save!
42
+ end
43
+ end
44
+
45
+ it 'runs callbacks at the moment on destroy' do
46
+ Chewy.strategy(:urgent) do
47
+ expect(city).not_to receive(:update_chewy_indices)
48
+ expect(Chewy.strategy.current).not_to receive(:update_chewy_indices)
49
+ expect(city).to receive(:run_chewy_callbacks)
50
+
51
+ city.destroy
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'when Chewy.use_after_commit_callbacks is true' do
57
+ let(:use_after_commit_callbacks) { true }
58
+
59
+ include_examples 'handles callbacks correctly'
60
+ end
61
+
62
+ context 'when Chewy.use_after_commit_callbacks is false' do
63
+ let(:use_after_commit_callbacks) { false }
64
+
65
+ include_examples 'handles callbacks correctly'
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Index::Observe::Callback do
4
+ subject(:callback) { described_class.new(executable) }
5
+
6
+ before do
7
+ stub_model(:city) do
8
+ attr_accessor :population
9
+ end
10
+ end
11
+
12
+ let(:city) { City.create!(population: 100) }
13
+
14
+ describe '#call' do
15
+ context 'when executable is has arity 0' do
16
+ let(:executable) { -> { population } }
17
+
18
+ it 'calls exectuable within context' do
19
+ expect(callback.call(city)).to eq(city.population)
20
+ end
21
+ end
22
+
23
+ context 'when executable is has arity 1' do
24
+ let(:executable) { ->(record) { record.population } }
25
+
26
+ it 'calls exectuable within context' do
27
+ expect(callback.call(city)).to eq(city.population)
28
+ end
29
+ end
30
+
31
+ describe 'filters' do
32
+ let(:executable) { ->(_) {} }
33
+
34
+ describe 'if' do
35
+ subject(:callback) { described_class.new(executable, if: filter) }
36
+
37
+ shared_examples 'an if filter' do
38
+ context 'when condition is true' do
39
+ let(:condition) { true }
40
+
41
+ specify do
42
+ expect(executable).to receive(:call).with(city)
43
+
44
+ callback.call(city)
45
+ end
46
+ end
47
+
48
+ context 'when condition is false' do
49
+ let(:condition) { false }
50
+
51
+ specify do
52
+ expect(executable).not_to receive(:call)
53
+
54
+ callback.call(city)
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'when filter is symbol' do
60
+ let(:filter) { :condition }
61
+
62
+ before do
63
+ allow(city).to receive(:condition).and_return(condition)
64
+ end
65
+
66
+ include_examples 'an if filter'
67
+ end
68
+
69
+ context 'when filter is proc' do
70
+ let(:filter) { -> { condition_state } }
71
+
72
+ before do
73
+ allow_any_instance_of(City).to receive(:condition_state).and_return(condition)
74
+ end
75
+
76
+ include_examples 'an if filter'
77
+ end
78
+
79
+ context 'when filter is literal' do
80
+ let(:filter) { condition }
81
+
82
+ include_examples 'an if filter'
83
+ end
84
+ end
85
+
86
+ describe 'unless' do
87
+ subject(:callback) { described_class.new(executable, unless: filter) }
88
+
89
+ shared_examples 'an unless filter' do
90
+ context 'when condition is true' do
91
+ let(:condition) { true }
92
+
93
+ specify do
94
+ expect(executable).not_to receive(:call)
95
+
96
+ callback.call(city)
97
+ end
98
+ end
99
+
100
+ context 'when condition is false' do
101
+ let(:condition) { false }
102
+
103
+ specify do
104
+ expect(executable).to receive(:call).with(city)
105
+
106
+ callback.call(city)
107
+ end
108
+ end
109
+ end
110
+
111
+ context 'when filter is symbol' do
112
+ let(:filter) { :condition }
113
+
114
+ before do
115
+ allow(city).to receive(:condition).and_return(condition)
116
+ end
117
+
118
+ include_examples 'an unless filter'
119
+ end
120
+
121
+ context 'when filter is proc' do
122
+ let(:filter) { -> { condition_state } }
123
+
124
+ before do
125
+ allow_any_instance_of(City).to receive(:condition_state).and_return(condition)
126
+ end
127
+
128
+ include_examples 'an unless filter'
129
+ end
130
+
131
+ context 'when filter is literal' do
132
+ let(:filter) { condition }
133
+
134
+ include_examples 'an unless filter'
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Index::Observe do
4
+ describe '.update_index' do
5
+ before do
6
+ stub_index(:dummies)
7
+ end
8
+
9
+ let(:backreferenced) { Array.new(3) { |i| double(id: i) } }
10
+
11
+ specify do
12
+ expect { DummiesIndex.update_index(backreferenced) }
13
+ .to raise_error Chewy::UndefinedUpdateStrategy
14
+ end
15
+ specify do
16
+ expect { DummiesIndex.update_index([]) }
17
+ .not_to update_index('dummies')
18
+ end
19
+ specify do
20
+ expect { DummiesIndex.update_index(nil) }
21
+ .not_to update_index('dummies')
22
+ end
23
+ end
24
+
25
+ context 'integration', :orm do
26
+ let(:update_condition) { true }
27
+
28
+ before do
29
+ stub_model(:city) do
30
+ update_index(-> { 'cities' }, :self)
31
+ update_index('countries') { changes['country_id'] || previous_changes['country_id'] || country }
32
+ end
33
+
34
+ stub_model(:country) do
35
+ update_index('cities', if: -> { update_condition }) { cities }
36
+ update_index(-> { 'countries' }, :self)
37
+ attr_accessor :update_condition
38
+ end
39
+
40
+ City.belongs_to :country
41
+ Country.has_many :cities
42
+
43
+ stub_index(:cities) do
44
+ index_scope City
45
+ end
46
+
47
+ stub_index(:countries) do
48
+ index_scope Country
49
+ end
50
+ end
51
+
52
+ context do
53
+ let!(:country1) { Chewy.strategy(:atomic) { Country.create!(id: 1, update_condition: update_condition) } }
54
+ let!(:country2) { Chewy.strategy(:atomic) { Country.create!(id: 2, update_condition: update_condition) } }
55
+ let!(:city) { Chewy.strategy(:atomic) { City.create!(id: 1, country: country1) } }
56
+
57
+ specify { expect { city.save! }.to update_index('cities').and_reindex(city).only }
58
+ specify { expect { city.save! }.to update_index('countries').and_reindex(country1).only }
59
+
60
+ specify { expect { city.destroy }.to update_index('cities') }
61
+ specify { expect { city.destroy }.to update_index('countries').and_reindex(country1).only }
62
+
63
+ specify { expect { city.update!(country: nil) }.to update_index('cities').and_reindex(city).only }
64
+ specify { expect { city.update!(country: nil) }.to update_index('countries').and_reindex(country1).only }
65
+
66
+ specify { expect { city.update!(country: country2) }.to update_index('cities').and_reindex(city).only }
67
+ specify do
68
+ expect { city.update!(country: country2) }
69
+ .to update_index('countries').and_reindex(country1, country2).only
70
+ end
71
+ end
72
+
73
+ context do
74
+ let!(:country) do
75
+ Chewy.strategy(:atomic) do
76
+ cities = Array.new(2) { |i| City.create!(id: i) }
77
+ Country.create!(id: 1, cities: cities, update_condition: update_condition)
78
+ end
79
+ end
80
+
81
+ specify { expect { country.save! }.to update_index('cities').and_reindex(country.cities).only }
82
+ specify { expect { country.save! }.to update_index('countries').and_reindex(country).only }
83
+
84
+ specify { expect { country.destroy }.to update_index('cities').and_reindex(country.cities).only }
85
+ specify { expect { country.destroy }.to update_index('countries') }
86
+
87
+ context 'conditional update' do
88
+ let(:update_condition) { false }
89
+ specify { expect { country.save! }.not_to update_index('cities') }
90
+ specify { expect { country.destroy }.not_to update_index('cities') }
91
+ end
92
+ end
93
+ end
94
+
95
+ context 'transactions', :active_record do
96
+ context do
97
+ before { stub_model(:city) { update_index 'cities', :self } }
98
+ before { stub_index(:cities) { index_scope City } }
99
+
100
+ specify do
101
+ Chewy.strategy(:urgent) do
102
+ ActiveRecord::Base.transaction do
103
+ expect { City.create! }.not_to update_index('cities')
104
+ end
105
+ end
106
+ end
107
+
108
+ specify do
109
+ city = Chewy.strategy(:bypass) { City.create! }
110
+
111
+ Chewy.strategy(:urgent) do
112
+ ActiveRecord::Base.transaction do
113
+ expect { city.destroy }.not_to update_index('cities')
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ context do
120
+ before { allow(Chewy).to receive_messages(use_after_commit_callbacks: false) }
121
+ before { stub_model(:city) { update_index 'cities', :self } }
122
+ before { stub_index(:cities) { index_scope City } }
123
+
124
+ specify do
125
+ Chewy.strategy(:urgent) do
126
+ ActiveRecord::Base.transaction do
127
+ expect { City.create! }.to update_index('cities')
128
+ end
129
+ end
130
+ end
131
+
132
+ specify do
133
+ city = Chewy.strategy(:bypass) { City.create! }
134
+
135
+ Chewy.strategy(:urgent) do
136
+ ActiveRecord::Base.transaction do
137
+ expect { city.destroy }.to update_index('cities')
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -118,7 +118,9 @@ describe Chewy::Index::Settings do
118
118
  end
119
119
 
120
120
  context do
121
- before { allow(Chewy).to receive_messages(configuration: {index: {number_of_shards: 7, number_of_replicas: 2}}) }
121
+ before do
122
+ allow(Chewy).to receive_messages(configuration: {index: {number_of_shards: 7, number_of_replicas: 2}})
123
+ end
122
124
 
123
125
  specify do
124
126
  expect(described_class.new.to_hash)
@@ -5,44 +5,34 @@ describe Chewy::Index::Specification do
5
5
 
6
6
  let(:index1) do
7
7
  stub_index(:places) do
8
- define_type(:city) do
9
- field :founded_on, type: 'date'
10
- end
8
+ field :founded_on, type: 'date'
11
9
  end
12
10
  end
13
11
 
14
12
  let(:index2) do
15
13
  stub_index(:places) do
16
14
  settings analyzer: {}
17
- define_type(:city) do
18
- field :founded_on, type: 'date'
19
- end
15
+ field :founded_on, type: 'date'
20
16
  end
21
17
  end
22
18
 
23
19
  let(:index3) do
24
20
  stub_index(:places) do
25
- define_type(:city) do
26
- field :founded_on, type: 'date'
27
- field :population, type: 'integer'
28
- end
21
+ field :founded_on, type: 'date'
22
+ field :population, type: 'integer'
29
23
  end
30
24
  end
31
25
 
32
26
  let(:index4) do
33
27
  stub_index(:places) do
34
- define_type(:city) do
35
- field :population, type: 'integer'
36
- field :founded_on, type: 'date'
37
- end
28
+ field :population, type: 'integer'
29
+ field :founded_on, type: 'date'
38
30
  end
39
31
  end
40
32
 
41
33
  let(:index5) do
42
34
  stub_index('namespace/cities') do
43
- define_type(:city) do
44
- field :population, type: 'integer'
45
- end
35
+ field :population, type: 'integer'
46
36
  end
47
37
  end
48
38
 
@@ -56,12 +46,12 @@ describe Chewy::Index::Specification do
56
46
  specify do
57
47
  expect { specification1.lock! }.to change { Chewy::Stash::Specification.all.hits }.from([]).to([{
58
48
  '_index' => 'chewy_specifications',
59
- '_type' => 'specification',
49
+ '_type' => '_doc',
60
50
  '_id' => 'places',
61
51
  '_score' => 1.0,
62
52
  '_source' => {'specification' => Base64.encode64({
63
53
  'settings' => {'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
64
- 'mappings' => {'city' => {'properties' => {'founded_on' => {'type' => 'date'}}}}
54
+ 'mappings' => {'properties' => {'founded_on' => {'type' => 'date'}}}
65
55
  }.to_json)}
66
56
  }])
67
57
  end
@@ -72,21 +62,21 @@ describe Chewy::Index::Specification do
72
62
  specify do
73
63
  expect { specification5.lock! }.to change { Chewy::Stash::Specification.all.hits }.to([{
74
64
  '_index' => 'chewy_specifications',
75
- '_type' => 'specification',
65
+ '_type' => '_doc',
76
66
  '_id' => 'places',
77
67
  '_score' => 1.0,
78
68
  '_source' => {'specification' => Base64.encode64({
79
69
  'settings' => {'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
80
- 'mappings' => {'city' => {'properties' => {'founded_on' => {'type' => 'date'}}}}
70
+ 'mappings' => {'properties' => {'founded_on' => {'type' => 'date'}}}
81
71
  }.to_json)}
82
72
  }, {
83
73
  '_index' => 'chewy_specifications',
84
- '_type' => 'specification',
74
+ '_type' => '_doc',
85
75
  '_id' => 'namespace/cities',
86
76
  '_score' => 1.0,
87
77
  '_source' => {'specification' => Base64.encode64({
88
78
  'settings' => {'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
89
- 'mappings' => {'city' => {'properties' => {'population' => {'type' => 'integer'}}}}
79
+ 'mappings' => {'properties' => {'population' => {'type' => 'integer'}}}
90
80
  }.to_json)}
91
81
  }])
92
82
  end
@@ -97,14 +87,14 @@ describe Chewy::Index::Specification do
97
87
  specify do
98
88
  expect { specification1.lock! }.to change { specification1.locked }.from({}).to(
99
89
  'settings' => {'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
100
- 'mappings' => {'city' => {'properties' => {'founded_on' => {'type' => 'date'}}}}
90
+ 'mappings' => {'properties' => {'founded_on' => {'type' => 'date'}}}
101
91
  )
102
92
  end
103
93
 
104
94
  specify do
105
95
  expect { specification5.lock! }.to change { specification5.locked }.from({}).to(
106
96
  'settings' => {'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
107
- 'mappings' => {'city' => {'properties' => {'population' => {'type' => 'integer'}}}}
97
+ 'mappings' => {'properties' => {'population' => {'type' => 'integer'}}}
108
98
  )
109
99
  end
110
100
 
@@ -114,20 +104,20 @@ describe Chewy::Index::Specification do
114
104
  specify do
115
105
  expect { specification2.lock! }.to change { specification2.locked }.from(
116
106
  'settings' => {'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
117
- 'mappings' => {'city' => {'properties' => {'founded_on' => {'type' => 'date'}}}}
107
+ 'mappings' => {'properties' => {'founded_on' => {'type' => 'date'}}}
118
108
  ).to(
119
109
  'settings' => {'analyzer' => {}, 'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
120
- 'mappings' => {'city' => {'properties' => {'founded_on' => {'type' => 'date'}}}}
110
+ 'mappings' => {'properties' => {'founded_on' => {'type' => 'date'}}}
121
111
  )
122
112
  end
123
113
 
124
114
  specify do
125
115
  expect { specification3.lock! }.to change { specification3.locked }.from(
126
116
  'settings' => {'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
127
- 'mappings' => {'city' => {'properties' => {'founded_on' => {'type' => 'date'}}}}
117
+ 'mappings' => {'properties' => {'founded_on' => {'type' => 'date'}}}
128
118
  ).to(
129
119
  'settings' => {'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}},
130
- 'mappings' => {'city' => {'properties' => {'founded_on' => {'type' => 'date'}, 'population' => {'type' => 'integer'}}}}
120
+ 'mappings' => {'properties' => {'founded_on' => {'type' => 'date'}, 'population' => {'type' => 'integer'}}}
131
121
  )
132
122
  end
133
123
  end
@@ -136,7 +126,7 @@ describe Chewy::Index::Specification do
136
126
  describe '#current' do
137
127
  specify do
138
128
  expect(specification2.current).to eq(
139
- 'mappings' => {'city' => {'properties' => {'founded_on' => {'type' => 'date'}}}},
129
+ 'mappings' => {'properties' => {'founded_on' => {'type' => 'date'}}},
140
130
  'settings' => {'analyzer' => {}, 'index' => {'number_of_shards' => 1, 'number_of_replicas' => 0}}
141
131
  )
142
132
  end