rails-contact 0.1.17 → 0.1.18
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/CHANGELOG.md +14 -0
- data/app/controllers/rails/contact/contacts_controller.rb +3 -3
- data/lib/rails/contact/search/backends/database.rb +10 -2
- data/lib/rails/contact/version.rb +1 -1
- data/spec/controllers/contacts_controller_spec.rb +15 -5
- data/spec/search/database_backend_spec.rb +22 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b0b84870f841f736094084fa2ae0c08805f5b54a30fa8960b95cc04f14998001
|
|
4
|
+
data.tar.gz: 830dfc497510913b838651a00f430d36919c35fca155b54424dae053d4feba60
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bab63c0475d073586b14a681c7822f6185b4437e077b5bf3583fc7fa1c68f0ee581a4e7248d6498e77d72e0721c41e8105c188c56dfdeda54071573b9c4b33df
|
|
7
|
+
data.tar.gz: d46deab8ed814b053834de5157f76ef089efdc3fb04d630a03dbf85375b8686a89f70ab706b956b57f31bdf2152d2fcb9cca6352bccdecef310dfa21b8558486
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.18
|
|
4
|
+
|
|
5
|
+
- **The `city` filter is a multi-select.** `?city[]=Pune&city[]=Delhi` now
|
|
6
|
+
filters on several current cities at once, matching how `region` and
|
|
7
|
+
`csv_import_id` already behave. The database backend always handled an
|
|
8
|
+
array (`where(current_city: [...])`) — only the parameter permit was
|
|
9
|
+
scalar, which silently dropped every value but the last. Blank entries
|
|
10
|
+
(the hidden option a `<select multiple>` always submits) are stripped, and
|
|
11
|
+
an old single-value bookmark (`?city=Pune`) is coerced to a one-element
|
|
12
|
+
array, so no existing link changes meaning. The database backend now drops
|
|
13
|
+
blank entries from `city`/`region` itself as well, so a caller reaching it
|
|
14
|
+
directly gets "no filter" from an untouched multi-select instead of zero
|
|
15
|
+
rows.
|
|
16
|
+
|
|
3
17
|
## 0.1.17
|
|
4
18
|
|
|
5
19
|
- **Database backend free-text search is now prefix search.** `q` matches
|
|
@@ -136,7 +136,6 @@ module Rails
|
|
|
136
136
|
metadata_scalars << :sort if config.metadata_sorts.any?
|
|
137
137
|
|
|
138
138
|
permitted = params.permit(
|
|
139
|
-
:city,
|
|
140
139
|
:sync_eligible,
|
|
141
140
|
:starred,
|
|
142
141
|
:travel_date_start,
|
|
@@ -144,16 +143,17 @@ module Rails
|
|
|
144
143
|
:contact_created_at_start,
|
|
145
144
|
:contact_created_at_end,
|
|
146
145
|
*metadata_scalars,
|
|
146
|
+
city: [],
|
|
147
147
|
region: [],
|
|
148
148
|
csv_import_id: [],
|
|
149
149
|
**metadata_arrays.index_with { [] }
|
|
150
150
|
)
|
|
151
151
|
|
|
152
|
-
([ :region, :csv_import_id ] + metadata_arrays).each { |key| normalize_multi_select!(permitted, key) }
|
|
152
|
+
([ :city, :region, :csv_import_id ] + metadata_arrays).each { |key| normalize_multi_select!(permitted, key) }
|
|
153
153
|
permitted
|
|
154
154
|
end
|
|
155
155
|
|
|
156
|
-
# region, csv_import_id and every configured :values metadata filter are
|
|
156
|
+
# city, region, csv_import_id and every configured :values metadata filter are
|
|
157
157
|
# multi-selects: a <select multiple> submits param[] (an array) plus a
|
|
158
158
|
# hidden param[]="" that Rails always sends, so the blank must be
|
|
159
159
|
# stripped — otherwise IN ('', 'x') matches every blank-valued row.
|
|
@@ -106,8 +106,16 @@ module Rails
|
|
|
106
106
|
|
|
107
107
|
def apply_filters(scope, filters)
|
|
108
108
|
scoped = scope
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
# city and region are multi-selects: one value or many. Blanks are
|
|
110
|
+
# dropped here as well as in the controller — an untouched
|
|
111
|
+
# <select multiple> submits [""], and `where(col: [""])` would
|
|
112
|
+
# return nothing at all rather than "no city filter". A caller
|
|
113
|
+
# reaching the backend directly gets the same answer as one coming
|
|
114
|
+
# through filter_params.
|
|
115
|
+
%w[city region].zip(%i[current_city region_name]).each do |key, column|
|
|
116
|
+
values = Array(filters[key]).map(&:to_s).reject(&:blank?)
|
|
117
|
+
scoped = scoped.where(column => values) if values.any?
|
|
118
|
+
end
|
|
111
119
|
scoped = scoped.where(starred: ActiveModel::Type::Boolean.new.cast(filters["starred"])) if filters["starred"].present?
|
|
112
120
|
if filters["sync_eligible"].present?
|
|
113
121
|
scoped = scoped.where(sync_eligible: ActiveModel::Type::Boolean.new.cast(filters["sync_eligible"]))
|
|
@@ -4,16 +4,26 @@ RSpec.describe Rails::Contact::ContactsController do
|
|
|
4
4
|
let(:controller) { described_class.new }
|
|
5
5
|
|
|
6
6
|
describe "private filter params" do
|
|
7
|
-
|
|
7
|
+
# city joined region as a multi-select in 0.1.18, so a scalar from an old
|
|
8
|
+
# bookmark is coerced to a one-element array rather than kept as a string.
|
|
9
|
+
it "permits sync_eligible and coerces scalar city/region to arrays" do
|
|
8
10
|
controller.params = ActionController::Parameters.new(city: "Delhi", region: "Europe", sync_eligible: "true", x: "1")
|
|
9
11
|
permitted = controller.send(:filter_params)
|
|
10
|
-
expect(permitted.to_h).to eq({ "city" => "Delhi", "region" => [ "Europe" ], "sync_eligible" => "true" })
|
|
12
|
+
expect(permitted.to_h).to eq({ "city" => [ "Delhi" ], "region" => [ "Europe" ], "sync_eligible" => "true" })
|
|
11
13
|
end
|
|
12
14
|
|
|
13
|
-
it "permits multi-select region[] and csv_import_id[] arrays" do
|
|
14
|
-
controller.params = ActionController::Parameters.new(region: [ "Europe", "Asia" ], csv_import_id: [ "5", "7" ])
|
|
15
|
+
it "permits multi-select city[], region[] and csv_import_id[] arrays" do
|
|
16
|
+
controller.params = ActionController::Parameters.new(city: [ "Pune", "Delhi" ], region: [ "Europe", "Asia" ], csv_import_id: [ "5", "7" ])
|
|
15
17
|
permitted = controller.send(:filter_params)
|
|
16
|
-
expect(permitted.to_h).to eq({ "region" => [ "Europe", "Asia" ], "csv_import_id" => [ "5", "7" ] })
|
|
18
|
+
expect(permitted.to_h).to eq({ "city" => [ "Pune", "Delhi" ], "region" => [ "Europe", "Asia" ], "csv_import_id" => [ "5", "7" ] })
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "strips the blank a city multi-select submits, and drops it when only blanks arrive" do
|
|
22
|
+
controller.params = ActionController::Parameters.new(city: [ "", "Pune" ])
|
|
23
|
+
expect(controller.send(:filter_params).to_h).to eq({ "city" => [ "Pune" ] })
|
|
24
|
+
|
|
25
|
+
controller.params = ActionController::Parameters.new(city: [ "" ])
|
|
26
|
+
expect(controller.send(:filter_params).to_h).to eq({})
|
|
17
27
|
end
|
|
18
28
|
|
|
19
29
|
it "strips the hidden blank a <select multiple> submits" do
|
|
@@ -29,6 +29,28 @@ RSpec.describe Rails::Contact::Search::Backends::Database do
|
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# City became a multi-select in 0.1.18. The backend always accepted an array
|
|
33
|
+
# here — what was missing was a permit that let one through.
|
|
34
|
+
describe "city filter (multi-select)" do
|
|
35
|
+
# Distinct from the factory default ("Delhi"), so alice/bob/carol above
|
|
36
|
+
# can't drift into these expectations.
|
|
37
|
+
let!(:pune) { create(:rails_contact_contact, given_name: "Pia", current_city: "Pune") }
|
|
38
|
+
let!(:jaipur) { create(:rails_contact_contact, given_name: "Dev", current_city: "Jaipur") }
|
|
39
|
+
let!(:kochi) { create(:rails_contact_contact, given_name: "Mira", current_city: "Kochi") }
|
|
40
|
+
|
|
41
|
+
it "matches contacts in every selected city (array -> IN)" do
|
|
42
|
+
expect(records("city" => [ "Pune", "Jaipur" ])).to match_array([ pune, jaipur ])
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "matches a single city exactly as before (scalar)" do
|
|
46
|
+
expect(records("city" => "Kochi")).to match_array([ kochi ])
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "applies no constraint when the selection is blank only" do
|
|
50
|
+
expect(records("city" => [ "" ]).count).to eq(Rails::Contact::Contact.count)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
32
54
|
describe "query sanitization" do
|
|
33
55
|
def search_for(query)
|
|
34
56
|
described_class.new.search(query, {}, page: 1, per_page: 25).records
|