mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-18 13:17:29 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
7
toolkit/components/places/tests/unit/.eslintrc.js
Normal file
7
toolkit/components/places/tests/unit/.eslintrc.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
|
||||
]
|
||||
};
|
||||
36
toolkit/components/places/tests/unit/bookmarks.corrupt.html
Normal file
36
toolkit/components/places/tests/unit/bookmarks.corrupt.html
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<!-- This is an automatically generated file.
|
||||
It will be read and overwritten.
|
||||
DO NOT EDIT! -->
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
||||
<TITLE>Bookmarks</TITLE>
|
||||
<H1 LAST_MODIFIED="1177541029">Bookmarks</H1>
|
||||
|
||||
<DL><p>
|
||||
<DT><H3 ID="rdf:#$ZvPhC3">Mozilla Firefox</H3>
|
||||
<DL><p>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/firefox/help/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$22iCK1">Help and Tutorials</A>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/firefox/customize/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$32iCK1">Customize Firefox</A>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/firefox/community/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$42iCK1">Get Involved</A>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/about/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$52iCK1">About Us</A>
|
||||
<DT><A HREF="b0rked" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$52iCK1">About Us</A>
|
||||
</DL><p>
|
||||
<DT><H3 ADD_DATE="1177541020" LAST_MODIFIED="1177541050" ID="rdf:#$74Gpx2">test</H3>
|
||||
<DD>folder test comment
|
||||
<DL><p>
|
||||
<DT><A HREF="http://test/post" ADD_DATE="1177375336" LAST_MODIFIED="1177375423" SHORTCUTURL="test" WEB_PANEL="true" POST_DATA="hidden1%3Dbar&text1%3D%25s" LAST_CHARSET="ISO-8859-1" ID="rdf:#$pYFe7">test post keyword</A>
|
||||
<DD>item description
|
||||
</DL>
|
||||
<DT><H3 UNFILED_BOOKMARKS_FOLDER="true">Unsorted Bookmarks</H3>
|
||||
<DL><p>
|
||||
<DT><A HREF="http://example.tld">Example.tld</A>
|
||||
</DL><p>
|
||||
<DT><H3 LAST_MODIFIED="1177541040" PERSONAL_TOOLBAR_FOLDER="true" ID="rdf:#$FvPhC3">Bookmarks Toolbar Folder</H3>
|
||||
<DD>Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar
|
||||
<DL><p>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/firefox/central/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$GvPhC3">Getting Started</A>
|
||||
<DT><A HREF="http://en-US.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/" LAST_MODIFIED="1177541035" FEEDURL="http://en-US.fxfeeds.mozilla.com/en-US/firefox/headlines.xml" ID="rdf:#$HvPhC3">Latest Headlines</A>
|
||||
<DT><A HREF="http://bogus-icon.mozilla.com/" ICON="b0rked" ID="rdf:#$GvPhC3">Getting Started</A>
|
||||
<DD>Livemark test comment
|
||||
</DL><p>
|
||||
</DL><p>
|
||||
1
toolkit/components/places/tests/unit/bookmarks.json
Normal file
1
toolkit/components/places/tests/unit/bookmarks.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<!-- This is an automatically generated file.
|
||||
It will be read and overwritten.
|
||||
DO NOT EDIT! -->
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
||||
<TITLE>Bookmarks</TITLE>
|
||||
<H1 LAST_MODIFIED="1177541029">Bookmarks</H1>
|
||||
|
||||
<DL><p>
|
||||
<DT><H3 ID="rdf:#$ZvPhC3">Mozilla Firefox</H3>
|
||||
<DL><p>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/firefox/help/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$22iCK1">Help and Tutorials</A>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/firefox/customize/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$32iCK1">Customize Firefox</A>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/firefox/community/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$42iCK1">Get Involved</A>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/about/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$52iCK1">About Us</A>
|
||||
</DL><p>
|
||||
<HR>
|
||||
<DT><H3 ADD_DATE="1177541020" LAST_MODIFIED="1177541050" ID="rdf:#$74Gpx2">test</H3>
|
||||
<DD>folder test comment
|
||||
<DL><p>
|
||||
<DT><A HREF="http://test/post" ADD_DATE="1177375336" LAST_MODIFIED="1177375423" SHORTCUTURL="test" WEB_PANEL="true" POST_DATA="hidden1%3Dbar&text1%3D%25s" LAST_CHARSET="ISO-8859-1" ID="rdf:#$pYFe7">test post keyword</A>
|
||||
<DD>item description
|
||||
</DL>
|
||||
<DT><H3 UNFILED_BOOKMARKS_FOLDER="true">Unsorted Bookmarks</H3>
|
||||
<DL><p>
|
||||
<DT><A HREF="http://example.tld">Example.tld</A>
|
||||
</DL><p>
|
||||
<DT><H3 LAST_MODIFIED="1177541040" PERSONAL_TOOLBAR_FOLDER="true" ID="rdf:#$FvPhC3">Bookmarks Toolbar Folder</H3>
|
||||
<DD>Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar
|
||||
<DL><p>
|
||||
<DT><A HREF="http://en-US.www.mozilla.com/en-US/firefox/central/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$GvPhC3">Getting Started</A>
|
||||
<DT><A HREF="http://en-US.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/" LAST_MODIFIED="1177541035" FEEDURL="http://en-US.fxfeeds.mozilla.com/en-US/firefox/headlines.xml" ID="rdf:#$HvPhC3">Latest Headlines</A>
|
||||
<DD>Livemark test comment
|
||||
</DL><p>
|
||||
</DL><p>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<HTML>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
||||
<Title>Bookmarks</Title>
|
||||
<H1>Bookmarks</H1>
|
||||
<DT><H3>Subtitle</H3>
|
||||
<DL><p>
|
||||
<DT><A HREF="http://www.mozilla.org/">Mozilla</A>
|
||||
</DL><p>
|
||||
</HTML>
|
||||
BIN
toolkit/components/places/tests/unit/bug476292.sqlite
Normal file
BIN
toolkit/components/places/tests/unit/bug476292.sqlite
Normal file
Binary file not shown.
BIN
toolkit/components/places/tests/unit/corruptDB.sqlite
Normal file
BIN
toolkit/components/places/tests/unit/corruptDB.sqlite
Normal file
Binary file not shown.
BIN
toolkit/components/places/tests/unit/default.sqlite
Normal file
BIN
toolkit/components/places/tests/unit/default.sqlite
Normal file
Binary file not shown.
20
toolkit/components/places/tests/unit/head_bookmarks.js
Normal file
20
toolkit/components/places/tests/unit/head_bookmarks.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var Ci = Components.interfaces;
|
||||
var Cc = Components.classes;
|
||||
var Cr = Components.results;
|
||||
var Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Import common head.
|
||||
{
|
||||
let commonFile = do_get_file("../head_common.js", false);
|
||||
let uri = Services.io.newFileURI(commonFile);
|
||||
Services.scriptloader.loadSubScript(uri.spec, this);
|
||||
}
|
||||
|
||||
// Put any other stuff relative to this test folder below.
|
||||
17
toolkit/components/places/tests/unit/livemark.xml
Normal file
17
toolkit/components/places/tests/unit/livemark.xml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Livemark Feed</title>
|
||||
<link href="https://example.com/"/>
|
||||
<updated>2016-08-09T19:51:45.147Z</updated>
|
||||
<author>
|
||||
<name>John Doe</name>
|
||||
</author>
|
||||
<id>urn:uuid:e7947414-6ee0-4009-ae75-8b0ad3c6894b</id>
|
||||
<entry>
|
||||
<title>Some awesome article</title>
|
||||
<link href="https://example.com/some-article"/>
|
||||
<id>urn:uuid:d72ce019-0a56-4a0b-ac03-f66117d78141</id>
|
||||
<updated>2016-08-09T19:57:22.178Z</updated>
|
||||
<summary>My great article summary.</summary>
|
||||
</entry>
|
||||
</feed>
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"guid":"root________","title":"","index":0,"dateAdded":1475084731479000,"lastModified":1475084731479000,"id":1,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"guid":"menu________","title":"Bookmarks Menu","index":0,"dateAdded":1475084731479000,"lastModified":1475084731768000,"id":2,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"guid":"X6lUyOspVYwi","title":"Test Pilot","index":0,"dateAdded":1475084731768000,"lastModified":1475084731768000,"id":3,"type":"text/x-moz-place","uri":"https://testpilot.firefox.com/"},{"guid":"XF4yRP6bTuil","title":"Mobile bookmarks query","index":1,"dateAdded":1475084731768000,"lastModified":1475084731768000,"id":11,"type":"text/x-moz-place","uri":"place:folder=101"}]},{"guid":"toolbar_____","title":"Bookmarks Toolbar","index":1,"dateAdded":1475084731479000,"lastModified":1475084731742000,"id":4,"type":"text/x-moz-place-container","root":"toolbarFolder","children":[{"guid":"buy7711R3ZgE","title":"MDN","index":0,"dateAdded":1475084731769000,"lastModified":1475084731769000,"id":5,"type":"text/x-moz-place","uri":"https://developer.mozilla.org"}]},{"guid":"3qmd_imziEBE","title":"Mobile Bookmarks","index":5,"dateAdded":1475084731479000,"lastModified":1475084731770000,"id":101,"annos":[{"name":"mobile/bookmarksRoot","flags":0,"expires":4,"value":1},{"name":"bookmarkProperties/description","flags":0,"expires":4,"mimeType":null,"type":3,"value":"A description of the mobile folder that should be ignored on import"}],"type":"text/x-moz-place-container","children":[{"guid":"_o8e1_zxTJFg","title":"Get Firefox!","index":0,"dateAdded":1475084731769000,"lastModified":1475084731769000,"id":7,"type":"text/x-moz-place","uri":"http://getfirefox.com/"},{"guid":"QCtSqkVYUbXB","title":"Get Thunderbird!","index":1,"dateAdded":1475084731770000,"lastModified":1475084731770000,"id":8,"type":"text/x-moz-place","uri":"http://getthunderbird.com/"}]},{"guid":"unfiled_____","title":"Other Bookmarks","index":3,"dateAdded":1475084731479000,"lastModified":1475084731742000,"id":9,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder","children":[{"guid":"KIa9iKZab2Z5","title":"Add-ons","index":0,"dateAdded":1475084731769000,"lastModified":1475084731769000,"id":10,"type":"text/x-moz-place","uri":"https://addons.mozilla.org"}]}]}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"guid":"root________","title":"","index":0,"dateAdded":1475084731479000,"lastModified":1475084731479000,"id":1,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"guid":"menu________","title":"Bookmarks Menu","index":0,"dateAdded":1475084731479000,"lastModified":1475084731768000,"id":2,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"guid":"Utodo9b0oVws","title":"Firefox Accounts","index":0,"dateAdded":1475084731955000,"lastModified":1475084731955000,"id":3,"type":"text/x-moz-place","uri":"https://accounts.firefox.com/"}]},{"guid":"toolbar_____","title":"Bookmarks Toolbar","index":1,"dateAdded":1475084731479000,"lastModified":1475084731742000,"id":4,"type":"text/x-moz-place-container","root":"toolbarFolder"},{"guid":"3qmd_imziEBE","title":"Mobile Bookmarks","index":5,"dateAdded":1475084731479000,"lastModified":1475084731770000,"id":5,"annos":[{"name":"mobile/bookmarksRoot","flags":0,"expires":4,"value":1},{"name":"bookmarkProperties/description","flags":0,"expires":4,"mimeType":null,"type":3,"value":"A description of the mobile folder that should be ignored on import"}],"type":"text/x-moz-place-container","children":[{"guid":"a17yW6-nTxEJ","title":"Mozilla","index":0,"dateAdded":1475084731959000,"lastModified":1475084731959000,"id":6,"type":"text/x-moz-place","uri":"https://mozilla.org/"},{"guid":"xV10h9Wi3FBM","title":"Bugzilla","index":1,"dateAdded":1475084731961000,"lastModified":1475084731961000,"id":7,"type":"text/x-moz-place","uri":"https://bugzilla.mozilla.org/"}]},{"guid":"unfiled_____","title":"Other Bookmarks","index":3,"dateAdded":1475084731479000,"lastModified":1475084731742000,"id":8,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder"}]}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"guid":"root________","title":"","index":0,"dateAdded":1475084731479000,"lastModified":1475084731479000,"id":1,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"guid":"menu________","title":"Bookmarks Menu","index":0,"dateAdded":1475084731479000,"lastModified":1475084731768000,"id":2,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"guid":"buy7711R3ZgE","title":"MDN","index":0,"dateAdded":1475084731769000,"lastModified":1475084731769000,"id":3,"type":"text/x-moz-place","uri":"https://developer.mozilla.org"},{"guid":"F_LBgd1fS_uQ","title":"Mobile bookmarks query for first folder","index":1,"dateAdded":1475084731768000,"lastModified":1475084731768000,"id":11,"type":"text/x-moz-place","uri":"place:folder=101"},{"guid":"oIpmQXMWsXvY","title":"Mobile bookmarks query for second folder","index":2,"dateAdded":1475084731768000,"lastModified":1475084731768000,"id":12,"type":"text/x-moz-place","uri":"place:folder=102"}]},{"guid":"3qmd_imziEBE","title":"Mobile Bookmarks","index":5,"dateAdded":1475084731479000,"lastModified":1475084731770000,"id":101,"annos":[{"name":"mobile/bookmarksRoot","flags":0,"expires":4,"value":1},{"name":"bookmarkProperties/description","flags":0,"expires":4,"mimeType":null,"type":3,"value":"A description of the mobile folder that should be ignored on import"}],"type":"text/x-moz-place-container","children":[{"guid":"a17yW6-nTxEJ","title":"Mozilla","index":0,"dateAdded":1475084731959000,"lastModified":1475084731959000,"id":5,"type":"text/x-moz-place","uri":"https://mozilla.org/"}]},{"guid":"toolbar_____","title":"Bookmarks Toolbar","index":1,"dateAdded":1475084731479000,"lastModified":1475084731742000,"id":6,"type":"text/x-moz-place-container","root":"toolbarFolder","children":[{"guid":"Utodo9b0oVws","title":"Firefox Accounts","index":0,"dateAdded":1475084731955000,"lastModified":1475084731955000,"id":7,"type":"text/x-moz-place","uri":"https://accounts.firefox.com/"}]},{"guid":"o4YjJpgsufU-","title":"Mobile Bookmarks","index":7,"dateAdded":1475084731479000,"lastModified":1475084731770000,"id":102,"annos":[{"name":"mobile/bookmarksRoot","flags":0,"expires":4,"value":1}],"type":"text/x-moz-place-container","children":[{"guid":"sSZ86WT9WbN3","title":"DXR","index":0,"dateAdded":1475084731769000,"lastModified":1475084731769000,"id":9,"type":"text/x-moz-place","uri":"https://dxr.mozilla.org"}]},{"guid":"unfiled_____","title":"Other Bookmarks","index":3,"dateAdded":1475084731479000,"lastModified":1475084731742000,"id":10,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder","children":[{"guid":"xV10h9Wi3FBM","title":"Bugzilla","index":1,"dateAdded":1475084731961000,"lastModified":1475084731961000,"id":11,"type":"text/x-moz-place","uri":"https://bugzilla.mozilla.org/"}]}]}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"guid":"root________","title":"","index":0,"dateAdded":1475084731479000,"lastModified":1475084731479000,"id":1,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"guid":"menu________","title":"Bookmarks Menu","index":0,"dateAdded":1475084731479000,"lastModified":1475084731768000,"id":2,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"guid":"X6lUyOspVYwi","title":"Test Pilot","index":0,"dateAdded":1475084731768000,"lastModified":1475084731768000,"id":3,"type":"text/x-moz-place","uri":"https://testpilot.firefox.com/"}]},{"guid":"toolbar_____","title":"Bookmarks Toolbar","index":1,"dateAdded":1475084731479000,"lastModified":1475084731742000,"id":4,"type":"text/x-moz-place-container","root":"toolbarFolder"},{"guid":"unfiled_____","title":"Other Bookmarks","index":3,"dateAdded":1475084731479000,"lastModified":1475084731742000,"id":5,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder"},{"guid":"mobile______","title":"Mobile Bookmarks","index":4,"dateAdded":1475084731479000,"lastModified":1475084731770000,"id":6,"annos":[{"name":"mobile/bookmarksRoot","flags":0,"expires":4,"value":1}],"type":"text/x-moz-place-container","root":"mobileFolder","children":[{"guid":"_o8e1_zxTJFg","title":"Get Firefox!","index":0,"dateAdded":1475084731769000,"lastModified":1475084731769000,"id":7,"type":"text/x-moz-place","uri":"http://getfirefox.com/"},{"guid":"QCtSqkVYUbXB","title":"Get Thunderbird!","index":1,"dateAdded":1475084731770000,"lastModified":1475084731770000,"id":8,"type":"text/x-moz-place","uri":"http://getthunderbird.com/"}]}]}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"guid":"root________","title":"","index":0,"dateAdded":1475084731479000,"lastModified":1475084731479000,"id":1,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"guid":"menu________","title":"Bookmarks Menu","index":0,"dateAdded":1475084731479000,"lastModified":1475084731955000,"id":2,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"guid":"Utodo9b0oVws","title":"Firefox Accounts","index":0,"dateAdded":1475084731955000,"lastModified":1475084731955000,"id":3,"type":"text/x-moz-place","uri":"https://accounts.firefox.com/"}]},{"guid":"toolbar_____","title":"Bookmarks Toolbar","index":1,"dateAdded":1475084731479000,"lastModified":1475084731938000,"id":4,"type":"text/x-moz-place-container","root":"toolbarFolder"},{"guid":"unfiled_____","title":"Other Bookmarks","index":3,"dateAdded":1475084731479000,"lastModified":1475084731938000,"id":5,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder"},{"guid":"mobile______","title":"Mobile Bookmarks","index":4,"dateAdded":1475084731479000,"lastModified":1475084731961000,"id":6,"annos":[{"name":"mobile/bookmarksRoot","flags":0,"expires":4,"value":1}],"type":"text/x-moz-place-container","root":"mobileFolder","children":[{"guid":"a17yW6-nTxEJ","title":"Mozilla","index":0,"dateAdded":1475084731959000,"lastModified":1475084731959000,"id":7,"type":"text/x-moz-place","uri":"https://mozilla.org/"},{"guid":"xV10h9Wi3FBM","title":"Bugzilla","index":1,"dateAdded":1475084731961000,"lastModified":1475084731961000,"id":8,"type":"text/x-moz-place","uri":"https://bugzilla.mozilla.org/"}]}]}
|
||||
48
toolkit/components/places/tests/unit/nsDummyObserver.js
Normal file
48
toolkit/components/places/tests/unit/nsDummyObserver.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
// Dummy boomark/history observer
|
||||
function DummyObserver() {
|
||||
Services.obs.notifyObservers(null, "dummy-observer-created", null);
|
||||
}
|
||||
|
||||
DummyObserver.prototype = {
|
||||
// history observer
|
||||
onBeginUpdateBatch: function () {},
|
||||
onEndUpdateBatch: function () {},
|
||||
onVisit: function (aURI, aVisitID, aTime, aSessionID, aReferringID, aTransitionType) {
|
||||
Services.obs.notifyObservers(null, "dummy-observer-visited", null);
|
||||
},
|
||||
onTitleChanged: function () {},
|
||||
onDeleteURI: function () {},
|
||||
onClearHistory: function () {},
|
||||
onPageChanged: function () {},
|
||||
onDeleteVisits: function () {},
|
||||
|
||||
// bookmark observer
|
||||
// onBeginUpdateBatch: function() {},
|
||||
// onEndUpdateBatch: function() {},
|
||||
onItemAdded: function(aItemId, aParentId, aIndex, aItemType, aURI) {
|
||||
Services.obs.notifyObservers(null, "dummy-observer-item-added", null);
|
||||
},
|
||||
onItemChanged: function () {},
|
||||
onItemRemoved: function() {},
|
||||
onItemVisited: function() {},
|
||||
onItemMoved: function() {},
|
||||
|
||||
classID: Components.ID("62e221d3-68c3-4e1a-8943-a27beb5005fe"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsINavBookmarkObserver,
|
||||
Ci.nsINavHistoryObserver,
|
||||
])
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DummyObserver]);
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
component 62e221d3-68c3-4e1a-8943-a27beb5005fe nsDummyObserver.js
|
||||
contract @mozilla.org/places/test/dummy-observer;1 62e221d3-68c3-4e1a-8943-a27beb5005fe
|
||||
category bookmark-observers nsDummyObserver @mozilla.org/places/test/dummy-observer;1
|
||||
category history-observers nsDummyObserver @mozilla.org/places/test/dummy-observer;1
|
||||
BIN
toolkit/components/places/tests/unit/places.sparse.sqlite
Normal file
BIN
toolkit/components/places/tests/unit/places.sparse.sqlite
Normal file
Binary file not shown.
273
toolkit/components/places/tests/unit/test_000_frecency.js
Normal file
273
toolkit/components/places/tests/unit/test_000_frecency.js
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
|
||||
Autocomplete Frecency Tests
|
||||
|
||||
- add a visit for each score permutation
|
||||
- search
|
||||
- test number of matches
|
||||
- test each item's location in results
|
||||
|
||||
*/
|
||||
|
||||
try {
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get services\n");
|
||||
}
|
||||
|
||||
var bucketPrefs = [
|
||||
[ "firstBucketCutoff", "firstBucketWeight"],
|
||||
[ "secondBucketCutoff", "secondBucketWeight"],
|
||||
[ "thirdBucketCutoff", "thirdBucketWeight"],
|
||||
[ "fourthBucketCutoff", "fourthBucketWeight"],
|
||||
[ null, "defaultBucketWeight"]
|
||||
];
|
||||
|
||||
var bonusPrefs = {
|
||||
embedVisitBonus: Ci.nsINavHistoryService.TRANSITION_EMBED,
|
||||
framedLinkVisitBonus: Ci.nsINavHistoryService.TRANSITION_FRAMED_LINK,
|
||||
linkVisitBonus: Ci.nsINavHistoryService.TRANSITION_LINK,
|
||||
typedVisitBonus: Ci.nsINavHistoryService.TRANSITION_TYPED,
|
||||
bookmarkVisitBonus: Ci.nsINavHistoryService.TRANSITION_BOOKMARK,
|
||||
downloadVisitBonus: Ci.nsINavHistoryService.TRANSITION_DOWNLOAD,
|
||||
permRedirectVisitBonus: Ci.nsINavHistoryService.TRANSITION_REDIRECT_PERMANENT,
|
||||
tempRedirectVisitBonus: Ci.nsINavHistoryService.TRANSITION_REDIRECT_TEMPORARY,
|
||||
reloadVisitBonus: Ci.nsINavHistoryService.TRANSITION_RELOAD,
|
||||
};
|
||||
|
||||
// create test data
|
||||
var searchTerm = "frecency";
|
||||
var results = [];
|
||||
var matchCount = 0;
|
||||
var now = Date.now();
|
||||
var prefPrefix = "places.frecency.";
|
||||
|
||||
function* task_initializeBucket(bucket) {
|
||||
let [cutoffName, weightName] = bucket;
|
||||
// get pref values
|
||||
var weight = 0, cutoff = 0;
|
||||
try {
|
||||
weight = prefs.getIntPref(prefPrefix + weightName);
|
||||
} catch (ex) {}
|
||||
try {
|
||||
cutoff = prefs.getIntPref(prefPrefix + cutoffName);
|
||||
} catch (ex) {}
|
||||
|
||||
if (cutoff < 1)
|
||||
return;
|
||||
|
||||
// generate a date within the cutoff period
|
||||
var dateInPeriod = (now - ((cutoff - 1) * 86400 * 1000)) * 1000;
|
||||
|
||||
for (let [bonusName, visitType] of Object.entries(bonusPrefs)) {
|
||||
var frecency = -1;
|
||||
var calculatedURI = null;
|
||||
var matchTitle = "";
|
||||
var bonusValue = prefs.getIntPref(prefPrefix + bonusName);
|
||||
// unvisited (only for first cutoff date bucket)
|
||||
if (bonusName == "unvisitedBookmarkBonus" || bonusName == "unvisitedTypedBonus") {
|
||||
if (cutoffName == "firstBucketCutoff") {
|
||||
let points = Math.ceil(bonusValue / parseFloat(100.0) * weight);
|
||||
var visitCount = 1; // bonusName == "unvisitedBookmarkBonus" ? 1 : 0;
|
||||
frecency = Math.ceil(visitCount * points);
|
||||
calculatedURI = uri("http://" + searchTerm + ".com/" +
|
||||
bonusName + ":" + bonusValue + "/cutoff:" + cutoff +
|
||||
"/weight:" + weight + "/frecency:" + frecency);
|
||||
if (bonusName == "unvisitedBookmarkBonus") {
|
||||
matchTitle = searchTerm + "UnvisitedBookmark";
|
||||
bmsvc.insertBookmark(bmsvc.unfiledBookmarksFolder, calculatedURI, bmsvc.DEFAULT_INDEX, matchTitle);
|
||||
}
|
||||
else {
|
||||
matchTitle = searchTerm + "UnvisitedTyped";
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: calculatedURI,
|
||||
title: matchTitle,
|
||||
transition: visitType,
|
||||
visitDate: now
|
||||
});
|
||||
histsvc.markPageAsTyped(calculatedURI);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// visited
|
||||
// visited bookmarks get the visited bookmark bonus twice
|
||||
if (visitType == Ci.nsINavHistoryService.TRANSITION_BOOKMARK)
|
||||
bonusValue = bonusValue * 2;
|
||||
|
||||
let points = Math.ceil(1 * ((bonusValue / parseFloat(100.000000)).toFixed(6) * weight) / 1);
|
||||
if (!points) {
|
||||
if (visitType == Ci.nsINavHistoryService.TRANSITION_EMBED ||
|
||||
visitType == Ci.nsINavHistoryService.TRANSITION_FRAMED_LINK ||
|
||||
visitType == Ci.nsINavHistoryService.TRANSITION_DOWNLOAD ||
|
||||
visitType == Ci.nsINavHistoryService.TRANSITION_RELOAD ||
|
||||
bonusName == "defaultVisitBonus")
|
||||
frecency = 0;
|
||||
else
|
||||
frecency = -1;
|
||||
}
|
||||
else
|
||||
frecency = points;
|
||||
calculatedURI = uri("http://" + searchTerm + ".com/" +
|
||||
bonusName + ":" + bonusValue + "/cutoff:" + cutoff +
|
||||
"/weight:" + weight + "/frecency:" + frecency);
|
||||
if (visitType == Ci.nsINavHistoryService.TRANSITION_BOOKMARK) {
|
||||
matchTitle = searchTerm + "Bookmarked";
|
||||
bmsvc.insertBookmark(bmsvc.unfiledBookmarksFolder, calculatedURI, bmsvc.DEFAULT_INDEX, matchTitle);
|
||||
}
|
||||
else
|
||||
matchTitle = calculatedURI.spec.substr(calculatedURI.spec.lastIndexOf("/")+1);
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: calculatedURI,
|
||||
transition: visitType,
|
||||
visitDate: dateInPeriod
|
||||
});
|
||||
}
|
||||
|
||||
if (calculatedURI && frecency) {
|
||||
results.push([calculatedURI, frecency, matchTitle]);
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: calculatedURI,
|
||||
title: matchTitle,
|
||||
transition: visitType,
|
||||
visitDate: dateInPeriod
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
add_task(function* test_frecency()
|
||||
{
|
||||
// Disable autoFill for this test.
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill", false);
|
||||
do_register_cleanup(() => Services.prefs.clearUserPref("browser.urlbar.autoFill"));
|
||||
for (let bucket of bucketPrefs) {
|
||||
yield task_initializeBucket(bucket);
|
||||
}
|
||||
|
||||
// sort results by frecency
|
||||
results.sort((a, b) => b[1] - a[1]);
|
||||
// Make sure there's enough results returned
|
||||
prefs.setIntPref("browser.urlbar.maxRichResults", results.length);
|
||||
|
||||
// DEBUG
|
||||
// results.every(function(el) { dump("result: " + el[1] + ": " + el[0].spec + " (" + el[2] + ")\n"); return true; })
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
|
||||
controller.input = input;
|
||||
|
||||
// always search in history + bookmarks, no matter what the default is
|
||||
prefs.setIntPref("browser.urlbar.search.sources", 3);
|
||||
prefs.setIntPref("browser.urlbar.default.behavior", 0);
|
||||
|
||||
var numSearchesStarted = 0;
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
};
|
||||
|
||||
let deferred = Promise.defer();
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
|
||||
// test that all records with non-zero frecency were matched
|
||||
do_check_eq(controller.matchCount, results.length);
|
||||
|
||||
// test that matches are sorted by frecency
|
||||
for (var i = 0; i < controller.matchCount; i++) {
|
||||
let searchURL = controller.getValueAt(i);
|
||||
let expectURL = results[i][0].spec;
|
||||
if (searchURL == expectURL) {
|
||||
do_check_eq(controller.getValueAt(i), results[i][0].spec);
|
||||
do_check_eq(controller.getCommentAt(i), results[i][2]);
|
||||
} else {
|
||||
// If the results didn't match exactly, perhaps it's still the right
|
||||
// frecency just in the wrong "order" (order of same frecency is
|
||||
// undefined), so check if frecency matches. This is okay because we
|
||||
// can still ensure the correct number of expected frecencies.
|
||||
let getFrecency = aURL => aURL.match(/frecency:(-?\d+)$/)[1];
|
||||
print("### checking for same frecency between '" + searchURL +
|
||||
"' and '" + expectURL + "'");
|
||||
do_check_eq(getFrecency(searchURL), getFrecency(expectURL));
|
||||
}
|
||||
}
|
||||
deferred.resolve();
|
||||
};
|
||||
|
||||
controller.startSearch(searchTerm);
|
||||
|
||||
yield deferred.promise;
|
||||
});
|
||||
42
toolkit/components/places/tests/unit/test_1085291.js
Normal file
42
toolkit/components/places/tests/unit/test_1085291.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
add_task(function* () {
|
||||
// test that nodes inserted by incremental update for bookmarks of all types
|
||||
// have the extra bookmark properties (bookmarkGuid, dateAdded, lastModified).
|
||||
|
||||
// getFolderContents opens the root node.
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root;
|
||||
|
||||
function* insertAndTest(bmInfo) {
|
||||
bmInfo = yield PlacesUtils.bookmarks.insert(bmInfo);
|
||||
let node = root.getChild(root.childCount - 1);
|
||||
Assert.equal(node.bookmarkGuid, bmInfo.guid);
|
||||
Assert.equal(node.dateAdded, bmInfo.dateAdded * 1000);
|
||||
Assert.equal(node.lastModified, bmInfo.lastModified * 1000);
|
||||
}
|
||||
|
||||
// Normal bookmark.
|
||||
yield insertAndTest({ parentGuid: root.bookmarkGuid
|
||||
, type: PlacesUtils.bookmarks.TYPE_BOOKMARK
|
||||
, title: "Test Bookmark"
|
||||
, url: "http://test.url.tld" });
|
||||
|
||||
// place: query
|
||||
yield insertAndTest({ parentGuid: root.bookmarkGuid
|
||||
, type: PlacesUtils.bookmarks.TYPE_BOOKMARK
|
||||
, title: "Test Query"
|
||||
, url: "place:folder=BOOKMARKS_MENU" });
|
||||
|
||||
// folder
|
||||
yield insertAndTest({ parentGuid: root.bookmarkGuid
|
||||
, type: PlacesUtils.bookmarks.TYPE_FOLDER
|
||||
, title: "Test Folder" });
|
||||
|
||||
// separator
|
||||
yield insertAndTest({ parentGuid: root.bookmarkGuid
|
||||
, type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
|
||||
|
||||
root.containerOpen = false;
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
24
toolkit/components/places/tests/unit/test_1105208.js
Normal file
24
toolkit/components/places/tests/unit/test_1105208.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Test that result node for folder shortcuts get the target folder title if
|
||||
// the shortcut itself has no title set.
|
||||
add_task(function* () {
|
||||
let shortcutInfo = yield PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "place:folder=TOOLBAR"
|
||||
});
|
||||
|
||||
let unfiledRoot =
|
||||
PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
let shortcutNode = unfiledRoot.getChild(unfiledRoot.childCount - 1);
|
||||
Assert.equal(shortcutNode.bookmarkGuid, shortcutInfo.guid);
|
||||
|
||||
let toolbarInfo =
|
||||
yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.toolbarGuid);
|
||||
Assert.equal(shortcutNode.title, toolbarInfo.title);
|
||||
|
||||
unfiledRoot.containerOpen = false;
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
63
toolkit/components/places/tests/unit/test_1105866.js
Normal file
63
toolkit/components/places/tests/unit/test_1105866.js
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
add_task(function* test_folder_shortcuts() {
|
||||
let shortcutInfo = yield PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "place:folder=TOOLBAR"
|
||||
});
|
||||
|
||||
let unfiledRoot =
|
||||
PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
let shortcutNode = unfiledRoot.getChild(unfiledRoot.childCount - 1);
|
||||
Assert.strictEqual(shortcutNode.itemId,
|
||||
yield PlacesUtils.promiseItemId(shortcutInfo.guid));
|
||||
Assert.strictEqual(PlacesUtils.asQuery(shortcutNode).folderItemId,
|
||||
PlacesUtils.toolbarFolderId);
|
||||
Assert.strictEqual(shortcutNode.bookmarkGuid, shortcutInfo.guid);
|
||||
Assert.strictEqual(PlacesUtils.asQuery(shortcutNode).targetFolderGuid,
|
||||
PlacesUtils.bookmarks.toolbarGuid);
|
||||
|
||||
// test that a node added incrementally also behaves just as well.
|
||||
shortcutInfo = yield PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "place:folder=BOOKMARKS_MENU"
|
||||
});
|
||||
shortcutNode = unfiledRoot.getChild(unfiledRoot.childCount - 1);
|
||||
Assert.strictEqual(shortcutNode.itemId,
|
||||
yield PlacesUtils.promiseItemId(shortcutInfo.guid));
|
||||
Assert.strictEqual(PlacesUtils.asQuery(shortcutNode).folderItemId,
|
||||
PlacesUtils.bookmarksMenuFolderId);
|
||||
Assert.strictEqual(shortcutNode.bookmarkGuid, shortcutInfo.guid);
|
||||
Assert.strictEqual(PlacesUtils.asQuery(shortcutNode).targetFolderGuid,
|
||||
PlacesUtils.bookmarks.menuGuid);
|
||||
|
||||
unfiledRoot.containerOpen = false;
|
||||
});
|
||||
|
||||
add_task(function* test_plain_folder() {
|
||||
let folderInfo = yield PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
});
|
||||
|
||||
let unfiledRoot =
|
||||
PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
let lastChild = unfiledRoot.getChild(unfiledRoot.childCount - 1);
|
||||
Assert.strictEqual(lastChild.bookmarkGuid, folderInfo.guid);
|
||||
Assert.strictEqual(PlacesUtils.asQuery(lastChild).targetFolderGuid,
|
||||
folderInfo.guid);
|
||||
});
|
||||
|
||||
add_task(function* test_non_item_query() {
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
let root = PlacesUtils.history.executeQuery(
|
||||
PlacesUtils.history.getNewQuery(), options).root;
|
||||
Assert.strictEqual(root.itemId, -1);
|
||||
Assert.strictEqual(PlacesUtils.asQuery(root).folderItemId, -1);
|
||||
Assert.strictEqual(root.bookmarkGuid, "");
|
||||
Assert.strictEqual(PlacesUtils.asQuery(root).targetFolderGuid, "");
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
65
toolkit/components/places/tests/unit/test_317472.js
Normal file
65
toolkit/components/places/tests/unit/test_317472.js
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const charset = "UTF-8";
|
||||
const CHARSET_ANNO = "URIProperties/characterSet";
|
||||
|
||||
const TEST_URI = uri("http://foo.com");
|
||||
const TEST_BOOKMARKED_URI = uri("http://bar.com");
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
// add pages to history
|
||||
yield PlacesTestUtils.addVisits(TEST_URI);
|
||||
yield PlacesTestUtils.addVisits(TEST_BOOKMARKED_URI);
|
||||
|
||||
// create bookmarks on TEST_BOOKMARKED_URI
|
||||
PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
TEST_BOOKMARKED_URI, PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
TEST_BOOKMARKED_URI.spec);
|
||||
PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.toolbarFolderId,
|
||||
TEST_BOOKMARKED_URI, PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
TEST_BOOKMARKED_URI.spec);
|
||||
|
||||
// set charset on not-bookmarked page
|
||||
yield PlacesUtils.setCharsetForURI(TEST_URI, charset);
|
||||
// set charset on bookmarked page
|
||||
yield PlacesUtils.setCharsetForURI(TEST_BOOKMARKED_URI, charset);
|
||||
|
||||
// check that we have created a page annotation
|
||||
do_check_eq(PlacesUtils.annotations.getPageAnnotation(TEST_URI, CHARSET_ANNO), charset);
|
||||
|
||||
// get charset from not-bookmarked page
|
||||
do_check_eq((yield PlacesUtils.getCharsetForURI(TEST_URI)), charset);
|
||||
|
||||
// get charset from bookmarked page
|
||||
do_check_eq((yield PlacesUtils.getCharsetForURI(TEST_BOOKMARKED_URI)), charset);
|
||||
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
|
||||
// ensure that charset has gone for not-bookmarked page
|
||||
do_check_neq((yield PlacesUtils.getCharsetForURI(TEST_URI)), charset);
|
||||
|
||||
// check that page annotation has been removed
|
||||
try {
|
||||
PlacesUtils.annotations.getPageAnnotation(TEST_URI, CHARSET_ANNO);
|
||||
do_throw("Charset page annotation has not been removed correctly");
|
||||
} catch (e) {}
|
||||
|
||||
// ensure that charset still exists for bookmarked page
|
||||
do_check_eq((yield PlacesUtils.getCharsetForURI(TEST_BOOKMARKED_URI)), charset);
|
||||
|
||||
// remove charset from bookmark and check that has gone
|
||||
yield PlacesUtils.setCharsetForURI(TEST_BOOKMARKED_URI, "");
|
||||
do_check_neq((yield PlacesUtils.getCharsetForURI(TEST_BOOKMARKED_URI)), charset);
|
||||
});
|
||||
95
toolkit/components/places/tests/unit/test_331487.js
Normal file
95
toolkit/components/places/tests/unit/test_331487.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get history service
|
||||
try {
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get history service\n");
|
||||
}
|
||||
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
// add a folder
|
||||
var folder = bmsvc.createFolder(bmsvc.placesRoot, "test folder", bmsvc.DEFAULT_INDEX);
|
||||
|
||||
// add a bookmark to the folder
|
||||
var b1 = bmsvc.insertBookmark(folder, uri("http://a1.com/"),
|
||||
bmsvc.DEFAULT_INDEX, "1 title");
|
||||
// add a subfolder
|
||||
var sf1 = bmsvc.createFolder(folder, "subfolder 1", bmsvc.DEFAULT_INDEX);
|
||||
|
||||
// add a bookmark to the subfolder
|
||||
var b2 = bmsvc.insertBookmark(sf1, uri("http://a2.com/"),
|
||||
bmsvc.DEFAULT_INDEX, "2 title");
|
||||
|
||||
// add a subfolder to the subfolder
|
||||
var sf2 = bmsvc.createFolder(sf1, "subfolder 2", bmsvc.DEFAULT_INDEX);
|
||||
|
||||
// add a bookmark to the subfolder of the subfolder
|
||||
var b3 = bmsvc.insertBookmark(sf2, uri("http://a3.com/"),
|
||||
bmsvc.DEFAULT_INDEX, "3 title");
|
||||
|
||||
// bookmark query that should result in the "hierarchical" result
|
||||
// because there is one query, one folder,
|
||||
// no begin time, no end time, no domain, no uri, no search term
|
||||
// and no max results. See GetSimpleBookmarksQueryFolder()
|
||||
// for more details.
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
var query = histsvc.getNewQuery();
|
||||
query.setFolders([folder], 1);
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 2);
|
||||
do_check_eq(root.getChild(0).itemId, b1);
|
||||
do_check_eq(root.getChild(1).itemId, sf1);
|
||||
|
||||
// check the contents of the subfolder
|
||||
var sf1Node = root.getChild(1);
|
||||
sf1Node = sf1Node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
sf1Node.containerOpen = true;
|
||||
do_check_eq(sf1Node.childCount, 2);
|
||||
do_check_eq(sf1Node.getChild(0).itemId, b2);
|
||||
do_check_eq(sf1Node.getChild(1).itemId, sf2);
|
||||
|
||||
// check the contents of the subfolder's subfolder
|
||||
var sf2Node = sf1Node.getChild(1);
|
||||
sf2Node = sf2Node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
sf2Node.containerOpen = true;
|
||||
do_check_eq(sf2Node.childCount, 1);
|
||||
do_check_eq(sf2Node.getChild(0).itemId, b3);
|
||||
|
||||
sf2Node.containerOpen = false;
|
||||
sf1Node.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
|
||||
// bookmark query that should result in a flat list
|
||||
// because we specified max results
|
||||
options = histsvc.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
options.maxResults = 10;
|
||||
query = histsvc.getNewQuery();
|
||||
query.setFolders([folder], 1);
|
||||
result = histsvc.executeQuery(query, options);
|
||||
root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 3);
|
||||
do_check_eq(root.getChild(0).itemId, b1);
|
||||
do_check_eq(root.getChild(1).itemId, b2);
|
||||
do_check_eq(root.getChild(2).itemId, b3);
|
||||
root.containerOpen = false;
|
||||
|
||||
// XXX TODO
|
||||
// test that if we have: more than one query,
|
||||
// multiple folders, a begin time, an end time, a domain, a uri
|
||||
// or a search term, that we get the (correct) flat list results
|
||||
// (like we do when specified maxResults)
|
||||
}
|
||||
173
toolkit/components/places/tests/unit/test_384370.js
Normal file
173
toolkit/components/places/tests/unit/test_384370.js
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
|
||||
const DESCRIPTION_ANNO = "bookmarkProperties/description";
|
||||
|
||||
var tagData = [
|
||||
{ uri: uri("http://slint.us"), tags: ["indie", "kentucky", "music"] },
|
||||
{ uri: uri("http://en.wikipedia.org/wiki/Diplodocus"), tags: ["dinosaur", "dj", "rad word"] }
|
||||
];
|
||||
|
||||
var bookmarkData = [
|
||||
{ uri: uri("http://slint.us"), title: "indie, kentucky, music" },
|
||||
{ uri: uri("http://en.wikipedia.org/wiki/Diplodocus"), title: "dinosaur, dj, rad word" }
|
||||
];
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
/*
|
||||
HTML+FEATURES SUMMARY:
|
||||
- import legacy bookmarks
|
||||
- export as json, import, test (tests integrity of html > json)
|
||||
- export as html, import, test (tests integrity of json > html)
|
||||
|
||||
BACKUP/RESTORE SUMMARY:
|
||||
- create a bookmark in each root
|
||||
- tag multiple URIs with multiple tags
|
||||
- export as json, import, test
|
||||
*/
|
||||
add_task(function* () {
|
||||
// Remove eventual bookmarks.exported.json.
|
||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.exported.json");
|
||||
if ((yield OS.File.exists(jsonFile)))
|
||||
yield OS.File.remove(jsonFile);
|
||||
|
||||
// Test importing a pre-Places canonical bookmarks file.
|
||||
// Note: we do not empty the db before this import to catch bugs like 380999
|
||||
let htmlFile = OS.Path.join(do_get_cwd().path, "bookmarks.preplaces.html");
|
||||
yield BookmarkHTMLUtils.importFromFile(htmlFile, true);
|
||||
|
||||
// Populate the database.
|
||||
for (let { uri, tags } of tagData) {
|
||||
PlacesUtils.tagging.tagURI(uri, tags);
|
||||
}
|
||||
for (let { uri, title } of bookmarkData) {
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: uri,
|
||||
title });
|
||||
}
|
||||
for (let { uri, title } of bookmarkData) {
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
url: uri,
|
||||
title });
|
||||
}
|
||||
|
||||
yield validate();
|
||||
|
||||
// Test exporting a Places canonical json file.
|
||||
// 1. export to bookmarks.exported.json
|
||||
yield BookmarkJSONUtils.exportToFile(jsonFile);
|
||||
do_print("exported json");
|
||||
|
||||
// 2. empty bookmarks db
|
||||
// 3. import bookmarks.exported.json
|
||||
yield BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||
do_print("imported json");
|
||||
|
||||
// 4. run the test-suite
|
||||
yield validate();
|
||||
do_print("validated import");
|
||||
});
|
||||
|
||||
function* validate() {
|
||||
yield testMenuBookmarks();
|
||||
yield testToolbarBookmarks();
|
||||
testUnfiledBookmarks();
|
||||
testTags();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
}
|
||||
|
||||
// Tests a bookmarks datastore that has a set of bookmarks, etc
|
||||
// that flex each supported field and feature.
|
||||
function* testMenuBookmarks() {
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarksMenuFolderId).root;
|
||||
Assert.equal(root.childCount, 3);
|
||||
|
||||
let separatorNode = root.getChild(1);
|
||||
Assert.equal(separatorNode.type, separatorNode.RESULT_TYPE_SEPARATOR);
|
||||
|
||||
let folderNode = root.getChild(2);
|
||||
Assert.equal(folderNode.type, folderNode.RESULT_TYPE_FOLDER);
|
||||
Assert.equal(folderNode.title, "test");
|
||||
let folder = yield PlacesUtils.bookmarks.fetch(folderNode.bookmarkGuid);
|
||||
Assert.equal(folder.dateAdded.getTime(), 1177541020000);
|
||||
|
||||
Assert.equal(PlacesUtils.asQuery(folderNode).hasChildren, true);
|
||||
|
||||
Assert.equal("folder test comment",
|
||||
PlacesUtils.annotations.getItemAnnotation(folderNode.itemId,
|
||||
DESCRIPTION_ANNO));
|
||||
|
||||
// open test folder, and test the children
|
||||
folderNode.containerOpen = true;
|
||||
Assert.equal(folderNode.childCount, 1);
|
||||
|
||||
let bookmarkNode = folderNode.getChild(0);
|
||||
Assert.equal("http://test/post", bookmarkNode.uri);
|
||||
Assert.equal("test post keyword", bookmarkNode.title);
|
||||
Assert.ok(PlacesUtils.annotations.itemHasAnnotation(bookmarkNode.itemId,
|
||||
LOAD_IN_SIDEBAR_ANNO));
|
||||
Assert.equal(bookmarkNode.dateAdded, 1177375336000000);
|
||||
|
||||
let entry = yield PlacesUtils.keywords.fetch({ url: bookmarkNode.uri });
|
||||
Assert.equal("test", entry.keyword);
|
||||
Assert.equal("hidden1%3Dbar&text1%3D%25s", entry.postData);
|
||||
|
||||
Assert.equal("ISO-8859-1",
|
||||
(yield PlacesUtils.getCharsetForURI(NetUtil.newURI(bookmarkNode.uri))));
|
||||
Assert.equal("item description",
|
||||
PlacesUtils.annotations.getItemAnnotation(bookmarkNode.itemId,
|
||||
DESCRIPTION_ANNO));
|
||||
|
||||
folderNode.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
function* testToolbarBookmarks() {
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root;
|
||||
|
||||
// child count (add 2 for pre-existing items)
|
||||
Assert.equal(root.childCount, bookmarkData.length + 2);
|
||||
|
||||
let livemarkNode = root.getChild(1);
|
||||
Assert.equal("Latest Headlines", livemarkNode.title);
|
||||
|
||||
let livemark = yield PlacesUtils.livemarks.getLivemark({ id: livemarkNode.itemId });
|
||||
Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
|
||||
livemark.siteURI.spec);
|
||||
Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
|
||||
livemark.feedURI.spec);
|
||||
|
||||
// test added bookmark data
|
||||
let bookmarkNode = root.getChild(2);
|
||||
Assert.equal(bookmarkNode.uri, bookmarkData[0].uri.spec);
|
||||
Assert.equal(bookmarkNode.title, bookmarkData[0].title);
|
||||
bookmarkNode = root.getChild(3);
|
||||
Assert.equal(bookmarkNode.uri, bookmarkData[1].uri.spec);
|
||||
Assert.equal(bookmarkNode.title, bookmarkData[1].title);
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
function testUnfiledBookmarks() {
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
// child count (add 1 for pre-existing item)
|
||||
Assert.equal(root.childCount, bookmarkData.length + 1);
|
||||
for (let i = 1; i < root.childCount; ++i) {
|
||||
let child = root.getChild(i);
|
||||
Assert.equal(child.uri, bookmarkData[i - 1].uri.spec);
|
||||
Assert.equal(child.title, bookmarkData[i - 1].title);
|
||||
if (child.tags)
|
||||
Assert.equal(child.tags, bookmarkData[i - 1].title);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
function testTags() {
|
||||
for (let { uri, tags } of tagData) {
|
||||
do_print("Test tags for " + uri.spec + ": " + tags + "\n");
|
||||
let foundTags = PlacesUtils.tagging.getTagsForURI(uri);
|
||||
Assert.equal(foundTags.length, tags.length);
|
||||
Assert.ok(tags.every(tag => foundTags.includes(tag)));
|
||||
}
|
||||
}
|
||||
142
toolkit/components/places/tests/unit/test_385397.js
Normal file
142
toolkit/components/places/tests/unit/test_385397.js
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const TOTAL_SITES = 20;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
let now = (Date.now() - 10000) * 1000;
|
||||
|
||||
for (let i = 0; i < TOTAL_SITES; i++) {
|
||||
let site = "http://www.test-" + i + ".com/";
|
||||
let testURI = uri(site);
|
||||
let testImageURI = uri(site + "blank.gif");
|
||||
let when = now + (i * TOTAL_SITES * 1000);
|
||||
yield PlacesTestUtils.addVisits([
|
||||
{ uri: testURI, visitDate: when, transition: TRANSITION_TYPED },
|
||||
{ uri: testImageURI, visitDate: when + 1000, transition: TRANSITION_EMBED },
|
||||
{ uri: testImageURI, visitDate: when + 2000, transition: TRANSITION_FRAMED_LINK },
|
||||
{ uri: testURI, visitDate: when + 3000, transition: TRANSITION_LINK },
|
||||
]);
|
||||
}
|
||||
|
||||
// verify our visits AS_VISIT, ordered by date descending
|
||||
// including hidden
|
||||
// we should get 80 visits:
|
||||
// http://www.test-19.com/
|
||||
// http://www.test-19.com/blank.gif
|
||||
// http://www.test-19.com/
|
||||
// http://www.test-19.com/
|
||||
// ...
|
||||
// http://www.test-0.com/
|
||||
// http://www.test-0.com/blank.gif
|
||||
// http://www.test-0.com/
|
||||
// http://www.test-0.com/
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
options.resultType = options.RESULTS_AS_VISIT;
|
||||
options.includeHidden = true;
|
||||
let root = PlacesUtils.history.executeQuery(PlacesUtils.history.getNewQuery(),
|
||||
options).root;
|
||||
root.containerOpen = true;
|
||||
let cc = root.childCount;
|
||||
// Embed visits are not added to the database, thus they won't appear.
|
||||
do_check_eq(cc, 3 * TOTAL_SITES);
|
||||
for (let i = 0; i < TOTAL_SITES; i++) {
|
||||
let index = i * 3;
|
||||
let node = root.getChild(index);
|
||||
let site = "http://www.test-" + (TOTAL_SITES - 1 - i) + ".com/";
|
||||
do_check_eq(node.uri, site);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
node = root.getChild(++index);
|
||||
do_check_eq(node.uri, site + "blank.gif");
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
node = root.getChild(++index);
|
||||
do_check_eq(node.uri, site);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
|
||||
// verify our visits AS_VISIT, ordered by date descending
|
||||
// we should get 40 visits:
|
||||
// http://www.test-19.com/
|
||||
// http://www.test-19.com/
|
||||
// ...
|
||||
// http://www.test-0.com/
|
||||
// http://www.test-0.com/
|
||||
options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
options.resultType = options.RESULTS_AS_VISIT;
|
||||
root = PlacesUtils.history.executeQuery(PlacesUtils.history.getNewQuery(),
|
||||
options).root;
|
||||
root.containerOpen = true;
|
||||
cc = root.childCount;
|
||||
// 2 * TOTAL_SITES because we count the TYPED and LINK, but not EMBED or FRAMED
|
||||
do_check_eq(cc, 2 * TOTAL_SITES);
|
||||
for (let i=0; i < TOTAL_SITES; i++) {
|
||||
let index = i * 2;
|
||||
let node = root.getChild(index);
|
||||
let site = "http://www.test-" + (TOTAL_SITES - 1 - i) + ".com/";
|
||||
do_check_eq(node.uri, site);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
node = root.getChild(++index);
|
||||
do_check_eq(node.uri, site);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
|
||||
// test our optimized query for the places menu
|
||||
// place:type=0&sort=4&maxResults=10
|
||||
// verify our visits AS_URI, ordered by date descending
|
||||
// we should get 10 visits:
|
||||
// http://www.test-19.com/
|
||||
// ...
|
||||
// http://www.test-10.com/
|
||||
options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
options.maxResults = 10;
|
||||
options.resultType = options.RESULTS_AS_URI;
|
||||
root = PlacesUtils.history.executeQuery(PlacesUtils.history.getNewQuery(),
|
||||
options).root;
|
||||
root.containerOpen = true;
|
||||
cc = root.childCount;
|
||||
do_check_eq(cc, options.maxResults);
|
||||
for (let i=0; i < cc; i++) {
|
||||
let node = root.getChild(i);
|
||||
let site = "http://www.test-" + (TOTAL_SITES - 1 - i) + ".com/";
|
||||
do_check_eq(node.uri, site);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
|
||||
// test without a maxResults, which executes a different query
|
||||
// but the first 10 results should be the same.
|
||||
// verify our visits AS_URI, ordered by date descending
|
||||
// we should get 20 visits, but the first 10 should be
|
||||
// http://www.test-19.com/
|
||||
// ...
|
||||
// http://www.test-10.com/
|
||||
options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
options.resultType = options.RESULTS_AS_URI;
|
||||
root = PlacesUtils.history.executeQuery(PlacesUtils.history.getNewQuery(),
|
||||
options).root;
|
||||
root.containerOpen = true;
|
||||
cc = root.childCount;
|
||||
do_check_eq(cc, TOTAL_SITES);
|
||||
for (let i=0; i < 10; i++) {
|
||||
let node = root.getChild(i);
|
||||
let site = "http://www.test-" + (TOTAL_SITES - 1 - i) + ".com/";
|
||||
do_check_eq(node.uri, site);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
});
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Obtains the id of the folder obtained from the query.
|
||||
*
|
||||
* @param aFolderID
|
||||
* The id of the folder we want to generate a query for.
|
||||
* @returns the string representation of the query for the given folder.
|
||||
*/
|
||||
function query_string(aFolderID)
|
||||
{
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
var query = hs.getNewQuery();
|
||||
query.setFolders([aFolderID], 1);
|
||||
var options = hs.getNewQueryOptions();
|
||||
return hs.queriesToQueryString([query], 1, options);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
const QUERIES = [
|
||||
"folder=PLACES_ROOT"
|
||||
, "folder=BOOKMARKS_MENU"
|
||||
, "folder=TAGS"
|
||||
, "folder=UNFILED_BOOKMARKS"
|
||||
, "folder=TOOLBAR"
|
||||
];
|
||||
const FOLDER_IDS = [
|
||||
bs.placesRoot
|
||||
, bs.bookmarksMenuFolder
|
||||
, bs.tagsFolder
|
||||
, bs.unfiledBookmarksFolder
|
||||
, bs.toolbarFolder
|
||||
];
|
||||
|
||||
|
||||
for (var i = 0; i < QUERIES.length; i++) {
|
||||
var result = query_string(FOLDER_IDS[i]);
|
||||
dump("Looking for '" + QUERIES[i] + "' in '" + result + "'\n");
|
||||
do_check_neq(-1, result.indexOf(QUERIES[i]));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Obtains the id of the folder obtained from the query.
|
||||
*
|
||||
* @param aQuery
|
||||
* The query to obtain the folder id from.
|
||||
* @returns the folder id of the folder of the root node of the query.
|
||||
*/
|
||||
function folder_id(aQuery)
|
||||
{
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
dump("Checking query '" + aQuery + "'\n");
|
||||
var options = { };
|
||||
var queries = { };
|
||||
var size = { };
|
||||
hs.queryStringToQueries(aQuery, queries, size, options);
|
||||
var result = hs.executeQueries(queries.value, size.value, options.value);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_true(root.hasChildren);
|
||||
var folderID = root.getChild(0).parent.itemId;
|
||||
root.containerOpen = false;
|
||||
return folderID;
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
const QUERIES = [
|
||||
"place:folder=PLACES_ROOT"
|
||||
, "place:folder=BOOKMARKS_MENU"
|
||||
, "place:folder=TAGS"
|
||||
, "place:folder=UNFILED_BOOKMARKS"
|
||||
, "place:folder=TOOLBAR"
|
||||
];
|
||||
const FOLDER_IDS = [
|
||||
bs.placesRoot
|
||||
, bs.bookmarksMenuFolder
|
||||
, bs.tagsFolder
|
||||
, bs.unfiledBookmarksFolder
|
||||
, bs.toolbarFolder
|
||||
];
|
||||
|
||||
// add something in the bookmarks menu folder so a query to it returns results
|
||||
bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://example.com/bmf/"),
|
||||
Ci.nsINavBookmarksService.DEFAULT_INDEX, "bmf");
|
||||
|
||||
// add something to the tags folder
|
||||
var ts = Cc["@mozilla.org/browser/tagging-service;1"].
|
||||
getService(Ci.nsITaggingService);
|
||||
ts.tagURI(uri("http://www.example.com/"), ["tag"]);
|
||||
|
||||
// add something to the unfiled bookmarks folder
|
||||
bs.insertBookmark(bs.unfiledBookmarksFolder, uri("http://example.com/ubf/"),
|
||||
Ci.nsINavBookmarksService.DEFAULT_INDEX, "ubf");
|
||||
|
||||
// add something to the toolbar folder
|
||||
bs.insertBookmark(bs.toolbarFolder, uri("http://example.com/tf/"),
|
||||
Ci.nsINavBookmarksService.DEFAULT_INDEX, "tf");
|
||||
|
||||
for (var i = 0; i < QUERIES.length; i++) {
|
||||
var result = folder_id(QUERIES[i]);
|
||||
dump("expected " + FOLDER_IDS[i] + ", got " + result + "\n");
|
||||
do_check_eq(FOLDER_IDS[i], result);
|
||||
}
|
||||
}
|
||||
78
toolkit/components/places/tests/unit/test_399266.js
Normal file
78
toolkit/components/places/tests/unit/test_399266.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const TOTAL_SITES = 20;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
let places = [];
|
||||
for (let i = 0; i < TOTAL_SITES; i++) {
|
||||
for (let j = 0; j <= i; j++) {
|
||||
places.push({ uri: uri("http://www.test-" + i + ".com/"),
|
||||
transition: TRANSITION_TYPED });
|
||||
// because these are embedded visits, they should not show up on our
|
||||
// query results. If they do, we have a problem.
|
||||
places.push({ uri: uri("http://www.hidden.com/hidden.gif"),
|
||||
transition: TRANSITION_EMBED });
|
||||
places.push({ uri: uri("http://www.alsohidden.com/hidden.gif"),
|
||||
transition: TRANSITION_FRAMED_LINK });
|
||||
}
|
||||
}
|
||||
yield PlacesTestUtils.addVisits(places);
|
||||
|
||||
// test our optimized query for the "Most Visited" item
|
||||
// in the "Smart Bookmarks" folder
|
||||
// place:queryType=0&sort=8&maxResults=10
|
||||
// verify our visits AS_URI, ordered by visit count descending
|
||||
// we should get 10 visits:
|
||||
// http://www.test-19.com/
|
||||
// ...
|
||||
// http://www.test-10.com/
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = options.SORT_BY_VISITCOUNT_DESCENDING;
|
||||
options.maxResults = 10;
|
||||
options.resultType = options.RESULTS_AS_URI;
|
||||
let root = PlacesUtils.history.executeQuery(PlacesUtils.history.getNewQuery(),
|
||||
options).root;
|
||||
root.containerOpen = true;
|
||||
let cc = root.childCount;
|
||||
do_check_eq(cc, options.maxResults);
|
||||
for (let i = 0; i < cc; i++) {
|
||||
let node = root.getChild(i);
|
||||
let site = "http://www.test-" + (TOTAL_SITES - 1 - i) + ".com/";
|
||||
do_check_eq(node.uri, site);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
|
||||
// test without a maxResults, which executes a different query
|
||||
// but the first 10 results should be the same.
|
||||
// verify our visits AS_URI, ordered by visit count descending
|
||||
// we should get 20 visits, but the first 10 should be
|
||||
// http://www.test-19.com/
|
||||
// ...
|
||||
// http://www.test-10.com/
|
||||
options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = options.SORT_BY_VISITCOUNT_DESCENDING;
|
||||
options.resultType = options.RESULTS_AS_URI;
|
||||
root = PlacesUtils.history.executeQuery(PlacesUtils.history.getNewQuery(),
|
||||
options).root;
|
||||
root.containerOpen = true;
|
||||
cc = root.childCount;
|
||||
do_check_eq(cc, TOTAL_SITES);
|
||||
for (let i = 0; i < 10; i++) {
|
||||
let node = root.getChild(i);
|
||||
let site = "http://www.test-" + (TOTAL_SITES - 1 - i) + ".com/";
|
||||
do_check_eq(node.uri, site);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
});
|
||||
62
toolkit/components/places/tests/unit/test_402799.js
Normal file
62
toolkit/components/places/tests/unit/test_402799.js
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get history services
|
||||
try {
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bhist = histsvc.QueryInterface(Ci.nsIBrowserHistory);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get history services\n");
|
||||
}
|
||||
|
||||
// Get bookmark service
|
||||
try {
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("Could not get the nav-bookmarks-service\n");
|
||||
}
|
||||
|
||||
// Get tagging service
|
||||
try {
|
||||
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
|
||||
getService(Ci.nsITaggingService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get tagging service\n");
|
||||
}
|
||||
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
var uri1 = uri("http://foo.bar/");
|
||||
|
||||
// create 2 bookmarks on the same uri
|
||||
bmsvc.insertBookmark(bmsvc.bookmarksMenuFolder, uri1,
|
||||
bmsvc.DEFAULT_INDEX, "title 1");
|
||||
bmsvc.insertBookmark(bmsvc.toolbarFolder, uri1,
|
||||
bmsvc.DEFAULT_INDEX, "title 2");
|
||||
// add some tags
|
||||
tagssvc.tagURI(uri1, ["foo", "bar", "foobar", "foo bar"]);
|
||||
|
||||
// check that a generic bookmark query returns only real bookmarks
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
|
||||
var query = histsvc.getNewQuery();
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
|
||||
root.containerOpen = true;
|
||||
var cc = root.childCount;
|
||||
do_check_eq(cc, 2);
|
||||
var node1 = root.getChild(0);
|
||||
do_check_eq(bmsvc.getFolderIdForItem(node1.itemId), bmsvc.bookmarksMenuFolder);
|
||||
var node2 = root.getChild(1);
|
||||
do_check_eq(bmsvc.getFolderIdForItem(node2.itemId), bmsvc.toolbarFolder);
|
||||
root.containerOpen = false;
|
||||
}
|
||||
57
toolkit/components/places/tests/unit/test_405497.js
Normal file
57
toolkit/components/places/tests/unit/test_405497.js
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
/**
|
||||
* The callback object for runInBatchMode.
|
||||
*
|
||||
* @param aService
|
||||
* Takes a reference to the history service or the bookmark service.
|
||||
* This determines which service should be called when calling the second
|
||||
* runInBatchMode the second time.
|
||||
*/
|
||||
function callback(aService)
|
||||
{
|
||||
this.callCount = 0;
|
||||
this.service = aService;
|
||||
}
|
||||
callback.prototype = {
|
||||
// nsINavHistoryBatchCallback
|
||||
|
||||
runBatched: function(aUserData)
|
||||
{
|
||||
this.callCount++;
|
||||
|
||||
if (this.callCount == 1) {
|
||||
// We want to call run in batched once more.
|
||||
this.service.runInBatchMode(this, null);
|
||||
return;
|
||||
}
|
||||
|
||||
do_check_eq(this.callCount, 2);
|
||||
do_test_finished();
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryBatchCallback])
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
// checking the history service
|
||||
do_test_pending();
|
||||
hs.runInBatchMode(new callback(hs), null);
|
||||
|
||||
// checking the bookmark service
|
||||
do_test_pending();
|
||||
bs.runInBatchMode(new callback(bs), null);
|
||||
}
|
||||
165
toolkit/components/places/tests/unit/test_408221.js
Normal file
165
toolkit/components/places/tests/unit/test_408221.js
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var current_test = 0;
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get tagging service
|
||||
try {
|
||||
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
|
||||
getService(Ci.nsITaggingService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get tagging service\n");
|
||||
}
|
||||
|
||||
function ensure_tag_results(uris, searchTerm)
|
||||
{
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
|
||||
controller.input = input;
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
var numSearchesStarted = 0;
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
do_check_eq(controller.matchCount, uris.length);
|
||||
let vals = [];
|
||||
for (let i=0; i<controller.matchCount; i++) {
|
||||
// Keep the URL for later because order of tag results is undefined
|
||||
vals.push(controller.getValueAt(i));
|
||||
do_check_eq(controller.getStyleAt(i), "bookmark-tag");
|
||||
}
|
||||
// Sort the results then check if we have the right items
|
||||
vals.sort().forEach((val, i) => do_check_eq(val, uris[i].spec))
|
||||
|
||||
if (current_test < (tests.length - 1)) {
|
||||
current_test++;
|
||||
tests[current_test]();
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.startSearch(searchTerm);
|
||||
}
|
||||
|
||||
var uri1 = uri("http://site.tld/1");
|
||||
var uri2 = uri("http://site.tld/2");
|
||||
var uri3 = uri("http://site.tld/3");
|
||||
var uri4 = uri("http://site.tld/4");
|
||||
var uri5 = uri("http://site.tld/5");
|
||||
var uri6 = uri("http://site.tld/6");
|
||||
|
||||
var tests = [function() { ensure_tag_results([uri1, uri2, uri3], "foo"); },
|
||||
function() { ensure_tag_results([uri1, uri2, uri3], "Foo"); },
|
||||
function() { ensure_tag_results([uri1, uri2, uri3], "foO"); },
|
||||
function() { ensure_tag_results([uri4, uri5, uri6], "bar mud"); },
|
||||
function() { ensure_tag_results([uri4, uri5, uri6], "BAR MUD"); },
|
||||
function() { ensure_tag_results([uri4, uri5, uri6], "Bar Mud"); }];
|
||||
|
||||
/**
|
||||
* Properly tags a uri adding it to bookmarks.
|
||||
*
|
||||
* @param aURI
|
||||
* The nsIURI to tag.
|
||||
* @param aTags
|
||||
* The tags to add.
|
||||
*/
|
||||
function tagURI(aURI, aTags) {
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
aURI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"A title");
|
||||
tagssvc.tagURI(aURI, aTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test bug #408221
|
||||
*/
|
||||
function run_test() {
|
||||
// always search in history + bookmarks, no matter what the default is
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
prefs.setIntPref("browser.urlbar.search.sources", 3);
|
||||
prefs.setIntPref("browser.urlbar.default.behavior", 0);
|
||||
|
||||
tagURI(uri1, ["Foo"]);
|
||||
tagURI(uri2, ["FOO"]);
|
||||
tagURI(uri3, ["foO"]);
|
||||
tagURI(uri4, ["BAR"]);
|
||||
tagURI(uri4, ["MUD"]);
|
||||
tagURI(uri5, ["bar"]);
|
||||
tagURI(uri5, ["mud"]);
|
||||
tagURI(uri6, ["baR"]);
|
||||
tagURI(uri6, ["muD"]);
|
||||
|
||||
tests[0]();
|
||||
}
|
||||
136
toolkit/components/places/tests/unit/test_412132.js
Normal file
136
toolkit/components/places/tests/unit/test_412132.js
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* TEST DESCRIPTION:
|
||||
*
|
||||
* Tests patch to Bug 412132:
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=412132
|
||||
*/
|
||||
|
||||
add_task(function* changeuri_unvisited_bookmark()
|
||||
{
|
||||
do_print("After changing URI of bookmark, frecency of bookmark's " +
|
||||
"original URI should be zero if original URI is unvisited and " +
|
||||
"no longer bookmarked.");
|
||||
const TEST_URI = NetUtil.newURI("http://example.com/1");
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(id, uri("http://example.com/2"));
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Unvisited URI no longer bookmarked => frecency should = 0");
|
||||
do_check_eq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
add_task(function* changeuri_visited_bookmark()
|
||||
{
|
||||
do_print("After changing URI of bookmark, frecency of bookmark's " +
|
||||
"original URI should not be zero if original URI is visited.");
|
||||
const TEST_URI = NetUtil.newURI("http://example.com/1");
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
yield PlacesTestUtils.addVisits(TEST_URI);
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(id, uri("http://example.com/2"));
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
add_task(function* changeuri_bookmark_still_bookmarked()
|
||||
{
|
||||
do_print("After changing URI of bookmark, frecency of bookmark's " +
|
||||
"original URI should not be zero if original URI is still " +
|
||||
"bookmarked.");
|
||||
const TEST_URI = NetUtil.newURI("http://example.com/1");
|
||||
let id1 = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark 1 title");
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark 2 title");
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(id1, uri("http://example.com/2"));
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI still bookmarked => frecency should != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
add_task(function* changeuri_nonexistent_bookmark()
|
||||
{
|
||||
do_print("Changing the URI of a nonexistent bookmark should fail.");
|
||||
function tryChange(itemId)
|
||||
{
|
||||
try {
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(itemId + 1, uri("http://example.com/2"));
|
||||
do_throw("Nonexistent bookmark should throw.");
|
||||
}
|
||||
catch (ex) {}
|
||||
}
|
||||
|
||||
// First try a straight-up bogus item ID, one greater than the current max
|
||||
// ID.
|
||||
let stmt = DBConn().createStatement("SELECT MAX(id) FROM moz_bookmarks");
|
||||
stmt.executeStep();
|
||||
let maxId = stmt.getInt32(0);
|
||||
stmt.finalize();
|
||||
tryChange(maxId + 1);
|
||||
|
||||
// Now add a bookmark, delete it, and check.
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri("http://example.com/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
tryChange(id);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
118
toolkit/components/places/tests/unit/test_413784.js
Normal file
118
toolkit/components/places/tests/unit/test_413784.js
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
|
||||
Test autocomplete for non-English URLs
|
||||
|
||||
- add a visit for a page with a non-English URL
|
||||
- search
|
||||
- test number of matches (should be exactly one)
|
||||
|
||||
*/
|
||||
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
// create test data
|
||||
var searchTerm = "ユニコード";
|
||||
var decoded = "http://www.foobar.com/" + searchTerm + "/";
|
||||
var url = uri(decoded);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
do_test_pending();
|
||||
PlacesTestUtils.addVisits(url).then(continue_test);
|
||||
}
|
||||
|
||||
function continue_test()
|
||||
{
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
|
||||
controller.input = input;
|
||||
|
||||
var numSearchesStarted = 0;
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
|
||||
// test that we found the entry we added
|
||||
do_check_eq(controller.matchCount, 1);
|
||||
|
||||
// Make sure the url is the same according to spec, so it can be deleted
|
||||
do_check_eq(controller.getValueAt(0), url.spec);
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.startSearch(searchTerm);
|
||||
}
|
||||
43
toolkit/components/places/tests/unit/test_415460.js
Normal file
43
toolkit/components/places/tests/unit/test_415460.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
/**
|
||||
* Checks to see that a search has exactly one result in the database.
|
||||
*
|
||||
* @param aTerms
|
||||
* The terms to search for.
|
||||
* @returns true if the search returns one result, false otherwise.
|
||||
*/
|
||||
function search_has_result(aTerms)
|
||||
{
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.maxResults = 1;
|
||||
options.resultType = options.RESULTS_AS_URI;
|
||||
var query = hs.getNewQuery();
|
||||
query.searchTerms = aTerms;
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var cc = root.childCount;
|
||||
root.containerOpen = false;
|
||||
return (cc == 1);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
const SEARCH_TERM = "ユニコード";
|
||||
const TEST_URL = "http://example.com/" + SEARCH_TERM + "/";
|
||||
yield PlacesTestUtils.addVisits(uri(TEST_URL));
|
||||
do_check_true(search_has_result(SEARCH_TERM));
|
||||
});
|
||||
102
toolkit/components/places/tests/unit/test_415757.js
Normal file
102
toolkit/components/places/tests/unit/test_415757.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Checks to see that a URI is in the database.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check.
|
||||
* @returns true if the URI is in the DB, false otherwise.
|
||||
*/
|
||||
function uri_in_db(aURI) {
|
||||
var options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.maxResults = 1;
|
||||
options.resultType = options.RESULTS_AS_URI
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.uri = aURI;
|
||||
var result = PlacesUtils.history.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var cc = root.childCount;
|
||||
root.containerOpen = false;
|
||||
return (cc == 1);
|
||||
}
|
||||
|
||||
const TOTAL_SITES = 20;
|
||||
|
||||
// main
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
// add pages to global history
|
||||
for (let i = 0; i < TOTAL_SITES; i++) {
|
||||
let site = "http://www.test-" + i + ".com/";
|
||||
let testURI = uri(site);
|
||||
let when = Date.now() * 1000 + (i * TOTAL_SITES);
|
||||
yield PlacesTestUtils.addVisits({ uri: testURI, visitDate: when });
|
||||
}
|
||||
for (let i = 0; i < TOTAL_SITES; i++) {
|
||||
let site = "http://www.test.com/" + i + "/";
|
||||
let testURI = uri(site);
|
||||
let when = Date.now() * 1000 + (i * TOTAL_SITES);
|
||||
yield PlacesTestUtils.addVisits({ uri: testURI, visitDate: when });
|
||||
}
|
||||
|
||||
// set a page annotation on one of the urls that will be removed
|
||||
var testAnnoDeletedURI = uri("http://www.test.com/1/");
|
||||
var testAnnoDeletedName = "foo";
|
||||
var testAnnoDeletedValue = "bar";
|
||||
PlacesUtils.annotations.setPageAnnotation(testAnnoDeletedURI,
|
||||
testAnnoDeletedName,
|
||||
testAnnoDeletedValue, 0,
|
||||
PlacesUtils.annotations.EXPIRE_WITH_HISTORY);
|
||||
|
||||
// set a page annotation on one of the urls that will NOT be removed
|
||||
var testAnnoRetainedURI = uri("http://www.test-1.com/");
|
||||
var testAnnoRetainedName = "foo";
|
||||
var testAnnoRetainedValue = "bar";
|
||||
PlacesUtils.annotations.setPageAnnotation(testAnnoRetainedURI,
|
||||
testAnnoRetainedName,
|
||||
testAnnoRetainedValue, 0,
|
||||
PlacesUtils.annotations.EXPIRE_WITH_HISTORY);
|
||||
|
||||
// remove pages from www.test.com
|
||||
PlacesUtils.history.removePagesFromHost("www.test.com", false);
|
||||
|
||||
// check that all pages in www.test.com have been removed
|
||||
for (let i = 0; i < TOTAL_SITES; i++) {
|
||||
let site = "http://www.test.com/" + i + "/";
|
||||
let testURI = uri(site);
|
||||
do_check_false(uri_in_db(testURI));
|
||||
}
|
||||
|
||||
// check that all pages in www.test-X.com have NOT been removed
|
||||
for (let i = 0; i < TOTAL_SITES; i++) {
|
||||
let site = "http://www.test-" + i + ".com/";
|
||||
let testURI = uri(site);
|
||||
do_check_true(uri_in_db(testURI));
|
||||
}
|
||||
|
||||
// check that annotation on the removed item does not exists
|
||||
try {
|
||||
PlacesUtils.annotations.getPageAnnotation(testAnnoDeletedURI, testAnnoName);
|
||||
do_throw("fetching page-annotation that doesn't exist, should've thrown");
|
||||
} catch (ex) {}
|
||||
|
||||
// check that annotation on the NOT removed item still exists
|
||||
try {
|
||||
var annoVal = PlacesUtils.annotations.getPageAnnotation(testAnnoRetainedURI,
|
||||
testAnnoRetainedName);
|
||||
} catch (ex) {
|
||||
do_throw("The annotation has been removed erroneously");
|
||||
}
|
||||
do_check_eq(annoVal, testAnnoRetainedValue);
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get services.
|
||||
try {
|
||||
var histSvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bmSvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var annoSvc = Cc["@mozilla.org/browser/annotation-service;1"]
|
||||
.getService(Ci.nsIAnnotationService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get services\n");
|
||||
}
|
||||
|
||||
var validAnnoName = "validAnno";
|
||||
var validItemName = "validItem";
|
||||
var deletedAnnoName = "deletedAnno";
|
||||
var deletedItemName = "deletedItem";
|
||||
var bookmarkedURI = uri("http://www.mozilla.org/");
|
||||
// set lastModified to the past to prevent VM timing bugs
|
||||
var pastDate = Date.now() * 1000 - 1;
|
||||
var deletedBookmarkIds = [];
|
||||
|
||||
// bookmarks observer
|
||||
var observer = {
|
||||
// cached ordered array of notified items
|
||||
_onItemRemovedItemIds: [],
|
||||
onItemRemoved: function(aItemId, aParentId, aIndex) {
|
||||
// We should first get notifications for children, then for their parent
|
||||
do_check_eq(this._onItemRemovedItemIds.indexOf(aParentId), -1);
|
||||
// Ensure we are not wrongly removing 1 level up
|
||||
do_check_neq(aParentId, bmSvc.toolbarFolder);
|
||||
// Removed item must be one of those we have manually deleted
|
||||
do_check_neq(deletedBookmarkIds.indexOf(aItemId), -1);
|
||||
this._onItemRemovedItemIds.push(aItemId);
|
||||
},
|
||||
|
||||
QueryInterface: function(aIID) {
|
||||
if (aIID.equals(Ci.nsINavBookmarkObserver) ||
|
||||
aIID.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
bmSvc.addObserver(observer, false);
|
||||
|
||||
function add_bookmarks() {
|
||||
// This is the folder we will cleanup
|
||||
var validFolderId = bmSvc.createFolder(bmSvc.toolbarFolder,
|
||||
validItemName,
|
||||
bmSvc.DEFAULT_INDEX);
|
||||
annoSvc.setItemAnnotation(validFolderId, validAnnoName,
|
||||
"annotation", 0,
|
||||
annoSvc.EXPIRE_NEVER);
|
||||
bmSvc.setItemLastModified(validFolderId, pastDate);
|
||||
|
||||
// This bookmark should not be deleted
|
||||
var validItemId = bmSvc.insertBookmark(bmSvc.toolbarFolder,
|
||||
bookmarkedURI,
|
||||
bmSvc.DEFAULT_INDEX,
|
||||
validItemName);
|
||||
annoSvc.setItemAnnotation(validItemId, validAnnoName,
|
||||
"annotation", 0, annoSvc.EXPIRE_NEVER);
|
||||
|
||||
// The following contents should be deleted
|
||||
var deletedItemId = bmSvc.insertBookmark(validFolderId,
|
||||
bookmarkedURI,
|
||||
bmSvc.DEFAULT_INDEX,
|
||||
deletedItemName);
|
||||
annoSvc.setItemAnnotation(deletedItemId, deletedAnnoName,
|
||||
"annotation", 0, annoSvc.EXPIRE_NEVER);
|
||||
deletedBookmarkIds.push(deletedItemId);
|
||||
|
||||
var internalFolderId = bmSvc.createFolder(validFolderId,
|
||||
deletedItemName,
|
||||
bmSvc.DEFAULT_INDEX);
|
||||
annoSvc.setItemAnnotation(internalFolderId, deletedAnnoName,
|
||||
"annotation", 0, annoSvc.EXPIRE_NEVER);
|
||||
deletedBookmarkIds.push(internalFolderId);
|
||||
|
||||
deletedItemId = bmSvc.insertBookmark(internalFolderId,
|
||||
bookmarkedURI,
|
||||
bmSvc.DEFAULT_INDEX,
|
||||
deletedItemName);
|
||||
annoSvc.setItemAnnotation(deletedItemId, deletedAnnoName,
|
||||
"annotation", 0, annoSvc.EXPIRE_NEVER);
|
||||
deletedBookmarkIds.push(deletedItemId);
|
||||
|
||||
return validFolderId;
|
||||
}
|
||||
|
||||
function check_bookmarks(aFolderId) {
|
||||
// check that we still have valid bookmarks
|
||||
var bookmarks = bmSvc.getBookmarkIdsForURI(bookmarkedURI);
|
||||
for (var i = 0; i < bookmarks.length; i++) {
|
||||
do_check_eq(bmSvc.getItemTitle(bookmarks[i]), validItemName);
|
||||
do_check_true(annoSvc.itemHasAnnotation(bookmarks[i], validAnnoName));
|
||||
}
|
||||
|
||||
// check that folder exists and has still its annotation
|
||||
do_check_eq(bmSvc.getItemTitle(aFolderId), validItemName);
|
||||
do_check_true(annoSvc.itemHasAnnotation(aFolderId, validAnnoName));
|
||||
|
||||
// check that folder is empty
|
||||
var options = histSvc.getNewQueryOptions();
|
||||
var query = histSvc.getNewQuery();
|
||||
query.setFolders([aFolderId], 1);
|
||||
var result = histSvc.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 0);
|
||||
root.containerOpen = false;
|
||||
|
||||
// test that lastModified got updated
|
||||
do_check_true(pastDate < bmSvc.getItemLastModified(aFolderId));
|
||||
|
||||
// test that all children have been deleted, we use annos for that
|
||||
var deletedItems = annoSvc.getItemsWithAnnotation(deletedAnnoName);
|
||||
do_check_eq(deletedItems.length, 0);
|
||||
|
||||
// test that observer has been called for (and only for) deleted items
|
||||
do_check_eq(observer._onItemRemovedItemIds.length, deletedBookmarkIds.length);
|
||||
|
||||
// Sanity check: all roots should be intact
|
||||
do_check_eq(bmSvc.getFolderIdForItem(bmSvc.placesRoot), 0);
|
||||
do_check_eq(bmSvc.getFolderIdForItem(bmSvc.bookmarksMenuFolder), bmSvc.placesRoot);
|
||||
do_check_eq(bmSvc.getFolderIdForItem(bmSvc.tagsFolder), bmSvc.placesRoot);
|
||||
do_check_eq(bmSvc.getFolderIdForItem(bmSvc.unfiledBookmarksFolder), bmSvc.placesRoot);
|
||||
do_check_eq(bmSvc.getFolderIdForItem(bmSvc.toolbarFolder), bmSvc.placesRoot);
|
||||
}
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
var folderId = add_bookmarks();
|
||||
bmSvc.removeFolderChildren(folderId);
|
||||
check_bookmarks(folderId);
|
||||
}
|
||||
96
toolkit/components/places/tests/unit/test_419731.js
Normal file
96
toolkit/components/places/tests/unit/test_419731.js
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test() {
|
||||
let uri1 = NetUtil.newURI("http://foo.bar/");
|
||||
|
||||
// create 2 bookmarks
|
||||
let bookmark1id = PlacesUtils.bookmarks
|
||||
.insertBookmark(PlacesUtils.bookmarksMenuFolderId,
|
||||
uri1,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"title 1");
|
||||
let bookmark2id = PlacesUtils.bookmarks
|
||||
.insertBookmark(PlacesUtils.toolbarFolderId,
|
||||
uri1,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"title 2");
|
||||
// add a new tag
|
||||
PlacesUtils.tagging.tagURI(uri1, ["foo"]);
|
||||
|
||||
// get tag folder id
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([PlacesUtils.tagsFolderId], 1);
|
||||
let result = PlacesUtils.history.executeQuery(query, options);
|
||||
let tagRoot = result.root;
|
||||
tagRoot.containerOpen = true;
|
||||
let tagNode = tagRoot.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
let tagItemId = tagNode.itemId;
|
||||
tagRoot.containerOpen = false;
|
||||
|
||||
// change bookmark 1 title
|
||||
PlacesUtils.bookmarks.setItemTitle(bookmark1id, "new title 1");
|
||||
|
||||
// Workaround timers resolution and time skews.
|
||||
let bookmark2LastMod = PlacesUtils.bookmarks.getItemLastModified(bookmark2id);
|
||||
PlacesUtils.bookmarks.setItemLastModified(bookmark1id, bookmark2LastMod + 1000);
|
||||
|
||||
// Query the tag.
|
||||
options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
options.resultType = options.RESULTS_AS_TAG_QUERY;
|
||||
|
||||
query = PlacesUtils.history.getNewQuery();
|
||||
result = PlacesUtils.history.executeQuery(query, options);
|
||||
let root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 1);
|
||||
|
||||
let theTag = root.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
// Bug 524219: Check that renaming the tag shows up in the result.
|
||||
do_check_eq(theTag.title, "foo")
|
||||
PlacesUtils.bookmarks.setItemTitle(tagItemId, "bar");
|
||||
|
||||
// Check that the item has been replaced
|
||||
do_check_neq(theTag, root.getChild(0));
|
||||
theTag = root.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(theTag.title, "bar");
|
||||
|
||||
// Check that tag container contains new title
|
||||
theTag.containerOpen = true;
|
||||
do_check_eq(theTag.childCount, 1);
|
||||
let node = theTag.getChild(0);
|
||||
do_check_eq(node.title, "new title 1");
|
||||
theTag.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
|
||||
// Change bookmark 2 title.
|
||||
PlacesUtils.bookmarks.setItemTitle(bookmark2id, "new title 2");
|
||||
|
||||
// Workaround timers resolution and time skews.
|
||||
let bookmark1LastMod = PlacesUtils.bookmarks.getItemLastModified(bookmark1id);
|
||||
PlacesUtils.bookmarks.setItemLastModified(bookmark2id, bookmark1LastMod + 1000);
|
||||
|
||||
// Check that tag container contains new title
|
||||
options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
options.resultType = options.RESULTS_AS_TAG_CONTENTS;
|
||||
|
||||
query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([tagItemId], 1);
|
||||
result = PlacesUtils.history.executeQuery(query, options);
|
||||
root = result.root;
|
||||
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 1);
|
||||
node = root.getChild(0);
|
||||
do_check_eq(node.title, "new title 2");
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// get services
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
|
||||
getService(Ci.nsITaggingService);
|
||||
|
||||
function run_test() {
|
||||
// get toolbar node
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
var query = histsvc.getNewQuery();
|
||||
query.setFolders([bmsvc.toolbarFolder], 1);
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var toolbarNode = result.root;
|
||||
toolbarNode.containerOpen = true;
|
||||
|
||||
// add a bookmark
|
||||
var bookmarkURI = uri("http://foo.com");
|
||||
var bookmarkId = bmsvc.insertBookmark(bmsvc.toolbarFolder, bookmarkURI,
|
||||
bmsvc.DEFAULT_INDEX, "");
|
||||
|
||||
// get the node for the new bookmark
|
||||
var node = toolbarNode.getChild(toolbarNode.childCount-1);
|
||||
do_check_eq(node.itemId, bookmarkId);
|
||||
|
||||
// confirm there's no tags via the .tags property
|
||||
do_check_eq(node.tags, null);
|
||||
|
||||
// add a tag
|
||||
tagssvc.tagURI(bookmarkURI, ["foo"]);
|
||||
do_check_eq(node.tags, "foo");
|
||||
|
||||
// add another tag, to test delimiter and sorting
|
||||
tagssvc.tagURI(bookmarkURI, ["bar"]);
|
||||
do_check_eq(node.tags, "bar, foo");
|
||||
|
||||
// remove the tags, confirming the property is cleared
|
||||
tagssvc.untagURI(bookmarkURI, null);
|
||||
do_check_eq(node.tags, null);
|
||||
|
||||
toolbarNode.containerOpen = false;
|
||||
}
|
||||
74
toolkit/components/places/tests/unit/test_425563.js
Normal file
74
toolkit/components/places/tests/unit/test_425563.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
let count_visited_URIs = ["http://www.test-link.com/",
|
||||
"http://www.test-typed.com/",
|
||||
"http://www.test-bookmark.com/",
|
||||
"http://www.test-redirect-permanent.com/",
|
||||
"http://www.test-redirect-temporary.com/"];
|
||||
|
||||
let notcount_visited_URIs = ["http://www.test-embed.com/",
|
||||
"http://www.test-download.com/",
|
||||
"http://www.test-framed.com/",
|
||||
"http://www.test-reload.com/"];
|
||||
|
||||
// add visits, one for each transition type
|
||||
yield PlacesTestUtils.addVisits([
|
||||
{ uri: uri("http://www.test-link.com/"),
|
||||
transition: TRANSITION_LINK },
|
||||
{ uri: uri("http://www.test-typed.com/"),
|
||||
transition: TRANSITION_TYPED },
|
||||
{ uri: uri("http://www.test-bookmark.com/"),
|
||||
transition: TRANSITION_BOOKMARK },
|
||||
{ uri: uri("http://www.test-embed.com/"),
|
||||
transition: TRANSITION_EMBED },
|
||||
{ uri: uri("http://www.test-framed.com/"),
|
||||
transition: TRANSITION_FRAMED_LINK },
|
||||
{ uri: uri("http://www.test-redirect-permanent.com/"),
|
||||
transition: TRANSITION_REDIRECT_PERMANENT },
|
||||
{ uri: uri("http://www.test-redirect-temporary.com/"),
|
||||
transition: TRANSITION_REDIRECT_TEMPORARY },
|
||||
{ uri: uri("http://www.test-download.com/"),
|
||||
transition: TRANSITION_DOWNLOAD },
|
||||
{ uri: uri("http://www.test-reload.com/"),
|
||||
transition: TRANSITION_RELOAD },
|
||||
]);
|
||||
|
||||
// check that all links are marked as visited
|
||||
for (let visited_uri of count_visited_URIs) {
|
||||
do_check_true(yield promiseIsURIVisited(uri(visited_uri)));
|
||||
}
|
||||
for (let visited_uri of notcount_visited_URIs) {
|
||||
do_check_true(yield promiseIsURIVisited(uri(visited_uri)));
|
||||
}
|
||||
|
||||
// check that visit_count does not take in count embed and downloads
|
||||
// maxVisits query are directly binded to visit_count
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = options.SORT_BY_VISITCOUNT_DESCENDING;
|
||||
options.resultType = options.RESULTS_AS_VISIT;
|
||||
options.includeHidden = true;
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
query.minVisits = 1;
|
||||
let root = PlacesUtils.history.executeQuery(query, options).root;
|
||||
|
||||
root.containerOpen = true;
|
||||
let cc = root.childCount;
|
||||
do_check_eq(cc, count_visited_URIs.length);
|
||||
|
||||
for (let i = 0; i < cc; i++) {
|
||||
let node = root.getChild(i);
|
||||
do_check_neq(count_visited_URIs.indexOf(node.uri), -1);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
});
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
|
||||
- add a folder
|
||||
- add a folder-shortcut to the new folder
|
||||
- query for the shortcut
|
||||
- remove the folder-shortcut
|
||||
- confirm the shortcut is removed from the query results
|
||||
|
||||
*/
|
||||
|
||||
function run_test() {
|
||||
const IDX = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
var folderId =
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId, "", IDX);
|
||||
|
||||
var queryId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId,
|
||||
uri("place:folder=" + folderId), IDX, "");
|
||||
|
||||
var root = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId, false, true).root;
|
||||
|
||||
var oldCount = root.childCount;
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(queryId);
|
||||
|
||||
do_check_eq(root.childCount, oldCount-1);
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test() {
|
||||
try {
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
} catch (ex) {
|
||||
do_throw("Unable to initialize Places services");
|
||||
}
|
||||
|
||||
// create a query bookmark
|
||||
var queryId = bmsvc.insertBookmark(bmsvc.toolbarFolder, uri("place:"),
|
||||
0 /* first item */, "test query");
|
||||
|
||||
// query for that query
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
var query = histsvc.getNewQuery();
|
||||
query.setFolders([bmsvc.toolbarFolder], 1);
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var queryNode = root.getChild(0);
|
||||
do_check_eq(queryNode.title, "test query");
|
||||
|
||||
// change the title
|
||||
bmsvc.setItemTitle(queryId, "foo");
|
||||
|
||||
// confirm the node was updated
|
||||
do_check_eq(queryNode.title, "foo");
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
try {
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
} catch (ex) {
|
||||
do_throw("Unable to initialize Places services");
|
||||
}
|
||||
|
||||
// add a visit
|
||||
var testURI = uri("http://test");
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
|
||||
// query for the visit
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
options.maxResults = 1;
|
||||
options.resultType = options.RESULTS_AS_URI;
|
||||
var query = histsvc.getNewQuery();
|
||||
query.uri = testURI;
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
|
||||
// check hasChildren while the container is closed
|
||||
do_check_eq(root.hasChildren, true);
|
||||
|
||||
// now check via the saved search path
|
||||
var queryURI = histsvc.queriesToQueryString([query], 1, options);
|
||||
bmsvc.insertBookmark(bmsvc.toolbarFolder, uri(queryURI),
|
||||
0 /* first item */, "test query");
|
||||
|
||||
// query for that query
|
||||
options = histsvc.getNewQueryOptions();
|
||||
query = histsvc.getNewQuery();
|
||||
query.setFolders([bmsvc.toolbarFolder], 1);
|
||||
result = histsvc.executeQuery(query, options);
|
||||
root = result.root;
|
||||
root.containerOpen = true;
|
||||
var queryNode = root.getChild(0);
|
||||
do_check_eq(queryNode.title, "test query");
|
||||
queryNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(queryNode.hasChildren, true);
|
||||
root.containerOpen = false;
|
||||
});
|
||||
36
toolkit/components/places/tests/unit/test_452777.js
Normal file
36
toolkit/components/places/tests/unit/test_452777.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
* vim:set ts=2 sw=2 sts=2 expandtab
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* This test ensures that when removing a folder within a transaction, undoing
|
||||
* the transaction restores it with the same id (as received by the observers).
|
||||
*/
|
||||
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
function run_test()
|
||||
{
|
||||
const TITLE = "test folder";
|
||||
|
||||
// Create two test folders; remove the first one. This ensures that undoing
|
||||
// the removal will not get the same id by chance (the insert id's can be
|
||||
// reused in SQLite).
|
||||
let id = bs.createFolder(bs.placesRoot, TITLE, -1);
|
||||
bs.createFolder(bs.placesRoot, "test folder 2", -1);
|
||||
let transaction = bs.getRemoveFolderTransaction(id);
|
||||
transaction.doTransaction();
|
||||
|
||||
// Now check to make sure it gets added with the right id
|
||||
bs.addObserver({
|
||||
onItemAdded: function(aItemId, aFolder, aIndex, aItemType, aURI, aTitle)
|
||||
{
|
||||
do_check_eq(aItemId, id);
|
||||
do_check_eq(aTitle, TITLE);
|
||||
}
|
||||
}, false);
|
||||
transaction.undoTransaction();
|
||||
}
|
||||
124
toolkit/components/places/tests/unit/test_454977.js
Normal file
124
toolkit/components/places/tests/unit/test_454977.js
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Cache actual visit_count value, filled by add_visit, used by check_results
|
||||
var visit_count = 0;
|
||||
|
||||
// Returns the Place ID corresponding to an added visit.
|
||||
function* task_add_visit(aURI, aVisitType)
|
||||
{
|
||||
// Add the visit asynchronously, and save its visit ID.
|
||||
let deferUpdatePlaces = new Promise((resolve, reject) =>
|
||||
{
|
||||
PlacesUtils.asyncHistory.updatePlaces({
|
||||
uri: aURI,
|
||||
visits: [{ transitionType: aVisitType, visitDate: Date.now() * 1000 }]
|
||||
}, {
|
||||
handleError: function TAV_handleError() {
|
||||
reject(new Error("Unexpected error in adding visit."));
|
||||
},
|
||||
handleResult: function (aPlaceInfo) {
|
||||
this.visitId = aPlaceInfo.visits[0].visitId;
|
||||
},
|
||||
handleCompletion: function TAV_handleCompletion() {
|
||||
resolve(this.visitId);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let visitId = yield deferUpdatePlaces;
|
||||
|
||||
// Increase visit_count if applicable
|
||||
if (aVisitType != 0 &&
|
||||
aVisitType != TRANSITION_EMBED &&
|
||||
aVisitType != TRANSITION_FRAMED_LINK &&
|
||||
aVisitType != TRANSITION_DOWNLOAD &&
|
||||
aVisitType != TRANSITION_RELOAD) {
|
||||
visit_count ++;
|
||||
}
|
||||
|
||||
// Get the place id
|
||||
if (visitId > 0) {
|
||||
let sql = "SELECT place_id FROM moz_historyvisits WHERE id = ?1";
|
||||
let stmt = DBConn().createStatement(sql);
|
||||
stmt.bindByIndex(0, visitId);
|
||||
do_check_true(stmt.executeStep());
|
||||
let placeId = stmt.getInt64(0);
|
||||
stmt.finalize();
|
||||
do_check_true(placeId > 0);
|
||||
return placeId;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for results consistency, using visit_count as constraint
|
||||
* @param aExpectedCount
|
||||
* Number of history results we are expecting (excluded hidden ones)
|
||||
* @param aExpectedCountWithHidden
|
||||
* Number of history results we are expecting (included hidden ones)
|
||||
*/
|
||||
function check_results(aExpectedCount, aExpectedCountWithHidden)
|
||||
{
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
// used to check visit_count
|
||||
query.minVisits = visit_count;
|
||||
query.maxVisits = visit_count;
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
|
||||
let root = PlacesUtils.history.executeQuery(query, options).root;
|
||||
root.containerOpen = true;
|
||||
// Children without hidden ones
|
||||
do_check_eq(root.childCount, aExpectedCount);
|
||||
root.containerOpen = false;
|
||||
|
||||
// Execute again with includeHidden = true
|
||||
// This will ensure visit_count is correct
|
||||
options.includeHidden = true;
|
||||
root = PlacesUtils.history.executeQuery(query, options).root;
|
||||
root.containerOpen = true;
|
||||
// Children with hidden ones
|
||||
do_check_eq(root.childCount, aExpectedCountWithHidden);
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
// main
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
const TEST_URI = uri("http://test.mozilla.org/");
|
||||
|
||||
// Add a visit that force hidden
|
||||
yield task_add_visit(TEST_URI, TRANSITION_EMBED);
|
||||
check_results(0, 0);
|
||||
|
||||
let placeId = yield task_add_visit(TEST_URI, TRANSITION_FRAMED_LINK);
|
||||
check_results(0, 1);
|
||||
|
||||
// Add a visit that force unhide and check the place id.
|
||||
// - We expect that the place gets hidden = 0 while retaining the same
|
||||
// place id and a correct visit_count.
|
||||
do_check_eq((yield task_add_visit(TEST_URI, TRANSITION_TYPED)), placeId);
|
||||
check_results(1, 1);
|
||||
|
||||
// Add a visit that should not increase visit_count
|
||||
do_check_eq((yield task_add_visit(TEST_URI, TRANSITION_RELOAD)), placeId);
|
||||
check_results(1, 1);
|
||||
|
||||
// Add a visit that should not increase visit_count
|
||||
do_check_eq((yield task_add_visit(TEST_URI, TRANSITION_DOWNLOAD)), placeId);
|
||||
check_results(1, 1);
|
||||
|
||||
// Add a visit, check that hidden is not overwritten
|
||||
// - We expect that the place has still hidden = 0, while retaining
|
||||
// correct visit_count.
|
||||
yield task_add_visit(TEST_URI, TRANSITION_EMBED);
|
||||
check_results(1, 1);
|
||||
});
|
||||
60
toolkit/components/places/tests/unit/test_463863.js
Normal file
60
toolkit/components/places/tests/unit/test_463863.js
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* TEST DESCRIPTION:
|
||||
*
|
||||
* This test checks that in a basic history query all transition types visits
|
||||
* appear but TRANSITION_EMBED and TRANSITION_FRAMED_LINK ones.
|
||||
*/
|
||||
|
||||
var transitions = [
|
||||
TRANSITION_LINK
|
||||
, TRANSITION_TYPED
|
||||
, TRANSITION_BOOKMARK
|
||||
, TRANSITION_EMBED
|
||||
, TRANSITION_FRAMED_LINK
|
||||
, TRANSITION_REDIRECT_PERMANENT
|
||||
, TRANSITION_REDIRECT_TEMPORARY
|
||||
, TRANSITION_DOWNLOAD
|
||||
];
|
||||
|
||||
function runQuery(aResultType) {
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.resultType = aResultType;
|
||||
let root = PlacesUtils.history.executeQuery(PlacesUtils.history.getNewQuery(),
|
||||
options).root;
|
||||
root.containerOpen = true;
|
||||
let cc = root.childCount;
|
||||
do_check_eq(cc, transitions.length - 2);
|
||||
|
||||
for (let i = 0; i < cc; i++) {
|
||||
let node = root.getChild(i);
|
||||
// Check that all transition types but EMBED and FRAMED appear in results
|
||||
do_check_neq(node.uri.substr(6, 1), TRANSITION_EMBED);
|
||||
do_check_neq(node.uri.substr(6, 1), TRANSITION_FRAMED_LINK);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
// add visits, one for each transition type
|
||||
for (let transition of transitions) {
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: uri("http://" + transition + ".mozilla.org/"),
|
||||
transition: transition
|
||||
});
|
||||
}
|
||||
|
||||
runQuery(Ci.nsINavHistoryQueryOptions.RESULTS_AS_VISIT);
|
||||
runQuery(Ci.nsINavHistoryQueryOptions.RESULTS_AS_URI);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
function run_test() {
|
||||
var query = hs.getNewQuery();
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULT_TYPE_QUERY;
|
||||
var result = hs.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
var rootNode = result.root;
|
||||
rootNode.QueryInterface(Ci.nsINavHistoryQueryResultNode);
|
||||
var queries = rootNode.getQueries();
|
||||
do_check_eq(queries[0].uri, null); // Should be null, instead of crashing the browser
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* TEST DESCRIPTION:
|
||||
*
|
||||
* This test checks that setting a sort on a RESULTS_AS_DATE_QUERY query,
|
||||
* children of inside containers are sorted accordingly.
|
||||
*/
|
||||
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
// Will be inserted in this order, so last one will be the newest visit.
|
||||
var pages = [
|
||||
"http://a.mozilla.org/1/",
|
||||
"http://a.mozilla.org/2/",
|
||||
"http://a.mozilla.org/3/",
|
||||
"http://a.mozilla.org/4/",
|
||||
"http://b.mozilla.org/5/",
|
||||
"http://b.mozilla.org/6/",
|
||||
"http://b.mozilla.org/7/",
|
||||
"http://b.mozilla.org/8/",
|
||||
];
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_initialize()
|
||||
{
|
||||
var noon = new Date();
|
||||
noon.setHours(12);
|
||||
|
||||
// Add visits.
|
||||
for (let pageIndex = 0; pageIndex < pages.length; ++pageIndex) {
|
||||
let page = pages[pageIndex];
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: uri(page),
|
||||
visitDate: noon - (pages.length - pageIndex) * 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that sorting date query by none will sort by title asc.
|
||||
*/
|
||||
add_task(function() {
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_DATE_QUERY;
|
||||
// This should sort by title asc.
|
||||
options.sortingMode = options.SORT_BY_NONE;
|
||||
var query = hs.getNewQuery();
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var dayContainer = root.getChild(0).QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
dayContainer.containerOpen = true;
|
||||
|
||||
var cc = dayContainer.childCount;
|
||||
do_check_eq(cc, pages.length);
|
||||
for (var i = 0; i < cc; i++) {
|
||||
var node = dayContainer.getChild(i);
|
||||
do_check_eq(pages[i], node.uri);
|
||||
}
|
||||
|
||||
dayContainer.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that sorting date query by date will sort accordingly.
|
||||
*/
|
||||
add_task(function() {
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_DATE_QUERY;
|
||||
// This should sort by title asc.
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
var query = hs.getNewQuery();
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var dayContainer = root.getChild(0).QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
dayContainer.containerOpen = true;
|
||||
|
||||
var cc = dayContainer.childCount;
|
||||
do_check_eq(cc, pages.length);
|
||||
for (var i = 0; i < cc; i++) {
|
||||
var node = dayContainer.getChild(i);
|
||||
do_check_eq(pages[pages.length - i - 1], node.uri);
|
||||
}
|
||||
|
||||
dayContainer.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that sorting date site query by date will still sort by title asc.
|
||||
*/
|
||||
add_task(function() {
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_DATE_SITE_QUERY;
|
||||
// This should sort by title asc.
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
var query = hs.getNewQuery();
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var dayContainer = root.getChild(0).QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
dayContainer.containerOpen = true;
|
||||
var siteContainer = dayContainer.getChild(0).QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(siteContainer.title, "a.mozilla.org");
|
||||
siteContainer.containerOpen = true;
|
||||
|
||||
var cc = siteContainer.childCount;
|
||||
do_check_eq(cc, pages.length / 2);
|
||||
for (var i = 0; i < cc / 2; i++) {
|
||||
var node = siteContainer.getChild(i);
|
||||
do_check_eq(pages[i], node.uri);
|
||||
}
|
||||
|
||||
siteContainer.containerOpen = false;
|
||||
dayContainer.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
});
|
||||
56
toolkit/components/places/tests/unit/test_536081.js
Normal file
56
toolkit/components/places/tests/unit/test_536081.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bh = hs.QueryInterface(Ci.nsIBrowserHistory);
|
||||
var db = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
|
||||
|
||||
const URLS = [
|
||||
{ u: "http://www.google.com/search?q=testing%3Bthis&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:unofficial&client=firefox-a",
|
||||
s: "goog" },
|
||||
];
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
for (let url of URLS) {
|
||||
yield task_test_url(url);
|
||||
}
|
||||
});
|
||||
|
||||
function* task_test_url(aURL) {
|
||||
print("Testing url: " + aURL.u);
|
||||
yield PlacesTestUtils.addVisits(uri(aURL.u));
|
||||
let query = hs.getNewQuery();
|
||||
query.searchTerms = aURL.s;
|
||||
let options = hs.getNewQueryOptions();
|
||||
let root = hs.executeQuery(query, options).root;
|
||||
root.containerOpen = true;
|
||||
let cc = root.childCount;
|
||||
do_check_eq(cc, 1);
|
||||
print("Checking url is in the query.");
|
||||
let node = root.getChild(0);
|
||||
print("Found " + node.uri);
|
||||
root.containerOpen = false;
|
||||
bh.removePage(uri(node.uri));
|
||||
}
|
||||
|
||||
function check_empty_table(table_name) {
|
||||
print("Checking url has been removed.");
|
||||
let stmt = db.createStatement("SELECT count(*) FROM " + table_name);
|
||||
try {
|
||||
stmt.executeStep();
|
||||
do_check_eq(stmt.getInt32(0), 0);
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Cu.import("resource://gre/modules/PlacesSearchAutocompleteProvider.jsm");
|
||||
|
||||
function run_test() {
|
||||
// Tell the search service we are running in the US. This also has the
|
||||
// desired side-effect of preventing our geoip lookup.
|
||||
Services.prefs.setBoolPref("browser.search.isUS", true);
|
||||
Services.prefs.setCharPref("browser.search.countryCode", "US");
|
||||
Services.prefs.setBoolPref("browser.search.geoSpecificDefaults", false);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* search_engine_match() {
|
||||
let engine = yield promiseDefaultSearchEngine();
|
||||
let token = engine.getResultDomain();
|
||||
let match = yield PlacesSearchAutocompleteProvider.findMatchByToken(token.substr(0, 1));
|
||||
do_check_eq(match.url, engine.searchForm);
|
||||
do_check_eq(match.engineName, engine.name);
|
||||
do_check_eq(match.iconUrl, engine.iconURI ? engine.iconURI.spec : null);
|
||||
});
|
||||
|
||||
add_task(function* no_match() {
|
||||
do_check_eq(null, yield PlacesSearchAutocompleteProvider.findMatchByToken("test"));
|
||||
});
|
||||
|
||||
add_task(function* hide_search_engine_nomatch() {
|
||||
let engine = yield promiseDefaultSearchEngine();
|
||||
let token = engine.getResultDomain();
|
||||
let promiseTopic = promiseSearchTopic("engine-changed");
|
||||
Services.search.removeEngine(engine);
|
||||
yield promiseTopic;
|
||||
do_check_true(engine.hidden);
|
||||
do_check_eq(null, yield PlacesSearchAutocompleteProvider.findMatchByToken(token.substr(0, 1)));
|
||||
});
|
||||
|
||||
add_task(function* add_search_engine_match() {
|
||||
let promiseTopic = promiseSearchTopic("engine-added");
|
||||
do_check_eq(null, yield PlacesSearchAutocompleteProvider.findMatchByToken("bacon"));
|
||||
Services.search.addEngineWithDetails("bacon", "", "pork", "Search Bacon",
|
||||
"GET", "http://www.bacon.moz/?search={searchTerms}");
|
||||
yield promiseTopic;
|
||||
let match = yield PlacesSearchAutocompleteProvider.findMatchByToken("bacon");
|
||||
do_check_eq(match.url, "http://www.bacon.moz");
|
||||
do_check_eq(match.engineName, "bacon");
|
||||
do_check_eq(match.iconUrl, null);
|
||||
});
|
||||
|
||||
add_task(function* test_aliased_search_engine_match() {
|
||||
do_check_eq(null, yield PlacesSearchAutocompleteProvider.findMatchByAlias("sober"));
|
||||
// Lower case
|
||||
let match = yield PlacesSearchAutocompleteProvider.findMatchByAlias("pork");
|
||||
do_check_eq(match.engineName, "bacon");
|
||||
do_check_eq(match.alias, "pork");
|
||||
do_check_eq(match.iconUrl, null);
|
||||
// Upper case
|
||||
let match1 = yield PlacesSearchAutocompleteProvider.findMatchByAlias("PORK");
|
||||
do_check_eq(match1.engineName, "bacon");
|
||||
do_check_eq(match1.alias, "pork");
|
||||
do_check_eq(match1.iconUrl, null);
|
||||
// Cap case
|
||||
let match2 = yield PlacesSearchAutocompleteProvider.findMatchByAlias("Pork");
|
||||
do_check_eq(match2.engineName, "bacon");
|
||||
do_check_eq(match2.alias, "pork");
|
||||
do_check_eq(match2.iconUrl, null);
|
||||
});
|
||||
|
||||
add_task(function* test_aliased_search_engine_match_upper_case_alias() {
|
||||
let promiseTopic = promiseSearchTopic("engine-added");
|
||||
do_check_eq(null, yield PlacesSearchAutocompleteProvider.findMatchByToken("patch"));
|
||||
Services.search.addEngineWithDetails("patch", "", "PR", "Search Patch",
|
||||
"GET", "http://www.patch.moz/?search={searchTerms}");
|
||||
yield promiseTopic;
|
||||
// lower case
|
||||
let match = yield PlacesSearchAutocompleteProvider.findMatchByAlias("pr");
|
||||
do_check_eq(match.engineName, "patch");
|
||||
do_check_eq(match.alias, "PR");
|
||||
do_check_eq(match.iconUrl, null);
|
||||
// Upper case
|
||||
let match1 = yield PlacesSearchAutocompleteProvider.findMatchByAlias("PR");
|
||||
do_check_eq(match1.engineName, "patch");
|
||||
do_check_eq(match1.alias, "PR");
|
||||
do_check_eq(match1.iconUrl, null);
|
||||
// Cap case
|
||||
let match2 = yield PlacesSearchAutocompleteProvider.findMatchByAlias("Pr");
|
||||
do_check_eq(match2.engineName, "patch");
|
||||
do_check_eq(match2.alias, "PR");
|
||||
do_check_eq(match2.iconUrl, null);
|
||||
});
|
||||
|
||||
add_task(function* remove_search_engine_nomatch() {
|
||||
let engine = Services.search.getEngineByName("bacon");
|
||||
let promiseTopic = promiseSearchTopic("engine-removed");
|
||||
Services.search.removeEngine(engine);
|
||||
yield promiseTopic;
|
||||
do_check_eq(null, yield PlacesSearchAutocompleteProvider.findMatchByToken("bacon"));
|
||||
});
|
||||
|
||||
add_task(function* test_parseSubmissionURL_basic() {
|
||||
// Most of the logic of parseSubmissionURL is tested in the search service
|
||||
// itself, thus we only do a sanity check of the wrapper here.
|
||||
let engine = yield promiseDefaultSearchEngine();
|
||||
let submissionURL = engine.getSubmission("terms").uri.spec;
|
||||
|
||||
let result = PlacesSearchAutocompleteProvider.parseSubmissionURL(submissionURL);
|
||||
do_check_eq(result.engineName, engine.name);
|
||||
do_check_eq(result.terms, "terms");
|
||||
|
||||
result = PlacesSearchAutocompleteProvider.parseSubmissionURL("http://example.org/");
|
||||
do_check_eq(result, null);
|
||||
});
|
||||
|
||||
function promiseDefaultSearchEngine() {
|
||||
let deferred = Promise.defer();
|
||||
Services.search.init( () => {
|
||||
deferred.resolve(Services.search.defaultEngine);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function promiseSearchTopic(expectedVerb) {
|
||||
let deferred = Promise.defer();
|
||||
Services.obs.addObserver( function observe(subject, topic, verb) {
|
||||
do_print("browser-search-engine-modified: " + verb);
|
||||
if (verb == expectedVerb) {
|
||||
Services.obs.removeObserver(observe, "browser-search-engine-modified");
|
||||
deferred.resolve();
|
||||
}
|
||||
}, "browser-search-engine-modified", false);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* This file tests PlacesUtils.asyncGetBookmarkIds method.
|
||||
*/
|
||||
|
||||
const TEST_URL = "http://www.example.com/";
|
||||
|
||||
var promiseAsyncGetBookmarkIds = Task.async(function* (url) {
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
return new Promise(resolve => {
|
||||
PlacesUtils.asyncGetBookmarkIds(url, (itemIds, uri) => {
|
||||
Assert.equal(uri, url);
|
||||
resolve({ itemIds, url });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* test_no_bookmark() {
|
||||
let { itemIds, url } = yield promiseAsyncGetBookmarkIds(TEST_URL);
|
||||
Assert.equal(itemIds.length, 0);
|
||||
Assert.equal(url, TEST_URL);
|
||||
});
|
||||
|
||||
add_task(function* test_one_bookmark() {
|
||||
let bookmark = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: TEST_URL,
|
||||
title: "test"
|
||||
});
|
||||
let itemId = yield PlacesUtils.promiseItemId(bookmark.guid);
|
||||
{
|
||||
let { itemIds, url } = yield promiseAsyncGetBookmarkIds(NetUtil.newURI(TEST_URL));
|
||||
Assert.equal(itemIds.length, 1);
|
||||
Assert.equal(itemIds[0], itemId);
|
||||
Assert.equal(url.spec, TEST_URL);
|
||||
}
|
||||
{
|
||||
let { itemIds, url } = yield promiseAsyncGetBookmarkIds(TEST_URL);
|
||||
Assert.equal(itemIds.length, 1);
|
||||
Assert.equal(itemIds[0], itemId);
|
||||
Assert.equal(url, TEST_URL);
|
||||
}
|
||||
yield PlacesUtils.bookmarks.remove(bookmark);
|
||||
});
|
||||
|
||||
add_task(function* test_multiple_bookmarks() {
|
||||
let ids = [];
|
||||
let bookmark1 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: TEST_URL,
|
||||
title: "test"
|
||||
});
|
||||
ids.push((yield PlacesUtils.promiseItemId(bookmark1.guid)));
|
||||
let bookmark2 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: TEST_URL,
|
||||
title: "test"
|
||||
});
|
||||
ids.push((yield PlacesUtils.promiseItemId(bookmark2.guid)));
|
||||
|
||||
let { itemIds, url } = yield promiseAsyncGetBookmarkIds(TEST_URL);
|
||||
Assert.deepEqual(ids, itemIds);
|
||||
Assert.equal(url, TEST_URL);
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(bookmark1);
|
||||
yield PlacesUtils.bookmarks.remove(bookmark2);
|
||||
});
|
||||
|
||||
add_task(function* test_cancel() {
|
||||
let pending = PlacesUtils.asyncGetBookmarkIds(TEST_URL, () => {
|
||||
Assert.ok(false, "A canceled pending statement should not be invoked");
|
||||
});
|
||||
pending.cancel();
|
||||
|
||||
let { itemIds, url } = yield promiseAsyncGetBookmarkIds(TEST_URL);
|
||||
Assert.equal(itemIds.length, 0);
|
||||
Assert.equal(url, TEST_URL);
|
||||
});
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
add_task(function* () {
|
||||
do_print("Add a bookmark.");
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let id = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
Assert.equal((yield PlacesUtils.promiseItemGuid(id)), bm.guid);
|
||||
|
||||
// Ensure invalidating a non-existent itemId doesn't throw.
|
||||
PlacesUtils.invalidateCachedGuidFor(null);
|
||||
PlacesUtils.invalidateCachedGuidFor(9999);
|
||||
|
||||
do_print("Change the GUID.");
|
||||
yield PlacesUtils.withConnectionWrapper("test", Task.async(function*(db) {
|
||||
yield db.execute("UPDATE moz_bookmarks SET guid = :guid WHERE id = :id",
|
||||
{ guid: "123456789012", id});
|
||||
}));
|
||||
// The cache should still point to the wrong id.
|
||||
Assert.equal((yield PlacesUtils.promiseItemGuid(id)), bm.guid);
|
||||
|
||||
do_print("Invalidate the cache.");
|
||||
PlacesUtils.invalidateCachedGuidFor(id);
|
||||
Assert.equal((yield PlacesUtils.promiseItemGuid(id)), "123456789012");
|
||||
Assert.equal((yield PlacesUtils.promiseItemId("123456789012")), id);
|
||||
yield Assert.rejects(PlacesUtils.promiseItemId(bm.guid), /no item found for the given GUID/);
|
||||
});
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
|
||||
const TEST_URI = NetUtil.newURI("http://moz.org/")
|
||||
let observer = {
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsINavBookmarkObserver,
|
||||
]),
|
||||
|
||||
onBeginUpdateBatch: function () {},
|
||||
onEndUpdateBatch: function () {},
|
||||
onItemAdded: function (aItemId, aParentId, aIndex, aItemType, aURI) {
|
||||
do_check_true(aURI.equals(TEST_URI));
|
||||
PlacesUtils.removeLazyBookmarkObserver(this);
|
||||
do_test_finished();
|
||||
},
|
||||
onItemRemoved: function () {},
|
||||
onItemChanged: function () {},
|
||||
onItemVisited: function () {},
|
||||
onItemMoved: function () {},
|
||||
};
|
||||
|
||||
// Check registration and removal with uninitialized bookmarks service.
|
||||
PlacesUtils.addLazyBookmarkObserver(observer);
|
||||
PlacesUtils.removeLazyBookmarkObserver(observer);
|
||||
|
||||
// Add a proper lazy observer we will test.
|
||||
PlacesUtils.addLazyBookmarkObserver(observer);
|
||||
|
||||
// Check that we don't leak when adding and removing an observer while the
|
||||
// bookmarks service is instantiated but no change happened (bug 721319).
|
||||
PlacesUtils.bookmarks;
|
||||
PlacesUtils.addLazyBookmarkObserver(observer);
|
||||
PlacesUtils.removeLazyBookmarkObserver(observer);
|
||||
try {
|
||||
PlacesUtils.bookmarks.removeObserver(observer);
|
||||
do_throw("Trying to remove a nonexisting observer should throw!");
|
||||
} catch (ex) {}
|
||||
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"Bookmark title");
|
||||
}
|
||||
406
toolkit/components/places/tests/unit/test_adaptive.js
Normal file
406
toolkit/components/places/tests/unit/test_adaptive.js
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Test for bug 395739 to make sure the feedback to the search results in those
|
||||
* entries getting better ranks. Additionally, exact matches should be ranked
|
||||
* higher. Because the interactions among adaptive rank and visit counts is not
|
||||
* well defined, this test holds one of the two values constant when modifying
|
||||
* the other.
|
||||
*
|
||||
* This also tests bug 395735 for the instrumentation feedback mechanism.
|
||||
*
|
||||
* Bug 411293 is tested to make sure the drop down strongly prefers previously
|
||||
* typed pages that have been selected and are moved to the top with adaptive
|
||||
* learning.
|
||||
*/
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
get minResultsForPopup() {
|
||||
return 0;
|
||||
},
|
||||
get timeout() {
|
||||
return 10;
|
||||
},
|
||||
get searchParam() {
|
||||
return "";
|
||||
},
|
||||
get textValue() {
|
||||
return "";
|
||||
},
|
||||
get disableAutoComplete() {
|
||||
return false;
|
||||
},
|
||||
get completeDefaultIndex() {
|
||||
return false;
|
||||
},
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
getSearchAt: function (aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function () {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
get popupOpen() {
|
||||
return false;
|
||||
},
|
||||
popup: {
|
||||
set selectedIndex(aIndex) {},
|
||||
invalidate: function () {},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup])
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput])
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that autocomplete results are ordered correctly.
|
||||
*/
|
||||
function ensure_results(expected, searchTerm)
|
||||
{
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete.
|
||||
let input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
|
||||
controller.input = input;
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
do_check_eq(controller.matchCount, expected.length);
|
||||
for (let i = 0; i < controller.matchCount; i++) {
|
||||
print("Testing for '" + expected[i].uri.spec + "' got '" + controller.getValueAt(i) + "'");
|
||||
do_check_eq(controller.getValueAt(i), expected[i].uri.spec);
|
||||
do_check_eq(controller.getStyleAt(i), expected[i].style);
|
||||
}
|
||||
|
||||
deferEnsureResults.resolve();
|
||||
};
|
||||
|
||||
controller.startSearch(searchTerm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronous task that bumps up the rank for an uri.
|
||||
*/
|
||||
function* task_setCountRank(aURI, aCount, aRank, aSearch, aBookmark)
|
||||
{
|
||||
// Bump up the visit count for the uri.
|
||||
let visits = [];
|
||||
for (let i = 0; i < aCount; i++) {
|
||||
visits.push({ uri: aURI, visitDate: d1, transition: TRANSITION_TYPED });
|
||||
}
|
||||
yield PlacesTestUtils.addVisits(visits);
|
||||
|
||||
// Make a nsIAutoCompleteController and friends for instrumentation feedback.
|
||||
let thing = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput,
|
||||
Ci.nsIAutoCompletePopup,
|
||||
Ci.nsIAutoCompleteController]),
|
||||
get popup() {
|
||||
return thing;
|
||||
},
|
||||
get controller() {
|
||||
return thing;
|
||||
},
|
||||
popupOpen: true,
|
||||
selectedIndex: 0,
|
||||
getValueAt: function() {
|
||||
return aURI.spec;
|
||||
},
|
||||
searchString: aSearch
|
||||
};
|
||||
|
||||
// Bump up the instrumentation feedback.
|
||||
for (let i = 0; i < aRank; i++) {
|
||||
Services.obs.notifyObservers(thing, "autocomplete-will-enter-text", null);
|
||||
}
|
||||
|
||||
// If this is supposed to be a bookmark, add it.
|
||||
if (aBookmark) {
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
aURI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test_book");
|
||||
|
||||
// And add the tag if we need to.
|
||||
if (aBookmark == "tag") {
|
||||
PlacesUtils.tagging.tagURI(aURI, ["test_tag"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decay the adaptive entries by sending the daily idle topic.
|
||||
*/
|
||||
function doAdaptiveDecay()
|
||||
{
|
||||
PlacesUtils.history.runInBatchMode({
|
||||
runBatched: function() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
PlacesUtils.history.QueryInterface(Ci.nsIObserver)
|
||||
.observe(null, "idle-daily", null);
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
var uri1 = uri("http://site.tld/1");
|
||||
var uri2 = uri("http://site.tld/2");
|
||||
|
||||
// d1 is some date for the page visit
|
||||
var d1 = new Date(Date.now() - 1000 * 60 * 60) * 1000;
|
||||
// c1 is larger (should show up higher) than c2
|
||||
var c1 = 10;
|
||||
var c2 = 1;
|
||||
// s1 is a partial match of s2
|
||||
var s0 = "";
|
||||
var s1 = "si";
|
||||
var s2 = "site";
|
||||
|
||||
var observer = {
|
||||
results: null,
|
||||
search: null,
|
||||
runCount: -1,
|
||||
observe: function(aSubject, aTopic, aData)
|
||||
{
|
||||
if (--this.runCount > 0)
|
||||
return;
|
||||
ensure_results(this.results, this.search);
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, PlacesUtils.TOPIC_FEEDBACK_UPDATED, false);
|
||||
|
||||
/**
|
||||
* Make the result object for a given URI that will be passed to ensure_results.
|
||||
*/
|
||||
function makeResult(aURI, aStyle = "favicon") {
|
||||
return {
|
||||
uri: aURI,
|
||||
style: aStyle,
|
||||
};
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test things without a search term.
|
||||
function*() {
|
||||
print("Test 0 same count, diff rank, same term; no search");
|
||||
observer.results = [
|
||||
makeResult(uri1),
|
||||
makeResult(uri2),
|
||||
];
|
||||
observer.search = s0;
|
||||
observer.runCount = c1 + c2;
|
||||
yield task_setCountRank(uri1, c1, c1, s2);
|
||||
yield task_setCountRank(uri2, c1, c2, s2);
|
||||
},
|
||||
function*() {
|
||||
print("Test 1 same count, diff rank, same term; no search");
|
||||
observer.results = [
|
||||
makeResult(uri2),
|
||||
makeResult(uri1),
|
||||
];
|
||||
observer.search = s0;
|
||||
observer.runCount = c1 + c2;
|
||||
yield task_setCountRank(uri1, c1, c2, s2);
|
||||
yield task_setCountRank(uri2, c1, c1, s2);
|
||||
},
|
||||
function*() {
|
||||
print("Test 2 diff count, same rank, same term; no search");
|
||||
observer.results = [
|
||||
makeResult(uri1),
|
||||
makeResult(uri2),
|
||||
];
|
||||
observer.search = s0;
|
||||
observer.runCount = c1 + c1;
|
||||
yield task_setCountRank(uri1, c1, c1, s2);
|
||||
yield task_setCountRank(uri2, c2, c1, s2);
|
||||
},
|
||||
function*() {
|
||||
print("Test 3 diff count, same rank, same term; no search");
|
||||
observer.results = [
|
||||
makeResult(uri2),
|
||||
makeResult(uri1),
|
||||
];
|
||||
observer.search = s0;
|
||||
observer.runCount = c1 + c1;
|
||||
yield task_setCountRank(uri1, c2, c1, s2);
|
||||
yield task_setCountRank(uri2, c1, c1, s2);
|
||||
},
|
||||
|
||||
// Test things with a search term (exact match one, partial other).
|
||||
function*() {
|
||||
print("Test 4 same count, same rank, diff term; one exact/one partial search");
|
||||
observer.results = [
|
||||
makeResult(uri1),
|
||||
makeResult(uri2),
|
||||
];
|
||||
observer.search = s1;
|
||||
observer.runCount = c1 + c1;
|
||||
yield task_setCountRank(uri1, c1, c1, s1);
|
||||
yield task_setCountRank(uri2, c1, c1, s2);
|
||||
},
|
||||
function*() {
|
||||
print("Test 5 same count, same rank, diff term; one exact/one partial search");
|
||||
observer.results = [
|
||||
makeResult(uri2),
|
||||
makeResult(uri1),
|
||||
];
|
||||
observer.search = s1;
|
||||
observer.runCount = c1 + c1;
|
||||
yield task_setCountRank(uri1, c1, c1, s2);
|
||||
yield task_setCountRank(uri2, c1, c1, s1);
|
||||
},
|
||||
|
||||
// Test things with a search term (exact match both).
|
||||
function*() {
|
||||
print("Test 6 same count, diff rank, same term; both exact search");
|
||||
observer.results = [
|
||||
makeResult(uri1),
|
||||
makeResult(uri2),
|
||||
];
|
||||
observer.search = s1;
|
||||
observer.runCount = c1 + c2;
|
||||
yield task_setCountRank(uri1, c1, c1, s1);
|
||||
yield task_setCountRank(uri2, c1, c2, s1);
|
||||
},
|
||||
function*() {
|
||||
print("Test 7 same count, diff rank, same term; both exact search");
|
||||
observer.results = [
|
||||
makeResult(uri2),
|
||||
makeResult(uri1),
|
||||
];
|
||||
observer.search = s1;
|
||||
observer.runCount = c1 + c2;
|
||||
yield task_setCountRank(uri1, c1, c2, s1);
|
||||
yield task_setCountRank(uri2, c1, c1, s1);
|
||||
},
|
||||
|
||||
// Test things with a search term (partial match both).
|
||||
function*() {
|
||||
print("Test 8 same count, diff rank, same term; both partial search");
|
||||
observer.results = [
|
||||
makeResult(uri1),
|
||||
makeResult(uri2),
|
||||
];
|
||||
observer.search = s1;
|
||||
observer.runCount = c1 + c2;
|
||||
yield task_setCountRank(uri1, c1, c1, s2);
|
||||
yield task_setCountRank(uri2, c1, c2, s2);
|
||||
},
|
||||
function*() {
|
||||
print("Test 9 same count, diff rank, same term; both partial search");
|
||||
observer.results = [
|
||||
makeResult(uri2),
|
||||
makeResult(uri1),
|
||||
];
|
||||
observer.search = s1;
|
||||
observer.runCount = c1 + c2;
|
||||
yield task_setCountRank(uri1, c1, c2, s2);
|
||||
yield task_setCountRank(uri2, c1, c1, s2);
|
||||
},
|
||||
function*() {
|
||||
print("Test 10 same count, same rank, same term, decay first; exact match");
|
||||
observer.results = [
|
||||
makeResult(uri2),
|
||||
makeResult(uri1),
|
||||
];
|
||||
observer.search = s1;
|
||||
observer.runCount = c1 + c1;
|
||||
yield task_setCountRank(uri1, c1, c1, s1);
|
||||
doAdaptiveDecay();
|
||||
yield task_setCountRank(uri2, c1, c1, s1);
|
||||
},
|
||||
function*() {
|
||||
print("Test 11 same count, same rank, same term, decay second; exact match");
|
||||
observer.results = [
|
||||
makeResult(uri1),
|
||||
makeResult(uri2),
|
||||
];
|
||||
observer.search = s1;
|
||||
observer.runCount = c1 + c1;
|
||||
yield task_setCountRank(uri2, c1, c1, s1);
|
||||
doAdaptiveDecay();
|
||||
yield task_setCountRank(uri1, c1, c1, s1);
|
||||
},
|
||||
// Test that bookmarks are hidden if the preferences are set right.
|
||||
function*() {
|
||||
print("Test 12 same count, diff rank, same term; no search; history only");
|
||||
Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
|
||||
Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", false);
|
||||
Services.prefs.setBoolPref("browser.urlbar.suggest.openpage", false);
|
||||
observer.results = [
|
||||
makeResult(uri1),
|
||||
makeResult(uri2),
|
||||
];
|
||||
observer.search = s0;
|
||||
observer.runCount = c1 + c2;
|
||||
yield task_setCountRank(uri1, c1, c1, s2, "bookmark");
|
||||
yield task_setCountRank(uri2, c1, c2, s2);
|
||||
},
|
||||
// Test that tags are shown if the preferences are set right.
|
||||
function*() {
|
||||
print("Test 13 same count, diff rank, same term; no search; history only with tag");
|
||||
Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
|
||||
Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", false);
|
||||
Services.prefs.setBoolPref("browser.urlbar.suggest.openpage", false);
|
||||
observer.results = [
|
||||
makeResult(uri1, "tag"),
|
||||
makeResult(uri2),
|
||||
];
|
||||
observer.search = s0;
|
||||
observer.runCount = c1 + c2;
|
||||
yield task_setCountRank(uri1, c1, c1, s2, "tag");
|
||||
yield task_setCountRank(uri2, c1, c2, s2);
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* This deferred object contains a promise that is resolved when the
|
||||
* ensure_results function has finished its execution.
|
||||
*/
|
||||
var deferEnsureResults;
|
||||
|
||||
/**
|
||||
* Test adaptive autocomplete.
|
||||
*/
|
||||
add_task(function* test_adaptive()
|
||||
{
|
||||
// Disable autoFill for this test.
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill", false);
|
||||
do_register_cleanup(() => Services.prefs.clearUserPref("browser.urlbar.autoFill"));
|
||||
for (let test of tests) {
|
||||
// Cleanup.
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.tagsFolderId);
|
||||
observer.runCount = -1;
|
||||
|
||||
let types = ["history", "bookmark", "openpage"];
|
||||
for (let type of types) {
|
||||
Services.prefs.clearUserPref("browser.urlbar.suggest." + type);
|
||||
}
|
||||
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
|
||||
deferEnsureResults = Promise.defer();
|
||||
yield test();
|
||||
yield deferEnsureResults.promise;
|
||||
}
|
||||
|
||||
Services.obs.removeObserver(observer, PlacesUtils.TOPIC_FEEDBACK_UPDATED);
|
||||
});
|
||||
141
toolkit/components/places/tests/unit/test_adaptive_bug527311.js
Normal file
141
toolkit/components/places/tests/unit/test_adaptive_bug527311.js
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const TEST_URL = "http://adapt.mozilla.org/";
|
||||
const SEARCH_STRING = "adapt";
|
||||
const SUGGEST_TYPES = ["history", "bookmark", "openpage"];
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
var ps = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
|
||||
const PLACES_AUTOCOMPLETE_FEEDBACK_UPDATED_TOPIC =
|
||||
"places-autocomplete-feedback-updated";
|
||||
|
||||
function cleanup() {
|
||||
for (let type of SUGGEST_TYPES) {
|
||||
ps.clearUserPref("browser.urlbar.suggest." + type);
|
||||
}
|
||||
}
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
searches: null,
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function ACI_getSearchAt(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchComplete: function ACI_onSearchComplete() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function() {},
|
||||
invalidate: function() {},
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function check_results() {
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
let input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
controller.input = input;
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH);
|
||||
do_check_eq(controller.matchCount, 0);
|
||||
|
||||
PlacesUtils.bookmarks.eraseEverything().then(() => {
|
||||
cleanup();
|
||||
do_test_finished();
|
||||
});
|
||||
};
|
||||
|
||||
controller.startSearch(SEARCH_STRING);
|
||||
}
|
||||
|
||||
|
||||
function addAdaptiveFeedback(aUrl, aSearch, aCallback) {
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
os.removeObserver(observer, PLACES_AUTOCOMPLETE_FEEDBACK_UPDATED_TOPIC);
|
||||
do_timeout(0, aCallback);
|
||||
}
|
||||
};
|
||||
os.addObserver(observer, PLACES_AUTOCOMPLETE_FEEDBACK_UPDATED_TOPIC, false);
|
||||
|
||||
let thing = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput,
|
||||
Ci.nsIAutoCompletePopup,
|
||||
Ci.nsIAutoCompleteController]),
|
||||
get popup() { return thing; },
|
||||
get controller() { return thing; },
|
||||
popupOpen: true,
|
||||
selectedIndex: 0,
|
||||
getValueAt: () => aUrl,
|
||||
searchString: aSearch
|
||||
};
|
||||
|
||||
os.notifyObservers(thing, "autocomplete-will-enter-text", null);
|
||||
}
|
||||
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
|
||||
// Add a bookmark to our url.
|
||||
bs.insertBookmark(bs.unfiledBookmarksFolder, uri(TEST_URL),
|
||||
bs.DEFAULT_INDEX, "test_book");
|
||||
// We want to search only history.
|
||||
for (let type of SUGGEST_TYPES) {
|
||||
type == "history" ? ps.setBoolPref("browser.urlbar.suggest." + type, true)
|
||||
: ps.setBoolPref("browser.urlbar.suggest." + type, false);
|
||||
}
|
||||
|
||||
// Add an adaptive entry.
|
||||
addAdaptiveFeedback(TEST_URL, SEARCH_STRING, check_results);
|
||||
}
|
||||
28
toolkit/components/places/tests/unit/test_analyze.js
Normal file
28
toolkit/components/places/tests/unit/test_analyze.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests sqlite_sta1 table exists, it should be created by analyze.
|
||||
// Since the bookmark roots are created when the DB is created (bug 704855),
|
||||
// the table will contain data.
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
|
||||
let stmt = DBConn().createAsyncStatement(
|
||||
"SELECT ROWID FROM sqlite_stat1"
|
||||
);
|
||||
stmt.executeAsync({
|
||||
_gotResult: false,
|
||||
handleResult: function(aResultSet) {
|
||||
this._gotResult = true;
|
||||
},
|
||||
handleError: function(aError) {
|
||||
do_throw("Unexpected error (" + aError.result + "): " + aError.message);
|
||||
},
|
||||
handleCompletion: function(aReason) {
|
||||
do_check_true(this._gotResult);
|
||||
do_test_finished();
|
||||
}
|
||||
});
|
||||
stmt.finalize();
|
||||
}
|
||||
363
toolkit/components/places/tests/unit/test_annotations.js
Normal file
363
toolkit/components/places/tests/unit/test_annotations.js
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get bookmark service
|
||||
try {
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get nav-bookmarks-service\n");
|
||||
}
|
||||
|
||||
// Get annotation service
|
||||
try {
|
||||
var annosvc= Cc["@mozilla.org/browser/annotation-service;1"].getService(Ci.nsIAnnotationService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get annotation service\n");
|
||||
}
|
||||
|
||||
var annoObserver = {
|
||||
PAGE_lastSet_URI: "",
|
||||
PAGE_lastSet_AnnoName: "",
|
||||
|
||||
onPageAnnotationSet: function(aURI, aName) {
|
||||
this.PAGE_lastSet_URI = aURI.spec;
|
||||
this.PAGE_lastSet_AnnoName = aName;
|
||||
},
|
||||
|
||||
ITEM_lastSet_Id: -1,
|
||||
ITEM_lastSet_AnnoName: "",
|
||||
onItemAnnotationSet: function(aItemId, aName) {
|
||||
this.ITEM_lastSet_Id = aItemId;
|
||||
this.ITEM_lastSet_AnnoName = aName;
|
||||
},
|
||||
|
||||
PAGE_lastRemoved_URI: "",
|
||||
PAGE_lastRemoved_AnnoName: "",
|
||||
onPageAnnotationRemoved: function(aURI, aName) {
|
||||
this.PAGE_lastRemoved_URI = aURI.spec;
|
||||
this.PAGE_lastRemoved_AnnoName = aName;
|
||||
},
|
||||
|
||||
ITEM_lastRemoved_Id: -1,
|
||||
ITEM_lastRemoved_AnnoName: "",
|
||||
onItemAnnotationRemoved: function(aItemId, aName) {
|
||||
this.ITEM_lastRemoved_Id = aItemId;
|
||||
this.ITEM_lastRemoved_AnnoName = aName;
|
||||
}
|
||||
};
|
||||
|
||||
// main
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
var testURI = uri("http://mozilla.com/");
|
||||
var testItemId = bmsvc.insertBookmark(bmsvc.bookmarksMenuFolder, testURI, -1, "");
|
||||
var testAnnoName = "moz-test-places/annotations";
|
||||
var testAnnoVal = "test";
|
||||
|
||||
annosvc.addObserver(annoObserver);
|
||||
// create new string annotation
|
||||
try {
|
||||
annosvc.setPageAnnotation(testURI, testAnnoName, testAnnoVal, 0, 0);
|
||||
} catch (ex) {
|
||||
do_throw("unable to add page-annotation");
|
||||
}
|
||||
do_check_eq(annoObserver.PAGE_lastSet_URI, testURI.spec);
|
||||
do_check_eq(annoObserver.PAGE_lastSet_AnnoName, testAnnoName);
|
||||
|
||||
// get string annotation
|
||||
do_check_true(annosvc.pageHasAnnotation(testURI, testAnnoName));
|
||||
var storedAnnoVal = annosvc.getPageAnnotation(testURI, testAnnoName);
|
||||
do_check_true(testAnnoVal === storedAnnoVal);
|
||||
// string item-annotation
|
||||
try {
|
||||
var lastModified = bmsvc.getItemLastModified(testItemId);
|
||||
// Verify that lastModified equals dateAdded before we set the annotation.
|
||||
do_check_eq(lastModified, bmsvc.getItemDateAdded(testItemId));
|
||||
// Workaround possible VM timers issues moving last modified to the past.
|
||||
bmsvc.setItemLastModified(testItemId, --lastModified);
|
||||
annosvc.setItemAnnotation(testItemId, testAnnoName, testAnnoVal, 0, 0);
|
||||
var lastModified2 = bmsvc.getItemLastModified(testItemId);
|
||||
// verify that setting the annotation updates the last modified time
|
||||
do_check_true(lastModified2 > lastModified);
|
||||
} catch (ex) {
|
||||
do_throw("unable to add item annotation");
|
||||
}
|
||||
do_check_eq(annoObserver.ITEM_lastSet_Id, testItemId);
|
||||
do_check_eq(annoObserver.ITEM_lastSet_AnnoName, testAnnoName);
|
||||
|
||||
try {
|
||||
var annoVal = annosvc.getItemAnnotation(testItemId, testAnnoName);
|
||||
// verify the anno value
|
||||
do_check_true(testAnnoVal === annoVal);
|
||||
} catch (ex) {
|
||||
do_throw("unable to get item annotation");
|
||||
}
|
||||
|
||||
// test getPagesWithAnnotation
|
||||
var uri2 = uri("http://www.tests.tld");
|
||||
yield PlacesTestUtils.addVisits(uri2);
|
||||
annosvc.setPageAnnotation(uri2, testAnnoName, testAnnoVal, 0, 0);
|
||||
var pages = annosvc.getPagesWithAnnotation(testAnnoName);
|
||||
do_check_eq(pages.length, 2);
|
||||
// Don't rely on the order
|
||||
do_check_false(pages[0].equals(pages[1]));
|
||||
do_check_true(pages[0].equals(testURI) || pages[1].equals(testURI));
|
||||
do_check_true(pages[0].equals(uri2) || pages[1].equals(uri2));
|
||||
|
||||
// test getItemsWithAnnotation
|
||||
var testItemId2 = bmsvc.insertBookmark(bmsvc.bookmarksMenuFolder, uri2, -1, "");
|
||||
annosvc.setItemAnnotation(testItemId2, testAnnoName, testAnnoVal, 0, 0);
|
||||
var items = annosvc.getItemsWithAnnotation(testAnnoName);
|
||||
do_check_eq(items.length, 2);
|
||||
// Don't rely on the order
|
||||
do_check_true(items[0] != items[1]);
|
||||
do_check_true(items[0] == testItemId || items[1] == testItemId);
|
||||
do_check_true(items[0] == testItemId2 || items[1] == testItemId2);
|
||||
|
||||
// get annotation that doesn't exist
|
||||
try {
|
||||
annosvc.getPageAnnotation(testURI, "blah");
|
||||
do_throw("fetching page-annotation that doesn't exist, should've thrown");
|
||||
} catch (ex) {}
|
||||
try {
|
||||
annosvc.getItemAnnotation(testURI, "blah");
|
||||
do_throw("fetching item-annotation that doesn't exist, should've thrown");
|
||||
} catch (ex) {}
|
||||
|
||||
// get annotation info
|
||||
var flags = {}, exp = {}, storageType = {};
|
||||
annosvc.getPageAnnotationInfo(testURI, testAnnoName, flags, exp, storageType);
|
||||
do_check_eq(flags.value, 0);
|
||||
do_check_eq(exp.value, 0);
|
||||
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_STRING);
|
||||
annosvc.getItemAnnotationInfo(testItemId, testAnnoName, flags, exp, storageType);
|
||||
do_check_eq(flags.value, 0);
|
||||
do_check_eq(exp.value, 0);
|
||||
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_STRING);
|
||||
|
||||
// get annotation names for a uri
|
||||
var annoNames = annosvc.getPageAnnotationNames(testURI);
|
||||
do_check_eq(annoNames.length, 1);
|
||||
do_check_eq(annoNames[0], "moz-test-places/annotations");
|
||||
|
||||
// get annotation names for an item
|
||||
annoNames = annosvc.getItemAnnotationNames(testItemId);
|
||||
do_check_eq(annoNames.length, 1);
|
||||
do_check_eq(annoNames[0], "moz-test-places/annotations");
|
||||
|
||||
// copy annotations to another uri
|
||||
var newURI = uri("http://mozilla.org");
|
||||
yield PlacesTestUtils.addVisits(newURI);
|
||||
annosvc.setPageAnnotation(testURI, "oldAnno", "new", 0, 0);
|
||||
annosvc.setPageAnnotation(newURI, "oldAnno", "old", 0, 0);
|
||||
annoNames = annosvc.getPageAnnotationNames(newURI);
|
||||
do_check_eq(annoNames.length, 1);
|
||||
do_check_eq(annoNames[0], "oldAnno");
|
||||
var oldAnnoNames = annosvc.getPageAnnotationNames(testURI);
|
||||
do_check_eq(oldAnnoNames.length, 2);
|
||||
var copiedAnno = oldAnnoNames[0];
|
||||
annosvc.copyPageAnnotations(testURI, newURI, false);
|
||||
var newAnnoNames = annosvc.getPageAnnotationNames(newURI);
|
||||
do_check_eq(newAnnoNames.length, 2);
|
||||
do_check_true(annosvc.pageHasAnnotation(newURI, "oldAnno"));
|
||||
do_check_true(annosvc.pageHasAnnotation(newURI, copiedAnno));
|
||||
do_check_eq(annosvc.getPageAnnotation(newURI, "oldAnno"), "old");
|
||||
annosvc.setPageAnnotation(newURI, "oldAnno", "new", 0, 0);
|
||||
annosvc.copyPageAnnotations(testURI, newURI, true);
|
||||
newAnnoNames = annosvc.getPageAnnotationNames(newURI);
|
||||
do_check_eq(newAnnoNames.length, 2);
|
||||
do_check_true(annosvc.pageHasAnnotation(newURI, "oldAnno"));
|
||||
do_check_true(annosvc.pageHasAnnotation(newURI, copiedAnno));
|
||||
do_check_eq(annosvc.getPageAnnotation(newURI, "oldAnno"), "new");
|
||||
|
||||
|
||||
// copy annotations to another item
|
||||
newURI = uri("http://mozilla.org");
|
||||
var newItemId = bmsvc.insertBookmark(bmsvc.bookmarksMenuFolder, newURI, -1, "");
|
||||
var itemId = bmsvc.insertBookmark(bmsvc.bookmarksMenuFolder, testURI, -1, "");
|
||||
annosvc.setItemAnnotation(itemId, "oldAnno", "new", 0, 0);
|
||||
annosvc.setItemAnnotation(itemId, "testAnno", "test", 0, 0);
|
||||
annosvc.setItemAnnotation(newItemId, "oldAnno", "old", 0, 0);
|
||||
annoNames = annosvc.getItemAnnotationNames(newItemId);
|
||||
do_check_eq(annoNames.length, 1);
|
||||
do_check_eq(annoNames[0], "oldAnno");
|
||||
oldAnnoNames = annosvc.getItemAnnotationNames(itemId);
|
||||
do_check_eq(oldAnnoNames.length, 2);
|
||||
copiedAnno = oldAnnoNames[0];
|
||||
annosvc.copyItemAnnotations(itemId, newItemId, false);
|
||||
newAnnoNames = annosvc.getItemAnnotationNames(newItemId);
|
||||
do_check_eq(newAnnoNames.length, 2);
|
||||
do_check_true(annosvc.itemHasAnnotation(newItemId, "oldAnno"));
|
||||
do_check_true(annosvc.itemHasAnnotation(newItemId, copiedAnno));
|
||||
do_check_eq(annosvc.getItemAnnotation(newItemId, "oldAnno"), "old");
|
||||
annosvc.setItemAnnotation(newItemId, "oldAnno", "new", 0, 0);
|
||||
annosvc.copyItemAnnotations(itemId, newItemId, true);
|
||||
newAnnoNames = annosvc.getItemAnnotationNames(newItemId);
|
||||
do_check_eq(newAnnoNames.length, 2);
|
||||
do_check_true(annosvc.itemHasAnnotation(newItemId, "oldAnno"));
|
||||
do_check_true(annosvc.itemHasAnnotation(newItemId, copiedAnno));
|
||||
do_check_eq(annosvc.getItemAnnotation(newItemId, "oldAnno"), "new");
|
||||
|
||||
// test int32 anno type
|
||||
var int32Key = testAnnoName + "/types/Int32";
|
||||
var int32Val = 23;
|
||||
annosvc.setPageAnnotation(testURI, int32Key, int32Val, 0, 0);
|
||||
do_check_true(annosvc.pageHasAnnotation(testURI, int32Key));
|
||||
flags = {}, exp = {}, storageType = {};
|
||||
annosvc.getPageAnnotationInfo(testURI, int32Key, flags, exp, storageType);
|
||||
do_check_eq(flags.value, 0);
|
||||
do_check_eq(exp.value, 0);
|
||||
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_INT32);
|
||||
var storedVal = annosvc.getPageAnnotation(testURI, int32Key);
|
||||
do_check_true(int32Val === storedVal);
|
||||
annosvc.setItemAnnotation(testItemId, int32Key, int32Val, 0, 0);
|
||||
do_check_true(annosvc.itemHasAnnotation(testItemId, int32Key));
|
||||
annosvc.getItemAnnotationInfo(testItemId, int32Key, flags, exp, storageType);
|
||||
do_check_eq(flags.value, 0);
|
||||
do_check_eq(exp.value, 0);
|
||||
storedVal = annosvc.getItemAnnotation(testItemId, int32Key);
|
||||
do_check_true(int32Val === storedVal);
|
||||
|
||||
// test int64 anno type
|
||||
var int64Key = testAnnoName + "/types/Int64";
|
||||
var int64Val = 4294967296;
|
||||
annosvc.setPageAnnotation(testURI, int64Key, int64Val, 0, 0);
|
||||
annosvc.getPageAnnotationInfo(testURI, int64Key, flags, exp, storageType);
|
||||
do_check_eq(flags.value, 0);
|
||||
do_check_eq(exp.value, 0);
|
||||
storedVal = annosvc.getPageAnnotation(testURI, int64Key);
|
||||
do_check_true(int64Val === storedVal);
|
||||
annosvc.setItemAnnotation(testItemId, int64Key, int64Val, 0, 0);
|
||||
do_check_true(annosvc.itemHasAnnotation(testItemId, int64Key));
|
||||
annosvc.getItemAnnotationInfo(testItemId, int64Key, flags, exp, storageType);
|
||||
do_check_eq(flags.value, 0);
|
||||
do_check_eq(exp.value, 0);
|
||||
storedVal = annosvc.getItemAnnotation(testItemId, int64Key);
|
||||
do_check_true(int64Val === storedVal);
|
||||
|
||||
// test double anno type
|
||||
var doubleKey = testAnnoName + "/types/Double";
|
||||
var doubleVal = 0.000002342;
|
||||
annosvc.setPageAnnotation(testURI, doubleKey, doubleVal, 0, 0);
|
||||
annosvc.getPageAnnotationInfo(testURI, doubleKey, flags, exp, storageType);
|
||||
do_check_eq(flags.value, 0);
|
||||
do_check_eq(exp.value, 0);
|
||||
storedVal = annosvc.getPageAnnotation(testURI, doubleKey);
|
||||
do_check_true(doubleVal === storedVal);
|
||||
annosvc.setItemAnnotation(testItemId, doubleKey, doubleVal, 0, 0);
|
||||
do_check_true(annosvc.itemHasAnnotation(testItemId, doubleKey));
|
||||
annosvc.getItemAnnotationInfo(testItemId, doubleKey, flags, exp, storageType);
|
||||
do_check_eq(flags.value, 0);
|
||||
do_check_eq(exp.value, 0);
|
||||
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_DOUBLE);
|
||||
storedVal = annosvc.getItemAnnotation(testItemId, doubleKey);
|
||||
do_check_true(doubleVal === storedVal);
|
||||
|
||||
// test annotation removal
|
||||
annosvc.removePageAnnotation(testURI, int32Key);
|
||||
|
||||
annosvc.setItemAnnotation(testItemId, testAnnoName, testAnnoVal, 0, 0);
|
||||
// verify that removing an annotation updates the last modified date
|
||||
var lastModified3 = bmsvc.getItemLastModified(testItemId);
|
||||
// Workaround possible VM timers issues moving last modified to the past.
|
||||
bmsvc.setItemLastModified(testItemId, --lastModified3);
|
||||
annosvc.removeItemAnnotation(testItemId, int32Key);
|
||||
var lastModified4 = bmsvc.getItemLastModified(testItemId);
|
||||
do_print("verify that removing an annotation updates the last modified date");
|
||||
do_print("lastModified3 = " + lastModified3);
|
||||
do_print("lastModified4 = " + lastModified4);
|
||||
do_check_true(lastModified4 > lastModified3);
|
||||
|
||||
do_check_eq(annoObserver.PAGE_lastRemoved_URI, testURI.spec);
|
||||
do_check_eq(annoObserver.PAGE_lastRemoved_AnnoName, int32Key);
|
||||
do_check_eq(annoObserver.ITEM_lastRemoved_Id, testItemId);
|
||||
do_check_eq(annoObserver.ITEM_lastRemoved_AnnoName, int32Key);
|
||||
|
||||
// test that getItems/PagesWithAnnotation returns an empty array after
|
||||
// removing all items/pages which had the annotation set, see bug 380317.
|
||||
do_check_eq(annosvc.getItemsWithAnnotation(int32Key).length, 0);
|
||||
do_check_eq(annosvc.getPagesWithAnnotation(int32Key).length, 0);
|
||||
|
||||
// Setting item annotations on invalid item ids should throw
|
||||
var invalidIds = [-1, 0, 37643];
|
||||
for (var id of invalidIds) {
|
||||
try {
|
||||
annosvc.setItemAnnotation(id, "foo", "bar", 0, 0);
|
||||
do_throw("setItemAnnotation* should throw for invalid item id: " + id)
|
||||
}
|
||||
catch (ex) { }
|
||||
}
|
||||
|
||||
// setting an annotation with EXPIRE_HISTORY for an item should throw
|
||||
itemId = bmsvc.insertBookmark(bmsvc.bookmarksMenuFolder, testURI, -1, "");
|
||||
try {
|
||||
annosvc.setItemAnnotation(itemId, "foo", "bar", 0, annosvc.EXPIRE_WITH_HISTORY);
|
||||
do_throw("setting an item annotation with EXPIRE_HISTORY should throw");
|
||||
}
|
||||
catch (ex) {
|
||||
}
|
||||
|
||||
annosvc.removeObserver(annoObserver);
|
||||
});
|
||||
|
||||
add_test(function test_getAnnotationsHavingName() {
|
||||
let uri = NetUtil.newURI("http://cat.mozilla.org");
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.unfiledBookmarksFolderId, uri,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "cat");
|
||||
let fid = PlacesUtils.bookmarks.createFolder(
|
||||
PlacesUtils.unfiledBookmarksFolderId, "pillow",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
|
||||
const ANNOS = {
|
||||
"int": 7,
|
||||
"double": 7.7,
|
||||
"string": "seven"
|
||||
};
|
||||
for (let name in ANNOS) {
|
||||
PlacesUtils.annotations.setPageAnnotation(
|
||||
uri, name, ANNOS[name], 0,
|
||||
PlacesUtils.annotations.EXPIRE_SESSION);
|
||||
PlacesUtils.annotations.setItemAnnotation(
|
||||
id, name, ANNOS[name], 0,
|
||||
PlacesUtils.annotations.EXPIRE_SESSION);
|
||||
PlacesUtils.annotations.setItemAnnotation(
|
||||
fid, name, ANNOS[name], 0,
|
||||
PlacesUtils.annotations.EXPIRE_SESSION);
|
||||
}
|
||||
|
||||
for (let name in ANNOS) {
|
||||
let results = PlacesUtils.annotations.getAnnotationsWithName(name);
|
||||
do_check_eq(results.length, 3);
|
||||
|
||||
for (let result of results) {
|
||||
do_check_eq(result.annotationName, name);
|
||||
do_check_eq(result.annotationValue, ANNOS[name]);
|
||||
if (result.uri)
|
||||
do_check_true(result.uri.equals(uri));
|
||||
else
|
||||
do_check_true(result.itemId > 0);
|
||||
|
||||
if (result.itemId != -1) {
|
||||
if (result.uri)
|
||||
do_check_eq(result.itemId, id);
|
||||
else
|
||||
do_check_eq(result.itemId, fid);
|
||||
do_check_guid_for_bookmark(result.itemId, result.guid);
|
||||
}
|
||||
else {
|
||||
do_check_guid_for_uri(result.uri, result.guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// This is a test for asyncExecuteLegacyQueries API.
|
||||
|
||||
var tests = [
|
||||
|
||||
function test_history_query() {
|
||||
let uri = NetUtil.newURI("http://test.visit.mozilla.com/");
|
||||
let title = "Test visit";
|
||||
PlacesTestUtils.addVisits({ uri: uri, title: title }).then(function () {
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING;
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
|
||||
PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.asyncExecuteLegacyQueries([query], 1, options, {
|
||||
handleResult: function (aResultSet) {
|
||||
for (let row; (row = aResultSet.getNextRow());) {
|
||||
try {
|
||||
do_check_eq(row.getResultByIndex(1), uri.spec);
|
||||
do_check_eq(row.getResultByIndex(2), title);
|
||||
} catch (e) {
|
||||
do_throw("Error while fetching page data.");
|
||||
}
|
||||
}
|
||||
},
|
||||
handleError: function (aError) {
|
||||
do_throw("Async execution error (" + aError.result + "): " + aError.message);
|
||||
},
|
||||
handleCompletion: function (aReason) {
|
||||
run_next_test();
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
function test_bookmarks_query() {
|
||||
let uri = NetUtil.newURI("http://test.bookmark.mozilla.com/");
|
||||
let title = "Test bookmark";
|
||||
bookmark(uri, title);
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.sortingMode = Ci.nsINavHistoryQueryOptions.SORT_BY_LASMODIFIED_DESCENDING;
|
||||
options.queryType = options.QUERY_TYPE_BOOKMARKS;
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
|
||||
PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.asyncExecuteLegacyQueries([query], 1, options, {
|
||||
handleResult: function (aResultSet) {
|
||||
for (let row; (row = aResultSet.getNextRow());) {
|
||||
try {
|
||||
do_check_eq(row.getResultByIndex(1), uri.spec);
|
||||
do_check_eq(row.getResultByIndex(2), title);
|
||||
} catch (e) {
|
||||
do_throw("Error while fetching page data.");
|
||||
}
|
||||
}
|
||||
},
|
||||
handleError: function (aError) {
|
||||
do_throw("Async execution error (" + aError.result + "): " + aError.message);
|
||||
},
|
||||
handleCompletion: function (aReason) {
|
||||
run_next_test();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
function bookmark(aURI, aTitle)
|
||||
{
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
aURI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
aTitle);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
do_test_pending();
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function run_next_test() {
|
||||
if (tests.length == 0) {
|
||||
do_test_finished();
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
PlacesTestUtils.clearHistory(),
|
||||
PlacesUtils.bookmarks.eraseEverything()
|
||||
]).then(tests.shift());
|
||||
}
|
||||
1118
toolkit/components/places/tests/unit/test_async_history_api.js
Normal file
1118
toolkit/components/places/tests/unit/test_async_history_api.js
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,55 @@
|
|||
// This is testing the frankenstein situation Sync forces Places into.
|
||||
// Sync does runInBatchMode() and before the callback returns the Places async
|
||||
// APIs are used (either by Sync itself, or by any other code in the system)
|
||||
// As seen in bug 1197856 and bug 1190131.
|
||||
|
||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
// This function "waits" for a promise to resolve by spinning a nested event
|
||||
// loop.
|
||||
function waitForPromise(promise) {
|
||||
let thread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread;
|
||||
|
||||
let finalResult, finalException;
|
||||
|
||||
promise.then(result => {
|
||||
finalResult = result;
|
||||
}, err => {
|
||||
finalException = err;
|
||||
});
|
||||
|
||||
// Keep waiting until our callback is triggered (unless the app is quitting).
|
||||
while (!finalResult && !finalException) {
|
||||
thread.processNextEvent(true);
|
||||
}
|
||||
if (finalException) {
|
||||
throw finalException;
|
||||
}
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
add_test(function() {
|
||||
let testCompleted = false;
|
||||
PlacesUtils.bookmarks.runInBatchMode({
|
||||
runBatched() {
|
||||
// create a bookmark.
|
||||
let info = { parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/" };
|
||||
let insertPromise = PlacesUtils.bookmarks.insert(info);
|
||||
let bookmark = waitForPromise(insertPromise);
|
||||
// Check we got a bookmark (bookmark creation failed completely in
|
||||
// bug 1190131)
|
||||
equal(bookmark.url, info.url);
|
||||
// Check the promiseItemGuid and promiseItemId helpers - failure in these
|
||||
// was the underlying reason for the failure.
|
||||
let id = waitForPromise(PlacesUtils.promiseItemId(bookmark.guid));
|
||||
let guid = waitForPromise(PlacesUtils.promiseItemGuid(id));
|
||||
equal(guid, bookmark.guid, "id and guid round-tripped correctly");
|
||||
testCompleted = true;
|
||||
}
|
||||
}, null);
|
||||
// make sure we tested what we think we tested.
|
||||
ok(testCompleted);
|
||||
run_next_test();
|
||||
});
|
||||
1739
toolkit/components/places/tests/unit/test_async_transactions.js
Normal file
1739
toolkit/components/places/tests/unit/test_async_transactions.js
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Added with bug 508102 to make sure that calling stopSearch on our
|
||||
* AutoComplete implementation does not throw.
|
||||
*/
|
||||
|
||||
// Globals and Constants
|
||||
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var ac = Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"].
|
||||
getService(Ci.nsIAutoCompleteSearch);
|
||||
|
||||
// Test Functions
|
||||
|
||||
function test_stopSearch()
|
||||
{
|
||||
try {
|
||||
ac.stopSearch();
|
||||
}
|
||||
catch (e) {
|
||||
do_throw("we should not have caught anything!");
|
||||
}
|
||||
}
|
||||
|
||||
// Test Runner
|
||||
|
||||
var tests = [
|
||||
test_stopSearch,
|
||||
];
|
||||
function run_test()
|
||||
{
|
||||
tests.forEach(test => test());
|
||||
}
|
||||
57
toolkit/components/places/tests/unit/test_bookmark_catobs.js
Normal file
57
toolkit/components/places/tests/unit/test_bookmark_catobs.js
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function run_test() {
|
||||
run_next_test()
|
||||
}
|
||||
|
||||
add_task(function* test_observers() {
|
||||
do_load_manifest("nsDummyObserver.manifest");
|
||||
|
||||
let dummyCreated = false;
|
||||
let dummyReceivedOnItemAdded = false;
|
||||
|
||||
Services.obs.addObserver(function created() {
|
||||
Services.obs.removeObserver(created, "dummy-observer-created");
|
||||
dummyCreated = true;
|
||||
}, "dummy-observer-created", false);
|
||||
Services.obs.addObserver(function added() {
|
||||
Services.obs.removeObserver(added, "dummy-observer-item-added");
|
||||
dummyReceivedOnItemAdded = true;
|
||||
}, "dummy-observer-item-added", false);
|
||||
|
||||
let initialObservers = PlacesUtils.bookmarks.getObservers();
|
||||
|
||||
// Add a common observer, it should be invoked after the category observer.
|
||||
let notificationsPromised = new Promise((resolve, reject) => {
|
||||
PlacesUtils.bookmarks.addObserver( {
|
||||
__proto__: NavBookmarkObserver.prototype,
|
||||
onItemAdded() {
|
||||
let observers = PlacesUtils.bookmarks.getObservers();
|
||||
Assert.equal(observers.length, initialObservers.length + 1);
|
||||
|
||||
// Check the common observer is the last one.
|
||||
for (let i = 0; i < initialObservers.length; ++i) {
|
||||
Assert.equal(initialObservers[i], observers[i]);
|
||||
}
|
||||
|
||||
PlacesUtils.bookmarks.removeObserver(this);
|
||||
observers = PlacesUtils.bookmarks.getObservers();
|
||||
Assert.equal(observers.length, initialObservers.length);
|
||||
|
||||
// Check the category observer has been invoked before this one.
|
||||
Assert.ok(dummyCreated);
|
||||
Assert.ok(dummyReceivedOnItemAdded);
|
||||
resolve();
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
|
||||
// Add a bookmark
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri("http://typed.mozilla.org"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark");
|
||||
|
||||
yield notificationsPromised;
|
||||
});
|
||||
385
toolkit/components/places/tests/unit/test_bookmarks_html.js
Normal file
385
toolkit/components/places/tests/unit/test_bookmarks_html.js
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
|
||||
const DESCRIPTION_ANNO = "bookmarkProperties/description";
|
||||
|
||||
// An object representing the contents of bookmarks.preplaces.html.
|
||||
var test_bookmarks = {
|
||||
menu: [
|
||||
{ title: "Mozilla Firefox",
|
||||
children: [
|
||||
{ title: "Help and Tutorials",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/help/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
{ title: "Customize Firefox",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/customize/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
{ title: "Get Involved",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/community/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
{ title: "About Us",
|
||||
url: "http://en-us.www.mozilla.com/en-US/about/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR
|
||||
},
|
||||
{ title: "test",
|
||||
description: "folder test comment",
|
||||
dateAdded: 1177541020000000,
|
||||
lastModified: 1177541050000000,
|
||||
children: [
|
||||
{ title: "test post keyword",
|
||||
description: "item description",
|
||||
dateAdded: 1177375336000000,
|
||||
lastModified: 1177375423000000,
|
||||
keyword: "test",
|
||||
sidebar: true,
|
||||
postData: "hidden1%3Dbar&text1%3D%25s",
|
||||
charset: "ISO-8859-1",
|
||||
url: "http://test/post"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
toolbar: [
|
||||
{ title: "Getting Started",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/central/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
{ title: "Latest Headlines",
|
||||
url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
|
||||
feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml"
|
||||
}
|
||||
],
|
||||
unfiled: [
|
||||
{ title: "Example.tld",
|
||||
url: "http://example.tld/"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Pre-Places bookmarks.html file pointer.
|
||||
var gBookmarksFileOld;
|
||||
// Places bookmarks.html file pointer.
|
||||
var gBookmarksFileNew;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* setup() {
|
||||
// Avoid creating smart bookmarks during the test.
|
||||
Services.prefs.setIntPref("browser.places.smartBookmarksVersion", -1);
|
||||
|
||||
// File pointer to legacy bookmarks file.
|
||||
gBookmarksFileOld = do_get_file("bookmarks.preplaces.html");
|
||||
|
||||
// File pointer to a new Places-exported bookmarks file.
|
||||
gBookmarksFileNew = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
|
||||
gBookmarksFileNew.append("bookmarks.exported.html");
|
||||
if (gBookmarksFileNew.exists()) {
|
||||
gBookmarksFileNew.remove(false);
|
||||
}
|
||||
|
||||
// This test must be the first one, since it setups the new bookmarks.html.
|
||||
// Test importing a pre-Places canonical bookmarks file.
|
||||
// 1. import bookmarks.preplaces.html
|
||||
// 2. run the test-suite
|
||||
// Note: we do not empty the db before this import to catch bugs like 380999
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileOld, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_import_new()
|
||||
{
|
||||
// Test importing a Places bookmarks.html file.
|
||||
// 1. import bookmarks.exported.html
|
||||
// 2. run the test-suite
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
yield testImportedBookmarks();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_emptytitle_export()
|
||||
{
|
||||
// Test exporting and importing with an empty-titled bookmark.
|
||||
// 1. import bookmarks
|
||||
// 2. create an empty-titled bookmark.
|
||||
// 3. export to bookmarks.exported.html
|
||||
// 4. empty bookmarks db
|
||||
// 5. import bookmarks.exported.html
|
||||
// 6. run the test-suite
|
||||
// 7. remove the empty-titled bookmark
|
||||
// 8. export to bookmarks.exported.html
|
||||
// 9. empty bookmarks db and continue
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
const NOTITLE_URL = "http://notitle.mozilla.org/";
|
||||
let bookmark = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: NOTITLE_URL
|
||||
});
|
||||
test_bookmarks.unfiled.push({ title: "", url: NOTITLE_URL });
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
|
||||
// Cleanup.
|
||||
test_bookmarks.unfiled.pop();
|
||||
// HTML imports don't restore GUIDs yet.
|
||||
let reimportedBookmark = yield PlacesUtils.bookmarks.fetch({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: PlacesUtils.bookmarks.DEFAULT_INDEX
|
||||
});
|
||||
Assert.equal(reimportedBookmark.url.href, bookmark.url.href);
|
||||
yield PlacesUtils.bookmarks.remove(reimportedBookmark);
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_import_chromefavicon()
|
||||
{
|
||||
// Test exporting and importing with a bookmark pointing to a chrome favicon.
|
||||
// 1. import bookmarks
|
||||
// 2. create a bookmark pointing to a chrome favicon.
|
||||
// 3. export to bookmarks.exported.html
|
||||
// 4. empty bookmarks db
|
||||
// 5. import bookmarks.exported.html
|
||||
// 6. run the test-suite
|
||||
// 7. remove the bookmark pointing to a chrome favicon.
|
||||
// 8. export to bookmarks.exported.html
|
||||
// 9. empty bookmarks db and continue
|
||||
|
||||
const PAGE_URI = NetUtil.newURI("http://example.com/chromefavicon_page");
|
||||
const CHROME_FAVICON_URI = NetUtil.newURI("chrome://global/skin/icons/information-16.png");
|
||||
const CHROME_FAVICON_URI_2 = NetUtil.newURI("chrome://global/skin/icons/error-16.png");
|
||||
|
||||
do_print("Importing from html");
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Insert bookmark");
|
||||
yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: PAGE_URI,
|
||||
title: "Test"
|
||||
});
|
||||
|
||||
do_print("Set favicon");
|
||||
yield new Promise(resolve => {
|
||||
PlacesUtils.favicons.setAndFetchFaviconForPage(
|
||||
PAGE_URI, CHROME_FAVICON_URI, true,
|
||||
PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
|
||||
resolve, Services.scriptSecurityManager.getSystemPrincipal());
|
||||
});
|
||||
|
||||
let data = yield new Promise(resolve => {
|
||||
PlacesUtils.favicons.getFaviconDataForPage(
|
||||
PAGE_URI, (uri, dataLen, faviconData, mimeType) => resolve(faviconData));
|
||||
});
|
||||
|
||||
let base64Icon = "data:image/png;base64," +
|
||||
base64EncodeString(String.fromCharCode.apply(String, data));
|
||||
|
||||
test_bookmarks.unfiled.push(
|
||||
{ title: "Test", url: PAGE_URI.spec, icon: base64Icon });
|
||||
|
||||
do_print("Export to html");
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Set favicon");
|
||||
// Change the favicon to check it's really imported again later.
|
||||
yield new Promise(resolve => {
|
||||
PlacesUtils.favicons.setAndFetchFaviconForPage(
|
||||
PAGE_URI, CHROME_FAVICON_URI_2, true,
|
||||
PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
|
||||
resolve, Services.scriptSecurityManager.getSystemPrincipal());
|
||||
});
|
||||
|
||||
do_print("import from html");
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Test imported bookmarks");
|
||||
yield testImportedBookmarks();
|
||||
|
||||
// Cleanup.
|
||||
test_bookmarks.unfiled.pop();
|
||||
// HTML imports don't restore GUIDs yet.
|
||||
let reimportedBookmark = yield PlacesUtils.bookmarks.fetch({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: PlacesUtils.bookmarks.DEFAULT_INDEX
|
||||
});
|
||||
yield PlacesUtils.bookmarks.remove(reimportedBookmark);
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_import_ontop()
|
||||
{
|
||||
// Test importing the exported bookmarks.html file *on top of* the existing
|
||||
// bookmarks.
|
||||
// 1. empty bookmarks db
|
||||
// 2. import the exported bookmarks file
|
||||
// 3. export to file
|
||||
// 3. import the exported bookmarks file
|
||||
// 4. run the test-suite
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
function* testImportedBookmarks()
|
||||
{
|
||||
for (let group in test_bookmarks) {
|
||||
do_print("[testImportedBookmarks()] Checking group '" + group + "'");
|
||||
|
||||
let root;
|
||||
switch (group) {
|
||||
case "menu":
|
||||
root = PlacesUtils.getFolderContents(PlacesUtils.bookmarksMenuFolderId).root;
|
||||
break;
|
||||
case "toolbar":
|
||||
root = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root;
|
||||
break;
|
||||
case "unfiled":
|
||||
root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
break;
|
||||
}
|
||||
|
||||
let items = test_bookmarks[group];
|
||||
do_check_eq(root.childCount, items.length);
|
||||
|
||||
for (let key in items) {
|
||||
yield checkItem(items[key], root.getChild(key));
|
||||
}
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
function* checkItem(aExpected, aNode)
|
||||
{
|
||||
let id = aNode.itemId;
|
||||
|
||||
return Task.spawn(function* () {
|
||||
for (prop in aExpected) {
|
||||
switch (prop) {
|
||||
case "type":
|
||||
do_check_eq(aNode.type, aExpected.type);
|
||||
break;
|
||||
case "title":
|
||||
do_check_eq(aNode.title, aExpected.title);
|
||||
break;
|
||||
case "description":
|
||||
do_check_eq(PlacesUtils.annotations
|
||||
.getItemAnnotation(id, DESCRIPTION_ANNO),
|
||||
aExpected.description);
|
||||
break;
|
||||
case "dateAdded":
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemDateAdded(id),
|
||||
aExpected.dateAdded);
|
||||
break;
|
||||
case "lastModified":
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemLastModified(id),
|
||||
aExpected.lastModified);
|
||||
break;
|
||||
case "url":
|
||||
if (!("feedUrl" in aExpected))
|
||||
do_check_eq(aNode.uri, aExpected.url)
|
||||
break;
|
||||
case "icon":
|
||||
let deferred = Promise.defer();
|
||||
PlacesUtils.favicons.getFaviconDataForPage(
|
||||
NetUtil.newURI(aExpected.url),
|
||||
function (aURI, aDataLen, aData, aMimeType) {
|
||||
deferred.resolve(aData);
|
||||
});
|
||||
let data = yield deferred.promise;
|
||||
let base64Icon = "data:image/png;base64," +
|
||||
base64EncodeString(String.fromCharCode.apply(String, data));
|
||||
do_check_true(base64Icon == aExpected.icon);
|
||||
break;
|
||||
case "keyword": {
|
||||
let entry = yield PlacesUtils.keywords.fetch({ url: aNode.uri });
|
||||
Assert.equal(entry.keyword, aExpected.keyword);
|
||||
break;
|
||||
}
|
||||
case "sidebar":
|
||||
do_check_eq(PlacesUtils.annotations
|
||||
.itemHasAnnotation(id, LOAD_IN_SIDEBAR_ANNO),
|
||||
aExpected.sidebar);
|
||||
break;
|
||||
case "postData": {
|
||||
let entry = yield PlacesUtils.keywords.fetch({ url: aNode.uri });
|
||||
Assert.equal(entry.postData, aExpected.postData);
|
||||
break;
|
||||
}
|
||||
case "charset":
|
||||
let testURI = NetUtil.newURI(aNode.uri);
|
||||
do_check_eq((yield PlacesUtils.getCharsetForURI(testURI)), aExpected.charset);
|
||||
break;
|
||||
case "feedUrl":
|
||||
let livemark = yield PlacesUtils.livemarks.getLivemark({ id: id });
|
||||
do_check_eq(livemark.siteURI.spec, aExpected.url);
|
||||
do_check_eq(livemark.feedURI.spec, aExpected.feedUrl);
|
||||
break;
|
||||
case "children":
|
||||
let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(folder.hasChildren, aExpected.children.length > 0);
|
||||
folder.containerOpen = true;
|
||||
do_check_eq(folder.childCount, aExpected.children.length);
|
||||
|
||||
for (let index = 0; index < aExpected.children.length; index++) {
|
||||
yield checkItem(aExpected.children[index], folder.getChild(index));
|
||||
}
|
||||
|
||||
folder.containerOpen = false;
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown property");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* This test ensures that importing/exporting to HTML does not stop
|
||||
* if a malformed uri is found.
|
||||
*/
|
||||
|
||||
const DESCRIPTION_ANNO = "bookmarkProperties/description";
|
||||
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
|
||||
|
||||
const TEST_FAVICON_PAGE_URL = "http://en-US.www.mozilla.com/en-US/firefox/central/";
|
||||
const TEST_FAVICON_DATA_SIZE = 580;
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_corrupt_file() {
|
||||
// avoid creating the places smart folder during tests
|
||||
Services.prefs.setIntPref("browser.places.smartBookmarksVersion", -1);
|
||||
|
||||
// Import bookmarks from the corrupt file.
|
||||
let corruptHtml = OS.Path.join(do_get_cwd().path, "bookmarks.corrupt.html");
|
||||
yield BookmarkHTMLUtils.importFromFile(corruptHtml, true);
|
||||
|
||||
// Check that bookmarks that are not corrupt have been imported.
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield database_check();
|
||||
});
|
||||
|
||||
add_task(function* test_corrupt_database() {
|
||||
// Create corruption in the database, then export.
|
||||
let corruptBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
url: "http://test.mozilla.org",
|
||||
title: "We love belugas" });
|
||||
yield PlacesUtils.withConnectionWrapper("test", Task.async(function*(db) {
|
||||
yield db.execute("UPDATE moz_bookmarks SET fk = NULL WHERE guid = :guid",
|
||||
{ guid: corruptBookmark.guid });
|
||||
}));
|
||||
|
||||
let bookmarksFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.exported.html");
|
||||
if ((yield OS.File.exists(bookmarksFile)))
|
||||
yield OS.File.remove(bookmarksFile);
|
||||
yield BookmarkHTMLUtils.exportToFile(bookmarksFile);
|
||||
|
||||
// Import again and check for correctness.
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield BookmarkHTMLUtils.importFromFile(bookmarksFile, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield database_check();
|
||||
});
|
||||
|
||||
/*
|
||||
* Check for imported bookmarks correctness
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When the checks are finished.
|
||||
* @rejects Never.
|
||||
*/
|
||||
var database_check = Task.async(function* () {
|
||||
// BOOKMARKS MENU
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarksMenuFolderId).root;
|
||||
Assert.equal(root.childCount, 2);
|
||||
|
||||
let folderNode = root.getChild(1);
|
||||
Assert.equal(folderNode.type, folderNode.RESULT_TYPE_FOLDER);
|
||||
Assert.equal(folderNode.title, "test");
|
||||
Assert.equal(PlacesUtils.bookmarks.getItemDateAdded(folderNode.itemId), 1177541020000000);
|
||||
Assert.equal(PlacesUtils.bookmarks.getItemLastModified(folderNode.itemId), 1177541050000000);
|
||||
Assert.equal("folder test comment",
|
||||
PlacesUtils.annotations.getItemAnnotation(folderNode.itemId,
|
||||
DESCRIPTION_ANNO));
|
||||
// open test folder, and test the children
|
||||
PlacesUtils.asQuery(folderNode);
|
||||
Assert.equal(folderNode.hasChildren, true);
|
||||
folderNode.containerOpen = true;
|
||||
Assert.equal(folderNode.childCount, 1);
|
||||
|
||||
let bookmarkNode = folderNode.getChild(0);
|
||||
Assert.equal("http://test/post", bookmarkNode.uri);
|
||||
Assert.equal("test post keyword", bookmarkNode.title);
|
||||
|
||||
let entry = yield PlacesUtils.keywords.fetch({ url: bookmarkNode.uri });
|
||||
Assert.equal("test", entry.keyword);
|
||||
Assert.equal("hidden1%3Dbar&text1%3D%25s", entry.postData);
|
||||
|
||||
Assert.ok(PlacesUtils.annotations.itemHasAnnotation(bookmarkNode.itemId,
|
||||
LOAD_IN_SIDEBAR_ANNO));
|
||||
Assert.equal(bookmarkNode.dateAdded, 1177375336000000);
|
||||
Assert.equal(bookmarkNode.lastModified, 1177375423000000);
|
||||
|
||||
Assert.equal((yield PlacesUtils.getCharsetForURI(NetUtil.newURI(bookmarkNode.uri))),
|
||||
"ISO-8859-1");
|
||||
|
||||
Assert.equal("item description",
|
||||
PlacesUtils.annotations.getItemAnnotation(bookmarkNode.itemId,
|
||||
DESCRIPTION_ANNO));
|
||||
|
||||
// clean up
|
||||
folderNode.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
|
||||
// BOOKMARKS TOOLBAR
|
||||
root = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root;
|
||||
Assert.equal(root.childCount, 3);
|
||||
|
||||
// For now some promises are resolved later, so we can't guarantee an order.
|
||||
let foundLivemark = false;
|
||||
for (let i = 0; i < root.childCount; ++i) {
|
||||
let node = root.getChild(i);
|
||||
if (node.title == "Latest Headlines") {
|
||||
foundLivemark = true;
|
||||
Assert.equal("Latest Headlines", node.title);
|
||||
|
||||
let livemark = yield PlacesUtils.livemarks.getLivemark({ guid: node.bookmarkGuid });
|
||||
Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
|
||||
livemark.siteURI.spec);
|
||||
Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
|
||||
livemark.feedURI.spec);
|
||||
}
|
||||
}
|
||||
Assert.ok(foundLivemark);
|
||||
|
||||
// cleanup
|
||||
root.containerOpen = false;
|
||||
|
||||
// UNFILED BOOKMARKS
|
||||
root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
Assert.equal(root.childCount, 1);
|
||||
root.containerOpen = false;
|
||||
|
||||
// favicons
|
||||
yield new Promise(resolve => {
|
||||
PlacesUtils.favicons.getFaviconDataForPage(uri(TEST_FAVICON_PAGE_URL),
|
||||
(aURI, aDataLen, aData, aMimeType) => {
|
||||
// aURI should never be null when aDataLen > 0.
|
||||
Assert.notEqual(aURI, null);
|
||||
// Favicon data is stored in the bookmarks file as a "data:" URI. For
|
||||
// simplicity, instead of converting the data we receive to a "data:" URI
|
||||
// and comparing it, we just check the data size.
|
||||
Assert.equal(TEST_FAVICON_DATA_SIZE, aDataLen);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
var bookmarkData = [
|
||||
{ uri: uri("http://www.toastytech.com"),
|
||||
title: "Nathan's Toasty Technology Page",
|
||||
tags: ["technology", "personal", "retro"] },
|
||||
{ uri: uri("http://www.reddit.com"),
|
||||
title: "reddit: the front page of the internet",
|
||||
tags: ["social media", "news", "humour"] },
|
||||
{ uri: uri("http://www.4chan.org"),
|
||||
title: "4chan",
|
||||
tags: ["discussion", "imageboard", "anime"] }
|
||||
];
|
||||
|
||||
/*
|
||||
TEST SUMMARY
|
||||
- Add bookmarks with tags
|
||||
- Export tagged bookmarks as HTML file
|
||||
- Delete bookmarks
|
||||
- Import bookmarks from HTML file
|
||||
- Check that all bookmarks are successfully imported with tags
|
||||
*/
|
||||
|
||||
add_task(function* test_import_tags() {
|
||||
// Removes bookmarks.html if the file already exists.
|
||||
let HTMLFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.html");
|
||||
if ((yield OS.File.exists(HTMLFile)))
|
||||
yield OS.File.remove(HTMLFile);
|
||||
|
||||
// Adds bookmarks and tags to the database.
|
||||
let bookmarkList = new Set();
|
||||
for (let { uri, title, tags } of bookmarkData) {
|
||||
bookmarkList.add(yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: uri,
|
||||
title }));
|
||||
PlacesUtils.tagging.tagURI(uri, tags);
|
||||
}
|
||||
|
||||
// Exports the bookmarks as a HTML file.
|
||||
yield BookmarkHTMLUtils.exportToFile(HTMLFile);
|
||||
|
||||
// Deletes bookmarks and tags from the database.
|
||||
for (let bookmark of bookmarkList) {
|
||||
yield PlacesUtils.bookmarks.remove(bookmark.guid);
|
||||
}
|
||||
|
||||
// Re-imports the bookmarks from the HTML file.
|
||||
yield BookmarkHTMLUtils.importFromFile(HTMLFile, true);
|
||||
|
||||
// Tests to ensure that the tags are still present for each bookmark URI.
|
||||
for (let { uri, tags } of bookmarkData) {
|
||||
do_print("Test tags for " + uri.spec + ": " + tags + "\n");
|
||||
let foundTags = PlacesUtils.tagging.getTagsForURI(uri);
|
||||
Assert.equal(foundTags.length, tags.length);
|
||||
Assert.ok(tags.every(tag => foundTags.includes(tag)));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Test for bug #801450
|
||||
|
||||
// Get Services
|
||||
Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_bookmarks_html_singleframe()
|
||||
{
|
||||
let bookmarksFile = OS.Path.join(do_get_cwd().path, "bookmarks_html_singleframe.html");
|
||||
yield BookmarkHTMLUtils.importFromFile(bookmarksFile, true);
|
||||
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarksMenuFolderId).root;
|
||||
do_check_eq(root.childCount, 1);
|
||||
let folder = root.getChild(0);
|
||||
PlacesUtils.asContainer(folder).containerOpen = true;
|
||||
do_check_eq(folder.title, "Subtitle");
|
||||
do_check_eq(folder.childCount, 1);
|
||||
let bookmark = folder.getChild(0);
|
||||
do_check_eq(bookmark.uri, "http://www.mozilla.org/");
|
||||
do_check_eq(bookmark.title, "Mozilla");
|
||||
folder.containerOpen = false;
|
||||
});
|
||||
241
toolkit/components/places/tests/unit/test_bookmarks_json.js
Normal file
241
toolkit/components/places/tests/unit/test_bookmarks_json.js
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Cu.import("resource://gre/modules/BookmarkJSONUtils.jsm");
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
|
||||
const DESCRIPTION_ANNO = "bookmarkProperties/description";
|
||||
|
||||
// An object representing the contents of bookmarks.json.
|
||||
var test_bookmarks = {
|
||||
menu: [
|
||||
{ guid: "OCyeUO5uu9FF",
|
||||
title: "Mozilla Firefox",
|
||||
children: [
|
||||
{ guid:"OCyeUO5uu9FG",
|
||||
title: "Help and Tutorials",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/help/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
{ guid:"OCyeUO5uu9FH",
|
||||
title: "Customize Firefox",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/customize/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
{ guid:"OCyeUO5uu9FI",
|
||||
title: "Get Involved",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/community/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
{ guid:"OCyeUO5uu9FJ",
|
||||
title: "About Us",
|
||||
url: "http://en-us.www.mozilla.com/en-US/about/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
guid: "OCyeUO5uu9FK",
|
||||
type: Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR
|
||||
},
|
||||
{
|
||||
guid:"OCyeUO5uu9FL",
|
||||
title: "test",
|
||||
description: "folder test comment",
|
||||
dateAdded: 1177541020000000,
|
||||
// lastModified: 1177541050000000,
|
||||
children: [
|
||||
{ guid:"OCyeUO5uu9GX",
|
||||
title: "test post keyword",
|
||||
description: "item description",
|
||||
dateAdded: 1177375336000000,
|
||||
// lastModified: 1177375423000000,
|
||||
keyword: "test",
|
||||
sidebar: true,
|
||||
postData: "hidden1%3Dbar&text1%3D%25s",
|
||||
charset: "ISO-8859-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
toolbar: [
|
||||
{ guid: "OCyeUO5uu9FB",
|
||||
title: "Getting Started",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/central/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
{ guid:"OCyeUO5uu9FR",
|
||||
title: "Latest Headlines",
|
||||
url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
|
||||
feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml"
|
||||
}
|
||||
],
|
||||
unfiled: [
|
||||
{ guid: "OCyeUO5uu9FW",
|
||||
title: "Example.tld",
|
||||
url: "http://example.tld/"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Exported bookmarks file pointer.
|
||||
var bookmarksExportedFile;
|
||||
|
||||
add_task(function* test_import_bookmarks() {
|
||||
let bookmarksFile = OS.Path.join(do_get_cwd().path, "bookmarks.json");
|
||||
|
||||
yield BookmarkJSONUtils.importFromFile(bookmarksFile, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
});
|
||||
|
||||
add_task(function* test_export_bookmarks() {
|
||||
bookmarksExportedFile = OS.Path.join(OS.Constants.Path.profileDir,
|
||||
"bookmarks.exported.json");
|
||||
yield BookmarkJSONUtils.exportToFile(bookmarksExportedFile);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_import_exported_bookmarks() {
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield BookmarkJSONUtils.importFromFile(bookmarksExportedFile, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
});
|
||||
|
||||
add_task(function* test_import_ontop() {
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield BookmarkJSONUtils.importFromFile(bookmarksExportedFile, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield BookmarkJSONUtils.exportToFile(bookmarksExportedFile);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield BookmarkJSONUtils.importFromFile(bookmarksExportedFile, true);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
});
|
||||
|
||||
add_task(function* test_clean() {
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
function* testImportedBookmarks() {
|
||||
for (let group in test_bookmarks) {
|
||||
do_print("[testImportedBookmarks()] Checking group '" + group + "'");
|
||||
|
||||
let root;
|
||||
switch (group) {
|
||||
case "menu":
|
||||
root =
|
||||
PlacesUtils.getFolderContents(PlacesUtils.bookmarksMenuFolderId).root;
|
||||
break;
|
||||
case "toolbar":
|
||||
root =
|
||||
PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root;
|
||||
break;
|
||||
case "unfiled":
|
||||
root =
|
||||
PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
break;
|
||||
}
|
||||
|
||||
let items = test_bookmarks[group];
|
||||
do_check_eq(root.childCount, items.length);
|
||||
|
||||
for (let key in items) {
|
||||
yield checkItem(items[key], root.getChild(key));
|
||||
}
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
function* checkItem(aExpected, aNode) {
|
||||
let id = aNode.itemId;
|
||||
|
||||
return Task.spawn(function* () {
|
||||
for (prop in aExpected) {
|
||||
switch (prop) {
|
||||
case "type":
|
||||
do_check_eq(aNode.type, aExpected.type);
|
||||
break;
|
||||
case "title":
|
||||
do_check_eq(aNode.title, aExpected.title);
|
||||
break;
|
||||
case "description":
|
||||
do_check_eq(PlacesUtils.annotations.getItemAnnotation(
|
||||
id, DESCRIPTION_ANNO), aExpected.description);
|
||||
break;
|
||||
case "dateAdded":
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemDateAdded(id),
|
||||
aExpected.dateAdded);
|
||||
break;
|
||||
case "lastModified":
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemLastModified(id),
|
||||
aExpected.lastModified);
|
||||
break;
|
||||
case "url":
|
||||
if (!("feedUrl" in aExpected))
|
||||
do_check_eq(aNode.uri, aExpected.url);
|
||||
break;
|
||||
case "icon":
|
||||
let deferred = Promise.defer();
|
||||
PlacesUtils.favicons.getFaviconDataForPage(
|
||||
NetUtil.newURI(aExpected.url),
|
||||
function (aURI, aDataLen, aData, aMimeType) {
|
||||
deferred.resolve(aData);
|
||||
});
|
||||
let data = yield deferred.promise;
|
||||
let base64Icon = "data:image/png;base64," +
|
||||
base64EncodeString(String.fromCharCode.apply(String, data));
|
||||
do_check_true(base64Icon == aExpected.icon);
|
||||
break;
|
||||
case "keyword": {
|
||||
let entry = yield PlacesUtils.keywords.fetch({ url: aNode.uri });
|
||||
Assert.equal(entry.keyword, aExpected.keyword);
|
||||
break;
|
||||
}
|
||||
case "guid":
|
||||
let guid = yield PlacesUtils.promiseItemGuid(id);
|
||||
do_check_eq(guid, aExpected.guid);
|
||||
break;
|
||||
case "sidebar":
|
||||
do_check_eq(PlacesUtils.annotations.itemHasAnnotation(
|
||||
id, LOAD_IN_SIDEBAR_ANNO), aExpected.sidebar);
|
||||
break;
|
||||
case "postData": {
|
||||
let entry = yield PlacesUtils.keywords.fetch({ url: aNode.uri });
|
||||
Assert.equal(entry.postData, aExpected.postData);
|
||||
break;
|
||||
}
|
||||
case "charset":
|
||||
let testURI = NetUtil.newURI(aNode.uri);
|
||||
do_check_eq((yield PlacesUtils.getCharsetForURI(testURI)), aExpected.charset);
|
||||
break;
|
||||
case "feedUrl":
|
||||
let livemark = yield PlacesUtils.livemarks.getLivemark({ id: id });
|
||||
do_check_eq(livemark.siteURI.spec, aExpected.url);
|
||||
do_check_eq(livemark.feedURI.spec, aExpected.feedUrl);
|
||||
break;
|
||||
case "children":
|
||||
let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(folder.hasChildren, aExpected.children.length > 0);
|
||||
folder.containerOpen = true;
|
||||
do_check_eq(folder.childCount, aExpected.children.length);
|
||||
|
||||
for (let index = 0; index < aExpected.children.length; index++) {
|
||||
yield checkItem(aExpected.children[index], folder.getChild(index));
|
||||
}
|
||||
|
||||
folder.containerOpen = false;
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown property");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,325 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
|
||||
/**
|
||||
* Tests the bookmarks-restore-* nsIObserver notifications after restoring
|
||||
* bookmarks from JSON and HTML. See bug 470314.
|
||||
*/
|
||||
|
||||
// The topics and data passed to nsIObserver.observe() on bookmarks restore
|
||||
const NSIOBSERVER_TOPIC_BEGIN = "bookmarks-restore-begin";
|
||||
const NSIOBSERVER_TOPIC_SUCCESS = "bookmarks-restore-success";
|
||||
const NSIOBSERVER_TOPIC_FAILED = "bookmarks-restore-failed";
|
||||
const NSIOBSERVER_DATA_JSON = "json";
|
||||
const NSIOBSERVER_DATA_HTML = "html";
|
||||
const NSIOBSERVER_DATA_HTML_INIT = "html-initial";
|
||||
|
||||
// Bookmarks are added for these URIs
|
||||
var uris = [
|
||||
"http://example.com/1",
|
||||
"http://example.com/2",
|
||||
"http://example.com/3",
|
||||
"http://example.com/4",
|
||||
"http://example.com/5",
|
||||
];
|
||||
|
||||
/**
|
||||
* Adds some bookmarks for the URIs in |uris|.
|
||||
*/
|
||||
function* addBookmarks() {
|
||||
for (let url of uris) {
|
||||
yield PlacesUtils.bookmarks.insert({
|
||||
url: url, parentGuid: PlacesUtils.bookmarks.menuGuid
|
||||
})
|
||||
}
|
||||
checkBookmarksExist();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that all of the bookmarks created for |uris| exist. It works by
|
||||
* creating one query per URI and then ORing all the queries. The number of
|
||||
* results returned should be uris.length.
|
||||
*/
|
||||
function checkBookmarksExist() {
|
||||
let hs = PlacesUtils.history;
|
||||
let queries = uris.map(function (u) {
|
||||
let q = hs.getNewQuery();
|
||||
q.uri = uri(u);
|
||||
return q;
|
||||
});
|
||||
let options = hs.getNewQueryOptions();
|
||||
options.queryType = options.QUERY_TYPE_BOOKMARKS;
|
||||
let root = hs.executeQueries(queries, uris.length, options).root;
|
||||
root.containerOpen = true;
|
||||
Assert.equal(root.childCount, uris.length);
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an file in the profile directory.
|
||||
*
|
||||
* @param aBasename
|
||||
* e.g., "foo.txt" in the path /some/long/path/foo.txt
|
||||
* @return {Promise}
|
||||
* @resolves to an OS.File path
|
||||
*/
|
||||
function promiseFile(aBasename) {
|
||||
let path = OS.Path.join(OS.Constants.Path.profileDir, aBasename);
|
||||
do_print("opening " + path);
|
||||
return OS.File.open(path, { truncate: true })
|
||||
.then(aFile => {
|
||||
aFile.close();
|
||||
return path;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register observers via promiseTopicObserved helper.
|
||||
*
|
||||
* @param {boolean} expectSuccess pass true when expect a success notification
|
||||
* @return {Promise[]}
|
||||
*/
|
||||
function registerObservers(expectSuccess) {
|
||||
let promiseBegin = promiseTopicObserved(NSIOBSERVER_TOPIC_BEGIN);
|
||||
let promiseResult;
|
||||
if (expectSuccess) {
|
||||
promiseResult = promiseTopicObserved(NSIOBSERVER_TOPIC_SUCCESS);
|
||||
} else {
|
||||
promiseResult = promiseTopicObserved(NSIOBSERVER_TOPIC_FAILED);
|
||||
}
|
||||
|
||||
return [promiseBegin, promiseResult];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check notification results.
|
||||
*
|
||||
* @param {Promise[]} expectPromises array contain promiseBegin and promiseResult
|
||||
* @param {object} expectedData contain data and folderId
|
||||
*/
|
||||
function* checkObservers(expectPromises, expectedData) {
|
||||
let [promiseBegin, promiseResult] = expectPromises;
|
||||
|
||||
let beginData = (yield promiseBegin)[1];
|
||||
Assert.equal(beginData, expectedData.data,
|
||||
"Data for current test should be what is expected");
|
||||
|
||||
let [resultSubject, resultData] = yield promiseResult;
|
||||
Assert.equal(resultData, expectedData.data,
|
||||
"Data for current test should be what is expected");
|
||||
|
||||
// Make sure folder ID is what is expected. For importing HTML into a
|
||||
// folder, this will be an integer, otherwise null.
|
||||
if (resultSubject) {
|
||||
Assert.equal(aSubject.QueryInterface(Ci.nsISupportsPRInt64).data,
|
||||
expectedData.folderId);
|
||||
} else {
|
||||
Assert.equal(expectedData.folderId, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run after every test cases.
|
||||
*/
|
||||
function* teardown(file, begin, success, fail) {
|
||||
// On restore failed, file may not exist, so wrap in try-catch.
|
||||
try {
|
||||
yield OS.File.remove(file, {ignoreAbsent: true});
|
||||
} catch (e) {}
|
||||
|
||||
// clean up bookmarks
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
}
|
||||
|
||||
add_task(function* test_json_restore_normal() {
|
||||
// data: the data passed to nsIObserver.observe() corresponding to the test
|
||||
// folderId: for HTML restore into a folder, the folder ID to restore into;
|
||||
// otherwise, set it to null
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_JSON,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(true);
|
||||
|
||||
do_print("JSON restore: normal restore should succeed");
|
||||
let file = yield promiseFile("bookmarks-test_restoreNotification.json");
|
||||
yield addBookmarks();
|
||||
|
||||
yield BookmarkJSONUtils.exportToFile(file);
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
try {
|
||||
yield BookmarkJSONUtils.importFromFile(file, true);
|
||||
} catch (e) {
|
||||
do_throw(" Restore should not have failed" + e);
|
||||
}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
||||
add_task(function* test_json_restore_empty() {
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_JSON,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(true);
|
||||
|
||||
do_print("JSON restore: empty file should succeed");
|
||||
let file = yield promiseFile("bookmarks-test_restoreNotification.json");
|
||||
try {
|
||||
yield BookmarkJSONUtils.importFromFile(file, true);
|
||||
} catch (e) {
|
||||
do_throw(" Restore should not have failed" + e);
|
||||
}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
||||
add_task(function* test_json_restore_nonexist() {
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_JSON,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(false);
|
||||
|
||||
do_print("JSON restore: nonexistent file should fail");
|
||||
let file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
|
||||
file.append("this file doesn't exist because nobody created it 1");
|
||||
try {
|
||||
yield BookmarkJSONUtils.importFromFile(file, true);
|
||||
do_throw(" Restore should have failed");
|
||||
} catch (e) {}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
||||
add_task(function* test_html_restore_normal() {
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_HTML,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(true);
|
||||
|
||||
do_print("HTML restore: normal restore should succeed");
|
||||
let file = yield promiseFile("bookmarks-test_restoreNotification.html");
|
||||
yield addBookmarks();
|
||||
yield BookmarkHTMLUtils.exportToFile(file);
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(file, false)
|
||||
.then(null, do_report_unexpected_exception);
|
||||
} catch (e) {
|
||||
do_throw(" Restore should not have failed");
|
||||
}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
||||
add_task(function* test_html_restore_empty() {
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_HTML,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(true);
|
||||
|
||||
do_print("HTML restore: empty file should succeed");
|
||||
let file = yield promiseFile("bookmarks-test_restoreNotification.init.html");
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(file, false)
|
||||
.then(null, do_report_unexpected_exception);
|
||||
} catch (e) {
|
||||
do_throw(" Restore should not have failed");
|
||||
}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
||||
add_task(function* test_html_restore_nonexist() {
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_HTML,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(false);
|
||||
|
||||
do_print("HTML restore: nonexistent file should fail");
|
||||
let file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
|
||||
file.append("this file doesn't exist because nobody created it 2");
|
||||
try {
|
||||
yield BookmarkHTMLUtils.importFromFile(file, false);
|
||||
do_throw("Should fail!");
|
||||
} catch (e) {}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
||||
add_task(function* test_html_init_restore_normal() {
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_HTML_INIT,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(true);
|
||||
|
||||
do_print("HTML initial restore: normal restore should succeed");
|
||||
let file = yield promiseFile("bookmarks-test_restoreNotification.init.html");
|
||||
yield addBookmarks();
|
||||
yield BookmarkHTMLUtils.exportToFile(file);
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(file, true)
|
||||
.then(null, do_report_unexpected_exception);
|
||||
} catch (e) {
|
||||
do_throw(" Restore should not have failed");
|
||||
}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
||||
add_task(function* test_html_init_restore_empty() {
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_HTML_INIT,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(true);
|
||||
|
||||
do_print("HTML initial restore: empty file should succeed");
|
||||
let file = yield promiseFile("bookmarks-test_restoreNotification.init.html");
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(file, true)
|
||||
.then(null, do_report_unexpected_exception);
|
||||
} catch (e) {
|
||||
do_throw(" Restore should not have failed");
|
||||
}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
||||
add_task(function* test_html_init_restore_nonexist() {
|
||||
let expectedData = {
|
||||
data: NSIOBSERVER_DATA_HTML_INIT,
|
||||
folderId: null
|
||||
}
|
||||
let expectPromises = registerObservers(false);
|
||||
|
||||
do_print("HTML initial restore: nonexistent file should fail");
|
||||
let file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
|
||||
file.append("this file doesn't exist because nobody created it 3");
|
||||
try {
|
||||
yield BookmarkHTMLUtils.importFromFile(file, true);
|
||||
do_throw("Should fail!");
|
||||
} catch (e) {}
|
||||
|
||||
yield checkObservers(expectPromises, expectedData);
|
||||
yield teardown(file);
|
||||
});
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Both SetItemtitle and insertBookmark should allow for null titles.
|
||||
*/
|
||||
|
||||
const bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
const TEST_URL = "http://www.mozilla.org";
|
||||
|
||||
function run_test() {
|
||||
// Insert a bookmark with an empty title.
|
||||
var itemId = bs.insertBookmark(bs.toolbarFolder,
|
||||
uri(TEST_URL),
|
||||
bs.DEFAULT_INDEX,
|
||||
"");
|
||||
// Check returned title is an empty string.
|
||||
do_check_eq(bs.getItemTitle(itemId), "");
|
||||
// Set title to null.
|
||||
bs.setItemTitle(itemId, null);
|
||||
// Check returned title is null.
|
||||
do_check_eq(bs.getItemTitle(itemId), null);
|
||||
// Cleanup.
|
||||
bs.removeItem(itemId);
|
||||
|
||||
// Insert a bookmark with a null title.
|
||||
itemId = bs.insertBookmark(bs.toolbarFolder,
|
||||
uri(TEST_URL),
|
||||
bs.DEFAULT_INDEX,
|
||||
null);
|
||||
// Check returned title is null.
|
||||
do_check_eq(bs.getItemTitle(itemId), null);
|
||||
// Set title to an empty string.
|
||||
bs.setItemTitle(itemId, "");
|
||||
// Check returned title is an empty string.
|
||||
do_check_eq(bs.getItemTitle(itemId), "");
|
||||
// Cleanup.
|
||||
bs.removeItem(itemId);
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.unfiledBookmarksFolderId, NetUtil.newURI("http://1.moz.org/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "Bookmark 1"
|
||||
);
|
||||
let id1 = PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.unfiledBookmarksFolderId, NetUtil.newURI("place:folder=1234"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "Shortcut 1"
|
||||
);
|
||||
let id2 = PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.unfiledBookmarksFolderId, NetUtil.newURI("place:folder=-1"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "Shortcut 2"
|
||||
);
|
||||
PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.unfiledBookmarksFolderId, NetUtil.newURI("http://2.moz.org/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "Bookmark 2"
|
||||
);
|
||||
|
||||
// Add also a simple visit.
|
||||
yield PlacesTestUtils.addVisits(uri(("http://3.moz.org/")));
|
||||
|
||||
// Query containing a broken folder shortcuts among results.
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([PlacesUtils.unfiledBookmarksFolderId], 1);
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
let root = PlacesUtils.history.executeQuery(query, options).root;
|
||||
root.containerOpen = true;
|
||||
|
||||
do_check_eq(root.childCount, 4);
|
||||
|
||||
let shortcut = root.getChild(1);
|
||||
do_check_eq(shortcut.uri, "place:folder=1234");
|
||||
PlacesUtils.asContainer(shortcut);
|
||||
shortcut.containerOpen = true;
|
||||
do_check_eq(shortcut.childCount, 0);
|
||||
shortcut.containerOpen = false;
|
||||
// Remove the broken shortcut while the containing result is open.
|
||||
PlacesUtils.bookmarks.removeItem(id1);
|
||||
do_check_eq(root.childCount, 3);
|
||||
|
||||
shortcut = root.getChild(1);
|
||||
do_check_eq(shortcut.uri, "place:folder=-1");
|
||||
PlacesUtils.asContainer(shortcut);
|
||||
shortcut.containerOpen = true;
|
||||
do_check_eq(shortcut.childCount, 0);
|
||||
shortcut.containerOpen = false;
|
||||
// Remove the broken shortcut while the containing result is open.
|
||||
PlacesUtils.bookmarks.removeItem(id2);
|
||||
do_check_eq(root.childCount, 2);
|
||||
|
||||
root.containerOpen = false;
|
||||
|
||||
// Broken folder shortcut as root node.
|
||||
query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([1234], 1);
|
||||
options = PlacesUtils.history.getNewQueryOptions();
|
||||
root = PlacesUtils.history.executeQuery(query, options).root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 0);
|
||||
root.containerOpen = false;
|
||||
|
||||
// Broken folder shortcut as root node with folder=-1.
|
||||
query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([-1], 1);
|
||||
options = PlacesUtils.history.getNewQueryOptions();
|
||||
root = PlacesUtils.history.executeQuery(query, options).root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 0);
|
||||
root.containerOpen = false;
|
||||
});
|
||||
129
toolkit/components/places/tests/unit/test_browserhistory.js
Normal file
129
toolkit/components/places/tests/unit/test_browserhistory.js
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const TEST_URI = NetUtil.newURI("http://mozilla.com/");
|
||||
const TEST_SUBDOMAIN_URI = NetUtil.newURI("http://foobar.mozilla.com/");
|
||||
|
||||
add_task(function* test_addPage() {
|
||||
yield PlacesTestUtils.addVisits(TEST_URI);
|
||||
do_check_eq(1, PlacesUtils.history.hasHistoryEntries);
|
||||
});
|
||||
|
||||
add_task(function* test_removePage() {
|
||||
PlacesUtils.bhistory.removePage(TEST_URI);
|
||||
do_check_eq(0, PlacesUtils.history.hasHistoryEntries);
|
||||
});
|
||||
|
||||
add_task(function* test_removePages() {
|
||||
let pages = [];
|
||||
for (let i = 0; i < 8; i++) {
|
||||
pages.push(NetUtil.newURI(TEST_URI.spec + i));
|
||||
}
|
||||
|
||||
yield PlacesTestUtils.addVisits(pages.map(uri => ({ uri: uri })));
|
||||
// Bookmarked item should not be removed from moz_places.
|
||||
const ANNO_INDEX = 1;
|
||||
const ANNO_NAME = "testAnno";
|
||||
const ANNO_VALUE = "foo";
|
||||
const BOOKMARK_INDEX = 2;
|
||||
PlacesUtils.annotations.setPageAnnotation(pages[ANNO_INDEX],
|
||||
ANNO_NAME, ANNO_VALUE, 0,
|
||||
Ci.nsIAnnotationService.EXPIRE_NEVER);
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
pages[BOOKMARK_INDEX],
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test bookmark");
|
||||
PlacesUtils.annotations.setPageAnnotation(pages[BOOKMARK_INDEX],
|
||||
ANNO_NAME, ANNO_VALUE, 0,
|
||||
Ci.nsIAnnotationService.EXPIRE_NEVER);
|
||||
|
||||
PlacesUtils.bhistory.removePages(pages, pages.length);
|
||||
do_check_eq(0, PlacesUtils.history.hasHistoryEntries);
|
||||
|
||||
// Check that the bookmark and its annotation still exist.
|
||||
do_check_true(PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0) > 0);
|
||||
do_check_eq(PlacesUtils.annotations.getPageAnnotation(pages[BOOKMARK_INDEX], ANNO_NAME),
|
||||
ANNO_VALUE);
|
||||
|
||||
// Check the annotation on the non-bookmarked page does not exist anymore.
|
||||
try {
|
||||
PlacesUtils.annotations.getPageAnnotation(pages[ANNO_INDEX], ANNO_NAME);
|
||||
do_throw("did not expire expire_never anno on a not bookmarked item");
|
||||
} catch (ex) {}
|
||||
|
||||
// Cleanup.
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
add_task(function* test_removePagesByTimeframe() {
|
||||
let visits = [];
|
||||
let startDate = (Date.now() - 10000) * 1000;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
visits.push({
|
||||
uri: NetUtil.newURI(TEST_URI.spec + i),
|
||||
visitDate: startDate + i * 1000
|
||||
});
|
||||
}
|
||||
|
||||
yield PlacesTestUtils.addVisits(visits);
|
||||
|
||||
// Delete all pages except the first and the last.
|
||||
PlacesUtils.bhistory.removePagesByTimeframe(startDate + 1000, startDate + 8000);
|
||||
|
||||
// Check that we have removed the correct pages.
|
||||
for (let i = 0; i < 10; i++) {
|
||||
do_check_eq(page_in_database(NetUtil.newURI(TEST_URI.spec + i)) == 0,
|
||||
i > 0 && i < 9);
|
||||
}
|
||||
|
||||
// Clear remaining items and check that all pages have been removed.
|
||||
PlacesUtils.bhistory.removePagesByTimeframe(startDate, startDate + 9000);
|
||||
do_check_eq(0, PlacesUtils.history.hasHistoryEntries);
|
||||
});
|
||||
|
||||
add_task(function* test_removePagesFromHost() {
|
||||
yield PlacesTestUtils.addVisits(TEST_URI);
|
||||
PlacesUtils.bhistory.removePagesFromHost("mozilla.com", true);
|
||||
do_check_eq(0, PlacesUtils.history.hasHistoryEntries);
|
||||
});
|
||||
|
||||
add_task(function* test_removePagesFromHost_keepSubdomains() {
|
||||
yield PlacesTestUtils.addVisits([{ uri: TEST_URI }, { uri: TEST_SUBDOMAIN_URI }]);
|
||||
PlacesUtils.bhistory.removePagesFromHost("mozilla.com", false);
|
||||
do_check_eq(1, PlacesUtils.history.hasHistoryEntries);
|
||||
});
|
||||
|
||||
add_task(function* test_history_clear() {
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
do_check_eq(0, PlacesUtils.history.hasHistoryEntries);
|
||||
});
|
||||
|
||||
add_task(function* test_getObservers() {
|
||||
// Ensure that getObservers() invalidates the hasHistoryEntries cache.
|
||||
yield PlacesTestUtils.addVisits(TEST_URI);
|
||||
do_check_eq(1, PlacesUtils.history.hasHistoryEntries);
|
||||
// This is just for testing purposes, never do it.
|
||||
return new Promise((resolve, reject) => {
|
||||
DBConn().executeSimpleSQLAsync("DELETE FROM moz_historyvisits", {
|
||||
handleError: function(error) {
|
||||
reject(error);
|
||||
},
|
||||
handleResult: function(result) {
|
||||
},
|
||||
handleCompletion: function(result) {
|
||||
// Just invoking getObservers should be enough to invalidate the cache.
|
||||
PlacesUtils.history.getObservers();
|
||||
do_check_eq(0, PlacesUtils.history.hasHistoryEntries);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Test that asking for a livemark in a annotationChanged notification works.
|
||||
add_task(function* () {
|
||||
let annoPromise = new Promise(resolve => {
|
||||
let annoObserver = {
|
||||
onItemAnnotationSet(id, name) {
|
||||
if (name == PlacesUtils.LMANNO_FEEDURI) {
|
||||
PlacesUtils.annotations.removeObserver(this);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
onItemAnnotationRemoved() {},
|
||||
onPageAnnotationSet() {},
|
||||
onPageAnnotationRemoved() {},
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIAnnotationObserver
|
||||
]),
|
||||
};
|
||||
PlacesUtils.annotations.addObserver(annoObserver, false);
|
||||
});
|
||||
|
||||
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "livemark title"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, index: PlacesUtils.bookmarks.DEFAULT_INDEX
|
||||
, siteURI: uri("http://example.com/")
|
||||
, feedURI: uri("http://example.com/rdf")
|
||||
});
|
||||
|
||||
yield annoPromise;
|
||||
|
||||
livemark = yield PlacesUtils.livemarks.getLivemark({ guid: livemark.guid });
|
||||
Assert.ok(livemark);
|
||||
yield PlacesUtils.livemarks.removeLivemark({ guid: livemark.guid });
|
||||
});
|
||||
117
toolkit/components/places/tests/unit/test_childlessTags.js
Normal file
117
toolkit/components/places/tests/unit/test_childlessTags.js
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Ensures that removal of a bookmark untags the bookmark if it's no longer
|
||||
* contained in any regular, non-tag folders. See bug 444849.
|
||||
*/
|
||||
|
||||
// Add your tests here. Each is an object with a summary string |desc| and a
|
||||
// method run() that's called to run the test.
|
||||
var tests = [
|
||||
{
|
||||
desc: "Removing a tagged bookmark should cause the tag to be removed.",
|
||||
run: function () {
|
||||
print(" Make a bookmark.");
|
||||
var bmId = bmsvc.insertBookmark(bmsvc.unfiledBookmarksFolder,
|
||||
BOOKMARK_URI,
|
||||
bmsvc.DEFAULT_INDEX,
|
||||
"test bookmark");
|
||||
do_check_true(bmId > 0);
|
||||
|
||||
print(" Tag it up.");
|
||||
var tags = ["foo", "bar"];
|
||||
tagssvc.tagURI(BOOKMARK_URI, tags);
|
||||
ensureTagsExist(tags);
|
||||
|
||||
print(" Remove the bookmark. The tags should no longer exist.");
|
||||
bmsvc.removeItem(bmId);
|
||||
ensureTagsExist([]);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
desc: "Removing a folder containing a tagged bookmark should cause the " +
|
||||
"tag to be removed.",
|
||||
run: function () {
|
||||
print(" Make a folder.");
|
||||
var folderId = bmsvc.createFolder(bmsvc.unfiledBookmarksFolder,
|
||||
"test folder",
|
||||
bmsvc.DEFAULT_INDEX);
|
||||
do_check_true(folderId > 0);
|
||||
|
||||
print(" Stick a bookmark in the folder.");
|
||||
var bmId = bmsvc.insertBookmark(folderId,
|
||||
BOOKMARK_URI,
|
||||
bmsvc.DEFAULT_INDEX,
|
||||
"test bookmark");
|
||||
do_check_true(bmId > 0);
|
||||
|
||||
print(" Tag the bookmark.");
|
||||
var tags = ["foo", "bar"];
|
||||
tagssvc.tagURI(BOOKMARK_URI, tags);
|
||||
ensureTagsExist(tags);
|
||||
|
||||
print(" Remove the folder. The tags should no longer exist.");
|
||||
bmsvc.removeItem(folderId);
|
||||
ensureTagsExist([]);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
|
||||
getService(Ci.nsITaggingService);
|
||||
|
||||
const BOOKMARK_URI = uri("http://example.com/");
|
||||
|
||||
/**
|
||||
* Runs a tag query and ensures that the tags returned are those and only those
|
||||
* in aTags. aTags may be empty, in which case this function ensures that no
|
||||
* tags exist.
|
||||
*
|
||||
* @param aTags
|
||||
* An array of tags (strings)
|
||||
*/
|
||||
function ensureTagsExist(aTags) {
|
||||
var query = histsvc.getNewQuery();
|
||||
var opts = histsvc.getNewQueryOptions();
|
||||
opts.resultType = opts.RESULTS_AS_TAG_QUERY;
|
||||
var resultRoot = histsvc.executeQuery(query, opts).root;
|
||||
|
||||
// Dupe aTags.
|
||||
var tags = aTags.slice(0);
|
||||
|
||||
resultRoot.containerOpen = true;
|
||||
|
||||
// Ensure that the number of tags returned from the query is the same as the
|
||||
// number in |tags|.
|
||||
do_check_eq(resultRoot.childCount, tags.length);
|
||||
|
||||
// For each tag result from the query, ensure that it's contained in |tags|.
|
||||
// Remove the tag from |tags| so that we ensure the sets are equal.
|
||||
for (let i = 0; i < resultRoot.childCount; i++) {
|
||||
var tag = resultRoot.getChild(i).title;
|
||||
var indexOfTag = tags.indexOf(tag);
|
||||
do_check_true(indexOfTag >= 0);
|
||||
tags.splice(indexOfTag, 1);
|
||||
}
|
||||
|
||||
resultRoot.containerOpen = false;
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
tests.forEach(function (test) {
|
||||
print("Running test: " + test.desc);
|
||||
test.run();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that history initialization correctly handles a request to forcibly
|
||||
// replace the current database.
|
||||
|
||||
add_task(function* () {
|
||||
let profileDBPath = yield OS.Path.join(OS.Constants.Path.profileDir, "places.sqlite");
|
||||
yield OS.File.remove(profileDBPath, {ignoreAbsent: true});
|
||||
// Ensure that our database doesn't already exist.
|
||||
Assert.ok(!(yield OS.File.exists(profileDBPath)), "places.sqlite shouldn't exist");
|
||||
let dir = yield OS.File.getCurrentDirectory();
|
||||
let src = OS.Path.join(dir, "corruptDB.sqlite");
|
||||
yield OS.File.copy(src, profileDBPath);
|
||||
Assert.ok(yield OS.File.exists(profileDBPath), "places.sqlite should exist");
|
||||
|
||||
let count = Services.telemetry
|
||||
.getHistogramById("PLACES_DATABASE_CORRUPTION_HANDLING_STAGE")
|
||||
.snapshot()
|
||||
.counts[3];
|
||||
Assert.equal(count, 0, "There should be no telemetry");
|
||||
|
||||
do_check_eq(PlacesUtils.history.databaseStatus,
|
||||
PlacesUtils.history.DATABASE_STATUS_CORRUPT);
|
||||
|
||||
count = Services.telemetry
|
||||
.getHistogramById("PLACES_DATABASE_CORRUPTION_HANDLING_STAGE")
|
||||
.snapshot()
|
||||
.counts[3];
|
||||
Assert.equal(count, 1, "Telemetry should have been added");
|
||||
});
|
||||
28
toolkit/components/places/tests/unit/test_crash_476292.js
Normal file
28
toolkit/components/places/tests/unit/test_crash_476292.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* This tests a crash during startup found in bug 476292 that was caused by
|
||||
* getting the bookmarks service during nsNavHistory::Init when the bookmarks
|
||||
* service was created before the history service was.
|
||||
*/
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// First, we need to move our old database file into our test profile
|
||||
// directory. This will trigger DATABASE_STATUS_UPGRADED (CREATE is not
|
||||
// sufficient since there will be no entries to update frecencies for, which
|
||||
// causes us to get the bookmarks service in the first place).
|
||||
let dbFile = do_get_file("bug476292.sqlite");
|
||||
let profD = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get(NS_APP_USER_PROFILE_50_DIR, Ci.nsIFile);
|
||||
dbFile.copyTo(profD, "places.sqlite");
|
||||
|
||||
// Now get the bookmarks service. This will crash when the bug exists.
|
||||
Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that history initialization correctly handles a request to forcibly
|
||||
// replace the current database.
|
||||
|
||||
function run_test() {
|
||||
// Ensure that our database doesn't already exist.
|
||||
let dbFile = gProfD.clone();
|
||||
dbFile.append("places.sqlite");
|
||||
do_check_false(dbFile.exists());
|
||||
|
||||
dbFile = gProfD.clone();
|
||||
dbFile.append("places.sqlite.corrupt");
|
||||
do_check_false(dbFile.exists());
|
||||
|
||||
let file = do_get_file("default.sqlite");
|
||||
file.copyToFollowingLinks(gProfD, "places.sqlite");
|
||||
file = gProfD.clone();
|
||||
file.append("places.sqlite");
|
||||
|
||||
// Create some unique stuff to check later.
|
||||
let db = Services.storage.openUnsharedDatabase(file);
|
||||
db.executeSimpleSQL("CREATE TABLE test (id INTEGER PRIMARY KEY)");
|
||||
db.close();
|
||||
|
||||
Services.prefs.setBoolPref("places.database.replaceOnStartup", true);
|
||||
do_check_eq(PlacesUtils.history.databaseStatus,
|
||||
PlacesUtils.history.DATABASE_STATUS_CORRUPT);
|
||||
|
||||
dbFile = gProfD.clone();
|
||||
dbFile.append("places.sqlite");
|
||||
do_check_true(dbFile.exists());
|
||||
|
||||
// Check the new database is really a new one.
|
||||
db = Services.storage.openUnsharedDatabase(file);
|
||||
try {
|
||||
db.executeSimpleSQL("DELETE * FROM test");
|
||||
do_throw("The new database should not have our unique content");
|
||||
} catch (ex) {}
|
||||
db.close();
|
||||
|
||||
dbFile = gProfD.clone();
|
||||
dbFile.append("places.sqlite.corrupt");
|
||||
do_check_true(dbFile.exists());
|
||||
}
|
||||
283
toolkit/components/places/tests/unit/test_download_history.js
Normal file
283
toolkit/components/places/tests/unit/test_download_history.js
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the nsIDownloadHistory Places implementation.
|
||||
*/
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gDownloadHistory",
|
||||
"@mozilla.org/browser/download-history;1",
|
||||
"nsIDownloadHistory");
|
||||
|
||||
const DOWNLOAD_URI = NetUtil.newURI("http://www.example.com/");
|
||||
const REFERRER_URI = NetUtil.newURI("http://www.example.org/");
|
||||
const PRIVATE_URI = NetUtil.newURI("http://www.example.net/");
|
||||
|
||||
/**
|
||||
* Waits for the first visit notification to be received.
|
||||
*
|
||||
* @param aCallback
|
||||
* Callback function to be called with the same arguments of onVisit.
|
||||
*/
|
||||
function waitForOnVisit(aCallback) {
|
||||
let historyObserver = {
|
||||
__proto__: NavHistoryObserver.prototype,
|
||||
onVisit: function HO_onVisit() {
|
||||
PlacesUtils.history.removeObserver(this);
|
||||
aCallback.apply(null, arguments);
|
||||
}
|
||||
};
|
||||
PlacesUtils.history.addObserver(historyObserver, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the first onDeleteURI notification to be received.
|
||||
*
|
||||
* @param aCallback
|
||||
* Callback function to be called with the same arguments of onDeleteURI.
|
||||
*/
|
||||
function waitForOnDeleteURI(aCallback) {
|
||||
let historyObserver = {
|
||||
__proto__: NavHistoryObserver.prototype,
|
||||
onDeleteURI: function HO_onDeleteURI() {
|
||||
PlacesUtils.history.removeObserver(this);
|
||||
aCallback.apply(null, arguments);
|
||||
}
|
||||
};
|
||||
PlacesUtils.history.addObserver(historyObserver, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the first onDeleteVisits notification to be received.
|
||||
*
|
||||
* @param aCallback
|
||||
* Callback function to be called with the same arguments of onDeleteVisits.
|
||||
*/
|
||||
function waitForOnDeleteVisits(aCallback) {
|
||||
let historyObserver = {
|
||||
__proto__: NavHistoryObserver.prototype,
|
||||
onDeleteVisits: function HO_onDeleteVisits() {
|
||||
PlacesUtils.history.removeObserver(this);
|
||||
aCallback.apply(null, arguments);
|
||||
}
|
||||
};
|
||||
PlacesUtils.history.addObserver(historyObserver, false);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_dh_is_from_places()
|
||||
{
|
||||
// Test that this nsIDownloadHistory is the one places implements.
|
||||
do_check_true(gDownloadHistory instanceof Ci.mozIAsyncHistory);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_dh_addRemoveDownload()
|
||||
{
|
||||
waitForOnVisit(function DHAD_onVisit(aURI) {
|
||||
do_check_true(aURI.equals(DOWNLOAD_URI));
|
||||
|
||||
// Verify that the URI is already available in results at this time.
|
||||
do_check_true(!!page_in_database(DOWNLOAD_URI));
|
||||
|
||||
waitForOnDeleteURI(function DHRAD_onDeleteURI(aDeletedURI) {
|
||||
do_check_true(aDeletedURI.equals(DOWNLOAD_URI));
|
||||
|
||||
// Verify that the URI is already available in results at this time.
|
||||
do_check_false(!!page_in_database(DOWNLOAD_URI));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
gDownloadHistory.removeAllDownloads();
|
||||
});
|
||||
|
||||
gDownloadHistory.addDownload(DOWNLOAD_URI, null, Date.now() * 1000);
|
||||
});
|
||||
|
||||
add_test(function test_dh_addMultiRemoveDownload()
|
||||
{
|
||||
PlacesTestUtils.addVisits({
|
||||
uri: DOWNLOAD_URI,
|
||||
transition: TRANSITION_TYPED
|
||||
}).then(function () {
|
||||
waitForOnVisit(function DHAD_onVisit(aURI) {
|
||||
do_check_true(aURI.equals(DOWNLOAD_URI));
|
||||
do_check_true(!!page_in_database(DOWNLOAD_URI));
|
||||
|
||||
waitForOnDeleteVisits(function DHRAD_onDeleteVisits(aDeletedURI) {
|
||||
do_check_true(aDeletedURI.equals(DOWNLOAD_URI));
|
||||
do_check_true(!!page_in_database(DOWNLOAD_URI));
|
||||
|
||||
PlacesTestUtils.clearHistory().then(run_next_test);
|
||||
});
|
||||
gDownloadHistory.removeAllDownloads();
|
||||
});
|
||||
|
||||
gDownloadHistory.addDownload(DOWNLOAD_URI, null, Date.now() * 1000);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_dh_addBookmarkRemoveDownload()
|
||||
{
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
DOWNLOAD_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"A bookmark");
|
||||
waitForOnVisit(function DHAD_onVisit(aURI) {
|
||||
do_check_true(aURI.equals(DOWNLOAD_URI));
|
||||
do_check_true(!!page_in_database(DOWNLOAD_URI));
|
||||
|
||||
waitForOnDeleteVisits(function DHRAD_onDeleteVisits(aDeletedURI) {
|
||||
do_check_true(aDeletedURI.equals(DOWNLOAD_URI));
|
||||
do_check_true(!!page_in_database(DOWNLOAD_URI));
|
||||
|
||||
PlacesTestUtils.clearHistory().then(run_next_test);
|
||||
});
|
||||
gDownloadHistory.removeAllDownloads();
|
||||
});
|
||||
|
||||
gDownloadHistory.addDownload(DOWNLOAD_URI, null, Date.now() * 1000);
|
||||
});
|
||||
|
||||
add_test(function test_dh_addDownload_referrer()
|
||||
{
|
||||
waitForOnVisit(function DHAD_prepareReferrer(aURI, aVisitID) {
|
||||
do_check_true(aURI.equals(REFERRER_URI));
|
||||
let referrerVisitId = aVisitID;
|
||||
|
||||
waitForOnVisit(function DHAD_onVisit(aVisitedURI, unused, unused2, unused3,
|
||||
aReferringID) {
|
||||
do_check_true(aVisitedURI.equals(DOWNLOAD_URI));
|
||||
do_check_eq(aReferringID, referrerVisitId);
|
||||
|
||||
// Verify that the URI is already available in results at this time.
|
||||
do_check_true(!!page_in_database(DOWNLOAD_URI));
|
||||
|
||||
PlacesTestUtils.clearHistory().then(run_next_test);
|
||||
});
|
||||
|
||||
gDownloadHistory.addDownload(DOWNLOAD_URI, REFERRER_URI, Date.now() * 1000);
|
||||
});
|
||||
|
||||
// Note that we don't pass the optional callback argument here because we must
|
||||
// ensure that we receive the onVisit notification before we call addDownload.
|
||||
PlacesUtils.asyncHistory.updatePlaces({
|
||||
uri: REFERRER_URI,
|
||||
visits: [{
|
||||
transitionType: Ci.nsINavHistoryService.TRANSITION_TYPED,
|
||||
visitDate: Date.now() * 1000
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_dh_addDownload_disabledHistory()
|
||||
{
|
||||
waitForOnVisit(function DHAD_onVisit(aURI) {
|
||||
// We should only receive the notification for the non-private URI. This
|
||||
// test is based on the assumption that visit notifications are received in
|
||||
// the same order of the addDownload calls, which is currently true because
|
||||
// database access is serialized on the same worker thread.
|
||||
do_check_true(aURI.equals(DOWNLOAD_URI));
|
||||
|
||||
do_check_true(!!page_in_database(DOWNLOAD_URI));
|
||||
do_check_false(!!page_in_database(PRIVATE_URI));
|
||||
|
||||
PlacesTestUtils.clearHistory().then(run_next_test);
|
||||
});
|
||||
|
||||
Services.prefs.setBoolPref("places.history.enabled", false);
|
||||
gDownloadHistory.addDownload(PRIVATE_URI, REFERRER_URI, Date.now() * 1000);
|
||||
|
||||
// The addDownload functions calls CanAddURI synchronously, thus we can set
|
||||
// the preference back to true immediately (not all apps enable places by
|
||||
// default).
|
||||
Services.prefs.setBoolPref("places.history.enabled", true);
|
||||
gDownloadHistory.addDownload(DOWNLOAD_URI, REFERRER_URI, Date.now() * 1000);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that nsIDownloadHistory::AddDownload saves the additional download
|
||||
* details if the optional destination URL is specified.
|
||||
*/
|
||||
add_test(function test_dh_details()
|
||||
{
|
||||
const REMOTE_URI = NetUtil.newURI("http://localhost/");
|
||||
const SOURCE_URI = NetUtil.newURI("http://example.com/test_dh_details");
|
||||
const DEST_FILE_NAME = "dest.txt";
|
||||
|
||||
// We must build a real, valid file URI for the destination.
|
||||
let destFileUri = NetUtil.newURI(FileUtils.getFile("TmpD", [DEST_FILE_NAME]));
|
||||
|
||||
let titleSet = false;
|
||||
let destinationFileUriSet = false;
|
||||
let destinationFileNameSet = false;
|
||||
|
||||
function checkFinished()
|
||||
{
|
||||
if (titleSet && destinationFileUriSet && destinationFileNameSet) {
|
||||
PlacesUtils.annotations.removeObserver(annoObserver);
|
||||
PlacesUtils.history.removeObserver(historyObserver);
|
||||
|
||||
PlacesTestUtils.clearHistory().then(run_next_test);
|
||||
}
|
||||
}
|
||||
|
||||
let annoObserver = {
|
||||
onPageAnnotationSet: function AO_onPageAnnotationSet(aPage, aName)
|
||||
{
|
||||
if (aPage.equals(SOURCE_URI)) {
|
||||
let value = PlacesUtils.annotations.getPageAnnotation(aPage, aName);
|
||||
switch (aName)
|
||||
{
|
||||
case "downloads/destinationFileURI":
|
||||
destinationFileUriSet = true;
|
||||
do_check_eq(value, destFileUri.spec);
|
||||
break;
|
||||
case "downloads/destinationFileName":
|
||||
destinationFileNameSet = true;
|
||||
do_check_eq(value, DEST_FILE_NAME);
|
||||
break;
|
||||
}
|
||||
checkFinished();
|
||||
}
|
||||
},
|
||||
onItemAnnotationSet: function() {},
|
||||
onPageAnnotationRemoved: function() {},
|
||||
onItemAnnotationRemoved: function() {}
|
||||
}
|
||||
|
||||
let historyObserver = {
|
||||
onBeginUpdateBatch: function() {},
|
||||
onEndUpdateBatch: function() {},
|
||||
onVisit: function() {},
|
||||
onTitleChanged: function HO_onTitleChanged(aURI, aPageTitle)
|
||||
{
|
||||
if (aURI.equals(SOURCE_URI)) {
|
||||
titleSet = true;
|
||||
do_check_eq(aPageTitle, DEST_FILE_NAME);
|
||||
checkFinished();
|
||||
}
|
||||
},
|
||||
onDeleteURI: function() {},
|
||||
onClearHistory: function() {},
|
||||
onPageChanged: function() {},
|
||||
onDeleteVisits: function() {}
|
||||
};
|
||||
|
||||
PlacesUtils.annotations.addObserver(annoObserver, false);
|
||||
PlacesUtils.history.addObserver(historyObserver, false);
|
||||
|
||||
// Both null values and remote URIs should not cause errors.
|
||||
gDownloadHistory.addDownload(SOURCE_URI, null, Date.now() * 1000);
|
||||
gDownloadHistory.addDownload(SOURCE_URI, null, Date.now() * 1000, null);
|
||||
gDownloadHistory.addDownload(SOURCE_URI, null, Date.now() * 1000, REMOTE_URI);
|
||||
|
||||
// Valid local file URIs should cause the download details to be saved.
|
||||
gDownloadHistory.addDownload(SOURCE_URI, null, Date.now() * 1000,
|
||||
destFileUri);
|
||||
});
|
||||
294
toolkit/components/places/tests/unit/test_frecency.js
Normal file
294
toolkit/components/places/tests/unit/test_frecency.js
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Test for bug 406358 to make sure frecency works for empty input/search, but
|
||||
* this also tests for non-empty inputs as well. Because the interactions among
|
||||
* *DIFFERENT* visit counts and visit dates is not well defined, this test
|
||||
* holds one of the two values constant when modifying the other.
|
||||
*
|
||||
* Also test bug 419068 to make sure tagged pages don't necessarily have to be
|
||||
* first in the results.
|
||||
*
|
||||
* Also test bug 426166 to make sure that the results of autocomplete searches
|
||||
* are stable. Note that failures of this test will be intermittent by nature
|
||||
* since we are testing to make sure that the unstable sort algorithm used
|
||||
* by SQLite is not changing the order of the results on us.
|
||||
*/
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
function ensure_results(uris, searchTerm)
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates()
|
||||
.then(() => ensure_results_internal(uris, searchTerm));
|
||||
}
|
||||
|
||||
function ensure_results_internal(uris, searchTerm)
|
||||
{
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
|
||||
controller.input = input;
|
||||
|
||||
var numSearchesStarted = 0;
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
do_check_eq(controller.matchCount, uris.length);
|
||||
for (var i=0; i<controller.matchCount; i++) {
|
||||
do_check_eq(controller.getValueAt(i), uris[i].spec);
|
||||
}
|
||||
|
||||
deferEnsureResults.resolve();
|
||||
};
|
||||
|
||||
controller.startSearch(searchTerm);
|
||||
}
|
||||
|
||||
// Get history service
|
||||
try {
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bhist = histsvc.QueryInterface(Ci.nsIBrowserHistory);
|
||||
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
|
||||
getService(Ci.nsITaggingService);
|
||||
var bmksvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get history service\n");
|
||||
}
|
||||
|
||||
function* task_setCountDate(aURI, aCount, aDate)
|
||||
{
|
||||
// We need visits so that frecency can be computed over multiple visits
|
||||
let visits = [];
|
||||
for (let i = 0; i < aCount; i++) {
|
||||
visits.push({ uri: aURI, visitDate: aDate, transition: TRANSITION_TYPED });
|
||||
}
|
||||
yield PlacesTestUtils.addVisits(visits);
|
||||
}
|
||||
|
||||
function setBookmark(aURI)
|
||||
{
|
||||
bmksvc.insertBookmark(bmksvc.bookmarksMenuFolder, aURI, -1, "bleh");
|
||||
}
|
||||
|
||||
function tagURI(aURI, aTags) {
|
||||
bmksvc.insertBookmark(bmksvc.unfiledBookmarksFolder, aURI,
|
||||
bmksvc.DEFAULT_INDEX, "bleh");
|
||||
tagssvc.tagURI(aURI, aTags);
|
||||
}
|
||||
|
||||
var uri1 = uri("http://site.tld/1");
|
||||
var uri2 = uri("http://site.tld/2");
|
||||
var uri3 = uri("http://aaaaaaaaaa/1");
|
||||
var uri4 = uri("http://aaaaaaaaaa/2");
|
||||
|
||||
// d1 is younger (should show up higher) than d2 (PRTime is in usecs not msec)
|
||||
// Make sure the dates fall into different frecency buckets
|
||||
var d1 = new Date(Date.now() - 1000 * 60 * 60) * 1000;
|
||||
var d2 = new Date(Date.now() - 1000 * 60 * 60 * 24 * 10) * 1000;
|
||||
// c1 is larger (should show up higher) than c2
|
||||
var c1 = 10;
|
||||
var c2 = 1;
|
||||
|
||||
var tests = [
|
||||
// test things without a search term
|
||||
function*() {
|
||||
print("TEST-INFO | Test 0: same count, different date");
|
||||
yield task_setCountDate(uri1, c1, d1);
|
||||
yield task_setCountDate(uri2, c1, d2);
|
||||
tagURI(uri1, ["site"]);
|
||||
ensure_results([uri1, uri2], "");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 1: same count, different date");
|
||||
yield task_setCountDate(uri1, c1, d2);
|
||||
yield task_setCountDate(uri2, c1, d1);
|
||||
tagURI(uri1, ["site"]);
|
||||
ensure_results([uri2, uri1], "");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 2: different count, same date");
|
||||
yield task_setCountDate(uri1, c1, d1);
|
||||
yield task_setCountDate(uri2, c2, d1);
|
||||
tagURI(uri1, ["site"]);
|
||||
ensure_results([uri1, uri2], "");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 3: different count, same date");
|
||||
yield task_setCountDate(uri1, c2, d1);
|
||||
yield task_setCountDate(uri2, c1, d1);
|
||||
tagURI(uri1, ["site"]);
|
||||
ensure_results([uri2, uri1], "");
|
||||
},
|
||||
|
||||
// test things with a search term
|
||||
function*() {
|
||||
print("TEST-INFO | Test 4: same count, different date");
|
||||
yield task_setCountDate(uri1, c1, d1);
|
||||
yield task_setCountDate(uri2, c1, d2);
|
||||
tagURI(uri1, ["site"]);
|
||||
ensure_results([uri1, uri2], "site");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 5: same count, different date");
|
||||
yield task_setCountDate(uri1, c1, d2);
|
||||
yield task_setCountDate(uri2, c1, d1);
|
||||
tagURI(uri1, ["site"]);
|
||||
ensure_results([uri2, uri1], "site");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 6: different count, same date");
|
||||
yield task_setCountDate(uri1, c1, d1);
|
||||
yield task_setCountDate(uri2, c2, d1);
|
||||
tagURI(uri1, ["site"]);
|
||||
ensure_results([uri1, uri2], "site");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 7: different count, same date");
|
||||
yield task_setCountDate(uri1, c2, d1);
|
||||
yield task_setCountDate(uri2, c1, d1);
|
||||
tagURI(uri1, ["site"]);
|
||||
ensure_results([uri2, uri1], "site");
|
||||
},
|
||||
// There are multiple tests for 8, hence the multiple functions
|
||||
// Bug 426166 section
|
||||
function*() {
|
||||
print("TEST-INFO | Test 8.1a: same count, same date");
|
||||
setBookmark(uri3);
|
||||
setBookmark(uri4);
|
||||
ensure_results([uri4, uri3], "a");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 8.1b: same count, same date");
|
||||
setBookmark(uri3);
|
||||
setBookmark(uri4);
|
||||
ensure_results([uri4, uri3], "aa");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 8.2: same count, same date");
|
||||
setBookmark(uri3);
|
||||
setBookmark(uri4);
|
||||
ensure_results([uri4, uri3], "aaa");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 8.3: same count, same date");
|
||||
setBookmark(uri3);
|
||||
setBookmark(uri4);
|
||||
ensure_results([uri4, uri3], "aaaa");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 8.4: same count, same date");
|
||||
setBookmark(uri3);
|
||||
setBookmark(uri4);
|
||||
ensure_results([uri4, uri3], "aaa");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 8.5: same count, same date");
|
||||
setBookmark(uri3);
|
||||
setBookmark(uri4);
|
||||
ensure_results([uri4, uri3], "aa");
|
||||
},
|
||||
function*() {
|
||||
print("TEST-INFO | Test 8.6: same count, same date");
|
||||
setBookmark(uri3);
|
||||
setBookmark(uri4);
|
||||
ensure_results([uri4, uri3], "a");
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* This deferred object contains a promise that is resolved when the
|
||||
* ensure_results_internal function has finished its execution.
|
||||
*/
|
||||
var deferEnsureResults;
|
||||
|
||||
add_task(function* test_frecency()
|
||||
{
|
||||
// Disable autoFill for this test.
|
||||
Services.prefs.setBoolPref("browser.urlbar.autoFill", false);
|
||||
do_register_cleanup(() => Services.prefs.clearUserPref("browser.urlbar.autoFill"));
|
||||
// always search in history + bookmarks, no matter what the default is
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
|
||||
prefs.setBoolPref("browser.urlbar.suggest.history", true);
|
||||
prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
|
||||
prefs.setBoolPref("browser.urlbar.suggest.openpage", false);
|
||||
for (let test of tests) {
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
|
||||
deferEnsureResults = Promise.defer();
|
||||
yield test();
|
||||
yield deferEnsureResults.promise;
|
||||
}
|
||||
for (let type of ["history", "bookmark", "openpage"]) {
|
||||
prefs.clearUserPref("browser.urlbar.suggest." + type);
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
// Each of these tests a path that triggers a frecency update. Together they
|
||||
// hit all sites that update a frecency.
|
||||
|
||||
// InsertVisitedURIs::UpdateFrecency and History::InsertPlace
|
||||
add_task(function* test_InsertVisitedURIs_UpdateFrecency_and_History_InsertPlace() {
|
||||
// InsertPlace is at the end of a path that UpdateFrecency is also on, so kill
|
||||
// two birds with one stone and expect two notifications. Trigger the path by
|
||||
// adding a download.
|
||||
let uri = NetUtil.newURI("http://example.com/a");
|
||||
Cc["@mozilla.org/browser/download-history;1"].
|
||||
getService(Ci.nsIDownloadHistory).
|
||||
addDownload(uri);
|
||||
yield Promise.all([onFrecencyChanged(uri), onFrecencyChanged(uri)]);
|
||||
});
|
||||
|
||||
// nsNavHistory::UpdateFrecency
|
||||
add_task(function* test_nsNavHistory_UpdateFrecency() {
|
||||
let bm = PlacesUtils.bookmarks;
|
||||
let uri = NetUtil.newURI("http://example.com/b");
|
||||
bm.insertBookmark(bm.unfiledBookmarksFolder, uri,
|
||||
Ci.nsINavBookmarksService.DEFAULT_INDEX, "test");
|
||||
yield onFrecencyChanged(uri);
|
||||
});
|
||||
|
||||
// nsNavHistory::invalidateFrecencies for particular pages
|
||||
add_task(function* test_nsNavHistory_invalidateFrecencies_somePages() {
|
||||
let uri = NetUtil.newURI("http://test-nsNavHistory-invalidateFrecencies-somePages.com/");
|
||||
// Bookmarking the URI is enough to add it to moz_places, and importantly, it
|
||||
// means that removePagesFromHost doesn't remove it from moz_places, so its
|
||||
// frecency is able to be changed.
|
||||
let bm = PlacesUtils.bookmarks;
|
||||
bm.insertBookmark(bm.unfiledBookmarksFolder, uri,
|
||||
Ci.nsINavBookmarksService.DEFAULT_INDEX, "test");
|
||||
PlacesUtils.history.removePagesFromHost(uri.host, false);
|
||||
yield onFrecencyChanged(uri);
|
||||
});
|
||||
|
||||
// nsNavHistory::invalidateFrecencies for all pages
|
||||
add_task(function* test_nsNavHistory_invalidateFrecencies_allPages() {
|
||||
yield Promise.all([onManyFrecenciesChanged(), PlacesTestUtils.clearHistory()]);
|
||||
});
|
||||
|
||||
// nsNavHistory::DecayFrecency and nsNavHistory::FixInvalidFrecencies
|
||||
add_task(function* test_nsNavHistory_DecayFrecency_and_nsNavHistory_FixInvalidFrecencies() {
|
||||
// FixInvalidFrecencies is at the end of a path that DecayFrecency is also on,
|
||||
// so expect two notifications. Trigger the path by making nsNavHistory
|
||||
// observe the idle-daily notification.
|
||||
PlacesUtils.history.QueryInterface(Ci.nsIObserver).
|
||||
observe(null, "idle-daily", "");
|
||||
yield Promise.all([onManyFrecenciesChanged(), onManyFrecenciesChanged()]);
|
||||
});
|
||||
|
||||
function onFrecencyChanged(expectedURI) {
|
||||
let deferred = Promise.defer();
|
||||
let obs = new NavHistoryObserver();
|
||||
obs.onFrecencyChanged =
|
||||
(uri, newFrecency, guid, hidden, visitDate) => {
|
||||
PlacesUtils.history.removeObserver(obs);
|
||||
do_check_true(!!uri);
|
||||
do_check_true(uri.equals(expectedURI));
|
||||
deferred.resolve();
|
||||
};
|
||||
PlacesUtils.history.addObserver(obs, false);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onManyFrecenciesChanged() {
|
||||
let deferred = Promise.defer();
|
||||
let obs = new NavHistoryObserver();
|
||||
obs.onManyFrecenciesChanged = () => {
|
||||
PlacesUtils.history.removeObserver(obs);
|
||||
do_check_true(true);
|
||||
deferred.resolve();
|
||||
};
|
||||
PlacesUtils.history.addObserver(obs, false);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests a zero frecency is correctly updated when inserting new valid visits.
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test()
|
||||
}
|
||||
|
||||
add_task(function* ()
|
||||
{
|
||||
const TEST_URI = NetUtil.newURI("http://example.com/");
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"A title");
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
do_check_true(frecencyForUrl(TEST_URI) > 0);
|
||||
|
||||
// Removing the bookmark should leave an orphan page with zero frecency.
|
||||
// Note this would usually be expired later by expiration.
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
do_check_eq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
// Now add a valid visit to the page, frecency should increase.
|
||||
yield PlacesTestUtils.addVisits({ uri: TEST_URI });
|
||||
do_check_true(frecencyForUrl(TEST_URI) > 0);
|
||||
});
|
||||
69
toolkit/components/places/tests/unit/test_getChildIndex.js
Normal file
69
toolkit/components/places/tests/unit/test_getChildIndex.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
* vim:set ts=2 sw=2 sts=2 et:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Tests nsNavHistoryContainerResultNode::GetChildIndex(aNode) functionality.
|
||||
*/
|
||||
|
||||
function run_test() {
|
||||
// Add a bookmark to the menu.
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarksMenuFolderId,
|
||||
uri("http://test.mozilla.org/bookmark/"),
|
||||
Ci.nsINavBookmarksService.DEFAULT_INDEX,
|
||||
"Test bookmark");
|
||||
|
||||
// Add a bookmark to unfiled folder.
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri("http://test.mozilla.org/unfiled/"),
|
||||
Ci.nsINavBookmarksService.DEFAULT_INDEX,
|
||||
"Unfiled bookmark");
|
||||
|
||||
// Get the unfiled bookmark node.
|
||||
let unfiledNode = getNodeAt(PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
if (!unfiledNode)
|
||||
do_throw("Unable to find bookmark in hierarchy!");
|
||||
do_check_eq(unfiledNode.title, "Unfiled bookmark");
|
||||
|
||||
let hs = PlacesUtils.history;
|
||||
let query = hs.getNewQuery();
|
||||
query.setFolders([PlacesUtils.bookmarksMenuFolderId], 1);
|
||||
let options = hs.getNewQueryOptions();
|
||||
options.queryType = options.QUERY_TYPE_BOOKMARKS;
|
||||
let root = hs.executeQuery(query, options).root;
|
||||
root.containerOpen = true;
|
||||
|
||||
// Check functionality for proper nodes.
|
||||
for (let i = 0; i < root.childCount; i++) {
|
||||
let node = root.getChild(i);
|
||||
print("Now testing: " + node.title);
|
||||
do_check_eq(root.getChildIndex(node), i);
|
||||
}
|
||||
|
||||
// Now search for an invalid node and expect an exception.
|
||||
try {
|
||||
root.getChildIndex(unfiledNode);
|
||||
do_throw("Searching for an invalid node should have thrown.");
|
||||
} catch (ex) {
|
||||
print("We correctly got an exception.");
|
||||
}
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
function getNodeAt(aFolderId, aIndex) {
|
||||
let hs = PlacesUtils.history;
|
||||
let query = hs.getNewQuery();
|
||||
query.setFolders([aFolderId], 1);
|
||||
let options = hs.getNewQueryOptions();
|
||||
options.queryType = options.QUERY_TYPE_BOOKMARKS;
|
||||
let root = hs.executeQuery(query, options).root;
|
||||
root.containerOpen = true;
|
||||
if (root.childCount < aIndex)
|
||||
do_throw("Not enough children to find bookmark!");
|
||||
let node = root.getChild(aIndex);
|
||||
root.containerOpen = false;
|
||||
return node;
|
||||
}
|
||||
112
toolkit/components/places/tests/unit/test_getPlacesInfo.js
Normal file
112
toolkit/components/places/tests/unit/test_getPlacesInfo.js
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function promiseGetPlacesInfo(aPlacesIdentifiers) {
|
||||
let deferred = Promise.defer();
|
||||
PlacesUtils.asyncHistory.getPlacesInfo(aPlacesIdentifiers, {
|
||||
_results: [],
|
||||
_errors: [],
|
||||
|
||||
handleResult: function handleResult(aPlaceInfo) {
|
||||
this._results.push(aPlaceInfo);
|
||||
},
|
||||
handleError: function handleError(aResultCode, aPlaceInfo) {
|
||||
this._errors.push({ resultCode: aResultCode, info: aPlaceInfo });
|
||||
},
|
||||
handleCompletion: function handleCompletion() {
|
||||
deferred.resolve({ errors: this._errors, results: this._results });
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function ensurePlacesInfoObjectsAreEqual(a, b) {
|
||||
do_check_true(a.uri.equals(b.uri));
|
||||
do_check_eq(a.title, b.title);
|
||||
do_check_eq(a.guid, b.guid);
|
||||
do_check_eq(a.placeId, b.placeId);
|
||||
}
|
||||
|
||||
function* test_getPlacesInfoExistentPlace() {
|
||||
let testURI = NetUtil.newURI("http://www.example.tld");
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
|
||||
let getPlacesInfoResult = yield promiseGetPlacesInfo([testURI]);
|
||||
do_check_eq(getPlacesInfoResult.results.length, 1);
|
||||
do_check_eq(getPlacesInfoResult.errors.length, 0);
|
||||
|
||||
let placeInfo = getPlacesInfoResult.results[0];
|
||||
do_check_true(placeInfo instanceof Ci.mozIPlaceInfo);
|
||||
|
||||
do_check_true(placeInfo.uri.equals(testURI));
|
||||
do_check_eq(placeInfo.title, "test visit for " + testURI.spec);
|
||||
do_check_true(placeInfo.guid.length > 0);
|
||||
do_check_eq(placeInfo.visits, null);
|
||||
}
|
||||
add_task(test_getPlacesInfoExistentPlace);
|
||||
|
||||
function* test_getPlacesInfoNonExistentPlace() {
|
||||
let testURI = NetUtil.newURI("http://www.example_non_existent.tld");
|
||||
let getPlacesInfoResult = yield promiseGetPlacesInfo(testURI);
|
||||
do_check_eq(getPlacesInfoResult.results.length, 0);
|
||||
do_check_eq(getPlacesInfoResult.errors.length, 1);
|
||||
}
|
||||
add_task(test_getPlacesInfoNonExistentPlace);
|
||||
|
||||
function* test_promisedHelper() {
|
||||
let uri = NetUtil.newURI("http://www.helper_existent_example.tld");
|
||||
yield PlacesTestUtils.addVisits(uri);
|
||||
let placeInfo = yield PlacesUtils.promisePlaceInfo(uri);
|
||||
do_check_true(placeInfo instanceof Ci.mozIPlaceInfo);
|
||||
|
||||
uri = NetUtil.newURI("http://www.helper_non_existent_example.tld");
|
||||
try {
|
||||
yield PlacesUtils.promisePlaceInfo(uri);
|
||||
do_throw("PlacesUtils.promisePlaceInfo should have rejected the promise");
|
||||
}
|
||||
catch (ex) { }
|
||||
}
|
||||
add_task(test_promisedHelper);
|
||||
|
||||
function* test_infoByGUID() {
|
||||
let testURI = NetUtil.newURI("http://www.guid_example.tld");
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
|
||||
let placeInfoByURI = yield PlacesUtils.promisePlaceInfo(testURI);
|
||||
let placeInfoByGUID = yield PlacesUtils.promisePlaceInfo(placeInfoByURI.guid);
|
||||
ensurePlacesInfoObjectsAreEqual(placeInfoByURI, placeInfoByGUID);
|
||||
}
|
||||
add_task(test_infoByGUID);
|
||||
|
||||
function* test_invalid_guid() {
|
||||
try {
|
||||
yield PlacesUtils.promisePlaceInfo("###");
|
||||
do_throw("getPlacesInfo should fail for invalid guids")
|
||||
}
|
||||
catch (ex) { }
|
||||
}
|
||||
add_task(test_invalid_guid);
|
||||
|
||||
function* test_mixed_selection() {
|
||||
let placeInfo1, placeInfo2;
|
||||
let uri = NetUtil.newURI("http://www.mixed_selection_test_1.tld");
|
||||
yield PlacesTestUtils.addVisits(uri);
|
||||
placeInfo1 = yield PlacesUtils.promisePlaceInfo(uri);
|
||||
|
||||
uri = NetUtil.newURI("http://www.mixed_selection_test_2.tld");
|
||||
yield PlacesTestUtils.addVisits(uri);
|
||||
placeInfo2 = yield PlacesUtils.promisePlaceInfo(uri);
|
||||
|
||||
let getPlacesInfoResult = yield promiseGetPlacesInfo([placeInfo1.uri, placeInfo2.guid]);
|
||||
do_check_eq(getPlacesInfoResult.results.length, 2);
|
||||
do_check_eq(getPlacesInfoResult.errors.length, 0);
|
||||
|
||||
do_check_eq(getPlacesInfoResult.results[0].uri.spec, placeInfo1.uri.spec);
|
||||
do_check_eq(getPlacesInfoResult.results[1].guid, placeInfo2.guid);
|
||||
}
|
||||
add_task(test_mixed_selection);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
184
toolkit/components/places/tests/unit/test_history.js
Normal file
184
toolkit/components/places/tests/unit/test_history.js
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get history services
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
/**
|
||||
* Checks to see that a URI is in the database.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check.
|
||||
* @returns true if the URI is in the DB, false otherwise.
|
||||
*/
|
||||
function uri_in_db(aURI) {
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
options.maxResults = 1;
|
||||
options.resultType = options.RESULTS_AS_URI
|
||||
var query = histsvc.getNewQuery();
|
||||
query.uri = aURI;
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var cc = root.childCount;
|
||||
root.containerOpen = false;
|
||||
return (cc == 1);
|
||||
}
|
||||
|
||||
// main
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
// we have a new profile, so we should have imported bookmarks
|
||||
do_check_eq(histsvc.databaseStatus, histsvc.DATABASE_STATUS_CREATE);
|
||||
|
||||
// add a visit
|
||||
var testURI = uri("http://mozilla.com");
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
|
||||
// now query for the visit, setting sorting and limit such that
|
||||
// we should retrieve only the visit we just added
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
options.maxResults = 1;
|
||||
// TODO: using full visit crashes in xpcshell test
|
||||
// options.resultType = options.RESULTS_AS_FULL_VISIT;
|
||||
options.resultType = options.RESULTS_AS_VISIT;
|
||||
var query = histsvc.getNewQuery();
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var cc = root.childCount;
|
||||
for (var i=0; i < cc; ++i) {
|
||||
var node = root.getChild(i);
|
||||
// test node properties in RESULTS_AS_VISIT
|
||||
do_check_eq(node.uri, testURI.spec);
|
||||
do_check_eq(node.type, Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
|
||||
// TODO: change query type to RESULTS_AS_FULL_VISIT and test this
|
||||
// do_check_eq(node.transitionType, histsvc.TRANSITION_TYPED);
|
||||
}
|
||||
root.containerOpen = false;
|
||||
|
||||
// add another visit for the same URI, and a third visit for a different URI
|
||||
var testURI2 = uri("http://google.com/");
|
||||
yield PlacesTestUtils.addVisits(testURI);
|
||||
yield PlacesTestUtils.addVisits(testURI2);
|
||||
|
||||
options.maxResults = 5;
|
||||
options.resultType = options.RESULTS_AS_URI;
|
||||
|
||||
// test minVisits
|
||||
query.minVisits = 0;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 2);
|
||||
result.root.containerOpen = false;
|
||||
query.minVisits = 1;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 2);
|
||||
result.root.containerOpen = false;
|
||||
query.minVisits = 2;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 1);
|
||||
query.minVisits = 3;
|
||||
result.root.containerOpen = false;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 0);
|
||||
result.root.containerOpen = false;
|
||||
|
||||
// test maxVisits
|
||||
query.minVisits = -1;
|
||||
query.maxVisits = -1;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 2);
|
||||
result.root.containerOpen = false;
|
||||
query.maxVisits = 0;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 0);
|
||||
result.root.containerOpen = false;
|
||||
query.maxVisits = 1;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 1);
|
||||
result.root.containerOpen = false;
|
||||
query.maxVisits = 2;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 2);
|
||||
result.root.containerOpen = false;
|
||||
query.maxVisits = 3;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 2);
|
||||
result.root.containerOpen = false;
|
||||
|
||||
// test annotation-based queries
|
||||
var annos = Cc["@mozilla.org/browser/annotation-service;1"].
|
||||
getService(Ci.nsIAnnotationService);
|
||||
annos.setPageAnnotation(uri("http://mozilla.com/"), "testAnno", 0, 0,
|
||||
Ci.nsIAnnotationService.EXPIRE_NEVER);
|
||||
query.annotation = "testAnno";
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 1);
|
||||
do_check_eq(result.root.getChild(0).uri, "http://mozilla.com/");
|
||||
result.root.containerOpen = false;
|
||||
|
||||
// test annotationIsNot
|
||||
query.annotationIsNot = true;
|
||||
result = histsvc.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
do_check_eq(result.root.childCount, 1);
|
||||
do_check_eq(result.root.getChild(0).uri, "http://google.com/");
|
||||
result.root.containerOpen = false;
|
||||
|
||||
// By default history is enabled.
|
||||
do_check_true(!histsvc.historyDisabled);
|
||||
|
||||
// test getPageTitle
|
||||
yield PlacesTestUtils.addVisits({ uri: uri("http://example.com"), title: "title" });
|
||||
let placeInfo = yield PlacesUtils.promisePlaceInfo(uri("http://example.com"));
|
||||
do_check_eq(placeInfo.title, "title");
|
||||
|
||||
// query for the visit
|
||||
do_check_true(uri_in_db(testURI));
|
||||
|
||||
// test for schema changes in bug 373239
|
||||
// get direct db connection
|
||||
var db = histsvc.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
|
||||
var q = "SELECT id FROM moz_bookmarks";
|
||||
var statement;
|
||||
try {
|
||||
statement = db.createStatement(q);
|
||||
} catch (ex) {
|
||||
do_throw("bookmarks table does not have id field, schema is too old!");
|
||||
}
|
||||
finally {
|
||||
statement.finalize();
|
||||
}
|
||||
|
||||
// bug 394741 - regressed history text searches
|
||||
yield PlacesTestUtils.addVisits(uri("http://mozilla.com"));
|
||||
options = histsvc.getNewQueryOptions();
|
||||
// options.resultType = options.RESULTS_AS_VISIT;
|
||||
query = histsvc.getNewQuery();
|
||||
query.searchTerms = "moz";
|
||||
result = histsvc.executeQuery(query, options);
|
||||
root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_true(root.childCount > 0);
|
||||
root.containerOpen = false;
|
||||
});
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var current_test = 0;
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get tagging service
|
||||
try {
|
||||
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
|
||||
getService(Ci.nsITaggingService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get tagging service\n");
|
||||
}
|
||||
|
||||
function ensure_tag_results(uris, searchTerm)
|
||||
{
|
||||
print("Searching for '" + searchTerm + "'");
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
|
||||
controller.input = input;
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
var numSearchesStarted = 0;
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
do_check_eq(controller.searchStatus,
|
||||
uris.length ?
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH :
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH);
|
||||
do_check_eq(controller.matchCount, uris.length);
|
||||
let vals = [];
|
||||
for (let i=0; i<controller.matchCount; i++) {
|
||||
// Keep the URL for later because order of tag results is undefined
|
||||
vals.push(controller.getValueAt(i));
|
||||
do_check_eq(controller.getStyleAt(i), "bookmark-tag");
|
||||
}
|
||||
// Sort the results then check if we have the right items
|
||||
vals.sort().forEach((val, i) => do_check_eq(val, uris[i].spec))
|
||||
|
||||
if (current_test < (tests.length - 1)) {
|
||||
current_test++;
|
||||
tests[current_test]();
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.startSearch(searchTerm);
|
||||
}
|
||||
|
||||
var uri1 = uri("http://site.tld/1/aaa");
|
||||
var uri2 = uri("http://site.tld/2/bbb");
|
||||
var uri3 = uri("http://site.tld/3/aaa");
|
||||
var uri4 = uri("http://site.tld/4/bbb");
|
||||
var uri5 = uri("http://site.tld/5/aaa");
|
||||
var uri6 = uri("http://site.tld/6/bbb");
|
||||
|
||||
var tests = [
|
||||
() => ensure_tag_results([uri1, uri4, uri6], "foo"),
|
||||
() => ensure_tag_results([uri1], "foo aaa"),
|
||||
() => ensure_tag_results([uri4, uri6], "foo bbb"),
|
||||
() => ensure_tag_results([uri2, uri4, uri5, uri6], "bar"),
|
||||
() => ensure_tag_results([uri5], "bar aaa"),
|
||||
() => ensure_tag_results([uri2, uri4, uri6], "bar bbb"),
|
||||
() => ensure_tag_results([uri3, uri5, uri6], "cheese"),
|
||||
() => ensure_tag_results([uri3, uri5], "chees aaa"),
|
||||
() => ensure_tag_results([uri6], "chees bbb"),
|
||||
() => ensure_tag_results([uri4, uri6], "fo bar"),
|
||||
() => ensure_tag_results([], "fo bar aaa"),
|
||||
() => ensure_tag_results([uri4, uri6], "fo bar bbb"),
|
||||
() => ensure_tag_results([uri4, uri6], "ba foo"),
|
||||
() => ensure_tag_results([], "ba foo aaa"),
|
||||
() => ensure_tag_results([uri4, uri6], "ba foo bbb"),
|
||||
() => ensure_tag_results([uri5, uri6], "ba chee"),
|
||||
() => ensure_tag_results([uri5], "ba chee aaa"),
|
||||
() => ensure_tag_results([uri6], "ba chee bbb"),
|
||||
() => ensure_tag_results([uri5, uri6], "cheese bar"),
|
||||
() => ensure_tag_results([uri5], "cheese bar aaa"),
|
||||
() => ensure_tag_results([uri6], "chees bar bbb"),
|
||||
() => ensure_tag_results([uri6], "cheese bar foo"),
|
||||
() => ensure_tag_results([], "foo bar cheese aaa"),
|
||||
() => ensure_tag_results([uri6], "foo bar cheese bbb"),
|
||||
];
|
||||
|
||||
/**
|
||||
* Properly tags a uri adding it to bookmarks.
|
||||
*
|
||||
* @param aURI
|
||||
* The nsIURI to tag.
|
||||
* @param aTags
|
||||
* The tags to add.
|
||||
*/
|
||||
function tagURI(aURI, aTags) {
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
aURI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"A title");
|
||||
tagssvc.tagURI(aURI, aTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test history autocomplete
|
||||
*/
|
||||
function run_test() {
|
||||
// always search in history + bookmarks, no matter what the default is
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
prefs.setIntPref("browser.urlbar.search.sources", 3);
|
||||
prefs.setIntPref("browser.urlbar.default.behavior", 0);
|
||||
|
||||
tagURI(uri1, ["foo"]);
|
||||
tagURI(uri2, ["bar"]);
|
||||
tagURI(uri3, ["cheese"]);
|
||||
tagURI(uri4, ["foo bar"]);
|
||||
tagURI(uri5, ["bar cheese"]);
|
||||
tagURI(uri6, ["foo bar cheese"]);
|
||||
|
||||
tests[0]();
|
||||
}
|
||||
55
toolkit/components/places/tests/unit/test_history_catobs.js
Normal file
55
toolkit/components/places/tests/unit/test_history_catobs.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
do_load_manifest("nsDummyObserver.manifest");
|
||||
|
||||
let dummyCreated = false;
|
||||
let dummyReceivedOnVisit = false;
|
||||
|
||||
Services.obs.addObserver(function created() {
|
||||
Services.obs.removeObserver(created, "dummy-observer-created");
|
||||
dummyCreated = true;
|
||||
}, "dummy-observer-created", false);
|
||||
Services.obs.addObserver(function visited() {
|
||||
Services.obs.removeObserver(visited, "dummy-observer-visited");
|
||||
dummyReceivedOnVisit = true;
|
||||
}, "dummy-observer-visited", false);
|
||||
|
||||
let initialObservers = PlacesUtils.history.getObservers();
|
||||
|
||||
// Add a common observer, it should be invoked after the category observer.
|
||||
let notificationsPromised = new Promise((resolve, reject) => {
|
||||
PlacesUtils.history.addObserver({
|
||||
__proto__: NavHistoryObserver.prototype,
|
||||
onVisit() {
|
||||
let observers = PlacesUtils.history.getObservers();
|
||||
Assert.equal(observers.length, initialObservers.length + 1);
|
||||
|
||||
// Check the common observer is the last one.
|
||||
for (let i = 0; i < initialObservers.length; ++i) {
|
||||
Assert.equal(initialObservers[i], observers[i]);
|
||||
}
|
||||
|
||||
PlacesUtils.history.removeObserver(this);
|
||||
observers = PlacesUtils.history.getObservers();
|
||||
Assert.equal(observers.length, initialObservers.length);
|
||||
|
||||
// Check the category observer has been invoked before this one.
|
||||
Assert.ok(dummyCreated);
|
||||
Assert.ok(dummyReceivedOnVisit);
|
||||
resolve();
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
|
||||
// Add a visit.
|
||||
yield PlacesTestUtils.addVisits(uri("http://typed.mozilla.org"));
|
||||
|
||||
yield notificationsPromised;
|
||||
});
|
||||
169
toolkit/components/places/tests/unit/test_history_clear.js
Normal file
169
toolkit/components/places/tests/unit/test_history_clear.js
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var mDBConn = DBConn();
|
||||
|
||||
function promiseOnClearHistoryObserved() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let historyObserver = {
|
||||
onBeginUpdateBatch: function() {},
|
||||
onEndUpdateBatch: function() {},
|
||||
onVisit: function() {},
|
||||
onTitleChanged: function() {},
|
||||
onDeleteURI: function(aURI) {},
|
||||
onPageChanged: function() {},
|
||||
onDeleteVisits: function() {},
|
||||
|
||||
onClearHistory: function() {
|
||||
PlacesUtils.history.removeObserver(this, false);
|
||||
deferred.resolve();
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsINavHistoryObserver,
|
||||
])
|
||||
}
|
||||
PlacesUtils.history.addObserver(historyObserver, false);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// This global variable is a promise object, initialized in run_test and waited
|
||||
// upon in the first asynchronous test. It is resolved when the
|
||||
// "places-init-complete" notification is received. We cannot initialize it in
|
||||
// the asynchronous test, because then it's too late to register the observer.
|
||||
var promiseInit;
|
||||
|
||||
function run_test() {
|
||||
// places-init-complete is notified after run_test, and it will
|
||||
// run a first frecency fix through async statements.
|
||||
// To avoid random failures we have to run after all of this.
|
||||
promiseInit = promiseTopicObserved(PlacesUtils.TOPIC_INIT_COMPLETE);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_history_clear()
|
||||
{
|
||||
yield promiseInit;
|
||||
|
||||
yield PlacesTestUtils.addVisits([
|
||||
{ uri: uri("http://typed.mozilla.org/"),
|
||||
transition: TRANSITION_TYPED },
|
||||
{ uri: uri("http://link.mozilla.org/"),
|
||||
transition: TRANSITION_LINK },
|
||||
{ uri: uri("http://download.mozilla.org/"),
|
||||
transition: TRANSITION_DOWNLOAD },
|
||||
{ uri: uri("http://redir_temp.mozilla.org/"),
|
||||
transition: TRANSITION_REDIRECT_TEMPORARY,
|
||||
referrer: "http://link.mozilla.org/"},
|
||||
{ uri: uri("http://redir_perm.mozilla.org/"),
|
||||
transition: TRANSITION_REDIRECT_PERMANENT,
|
||||
referrer: "http://link.mozilla.org/"},
|
||||
]);
|
||||
|
||||
// add a place: bookmark
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri("place:folder=4"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"shortcut");
|
||||
|
||||
// Add an expire never annotation
|
||||
// Actually expire never annotations are removed as soon as a page is removed
|
||||
// from the database, so this should act as a normal visit.
|
||||
PlacesUtils.annotations.setPageAnnotation(uri("http://download.mozilla.org/"),
|
||||
"never", "never", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
|
||||
// Add a bookmark
|
||||
// Bookmarked page should have history cleared and frecency = -1
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri("http://typed.mozilla.org/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark");
|
||||
|
||||
yield PlacesTestUtils.addVisits([
|
||||
{ uri: uri("http://typed.mozilla.org/"),
|
||||
transition: TRANSITION_BOOKMARK },
|
||||
{ uri: uri("http://frecency.mozilla.org/"),
|
||||
transition: TRANSITION_LINK },
|
||||
]);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// Clear history and wait for the onClearHistory notification.
|
||||
let promiseWaitClearHistory = promiseOnClearHistoryObserved();
|
||||
PlacesUtils.history.clear();
|
||||
yield promiseWaitClearHistory;
|
||||
|
||||
// check browserHistory returns no entries
|
||||
do_check_eq(0, PlacesUtils.history.hasHistoryEntries);
|
||||
|
||||
yield promiseTopicObserved(PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// Check that frecency for not cleared items (bookmarks) has been converted
|
||||
// to -1.
|
||||
stmt = mDBConn.createStatement(
|
||||
"SELECT h.id FROM moz_places h WHERE h.frecency > 0 ");
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
stmt = mDBConn.createStatement(
|
||||
`SELECT h.id FROM moz_places h WHERE h.frecency < 0
|
||||
AND EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1`);
|
||||
do_check_true(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
// Check that all visit_counts have been brought to 0
|
||||
stmt = mDBConn.createStatement(
|
||||
"SELECT id FROM moz_places WHERE visit_count <> 0 LIMIT 1");
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
// Check that history tables are empty
|
||||
stmt = mDBConn.createStatement(
|
||||
"SELECT * FROM (SELECT id FROM moz_historyvisits LIMIT 1)");
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
// Check that all moz_places entries except bookmarks and place: have been removed
|
||||
stmt = mDBConn.createStatement(
|
||||
`SELECT h.id FROM moz_places h WHERE
|
||||
url_hash NOT BETWEEN hash('place', 'prefix_lo') AND hash('place', 'prefix_hi')
|
||||
AND NOT EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1`);
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
// Check that we only have favicons for retained places
|
||||
stmt = mDBConn.createStatement(
|
||||
`SELECT f.id FROM moz_favicons f WHERE NOT EXISTS
|
||||
(SELECT id FROM moz_places WHERE favicon_id = f.id) LIMIT 1`);
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
// Check that we only have annotations for retained places
|
||||
stmt = mDBConn.createStatement(
|
||||
`SELECT a.id FROM moz_annos a WHERE NOT EXISTS
|
||||
(SELECT id FROM moz_places WHERE id = a.place_id) LIMIT 1`);
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
// Check that we only have inputhistory for retained places
|
||||
stmt = mDBConn.createStatement(
|
||||
`SELECT i.place_id FROM moz_inputhistory i WHERE NOT EXISTS
|
||||
(SELECT id FROM moz_places WHERE id = i.place_id) LIMIT 1`);
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
// Check that place:uris have frecency 0
|
||||
stmt = mDBConn.createStatement(
|
||||
`SELECT h.id FROM moz_places h
|
||||
WHERE url_hash BETWEEN hash('place', 'prefix_lo')
|
||||
AND hash('place', 'prefix_hi')
|
||||
AND h.frecency <> 0 LIMIT 1`);
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
});
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
const NS_PLACES_INIT_COMPLETE_TOPIC = "places-init-complete";
|
||||
const NS_PLACES_DATABASE_LOCKED_TOPIC = "places-database-locked";
|
||||
|
||||
add_task(function* () {
|
||||
// Create a dummy places.sqlite and open an unshared connection on it
|
||||
let db = Services.dirsvc.get('ProfD', Ci.nsIFile);
|
||||
db.append("places.sqlite");
|
||||
let dbConn = Services.storage.openUnsharedDatabase(db);
|
||||
Assert.ok(db.exists(), "The database should have been created");
|
||||
|
||||
// We need an exclusive lock on the db
|
||||
dbConn.executeSimpleSQL("PRAGMA locking_mode = EXCLUSIVE");
|
||||
// Exclusive locking is lazy applied, we need to make a write to activate it
|
||||
dbConn.executeSimpleSQL("PRAGMA USER_VERSION = 1");
|
||||
|
||||
// Try to create history service while the db is locked
|
||||
let promiseLocked = promiseTopicObserved(NS_PLACES_DATABASE_LOCKED_TOPIC);
|
||||
Assert.throws(() => Cc["@mozilla.org/browser/nav-history-service;1"]
|
||||
.getService(Ci.nsINavHistoryService),
|
||||
/NS_ERROR_XPC_GS_RETURNED_FAILURE/);
|
||||
yield promiseLocked;
|
||||
|
||||
// Close our connection and try to cleanup the file (could fail on Windows)
|
||||
dbConn.close();
|
||||
if (db.exists()) {
|
||||
try {
|
||||
db.remove(false);
|
||||
} catch (e) {
|
||||
do_print("Unable to remove dummy places.sqlite");
|
||||
}
|
||||
}
|
||||
|
||||
// Create history service correctly
|
||||
let promiseComplete = promiseTopicObserved(NS_PLACES_INIT_COMPLETE_TOPIC);
|
||||
Cc["@mozilla.org/browser/nav-history-service;1"]
|
||||
.getService(Ci.nsINavHistoryService);
|
||||
yield promiseComplete;
|
||||
});
|
||||
215
toolkit/components/places/tests/unit/test_history_observer.js
Normal file
215
toolkit/components/places/tests/unit/test_history_observer.js
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Generic nsINavHistoryObserver that doesn't implement anything, but provides
|
||||
* dummy methods to prevent errors about an object not having a certain method.
|
||||
*/
|
||||
function NavHistoryObserver() {
|
||||
}
|
||||
NavHistoryObserver.prototype = {
|
||||
onBeginUpdateBatch: function() { },
|
||||
onEndUpdateBatch: function() { },
|
||||
onVisit: function() { },
|
||||
onTitleChanged: function() { },
|
||||
onDeleteURI: function() { },
|
||||
onClearHistory: function() { },
|
||||
onPageChanged: function() { },
|
||||
onDeleteVisits: function() { },
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver])
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers a one-time history observer for and calls the callback
|
||||
* when the specified nsINavHistoryObserver method is called.
|
||||
* Returns a promise that is resolved when the callback returns.
|
||||
*/
|
||||
function onNotify(callback) {
|
||||
return new Promise(resolve => {
|
||||
let obs = new NavHistoryObserver();
|
||||
obs[callback.name] = function () {
|
||||
PlacesUtils.history.removeObserver(this);
|
||||
callback.apply(this, arguments);
|
||||
resolve();
|
||||
};
|
||||
PlacesUtils.history.addObserver(obs, false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronous task that adds a visit to the history database.
|
||||
*/
|
||||
function* task_add_visit(uri, timestamp, transition) {
|
||||
uri = uri || NetUtil.newURI("http://firefox.com/");
|
||||
timestamp = timestamp || Date.now() * 1000;
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: uri,
|
||||
transition: transition || TRANSITION_TYPED,
|
||||
visitDate: timestamp
|
||||
});
|
||||
return [uri, timestamp];
|
||||
}
|
||||
|
||||
add_task(function* test_onVisit() {
|
||||
let promiseNotify = onNotify(function onVisit(aURI, aVisitID, aTime,
|
||||
aSessionID, aReferringID,
|
||||
aTransitionType, aGUID,
|
||||
aHidden, aVisitCount, aTyped) {
|
||||
Assert.ok(aURI.equals(testuri));
|
||||
Assert.ok(aVisitID > 0);
|
||||
Assert.equal(aTime, testtime);
|
||||
Assert.equal(aSessionID, 0);
|
||||
Assert.equal(aReferringID, 0);
|
||||
Assert.equal(aTransitionType, TRANSITION_TYPED);
|
||||
do_check_guid_for_uri(aURI, aGUID);
|
||||
Assert.ok(!aHidden);
|
||||
Assert.equal(aVisitCount, 1);
|
||||
Assert.equal(aTyped, 1);
|
||||
});
|
||||
let testuri = NetUtil.newURI("http://firefox.com/");
|
||||
let testtime = Date.now() * 1000;
|
||||
yield task_add_visit(testuri, testtime);
|
||||
yield promiseNotify;
|
||||
});
|
||||
|
||||
add_task(function* test_onVisit() {
|
||||
let promiseNotify = onNotify(function onVisit(aURI, aVisitID, aTime,
|
||||
aSessionID, aReferringID,
|
||||
aTransitionType, aGUID,
|
||||
aHidden, aVisitCount, aTyped) {
|
||||
Assert.ok(aURI.equals(testuri));
|
||||
Assert.ok(aVisitID > 0);
|
||||
Assert.equal(aTime, testtime);
|
||||
Assert.equal(aSessionID, 0);
|
||||
Assert.equal(aReferringID, 0);
|
||||
Assert.equal(aTransitionType, TRANSITION_FRAMED_LINK);
|
||||
do_check_guid_for_uri(aURI, aGUID);
|
||||
Assert.ok(aHidden);
|
||||
Assert.equal(aVisitCount, 1);
|
||||
Assert.equal(aTyped, 0);
|
||||
});
|
||||
let testuri = NetUtil.newURI("http://hidden.firefox.com/");
|
||||
let testtime = Date.now() * 1000;
|
||||
yield task_add_visit(testuri, testtime, TRANSITION_FRAMED_LINK);
|
||||
yield promiseNotify;
|
||||
});
|
||||
|
||||
add_task(function* test_multiple_onVisit() {
|
||||
let testuri = NetUtil.newURI("http://self.firefox.com/");
|
||||
let promiseNotifications = new Promise(resolve => {
|
||||
let observer = {
|
||||
_c: 0,
|
||||
__proto__: NavHistoryObserver.prototype,
|
||||
onVisit(uri, id, time, unused, referrerId, transition, guid,
|
||||
hidden, visitCount, typed) {
|
||||
Assert.ok(testuri.equals(uri));
|
||||
Assert.ok(id > 0);
|
||||
Assert.ok(time > 0);
|
||||
Assert.ok(!hidden);
|
||||
do_check_guid_for_uri(uri, guid);
|
||||
switch (++this._c) {
|
||||
case 1:
|
||||
Assert.equal(referrerId, 0);
|
||||
Assert.equal(transition, TRANSITION_LINK);
|
||||
Assert.equal(visitCount, 1);
|
||||
Assert.equal(typed, 0);
|
||||
break;
|
||||
case 2:
|
||||
Assert.ok(referrerId > 0);
|
||||
Assert.equal(transition, TRANSITION_LINK);
|
||||
Assert.equal(visitCount, 2);
|
||||
Assert.equal(typed, 0);
|
||||
break;
|
||||
case 3:
|
||||
Assert.equal(referrerId, 0);
|
||||
Assert.equal(transition, TRANSITION_TYPED);
|
||||
Assert.equal(visitCount, 3);
|
||||
Assert.equal(typed, 1);
|
||||
|
||||
PlacesUtils.history.removeObserver(observer, false);
|
||||
resolve();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
PlacesUtils.history.addObserver(observer, false);
|
||||
});
|
||||
yield PlacesTestUtils.addVisits([
|
||||
{ uri: testuri, transition: TRANSITION_LINK },
|
||||
{ uri: testuri, referrer: testuri, transition: TRANSITION_LINK },
|
||||
{ uri: testuri, transition: TRANSITION_TYPED },
|
||||
]);
|
||||
yield promiseNotifications;
|
||||
});
|
||||
|
||||
add_task(function* test_onDeleteURI() {
|
||||
let promiseNotify = onNotify(function onDeleteURI(aURI, aGUID, aReason) {
|
||||
Assert.ok(aURI.equals(testuri));
|
||||
// Can't use do_check_guid_for_uri() here because the visit is already gone.
|
||||
Assert.equal(aGUID, testguid);
|
||||
Assert.equal(aReason, Ci.nsINavHistoryObserver.REASON_DELETED);
|
||||
});
|
||||
let [testuri] = yield task_add_visit();
|
||||
let testguid = do_get_guid_for_uri(testuri);
|
||||
PlacesUtils.bhistory.removePage(testuri);
|
||||
yield promiseNotify;
|
||||
});
|
||||
|
||||
add_task(function* test_onDeleteVisits() {
|
||||
let promiseNotify = onNotify(function onDeleteVisits(aURI, aVisitTime, aGUID,
|
||||
aReason) {
|
||||
Assert.ok(aURI.equals(testuri));
|
||||
// Can't use do_check_guid_for_uri() here because the visit is already gone.
|
||||
Assert.equal(aGUID, testguid);
|
||||
Assert.equal(aReason, Ci.nsINavHistoryObserver.REASON_DELETED);
|
||||
Assert.equal(aVisitTime, 0); // All visits have been removed.
|
||||
});
|
||||
let msecs24hrsAgo = Date.now() - (86400 * 1000);
|
||||
let [testuri] = yield task_add_visit(undefined, msecs24hrsAgo * 1000);
|
||||
// Add a bookmark so the page is not removed.
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
testuri,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test");
|
||||
let testguid = do_get_guid_for_uri(testuri);
|
||||
PlacesUtils.bhistory.removePage(testuri);
|
||||
yield promiseNotify;
|
||||
});
|
||||
|
||||
add_task(function* test_onTitleChanged() {
|
||||
let promiseNotify = onNotify(function onTitleChanged(aURI, aTitle, aGUID) {
|
||||
Assert.ok(aURI.equals(testuri));
|
||||
Assert.equal(aTitle, title);
|
||||
do_check_guid_for_uri(aURI, aGUID);
|
||||
});
|
||||
|
||||
let [testuri] = yield task_add_visit();
|
||||
let title = "test-title";
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: testuri,
|
||||
title: title
|
||||
});
|
||||
yield promiseNotify;
|
||||
});
|
||||
|
||||
add_task(function* test_onPageChanged() {
|
||||
let promiseNotify = onNotify(function onPageChanged(aURI, aChangedAttribute,
|
||||
aNewValue, aGUID) {
|
||||
Assert.equal(aChangedAttribute, Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON);
|
||||
Assert.ok(aURI.equals(testuri));
|
||||
Assert.equal(aNewValue, SMALLPNG_DATA_URI.spec);
|
||||
do_check_guid_for_uri(aURI, aGUID);
|
||||
});
|
||||
|
||||
let [testuri] = yield task_add_visit();
|
||||
|
||||
// The new favicon for the page must have data associated with it in order to
|
||||
// receive the onPageChanged notification. To keep this test self-contained,
|
||||
// we use an URI representing the smallest possible PNG file.
|
||||
PlacesUtils.favicons.setAndFetchFaviconForPage(testuri, SMALLPNG_DATA_URI,
|
||||
false,
|
||||
PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
|
||||
null,
|
||||
Services.scriptSecurityManager.getSystemPrincipal());
|
||||
yield promiseNotify;
|
||||
});
|
||||
447
toolkit/components/places/tests/unit/test_history_sidebar.js
Normal file
447
toolkit/components/places/tests/unit/test_history_sidebar.js
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get history service
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bh = hs.QueryInterface(Ci.nsIBrowserHistory);
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var ps = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
|
||||
/**
|
||||
* Adds a test URI visit to the database.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add a visit for.
|
||||
* @param aTime
|
||||
* Reference "now" time.
|
||||
* @param aDayOffset
|
||||
* number of days to add, pass a negative value to subtract them.
|
||||
*/
|
||||
function* task_add_normalized_visit(aURI, aTime, aDayOffset) {
|
||||
var dateObj = new Date(aTime);
|
||||
// Normalize to midnight
|
||||
dateObj.setHours(0);
|
||||
dateObj.setMinutes(0);
|
||||
dateObj.setSeconds(0);
|
||||
dateObj.setMilliseconds(0);
|
||||
// Days where DST changes should be taken in count.
|
||||
var previousDateObj = new Date(dateObj.getTime() + aDayOffset * 86400000);
|
||||
var DSTCorrection = (dateObj.getTimezoneOffset() -
|
||||
previousDateObj.getTimezoneOffset()) * 60 * 1000;
|
||||
// Substract aDayOffset
|
||||
var PRTimeWithOffset = (previousDateObj.getTime() - DSTCorrection) * 1000;
|
||||
var timeInMs = new Date(PRTimeWithOffset/1000);
|
||||
print("Adding visit to " + aURI.spec + " at " + timeInMs);
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: aURI,
|
||||
visitDate: PRTimeWithOffset
|
||||
});
|
||||
}
|
||||
|
||||
function days_for_x_months_ago(aNowObj, aMonths) {
|
||||
var oldTime = new Date();
|
||||
// Set day before month, otherwise we could try to calculate 30 February, or
|
||||
// other nonexistent days.
|
||||
oldTime.setDate(1);
|
||||
oldTime.setMonth(aNowObj.getMonth() - aMonths);
|
||||
oldTime.setHours(0);
|
||||
oldTime.setMinutes(0);
|
||||
oldTime.setSeconds(0);
|
||||
// Stay larger for eventual timezone issues, add 2 days.
|
||||
return parseInt((aNowObj - oldTime) / (1000*60*60*24)) + 2;
|
||||
}
|
||||
|
||||
var nowObj = new Date();
|
||||
// This test relies on en-US locale
|
||||
// Offset is number of days
|
||||
/* eslint-disable comma-spacing */
|
||||
var containers = [
|
||||
{ label: "Today" , offset: 0 , visible: true },
|
||||
{ label: "Yesterday" , offset: -1 , visible: true },
|
||||
{ label: "Last 7 days" , offset: -3 , visible: true },
|
||||
{ label: "This month" , offset: -8 , visible: nowObj.getDate() > 8 },
|
||||
{ label: "" , offset: -days_for_x_months_ago(nowObj, 0) , visible: true },
|
||||
{ label: "" , offset: -days_for_x_months_ago(nowObj, 1) , visible: true },
|
||||
{ label: "" , offset: -days_for_x_months_ago(nowObj, 2) , visible: true },
|
||||
{ label: "" , offset: -days_for_x_months_ago(nowObj, 3) , visible: true },
|
||||
{ label: "" , offset: -days_for_x_months_ago(nowObj, 4) , visible: true },
|
||||
{ label: "Older than 6 months" , offset: -days_for_x_months_ago(nowObj, 5) , visible: true },
|
||||
];
|
||||
/* eslint-enable comma-spacing */
|
||||
|
||||
var visibleContainers = containers.filter(
|
||||
function(aContainer) { return aContainer.visible });
|
||||
|
||||
/**
|
||||
* Asynchronous task that fills history and checks containers' labels.
|
||||
*/
|
||||
function* task_fill_history() {
|
||||
print("\n\n*** TEST Fill History\n");
|
||||
// We can't use "now" because our hardcoded offsets would be invalid for some
|
||||
// date. So we hardcode a date.
|
||||
for (let i = 0; i < containers.length; i++) {
|
||||
let container = containers[i];
|
||||
var testURI = uri("http://mirror"+i+".mozilla.com/b");
|
||||
yield task_add_normalized_visit(testURI, nowObj.getTime(), container.offset);
|
||||
testURI = uri("http://mirror"+i+".mozilla.com/a");
|
||||
yield task_add_normalized_visit(testURI, nowObj.getTime(), container.offset);
|
||||
testURI = uri("http://mirror"+i+".google.com/b");
|
||||
yield task_add_normalized_visit(testURI, nowObj.getTime(), container.offset);
|
||||
testURI = uri("http://mirror"+i+".google.com/a");
|
||||
yield task_add_normalized_visit(testURI, nowObj.getTime(), container.offset);
|
||||
// Bug 485703 - Hide date containers not containing additional entries
|
||||
// compared to previous ones.
|
||||
// Check after every new container is added.
|
||||
check_visit(container.offset);
|
||||
}
|
||||
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_DATE_SITE_QUERY;
|
||||
var query = hs.getNewQuery();
|
||||
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
|
||||
var cc = root.childCount;
|
||||
print("Found containers:");
|
||||
var previousLabels = [];
|
||||
for (let i = 0; i < cc; i++) {
|
||||
let container = visibleContainers[i];
|
||||
var node = root.getChild(i);
|
||||
print(node.title);
|
||||
if (container.label)
|
||||
do_check_eq(node.title, container.label);
|
||||
// Check labels are not repeated.
|
||||
do_check_eq(previousLabels.indexOf(node.title), -1);
|
||||
previousLabels.push(node.title);
|
||||
}
|
||||
do_check_eq(cc, visibleContainers.length);
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bug 485703 - Hide date containers not containing additional entries compared
|
||||
* to previous ones.
|
||||
*/
|
||||
function check_visit(aOffset) {
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_DATE_SITE_QUERY;
|
||||
var query = hs.getNewQuery();
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
var cc = root.childCount;
|
||||
|
||||
var unexpected = [];
|
||||
switch (aOffset) {
|
||||
case 0:
|
||||
unexpected = ["Yesterday", "Last 7 days", "This month"];
|
||||
break;
|
||||
case -1:
|
||||
unexpected = ["Last 7 days", "This month"];
|
||||
break;
|
||||
case -3:
|
||||
unexpected = ["This month"];
|
||||
break;
|
||||
default:
|
||||
// Other containers are tested later.
|
||||
}
|
||||
|
||||
print("Found containers:");
|
||||
for (var i = 0; i < cc; i++) {
|
||||
var node = root.getChild(i);
|
||||
print(node.title);
|
||||
do_check_eq(unexpected.indexOf(node.title), -1);
|
||||
}
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries history grouped by date and site, checking containers' labels and
|
||||
* children.
|
||||
*/
|
||||
function test_RESULTS_AS_DATE_SITE_QUERY() {
|
||||
print("\n\n*** TEST RESULTS_AS_DATE_SITE_QUERY\n");
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_DATE_SITE_QUERY;
|
||||
var query = hs.getNewQuery();
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
|
||||
// Check one of the days
|
||||
var dayNode = root.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
dayNode.containerOpen = true;
|
||||
do_check_eq(dayNode.childCount, 2);
|
||||
|
||||
// Items should be sorted by host
|
||||
var site1 = dayNode.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(site1.title, "mirror0.google.com");
|
||||
|
||||
var site2 = dayNode.getChild(1)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(site2.title, "mirror0.mozilla.com");
|
||||
|
||||
site1.containerOpen = true;
|
||||
do_check_eq(site1.childCount, 2);
|
||||
|
||||
// Inside of host sites are sorted by title
|
||||
var site1visit = site1.getChild(0);
|
||||
do_check_eq(site1visit.uri, "http://mirror0.google.com/a");
|
||||
|
||||
// Bug 473157: changing sorting mode should not affect the containers
|
||||
result.sortingMode = options.SORT_BY_TITLE_DESCENDING;
|
||||
|
||||
// Check one of the days
|
||||
dayNode = root.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
dayNode.containerOpen = true;
|
||||
do_check_eq(dayNode.childCount, 2);
|
||||
|
||||
// Hosts are still sorted by title
|
||||
site1 = dayNode.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(site1.title, "mirror0.google.com");
|
||||
|
||||
site2 = dayNode.getChild(1)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(site2.title, "mirror0.mozilla.com");
|
||||
|
||||
site1.containerOpen = true;
|
||||
do_check_eq(site1.childCount, 2);
|
||||
|
||||
// But URLs are now sorted by title descending
|
||||
site1visit = site1.getChild(0);
|
||||
do_check_eq(site1visit.uri, "http://mirror0.google.com/b");
|
||||
|
||||
site1.containerOpen = false;
|
||||
dayNode.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries history grouped by date, checking containers' labels and children.
|
||||
*/
|
||||
function test_RESULTS_AS_DATE_QUERY() {
|
||||
print("\n\n*** TEST RESULTS_AS_DATE_QUERY\n");
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_DATE_QUERY;
|
||||
var query = hs.getNewQuery();
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
|
||||
var cc = root.childCount;
|
||||
do_check_eq(cc, visibleContainers.length);
|
||||
print("Found containers:");
|
||||
for (var i = 0; i < cc; i++) {
|
||||
var container = visibleContainers[i];
|
||||
var node = root.getChild(i);
|
||||
print(node.title);
|
||||
if (container.label)
|
||||
do_check_eq(node.title, container.label);
|
||||
}
|
||||
|
||||
// Check one of the days
|
||||
var dayNode = root.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
dayNode.containerOpen = true;
|
||||
do_check_eq(dayNode.childCount, 4);
|
||||
|
||||
// Items should be sorted by title
|
||||
var visit1 = dayNode.getChild(0);
|
||||
do_check_eq(visit1.uri, "http://mirror0.google.com/a");
|
||||
|
||||
var visit2 = dayNode.getChild(3);
|
||||
do_check_eq(visit2.uri, "http://mirror0.mozilla.com/b");
|
||||
|
||||
// Bug 473157: changing sorting mode should not affect the containers
|
||||
result.sortingMode = options.SORT_BY_TITLE_DESCENDING;
|
||||
|
||||
// Check one of the days
|
||||
dayNode = root.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
dayNode.containerOpen = true;
|
||||
do_check_eq(dayNode.childCount, 4);
|
||||
|
||||
// But URLs are now sorted by title descending
|
||||
visit1 = dayNode.getChild(0);
|
||||
do_check_eq(visit1.uri, "http://mirror0.mozilla.com/b");
|
||||
|
||||
visit2 = dayNode.getChild(3);
|
||||
do_check_eq(visit2.uri, "http://mirror0.google.com/a");
|
||||
|
||||
dayNode.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries history grouped by site, checking containers' labels and children.
|
||||
*/
|
||||
function test_RESULTS_AS_SITE_QUERY() {
|
||||
print("\n\n*** TEST RESULTS_AS_SITE_QUERY\n");
|
||||
// add a bookmark with a domain not in the set of visits in the db
|
||||
var itemId = bs.insertBookmark(bs.toolbarFolder, uri("http://foobar"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_SITE_QUERY;
|
||||
options.sortingMode = options.SORT_BY_TITLE_ASCENDING;
|
||||
var query = hs.getNewQuery();
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, containers.length * 2);
|
||||
|
||||
/* Expected results:
|
||||
"mirror0.google.com",
|
||||
"mirror0.mozilla.com",
|
||||
"mirror1.google.com",
|
||||
"mirror1.mozilla.com",
|
||||
"mirror2.google.com",
|
||||
"mirror2.mozilla.com",
|
||||
"mirror3.google.com", <== We check for this site (index 6)
|
||||
"mirror3.mozilla.com",
|
||||
"mirror4.google.com",
|
||||
"mirror4.mozilla.com",
|
||||
"mirror5.google.com",
|
||||
"mirror5.mozilla.com",
|
||||
...
|
||||
*/
|
||||
|
||||
// Items should be sorted by host
|
||||
var siteNode = root.getChild(6)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(siteNode.title, "mirror3.google.com");
|
||||
|
||||
siteNode.containerOpen = true;
|
||||
do_check_eq(siteNode.childCount, 2);
|
||||
|
||||
// Inside of host sites are sorted by title
|
||||
var visitNode = siteNode.getChild(0);
|
||||
do_check_eq(visitNode.uri, "http://mirror3.google.com/a");
|
||||
|
||||
// Bug 473157: changing sorting mode should not affect the containers
|
||||
result.sortingMode = options.SORT_BY_TITLE_DESCENDING;
|
||||
siteNode = root.getChild(6)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(siteNode.title, "mirror3.google.com");
|
||||
|
||||
siteNode.containerOpen = true;
|
||||
do_check_eq(siteNode.childCount, 2);
|
||||
|
||||
// But URLs are now sorted by title descending
|
||||
var visit = siteNode.getChild(0);
|
||||
do_check_eq(visit.uri, "http://mirror3.google.com/b");
|
||||
|
||||
siteNode.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
|
||||
// Cleanup.
|
||||
bs.removeItem(itemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that queries grouped by date do liveupdate correctly.
|
||||
*/
|
||||
function* task_test_date_liveupdate(aResultType) {
|
||||
var midnight = nowObj;
|
||||
midnight.setHours(0);
|
||||
midnight.setMinutes(0);
|
||||
midnight.setSeconds(0);
|
||||
midnight.setMilliseconds(0);
|
||||
|
||||
// TEST 1. Test that the query correctly updates when it is root.
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.resultType = aResultType;
|
||||
var query = hs.getNewQuery();
|
||||
var result = hs.executeQuery(query, options);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
|
||||
do_check_eq(root.childCount, visibleContainers.length);
|
||||
// Remove "Today".
|
||||
hs.removePagesByTimeframe(midnight.getTime() * 1000, Date.now() * 1000);
|
||||
do_check_eq(root.childCount, visibleContainers.length - 1);
|
||||
|
||||
// Open "Last 7 days" container, this way we will have a container accepting
|
||||
// the new visit, but we should still add back "Today" container.
|
||||
var last7Days = root.getChild(1)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
last7Days.containerOpen = true;
|
||||
|
||||
// Add a visit for "Today". This should add back the missing "Today"
|
||||
// container.
|
||||
yield task_add_normalized_visit(uri("http://www.mozilla.org/"), nowObj.getTime(), 0);
|
||||
do_check_eq(root.childCount, visibleContainers.length);
|
||||
|
||||
last7Days.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
|
||||
// TEST 2. Test that the query correctly updates even if it is not root.
|
||||
var itemId = bs.insertBookmark(bs.toolbarFolder,
|
||||
uri("place:type=" + aResultType),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
|
||||
// Query toolbar and open our query container, then check again liveupdate.
|
||||
options = hs.getNewQueryOptions();
|
||||
query = hs.getNewQuery();
|
||||
query.setFolders([bs.toolbarFolder], 1);
|
||||
result = hs.executeQuery(query, options);
|
||||
root = result.root;
|
||||
root.containerOpen = true;
|
||||
do_check_eq(root.childCount, 1);
|
||||
var dateContainer = root.getChild(0).QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
dateContainer.containerOpen = true;
|
||||
|
||||
do_check_eq(dateContainer.childCount, visibleContainers.length);
|
||||
// Remove "Today".
|
||||
hs.removePagesByTimeframe(midnight.getTime() * 1000, Date.now() * 1000);
|
||||
do_check_eq(dateContainer.childCount, visibleContainers.length - 1);
|
||||
// Add a visit for "Today".
|
||||
yield task_add_normalized_visit(uri("http://www.mozilla.org/"), nowObj.getTime(), 0);
|
||||
do_check_eq(dateContainer.childCount, visibleContainers.length);
|
||||
|
||||
dateContainer.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
|
||||
// Cleanup.
|
||||
bs.removeItem(itemId);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_history_sidebar()
|
||||
{
|
||||
// If we're dangerously close to a date change, just bail out.
|
||||
if (nowObj.getHours() == 23 && nowObj.getMinutes() >= 50) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield task_fill_history();
|
||||
test_RESULTS_AS_DATE_SITE_QUERY();
|
||||
test_RESULTS_AS_DATE_QUERY();
|
||||
test_RESULTS_AS_SITE_QUERY();
|
||||
|
||||
yield task_test_date_liveupdate(Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY);
|
||||
yield task_test_date_liveupdate(Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY);
|
||||
|
||||
// The remaining views are
|
||||
// RESULTS_AS_URI + SORT_BY_VISITCOUNT_DESCENDING
|
||||
// -> test_399266.js
|
||||
// RESULTS_AS_URI + SORT_BY_DATE_DESCENDING
|
||||
// -> test_385397.js
|
||||
});
|
||||
226
toolkit/components/places/tests/unit/test_hosts_triggers.js
Normal file
226
toolkit/components/places/tests/unit/test_hosts_triggers.js
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the validity of various triggers that add remove hosts from moz_hosts
|
||||
*/
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gHistory",
|
||||
"@mozilla.org/browser/history;1",
|
||||
"mozIAsyncHistory");
|
||||
|
||||
// add some visits and remove them, add a bookmark,
|
||||
// change its uri, then remove it, and
|
||||
// for each change check that moz_hosts has correctly been updated.
|
||||
|
||||
function isHostInMozPlaces(aURI)
|
||||
{
|
||||
let stmt = DBConn().createStatement(
|
||||
`SELECT url
|
||||
FROM moz_places
|
||||
WHERE url_hash = hash(:host) AND url = :host`
|
||||
);
|
||||
let result = false;
|
||||
stmt.params.host = aURI.spec;
|
||||
while (stmt.executeStep()) {
|
||||
if (stmt.row.url == aURI.spec) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
stmt.finalize();
|
||||
return result;
|
||||
}
|
||||
|
||||
function isHostInMozHosts(aURI, aTyped, aPrefix)
|
||||
{
|
||||
let stmt = DBConn().createStatement(
|
||||
`SELECT host, typed, prefix
|
||||
FROM moz_hosts
|
||||
WHERE host = fixup_url(:host)
|
||||
AND frecency NOTNULL`
|
||||
);
|
||||
let result = false;
|
||||
stmt.params.host = aURI.host;
|
||||
if (stmt.executeStep()) {
|
||||
result = aTyped == stmt.row.typed && aPrefix == stmt.row.prefix;
|
||||
}
|
||||
stmt.finalize();
|
||||
return result;
|
||||
}
|
||||
|
||||
var urls = [{uri: NetUtil.newURI("http://visit1.mozilla.org"),
|
||||
expected: "visit1.mozilla.org",
|
||||
typed: 0,
|
||||
prefix: null
|
||||
},
|
||||
{uri: NetUtil.newURI("http://visit2.mozilla.org"),
|
||||
expected: "visit2.mozilla.org",
|
||||
typed: 0,
|
||||
prefix: null
|
||||
},
|
||||
{uri: NetUtil.newURI("http://www.foo.mozilla.org"),
|
||||
expected: "foo.mozilla.org",
|
||||
typed: 1,
|
||||
prefix: "www."
|
||||
},
|
||||
];
|
||||
|
||||
const NEW_URL = "http://different.mozilla.org/";
|
||||
|
||||
add_task(function* test_moz_hosts_update()
|
||||
{
|
||||
let places = [];
|
||||
urls.forEach(function(url) {
|
||||
let place = { uri: url.uri,
|
||||
title: "test for " + url.url,
|
||||
transition: url.typed ? TRANSITION_TYPED : undefined };
|
||||
places.push(place);
|
||||
});
|
||||
|
||||
yield PlacesTestUtils.addVisits(places);
|
||||
|
||||
do_check_true(isHostInMozHosts(urls[0].uri, urls[0].typed, urls[0].prefix));
|
||||
do_check_true(isHostInMozHosts(urls[1].uri, urls[1].typed, urls[1].prefix));
|
||||
do_check_true(isHostInMozHosts(urls[2].uri, urls[2].typed, urls[2].prefix));
|
||||
});
|
||||
|
||||
add_task(function* test_remove_places()
|
||||
{
|
||||
for (let idx in urls) {
|
||||
PlacesUtils.history.removePage(urls[idx].uri);
|
||||
}
|
||||
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
|
||||
for (let idx in urls) {
|
||||
do_check_false(isHostInMozHosts(urls[idx].uri, urls[idx].typed, urls[idx].prefix));
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_bookmark_changes()
|
||||
{
|
||||
let testUri = NetUtil.newURI("http://test.mozilla.org");
|
||||
|
||||
let itemId = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
testUri,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
|
||||
do_check_true(isHostInMozPlaces(testUri));
|
||||
|
||||
// Change the hostname
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(itemId, NetUtil.newURI(NEW_URL));
|
||||
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
|
||||
let newUri = NetUtil.newURI(NEW_URL);
|
||||
do_check_true(isHostInMozPlaces(newUri));
|
||||
do_check_true(isHostInMozHosts(newUri, false, null));
|
||||
do_check_false(isHostInMozHosts(NetUtil.newURI("http://test.mozilla.org"), false, null));
|
||||
});
|
||||
|
||||
add_task(function* test_bookmark_removal()
|
||||
{
|
||||
let itemId = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
let newUri = NetUtil.newURI(NEW_URL);
|
||||
PlacesUtils.bookmarks.removeItem(itemId);
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
|
||||
do_check_false(isHostInMozHosts(newUri, false, null));
|
||||
});
|
||||
|
||||
add_task(function* test_moz_hosts_typed_update()
|
||||
{
|
||||
const TEST_URI = NetUtil.newURI("http://typed.mozilla.com");
|
||||
let places = [{ uri: TEST_URI
|
||||
, title: "test for " + TEST_URI.spec
|
||||
},
|
||||
{ uri: TEST_URI
|
||||
, title: "test for " + TEST_URI.spec
|
||||
, transition: TRANSITION_TYPED
|
||||
}];
|
||||
|
||||
yield PlacesTestUtils.addVisits(places);
|
||||
|
||||
do_check_true(isHostInMozHosts(TEST_URI, true, null));
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
add_task(function* test_moz_hosts_www_remove()
|
||||
{
|
||||
function* test_removal(aURIToRemove, aURIToKeep, aCallback) {
|
||||
let places = [{ uri: aURIToRemove
|
||||
, title: "test for " + aURIToRemove.spec
|
||||
, transition: TRANSITION_TYPED
|
||||
},
|
||||
{ uri: aURIToKeep
|
||||
, title: "test for " + aURIToKeep.spec
|
||||
, transition: TRANSITION_TYPED
|
||||
}];
|
||||
|
||||
yield PlacesTestUtils.addVisits(places);
|
||||
print("removing " + aURIToRemove.spec + " keeping " + aURIToKeep);
|
||||
dump_table("moz_hosts");
|
||||
dump_table("moz_places");
|
||||
PlacesUtils.history.removePage(aURIToRemove);
|
||||
let prefix = /www/.test(aURIToKeep.spec) ? "www." : null;
|
||||
dump_table("moz_hosts");
|
||||
dump_table("moz_places");
|
||||
do_check_true(isHostInMozHosts(aURIToKeep, true, prefix));
|
||||
}
|
||||
|
||||
const TEST_URI = NetUtil.newURI("http://rem.mozilla.com");
|
||||
const TEST_WWW_URI = NetUtil.newURI("http://www.rem.mozilla.com");
|
||||
yield test_removal(TEST_URI, TEST_WWW_URI);
|
||||
yield test_removal(TEST_WWW_URI, TEST_URI);
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
add_task(function* test_moz_hosts_ftp_matchall()
|
||||
{
|
||||
const TEST_URI_1 = NetUtil.newURI("ftp://www.mozilla.com/");
|
||||
const TEST_URI_2 = NetUtil.newURI("ftp://mozilla.com/");
|
||||
|
||||
yield PlacesTestUtils.addVisits([
|
||||
{ uri: TEST_URI_1, transition: TRANSITION_TYPED },
|
||||
{ uri: TEST_URI_2, transition: TRANSITION_TYPED }
|
||||
]);
|
||||
|
||||
do_check_true(isHostInMozHosts(TEST_URI_1, true, "ftp://"));
|
||||
});
|
||||
|
||||
add_task(function* test_moz_hosts_ftp_not_matchall()
|
||||
{
|
||||
const TEST_URI_1 = NetUtil.newURI("http://mozilla.com/");
|
||||
const TEST_URI_2 = NetUtil.newURI("ftp://mozilla.com/");
|
||||
|
||||
yield PlacesTestUtils.addVisits([
|
||||
{ uri: TEST_URI_1, transition: TRANSITION_TYPED },
|
||||
{ uri: TEST_URI_2, transition: TRANSITION_TYPED }
|
||||
]);
|
||||
|
||||
do_check_true(isHostInMozHosts(TEST_URI_1, true, null));
|
||||
});
|
||||
|
||||
add_task(function* test_moz_hosts_update_2()
|
||||
{
|
||||
// Check that updating trigger takes into account prefixes for different
|
||||
// rev_hosts.
|
||||
const TEST_URI_1 = NetUtil.newURI("https://www.google.it/");
|
||||
const TEST_URI_2 = NetUtil.newURI("https://google.it/");
|
||||
let places = [{ uri: TEST_URI_1
|
||||
, transition: TRANSITION_TYPED
|
||||
},
|
||||
{ uri: TEST_URI_2
|
||||
}];
|
||||
yield PlacesTestUtils.addVisits(places);
|
||||
|
||||
do_check_true(isHostInMozHosts(TEST_URI_1, true, "https://www."));
|
||||
});
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
function* importFromFixture(fixture, replace) {
|
||||
let cwd = yield OS.File.getCurrentDirectory();
|
||||
let path = OS.Path.join(cwd, fixture);
|
||||
|
||||
do_print(`Importing from ${path}`);
|
||||
yield BookmarkJSONUtils.importFromFile(path, replace);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
}
|
||||
|
||||
function* treeEquals(guid, expected, message) {
|
||||
let root = yield PlacesUtils.promiseBookmarksTree(guid);
|
||||
let bookmarks = (function nodeToEntry(node) {
|
||||
let entry = { guid: node.guid, index: node.index }
|
||||
if (node.children) {
|
||||
entry.children = node.children.map(nodeToEntry);
|
||||
}
|
||||
if (node.annos) {
|
||||
entry.annos = node.annos;
|
||||
}
|
||||
return entry;
|
||||
}(root));
|
||||
|
||||
do_print(`Checking if ${guid} tree matches ${JSON.stringify(expected)}`);
|
||||
do_print(`Got bookmarks tree for ${guid}: ${JSON.stringify(bookmarks)}`);
|
||||
|
||||
deepEqual(bookmarks, expected, message);
|
||||
}
|
||||
|
||||
add_task(function* test_restore_mobile_bookmarks_root() {
|
||||
yield* importFromFixture("mobile_bookmarks_root_import.json",
|
||||
/* replace */ true);
|
||||
|
||||
yield* treeEquals(PlacesUtils.bookmarks.rootGuid, {
|
||||
guid: PlacesUtils.bookmarks.rootGuid,
|
||||
index: 0,
|
||||
children: [{
|
||||
guid: PlacesUtils.bookmarks.menuGuid,
|
||||
index: 0,
|
||||
children: [
|
||||
{ guid: "X6lUyOspVYwi", index: 0 },
|
||||
],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
index: 1,
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 3,
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.mobileGuid,
|
||||
index: 4,
|
||||
annos: [{
|
||||
name: "mobile/bookmarksRoot",
|
||||
flags: 0,
|
||||
expires: 4,
|
||||
value: 1,
|
||||
}],
|
||||
children: [
|
||||
{ guid: "_o8e1_zxTJFg", index: 0 },
|
||||
{ guid: "QCtSqkVYUbXB", index: 1 },
|
||||
],
|
||||
}],
|
||||
}, "Should restore mobile bookmarks from root");
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_import_mobile_bookmarks_root() {
|
||||
yield* importFromFixture("mobile_bookmarks_root_import.json",
|
||||
/* replace */ false);
|
||||
yield* importFromFixture("mobile_bookmarks_root_merge.json",
|
||||
/* replace */ false);
|
||||
|
||||
yield* treeEquals(PlacesUtils.bookmarks.rootGuid, {
|
||||
guid: PlacesUtils.bookmarks.rootGuid,
|
||||
index: 0,
|
||||
children: [{
|
||||
guid: PlacesUtils.bookmarks.menuGuid,
|
||||
index: 0,
|
||||
children: [
|
||||
{ guid: "Utodo9b0oVws", index: 0 },
|
||||
{ guid: "X6lUyOspVYwi", index: 1 },
|
||||
],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
index: 1,
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 3,
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.mobileGuid,
|
||||
index: 4,
|
||||
annos: [{
|
||||
name: "mobile/bookmarksRoot",
|
||||
flags: 0,
|
||||
expires: 4,
|
||||
value: 1,
|
||||
}],
|
||||
children: [
|
||||
{ guid: "a17yW6-nTxEJ", index: 0 },
|
||||
{ guid: "xV10h9Wi3FBM", index: 1 },
|
||||
{ guid: "_o8e1_zxTJFg", index: 2 },
|
||||
{ guid: "QCtSqkVYUbXB", index: 3 },
|
||||
],
|
||||
}],
|
||||
}, "Should merge bookmarks root contents");
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_restore_mobile_bookmarks_folder() {
|
||||
yield* importFromFixture("mobile_bookmarks_folder_import.json",
|
||||
/* replace */ true);
|
||||
|
||||
yield* treeEquals(PlacesUtils.bookmarks.rootGuid, {
|
||||
guid: PlacesUtils.bookmarks.rootGuid,
|
||||
index: 0,
|
||||
children: [{
|
||||
guid: PlacesUtils.bookmarks.menuGuid,
|
||||
index: 0,
|
||||
children: [
|
||||
{ guid: "X6lUyOspVYwi", index: 0 },
|
||||
{ guid: "XF4yRP6bTuil", index: 1 },
|
||||
],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
index: 1,
|
||||
children: [{ guid: "buy7711R3ZgE", index: 0 }],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 3,
|
||||
children: [{ guid: "KIa9iKZab2Z5", index: 0 }],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.mobileGuid,
|
||||
index: 4,
|
||||
annos: [{
|
||||
name: "mobile/bookmarksRoot",
|
||||
flags: 0,
|
||||
expires: 4,
|
||||
value: 1,
|
||||
}],
|
||||
children: [
|
||||
{ guid: "_o8e1_zxTJFg", index: 0 },
|
||||
{ guid: "QCtSqkVYUbXB", index: 1 },
|
||||
],
|
||||
}],
|
||||
}, "Should restore mobile bookmark folder contents into mobile root");
|
||||
|
||||
// We rewrite queries to point to the root ID instead of the name
|
||||
// ("MOBILE_BOOKMARKS") so that we don't break them if the user downgrades
|
||||
// to an earlier release channel. This can be removed along with the anno in
|
||||
// bug 1306445.
|
||||
let queryById = yield PlacesUtils.bookmarks.fetch("XF4yRP6bTuil");
|
||||
equal(queryById.url.href, "place:folder=" + PlacesUtils.mobileFolderId,
|
||||
"Should rewrite mobile query to point to root ID");
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_import_mobile_bookmarks_folder() {
|
||||
yield* importFromFixture("mobile_bookmarks_folder_import.json",
|
||||
/* replace */ false);
|
||||
yield* importFromFixture("mobile_bookmarks_folder_merge.json",
|
||||
/* replace */ false);
|
||||
|
||||
yield* treeEquals(PlacesUtils.bookmarks.rootGuid, {
|
||||
guid: PlacesUtils.bookmarks.rootGuid,
|
||||
index: 0,
|
||||
children: [{
|
||||
guid: PlacesUtils.bookmarks.menuGuid,
|
||||
index: 0,
|
||||
children: [
|
||||
{ guid: "Utodo9b0oVws", index: 0 },
|
||||
{ guid: "X6lUyOspVYwi", index: 1 },
|
||||
{ guid: "XF4yRP6bTuil", index: 2 },
|
||||
],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
index: 1,
|
||||
children: [{ guid: "buy7711R3ZgE", index: 0 }],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 3,
|
||||
children: [{ guid: "KIa9iKZab2Z5", index: 0 }],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.mobileGuid,
|
||||
index: 4,
|
||||
annos: [{
|
||||
name: "mobile/bookmarksRoot",
|
||||
flags: 0,
|
||||
expires: 4,
|
||||
value: 1,
|
||||
}],
|
||||
children: [
|
||||
{ guid: "a17yW6-nTxEJ", index: 0 },
|
||||
{ guid: "xV10h9Wi3FBM", index: 1 },
|
||||
{ guid: "_o8e1_zxTJFg", index: 2 },
|
||||
{ guid: "QCtSqkVYUbXB", index: 3 },
|
||||
],
|
||||
}],
|
||||
}, "Should merge bookmarks folder contents into mobile root");
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_restore_multiple_bookmarks_folders() {
|
||||
yield* importFromFixture("mobile_bookmarks_multiple_folders.json",
|
||||
/* replace */ true);
|
||||
|
||||
yield* treeEquals(PlacesUtils.bookmarks.rootGuid, {
|
||||
guid: PlacesUtils.bookmarks.rootGuid,
|
||||
index: 0,
|
||||
children: [{
|
||||
guid: PlacesUtils.bookmarks.menuGuid,
|
||||
index: 0,
|
||||
children: [
|
||||
{ guid: "buy7711R3ZgE", index: 0 },
|
||||
{ guid: "F_LBgd1fS_uQ", index: 1 },
|
||||
{ guid: "oIpmQXMWsXvY", index: 2 },
|
||||
],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
index: 1,
|
||||
children: [{ guid: "Utodo9b0oVws", index: 0 }],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 3,
|
||||
children: [{ guid: "xV10h9Wi3FBM", index: 0 }],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.mobileGuid,
|
||||
index: 4,
|
||||
annos: [{
|
||||
name: "mobile/bookmarksRoot",
|
||||
flags: 0,
|
||||
expires: 4,
|
||||
value: 1,
|
||||
}],
|
||||
children: [
|
||||
{ guid: "sSZ86WT9WbN3", index: 0 },
|
||||
{ guid: "a17yW6-nTxEJ", index: 1 },
|
||||
],
|
||||
}],
|
||||
}, "Should restore multiple bookmarks folder contents into root");
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* test_import_multiple_bookmarks_folders() {
|
||||
yield* importFromFixture("mobile_bookmarks_root_import.json",
|
||||
/* replace */ false);
|
||||
yield* importFromFixture("mobile_bookmarks_multiple_folders.json",
|
||||
/* replace */ false);
|
||||
|
||||
yield* treeEquals(PlacesUtils.bookmarks.rootGuid, {
|
||||
guid: PlacesUtils.bookmarks.rootGuid,
|
||||
index: 0,
|
||||
children: [{
|
||||
guid: PlacesUtils.bookmarks.menuGuid,
|
||||
index: 0,
|
||||
children: [
|
||||
{ guid: "buy7711R3ZgE", index: 0 },
|
||||
{ guid: "F_LBgd1fS_uQ", index: 1 },
|
||||
{ guid: "oIpmQXMWsXvY", index: 2 },
|
||||
{ guid: "X6lUyOspVYwi", index: 3 },
|
||||
],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
index: 1,
|
||||
children: [{ guid: "Utodo9b0oVws", index: 0 }],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 3,
|
||||
children: [{ guid: "xV10h9Wi3FBM", index: 0 }],
|
||||
}, {
|
||||
guid: PlacesUtils.bookmarks.mobileGuid,
|
||||
index: 4,
|
||||
annos: [{
|
||||
name: "mobile/bookmarksRoot",
|
||||
flags: 0,
|
||||
expires: 4,
|
||||
value: 1,
|
||||
}],
|
||||
children: [
|
||||
{ guid: "sSZ86WT9WbN3", index: 0 },
|
||||
{ guid: "a17yW6-nTxEJ", index: 1 },
|
||||
{ guid: "_o8e1_zxTJFg", index: 2 },
|
||||
{ guid: "QCtSqkVYUbXB", index: 3 },
|
||||
],
|
||||
}],
|
||||
}, "Should merge multiple mobile folders into root");
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
10
toolkit/components/places/tests/unit/test_isPageInDB.js
Normal file
10
toolkit/components/places/tests/unit/test_isPageInDB.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
|
||||
add_task(function* test_execute() {
|
||||
var good_uri = uri("http://mozilla.com");
|
||||
var bad_uri = uri("http://google.com");
|
||||
yield PlacesTestUtils.addVisits({uri: good_uri});
|
||||
do_check_true(yield PlacesTestUtils.isPageInDB(good_uri));
|
||||
do_check_false(yield PlacesTestUtils.isPageInDB(bad_uri));
|
||||
});
|
||||
84
toolkit/components/places/tests/unit/test_isURIVisited.js
Normal file
84
toolkit/components/places/tests/unit/test_isURIVisited.js
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests functionality of the isURIVisited API.
|
||||
|
||||
const SCHEMES = {
|
||||
"http://": true,
|
||||
"https://": true,
|
||||
"ftp://": true,
|
||||
"file:///": true,
|
||||
"about:": false,
|
||||
// nsIIOService.newURI() can throw if e.g. the app knows about imap://
|
||||
// but the account is not set up and so the URL is invalid for it.
|
||||
// "imap://": false,
|
||||
"news://": false,
|
||||
"mailbox:": false,
|
||||
"moz-anno:favicon:http://": false,
|
||||
"view-source:http://": false,
|
||||
"chrome://browser/content/browser.xul?": false,
|
||||
"resource://": false,
|
||||
"data:,": false,
|
||||
"wyciwyg:/0/http://": false,
|
||||
"javascript:": false,
|
||||
};
|
||||
|
||||
var gRunner;
|
||||
function run_test()
|
||||
{
|
||||
do_test_pending();
|
||||
gRunner = step();
|
||||
gRunner.next();
|
||||
}
|
||||
|
||||
function* step()
|
||||
{
|
||||
let history = Cc["@mozilla.org/browser/history;1"]
|
||||
.getService(Ci.mozIAsyncHistory);
|
||||
|
||||
for (let scheme in SCHEMES) {
|
||||
do_print("Testing scheme " + scheme);
|
||||
for (let t in PlacesUtils.history.TRANSITIONS) {
|
||||
do_print("With transition " + t);
|
||||
let transition = PlacesUtils.history.TRANSITIONS[t];
|
||||
|
||||
let uri = NetUtil.newURI(scheme + "mozilla.org/");
|
||||
|
||||
history.isURIVisited(uri, function(aURI, aIsVisited) {
|
||||
do_check_true(uri.equals(aURI));
|
||||
do_check_false(aIsVisited);
|
||||
|
||||
let callback = {
|
||||
handleError: function () {},
|
||||
handleResult: function () {},
|
||||
handleCompletion: function () {
|
||||
do_print("Added visit to " + uri.spec);
|
||||
|
||||
history.isURIVisited(uri, function (aURI2, aIsVisited2) {
|
||||
do_check_true(uri.equals(aURI2));
|
||||
let checker = SCHEMES[scheme] ? do_check_true : do_check_false;
|
||||
checker(aIsVisited2);
|
||||
|
||||
PlacesTestUtils.clearHistory().then(function () {
|
||||
history.isURIVisited(uri, function(aURI3, aIsVisited3) {
|
||||
do_check_true(uri.equals(aURI3));
|
||||
do_check_false(aIsVisited3);
|
||||
gRunner.next();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
history.updatePlaces({ uri: uri
|
||||
, visits: [ { transitionType: transition
|
||||
, visitDate: Date.now() * 1000
|
||||
} ]
|
||||
}, callback);
|
||||
});
|
||||
yield undefined;
|
||||
}
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
}
|
||||
75
toolkit/components/places/tests/unit/test_isvisited.js
Normal file
75
toolkit/components/places/tests/unit/test_isvisited.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
var referrer = uri("about:blank");
|
||||
|
||||
// add a http:// uri
|
||||
var uri1 = uri("http://mozilla.com");
|
||||
yield PlacesTestUtils.addVisits({uri: uri1, referrer: referrer});
|
||||
do_check_guid_for_uri(uri1);
|
||||
do_check_true(yield promiseIsURIVisited(uri1));
|
||||
|
||||
// add a https:// uri
|
||||
var uri2 = uri("https://etrade.com");
|
||||
yield PlacesTestUtils.addVisits({uri: uri2, referrer: referrer});
|
||||
do_check_guid_for_uri(uri2);
|
||||
do_check_true(yield promiseIsURIVisited(uri2));
|
||||
|
||||
// add a ftp:// uri
|
||||
var uri3 = uri("ftp://ftp.mozilla.org");
|
||||
yield PlacesTestUtils.addVisits({uri: uri3, referrer: referrer});
|
||||
do_check_guid_for_uri(uri3);
|
||||
do_check_true(yield promiseIsURIVisited(uri3));
|
||||
|
||||
// check if a nonexistent uri is visited
|
||||
var uri4 = uri("http://foobarcheese.com");
|
||||
do_check_false(yield promiseIsURIVisited(uri4));
|
||||
|
||||
// check that certain schemes never show up as visited
|
||||
// even if we attempt to add them to history
|
||||
// see CanAddURI() in nsNavHistory.cpp
|
||||
const URLS = [
|
||||
"about:config",
|
||||
"imap://cyrus.andrew.cmu.edu/archive.imap",
|
||||
"news://new.mozilla.org/mozilla.dev.apps.firefox",
|
||||
"mailbox:Inbox",
|
||||
"moz-anno:favicon:http://mozilla.org/made-up-favicon",
|
||||
"view-source:http://mozilla.org",
|
||||
"chrome://browser/content/browser.xul",
|
||||
"resource://gre-resources/hiddenWindow.html",
|
||||
"data:,Hello%2C%20World!",
|
||||
"wyciwyg:/0/http://mozilla.org",
|
||||
"javascript:alert('hello wolrd!');",
|
||||
"http://localhost/" + "a".repeat(1984),
|
||||
];
|
||||
for (let currentURL of URLS) {
|
||||
try {
|
||||
var cantAddUri = uri(currentURL);
|
||||
}
|
||||
catch (e) {
|
||||
// nsIIOService.newURI() can throw if e.g. our app knows about imap://
|
||||
// but the account is not set up and so the URL is invalid for us.
|
||||
// Note this in the log but ignore as it's not the subject of this test.
|
||||
do_print("Could not construct URI for '" + currentURL + "'; ignoring");
|
||||
}
|
||||
if (cantAddUri) {
|
||||
PlacesTestUtils.addVisits({uri: cantAddUri, referrer: referrer}).then(() => {
|
||||
do_throw("Should not have added history for invalid URI.");
|
||||
}, error => {
|
||||
do_check_true(error.message.includes("No items were added to history"));
|
||||
});
|
||||
do_check_false(yield promiseIsURIVisited(cantAddUri));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
548
toolkit/components/places/tests/unit/test_keywords.js
Normal file
548
toolkit/components/places/tests/unit/test_keywords.js
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
"use strict"
|
||||
|
||||
function* check_keyword(aExpectExists, aHref, aKeyword, aPostData = null) {
|
||||
// Check case-insensitivity.
|
||||
aKeyword = aKeyword.toUpperCase();
|
||||
|
||||
let entry = yield PlacesUtils.keywords.fetch(aKeyword);
|
||||
|
||||
Assert.deepEqual(entry, yield PlacesUtils.keywords.fetch({ keyword: aKeyword }));
|
||||
|
||||
if (aExpectExists) {
|
||||
Assert.ok(!!entry, "A keyword should exist");
|
||||
Assert.equal(entry.url.href, aHref);
|
||||
Assert.equal(entry.postData, aPostData);
|
||||
Assert.deepEqual(entry, yield PlacesUtils.keywords.fetch({ keyword: aKeyword, url: aHref }));
|
||||
let entries = [];
|
||||
yield PlacesUtils.keywords.fetch({ url: aHref }, e => entries.push(e));
|
||||
Assert.ok(entries.some(e => e.url.href == aHref && e.keyword == aKeyword.toLowerCase()));
|
||||
} else {
|
||||
Assert.ok(!entry || entry.url.href != aHref,
|
||||
"The given keyword entry should not exist");
|
||||
Assert.equal(null, yield PlacesUtils.keywords.fetch({ keyword: aKeyword, url: aHref }));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls the keywords cache waiting for the given keyword entry.
|
||||
*/
|
||||
function* promiseKeyword(keyword, expectedHref) {
|
||||
let href = null;
|
||||
do {
|
||||
yield new Promise(resolve => do_timeout(100, resolve));
|
||||
let entry = yield PlacesUtils.keywords.fetch(keyword);
|
||||
if (entry)
|
||||
href = entry.url.href;
|
||||
} while (href != expectedHref);
|
||||
}
|
||||
|
||||
function* check_no_orphans() {
|
||||
let db = yield PlacesUtils.promiseDBConnection();
|
||||
let rows = yield db.executeCached(
|
||||
`SELECT id FROM moz_keywords k
|
||||
WHERE NOT EXISTS (SELECT 1 FROM moz_places WHERE id = k.place_id)
|
||||
`);
|
||||
Assert.equal(rows.length, 0);
|
||||
}
|
||||
|
||||
function expectBookmarkNotifications() {
|
||||
let notifications = [];
|
||||
let observer = new Proxy(NavBookmarkObserver, {
|
||||
get(target, name) {
|
||||
if (name == "check") {
|
||||
PlacesUtils.bookmarks.removeObserver(observer);
|
||||
return expectedNotifications =>
|
||||
Assert.deepEqual(notifications, expectedNotifications);
|
||||
}
|
||||
|
||||
if (name.startsWith("onItemChanged")) {
|
||||
return function(itemId, property) {
|
||||
if (property != "keyword")
|
||||
return;
|
||||
let args = Array.from(arguments, arg => {
|
||||
if (arg && arg instanceof Ci.nsIURI)
|
||||
return new URL(arg.spec);
|
||||
if (arg && typeof(arg) == "number" && arg >= Date.now() * 1000)
|
||||
return new Date(parseInt(arg/1000));
|
||||
return arg;
|
||||
});
|
||||
notifications.push({ name: name, arguments: args });
|
||||
}
|
||||
}
|
||||
|
||||
if (name in target)
|
||||
return target[name];
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
PlacesUtils.bookmarks.addObserver(observer, false);
|
||||
return observer;
|
||||
}
|
||||
|
||||
add_task(function* test_invalid_input() {
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch(null),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch(5),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch(undefined),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({ keyword: null }),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({ keyword: {} }),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({ keyword: 5 }),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({}),
|
||||
/At least keyword or url must be provided/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({ keyword: "test" }, "test"),
|
||||
/onResult callback must be a valid function/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({ url: "test" }),
|
||||
/is not a valid URL/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({ url: {} }),
|
||||
/is not a valid URL/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({ url: null }),
|
||||
/is not a valid URL/);
|
||||
Assert.throws(() => PlacesUtils.keywords.fetch({ url: "" }),
|
||||
/is not a valid URL/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.keywords.insert(null),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert("test"),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert(undefined),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ }),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: null }),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: 5 }),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "" }),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", postData: 5 }),
|
||||
/Invalid POST data/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", postData: {} }),
|
||||
/Invalid POST data/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test" }),
|
||||
/is not a valid URL/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", url: 5 }),
|
||||
/is not a valid URL/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", url: "" }),
|
||||
/is not a valid URL/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", url: null }),
|
||||
/is not a valid URL/);
|
||||
Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", url: "mozilla" }),
|
||||
/is not a valid URL/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.keywords.remove(null),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.remove(""),
|
||||
/Invalid keyword/);
|
||||
Assert.throws(() => PlacesUtils.keywords.remove(5),
|
||||
/Invalid keyword/);
|
||||
});
|
||||
|
||||
add_task(function* test_addKeyword() {
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
let fc = yield foreign_count("http://example.com/");
|
||||
let observer = expectBookmarkNotifications();
|
||||
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" });
|
||||
observer.check([]);
|
||||
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 1); // +1 keyword
|
||||
|
||||
// Now remove the keyword.
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
observer.check([]);
|
||||
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc); // -1 keyword
|
||||
|
||||
// Check using URL.
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: new URL("http://example.com/") });
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
|
||||
yield check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_addBookmarkAndKeyword() {
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
let fc = yield foreign_count("http://example.com/");
|
||||
let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
|
||||
let observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" });
|
||||
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)),
|
||||
"keyword", false, "keyword",
|
||||
bookmark.lastModified, bookmark.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark.parentGuid)),
|
||||
bookmark.guid, bookmark.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // +1 bookmark +1 keyword
|
||||
|
||||
// Now remove the keyword.
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)),
|
||||
"keyword", false, "",
|
||||
bookmark.lastModified, bookmark.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark.parentGuid)),
|
||||
bookmark.guid, bookmark.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 1); // -1 keyword
|
||||
|
||||
// Add again the keyword, then remove the bookmark.
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" });
|
||||
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.bookmarks.remove(bookmark.guid);
|
||||
// the notification is synchronous but the removal process is async.
|
||||
// Unfortunately there's nothing explicit we can wait for.
|
||||
while ((yield foreign_count("http://example.com/")));
|
||||
// We don't get any itemChanged notification since the bookmark has been
|
||||
// removed already.
|
||||
observer.check([]);
|
||||
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
|
||||
yield check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_addKeywordToURIHavingKeyword() {
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
let fc = yield foreign_count("http://example.com/");
|
||||
|
||||
let observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" });
|
||||
observer.check([]);
|
||||
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 1); // +1 keyword
|
||||
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword2", url: "http://example.com/" });
|
||||
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
yield check_keyword(true, "http://example.com/", "keyword2");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // +1 keyword
|
||||
let entries = [];
|
||||
let entry = yield PlacesUtils.keywords.fetch({ url: "http://example.com/" }, e => entries.push(e));
|
||||
Assert.equal(entries.length, 2);
|
||||
Assert.deepEqual(entries[0], entry);
|
||||
|
||||
// Now remove the keywords.
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
yield PlacesUtils.keywords.remove("keyword2");
|
||||
observer.check([]);
|
||||
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
yield check_keyword(false, "http://example.com/", "keyword2");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc); // -1 keyword
|
||||
|
||||
yield check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_addBookmarkToURIHavingKeyword() {
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
let fc = yield foreign_count("http://example.com/");
|
||||
let observer = expectBookmarkNotifications();
|
||||
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" });
|
||||
observer.check([]);
|
||||
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 1); // +1 keyword
|
||||
|
||||
observer = expectBookmarkNotifications();
|
||||
let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // +1 bookmark
|
||||
observer.check([]);
|
||||
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.bookmarks.remove(bookmark.guid);
|
||||
// the notification is synchronous but the removal process is async.
|
||||
// Unfortunately there's nothing explicit we can wait for.
|
||||
while ((yield foreign_count("http://example.com/")));
|
||||
// We don't get any itemChanged notification since the bookmark has been
|
||||
// removed already.
|
||||
observer.check([]);
|
||||
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
|
||||
yield check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_sameKeywordDifferentURL() {
|
||||
let fc1 = yield foreign_count("http://example1.com/");
|
||||
let bookmark1 = yield PlacesUtils.bookmarks.insert({ url: "http://example1.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let fc2 = yield foreign_count("http://example2.com/");
|
||||
let bookmark2 = yield PlacesUtils.bookmarks.insert({ url: "http://example2.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example1.com/" });
|
||||
|
||||
yield check_keyword(true, "http://example1.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example1.com/")), fc1 + 2); // +1 bookmark +1 keyword
|
||||
yield check_keyword(false, "http://example2.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example2.com/")), fc2 + 1); // +1 bookmark
|
||||
|
||||
// Assign the same keyword to another url.
|
||||
let observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example2.com/" });
|
||||
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark1.guid)),
|
||||
"keyword", false, "",
|
||||
bookmark1.lastModified, bookmark1.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark1.parentGuid)),
|
||||
bookmark1.guid, bookmark1.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark2.guid)),
|
||||
"keyword", false, "keyword",
|
||||
bookmark2.lastModified, bookmark2.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark2.parentGuid)),
|
||||
bookmark2.guid, bookmark2.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
|
||||
yield check_keyword(false, "http://example1.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example1.com/")), fc1 + 1); // -1 keyword
|
||||
yield check_keyword(true, "http://example2.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example2.com/")), fc2 + 2); // +1 keyword
|
||||
|
||||
// Now remove the keyword.
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark2.guid)),
|
||||
"keyword", false, "",
|
||||
bookmark2.lastModified, bookmark2.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark2.parentGuid)),
|
||||
bookmark2.guid, bookmark2.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
|
||||
yield check_keyword(false, "http://example1.com/", "keyword");
|
||||
yield check_keyword(false, "http://example2.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example1.com/")), fc1 + 1);
|
||||
Assert.equal((yield foreign_count("http://example2.com/")), fc2 + 1); // -1 keyword
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(bookmark1);
|
||||
yield PlacesUtils.bookmarks.remove(bookmark2);
|
||||
Assert.equal((yield foreign_count("http://example1.com/")), fc1); // -1 bookmark
|
||||
while ((yield foreign_count("http://example2.com/"))); // -1 keyword
|
||||
|
||||
yield check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_sameURIDifferentKeyword() {
|
||||
let fc = yield foreign_count("http://example.com/");
|
||||
|
||||
let observer = expectBookmarkNotifications();
|
||||
let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
yield PlacesUtils.keywords.insert({keyword: "keyword", url: "http://example.com/" });
|
||||
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // +1 bookmark +1 keyword
|
||||
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)),
|
||||
"keyword", false, "keyword",
|
||||
bookmark.lastModified, bookmark.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark.parentGuid)),
|
||||
bookmark.guid, bookmark.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword2", url: "http://example.com/" });
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
yield check_keyword(true, "http://example.com/", "keyword2");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 3); // +1 keyword
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)),
|
||||
"keyword", false, "keyword2",
|
||||
bookmark.lastModified, bookmark.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark.parentGuid)),
|
||||
bookmark.guid, bookmark.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
|
||||
// Add a third keyword.
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword3", url: "http://example.com/" });
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
yield check_keyword(true, "http://example.com/", "keyword2");
|
||||
yield check_keyword(true, "http://example.com/", "keyword3");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 4); // +1 keyword
|
||||
|
||||
// Remove one of the keywords.
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
yield check_keyword(true, "http://example.com/", "keyword2");
|
||||
yield check_keyword(true, "http://example.com/", "keyword3");
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)),
|
||||
"keyword", false, "",
|
||||
bookmark.lastModified, bookmark.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark.parentGuid)),
|
||||
bookmark.guid, bookmark.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 3); // -1 keyword
|
||||
|
||||
// Now remove the bookmark.
|
||||
yield PlacesUtils.bookmarks.remove(bookmark);
|
||||
while ((yield foreign_count("http://example.com/")));
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
yield check_keyword(false, "http://example.com/", "keyword2");
|
||||
yield check_keyword(false, "http://example.com/", "keyword3");
|
||||
|
||||
check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_deleteKeywordMultipleBookmarks() {
|
||||
let fc = yield foreign_count("http://example.com/");
|
||||
|
||||
let observer = expectBookmarkNotifications();
|
||||
let bookmark1 = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let bookmark2 = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" });
|
||||
|
||||
yield check_keyword(true, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 3); // +2 bookmark +1 keyword
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark2.guid)),
|
||||
"keyword", false, "keyword",
|
||||
bookmark2.lastModified, bookmark2.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark2.parentGuid)),
|
||||
bookmark2.guid, bookmark2.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark1.guid)),
|
||||
"keyword", false, "keyword",
|
||||
bookmark1.lastModified, bookmark1.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark1.parentGuid)),
|
||||
bookmark1.guid, bookmark1.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
|
||||
observer = expectBookmarkNotifications();
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // -1 keyword
|
||||
observer.check([{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark2.guid)),
|
||||
"keyword", false, "",
|
||||
bookmark2.lastModified, bookmark2.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark2.parentGuid)),
|
||||
bookmark2.guid, bookmark2.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark1.guid)),
|
||||
"keyword", false, "",
|
||||
bookmark1.lastModified, bookmark1.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark1.parentGuid)),
|
||||
bookmark1.guid, bookmark1.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]);
|
||||
|
||||
// Now remove the bookmarks.
|
||||
yield PlacesUtils.bookmarks.remove(bookmark1);
|
||||
yield PlacesUtils.bookmarks.remove(bookmark2);
|
||||
Assert.equal((yield foreign_count("http://example.com/")), fc); // -2 bookmarks
|
||||
|
||||
check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_multipleKeywordsSamePostData() {
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/", postData: "postData1" });
|
||||
yield check_keyword(true, "http://example.com/", "keyword", "postData1");
|
||||
// Add another keyword with same postData, should fail.
|
||||
yield Assert.rejects(PlacesUtils.keywords.insert({ keyword: "keyword2", url: "http://example.com/", postData: "postData1" }),
|
||||
/constraint failed/);
|
||||
yield check_keyword(false, "http://example.com/", "keyword2", "postData1");
|
||||
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
|
||||
check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_oldPostDataAPI() {
|
||||
let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bookmark.guid);
|
||||
yield PlacesUtils.setPostDataForBookmark(itemId, "postData");
|
||||
yield check_keyword(true, "http://example.com/", "keyword", "postData");
|
||||
Assert.equal(PlacesUtils.getPostDataForBookmark(itemId), "postData");
|
||||
|
||||
yield PlacesUtils.keywords.remove("keyword");
|
||||
yield PlacesUtils.bookmarks.remove(bookmark);
|
||||
|
||||
check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_oldKeywordsAPI() {
|
||||
let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
yield check_keyword(false, "http://example.com/", "keyword");
|
||||
let itemId = yield PlacesUtils.promiseItemId(bookmark.guid);
|
||||
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword");
|
||||
yield promiseKeyword("keyword", "http://example.com/");
|
||||
|
||||
// Remove the keyword.
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "");
|
||||
yield promiseKeyword("keyword", null);
|
||||
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com" });
|
||||
Assert.equal(PlacesUtils.bookmarks.getKeywordForBookmark(itemId), "keyword");
|
||||
Assert.equal(PlacesUtils.bookmarks.getURIForKeyword("keyword").spec, "http://example.com/");
|
||||
yield PlacesUtils.bookmarks.remove(bookmark);
|
||||
|
||||
check_no_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_bookmarkURLChange() {
|
||||
let fc1 = yield foreign_count("http://example1.com/");
|
||||
let fc2 = yield foreign_count("http://example2.com/");
|
||||
let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example1.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
yield PlacesUtils.keywords.insert({ keyword: "keyword",
|
||||
url: "http://example1.com/" });
|
||||
|
||||
yield check_keyword(true, "http://example1.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example1.com/")), fc1 + 2); // +1 bookmark +1 keyword
|
||||
|
||||
yield PlacesUtils.bookmarks.update({ guid: bookmark.guid,
|
||||
url: "http://example2.com/"});
|
||||
yield promiseKeyword("keyword", "http://example2.com/");
|
||||
|
||||
yield check_keyword(false, "http://example1.com/", "keyword");
|
||||
yield check_keyword(true, "http://example2.com/", "keyword");
|
||||
Assert.equal((yield foreign_count("http://example1.com/")), fc1); // -1 bookmark -1 keyword
|
||||
Assert.equal((yield foreign_count("http://example2.com/")), fc2 + 2); // +1 bookmark +1 keyword
|
||||
});
|
||||
34
toolkit/components/places/tests/unit/test_lastModified.js
Normal file
34
toolkit/components/places/tests/unit/test_lastModified.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Test that inserting a new bookmark will set lastModified to the same
|
||||
* values as dateAdded.
|
||||
*/
|
||||
// main
|
||||
function run_test() {
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var itemId = bs.insertBookmark(bs.bookmarksMenuFolder,
|
||||
uri("http://www.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"itemTitle");
|
||||
var dateAdded = bs.getItemDateAdded(itemId);
|
||||
do_check_eq(dateAdded, bs.getItemLastModified(itemId));
|
||||
|
||||
// Change lastModified, then change dateAdded. LastModified should be set
|
||||
// to the new dateAdded.
|
||||
// This could randomly fail on virtual machines due to timing issues, so
|
||||
// we manually increase the time value. See bug 500640 for details.
|
||||
bs.setItemLastModified(itemId, dateAdded + 1000);
|
||||
do_check_true(bs.getItemLastModified(itemId) === dateAdded + 1000);
|
||||
do_check_true(bs.getItemDateAdded(itemId) < bs.getItemLastModified(itemId));
|
||||
bs.setItemDateAdded(itemId, dateAdded + 2000);
|
||||
do_check_true(bs.getItemDateAdded(itemId) === dateAdded + 2000);
|
||||
do_check_eq(bs.getItemDateAdded(itemId), bs.getItemLastModified(itemId));
|
||||
|
||||
bs.removeItem(itemId);
|
||||
}
|
||||
61
toolkit/components/places/tests/unit/test_markpageas.js
Normal file
61
toolkit/components/places/tests/unit/test_markpageas.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var gVisits = [{url: "http://www.mozilla.com/",
|
||||
transition: TRANSITION_TYPED},
|
||||
{url: "http://www.google.com/",
|
||||
transition: TRANSITION_BOOKMARK},
|
||||
{url: "http://www.espn.com/",
|
||||
transition: TRANSITION_LINK}];
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
let observer;
|
||||
let completionPromise = new Promise(resolveCompletionPromise => {
|
||||
observer = {
|
||||
__proto__: NavHistoryObserver.prototype,
|
||||
_visitCount: 0,
|
||||
onVisit: function (aURI, aVisitID, aTime, aSessionID, aReferringID,
|
||||
aTransitionType, aAdded)
|
||||
{
|
||||
do_check_eq(aURI.spec, gVisits[this._visitCount].url);
|
||||
do_check_eq(aTransitionType, gVisits[this._visitCount].transition);
|
||||
this._visitCount++;
|
||||
|
||||
if (this._visitCount == gVisits.length) {
|
||||
resolveCompletionPromise();
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
PlacesUtils.history.addObserver(observer, false);
|
||||
|
||||
for (var visit of gVisits) {
|
||||
if (visit.transition == TRANSITION_TYPED)
|
||||
PlacesUtils.history.markPageAsTyped(uri(visit.url));
|
||||
else if (visit.transition == TRANSITION_BOOKMARK)
|
||||
PlacesUtils.history.markPageAsFollowedBookmark(uri(visit.url))
|
||||
else {
|
||||
// because it is a top level visit with no referrer,
|
||||
// it will result in TRANSITION_LINK
|
||||
}
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: uri(visit.url),
|
||||
transition: visit.transition
|
||||
});
|
||||
}
|
||||
|
||||
yield completionPromise;
|
||||
|
||||
PlacesUtils.history.removeObserver(observer);
|
||||
});
|
||||
|
||||
514
toolkit/components/places/tests/unit/test_mozIAsyncLivemarks.js
Normal file
514
toolkit/components/places/tests/unit/test_mozIAsyncLivemarks.js
Normal file
|
|
@ -0,0 +1,514 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests functionality of the mozIAsyncLivemarks interface.
|
||||
|
||||
const FEED_URI = NetUtil.newURI("http://feed.rss/");
|
||||
const SITE_URI = NetUtil.newURI("http://site.org/");
|
||||
|
||||
// This test must be the first one, since it's testing the cache.
|
||||
add_task(function* test_livemark_cache() {
|
||||
// Add a livemark through other APIs.
|
||||
let folder = yield PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "test",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
});
|
||||
let id = yield PlacesUtils.promiseItemId(folder.guid);
|
||||
PlacesUtils.annotations
|
||||
.setItemAnnotation(id, PlacesUtils.LMANNO_FEEDURI,
|
||||
"http://example.com/feed",
|
||||
0, PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
PlacesUtils.annotations
|
||||
.setItemAnnotation(id, PlacesUtils.LMANNO_SITEURI,
|
||||
"http://example.com/site",
|
||||
0, PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
|
||||
let livemark = yield PlacesUtils.livemarks.getLivemark({ guid: folder.guid });
|
||||
Assert.equal(folder.guid, livemark.guid);
|
||||
Assert.equal(folder.dateAdded * 1000, livemark.dateAdded);
|
||||
Assert.equal(folder.parentGuid, livemark.parentGuid);
|
||||
Assert.equal(folder.index, livemark.index);
|
||||
Assert.equal(folder.title, livemark.title);
|
||||
Assert.equal(id, livemark.id);
|
||||
Assert.equal(PlacesUtils.unfiledBookmarksFolderId, livemark.parentId);
|
||||
Assert.equal("http://example.com/feed", livemark.feedURI.spec);
|
||||
Assert.equal("http://example.com/site", livemark.siteURI.spec);
|
||||
|
||||
yield PlacesUtils.livemarks.removeLivemark(livemark);
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_noArguments_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark();
|
||||
do_throw("Invoking addLivemark with no arguments should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_emptyObject_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark({});
|
||||
do_throw("Invoking addLivemark with empty object should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_badParentId_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark({ parentId: "test" });
|
||||
do_throw("Invoking addLivemark with a bad parent id should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_invalidParentId_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark({ parentId: -2 });
|
||||
do_throw("Invoking addLivemark with an invalid parent id should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_noIndex_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark({
|
||||
parentId: PlacesUtils.unfiledBookmarksFolderId });
|
||||
do_throw("Invoking addLivemark with no index should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_badIndex_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ parentId: PlacesUtils.unfiledBookmarksFolderId
|
||||
, index: "test" });
|
||||
do_throw("Invoking addLivemark with a bad index should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_invalidIndex_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ parentId: PlacesUtils.unfiledBookmarksFolderId
|
||||
, index: -2
|
||||
});
|
||||
do_throw("Invoking addLivemark with an invalid index should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_noFeedURI_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
do_throw("Invoking addLivemark with no feedURI should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_badFeedURI_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: "test" });
|
||||
do_throw("Invoking addLivemark with a bad feedURI should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_badSiteURI_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
, siteURI: "test" });
|
||||
do_throw("Invoking addLivemark with a bad siteURI should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_badGuid_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ parentGuid: PlacesUtils.bookmarks.unfileGuid
|
||||
, feedURI: FEED_URI
|
||||
, guid: "123456" });
|
||||
do_throw("Invoking addLivemark with a bad guid should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_parentId_succeeds() {
|
||||
let onItemAddedCalled = false;
|
||||
PlacesUtils.bookmarks.addObserver({
|
||||
__proto__: NavBookmarkObserver.prototype,
|
||||
onItemAdded: function onItemAdded(aItemId, aParentId, aIndex, aItemType,
|
||||
aURI, aTitle)
|
||||
{
|
||||
onItemAddedCalled = true;
|
||||
PlacesUtils.bookmarks.removeObserver(this);
|
||||
do_check_eq(aParentId, PlacesUtils.unfiledBookmarksFolderId);
|
||||
do_check_eq(aIndex, 0);
|
||||
do_check_eq(aItemType, Ci.nsINavBookmarksService.TYPE_FOLDER);
|
||||
do_check_eq(aTitle, "test");
|
||||
}
|
||||
}, false);
|
||||
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentId: PlacesUtils.unfiledBookmarksFolderId
|
||||
, feedURI: FEED_URI });
|
||||
do_check_true(onItemAddedCalled);
|
||||
});
|
||||
|
||||
|
||||
add_task(function* test_addLivemark_noSiteURI_succeeds() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
do_check_true(livemark.id > 0);
|
||||
do_check_valid_places_guid(livemark.guid);
|
||||
do_check_eq(livemark.title, "test");
|
||||
do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
|
||||
do_check_eq(livemark.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
do_check_true(livemark.feedURI.equals(FEED_URI));
|
||||
do_check_eq(livemark.siteURI, null);
|
||||
do_check_true(livemark.lastModified > 0);
|
||||
do_check_true(is_time_ordered(livemark.dateAdded, livemark.lastModified));
|
||||
|
||||
let bookmark = yield PlacesUtils.bookmarks.fetch(livemark.guid);
|
||||
do_check_eq(livemark.index, bookmark.index);
|
||||
do_check_eq(livemark.dateAdded, bookmark.dateAdded * 1000);
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_succeeds() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
, siteURI: SITE_URI
|
||||
});
|
||||
|
||||
do_check_true(livemark.id > 0);
|
||||
do_check_valid_places_guid(livemark.guid);
|
||||
do_check_eq(livemark.title, "test");
|
||||
do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
|
||||
do_check_eq(livemark.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
do_check_true(livemark.feedURI.equals(FEED_URI));
|
||||
do_check_true(livemark.siteURI.equals(SITE_URI));
|
||||
do_check_true(PlacesUtils.annotations
|
||||
.itemHasAnnotation(livemark.id,
|
||||
PlacesUtils.LMANNO_FEEDURI));
|
||||
do_check_true(PlacesUtils.annotations
|
||||
.itemHasAnnotation(livemark.id,
|
||||
PlacesUtils.LMANNO_SITEURI));
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_bogusid_succeeds() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ id: 100 // Should be ignored.
|
||||
, title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
, siteURI: SITE_URI
|
||||
});
|
||||
do_check_true(livemark.id > 0);
|
||||
do_check_neq(livemark.id, 100);
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_bogusParentId_fails() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentId: 187
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
do_throw("Adding a livemark with a bogus parent should fail");
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_bogusParentGuid_fails() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: "123456789012"
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
do_throw("Adding a livemark with a bogus parent should fail");
|
||||
} catch (ex) {}
|
||||
})
|
||||
|
||||
add_task(function* test_addLivemark_intoLivemark_fails() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
|
||||
try {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: livemark.guid
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
do_throw("Adding a livemark into a livemark should fail");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_forceGuid_succeeds() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
, guid: "1234567890AB"
|
||||
});
|
||||
do_check_eq(livemark.guid, "1234567890AB");
|
||||
do_check_guid_for_bookmark(livemark.id, "1234567890AB");
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_dateAdded_succeeds() {
|
||||
let dateAdded = new Date("2013-03-01T01:10:00") * 1000;
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
, dateAdded
|
||||
});
|
||||
do_check_eq(livemark.dateAdded, dateAdded);
|
||||
});
|
||||
|
||||
add_task(function* test_addLivemark_lastModified_succeeds() {
|
||||
let now = Date.now() * 1000;
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
, lastModified: now
|
||||
});
|
||||
do_check_eq(livemark.dateAdded, now);
|
||||
do_check_eq(livemark.lastModified, now);
|
||||
});
|
||||
|
||||
add_task(function* test_removeLivemark_emptyObject_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.removeLivemark({});
|
||||
do_throw("Invoking removeLivemark with empty object should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_removeLivemark_noValidId_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.removeLivemark({ id: -10, guid: "test"});
|
||||
do_throw("Invoking removeLivemark with no valid id should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_removeLivemark_nonExistent_fails() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.removeLivemark({ id: 1337 });
|
||||
do_throw("Removing a non-existent livemark should fail");
|
||||
}
|
||||
catch (ex) {
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_removeLivemark_guid_succeeds() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
, guid: "234567890ABC"
|
||||
});
|
||||
|
||||
do_check_eq(livemark.guid, "234567890ABC");
|
||||
|
||||
yield PlacesUtils.livemarks.removeLivemark({
|
||||
id: 789, guid: "234567890ABC"
|
||||
});
|
||||
|
||||
do_check_eq((yield PlacesUtils.bookmarks.fetch("234567890ABC")), null);
|
||||
});
|
||||
|
||||
add_task(function* test_removeLivemark_id_succeeds() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
|
||||
yield PlacesUtils.livemarks.removeLivemark({ id: livemark.id });
|
||||
|
||||
do_check_eq((yield PlacesUtils.bookmarks.fetch("234567890ABC")), null);
|
||||
});
|
||||
|
||||
add_task(function* test_getLivemark_emptyObject_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.getLivemark({});
|
||||
do_throw("Invoking getLivemark with empty object should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_getLivemark_noValidId_throws() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.getLivemark({ id: -10, guid: "test"});
|
||||
do_throw("Invoking getLivemark with no valid id should throw");
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_getLivemark_nonExistentId_fails() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.getLivemark({ id: 1234 });
|
||||
do_throw("getLivemark for a non existent id should fail");
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
add_task(function* test_getLivemark_nonExistentGUID_fails() {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.getLivemark({ guid: "34567890ABCD" });
|
||||
do_throw("getLivemark for a non-existent guid should fail");
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
add_task(function* test_getLivemark_guid_succeeds() {
|
||||
yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
, guid: "34567890ABCD" });
|
||||
|
||||
// invalid id to check the guid wins.
|
||||
let livemark =
|
||||
yield PlacesUtils.livemarks.getLivemark({ id: 789, guid: "34567890ABCD" });
|
||||
|
||||
do_check_eq(livemark.title, "test");
|
||||
do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
|
||||
do_check_eq(livemark.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
do_check_true(livemark.feedURI.equals(FEED_URI));
|
||||
do_check_eq(livemark.siteURI, null);
|
||||
do_check_eq(livemark.guid, "34567890ABCD");
|
||||
|
||||
let bookmark = yield PlacesUtils.bookmarks.fetch("34567890ABCD");
|
||||
do_check_eq(livemark.index, bookmark.index);
|
||||
});
|
||||
|
||||
add_task(function* test_getLivemark_id_succeeds() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
|
||||
livemark = yield PlacesUtils.livemarks.getLivemark({ id: livemark.id });
|
||||
|
||||
do_check_eq(livemark.title, "test");
|
||||
do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
|
||||
do_check_eq(livemark.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
do_check_true(livemark.feedURI.equals(FEED_URI));
|
||||
do_check_eq(livemark.siteURI, null);
|
||||
do_check_guid_for_bookmark(livemark.id, livemark.guid);
|
||||
|
||||
let bookmark = yield PlacesUtils.bookmarks.fetch(livemark.guid);
|
||||
do_check_eq(livemark.index, bookmark.index);
|
||||
});
|
||||
|
||||
add_task(function* test_getLivemark_removeItem_contention() {
|
||||
// do not yield.
|
||||
PlacesUtils.livemarks.addLivemark({ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
}).catch(() => { /* swallow errors*/ });
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
|
||||
livemark = yield PlacesUtils.livemarks.getLivemark({ guid: livemark.guid });
|
||||
|
||||
do_check_eq(livemark.title, "test");
|
||||
do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
|
||||
do_check_true(livemark.feedURI.equals(FEED_URI));
|
||||
do_check_eq(livemark.siteURI, null);
|
||||
do_check_guid_for_bookmark(livemark.id, livemark.guid);
|
||||
});
|
||||
|
||||
add_task(function* test_title_change() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI
|
||||
});
|
||||
|
||||
yield PlacesUtils.bookmarks.update({ guid: livemark.guid,
|
||||
title: "test2" });
|
||||
// Poll for the title change.
|
||||
while (true) {
|
||||
let lm = yield PlacesUtils.livemarks.getLivemark({ guid: livemark.guid });
|
||||
if (lm.title == "test2")
|
||||
break;
|
||||
yield new Promise(resolve => do_timeout(resolve, 100));
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_livemark_move() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI } );
|
||||
|
||||
yield PlacesUtils.bookmarks.update({ guid: livemark.guid,
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
index: PlacesUtils.bookmarks.DEFAULT_INDEX });
|
||||
// Poll for the parent change.
|
||||
while (true) {
|
||||
let lm = yield PlacesUtils.livemarks.getLivemark({ guid: livemark.guid });
|
||||
if (lm.parentGuid == PlacesUtils.bookmarks.toolbarGuid)
|
||||
break;
|
||||
yield new Promise(resolve => do_timeout(resolve, 100));
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* test_livemark_removed() {
|
||||
let livemark = yield PlacesUtils.livemarks.addLivemark(
|
||||
{ title: "test"
|
||||
, parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
, feedURI: FEED_URI } );
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(livemark.guid);
|
||||
// Poll for the livemark removal.
|
||||
while (true) {
|
||||
try {
|
||||
yield PlacesUtils.livemarks.getLivemark({ guid: livemark.guid });
|
||||
} catch (ex) {
|
||||
break;
|
||||
}
|
||||
yield new Promise(resolve => do_timeout(resolve, 100));
|
||||
}
|
||||
});
|
||||
53
toolkit/components/places/tests/unit/test_multi_queries.js
Normal file
53
toolkit/components/places/tests/unit/test_multi_queries.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Adds a test URI visit to history.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add a visit for.
|
||||
* @param aReferrer
|
||||
* The referring URI for the given URI. This can be null.
|
||||
*/
|
||||
function* add_visit(aURI, aDayOffset, aTransition) {
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: aURI,
|
||||
transition: aTransition,
|
||||
visitDate: (Date.now() + aDayOffset*86400000) * 1000
|
||||
});
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_execute()
|
||||
{
|
||||
yield add_visit(uri("http://mirror1.mozilla.com/a"), -1, TRANSITION_LINK);
|
||||
yield add_visit(uri("http://mirror2.mozilla.com/b"), -2, TRANSITION_LINK);
|
||||
yield add_visit(uri("http://mirror3.mozilla.com/c"), -4, TRANSITION_FRAMED_LINK);
|
||||
yield add_visit(uri("http://mirror1.google.com/b"), -1, TRANSITION_EMBED);
|
||||
yield add_visit(uri("http://mirror2.google.com/a"), -2, TRANSITION_LINK);
|
||||
yield add_visit(uri("http://mirror1.apache.org/b"), -3, TRANSITION_LINK);
|
||||
yield add_visit(uri("http://mirror2.apache.org/a"), -4, TRANSITION_FRAMED_LINK);
|
||||
|
||||
let queries = [
|
||||
PlacesUtils.history.getNewQuery(),
|
||||
PlacesUtils.history.getNewQuery()
|
||||
];
|
||||
queries[0].domain = "mozilla.com";
|
||||
queries[1].domain = "google.com";
|
||||
|
||||
let root = PlacesUtils.history.executeQueries(
|
||||
queries, queries.length, PlacesUtils.history.getNewQueryOptions()
|
||||
).root;
|
||||
root.containerOpen = true;
|
||||
let childCount = root.childCount;
|
||||
root.containerOpen = false;
|
||||
|
||||
do_check_eq(childCount, 3);
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue