michael@0: function getPostDataString(aIS) { michael@0: if (!aIS) michael@0: return null; michael@0: michael@0: var sis = Cc["@mozilla.org/scriptableinputstream;1"]. michael@0: createInstance(Ci.nsIScriptableInputStream); michael@0: sis.init(aIS); michael@0: var dataLines = sis.read(aIS.available()).split("\n"); michael@0: michael@0: // only want the last line michael@0: return dataLines[dataLines.length-1]; michael@0: } michael@0: michael@0: function keywordResult(aURL, aPostData, aIsUnsafe) { michael@0: this.url = aURL; michael@0: this.postData = aPostData; michael@0: this.isUnsafe = aIsUnsafe; michael@0: } michael@0: michael@0: function keyWordData() {} michael@0: keyWordData.prototype = { michael@0: init: function(aKeyWord, aURL, aPostData, aSearchWord) { michael@0: this.keyword = aKeyWord; michael@0: this.uri = makeURI(aURL); michael@0: this.postData = aPostData; michael@0: this.searchWord = aSearchWord; michael@0: michael@0: this.method = (this.postData ? "POST" : "GET"); michael@0: } michael@0: } michael@0: michael@0: function bmKeywordData(aKeyWord, aURL, aPostData, aSearchWord) { michael@0: this.init(aKeyWord, aURL, aPostData, aSearchWord); michael@0: } michael@0: bmKeywordData.prototype = new keyWordData(); michael@0: michael@0: function searchKeywordData(aKeyWord, aURL, aPostData, aSearchWord) { michael@0: this.init(aKeyWord, aURL, aPostData, aSearchWord); michael@0: } michael@0: searchKeywordData.prototype = new keyWordData(); michael@0: michael@0: var testData = [ michael@0: [new bmKeywordData("bmget", "http://bmget/search=%s", null, "foo"), michael@0: new keywordResult("http://bmget/search=foo", null)], michael@0: michael@0: [new bmKeywordData("bmpost", "http://bmpost/", "search=%s", "foo2"), michael@0: new keywordResult("http://bmpost/", "search=foo2")], michael@0: michael@0: [new bmKeywordData("bmpostget", "http://bmpostget/search1=%s", "search2=%s", "foo3"), michael@0: new keywordResult("http://bmpostget/search1=foo3", "search2=foo3")], michael@0: michael@0: [new bmKeywordData("bmget-nosearch", "http://bmget-nosearch/", null, ""), michael@0: new keywordResult("http://bmget-nosearch/", null)], michael@0: michael@0: [new searchKeywordData("searchget", "http://searchget/?search={searchTerms}", null, "foo4"), michael@0: new keywordResult("http://searchget/?search=foo4", null, true)], michael@0: michael@0: [new searchKeywordData("searchpost", "http://searchpost/", "search={searchTerms}", "foo5"), michael@0: new keywordResult("http://searchpost/", "search=foo5", true)], michael@0: michael@0: [new searchKeywordData("searchpostget", "http://searchpostget/?search1={searchTerms}", "search2={searchTerms}", "foo6"), michael@0: new keywordResult("http://searchpostget/?search1=foo6", "search2=foo6", true)], michael@0: michael@0: // Bookmark keywords that don't take parameters should not be activated if a michael@0: // parameter is passed (bug 420328). michael@0: [new bmKeywordData("bmget-noparam", "http://bmget-noparam/", null, "foo7"), michael@0: new keywordResult(null, null, true)], michael@0: [new bmKeywordData("bmpost-noparam", "http://bmpost-noparam/", "not_a=param", "foo8"), michael@0: new keywordResult(null, null, true)], michael@0: michael@0: // Test escaping (%s = escaped, %S = raw) michael@0: // UTF-8 default michael@0: [new bmKeywordData("bmget-escaping", "http://bmget/?esc=%s&raw=%S", null, "foé"), michael@0: new keywordResult("http://bmget/?esc=fo%C3%A9&raw=foé", null)], michael@0: // Explicitly-defined ISO-8859-1 michael@0: [new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "foé"), michael@0: new keywordResult("http://bmget/?esc=fo%E9&raw=foé", null)], michael@0: michael@0: // Bug 359809: Test escaping +, /, and @ michael@0: // UTF-8 default michael@0: [new bmKeywordData("bmget-escaping", "http://bmget/?esc=%s&raw=%S", null, "+/@"), michael@0: new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)], michael@0: // Explicitly-defined ISO-8859-1 michael@0: [new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "+/@"), michael@0: new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)], michael@0: michael@0: // Test using a non-bmKeywordData object, to test the behavior of michael@0: // getShortcutOrURIAndPostData for non-keywords (setupKeywords only adds keywords for michael@0: // bmKeywordData objects) michael@0: [{keyword: "http://gavinsharp.com"}, michael@0: new keywordResult(null, null, true)] michael@0: ]; michael@0: michael@0: function test() { michael@0: waitForExplicitFinish(); michael@0: michael@0: setupKeywords(); michael@0: michael@0: Task.spawn(function() { michael@0: for each (var item in testData) { michael@0: let [data, result] = item; michael@0: michael@0: let query = data.keyword; michael@0: if (data.searchWord) michael@0: query += " " + data.searchWord; michael@0: let returnedData = yield new Promise( michael@0: resolve => getShortcutOrURIAndPostData(query, resolve)); michael@0: // null result.url means we should expect the same query we sent in michael@0: let expected = result.url || query; michael@0: is(returnedData.url, expected, "got correct URL for " + data.keyword); michael@0: is(getPostDataString(returnedData.postData), result.postData, "got correct postData for " + data.keyword); michael@0: is(returnedData.mayInheritPrincipal, !result.isUnsafe, "got correct mayInheritPrincipal for " + data.keyword); michael@0: } michael@0: cleanupKeywords(); michael@0: }).then(finish); michael@0: } michael@0: michael@0: var gBMFolder = null; michael@0: var gAddedEngines = []; michael@0: function setupKeywords() { michael@0: gBMFolder = Application.bookmarks.menu.addFolder("keyword-test"); michael@0: for each (var item in testData) { michael@0: var data = item[0]; michael@0: if (data instanceof bmKeywordData) { michael@0: var bm = gBMFolder.addBookmark(data.keyword, data.uri); michael@0: bm.keyword = data.keyword; michael@0: if (data.postData) michael@0: bm.annotations.set("bookmarkProperties/POSTData", data.postData, Ci.nsIAnnotationService.EXPIRE_SESSION); michael@0: } michael@0: michael@0: if (data instanceof searchKeywordData) { michael@0: Services.search.addEngineWithDetails(data.keyword, "", data.keyword, "", data.method, data.uri.spec); michael@0: var addedEngine = Services.search.getEngineByName(data.keyword); michael@0: if (data.postData) { michael@0: var [paramName, paramValue] = data.postData.split("="); michael@0: addedEngine.addParam(paramName, paramValue, null); michael@0: } michael@0: michael@0: gAddedEngines.push(addedEngine); michael@0: } michael@0: } michael@0: } michael@0: michael@0: function cleanupKeywords() { michael@0: gBMFolder.remove(); michael@0: gAddedEngines.map(Services.search.removeEngine); michael@0: }