Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | 'use strict'; |
michael@0 | 5 | |
michael@0 | 6 | module.metadata = { |
michael@0 | 7 | 'engines': { |
michael@0 | 8 | 'Firefox': '*' |
michael@0 | 9 | } |
michael@0 | 10 | }; |
michael@0 | 11 | |
michael@0 | 12 | const { Cc, Ci } = require('chrome'); |
michael@0 | 13 | const { defer, all } = require('sdk/core/promise'); |
michael@0 | 14 | const { has } = require('sdk/util/array'); |
michael@0 | 15 | const { setTimeout } = require('sdk/timers'); |
michael@0 | 16 | const { before, after } = require('sdk/test/utils'); |
michael@0 | 17 | const { set } = require('sdk/preferences/service'); |
michael@0 | 18 | const { |
michael@0 | 19 | search |
michael@0 | 20 | } = require('sdk/places/history'); |
michael@0 | 21 | const { |
michael@0 | 22 | invalidResolve, invalidReject, createTree, |
michael@0 | 23 | compareWithHost, addVisits, resetPlaces |
michael@0 | 24 | } = require('../places-helper'); |
michael@0 | 25 | const { promisedEmitter } = require('sdk/places/utils'); |
michael@0 | 26 | |
michael@0 | 27 | exports.testEmptyQuery = function (assert, done) { |
michael@0 | 28 | let within = toBeWithin(); |
michael@0 | 29 | addVisits([ |
michael@0 | 30 | 'http://simplequery-1.com', 'http://simplequery-2.com' |
michael@0 | 31 | ]).then(searchP).then(results => { |
michael@0 | 32 | assert.equal(results.length, 2, 'Correct number of entries returned'); |
michael@0 | 33 | assert.equal(results[0].url, 'http://simplequery-1.com/', |
michael@0 | 34 | 'matches url'); |
michael@0 | 35 | assert.equal(results[1].url, 'http://simplequery-2.com/', |
michael@0 | 36 | 'matches url'); |
michael@0 | 37 | assert.equal(results[0].title, 'Test visit for ' + results[0].url, |
michael@0 | 38 | 'title matches'); |
michael@0 | 39 | assert.equal(results[1].title, 'Test visit for ' + results[1].url, |
michael@0 | 40 | 'title matches'); |
michael@0 | 41 | assert.equal(results[0].visitCount, 1, 'matches access'); |
michael@0 | 42 | assert.equal(results[1].visitCount, 1, 'matches access'); |
michael@0 | 43 | assert.ok(within(results[0].time), 'accurate access time'); |
michael@0 | 44 | assert.ok(within(results[1].time), 'accurate access time'); |
michael@0 | 45 | assert.equal(Object.keys(results[0]).length, 4, |
michael@0 | 46 | 'no addition exposed properties on history result'); |
michael@0 | 47 | done(); |
michael@0 | 48 | }, invalidReject); |
michael@0 | 49 | }; |
michael@0 | 50 | |
michael@0 | 51 | exports.testVisitCount = function (assert, done) { |
michael@0 | 52 | addVisits([ |
michael@0 | 53 | 'http://simplequery-1.com', 'http://simplequery-1.com', |
michael@0 | 54 | 'http://simplequery-1.com', 'http://simplequery-1.com' |
michael@0 | 55 | ]).then(searchP).then(results => { |
michael@0 | 56 | assert.equal(results.length, 1, 'Correct number of entries returned'); |
michael@0 | 57 | assert.equal(results[0].url, 'http://simplequery-1.com/', 'correct url'); |
michael@0 | 58 | assert.equal(results[0].visitCount, 4, 'matches access count'); |
michael@0 | 59 | done(); |
michael@0 | 60 | }, invalidReject); |
michael@0 | 61 | }; |
michael@0 | 62 | |
michael@0 | 63 | /* |
michael@0 | 64 | * Tests 4 scenarios |
michael@0 | 65 | * '*.mozilla.org' |
michael@0 | 66 | * 'mozilla.org' |
michael@0 | 67 | * 'http://mozilla.org/' |
michael@0 | 68 | * 'http://mozilla.org/*' |
michael@0 | 69 | */ |
michael@0 | 70 | exports.testSearchURL = function (assert, done) { |
michael@0 | 71 | addVisits([ |
michael@0 | 72 | 'http://developer.mozilla.org', 'http://mozilla.org', |
michael@0 | 73 | 'http://mozilla.org/index', 'https://mozilla.org' |
michael@0 | 74 | ]).then(() => searchP({ url: '*.mozilla.org' })) |
michael@0 | 75 | .then(results => { |
michael@0 | 76 | assert.equal(results.length, 4, 'returns all entries'); |
michael@0 | 77 | return searchP({ url: 'mozilla.org' }); |
michael@0 | 78 | }).then(results => { |
michael@0 | 79 | assert.equal(results.length, 3, 'returns entries where mozilla.org is host'); |
michael@0 | 80 | return searchP({ url: 'http://mozilla.org/' }); |
michael@0 | 81 | }).then(results => { |
michael@0 | 82 | assert.equal(results.length, 1, 'should just be an exact match'); |
michael@0 | 83 | return searchP({ url: 'http://mozilla.org/*' }); |
michael@0 | 84 | }).then(results => { |
michael@0 | 85 | assert.equal(results.length, 2, 'should match anything starting with substring'); |
michael@0 | 86 | done(); |
michael@0 | 87 | }); |
michael@0 | 88 | }; |
michael@0 | 89 | |
michael@0 | 90 | // Disabling due to intermittent Bug 892619 |
michael@0 | 91 | // TODO solve this |
michael@0 | 92 | /* |
michael@0 | 93 | exports.testSearchTimeRange = function (assert, done) { |
michael@0 | 94 | let firstTime, secondTime; |
michael@0 | 95 | addVisits([ |
michael@0 | 96 | 'http://earlyvisit.org', 'http://earlyvisit.org/earlytown.html' |
michael@0 | 97 | ]).then(searchP).then(results => { |
michael@0 | 98 | firstTime = results[0].time; |
michael@0 | 99 | var deferred = defer(); |
michael@0 | 100 | setTimeout(function () deferred.resolve(), 1000); |
michael@0 | 101 | return deferred.promise; |
michael@0 | 102 | }).then(() => { |
michael@0 | 103 | return addVisits(['http://newvisit.org', 'http://newvisit.org/whoawhoa.html']); |
michael@0 | 104 | }).then(searchP).then(results => { |
michael@0 | 105 | results.filter(({url, time}) => { |
michael@0 | 106 | if (/newvisit/.test(url)) secondTime = time; |
michael@0 | 107 | }); |
michael@0 | 108 | return searchP({ from: firstTime - 1000 }); |
michael@0 | 109 | }).then(results => { |
michael@0 | 110 | assert.equal(results.length, 4, 'should return all entries'); |
michael@0 | 111 | return searchP({ to: firstTime + 500 }); |
michael@0 | 112 | }).then(results => { |
michael@0 | 113 | assert.equal(results.length, 2, 'should return only first entries'); |
michael@0 | 114 | results.map(item => { |
michael@0 | 115 | assert.ok(/earlyvisit/.test(item.url), 'correct entry'); |
michael@0 | 116 | }); |
michael@0 | 117 | return searchP({ from: firstTime + 500 }); |
michael@0 | 118 | }).then(results => { |
michael@0 | 119 | assert.equal(results.length, 2, 'should return only last entries'); |
michael@0 | 120 | results.map(item => { |
michael@0 | 121 | assert.ok(/newvisit/.test(item.url), 'correct entry'); |
michael@0 | 122 | }); |
michael@0 | 123 | done(); |
michael@0 | 124 | }); |
michael@0 | 125 | }; |
michael@0 | 126 | */ |
michael@0 | 127 | exports.testSearchQuery = function (assert, done) { |
michael@0 | 128 | addVisits([ |
michael@0 | 129 | 'http://mozilla.com', 'http://webaud.io', 'http://mozilla.com/webfwd' |
michael@0 | 130 | ]).then(() => { |
michael@0 | 131 | return searchP({ query: 'moz' }); |
michael@0 | 132 | }).then(results => { |
michael@0 | 133 | assert.equal(results.length, 2, 'should return urls that match substring'); |
michael@0 | 134 | results.map(({url}) => { |
michael@0 | 135 | assert.ok(/moz/.test(url), 'correct item'); |
michael@0 | 136 | }); |
michael@0 | 137 | return searchP([{ query: 'webfwd' }, { query: 'aud.io' }]); |
michael@0 | 138 | }).then(results => { |
michael@0 | 139 | assert.equal(results.length, 2, 'should OR separate queries'); |
michael@0 | 140 | results.map(({url}) => { |
michael@0 | 141 | assert.ok(/webfwd|aud\.io/.test(url), 'correct item'); |
michael@0 | 142 | }); |
michael@0 | 143 | done(); |
michael@0 | 144 | }); |
michael@0 | 145 | }; |
michael@0 | 146 | |
michael@0 | 147 | /* |
michael@0 | 148 | * Query Options |
michael@0 | 149 | */ |
michael@0 | 150 | |
michael@0 | 151 | exports.testSearchCount = function (assert, done) { |
michael@0 | 152 | addVisits([ |
michael@0 | 153 | 'http://mozilla.com', 'http://webaud.io', 'http://mozilla.com/webfwd', |
michael@0 | 154 | 'http://developer.mozilla.com', 'http://bandcamp.com' |
michael@0 | 155 | ]).then(testCount(1)) |
michael@0 | 156 | .then(testCount(2)) |
michael@0 | 157 | .then(testCount(3)) |
michael@0 | 158 | .then(testCount(5)) |
michael@0 | 159 | .then(done); |
michael@0 | 160 | |
michael@0 | 161 | function testCount (n) { |
michael@0 | 162 | return function () { |
michael@0 | 163 | return searchP({}, { count: n }).then(results => { |
michael@0 | 164 | assert.equal(results.length, n, |
michael@0 | 165 | 'count ' + n + ' returns ' + n + ' results'); |
michael@0 | 166 | }); |
michael@0 | 167 | }; |
michael@0 | 168 | } |
michael@0 | 169 | }; |
michael@0 | 170 | |
michael@0 | 171 | exports.testSearchSort = function (assert, done) { |
michael@0 | 172 | let places = [ |
michael@0 | 173 | 'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/', |
michael@0 | 174 | 'http://developer.mozilla.com/', 'http://bandcamp.com/' |
michael@0 | 175 | ]; |
michael@0 | 176 | addVisits(places).then(() => { |
michael@0 | 177 | return searchP({}, { sort: 'title' }); |
michael@0 | 178 | }).then(results => { |
michael@0 | 179 | checkOrder(results, [4,3,0,2,1]); |
michael@0 | 180 | return searchP({}, { sort: 'title', descending: true }); |
michael@0 | 181 | }).then(results => { |
michael@0 | 182 | checkOrder(results, [1,2,0,3,4]); |
michael@0 | 183 | return searchP({}, { sort: 'url' }); |
michael@0 | 184 | }).then(results => { |
michael@0 | 185 | checkOrder(results, [4,3,0,2,1]); |
michael@0 | 186 | return searchP({}, { sort: 'url', descending: true }); |
michael@0 | 187 | }).then(results => { |
michael@0 | 188 | checkOrder(results, [1,2,0,3,4]); |
michael@0 | 189 | return addVisits('http://mozilla.com') // for visit conut |
michael@0 | 190 | .then(() => addVisits('http://github.com')); // for checking date |
michael@0 | 191 | }).then(() => { |
michael@0 | 192 | return searchP({}, { sort: 'visitCount' }); |
michael@0 | 193 | }).then(results => { |
michael@0 | 194 | assert.equal(results[5].url, 'http://mozilla.com/', |
michael@0 | 195 | 'last entry is the highest visit count'); |
michael@0 | 196 | return searchP({}, { sort: 'visitCount', descending: true }); |
michael@0 | 197 | }).then(results => { |
michael@0 | 198 | assert.equal(results[0].url, 'http://mozilla.com/', |
michael@0 | 199 | 'first entry is the highest visit count'); |
michael@0 | 200 | return searchP({}, { sort: 'date' }); |
michael@0 | 201 | }).then(results => { |
michael@0 | 202 | assert.equal(results[5].url, 'http://github.com/', |
michael@0 | 203 | 'latest visited should be first'); |
michael@0 | 204 | return searchP({}, { sort: 'date', descending: true }); |
michael@0 | 205 | }).then(results => { |
michael@0 | 206 | assert.equal(results[0].url, 'http://github.com/', |
michael@0 | 207 | 'latest visited should be at the end'); |
michael@0 | 208 | }).then(done); |
michael@0 | 209 | |
michael@0 | 210 | function checkOrder (results, nums) { |
michael@0 | 211 | assert.equal(results.length, nums.length, 'expected return count'); |
michael@0 | 212 | for (let i = 0; i < nums.length; i++) { |
michael@0 | 213 | assert.equal(results[i].url, places[nums[i]], 'successful order'); |
michael@0 | 214 | } |
michael@0 | 215 | } |
michael@0 | 216 | }; |
michael@0 | 217 | |
michael@0 | 218 | exports.testEmitters = function (assert, done) { |
michael@0 | 219 | let urls = [ |
michael@0 | 220 | 'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/', |
michael@0 | 221 | 'http://developer.mozilla.com/', 'http://bandcamp.com/' |
michael@0 | 222 | ]; |
michael@0 | 223 | addVisits(urls).then(() => { |
michael@0 | 224 | let count = 0; |
michael@0 | 225 | search().on('data', item => { |
michael@0 | 226 | assert.ok(~urls.indexOf(item.url), 'data value found in url list'); |
michael@0 | 227 | count++; |
michael@0 | 228 | }).on('end', results => { |
michael@0 | 229 | assert.equal(results.length, 5, 'correct count of items'); |
michael@0 | 230 | assert.equal(count, 5, 'data event called 5 times'); |
michael@0 | 231 | done(); |
michael@0 | 232 | }); |
michael@0 | 233 | }); |
michael@0 | 234 | }; |
michael@0 | 235 | |
michael@0 | 236 | function toBeWithin (range) { |
michael@0 | 237 | range = range || 2000; |
michael@0 | 238 | var current = new Date() * 1000; // convert to microseconds |
michael@0 | 239 | return compared => { |
michael@0 | 240 | return compared - current < range; |
michael@0 | 241 | }; |
michael@0 | 242 | } |
michael@0 | 243 | |
michael@0 | 244 | function searchP () { |
michael@0 | 245 | return promisedEmitter(search.apply(null, Array.slice(arguments))); |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | before(exports, (name, assert, done) => resetPlaces(done)); |
michael@0 | 249 | after(exports, (name, assert, done) => resetPlaces(done)); |