Revision control

1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
import GCDWebServers
6
@testable import Client
7
import UIKit
8
9
import XCTest
10
11
class SearchTests: XCTestCase {
12
func testParsing() {
13
let parser = OpenSearchParser(pluginMode: true)
14
let file = Bundle.main.path(forResource: "google-b-m", ofType: "xml", inDirectory: "SearchPlugins/")
15
let engine: OpenSearchEngine! = parser.parse(file!, engineID: "google-b-m")
16
XCTAssertEqual(engine.shortName, "Google")
17
18
// Test regular search queries.
19
XCTAssertEqual(engine.searchURLForQuery("foobar")!.absoluteString, "https://www.google.com/search?q=foobar&ie=utf-8&oe=utf-8&client=firefox-b-m")
20
21
// Test search suggestion queries.
22
XCTAssertEqual(engine.suggestURLForQuery("foobar")!.absoluteString, "https://www.google.com/complete/search?client=firefox&q=foobar")
23
}
24
25
func testURIFixup() {
26
// Check valid URLs. We can load these after some fixup.
27
checkValidURL("http://www.mozilla.org", afterFixup: "http://www.mozilla.org")
28
checkValidURL("about:", afterFixup: "about:")
29
checkValidURL("about:config", afterFixup: "about:config")
30
checkValidURL("about: config", afterFixup: "about:%20config")
31
checkValidURL("file:///f/o/o", afterFixup: "file:///f/o/o")
32
checkValidURL("ftp://ftp.mozilla.org", afterFixup: "ftp://ftp.mozilla.org")
33
checkValidURL("foo.bar", afterFixup: "http://foo.bar")
34
checkValidURL(" foo.bar ", afterFixup: "http://foo.bar")
35
checkValidURL("1.2.3", afterFixup: "http://1.2.3")
36
37
// Check invalid URLs. These are passed along to the default search engine.
38
checkInvalidURL("foobar")
39
checkInvalidURL("foo bar")
40
checkInvalidURL("mozilla. org")
41
checkInvalidURL("123")
42
checkInvalidURL("a/b")
43
checkInvalidURL("创业咖啡")
44
checkInvalidURL("创业咖啡 中国")
45
checkInvalidURL("创业咖啡. 中国")
46
}
47
48
func testURIFixupPunyCode() {
50
checkValidURL("创业咖啡.中国", afterFixup: "http://xn--vhq70hq9bhxa.xn--fiqs8s")
51
checkValidURL(" 创业咖啡.中国 ", afterFixup: "http://xn--vhq70hq9bhxa.xn--fiqs8s")
52
}
53
54
fileprivate func checkValidURL(_ beforeFixup: String, afterFixup: String) {
55
XCTAssertEqual(URIFixup.getURL(beforeFixup)!.absoluteString, afterFixup)
56
}
57
58
fileprivate func checkInvalidURL(_ beforeFixup: String) {
59
XCTAssertNil(URIFixup.getURL(beforeFixup))
60
}
61
62
func testSuggestClient() {
63
let webServerBase = startMockSuggestServer()
64
let engine = OpenSearchEngine(engineID: "mock", shortName: "Mock engine", image: UIImage(), searchTemplate: "", suggestTemplate: "\(webServerBase)?q={searchTerms}",
65
isCustomEngine: false)
66
let client = SearchSuggestClient(searchEngine: engine, userAgent: "Fx-testSuggestClient")
67
68
let query1 = self.expectation(description: "foo query")
69
client.query("foo", callback: { response, error in
70
withExtendedLifetime(client) {
71
if error != nil {
72
XCTFail("Error: \(error?.description ?? "nil")")
73
}
74
75
XCTAssertEqual(response![0], "foo")
76
XCTAssertEqual(response![1], "foo2")
77
XCTAssertEqual(response![2], "foo you")
78
79
query1.fulfill()
80
}
81
})
82
waitForExpectations(timeout: 10, handler: nil)
83
84
let query2 = self.expectation(description: "foo bar query")
85
client.query("foo bar", callback: { response, error in
86
withExtendedLifetime(client) {
87
if error != nil {
88
XCTFail("Error: \(error?.description ?? "nil")")
89
}
90
91
XCTAssertEqual(response![0], "foo bar soap")
92
XCTAssertEqual(response![1], "foo barstool")
93
XCTAssertEqual(response![2], "foo bartender")
94
95
query2.fulfill()
96
}
97
})
98
waitForExpectations(timeout: 10, handler: nil)
99
}
100
101
func testExtractingOfSearchTermsFromURL() {
102
let parser = OpenSearchParser(pluginMode: true)
103
var file = Bundle.main.path(forResource: "google-b-m", ofType: "xml", inDirectory: "SearchPlugins/")
104
let googleEngine: OpenSearchEngine! = parser.parse(file!, engineID: "google")
105
106
// create URL
107
let searchTerm = "Foo Bar"
108
let encodedSeachTerm = searchTerm.replacingOccurrences(of: " ", with: "+")
110
let duckDuckGoSearchURL = URL(string: "https://duckduckgo.com/?q=\(encodedSeachTerm)&ia=about")
111
let invalidSearchURL = URL(string: "https://www.google.co.uk")
112
113
// check it correctly matches google search term given google config
114
XCTAssertEqual(searchTerm, googleEngine.queryForSearchURL(googleSearchURL))
115
116
// check it doesn't match when the URL is not a search URL
117
XCTAssertNil(googleEngine.queryForSearchURL(invalidSearchURL))
118
119
// check that it matches given a different configuration
120
file = Bundle.main.path(forResource: "duckduckgo", ofType: "xml", inDirectory: "SearchPlugins/")
121
let duckDuckGoEngine: OpenSearchEngine! = parser.parse(file!, engineID: "duckduckgo")
122
XCTAssertEqual(searchTerm, duckDuckGoEngine.queryForSearchURL(duckDuckGoSearchURL))
123
124
// check it doesn't match search URLs for different configurations
125
XCTAssertNil(duckDuckGoEngine.queryForSearchURL(googleSearchURL))
126
127
// check that if you pass in a nil URL that everything works
128
XCTAssertNil(duckDuckGoEngine.queryForSearchURL(nil))
129
}
130
131
fileprivate func startMockSuggestServer() -> String {
132
let webServer: GCDWebServer = GCDWebServer()
133
134
webServer.addHandler(forMethod: "GET", path: "/", request: GCDWebServerRequest.self) { (request) -> GCDWebServerResponse? in
135
var suggestions: [String]!
136
let query = request.query!["q"]!
137
switch query {
138
case "foo":
139
suggestions = ["foo", "foo2", "foo you"]
140
case "foo bar":
141
suggestions = ["foo bar soap", "foo barstool", "foo bartender"]
142
default:
143
XCTFail("Unexpected query: \(query)")
144
}
145
return GCDWebServerDataResponse(jsonObject: [query, suggestions as Any])
146
}
147
148
if !webServer.start(withPort: 0, bonjourName: nil) {
149
XCTFail("Can't start the GCDWebServer")
150
}
151
153
}
154
}