1
+ require 'spec_helper'
2
+
3
+ describe Elasticsearch ::Model ::Adapter ::ActiveRecord do
4
+
5
+ before ( :all ) do
6
+ class DummyClassForActiveRecord ; end
7
+ end
8
+
9
+ after ( :all ) do
10
+ Elasticsearch ::Model ::Adapter ::Adapter . adapters . delete ( DummyClassForActiveRecord )
11
+ Object . send ( :remove_const , :DummyClassForActiveRecord ) if defined? ( DummyClassForActiveRecord )
12
+ end
13
+
14
+ let ( :model ) do
15
+ DummyClassForActiveRecord . new . tap do |m |
16
+ allow ( m ) . to receive ( :response ) . and_return ( double ( 'response' , response : response ) )
17
+ allow ( m ) . to receive ( :ids ) . and_return ( ids )
18
+ end
19
+ end
20
+
21
+ let ( :response ) do
22
+ { 'hits' => { 'hits' => [ { '_id' => 2 } , { '_id' => 1 } ] } }
23
+ end
24
+
25
+ let ( :ids ) do
26
+ [ 2 , 1 ]
27
+ end
28
+
29
+ let ( :record_1 ) do
30
+ double ( 'record' ) . tap do |rec |
31
+ allow ( rec ) . to receive ( :id ) . and_return ( 1 )
32
+ end
33
+ end
34
+
35
+ let ( :record_2 ) do
36
+ double ( 'record' ) . tap do |rec |
37
+ allow ( rec ) . to receive ( :id ) . and_return ( 2 )
38
+ end
39
+ end
40
+
41
+ let ( :records ) do
42
+ [ record_1 , record_2 ] . tap do |r |
43
+ allow ( r ) . to receive ( :load ) . and_return ( true )
44
+ allow ( r ) . to receive ( :exec_queries ) . and_return ( true )
45
+ end
46
+ end
47
+
48
+ describe 'adapter registration' do
49
+
50
+ before ( :all ) do
51
+ DummyClassForActiveRecord . __send__ :include , Elasticsearch ::Model ::Adapter ::ActiveRecord ::Records
52
+ end
53
+
54
+ it 'can register an adapater' do
55
+ expect ( Elasticsearch ::Model ::Adapter . adapters [ Elasticsearch ::Model ::Adapter ::ActiveRecord ] ) . not_to be_nil
56
+ expect ( Elasticsearch ::Model ::Adapter . adapters [ Elasticsearch ::Model ::Adapter ::ActiveRecord ] . call ( DummyClassForActiveRecord ) ) . to be ( false )
57
+ end
58
+ end
59
+
60
+ describe '#records' do
61
+
62
+ before ( :all ) do
63
+ DummyClassForActiveRecord . __send__ :include , Elasticsearch ::Model ::Adapter ::ActiveRecord ::Records
64
+ end
65
+
66
+ let ( :instance ) do
67
+ model . tap do |inst |
68
+ allow ( inst ) . to receive ( :klass ) . and_return ( double ( 'class' , primary_key : :some_key , where : records ) ) . at_least ( :once )
69
+ end
70
+ end
71
+
72
+ it 'returns the list of records' do
73
+ expect ( instance . records ) . to eq ( records )
74
+ end
75
+
76
+ it 'loads the records' do
77
+ expect ( instance . load ) . to eq ( true )
78
+ end
79
+
80
+ context 'when :includes is specified' do
81
+
82
+ before do
83
+ expect ( records ) . to receive ( :includes ) . with ( [ :submodel ] ) . once . and_return ( records )
84
+ instance . options [ :includes ] = [ :submodel ]
85
+ end
86
+
87
+ it 'incorporates the includes option in the query' do
88
+ expect ( instance . records ) . to eq ( records )
89
+ end
90
+ end
91
+
92
+ context 'when an order is not defined for the ActiveRecord query' do
93
+
94
+ context 'when the records have a different order than the hits' do
95
+
96
+ before do
97
+ records . instance_variable_set ( :@records , records )
98
+ end
99
+
100
+ it 'reorders the records based on hits order' do
101
+ expect ( records . collect ( &:id ) ) . to eq ( [ 1 , 2 ] )
102
+ expect ( instance . records . to_a . collect ( &:id ) ) . to eq ( [ 2 , 1 ] )
103
+ end
104
+ end
105
+ end
106
+
107
+ context 'when an order is defined for the ActiveRecord query' do
108
+
109
+ context 'when the records have a different order than the hits' do
110
+
111
+ before do
112
+ records . instance_variable_set ( :@records , records )
113
+ expect ( instance . records ) . to receive ( :order ) . and_return ( records )
114
+ end
115
+
116
+ it 'reorders the records based on hits order' do
117
+ expect ( records . collect ( &:id ) ) . to eq ( [ 1 , 2 ] )
118
+ expect ( instance . records . to_a . collect ( &:id ) ) . to eq ( [ 2 , 1 ] )
119
+ expect ( instance . order ( :foo ) . to_a . collect ( &:id ) ) . to eq ( [ 1 , 2 ] )
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ describe 'callbacks registration' do
126
+
127
+ before do
128
+ expect ( DummyClassForActiveRecord ) . to receive ( :after_commit ) . exactly ( 3 ) . times
129
+ end
130
+
131
+ it 'should register the model class for callbacks' do
132
+ Elasticsearch ::Model ::Adapter ::ActiveRecord ::Callbacks . included ( DummyClassForActiveRecord )
133
+ end
134
+ end
135
+
136
+ describe 'importing' do
137
+
138
+ before do
139
+ DummyClassForActiveRecord . __send__ :extend , Elasticsearch ::Model ::Adapter ::ActiveRecord ::Importing
140
+ end
141
+
142
+ context 'when an invalid scope is specified' do
143
+
144
+ it 'raises a NoMethodError' do
145
+ expect {
146
+ DummyClassForActiveRecord . __find_in_batches ( scope : :not_found_method )
147
+ } . to raise_exception ( NoMethodError )
148
+ end
149
+ end
150
+
151
+ context 'when a valid scope is specified' do
152
+
153
+ before do
154
+ expect ( DummyClassForActiveRecord ) . to receive ( :find_in_batches ) . once . and_return ( [ ] )
155
+ expect ( DummyClassForActiveRecord ) . to receive ( :published ) . once . and_return ( DummyClassForActiveRecord )
156
+ end
157
+
158
+ it 'uses the scope' do
159
+ expect ( DummyClassForActiveRecord . __find_in_batches ( scope : :published ) ) . to eq ( [ ] )
160
+ end
161
+ end
162
+
163
+ context 'allow query criteria to be specified' do
164
+
165
+ before do
166
+ expect ( DummyClassForActiveRecord ) . to receive ( :find_in_batches ) . once . and_return ( [ ] )
167
+ expect ( DummyClassForActiveRecord ) . to receive ( :where ) . with ( color : 'red' ) . once . and_return ( DummyClassForActiveRecord )
168
+ end
169
+
170
+ it 'uses the scope' do
171
+ expect ( DummyClassForActiveRecord . __find_in_batches ( query : -> { where ( color : 'red' ) } ) ) . to eq ( [ ] )
172
+ end
173
+ end
174
+
175
+ context 'when preprocessing batches' do
176
+
177
+ context 'if the query returns results' do
178
+
179
+ before do
180
+ class << DummyClassForActiveRecord
181
+ def find_in_batches ( options = { } , &block )
182
+ yield [ :a , :b ]
183
+ end
184
+
185
+ def update_batch ( batch )
186
+ batch . collect { |b | b . to_s + '!' }
187
+ end
188
+ end
189
+ end
190
+
191
+ it 'applies the preprocessing method' do
192
+ DummyClassForActiveRecord . __find_in_batches ( preprocess : :update_batch ) do |batch |
193
+ expect ( batch ) . to match ( [ 'a!' , 'b!' ] )
194
+ end
195
+ end
196
+ end
197
+
198
+ context 'if the query does not return results' do
199
+
200
+ before do
201
+ class << DummyClassForActiveRecord
202
+ def find_in_batches ( options = { } , &block )
203
+ yield [ :a , :b ]
204
+ end
205
+
206
+ def update_batch ( batch )
207
+ [ ]
208
+ end
209
+ end
210
+ end
211
+
212
+ it 'applies the preprocessing method' do
213
+ DummyClassForActiveRecord . __find_in_batches ( preprocess : :update_batch ) do |batch |
214
+ expect ( batch ) . to match ( [ ] )
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ context 'when transforming models' do
221
+
222
+ let ( :instance ) do
223
+ model . tap do |inst |
224
+ allow ( inst ) . to receive ( :id ) . and_return ( 1 )
225
+ allow ( inst ) . to receive ( :__elasticsearch__ ) . and_return ( double ( 'object' , id : 1 , as_indexed_json : { } ) )
226
+ end
227
+ end
228
+
229
+ it 'returns an proc' do
230
+ expect ( DummyClassForActiveRecord . __transform . respond_to? ( :call ) ) . to be ( true )
231
+ end
232
+
233
+ it 'provides a default transformation' do
234
+ expect ( DummyClassForActiveRecord . __transform . call ( instance ) ) . to eq ( index : { _id : 1 , data : { } } )
235
+ end
236
+ end
237
+ end
238
+ end
0 commit comments