diff --git a/.circleci/config.yml b/.circleci/config.yml index fa6248adf..f9c9aadf1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -106,7 +106,7 @@ jobs: command: make dependencies - run: name: Test frameworks - command: make ci-dev-test + command: make ci-full-test - run: make codecov - run: name: Prepare artifacts diff --git a/CHANGELOG.md b/CHANGELOG.md index ec80151fd..2fc6e2dd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Guide: https://keepachangelog.com/en/1.0.0/ +- [Tests] Change MockResponse into a protocol, create separate enums conforming to MockResponse for each API type (geocoding, sbs, autofill), add MockResponse as generic to each test base class and MockWebServer. + ## 2.0.0-rc.2 - [Discover] Add support for country, proximity, and origin parameters in Discover.Options search parameters. This fixes an issue when using search-along-route to query category results. diff --git a/MapboxSearch.xcodeproj/project.pbxproj b/MapboxSearch.xcodeproj/project.pbxproj index 487cd7d9f..e18a9aea6 100644 --- a/MapboxSearch.xcodeproj/project.pbxproj +++ b/MapboxSearch.xcodeproj/project.pbxproj @@ -12,6 +12,9 @@ 042477C62B72CCB000D870D5 /* geocoding-reverse-geocoding.json in Resources */ = {isa = PBXBuildFile; fileRef = 042477C42B72CCB000D870D5 /* geocoding-reverse-geocoding.json */; }; 042477C72B72CCB000D870D5 /* geocoding-reverse-geocoding.json in Resources */ = {isa = PBXBuildFile; fileRef = 042477C42B72CCB000D870D5 /* geocoding-reverse-geocoding.json */; }; 043A3D4D2B30F38300DB681B /* CoreAddress+AddressComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043A3D4C2B30F38300DB681B /* CoreAddress+AddressComponents.swift */; }; + 045514C22B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 045514C12B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift */; }; + 045514C32B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 045514C12B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift */; }; + 045514C42B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 045514C12B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift */; }; 048823482B6B0A9D00C770AA /* category-hotel-search-along-route-jp.json in Resources */ = {isa = PBXBuildFile; fileRef = 04AB0B7C2B6B043C00FDE7D5 /* category-hotel-search-along-route-jp.json */; }; 048823492B6B0A9D00C770AA /* category-hotel-search-along-route-jp.json in Resources */ = {isa = PBXBuildFile; fileRef = 04AB0B7C2B6B043C00FDE7D5 /* category-hotel-search-along-route-jp.json */; }; 0488234A2B6B0A9E00C770AA /* category-hotel-search-along-route-jp.json in Resources */ = {isa = PBXBuildFile; fileRef = 04AB0B7C2B6B043C00FDE7D5 /* category-hotel-search-along-route-jp.json */; }; @@ -498,6 +501,7 @@ 042477C12B7290E700D870D5 /* SearchEngineGeocodingIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchEngineGeocodingIntegrationTests.swift; sourceTree = ""; }; 042477C42B72CCB000D870D5 /* geocoding-reverse-geocoding.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "geocoding-reverse-geocoding.json"; sourceTree = ""; }; 043A3D4C2B30F38300DB681B /* CoreAddress+AddressComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CoreAddress+AddressComponents.swift"; sourceTree = ""; }; + 045514C12B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CoreApiType+ToSDKType.swift"; sourceTree = ""; }; 04AB0B792B6AF37800FDE7D5 /* DiscoverIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoverIntegrationTests.swift; sourceTree = ""; }; 04AB0B7C2B6B043C00FDE7D5 /* category-hotel-search-along-route-jp.json */ = {isa = PBXFileReference; explicitFileType = text.json; path = "category-hotel-search-along-route-jp.json"; sourceTree = ""; }; 04970F8C2B7A97C900213763 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; @@ -1458,6 +1462,7 @@ children = ( FEEDD3882508E24900DC0A98 /* LotLan+Extensions.swift */, F970FAD7252B14950000806B /* SearchResultType+Extensions.swift */, + 045514C12B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift */, ); path = Extensions; sourceTree = ""; @@ -2615,6 +2620,7 @@ F953A49325ECEB60003A3681 /* SearchCategorySuggestion+Samples.swift in Sources */, F9F882962583779A00062A82 /* CoreImageInfoStub.swift in Sources */, FEA92E712564149100427965 /* CoreSuggestAction+Samples.swift in Sources */, + 045514C32B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift in Sources */, 2CA1E22129F09CD200A533CF /* PlaceAutocomplete.Suggestion+Tests.swift in Sources */, FED7E1A825517C5100DA34D9 /* CoreBoundingBoxTests.swift in Sources */, F9D70E5C252740DD0019105F /* IndexableDataProviderTests.swift in Sources */, @@ -2663,6 +2669,7 @@ F9201ECA253EECE0002D141B /* CategorySuggestionsIntegrationTestCase.swift in Sources */, F907443B261B13F40091899C /* MockServerUITestCase.swift in Sources */, F9ACA6132642B66600F50CD4 /* MockWebServer.swift in Sources */, + 045514C42B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift in Sources */, FEEDD3D22508E45B00DC0A98 /* VisibilityTestCase.swift in Sources */, F9AB03C3261DBD7F00EDF1E7 /* MockResponse.swift in Sources */, FEEDD3CE2508E45B00DC0A98 /* BaseTestCase.swift in Sources */, @@ -2678,6 +2685,7 @@ files = ( F9C557B62670CC4500BE8B94 /* SearchEngineDelegateStub.swift in Sources */, F9C9461B2743CB1700763F2C /* TestTileStore.swift in Sources */, + 045514C22B7D4B58000D88B9 /* CoreApiType+ToSDKType.swift in Sources */, F9C557C12670CD8C00BE8B94 /* CoreSearchOptions+Samples.swift in Sources */, 1420F31C29A2800300D4A511 /* CoreSearchResultStub+Samples.swift in Sources */, F9C557B72670CC5600BE8B94 /* CoreSearchResultStub.swift in Sources */, diff --git a/Tests/Demo.xctestplan b/Tests/Demo.xctestplan index 7dcacae8b..4adbfc008 100644 --- a/Tests/Demo.xctestplan +++ b/Tests/Demo.xctestplan @@ -35,7 +35,8 @@ "testTargets" : [ { "skippedTests" : [ - "MockServerIntegrationTestCase" + "MockServerIntegrationTestCase", + "OfflineIntegrationTests" ], "target" : { "containerPath" : "container:MapboxSearch.xcodeproj", diff --git a/Tests/MapboxSearchIntegrationTests/AddressAutofillIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/AddressAutofillIntegrationTests.swift index 6cc2d6962..89dead51c 100644 --- a/Tests/MapboxSearchIntegrationTests/AddressAutofillIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/AddressAutofillIntegrationTests.swift @@ -2,7 +2,7 @@ import CoreLocation @testable import MapboxSearch import XCTest -final class AddressAutofillIntegrationTests: MockServerIntegrationTestCase { +final class AddressAutofillIntegrationTests: MockServerIntegrationTestCase { private var addressAutofill: AddressAutofill! private let locationProvider = WrapperLocationProvider(wrapping: DefaultLocationProvider()) @@ -18,7 +18,7 @@ final class AddressAutofillIntegrationTests: MockServerIntegrationTestCase { ) let engine = LocalhostMockServiceProvider.shared.createEngine( - apiType: CoreSearchEngine.ApiType.autofill, + apiType: Mock.coreApiType, accessToken: "access-token", locationProvider: locationProvider ) diff --git a/Tests/MapboxSearchIntegrationTests/CategorySearchEngineIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/CategorySearchEngineIntegrationTests.swift index 841b20f2f..eb7bb7f71 100644 --- a/Tests/MapboxSearchIntegrationTests/CategorySearchEngineIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/CategorySearchEngineIntegrationTests.swift @@ -2,16 +2,17 @@ import CoreLocation @testable import MapboxSearch import XCTest -final class CategorySearchEngineIntegrationTests: MockServerIntegrationTestCase { +final class CategorySearchEngineIntegrationTests: MockServerIntegrationTestCase { private var searchEngine: CategorySearchEngine! - override func setUp() { - super.setUp() + override func setUpWithError() throws { + try super.setUpWithError() + let apiType = try XCTUnwrap(Mock.coreApiType.toSDKType()) searchEngine = CategorySearchEngine( accessToken: "access-token", serviceProvider: LocalhostMockServiceProvider.shared, - apiType: .SBS + apiType: apiType ) } diff --git a/Tests/MapboxSearchIntegrationTests/DiscoverIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/DiscoverIntegrationTests.swift index 620a11a1b..e36a95d30 100644 --- a/Tests/MapboxSearchIntegrationTests/DiscoverIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/DiscoverIntegrationTests.swift @@ -2,7 +2,7 @@ import CoreLocation @testable import MapboxSearch import XCTest -class DiscoverIntegrationTests: MockServerIntegrationTestCase { +class DiscoverIntegrationTests: MockServerIntegrationTestCase { lazy var searchEngine = Discover(locationProvider: DefaultLocationProvider()) func testCategorySearchAlongRouteWithCountryProximityOrigin() throws { diff --git a/Tests/MapboxSearchIntegrationTests/MockServerIntegrationTestCase.swift b/Tests/MapboxSearchIntegrationTests/MockServerIntegrationTestCase.swift index b75bfe048..98b5bae97 100644 --- a/Tests/MapboxSearchIntegrationTests/MockServerIntegrationTestCase.swift +++ b/Tests/MapboxSearchIntegrationTests/MockServerIntegrationTestCase.swift @@ -2,10 +2,11 @@ import CoreLocation @testable import MapboxSearch import XCTest -class MockServerIntegrationTestCase: XCTestCase { - let server = MockWebServer() +class MockServerIntegrationTestCase: XCTestCase { + typealias Mock = Mock + let server = MockWebServer() - func setServerResponse(_ response: MockResponse, query: String? = nil) throws { + func setServerResponse(_ response: Mock, query: String? = nil) throws { try server.setResponse(response, query: query) } diff --git a/Tests/MapboxSearchIntegrationTests/OfflineIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/OfflineIntegrationTests.swift index c8cdb2580..1ab179677 100644 --- a/Tests/MapboxSearchIntegrationTests/OfflineIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/OfflineIntegrationTests.swift @@ -6,7 +6,7 @@ import MapboxCommon @testable import MapboxSearch import XCTest -class OfflineIntegrationTests: MockServerIntegrationTestCase { +class OfflineIntegrationTests: MockServerIntegrationTestCase { let delegate = SearchEngineDelegateStub() let searchEngine = SearchEngine() @@ -65,7 +65,7 @@ class OfflineIntegrationTests: MockServerIntegrationTestCase { XCTAssert(region.completedResourceCount > 0) XCTAssertEqual(region.requiredResourceCount, region.completedResourceCount) case .failure(let error): - XCTFail("Unable to load Regin, \(error.localizedDescription)") + XCTFail("Unable to load Region, \(error.localizedDescription)") } loadDataExpectation.fulfill() } diff --git a/Tests/MapboxSearchIntegrationTests/PlaceAutocompleteIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/PlaceAutocompleteIntegrationTests.swift index 8c2ae9b0a..895402f3c 100644 --- a/Tests/MapboxSearchIntegrationTests/PlaceAutocompleteIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/PlaceAutocompleteIntegrationTests.swift @@ -2,7 +2,7 @@ import CoreLocation @testable import MapboxSearch import XCTest -final class PlaceAutocompleteIntegrationTests: MockServerIntegrationTestCase { +final class PlaceAutocompleteIntegrationTests: MockServerIntegrationTestCase { private var placeAutocomplete: PlaceAutocomplete! override func setUp() { @@ -17,7 +17,7 @@ final class PlaceAutocompleteIntegrationTests: MockServerIntegrationTestCase { ) let engine = LocalhostMockServiceProvider.shared.createEngine( - apiType: CoreSearchEngine.ApiType.SBS, + apiType: Mock.coreApiType, accessToken: "access-token", locationProvider: WrapperLocationProvider(wrapping: DefaultLocationProvider()) ) diff --git a/Tests/MapboxSearchIntegrationTests/SearchEngineGeocodingIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/SearchEngineGeocodingIntegrationTests.swift index 6c5cbda1c..657aa411a 100644 --- a/Tests/MapboxSearchIntegrationTests/SearchEngineGeocodingIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/SearchEngineGeocodingIntegrationTests.swift @@ -2,18 +2,19 @@ import CoreLocation @testable import MapboxSearch import XCTest -class SearchEngineGeocodingIntegrationTests: MockServerIntegrationTestCase { +class SearchEngineGeocodingIntegrationTests: MockServerIntegrationTestCase { let delegate = SearchEngineDelegateStub() var searchEngine: SearchEngine! - override func setUp() { - super.setUp() + override func setUpWithError() throws { + try super.setUpWithError() + let apiType = try XCTUnwrap(Mock.coreApiType.toSDKType()) searchEngine = SearchEngine( accessToken: "access-token", serviceProvider: LocalhostMockServiceProvider.shared, locationProvider: DefaultLocationProvider(), - apiType: .geocoding + apiType: apiType ) searchEngine.delegate = delegate diff --git a/Tests/MapboxSearchIntegrationTests/SearchEngineIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/SearchEngineIntegrationTests.swift index 3fb4112f2..4de4971b4 100644 --- a/Tests/MapboxSearchIntegrationTests/SearchEngineIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/SearchEngineIntegrationTests.swift @@ -2,18 +2,19 @@ import CoreLocation @testable import MapboxSearch import XCTest -class SearchEngineIntegrationTests: MockServerIntegrationTestCase { +class SearchEngineIntegrationTests: MockServerIntegrationTestCase { let delegate = SearchEngineDelegateStub() var searchEngine: SearchEngine! - override func setUp() { - super.setUp() + override func setUpWithError() throws { + try super.setUpWithError() + let apiType = try XCTUnwrap(Mock.coreApiType.toSDKType()) searchEngine = SearchEngine( accessToken: "access-token", serviceProvider: LocalhostMockServiceProvider.shared, locationProvider: DefaultLocationProvider(), - apiType: .SBS + apiType: apiType ) searchEngine.delegate = delegate diff --git a/Tests/MapboxSearchTests/Common/Extensions/CoreApiType+ToSDKType.swift b/Tests/MapboxSearchTests/Common/Extensions/CoreApiType+ToSDKType.swift new file mode 100644 index 000000000..e57f013db --- /dev/null +++ b/Tests/MapboxSearchTests/Common/Extensions/CoreApiType+ToSDKType.swift @@ -0,0 +1,26 @@ +@testable import MapboxSearch + +extension CoreSearchEngine.ApiType { + /// Available only for tests. + /// This is necessary for tests using subclasses and usages of ``AbstractSearchEngine`` to dynamically instantiate + /// an engine with the appropriate ApiType for their test case mocks. + /// ``AbstractSearchEngine`` and subclasses use a ``MapboxSearch.ApiType`` enum which is a **subset** of the Core + /// ApiType. + /// For all other ApiTypes specialized classes are provided that use the Core ApiType directly (such as + /// AddressAutofill) or support is not yet fully implemented (such as search-box). + /// Tests that attempt to use an Autofill or Search-box API type with a custom SearchEngine (instead of a provided + /// specialized class) should encounter a runtime error. + func toSDKType() -> ApiType? { + switch self { + case .geocoding: + return .geocoding + case .SBS: + return .SBS + case .autofill, + .searchBox: + fallthrough + @unknown default: + fatalError() + } + } +} diff --git a/Tests/MapboxSearchUITests/BaseTestCase.swift b/Tests/MapboxSearchUITests/BaseTestCase.swift index ff38336d7..85295c824 100644 --- a/Tests/MapboxSearchUITests/BaseTestCase.swift +++ b/Tests/MapboxSearchUITests/BaseTestCase.swift @@ -1,5 +1,7 @@ import XCTest +/// Base XCTestCase class that provides testable application behavior. +/// Please use subclass ``MockServerUITestCase`` for tests. class BaseTestCase: XCTestCase { static let defaultTimeout: TimeInterval = 10.0 diff --git a/Tests/MapboxSearchUITests/Integration/CategorySuggestionsIntegrationTestCase.swift b/Tests/MapboxSearchUITests/Integration/CategorySuggestionsIntegrationTestCase.swift index 51b6b7feb..be6565e4b 100644 --- a/Tests/MapboxSearchUITests/Integration/CategorySuggestionsIntegrationTestCase.swift +++ b/Tests/MapboxSearchUITests/Integration/CategorySuggestionsIntegrationTestCase.swift @@ -1,7 +1,6 @@ - import XCTest -class CategorySuggestionsIntegrationTestCase: MockServerUITestCase { +class CategorySuggestionsIntegrationTestCase: MockSBSServerUITestCase { override func setUpWithError() throws { try super.setUpWithError() app.launch() diff --git a/Tests/MapboxSearchUITests/Integration/CategorySuggestionsNavigationIntegrationTestCase.swift b/Tests/MapboxSearchUITests/Integration/CategorySuggestionsNavigationIntegrationTestCase.swift index 3b29734ee..128676a7b 100644 --- a/Tests/MapboxSearchUITests/Integration/CategorySuggestionsNavigationIntegrationTestCase.swift +++ b/Tests/MapboxSearchUITests/Integration/CategorySuggestionsNavigationIntegrationTestCase.swift @@ -1,6 +1,6 @@ import XCTest -class CategorySuggestionsNavigationIntegrationTestCase: MockServerUITestCase { +class CategorySuggestionsNavigationIntegrationTestCase: MockSBSServerUITestCase { override func setUpWithError() throws { try super.setUpWithError() app.launch() diff --git a/Tests/MapboxSearchUITests/Integration/FavoritesIntegrationTestCase.swift b/Tests/MapboxSearchUITests/Integration/FavoritesIntegrationTestCase.swift index 32def32d3..b0cdd0a39 100644 --- a/Tests/MapboxSearchUITests/Integration/FavoritesIntegrationTestCase.swift +++ b/Tests/MapboxSearchUITests/Integration/FavoritesIntegrationTestCase.swift @@ -1,6 +1,6 @@ import XCTest -class FavoritesIntegrationTestCase: MockServerUITestCase { +class FavoritesIntegrationTestCase: MockSBSServerUITestCase { func testAddRemoveFavorite() throws { try server.setResponse(.suggestMinsk) try server.setResponse(.retrieveMinsk) diff --git a/Tests/MapboxSearchUITests/Integration/FeedbackIntegrationTestCase.swift b/Tests/MapboxSearchUITests/Integration/FeedbackIntegrationTestCase.swift index 3ef0bfc73..43774b1e9 100644 --- a/Tests/MapboxSearchUITests/Integration/FeedbackIntegrationTestCase.swift +++ b/Tests/MapboxSearchUITests/Integration/FeedbackIntegrationTestCase.swift @@ -2,7 +2,7 @@ import XCTest // TODO: Analytics -class FeedbackIntegrationTestCase: MockServerUITestCase { +class FeedbackIntegrationTestCase: MockSBSServerUITestCase { override func setUpWithError() throws { try super.setUpWithError() diff --git a/Tests/MapboxSearchUITests/Integration/SearchIntegrationTestCase.swift b/Tests/MapboxSearchUITests/Integration/SearchIntegrationTestCase.swift index e1c9f1593..3b8666eb7 100644 --- a/Tests/MapboxSearchUITests/Integration/SearchIntegrationTestCase.swift +++ b/Tests/MapboxSearchUITests/Integration/SearchIntegrationTestCase.swift @@ -1,6 +1,6 @@ import XCTest -class SearchIntegrationTestCase: MockServerUITestCase { +class SearchIntegrationTestCase: MockSBSServerUITestCase { func testRecentSearchRemove() throws { try server.setResponse(.suggestSanFrancisco) try server.setResponse(.retrieveSanFrancisco) diff --git a/Tests/MapboxSearchUITests/MockServerUITestCase.swift b/Tests/MapboxSearchUITests/MockServerUITestCase.swift index 4950a9ee8..4d0a3ed1e 100644 --- a/Tests/MapboxSearchUITests/MockServerUITestCase.swift +++ b/Tests/MapboxSearchUITests/MockServerUITestCase.swift @@ -1,7 +1,9 @@ import Foundation -class MockServerUITestCase: BaseTestCase { - let server = MockWebServer() +/// Base UI test case that uses mocked network responses extended on default testable app behavior. +/// Provide a type conforming to MockResponse and then make use of it when using `server` functions and properties. +class MockServerUITestCase: BaseTestCase { + let server = MockWebServer() override func setUpWithError() throws { try super.setUpWithError() @@ -17,3 +19,7 @@ class MockServerUITestCase: BaseTestCase { server.stop() } } + +/// Specialized default test case that uses SBSMockResponse. +/// SBS is the recommended API engine type and default for the Demo app and UI test cases in the 2.0.0 release series. +typealias MockSBSServerUITestCase = MockServerUITestCase diff --git a/Tests/MapboxSearchUITests/MockWebServer/MockResponse.swift b/Tests/MapboxSearchUITests/MockWebServer/MockResponse.swift index 61aa6ca01..b5ed5ec5a 100644 --- a/Tests/MapboxSearchUITests/MockWebServer/MockResponse.swift +++ b/Tests/MapboxSearchUITests/MockWebServer/MockResponse.swift @@ -1,17 +1,75 @@ import Foundation +@_implementationOnly import MapboxCoreSearch +@testable import MapboxSearch +import Swifter +import XCTest -enum MockResponse { - enum Endpoint: String { - case suggest - case retrieve - case reverse - case multiRetrieve = "retrieve/multi" - case categoryCafe = "cafe" - case categoryHotel = "hotel" - case addressSuggest = "autofill/suggest" - case addressRetrieve = "autofill/retrieve" +protocol MockResponse { + /// Resource from test bundle containing response JSON. + var filepath: String { get } + + /// HTTP Method used for this request, "GET" or "POST". + var httpMethod: HttpServer.HTTPMethod { get } + + /// URL path for this request. + var path: String { get } + + /// The API type for this mock. + /// Uses Core types to support address autofill. + static var coreApiType: CoreSearchEngine.ApiType { get } +} + +// MARK: - Geocoding + +enum GeocodingMockResponse: MockResponse { + case forwardGeocoding + case reverseGeocoding + case reverseGeocodingSBS + + var filepath: String { + let bundle = Bundle(for: MockWebServer.self) + switch self { + case .reverseGeocodingSBS: + return bundle.path(forResource: "reverse-geocoding-sbs", ofType: "json")! + case .reverseGeocoding: + return bundle.path(forResource: "geocoding-reverse-geocoding", ofType: "json")! + case .forwardGeocoding: + return bundle.path(forResource: "mapbox.places.san.francisco", ofType: "json")! + } + } + + var path: String { + var path = "/search/v1" + switch self { + case .forwardGeocoding: + path = "/geocoding/v5/mapbox.places/:query" + case .reverseGeocoding: + path = "/geocoding/v5/mapbox.places/:location" + + case .reverseGeocodingSBS: + path += "/:coordinates" + } + + return path + } + + var httpMethod: HttpServer.HTTPMethod { + switch self { + case .forwardGeocoding, + .reverseGeocoding, + .reverseGeocodingSBS: + return .get + } + } + + static var coreApiType: CoreSearchEngine.ApiType { + .geocoding } +} + +// MARK: - SBS +enum SBSMockResponse: MockResponse { case suggestEmpty case suggestMinsk case suggestSanFrancisco @@ -19,24 +77,19 @@ enum MockResponse { case suggestWithCoordinates case suggestWithMixedCoordinates case suggestCategoryWithCoordinates - case suggestAddressSanFrancisco case retrieveSanFrancisco case retrieveMinsk case retrieveCategory case retrievePoi case multiRetrieve - case retrieveAddressSanFrancisco case recursion - case forwardGeocoding - case reverseGeocoding - case reverseGeocodingSBS case categoryCafe case categoryHotelSearchAlongRoute_JP var filepath: String { - let bundle = Bundle(for: MockWebServer.self) + let bundle = Bundle(for: MockWebServer.self) switch self { case .suggestEmpty: return bundle.path(forResource: "suggestions-empty", ofType: "json")! @@ -62,22 +115,117 @@ enum MockResponse { return bundle.path(forResource: "retrieve-poi", ofType: "json")! case .recursion: return bundle.path(forResource: "recursion", ofType: "json")! - case .reverseGeocodingSBS: - return bundle.path(forResource: "reverse-geocoding-sbs", ofType: "json")! - case .reverseGeocoding: - return bundle.path(forResource: "geocoding-reverse-geocoding", ofType: "json")! - case .forwardGeocoding: - return bundle.path(forResource: "mapbox.places.san.francisco", ofType: "json")! case .multiRetrieve: return bundle.path(forResource: "retrieve-multi", ofType: "json")! case .categoryCafe: return bundle.path(forResource: "category-cafe", ofType: "json")! case .categoryHotelSearchAlongRoute_JP: return bundle.path(forResource: "category-hotel-search-along-route-jp", ofType: "json")! + } + } + + var path: String { + var path = "/search/v1" + + switch self { + case .suggestMinsk: + path += "/suggest/Minsk" + + case .suggestSanFrancisco: + path += "/suggest/San Francisco" + + case .suggestEmpty, + .suggestCategories, + .suggestWithCoordinates, + .suggestWithMixedCoordinates, + .recursion, + .suggestCategoryWithCoordinates: + path += "/suggest/:query" + + case .retrieveSanFrancisco, + .retrieveCategory, + .retrieveMinsk, + .retrievePoi: + path += "/retrieve" + + case .multiRetrieve: + path += "/retrieve/multi" + + case .categoryCafe, + .categoryHotelSearchAlongRoute_JP: + path += "/category/:category" + } + + return path + } + + var httpMethod: HttpServer.HTTPMethod { + switch self { + case .suggestMinsk, + .suggestSanFrancisco, + .suggestEmpty, + .suggestCategories, + .suggestWithCoordinates, + .suggestWithMixedCoordinates, + .suggestCategoryWithCoordinates, + .recursion, + .categoryCafe, + .categoryHotelSearchAlongRoute_JP: + return .get + + case .multiRetrieve, + .retrieveSanFrancisco, + .retrieveCategory, + .retrieveMinsk, + .retrievePoi: + return .post + } + } + + static var coreApiType: CoreSearchEngine.ApiType { + .SBS + } +} + +// MARK: - Autofill + +enum AutofillMockResponse: MockResponse { + case suggestAddressSanFrancisco + case retrieveAddressSanFrancisco + + var filepath: String { + let bundle = Bundle(for: MockWebServer.self) + switch self { + case .retrieveAddressSanFrancisco: + return bundle.path(forResource: "address-retrieve-san-francisco", ofType: "json")! case .suggestAddressSanFrancisco: return bundle.path(forResource: "address-suggestions-san-francisco", ofType: "json")! + } + } + + var path: String { + var path = "/search/v1" + + switch self { + case .suggestAddressSanFrancisco: + path = "/autofill/v1/suggest/:query" + case .retrieveAddressSanFrancisco: - return bundle.path(forResource: "address-retrieve-san-francisco", ofType: "json")! + path = "/autofill/v1/retrieve/:action.id" } + + return path + } + + var httpMethod: HttpServer.HTTPMethod { + switch self { + case .suggestAddressSanFrancisco, + .retrieveAddressSanFrancisco: + return .get + } + } + + static var coreApiType: CoreSearchEngine.ApiType { + .autofill } } diff --git a/Tests/MapboxSearchUITests/MockWebServer/MockWebServer.swift b/Tests/MapboxSearchUITests/MockWebServer/MockWebServer.swift index ce75d9f8f..29d646003 100644 --- a/Tests/MapboxSearchUITests/MockWebServer/MockWebServer.swift +++ b/Tests/MapboxSearchUITests/MockWebServer/MockWebServer.swift @@ -1,14 +1,14 @@ import Foundation import Swifter -final class MockWebServer { +final class MockWebServer { let endpoint = "http://localhost:8080" private let server = HttpServer() - func setResponse(_ response: MockResponse, query: String? = nil, statusCode: Int = 200) throws { - let route = Self.path(for: response) - let method = Self.httpMethod(for: response) + func setResponse(_ response: Mock, query: String? = nil, statusCode: Int = 200) throws { + let route = response.path + let method = response.httpMethod let response = HttpResponse.raw(statusCode, "mocked response", nil) { writer in try writer.write( @@ -25,9 +25,9 @@ final class MockWebServer { } } - func setResponse(endpoint: MockResponse, query: String? = nil, body: String, statusCode: Int) { - let route = Self.path(for: endpoint) - let method = Self.httpMethod(for: endpoint) + func setResponse(endpoint: Mock, query: String? = nil, body: String, statusCode: Int) { + let route = endpoint.path + let method = endpoint.httpMethod let response = HttpResponse.raw(statusCode, "mocked response", nil) { writer in try writer.write(body.data(using: .utf8)!) @@ -51,87 +51,8 @@ final class MockWebServer { } } -// MARK: - private - -extension MockWebServer { - fileprivate enum HTTPMethod { +extension HttpServer { + enum HTTPMethod { case get, post } - - fileprivate static func httpMethod(for response: MockResponse) -> HTTPMethod { - switch response { - case .suggestAddressSanFrancisco, - .retrieveAddressSanFrancisco, - .forwardGeocoding, - .suggestMinsk, - .suggestSanFrancisco, - .suggestEmpty, - .suggestCategories, - .suggestWithCoordinates, - .suggestWithMixedCoordinates, - .suggestCategoryWithCoordinates, - .recursion, - .reverseGeocoding, - .reverseGeocodingSBS, - .categoryCafe, - .categoryHotelSearchAlongRoute_JP: - return .get - - case .multiRetrieve, - .retrieveSanFrancisco, - .retrieveCategory, - .retrieveMinsk, - .retrievePoi: - return .post - } - } - - fileprivate static func path(for response: MockResponse) -> String { - var path = "/search/v1" - - switch response { - case .suggestAddressSanFrancisco: - path = "/autofill/v1/suggest/:query" - - case .retrieveAddressSanFrancisco: - path = "/autofill/v1/retrieve/:action.id" - - case .forwardGeocoding: - path = "/geocoding/v5/mapbox.places/:query" - - case .suggestMinsk: - path += "/suggest/Minsk" - - case .suggestSanFrancisco: - path += "/suggest/San Francisco" - - case .suggestEmpty, - .suggestCategories, - .suggestWithCoordinates, - .suggestWithMixedCoordinates, - .suggestCategoryWithCoordinates, - .recursion: - path += "/suggest/:query" - - case .retrieveSanFrancisco, - .retrieveCategory, - .retrieveMinsk, - .retrievePoi: - path += "/retrieve" - - case .reverseGeocoding: - path = "geocoding/v5/mapbox.places/:location" - - case .reverseGeocodingSBS: - path += "/:coordinates" - - case .multiRetrieve: - path += "/retrieve/multi" - - case .categoryCafe, .categoryHotelSearchAlongRoute_JP: - path += "/category/:category" - } - - return path - } } diff --git a/Tests/MapboxSearchUITests/VisibilityTestCase.swift b/Tests/MapboxSearchUITests/VisibilityTestCase.swift index d3cd54d4d..6b4b61587 100644 --- a/Tests/MapboxSearchUITests/VisibilityTestCase.swift +++ b/Tests/MapboxSearchUITests/VisibilityTestCase.swift @@ -1,11 +1,13 @@ import XCTest -class VisibilityTestCase: BaseTestCase { +class VisibilityTestCase: MockSBSServerUITestCase { override func setUpWithError() throws { try super.setUpWithError() - app.launch() XCUIDevice.shared.orientation = .portrait + + try server.setResponse(.suggestCategories) + try server.setResponse(.retrieveCategory) } func testSearchBarVisibility() throws {