elasticord 1.0.0 → 1.0.1
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/Gemfile.lock +3 -1
- data/dash_overlord.gemspec +2 -2
- data/elasticord.gemspec +1 -1
- data/lib/dash_overlord/models/v1/dynamo_db/base.rb +22 -11
- data/lib/dash_overlord/models/v1/dynamo_db/migration.rb +13 -3
- data/lib/dash_overlord/models/v1/dynamo_db/paginated_result.rb +16 -0
- data/lib/dash_overlord/models/v1/dynamo_db/scan.rb +114 -0
- data/lib/dash_overlord/use_cases/v1/dummy_data/create/charts/base.rb +3 -2
- data/lib/dash_overlord/use_cases/v1/dummy_data/create/charts/build.rb +1 -1
- data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/create/batch.rb +3 -2
- data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/apply_filters.rb +21 -0
- data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/apply_pagination.rb +62 -0
- data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/base.rb +39 -0
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/apply_filters.rb +2 -2
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/apply_pagination.rb +4 -11
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/base.rb +2 -6
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/build_meta_data.rb +26 -0
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/execute_query.rb +21 -0
- data/lib/dash_overlord/use_cases/v1/videos/index/dynamodb/search_and_paginate_videos.rb +7 -2
- data/lib/dash_overlord/use_cases/v1/videos/index/elastic_search/search_and_paginate_videos.rb +2 -80
- data/lib/elasticord/base.rb +10 -11
- data/lib/elasticord/entities/array_with_meta_data.rb +37 -0
- data/lib/elasticord/orm/search_builder.rb +101 -0
- data/lib/elasticord/version.rb +1 -1
- data/lib/tasks/create_dummy_data.rake +1 -0
- data/spec/dash_overlord/use_cases/v1/videos/index/dynamo_db_spec.rb +71 -9
- data/spec/elasticord/base_spec.rb +42 -155
- data/spec/elasticord/orm/search_builder_spec.rb +269 -0
- metadata +14 -3
@@ -2,69 +2,68 @@ require 'spec_helper'
|
|
2
2
|
require 'elasticsearch'
|
3
3
|
|
4
4
|
describe Elasticord::Base, elasticsearch: true do
|
5
|
+
ElasticordChildClass1 = Class.new(described_class)
|
6
|
+
|
5
7
|
def elastic_search_client
|
6
8
|
@elastic_search_client ||= Elasticsearch::Client.new
|
7
9
|
end
|
8
10
|
|
11
|
+
def get_one_elastic_search_record(id)
|
12
|
+
result = elastic_search_client.get \
|
13
|
+
id: id,
|
14
|
+
type: ElasticordChildClass1.type,
|
15
|
+
index: ElasticordChildClass1.index,
|
16
|
+
ignore: 404
|
17
|
+
|
18
|
+
result
|
19
|
+
end
|
20
|
+
|
9
21
|
describe '.index' do
|
10
22
|
it 'described_class should return the current env' do
|
11
23
|
expect(described_class.index).to eq ENV['ENV']
|
12
24
|
end
|
13
25
|
|
14
26
|
context 'given a child class' do
|
15
|
-
|
16
|
-
|
17
|
-
it 'ChildClass1 should return the same current env' do
|
18
|
-
expect(ChildClass1.index).to eq ENV['ENV']
|
27
|
+
it 'ElasticordChildClass1 should return the same current env' do
|
28
|
+
expect(ElasticordChildClass1.index).to eq ENV['ENV']
|
19
29
|
end
|
20
30
|
|
21
31
|
context 'given that the child class sets a new index' do
|
22
|
-
before {
|
32
|
+
before { ElasticordChildClass1.index = 'child_class_new_index' }
|
23
33
|
|
24
34
|
it 'described_class should return the current env' do
|
25
35
|
expect(described_class.index).to eq ENV['ENV']
|
26
36
|
end
|
27
37
|
|
28
|
-
it '
|
29
|
-
expect(
|
38
|
+
it 'ElasticordChildClass1 should return "child_class_new_index"' do
|
39
|
+
expect(ElasticordChildClass1.index).to eq 'child_class_new_index'
|
30
40
|
end
|
31
41
|
end
|
32
42
|
end
|
33
43
|
end
|
34
44
|
|
35
45
|
describe '.type' do
|
36
|
-
it 'described_class should return _all' do
|
46
|
+
it 'described_class should return "_all"' do
|
37
47
|
expect(described_class.type).to eq '_all'
|
38
48
|
end
|
39
49
|
|
40
50
|
context 'given a child class' do
|
41
|
-
|
42
|
-
|
43
|
-
it 'ChildClass2 should return child_class2' do
|
44
|
-
expect(ChildClass2.type).to eq 'child_class2'
|
51
|
+
it 'ElasticordChildClass1 should return "elasticord_child_class1"' do
|
52
|
+
expect(ElasticordChildClass1.type).to eq 'elasticord_child_class1'
|
45
53
|
end
|
46
54
|
end
|
47
55
|
end
|
48
56
|
|
49
57
|
describe '.create' do
|
50
|
-
|
51
|
-
|
52
|
-
def get_one(id)
|
53
|
-
result = elastic_search_client.get \
|
54
|
-
index: ChildClass3.index, type: ChildClass3.type, ignore: 404, id: id
|
55
|
-
|
56
|
-
result
|
57
|
-
end
|
58
|
-
|
59
|
-
context 'Given an id' do
|
58
|
+
context 'given an ID' do
|
60
59
|
let(:id) { '123' }
|
61
60
|
|
62
61
|
before do
|
63
|
-
@child_class =
|
62
|
+
@child_class = ElasticordChildClass1.create id: id, title: 'child class'
|
64
63
|
end
|
65
64
|
|
66
65
|
it 'ElasticSearch should contain a record with that specific id' do
|
67
|
-
result =
|
66
|
+
result = get_one_elastic_search_record id
|
68
67
|
|
69
68
|
expect(result['found']).to be true
|
70
69
|
end
|
@@ -73,18 +72,18 @@ describe Elasticord::Base, elasticsearch: true do
|
|
73
72
|
expect(@child_class.id).to eq id
|
74
73
|
end
|
75
74
|
|
76
|
-
it '@child_class should be an instance of
|
77
|
-
expect(@child_class).to be_an_instance_of
|
75
|
+
it '@child_class should be an instance of ElasticordChildClass1' do
|
76
|
+
expect(@child_class).to be_an_instance_of ElasticordChildClass1
|
78
77
|
end
|
79
78
|
end
|
80
79
|
|
81
|
-
context '
|
80
|
+
context 'given no ID' do
|
82
81
|
before do
|
83
|
-
@child_class =
|
82
|
+
@child_class = ElasticordChildClass1.create title: 'child class'
|
84
83
|
end
|
85
84
|
|
86
|
-
it 'ElasticSearch should contain a record with that specific id' do
|
87
|
-
result =
|
85
|
+
it 'ElasticSearch DB should contain a record with that specific id' do
|
86
|
+
result = get_one_elastic_search_record @child_class.id
|
88
87
|
|
89
88
|
expect(result['found']).to be true
|
90
89
|
end
|
@@ -92,149 +91,37 @@ describe Elasticord::Base, elasticsearch: true do
|
|
92
91
|
end
|
93
92
|
|
94
93
|
describe '.search' do
|
95
|
-
|
96
|
-
|
97
|
-
context 'Given that no record has been created' do
|
98
|
-
before do
|
99
|
-
ChildClass4.delete_all
|
100
|
-
ChildClass4.refresh_index
|
101
|
-
|
102
|
-
@search_result = ChildClass4.search({})
|
103
|
-
end
|
94
|
+
it 'should pass all params to a SearchBuilder instance' do
|
95
|
+
attributes = { query: { match: { brand: 'oficial' } } }
|
104
96
|
|
105
|
-
|
106
|
-
|
107
|
-
data: [],
|
108
|
-
total_results: 0
|
109
|
-
})
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
context 'Given that 5 recrod have been created' do
|
114
|
-
before do
|
115
|
-
ChildClass4.delete_all
|
116
|
-
5.times { ChildClass4.create(title: 'child class') }
|
117
|
-
ChildClass4.refresh_index
|
118
|
-
|
119
|
-
@search_result = ChildClass4.search({})
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'should return a hash with total_results: 5' do
|
123
|
-
expect(@search_result[:total_results]).to be 5
|
124
|
-
end
|
97
|
+
expect_any_instance_of(Elasticord::ORM::SearchBuilder).to \
|
98
|
+
receive(:load).with(attributes)
|
125
99
|
|
126
|
-
|
127
|
-
expect(@search_result[:data].length).to be 5
|
128
|
-
|
129
|
-
@search_result[:data].each do |child_class|
|
130
|
-
expect(child_class).to be_an_instance_of ChildClass4
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
context 'Given that 30 records have been created' do
|
136
|
-
before do
|
137
|
-
ChildClass4.delete_all
|
138
|
-
|
139
|
-
24.times do
|
140
|
-
ChildClass4.create \
|
141
|
-
title: 'child class', brand: 'oficial', locked: false
|
142
|
-
end
|
143
|
-
|
144
|
-
ChildClass4.create(title: 'class', brand: 'oficial', locked: true)
|
145
|
-
|
146
|
-
5.times do
|
147
|
-
ChildClass4.create(title: 'child', brand: 'unoficial', locked: false)
|
148
|
-
end
|
149
|
-
|
150
|
-
ChildClass4.refresh_index
|
151
|
-
end
|
152
|
-
|
153
|
-
context 'when no pagination params are passed' do
|
154
|
-
before do
|
155
|
-
@search_result = ChildClass4.search({})
|
156
|
-
end
|
157
|
-
|
158
|
-
it 'should return a hash with total_results: 30' do
|
159
|
-
expect(@search_result[:total_results]).to be 30
|
160
|
-
end
|
161
|
-
|
162
|
-
it 'should return a hash with 10 instances of the class' do
|
163
|
-
expect(@search_result[:data].length).to be 10
|
164
|
-
|
165
|
-
@search_result[:data].each do |child_class|
|
166
|
-
expect(child_class).to be_an_instance_of ChildClass4
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
context 'when single query params are passed' do
|
172
|
-
before do
|
173
|
-
@search_result = ChildClass4.search \
|
174
|
-
query: {
|
175
|
-
match: { brand: 'oficial' }
|
176
|
-
}
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'should return a hash with total_results: 25' do
|
180
|
-
expect(@search_result[:total_results]).to be 25
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'should return a hash with 10 elements' do
|
184
|
-
expect(@search_result[:data].length).to be 10
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
context 'when multi query params are passed' do
|
189
|
-
before do
|
190
|
-
@search_result = ChildClass4.search \
|
191
|
-
query: {
|
192
|
-
bool: {
|
193
|
-
must: [
|
194
|
-
{ match: { title: 'child class' } }
|
195
|
-
],
|
196
|
-
filter: [
|
197
|
-
{ term: { brand: 'oficial' } },
|
198
|
-
{ term: { locked: false } }
|
199
|
-
]
|
200
|
-
}
|
201
|
-
}
|
202
|
-
end
|
203
|
-
|
204
|
-
it 'should return a hash with total_results: 24' do
|
205
|
-
expect(@search_result[:total_results]).to be 24
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'should return a hash with 10 elements' do
|
209
|
-
expect(@search_result[:data].length).to be 10
|
210
|
-
end
|
211
|
-
end
|
100
|
+
ElasticordChildClass1.search(attributes)
|
212
101
|
end
|
213
102
|
end
|
214
103
|
|
215
104
|
describe '.get' do
|
216
|
-
|
217
|
-
|
218
|
-
context 'When the record does not exist' do
|
105
|
+
context 'when the record does not exist' do
|
219
106
|
it 'should return false' do
|
220
|
-
result =
|
107
|
+
result = ElasticordChildClass1.get '-1'
|
221
108
|
|
222
109
|
expect(result).to be false
|
223
110
|
end
|
224
111
|
end
|
225
112
|
|
226
|
-
context '
|
113
|
+
context 'when the record exists' do
|
227
114
|
before do
|
228
|
-
@child_class =
|
115
|
+
@child_class = ElasticordChildClass1.create title: 'child class'
|
229
116
|
|
230
|
-
@result =
|
117
|
+
@result = ElasticordChildClass1.get @child_class.id
|
231
118
|
end
|
232
119
|
|
233
|
-
it 'should return an instance of
|
234
|
-
expect(@result).to be_an_instance_of
|
120
|
+
it 'should return an instance of ElasticordChildClass1' do
|
121
|
+
expect(@result).to be_an_instance_of ElasticordChildClass1
|
235
122
|
end
|
236
123
|
|
237
|
-
it 'should return the same
|
124
|
+
it 'should return the same ID it requested' do
|
238
125
|
expect(@result.id).to be @child_class.id
|
239
126
|
end
|
240
127
|
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'elasticsearch'
|
3
|
+
|
4
|
+
describe Elasticord::ORM::SearchBuilder, elasticsearch: true do
|
5
|
+
ElasticordChildClass2 = Class.new(Elasticord::Base)
|
6
|
+
|
7
|
+
def new_search_builder
|
8
|
+
described_class.new \
|
9
|
+
ElasticordChildClass2,
|
10
|
+
ElasticordChildClass2.index,
|
11
|
+
ElasticordChildClass2.type
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#current_page' do
|
15
|
+
it 'should have a default value set' do
|
16
|
+
expect(new_search_builder.current_page).to \
|
17
|
+
be described_class::PAGE_DEFAULT
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#per_page' do
|
22
|
+
it 'should have a default value set' do
|
23
|
+
expect(new_search_builder.per_page).to \
|
24
|
+
be described_class::PER_PAGE_DEFAULT
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#body_params' do
|
29
|
+
it 'should have pagination params set' do
|
30
|
+
expect(new_search_builder.body_params).to match a_hash_including({
|
31
|
+
size: described_class::PER_PAGE_DEFAULT,
|
32
|
+
from: 0
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when setting #page with 2' do
|
37
|
+
before do
|
38
|
+
@search_builder = new_search_builder
|
39
|
+
@search_builder.page(2)
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when setting #per with 3' do
|
43
|
+
before do
|
44
|
+
@search_builder.per(3)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should have pagination params set' do
|
48
|
+
expect(@search_builder.body_params).to match a_hash_including({
|
49
|
+
size: 3,
|
50
|
+
from: 3
|
51
|
+
})
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#result' do
|
58
|
+
it 'should return a SearchBuilder instance' do
|
59
|
+
expect(new_search_builder.result(distinct: true)).to \
|
60
|
+
be_an_instance_of described_class
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#page' do
|
65
|
+
def search_builder
|
66
|
+
@search_builder ||= new_search_builder
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'sending 3 as an argument' do
|
70
|
+
before do
|
71
|
+
@result = search_builder.page(3)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should return a SearchBuilder instance' do
|
75
|
+
expect(@result).to be_an_instance_of described_class
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should set the #body_params used in #load' do
|
79
|
+
expect(@result.body_params[:from]).to be 20
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should set the #current_page to 3' do
|
83
|
+
expect(@result.current_page).to be 3
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#per' do
|
89
|
+
def search_builder
|
90
|
+
@search_builder ||= new_search_builder
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'sending 15 as an argument' do
|
94
|
+
before do
|
95
|
+
@result = search_builder.per(15)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should return a SearchBuilder instance' do
|
99
|
+
expect(@result).to be_an_instance_of described_class
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should set the #body_params used in #load' do
|
103
|
+
expect(@result.body_params[:size]).to be 15
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should set the #per_page to 15' do
|
107
|
+
expect(@result.per_page).to be 15
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'given that no record has been created' do
|
113
|
+
before do
|
114
|
+
ElasticordChildClass2.delete_all
|
115
|
+
ElasticordChildClass2.refresh_index
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#load' do
|
119
|
+
before do
|
120
|
+
@search_result = new_search_builder.load
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should return a pagination object with empty resources' do
|
124
|
+
expect(@search_result).to be_empty
|
125
|
+
expect(@search_result.total_results).to be 0
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'given that 5 records have been created' do
|
131
|
+
before do
|
132
|
+
ElasticordChildClass2.delete_all
|
133
|
+
5.times { ElasticordChildClass2.create(title: 'child class') }
|
134
|
+
ElasticordChildClass2.refresh_index
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '#load' do
|
138
|
+
before do
|
139
|
+
@search_result = new_search_builder.load
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should find 5 total_results' do
|
143
|
+
expect(@search_result.total_results).to be 5
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should return a pagination object with 5 instances of the class' do
|
147
|
+
expect(@search_result.length).to be 5
|
148
|
+
|
149
|
+
@search_result.each do |child_class|
|
150
|
+
expect(child_class).to be_an_instance_of ElasticordChildClass2
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'given that 30 records have been created' do
|
157
|
+
before do
|
158
|
+
ElasticordChildClass2.delete_all
|
159
|
+
|
160
|
+
24.times do
|
161
|
+
ElasticordChildClass2.create \
|
162
|
+
title: 'child class', brand: 'oficial', locked: false
|
163
|
+
end
|
164
|
+
|
165
|
+
ElasticordChildClass2.create(title: 'class', brand: 'oficial', locked: true)
|
166
|
+
|
167
|
+
5.times do
|
168
|
+
ElasticordChildClass2.create(title: 'child', brand: 'unoficial', locked: false)
|
169
|
+
end
|
170
|
+
|
171
|
+
ElasticordChildClass2.refresh_index
|
172
|
+
end
|
173
|
+
|
174
|
+
describe '#load' do
|
175
|
+
context 'when no pagination params are passed' do
|
176
|
+
before do
|
177
|
+
@search_result = new_search_builder.load({})
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should find 30 total_results' do
|
181
|
+
expect(@search_result.total_results).to be 30
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should return a pagination object with 10 instances of the class' do
|
185
|
+
expect(@search_result.length).to be 10
|
186
|
+
|
187
|
+
@search_result.each do |child_class|
|
188
|
+
expect(child_class).to be_an_instance_of ElasticordChildClass2
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when #page(2) was called' do
|
194
|
+
before do
|
195
|
+
@search_builder = new_search_builder.page(2)
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'when #per(15) was called' do
|
199
|
+
before do
|
200
|
+
@search_builder = @search_builder.per(15)
|
201
|
+
end
|
202
|
+
|
203
|
+
context 'when #ransack with multiple query params was called' do
|
204
|
+
before do
|
205
|
+
@search_builder = @search_builder.ransack({
|
206
|
+
brand_eq: 'oficial',
|
207
|
+
locked_eq: false
|
208
|
+
})
|
209
|
+
|
210
|
+
@search_builder = @search_builder.result(distinct: true)
|
211
|
+
|
212
|
+
@search_result = @search_builder.load
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'should return a pagination with the current data' do
|
216
|
+
expect(@search_result.per_page).to be 15
|
217
|
+
expect(@search_result.total_pages).to be 2
|
218
|
+
expect(@search_result.current_page).to be 2
|
219
|
+
expect(@search_result.total_results).to be 24
|
220
|
+
expect(@search_result.length).to be 9
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'when single query params are passed' do
|
227
|
+
before do
|
228
|
+
@search_result = new_search_builder.load \
|
229
|
+
query: {
|
230
|
+
match: { brand: 'oficial' }
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should find 25 total_results' do
|
235
|
+
expect(@search_result.total_results).to be 25
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should return a pagination object with 10 resources' do
|
239
|
+
expect(@search_result.length).to be 10
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'when multi query params are passed' do
|
244
|
+
before do
|
245
|
+
@search_result = new_search_builder.load \
|
246
|
+
query: {
|
247
|
+
bool: {
|
248
|
+
must: [
|
249
|
+
{ match: { title: 'child class' } }
|
250
|
+
],
|
251
|
+
filter: [
|
252
|
+
{ term: { brand: 'oficial' } },
|
253
|
+
{ term: { locked: false } }
|
254
|
+
]
|
255
|
+
}
|
256
|
+
}
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'should find 24 total_results' do
|
260
|
+
expect(@search_result.total_results).to be 24
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'should return a pagination object with 10 resources' do
|
264
|
+
expect(@search_result.length).to be 10
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|