Skip to content

Commit 3c38c63

Browse files
committed
Merge pull request #32 from mapbox/1ec5-escape-from-space-30
Escape queries
2 parents 9aad731 + c4422c8 commit 3c38c63

File tree

5 files changed

+93
-2
lines changed

5 files changed

+93
-2
lines changed

MapboxGeocoder.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
/* Begin PBXBuildFile section */
1010
8DF260A67CA4C55F8FA7CAA0 /* Pods_MapboxGeocoderTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CD6EA86BBE0D7DE16654CB4 /* Pods_MapboxGeocoderTests.framework */; };
1111
9FB47CA319B32DD7142B5830 /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6953F60F050AE274E006CB85 /* Pods.framework */; };
12+
DA210BAB1CB4BE73008088FD /* ForwardGeocodingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA210BAA1CB4BE73008088FD /* ForwardGeocodingTests.swift */; };
13+
DA210BAD1CB4BFF7008088FD /* forward_valid.json in Resources */ = {isa = PBXBuildFile; fileRef = DA210BAC1CB4BFF7008088FD /* forward_valid.json */; };
14+
DA210BAF1CB4C5A7008088FD /* forward_invalid.json in Resources */ = {isa = PBXBuildFile; fileRef = DA210BAE1CB4C5A7008088FD /* forward_invalid.json */; };
1215
DA2E03F01CB0FDB400D1269A /* MBPlacemark.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E03EF1CB0FDB400D1269A /* MBPlacemark.swift */; };
1316
DA2E03F21CB0FE0200D1269A /* MBRectangularRegion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E03F11CB0FE0200D1269A /* MBRectangularRegion.swift */; };
1417
DA2E03F71CB0FFD800D1269A /* MBGeocoderConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E03F61CB0FFD800D1269A /* MBGeocoderConfiguration.swift */; };
@@ -97,6 +100,9 @@
97100
A7FEE3C3AC9D553F9763CB06 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
98101
CC09570CD1A6D11014400590 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
99102
D9281D748078BEB61AACF246 /* Pods_Unit_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Unit_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
103+
DA210BAA1CB4BE73008088FD /* ForwardGeocodingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForwardGeocodingTests.swift; sourceTree = "<group>"; };
104+
DA210BAC1CB4BFF7008088FD /* forward_valid.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = forward_valid.json; sourceTree = "<group>"; };
105+
DA210BAE1CB4C5A7008088FD /* forward_invalid.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = forward_invalid.json; sourceTree = "<group>"; };
100106
DA2E03EF1CB0FDB400D1269A /* MBPlacemark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MBPlacemark.swift; sourceTree = "<group>"; };
101107
DA2E03F11CB0FE0200D1269A /* MBRectangularRegion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MBRectangularRegion.swift; sourceTree = "<group>"; };
102108
DA2E03F61CB0FFD800D1269A /* MBGeocoderConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MBGeocoderConfiguration.swift; sourceTree = "<group>"; };
@@ -283,6 +289,7 @@
283289
isa = PBXGroup;
284290
children = (
285291
DA701C001CB1292C00B0E520 /* MBGeocoderConfigurationTests.swift */,
292+
DA210BAA1CB4BE73008088FD /* ForwardGeocodingTests.swift */,
286293
DDF1E84C1BD6F7BA00C40C78 /* ReverseGeocodingTests.swift */,
287294
DDF1E84E1BD6F7BA00C40C78 /* Info.plist */,
288295
DDF1E8571BD700EB00C40C78 /* Fixtures */,
@@ -294,6 +301,8 @@
294301
DDF1E8571BD700EB00C40C78 /* Fixtures */ = {
295302
isa = PBXGroup;
296303
children = (
304+
DA210BAC1CB4BFF7008088FD /* forward_valid.json */,
305+
DA210BAE1CB4C5A7008088FD /* forward_invalid.json */,
297306
DDF1E85B1BD70E4C00C40C78 /* reverse_valid.json */,
298307
DDF1E85A1BD70E4C00C40C78 /* reverse_invalid.json */,
299308
);
@@ -468,8 +477,10 @@
468477
isa = PBXResourcesBuildPhase;
469478
buildActionMask = 2147483647;
470479
files = (
480+
DA210BAD1CB4BFF7008088FD /* forward_valid.json in Resources */,
471481
DDF1E85C1BD70E4C00C40C78 /* reverse_invalid.json in Resources */,
472482
DDF1E85D1BD70E4C00C40C78 /* reverse_valid.json in Resources */,
483+
DA210BAF1CB4C5A7008088FD /* forward_invalid.json in Resources */,
473484
);
474485
runOnlyForDeploymentPostprocessing = 0;
475486
};
@@ -605,6 +616,7 @@
605616
buildActionMask = 2147483647;
606617
files = (
607618
DDF1E84D1BD6F7BA00C40C78 /* ReverseGeocodingTests.swift in Sources */,
619+
DA210BAB1CB4BE73008088FD /* ForwardGeocodingTests.swift in Sources */,
608620
DA701C011CB1292C00B0E520 /* MBGeocoderConfigurationTests.swift in Sources */,
609621
DA701C031CB12A1800B0E520 /* Fixture.swift in Sources */,
610622
);

MapboxGeocoder/MBGeocoderRouter.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ internal enum MBGeocoderRouter: Router {
2525
case .V5(_, _, _, let ISOCountryCodes, let focusCoordinate, let scopes, let autocomplete):
2626
var params: [String: String] = [:]
2727
if let ISOCountryCodes = ISOCountryCodes {
28-
params["country"] = ISOCountryCodes.joinWithSeparator(",")
28+
params["country"] = ISOCountryCodes.joinWithSeparator(",").lowercaseString
2929
}
3030
if let focusCoordinate = focusCoordinate {
3131
params["proximity"] = String(format: "%.3f,%.3f", focusCoordinate.longitude, focusCoordinate.latitude)
@@ -43,7 +43,8 @@ internal enum MBGeocoderRouter: Router {
4343
var path: String {
4444
switch self {
4545
case .V5(_, let isPermanent, let query, _, _, _, _):
46-
return "geocoding/v5/mapbox.places\(isPermanent ? "-permanent" : "")/\(query).json"
46+
let encodedQuery = query.stringByReplacingOccurrencesOfString(" ", withString: "+").stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet())!
47+
return "geocoding/v5/mapbox.places\(isPermanent ? "-permanent" : "")/\(encodedQuery).json"
4748
}
4849
}
4950
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import XCTest
2+
import Nocilla
3+
import CoreLocation
4+
@testable import MapboxGeocoder
5+
6+
class ForwardGeocodingTests: XCTestCase {
7+
override func setUp() {
8+
super.setUp()
9+
LSNocilla.sharedInstance().start()
10+
}
11+
12+
override func tearDown() {
13+
LSNocilla.sharedInstance().clearStubs()
14+
LSNocilla.sharedInstance().stop()
15+
super.setUp()
16+
}
17+
18+
func testValidForwardGeocode() {
19+
let expectation = expectationWithDescription("forward geocode should return results")
20+
21+
let json = Fixture.stringFromFileNamed("forward_valid")
22+
stubRequest("GET", "https://api.mapbox.com/geocoding/v5/mapbox.places/1600+pennsylvania+ave+nw.json?access_token=\(BogusToken)&country=ca").andReturn(200).withHeaders(["Content-Type": "application/json"]).withBody(json)
23+
24+
let geocoder = MBGeocoder(accessToken: BogusToken)
25+
var addressPlacemark: MBPlacemark! = nil
26+
geocoder.geocodeAddressString("1600 pennsylvania ave nw", inCountries: ["CA"]) { (placemarks, error) in
27+
XCTAssertEqual(placemarks?.count, 5, "forward geocode should have 5 results")
28+
addressPlacemark = placemarks![0]
29+
30+
expectation.fulfill()
31+
}
32+
33+
waitForExpectationsWithTimeout(1) { (error) in
34+
XCTAssertNil(error, "Error: \(error)")
35+
XCTAssertFalse(geocoder.geocoding)
36+
}
37+
38+
XCTAssertEqual(addressPlacemark.description, "Pennsylvania Ave, Stellarton, Nova Scotia B0K 1S0, Canada", "forward geocode should populate description")
39+
XCTAssertEqual(addressPlacemark.name, "Pennsylvania Ave", "forward geocode should populate name")
40+
XCTAssertEqual(addressPlacemark.location?.coordinate, CLLocationCoordinate2D(latitude: 45.5562851, longitude: -62.661944), "forward geocode should populate location")
41+
XCTAssertEqual(addressPlacemark.scope, .Address, "forward geocode should populate scope")
42+
XCTAssertEqual(addressPlacemark.ISOcountryCode, "CA", "forward geocode should populate ISO country code")
43+
XCTAssertEqual(addressPlacemark.country, "Canada", "forward geocode should populate country")
44+
XCTAssertEqual(addressPlacemark.postalCode, "B0K 1S0", "forward geocode should populate postal code")
45+
XCTAssertEqual(addressPlacemark.administrativeArea, "Nova Scotia", "forward geocode should populate administrative area")
46+
XCTAssertEqual(addressPlacemark.subAdministrativeArea, "Stellarton", "forward geocode should populate sub-administrative area")
47+
XCTAssertEqual(addressPlacemark.locality, "Stellarton", "forward geocode should populate locality")
48+
XCTAssertEqual(addressPlacemark.thoroughfare, "Pennsylvania Ave", "forward geocode should populate thoroughfare")
49+
XCTAssertNil(addressPlacemark.subThoroughfare, "forward geocode should not populate sub-thoroughfare for street-only result")
50+
51+
XCTAssertNotNil(addressPlacemark.addressDictionary)
52+
let addressDictionary = addressPlacemark.addressDictionary!
53+
XCTAssertEqual(addressDictionary[MBPostalAddressStreetKey] as? String, "Pennsylvania Ave", "forward geocode should populate street in address dictionary")
54+
XCTAssertEqual(addressDictionary[MBPostalAddressCityKey] as? String, "Stellarton", "forward geocode should populate city in address dictionary")
55+
XCTAssertEqual(addressDictionary[MBPostalAddressStateKey] as? String, "Nova Scotia", "forward geocode should populate state in address dictionary")
56+
XCTAssertEqual(addressDictionary[MBPostalAddressCountryKey] as? String, "Canada", "forward geocode should populate country in address dictionary")
57+
XCTAssertEqual(addressDictionary[MBPostalAddressISOCountryCodeKey] as? String, "CA", "forward geocode should populate ISO country code in address dictionary")
58+
}
59+
60+
func testInvalidForwardGeocode() {
61+
let json = Fixture.stringFromFileNamed("forward_invalid")
62+
stubRequest("GET", "https://api.mapbox.com/geocoding/v5/mapbox.places/Sandy+Island,+New+Caledonia.json?access_token=\(BogusToken)&country=fr&types=region%2Cplace%2Clocality%2Cpoi").andReturn(200).withHeaders(["Content-Type": "application/json"]).withBody(json)
63+
64+
let expection = expectationWithDescription("forward geocode execute completion handler for invalid query")
65+
let geocoder = MBGeocoder(accessToken: BogusToken)
66+
geocoder.geocodeAddressString("Sandy Island, New Caledonia", withAllowedScopes: [.AdministrativeArea, .Place, .Locality, .PointOfInterest], inCountries: ["FR"]) { (placemarks, error) in
67+
XCTAssertEqual(placemarks?.count, 0, "forward geocode should return no results for invalid query")
68+
expection.fulfill()
69+
}
70+
71+
waitForExpectationsWithTimeout(1) { (error) in
72+
XCTAssertNil(error, "Error: \(error)")
73+
XCTAssertFalse(geocoder.geocoding)
74+
}
75+
}
76+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"type":"FeatureCollection","query":["sandy","island","new","caledonia"],"features":[],"attribution":"NOTICE: © 2016 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained."}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"type":"FeatureCollection","query":["1600","pennsylvania","ave","nw"],"features":[{"id":"address.12284612417573100","type":"Feature","text":"Pennsylvania Ave","place_name":"Pennsylvania Ave, Stellarton, Nova Scotia B0K 1S0, Canada","relevance":0.645,"properties":{},"center":[-62.661944,45.5562851],"geometry":{"type":"Point","coordinates":[-62.661944,45.5562851]},"context":[{"id":"place.55130","text":"Stellarton"},{"id":"postcode.13310912212063190","text":"B0K 1S0"},{"id":"region.10539239752558240","text":"Nova Scotia"},{"id":"country.15589894856372040","text":"Canada","short_code":"ca"}]},{"id":"address.18050667373573100","type":"Feature","text":"Pennsylvania Ave","place_name":"Pennsylvania Ave, Wasaga Beach, Ontario L9Z 3A8, Canada","relevance":0.39,"properties":{},"center":[-79.989025,44.503369],"geometry":{"type":"Point","coordinates":[-79.989025,44.503369]},"context":[{"id":"place.61967","text":"Wasaga Beach"},{"id":"postcode.17609609551414490","text":"L9Z 3A8"},{"id":"region.13373639426376420","text":"Ontario"},{"id":"country.15589894856372040","text":"Canada","short_code":"ca"}]},{"id":"address.6485281316573100","type":"Feature","text":"Pennsylvania Ave","place_name":"Pennsylvania Ave, Vaughan, Ontario L4K 3X6, Canada","relevance":0.39,"properties":{},"center":[-79.532497,43.802232],"geometry":{"type":"Point","coordinates":[-79.532497,43.802232]},"context":[{"id":"neighborhood.5043724752221980","text":"Vellore Woods"},{"id":"place.60547","text":"Vaughan"},{"id":"postcode.6385804433309570","text":"L4K 3X6"},{"id":"region.13373639426376420","text":"Ontario"},{"id":"country.15589894856372040","text":"Canada","short_code":"ca"}]},{"id":"address.6456604709573100","type":"Feature","text":"Pennsylvania Ave","place_name":"Pennsylvania Ave, Vaughan, Ontario L4K 3X8, Canada","relevance":0.39,"properties":{},"center":[-79.531684,43.802706],"geometry":{"type":"Point","coordinates":[-79.531684,43.802706]},"context":[{"id":"neighborhood.5043724752221980","text":"Vellore Woods"},{"id":"place.60547","text":"Vaughan"},{"id":"postcode.6367605302663760","text":"L4K 3X8"},{"id":"region.13373639426376420","text":"Ontario"},{"id":"country.15589894856372040","text":"Canada","short_code":"ca"}]},{"id":"region.14011193683716580","type":"Feature","text":"Northwest Territories","place_name":"Northwest Territories, Canada","relevance":0.24,"properties":{},"bbox":[-141.102750026,59.9981700000001,-102.0004990085,79.229293683],"center":[-128.403942,69.564626],"geometry":{"type":"Point","coordinates":[-128.403942,69.564626]},"context":[{"id":"country.15589894856372040","text":"Canada","short_code":"ca"}]}],"attribution":"NOTICE: © 2016 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained."}

0 commit comments

Comments
 (0)