openstax_utilities 4.1.0 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/app/routines/openstax/utilities/limit_and_paginate_relation.rb +85 -0
- data/app/routines/openstax/utilities/order_relation.rb +105 -0
- data/app/routines/openstax/utilities/search_and_organize_relation.rb +130 -0
- data/app/routines/openstax/utilities/search_relation.rb +94 -0
- data/lib/openstax/utilities/access_policy.rb +4 -3
- data/lib/openstax/utilities/assets.rb +29 -0
- data/lib/openstax/utilities/assets/manifest.rb +62 -0
- data/lib/openstax/utilities/version.rb +1 -1
- data/lib/openstax_utilities.rb +5 -5
- data/spec/cassettes/OpenStax_Utilities_Assets/loading_remote_manifest/uses_remote_json.yml +353 -0
- data/spec/dummy/app/access_policies/dummier_access_policy.rb +10 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/config/application.rb +6 -11
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/initializers/search_users.rb +26 -0
- data/spec/dummy/config/secrets.yml +2 -5
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +32144 -0
- data/spec/dummy/tmp/cache/C09/760/6da7b2a29da9cb0f80ef102c7effb91fab3374db +0 -0
- data/spec/factories/user.rb +1 -1
- data/spec/lib/openstax/utilities/access_policy_spec.rb +16 -15
- data/spec/lib/openstax/utilities/assets_spec.rb +40 -0
- data/spec/rails_helper.rb +1 -2
- data/spec/routines/openstax/utilities/limit_and_paginate_relation_spec.rb +72 -0
- data/spec/routines/openstax/utilities/order_relation_spec.rb +55 -0
- data/spec/routines/openstax/utilities/{abstract_keyword_search_routine_spec.rb → search_and_organize_relation_spec.rb} +54 -47
- data/spec/routines/openstax/utilities/search_relation_spec.rb +81 -0
- data/spec/vcr_helper.rb +18 -0
- metadata +123 -44
- data/app/handlers/openstax/utilities/keyword_search_handler.rb +0 -95
- data/app/routines/openstax/utilities/abstract_keyword_search_routine.rb +0 -158
- data/spec/dummy/app/routines/search_users.rb +0 -21
- data/spec/handlers/openstax/utilities/keyword_search_handler_spec.rb +0 -126
data/spec/factories/user.rb
CHANGED
@@ -5,7 +5,7 @@ module OpenStax
|
|
5
5
|
|
6
6
|
describe AccessPolicy do
|
7
7
|
|
8
|
-
let!(:user) {
|
8
|
+
let!(:user) { FactoryBot.create :user }
|
9
9
|
|
10
10
|
it 'responds to any _allowed? calls' do
|
11
11
|
AccessPolicy.register(User, DummyAccessPolicy)
|
@@ -24,30 +24,31 @@ module OpenStax
|
|
24
24
|
|
25
25
|
it 'delegates checks to policy classes based on resource class' do
|
26
26
|
dummy_object = double('Dummy')
|
27
|
-
dummy_policy = double('Dummy Policy', :action_allowed? => true)
|
28
27
|
|
29
28
|
AccessPolicy.register(User, DummyAccessPolicy)
|
30
|
-
AccessPolicy.register(dummy_object.class,
|
29
|
+
AccessPolicy.register(dummy_object.class, DummierAccessPolicy)
|
31
30
|
|
32
31
|
DummyAccessPolicy.last_action = nil
|
33
32
|
DummyAccessPolicy.last_requestor = nil
|
34
33
|
DummyAccessPolicy.last_resource = nil
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
expect{AccessPolicy.require_action_allowed!(:read, user, dummy_object)
|
40
|
-
}.not_to raise_error
|
35
|
+
DummierAccessPolicy.last_action = nil
|
36
|
+
DummierAccessPolicy.last_requestor = nil
|
37
|
+
DummierAccessPolicy.last_resource = nil
|
41
38
|
|
42
|
-
expect(
|
43
|
-
expect
|
44
|
-
|
39
|
+
expect(AccessPolicy.action_allowed?(:read, user, dummy_object)).to eq true
|
40
|
+
expect{
|
41
|
+
AccessPolicy.require_action_allowed!(:read, user, dummy_object)
|
42
|
+
}.not_to raise_error
|
45
43
|
|
46
|
-
expect(
|
47
|
-
|
44
|
+
expect(DummierAccessPolicy.last_action).to eq(:read)
|
45
|
+
expect(DummierAccessPolicy.last_requestor).to eq(user)
|
46
|
+
expect(DummierAccessPolicy.last_resource).to eq(dummy_object)
|
48
47
|
|
49
|
-
expect
|
50
|
-
|
48
|
+
expect(AccessPolicy.action_allowed?(:create, user, User.new)).to eq true
|
49
|
+
expect{
|
50
|
+
AccessPolicy.require_action_allowed!(:create, user, User.new)
|
51
|
+
}.not_to raise_error
|
51
52
|
|
52
53
|
expect(DummyAccessPolicy.last_action).to eq(:create)
|
53
54
|
expect(DummyAccessPolicy.last_requestor).to eq(user)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'vcr_helper'
|
3
|
+
|
4
|
+
RSpec.describe OpenStax::Utilities::Assets, vcr: VCR_OPTS do
|
5
|
+
before { RequestStore.store[:assets_manifest] = nil }
|
6
|
+
|
7
|
+
it 'defaults to name.js when manifest is missing' do
|
8
|
+
expect_any_instance_of(Faraday::Connection).to receive(:get).and_return(
|
9
|
+
OpenStruct.new success?: false
|
10
|
+
)
|
11
|
+
expect(described_class.tags_for(:foo)).to include "src='http://localhost:8000/dist/foo.js'"
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'reads asset url from manifest' do
|
15
|
+
expect_any_instance_of(Faraday::Connection).to receive(:get).and_return(
|
16
|
+
OpenStruct.new(
|
17
|
+
success?: true,
|
18
|
+
body: { entrypoints: { foo: { js: [ 'foo-732c56c32ff399b62.min.bar' ] } } }.to_json
|
19
|
+
)
|
20
|
+
)
|
21
|
+
expect(described_class.tags_for(:foo)).to include(
|
22
|
+
"src='http://localhost:8000/dist/foo-732c56c32ff399b62.min.bar'"
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'loading remote manifest' do
|
27
|
+
before do
|
28
|
+
@previous_assets_url = Rails.application.secrets.assets_url
|
29
|
+
Rails.application.secrets.assets_url = 'https://tutor-dev.openstax.org/assets'
|
30
|
+
end
|
31
|
+
after { Rails.application.secrets.assets_url = @previous_assets_url }
|
32
|
+
|
33
|
+
it 'uses remote json' do
|
34
|
+
expect(described_class.manifest).to be_kind_of described_class::Manifest
|
35
|
+
expect(described_class.tags_for(:tutor)).to(
|
36
|
+
eq "<script type='text/javascript' src='https://tutor-dev.openstax.org/assets/tutor-b920eb0be760a7c440bf.min.js' crossorigin='anonymous' async></script>"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/rails_helper.rb
CHANGED
@@ -3,9 +3,8 @@ ENV["RAILS_ENV"] ||= 'test'
|
|
3
3
|
require 'spec_helper'
|
4
4
|
require File.expand_path("../dummy/config/environment", __FILE__)
|
5
5
|
require 'rspec/rails'
|
6
|
-
require '
|
6
|
+
require 'factory_bot_rails'
|
7
7
|
require 'faker'
|
8
|
-
require 'squeel'
|
9
8
|
|
10
9
|
# Add additional requires below this line. Rails is not loaded until this point!
|
11
10
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module OpenStax
|
4
|
+
module Utilities
|
5
|
+
describe SearchRelation do
|
6
|
+
|
7
|
+
let!(:john_doe) { FactoryBot.create :user, name: "John Doe",
|
8
|
+
username: "doejohn",
|
9
|
+
email: "john@doe.com" }
|
10
|
+
|
11
|
+
let!(:jane_doe) { FactoryBot.create :user, name: "Jane Doe",
|
12
|
+
username: "doejane",
|
13
|
+
email: "jane@doe.com" }
|
14
|
+
|
15
|
+
let!(:jack_doe) { FactoryBot.create :user, name: "Jack Doe",
|
16
|
+
username: "doejack",
|
17
|
+
email: "jack@doe.com" }
|
18
|
+
|
19
|
+
before(:each) do
|
20
|
+
100.times do
|
21
|
+
FactoryBot.create(:user)
|
22
|
+
end
|
23
|
+
|
24
|
+
@relation = User.unscoped
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns nothing if too many results" do
|
28
|
+
routine = LimitAndPaginateRelation.call(relation: @relation,
|
29
|
+
max_items: 10)
|
30
|
+
outputs = routine.outputs
|
31
|
+
errors = routine.errors
|
32
|
+
expect(outputs).not_to be_empty
|
33
|
+
expect(outputs[:total_count]).to eq User.count
|
34
|
+
expect(outputs[:items]).to be_empty
|
35
|
+
expect(errors).not_to be_empty
|
36
|
+
expect(errors.first.code).to eq :too_many_items
|
37
|
+
end
|
38
|
+
|
39
|
+
it "paginates results" do
|
40
|
+
all_items = @relation.to_a
|
41
|
+
|
42
|
+
items = LimitAndPaginateRelation.call(relation: @relation,
|
43
|
+
per_page: 20).outputs[:items]
|
44
|
+
expect(items.limit(nil).offset(nil).count).to eq all_items.count
|
45
|
+
expect(items.limit(nil).offset(nil).to_a).to eq all_items
|
46
|
+
expect(items.count).to eq 20
|
47
|
+
expect(items.to_a).to eq all_items[0..19]
|
48
|
+
|
49
|
+
for page in 1..5
|
50
|
+
items = LimitAndPaginateRelation.call(relation: @relation,
|
51
|
+
page: page,
|
52
|
+
per_page: 20)
|
53
|
+
.outputs[:items]
|
54
|
+
expect(items.limit(nil).offset(nil).count).to eq all_items.count
|
55
|
+
expect(items.limit(nil).offset(nil).to_a).to eq all_items
|
56
|
+
expect(items.count).to eq 20
|
57
|
+
expect(items.to_a).to eq all_items.slice(20*(page-1), 20)
|
58
|
+
end
|
59
|
+
|
60
|
+
items = LimitAndPaginateRelation.call(relation: @relation,
|
61
|
+
page: 1000,
|
62
|
+
per_page: 20)
|
63
|
+
.outputs[:items]
|
64
|
+
expect(items.limit(nil).offset(nil).count).to eq all_items.count
|
65
|
+
expect(items.limit(nil).offset(nil).to_a).to eq all_items
|
66
|
+
expect(items.count).to eq 0
|
67
|
+
expect(items.to_a).to be_empty
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module OpenStax
|
4
|
+
module Utilities
|
5
|
+
describe SearchRelation do
|
6
|
+
let!(:john_doe) do
|
7
|
+
FactoryBot.create :user, name: "John Doe", username: "doejohn", email: "john@doe.com"
|
8
|
+
end
|
9
|
+
|
10
|
+
let!(:jane_doe) do
|
11
|
+
FactoryBot.create :user, name: "Jane Doe", username: "doejane", email: "jane@doe.com"
|
12
|
+
end
|
13
|
+
|
14
|
+
let!(:jack_doe) do
|
15
|
+
FactoryBot.create :user, name: "Jack Doe", username: "doejack", email: "jack@doe.com"
|
16
|
+
end
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
100.times { FactoryBot.create(:user) }
|
20
|
+
|
21
|
+
@relation = User.where(User.arel_table[:username].matches('doe%'))
|
22
|
+
end
|
23
|
+
|
24
|
+
it "orders results by multiple fields in different directions" do
|
25
|
+
items = OrderRelation.call(
|
26
|
+
relation: @relation,
|
27
|
+
sortable_fields: SearchUsers::SORTABLE_FIELDS,
|
28
|
+
order_by: 'cReAtEd_At AsC, iD'
|
29
|
+
).outputs[:items]
|
30
|
+
expect(items).to include(john_doe)
|
31
|
+
expect(items).to include(jane_doe)
|
32
|
+
expect(items).to include(jack_doe)
|
33
|
+
john_index = items.index(john_doe)
|
34
|
+
jane_index = items.index(jane_doe)
|
35
|
+
jack_index = items.index(jack_doe)
|
36
|
+
expect(jane_index).to be > john_index
|
37
|
+
expect(jack_index).to be > jane_index
|
38
|
+
|
39
|
+
items = OrderRelation.call(
|
40
|
+
relation: @relation,
|
41
|
+
sortable_fields: SearchUsers::SORTABLE_FIELDS,
|
42
|
+
order_by: 'CrEaTeD_aT dEsC, Id DeSc'
|
43
|
+
).outputs[:items]
|
44
|
+
expect(items).to include(john_doe)
|
45
|
+
expect(items).to include(jane_doe)
|
46
|
+
expect(items).to include(jack_doe)
|
47
|
+
john_index = items.index(john_doe)
|
48
|
+
jane_index = items.index(jane_doe)
|
49
|
+
jack_index = items.index(jack_doe)
|
50
|
+
expect(jane_index).to be < john_index
|
51
|
+
expect(jack_index).to be < jane_index
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -2,28 +2,36 @@ require 'rails_helper'
|
|
2
2
|
|
3
3
|
module OpenStax
|
4
4
|
module Utilities
|
5
|
-
describe
|
5
|
+
describe SearchAndOrganizeRelation do
|
6
6
|
|
7
|
-
|
7
|
+
OPTIONS = {
|
8
|
+
relation: SearchUsers::RELATION,
|
9
|
+
search_proc: SearchUsers::SEARCH_PROC,
|
10
|
+
sortable_fields: SearchUsers::SORTABLE_FIELDS,
|
11
|
+
max_items: SearchUsers::MAX_ITEMS
|
12
|
+
}
|
13
|
+
|
14
|
+
let!(:john_doe) { FactoryBot.create :user, name: "John Doe",
|
8
15
|
username: "doejohn",
|
9
16
|
email: "john@doe.com" }
|
10
17
|
|
11
|
-
let!(:jane_doe) {
|
18
|
+
let!(:jane_doe) { FactoryBot.create :user, name: "Jane Doe",
|
12
19
|
username: "doejane",
|
13
20
|
email: "jane@doe.com" }
|
14
21
|
|
15
|
-
let!(:jack_doe) {
|
22
|
+
let!(:jack_doe) { FactoryBot.create :user, name: "Jack Doe",
|
16
23
|
username: "doejack",
|
17
24
|
email: "jack@doe.com" }
|
18
25
|
|
19
26
|
before(:each) do
|
20
27
|
100.times do
|
21
|
-
|
28
|
+
FactoryBot.create(:user)
|
22
29
|
end
|
23
30
|
end
|
24
31
|
|
25
|
-
it "filters results
|
26
|
-
items =
|
32
|
+
it "filters results" do
|
33
|
+
items = SearchAndOrganizeRelation.call(OPTIONS.merge(params: {
|
34
|
+
q: 'last_name:dOe'})).outputs[:items]
|
27
35
|
|
28
36
|
expect(items).to include(john_doe)
|
29
37
|
expect(items).to include(jane_doe)
|
@@ -31,11 +39,9 @@ module OpenStax
|
|
31
39
|
items.each do |item|
|
32
40
|
expect(item.name.downcase).to match(/\A[\w]* doe[\w]*\z/i)
|
33
41
|
end
|
34
|
-
end
|
35
42
|
|
36
|
-
|
37
|
-
|
38
|
-
.outputs[:items]
|
43
|
+
items = SearchAndOrganizeRelation.call(OPTIONS.merge(params: {
|
44
|
+
q: 'first_name:jOhN last_name:DoE'})).outputs[:items]
|
39
45
|
|
40
46
|
expect(items).to include(john_doe)
|
41
47
|
expect(items).not_to include(jane_doe)
|
@@ -43,11 +49,9 @@ module OpenStax
|
|
43
49
|
items.each do |item|
|
44
50
|
expect(item.name).to match(/\Ajohn[\w]* doe[\w]*\z/i)
|
45
51
|
end
|
46
|
-
end
|
47
52
|
|
48
|
-
|
49
|
-
|
50
|
-
.outputs[:items]
|
53
|
+
items = SearchAndOrganizeRelation.call(OPTIONS.merge(params: {
|
54
|
+
q: 'first_name:JoHn,JaNe last_name:dOe'})).outputs[:items]
|
51
55
|
|
52
56
|
expect(items).to include(john_doe)
|
53
57
|
expect(items).to include(jane_doe)
|
@@ -57,22 +61,10 @@ module OpenStax
|
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
|
-
it "
|
61
|
-
items =
|
62
|
-
|
63
|
-
|
64
|
-
expect(items).to include(john_doe)
|
65
|
-
expect(items).not_to include(jane_doe)
|
66
|
-
expect(items).not_to include(jack_doe)
|
67
|
-
items.each do |item|
|
68
|
-
expect(item.name.downcase).to match(/\Ajohn[\w]* doe[\w]*\z/i)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
it "orders results by multiple fields in different directions" do
|
73
|
-
items = SearchUsers.call(User.unscoped, 'username:DoE',
|
74
|
-
order_by: 'cReAtEd_At AsC, iD')
|
75
|
-
.outputs[:items]
|
64
|
+
it "orders results" do
|
65
|
+
items = SearchAndOrganizeRelation.call(OPTIONS.merge(params: {
|
66
|
+
order_by: 'cReAtEd_At AsC, iD',
|
67
|
+
q: 'username:dOe'})).outputs[:items].to_a
|
76
68
|
expect(items).to include(john_doe)
|
77
69
|
expect(items).to include(jane_doe)
|
78
70
|
expect(items).to include(jack_doe)
|
@@ -81,13 +73,10 @@ module OpenStax
|
|
81
73
|
jack_index = items.index(jack_doe)
|
82
74
|
expect(jane_index).to be > john_index
|
83
75
|
expect(jack_index).to be > jane_index
|
84
|
-
items.each do |item|
|
85
|
-
expect(item.username).to match(/\Adoe[\w]*\z/i)
|
86
|
-
end
|
87
76
|
|
88
|
-
items =
|
89
|
-
|
90
|
-
|
77
|
+
items = SearchAndOrganizeRelation.call(OPTIONS.merge(params: {
|
78
|
+
order_by: 'CrEaTeD_aT dEsC, Id DeSc',
|
79
|
+
q: 'username:dOe'})).outputs[:items].to_a
|
91
80
|
expect(items).to include(john_doe)
|
92
81
|
expect(items).to include(jane_doe)
|
93
82
|
expect(items).to include(jack_doe)
|
@@ -96,31 +85,49 @@ module OpenStax
|
|
96
85
|
jack_index = items.index(jack_doe)
|
97
86
|
expect(jane_index).to be < john_index
|
98
87
|
expect(jack_index).to be < jane_index
|
99
|
-
|
100
|
-
|
101
|
-
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns nothing if too many results" do
|
91
|
+
routine = SearchAndOrganizeRelation.call(OPTIONS.merge(params: {
|
92
|
+
q: ''}))
|
93
|
+
outputs = routine.outputs
|
94
|
+
errors = routine.errors
|
95
|
+
expect(outputs).not_to be_empty
|
96
|
+
expect(outputs[:total_count]).to eq User.count
|
97
|
+
expect(outputs[:items]).to be_empty
|
98
|
+
expect(errors).not_to be_empty
|
99
|
+
expect(errors.first.code).to eq :too_many_items
|
102
100
|
end
|
103
101
|
|
104
102
|
it "paginates results" do
|
105
|
-
all_items = SearchUsers.
|
103
|
+
all_items = SearchUsers::RELATION.to_a
|
106
104
|
|
107
|
-
items =
|
108
|
-
|
105
|
+
items = SearchAndOrganizeRelation.call(OPTIONS
|
106
|
+
.except(:max_items)
|
107
|
+
.merge(params: {q: '',
|
108
|
+
per_page: 20})).outputs[:items]
|
109
|
+
expect(items.limit(nil).offset(nil).count).to eq all_items.length
|
109
110
|
expect(items.limit(nil).offset(nil).to_a).to eq all_items
|
110
111
|
expect(items.count).to eq 20
|
111
112
|
expect(items.to_a).to eq all_items[0..19]
|
112
113
|
|
113
114
|
for page in 1..5
|
114
|
-
items =
|
115
|
-
|
115
|
+
items = SearchAndOrganizeRelation.call(OPTIONS
|
116
|
+
.except(:max_items)
|
117
|
+
.merge(params: {q: '',
|
118
|
+
page: page,
|
119
|
+
per_page: 20})).outputs[:items]
|
116
120
|
expect(items.limit(nil).offset(nil).count).to eq all_items.count
|
117
121
|
expect(items.limit(nil).offset(nil).to_a).to eq all_items
|
118
122
|
expect(items.count).to eq 20
|
119
123
|
expect(items.to_a).to eq all_items.slice(20*(page-1), 20)
|
120
124
|
end
|
121
125
|
|
122
|
-
items =
|
123
|
-
|
126
|
+
items = SearchAndOrganizeRelation.call(OPTIONS
|
127
|
+
.except(:max_items)
|
128
|
+
.merge(params: {q: '',
|
129
|
+
page: 1000,
|
130
|
+
per_page: 20})).outputs[:items]
|
124
131
|
expect(items.limit(nil).offset(nil).count).to eq all_items.count
|
125
132
|
expect(items.limit(nil).offset(nil).to_a).to eq all_items
|
126
133
|
expect(items.count).to eq 0
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module OpenStax
|
4
|
+
module Utilities
|
5
|
+
describe SearchRelation do
|
6
|
+
let!(:john_doe) do
|
7
|
+
FactoryBot.create :user, name: "John Doe", username: "doejohn", email: "john@doe.com"
|
8
|
+
end
|
9
|
+
|
10
|
+
let!(:jane_doe) do
|
11
|
+
FactoryBot.create :user, name: "Jane Doe", username: "doejane", email: "jane@doe.com"
|
12
|
+
end
|
13
|
+
|
14
|
+
let!(:jack_doe) do
|
15
|
+
FactoryBot.create :user, name: "Jack Doe", username: "doejack", email: "jack@doe.com"
|
16
|
+
end
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
100.times do
|
20
|
+
FactoryBot.create(:user)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "filters results based on one field" do
|
25
|
+
items = SearchRelation.call(relation: SearchUsers::RELATION,
|
26
|
+
search_proc: SearchUsers::SEARCH_PROC,
|
27
|
+
query: 'last_name:dOe').outputs[:items]
|
28
|
+
|
29
|
+
expect(items).to include(john_doe)
|
30
|
+
expect(items).to include(jane_doe)
|
31
|
+
expect(items).to include(jack_doe)
|
32
|
+
items.each do |item|
|
33
|
+
expect(item.name.downcase).to match(/\A[\w]* doe[\w]*\z/i)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "filters results based on multiple fields" do
|
38
|
+
items = SearchRelation.call(relation: SearchUsers::RELATION,
|
39
|
+
search_proc: SearchUsers::SEARCH_PROC,
|
40
|
+
query: 'first_name:jOhN last_name:DoE')
|
41
|
+
.outputs[:items]
|
42
|
+
|
43
|
+
expect(items).to include(john_doe)
|
44
|
+
expect(items).not_to include(jane_doe)
|
45
|
+
expect(items).not_to include(jack_doe)
|
46
|
+
items.each do |item|
|
47
|
+
expect(item.name).to match(/\Ajohn[\w]* doe[\w]*\z/i)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "filters results based on multiple keywords per field" do
|
52
|
+
items = SearchRelation.call(relation: SearchUsers::RELATION,
|
53
|
+
search_proc: SearchUsers::SEARCH_PROC,
|
54
|
+
query: 'first_name:JoHn,JaNe last_name:dOe')
|
55
|
+
.outputs[:items]
|
56
|
+
|
57
|
+
expect(items).to include(john_doe)
|
58
|
+
expect(items).to include(jane_doe)
|
59
|
+
expect(items).not_to include(jack_doe)
|
60
|
+
items.each do |item|
|
61
|
+
expect(item.name).to match(/\A[john|jane][\w]* doe[\w]*\z/i)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "filters scoped results" do
|
66
|
+
items = SearchRelation.call(
|
67
|
+
relation: User.where(User.arel_table[:name].matches('jOhN%')),
|
68
|
+
search_proc: SearchUsers::SEARCH_PROC,
|
69
|
+
query: 'last_name:dOe'
|
70
|
+
).outputs[:items]
|
71
|
+
|
72
|
+
expect(items).to include(john_doe)
|
73
|
+
expect(items).not_to include(jane_doe)
|
74
|
+
expect(items).not_to include(jack_doe)
|
75
|
+
items.each do |item|
|
76
|
+
expect(item.name.downcase).to match(/\Ajohn[\w]* doe[\w]*\z/i)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|