Skip to content

Commit f026af1

Browse files
fix: FilterStorage URL encoding (#698)
* Add quotation for filter value in url encoded string * Add convenient string wrapping functions for URL encoding to improve readability
1 parent 423400f commit f026af1

File tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// String+Wrapping.swift
3+
//
4+
//
5+
// Created by Vladislav Fitc on 23/11/2020.
6+
//
7+
8+
import Foundation
9+
10+
extension String {
11+
12+
func wrappedInQuotes() -> String { "\"\(self)\"" }
13+
func wrappedInBrackets() -> String { "[\(self)]" }
14+
15+
}

Sources/AlgoliaSearchClient/Models/Search/Query/Query+URLEncodable.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extension Query {
1212
struct URLEncoder<Key: RawRepresentable> where Key.RawValue == String {
1313

1414
var queryItems: [URLQueryItem] = []
15-
15+
1616
mutating func set<T: URLEncodable>(_ value: T?, for key: Key) {
1717
guard let value = value else { return }
1818
queryItems.append(.init(name: key.rawValue, value: value.urlEncodedString))
@@ -30,39 +30,39 @@ extension Query {
3030

3131
mutating func set<S: Sequence>(_ value: S?, for key: Key) where S.Element == [String] {
3232
guard let value = value else { return }
33-
let valueToSet = "[\(value.map { "[\($0.map(\.urlEncodedString).sorted().joined(separator: ","))]" }.joined(separator: ","))]"
33+
let valueToSet = value.map { $0.map(\.urlEncodedString).sorted().joined(separator: ",").wrappedInBrackets() }.joined(separator: ",").wrappedInBrackets()
3434
queryItems.append(.init(name: key.rawValue, value: valueToSet))
3535
}
3636

3737
mutating func set(_ value: FiltersStorage?, for key: Key) {
38-
guard let value = value else { return }
38+
guard let value = value?.rawValue else { return }
3939
func toString(_ singleOrList: SingleOrList<String>) -> String {
4040
switch singleOrList {
4141
case .single(let value):
42-
return value
42+
return value.wrappedInQuotes()
4343
case .list(let list):
44-
return "[\(list.joined(separator: ","))]"
44+
return list.map { $0.wrappedInQuotes() }.joined(separator: ",").wrappedInBrackets()
4545
}
4646
}
47-
let valueToSet = "[\(value.rawValue.map(toString).joined(separator: ","))]"
47+
let valueToSet = value.map(toString).joined(separator: ",").wrappedInBrackets()
4848
queryItems.append(.init(name: key.rawValue, value: valueToSet))
4949
}
5050

5151
mutating func set<S: Sequence>(_ value: S?, for key: Key) where S.Element == BoundingBox {
5252
guard let value = value else { return }
53-
let valueToSet = "[\(value.map(\.urlEncodedString).joined(separator: ","))]"
53+
let valueToSet = value.map(\.urlEncodedString).joined(separator: ",").wrappedInBrackets()
5454
queryItems.append(.init(name: key.rawValue, value: valueToSet))
5555
}
5656

5757
mutating func set<S: Sequence>(_ value: S?, for key: Key) where S.Element == AroundPrecision {
5858
guard let value = value else { return }
59-
let valueToSet = "[\(value.map(\.urlEncodedString).joined(separator: ","))]"
59+
let valueToSet = value.map(\.urlEncodedString).joined(separator: ",").wrappedInBrackets()
6060
queryItems.append(.init(name: key.rawValue, value: valueToSet))
6161
}
6262

6363
mutating func set<S: Sequence>(_ value: S?, for key: Key) where S.Element == Polygon {
6464
guard let value = value else { return }
65-
let valueToSet = "[\(value.map(\.urlEncodedString).joined(separator: ","))]"
65+
let valueToSet = value.map(\.urlEncodedString).joined(separator: ",").wrappedInBrackets()
6666
queryItems.append(.init(name: key.rawValue, value: valueToSet))
6767
}
6868

Tests/AlgoliaSearchClientTests/Unit/QueryTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ class QueryTests: XCTestCase {
9494
"attributesToRetrieve=attr1,attr2,attr3",
9595
"restrictSearchableAttributes=rattr1,rattr2",
9696
"filters=(color:red%20OR%20color:yellow)%20AND%20on-sale",
97-
"facetFilters=%5B%5Bcolor:red,color:blue%5D,size:M%5D",
98-
"optionalFilters=%5B%5Bcolor:red,color:yellow%5D,on-sale%5D",
99-
"numericFilters=%5B%5Bprice%3E100,length%3C1000%5D,metrics%3E5%5D",
100-
"tagFilters=%5B%5Btag1,tag2%5D,tag3%5D",
97+
"facetFilters=%5B%5B%22color:red%22,%22color:blue%22%5D,%22size:M%22%5D",
98+
"optionalFilters=%5B%5B%22color:red%22,%22color:yellow%22%5D,%22on-sale%22%5D",
99+
"numericFilters=%5B%5B%22price%3E100%22,%22length%3C1000%22%5D,%22metrics%3E5%22%5D",
100+
"tagFilters=%5B%5B%22tag1%22,%22tag2%22%5D,%22tag3%22%5D",
101101
"sumOrFiltersScores=false",
102102
"facets=facet1,facet2,facet3",
103103
"maxValuesPerFacet=10",

0 commit comments

Comments
 (0)