mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-21 11:53:07 +09:00
333 lines
15 KiB
Swift
333 lines
15 KiB
Swift
/* 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/. */
|
|
|
|
import Foundation
|
|
import Shared
|
|
@testable import Storage
|
|
import Deferred
|
|
import SDWebImage
|
|
|
|
import XCTest
|
|
|
|
private let microsecondsPerMinute: UInt64 = 60_000_000 // 1000 * 1000 * 60
|
|
private let oneHourInMicroseconds: UInt64 = 60 * microsecondsPerMinute
|
|
private let oneDayInMicroseconds: UInt64 = 24 * oneHourInMicroseconds
|
|
|
|
class TestSQLiteHistoryRecommendations: XCTestCase {
|
|
let files = MockFiles()
|
|
|
|
var db: BrowserDB!
|
|
var prefs: MockProfilePrefs!
|
|
var history: SQLiteHistory!
|
|
var bookmarks: MergedSQLiteBookmarks!
|
|
var metadata: SQLiteMetadata!
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
|
|
db = BrowserDB(filename: "browser.db", schema: BrowserSchema(), files: files)
|
|
metadata = SQLiteMetadata(db: db)
|
|
prefs = MockProfilePrefs()
|
|
history = SQLiteHistory(db: db, prefs: prefs)
|
|
bookmarks = MergedSQLiteBookmarks(db: db)
|
|
}
|
|
|
|
override func tearDown() {
|
|
// Clear out anything we might have changed on disk
|
|
history.clearHistory().succeeded()
|
|
db.run("DELETE FROM \(TablePageMetadata)").succeeded()
|
|
db.run("DELETE FROM \(TableHighlights)").succeeded()
|
|
db.run("DELETE FROM \(TableActivityStreamBlocklist)").succeeded()
|
|
|
|
SDWebImageManager.shared().imageCache?.clearDisk()
|
|
SDWebImageManager.shared().imageCache?.clearMemory()
|
|
|
|
super.tearDown()
|
|
}
|
|
|
|
/*
|
|
* Verify that we return a non-recent history highlight if:
|
|
*
|
|
* 1. We haven't visited the site in the last 30 minutes
|
|
* 2. We've only visited the site less than or equal to 3 times
|
|
* 3. The site we visited has a non-empty title
|
|
*
|
|
*/
|
|
func testHistoryHighlights() {
|
|
let startTime = Date.nowMicroseconds()
|
|
let oneHourAgo = startTime - oneHourInMicroseconds
|
|
let fifteenMinutesAgo = startTime - 15 * microsecondsPerMinute
|
|
|
|
/*
|
|
* Site A: 1 visit, 1 hour ago = highlight
|
|
* Site B: 1 visits, 15 minutes ago = non-highlight
|
|
* Site C: 3 visits, 1 hour ago = highlight
|
|
* Site D: 4 visits, 1 hour ago = non-highlight
|
|
*/
|
|
let siteA = Site(url: "http://siteA/", title: "A")
|
|
let siteB = Site(url: "http://siteB/", title: "B")
|
|
let siteC = Site(url: "http://siteC/", title: "C")
|
|
let siteD = Site(url: "http://siteD/", title: "D")
|
|
|
|
let siteVisitA1 = SiteVisit(site: siteA, date: oneHourAgo, type: .link)
|
|
let siteVisitB1 = SiteVisit(site: siteB, date: fifteenMinutesAgo, type: .link)
|
|
|
|
let siteVisitC1 = SiteVisit(site: siteC, date: oneHourAgo + 1, type: .link)
|
|
let siteVisitC2 = SiteVisit(site: siteC, date: oneHourAgo + 1000, type: .link)
|
|
let siteVisitC3 = SiteVisit(site: siteC, date: oneHourAgo + 2000, type: .link)
|
|
|
|
let siteVisitD1 = SiteVisit(site: siteD, date: oneHourAgo, type: .link)
|
|
let siteVisitD2 = SiteVisit(site: siteD, date: oneHourAgo + 1000, type: .link)
|
|
let siteVisitD3 = SiteVisit(site: siteD, date: oneHourAgo + 2000, type: .link)
|
|
let siteVisitD4 = SiteVisit(site: siteD, date: oneHourAgo + 3000, type: .link)
|
|
|
|
history.clearHistory().succeeded()
|
|
history.addLocalVisit(siteVisitA1).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitB1).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitC1).succeeded()
|
|
history.addLocalVisit(siteVisitC2).succeeded()
|
|
history.addLocalVisit(siteVisitC3).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitD1).succeeded()
|
|
history.addLocalVisit(siteVisitD2).succeeded()
|
|
history.addLocalVisit(siteVisitD3).succeeded()
|
|
history.addLocalVisit(siteVisitD4).succeeded()
|
|
history.repopulate(invalidateTopSites: true, invalidateHighlights: true).succeeded()
|
|
let highlights = history.getHighlights().value.successValue!
|
|
XCTAssertEqual(highlights.count, 2)
|
|
XCTAssertEqual(highlights[0]!.title, "A")
|
|
XCTAssertEqual(highlights[1]!.title, "C")
|
|
}
|
|
|
|
/*
|
|
* Verify that we do not return a highlight if
|
|
* its domain is in the blacklist
|
|
*
|
|
*/
|
|
func testBlacklistHighlights() {
|
|
let startTime = Date.nowMicroseconds()
|
|
let oneHourAgo = startTime - oneHourInMicroseconds
|
|
let fifteenMinutesAgo = startTime - 15 * microsecondsPerMinute
|
|
|
|
/*
|
|
* Site A: 1 visit, 1 hour ago = highlight that is on the blacklist
|
|
* Site B: 1 visits, 15 minutes ago = non-highlight
|
|
* Site C: 3 visits, 1 hour ago = highlight that is on the blacklist
|
|
* Site D: 4 visits, 1 hour ago = non-highlight
|
|
*/
|
|
let siteA = Site(url: "http://www.google.com", title: "A")
|
|
let siteB = Site(url: "http://siteB/", title: "B")
|
|
let siteC = Site(url: "http://www.search.yahoo.com/", title: "C")
|
|
let siteD = Site(url: "http://siteD/", title: "D")
|
|
|
|
let siteVisitA1 = SiteVisit(site: siteA, date: oneHourAgo, type: .link)
|
|
let siteVisitB1 = SiteVisit(site: siteB, date: fifteenMinutesAgo, type: .link)
|
|
|
|
let siteVisitC1 = SiteVisit(site: siteC, date: oneHourAgo, type: .link)
|
|
let siteVisitC2 = SiteVisit(site: siteC, date: oneHourAgo + 1000, type: .link)
|
|
let siteVisitC3 = SiteVisit(site: siteC, date: oneHourAgo + 2000, type: .link)
|
|
|
|
let siteVisitD1 = SiteVisit(site: siteD, date: oneHourAgo, type: .link)
|
|
let siteVisitD2 = SiteVisit(site: siteD, date: oneHourAgo + 1000, type: .link)
|
|
let siteVisitD3 = SiteVisit(site: siteD, date: oneHourAgo + 2000, type: .link)
|
|
let siteVisitD4 = SiteVisit(site: siteD, date: oneHourAgo + 3000, type: .link)
|
|
|
|
history.clearHistory().succeeded()
|
|
history.addLocalVisit(siteVisitA1).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitB1).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitC1).succeeded()
|
|
history.addLocalVisit(siteVisitC2).succeeded()
|
|
history.addLocalVisit(siteVisitC3).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitD1).succeeded()
|
|
history.addLocalVisit(siteVisitD2).succeeded()
|
|
history.addLocalVisit(siteVisitD3).succeeded()
|
|
history.addLocalVisit(siteVisitD4).succeeded()
|
|
|
|
history.repopulate(invalidateTopSites: true, invalidateHighlights: true).succeeded()
|
|
let highlights = history.getHighlights().value.successValue!
|
|
XCTAssertEqual(highlights.count, 0)
|
|
}
|
|
|
|
/*
|
|
* Verify that we return the most recent highlight per domain
|
|
*/
|
|
func testMostRecentUniqueDomainReturnedInHighlights() {
|
|
let startTime = Date.nowMicroseconds()
|
|
let oneHourAgo = startTime - oneHourInMicroseconds
|
|
let twoHoursAgo = startTime - 2 * oneHourInMicroseconds
|
|
|
|
/*
|
|
* Site A: 1 visit, 1 hour ago = highlight
|
|
* Site C: 2 visits, 2 hours ago = highlight with the same domain
|
|
*/
|
|
let siteA = Site(url: "http://www.foo.com/", title: "A")
|
|
let siteC = Site(url: "http://m.foo.com/", title: "C")
|
|
|
|
let siteVisitA1 = SiteVisit(site: siteA, date: oneHourAgo, type: .link)
|
|
|
|
let siteVisitC1 = SiteVisit(site: siteC, date: twoHoursAgo, type: .link)
|
|
let siteVisitC2 = SiteVisit(site: siteC, date: twoHoursAgo + 1000, type: .link)
|
|
|
|
history.clearHistory().succeeded()
|
|
history.addLocalVisit(siteVisitA1).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitC1).succeeded()
|
|
history.addLocalVisit(siteVisitC2).succeeded()
|
|
|
|
history.repopulate(invalidateTopSites: true, invalidateHighlights: true).succeeded()
|
|
let highlights = history.getHighlights().value.successValue!
|
|
XCTAssertEqual(highlights.count, 1)
|
|
XCTAssertEqual(highlights[0]!.title, "A")
|
|
}
|
|
|
|
func testBookmarkHighlights() {
|
|
history.clearHistory().succeeded()
|
|
populateForRecommendationCalculations(history, bookmarks: bookmarks, metadata: metadata, historyCount: 10, bookmarkCount: 10)
|
|
|
|
let sites = history.getRecentBookmarks(5).value.successValue?.asArray()
|
|
XCTAssertEqual(sites!.count, 5, "5 bookmarks should have been fetched")
|
|
sites!.forEach { XCTAssertEqual($0.guid, "bookmark-\(sites!.index(of: $0)!)"); XCTAssertEqual($0.metadata?.description, "Test Description") }
|
|
}
|
|
|
|
func testMetadataReturnedInHighlights() {
|
|
let startTime = Date.nowMicroseconds()
|
|
let oneHourAgo = startTime - oneHourInMicroseconds
|
|
|
|
let siteA = Site(url: "http://siteA.com", title: "Site A")
|
|
let siteB = Site(url: "http://siteB.com/", title: "Site B")
|
|
let siteC = Site(url: "http://siteC.com/", title: "Site C")
|
|
|
|
let siteVisitA1 = SiteVisit(site: siteA, date: oneHourAgo, type: .link)
|
|
let siteVisitB1 = SiteVisit(site: siteB, date: oneHourAgo + 1000, type: .link)
|
|
|
|
let siteVisitC1 = SiteVisit(site: siteC, date: oneHourAgo, type: .link)
|
|
let siteVisitC2 = SiteVisit(site: siteC, date: oneHourAgo + 1000, type: .link)
|
|
let siteVisitC3 = SiteVisit(site: siteC, date: oneHourAgo + 2000, type: .link)
|
|
|
|
history.clearHistory().succeeded()
|
|
history.addLocalVisit(siteVisitA1).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitB1).succeeded()
|
|
|
|
history.addLocalVisit(siteVisitC1).succeeded()
|
|
history.addLocalVisit(siteVisitC2).succeeded()
|
|
history.addLocalVisit(siteVisitC3).succeeded()
|
|
|
|
// add metadata for 2 of the sites
|
|
let metadata = SQLiteMetadata(db: db)
|
|
let pageA = PageMetadata(id: nil, siteURL: siteA.url, mediaURL: "http://image.com",
|
|
title: siteA.title, description: "Test Description", type: nil, providerName: nil, mediaDataURI: nil, cacheImages: false)
|
|
metadata.storeMetadata(pageA, forPageURL: siteA.url.asURL!, expireAt: Date.now() + 3000).succeeded()
|
|
let pageB = PageMetadata(id: nil, siteURL: siteB.url, mediaURL: "http://image.com",
|
|
title: siteB.title, description: "Test Description", type: nil, providerName: nil, mediaDataURI: nil, cacheImages: false)
|
|
metadata.storeMetadata(pageB, forPageURL: siteB.url.asURL!, expireAt: Date.now() + 3000).succeeded()
|
|
let pageC = PageMetadata(id: nil, siteURL: siteC.url, mediaURL: "http://image.com",
|
|
title: siteC.title, description: "Test Description", type: nil, providerName: nil, mediaDataURI: nil, cacheImages: false)
|
|
metadata.storeMetadata(pageC, forPageURL: siteC.url.asURL!, expireAt: Date.now() + 3000).succeeded()
|
|
|
|
history.repopulate(invalidateTopSites: true, invalidateHighlights: true).succeeded()
|
|
let highlights = history.getHighlights().value.successValue!
|
|
XCTAssertEqual(highlights.count, 3)
|
|
|
|
for highlight in highlights {
|
|
XCTAssertNotNil(highlight?.metadata)
|
|
XCTAssertNotNil(highlight?.metadata?.mediaURL)
|
|
}
|
|
}
|
|
|
|
func testRemoveHighlightForURL() {
|
|
let startTime = Date.nowMicroseconds()
|
|
let oneHourAgo = startTime - oneHourInMicroseconds
|
|
|
|
let siteA = Site(url: "http://siteA/", title: "A")
|
|
let siteVisitA1 = SiteVisit(site: siteA, date: oneHourAgo, type: .link)
|
|
|
|
history.clearHistory().succeeded()
|
|
history.addLocalVisit(siteVisitA1).succeeded()
|
|
|
|
history.repopulate(invalidateTopSites: true, invalidateHighlights: true).succeeded()
|
|
var highlights = history.getHighlights().value.successValue!
|
|
XCTAssertEqual(highlights.count, 1)
|
|
XCTAssertEqual(highlights[0]!.title, "A")
|
|
|
|
history.removeHighlightForURL(siteA.url).succeeded()
|
|
history.repopulate(invalidateTopSites: true, invalidateHighlights: true).succeeded()
|
|
highlights = history.getHighlights().value.successValue!
|
|
XCTAssertEqual(highlights.count, 0)
|
|
}
|
|
|
|
func testClearHighlightsCache() {
|
|
let startTime = Date.nowMicroseconds()
|
|
let oneHourAgo = startTime - oneHourInMicroseconds
|
|
|
|
let siteA = Site(url: "http://siteA/", title: "A")
|
|
let siteVisitA1 = SiteVisit(site: siteA, date: oneHourAgo, type: .link)
|
|
|
|
history.clearHistory().succeeded()
|
|
history.addLocalVisit(siteVisitA1).succeeded()
|
|
|
|
history.repopulate(invalidateTopSites: true, invalidateHighlights: true).succeeded()
|
|
let highlights = history.getHighlights().value.successValue!
|
|
XCTAssertEqual(highlights.count, 1)
|
|
XCTAssertEqual(highlights[0]!.title, "A")
|
|
}
|
|
}
|
|
|
|
class TestSQLiteHistoryRecommendationsPerf: XCTestCase {
|
|
func testRecommendationPref() {
|
|
let files = MockFiles()
|
|
let db = BrowserDB(filename: "browser.db", schema: BrowserSchema(), files: files)
|
|
let metadata = SQLiteMetadata(db: db)
|
|
let prefs = MockProfilePrefs()
|
|
let history = SQLiteHistory(db: db, prefs: prefs)
|
|
let bookmarks = MergedSQLiteBookmarks(db: db)
|
|
|
|
let count = 500
|
|
|
|
history.clearHistory().succeeded()
|
|
populateForRecommendationCalculations(history, bookmarks: bookmarks, metadata: metadata, historyCount: count, bookmarkCount: count)
|
|
self.measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true) {
|
|
for _ in 0...5 {
|
|
history.repopulate(invalidateTopSites: true, invalidateHighlights: true).succeeded()
|
|
}
|
|
self.stopMeasuring()
|
|
}
|
|
}
|
|
}
|
|
|
|
private func populateForRecommendationCalculations(_ history: SQLiteHistory, bookmarks: MergedSQLiteBookmarks, metadata: SQLiteMetadata, historyCount: Int, bookmarkCount: Int) {
|
|
let baseMillis: UInt64 = baseInstantInMillis - 20000
|
|
|
|
for i in 0..<historyCount {
|
|
let site = Site(url: "http://s\(i)ite\(i)/foo", title: "A \(i)")
|
|
site.guid = "abc\(i)def"
|
|
|
|
history.insertOrUpdatePlace(site.asPlace(), modified: baseMillis).succeeded()
|
|
for j in 0...20 {
|
|
let visitTime = advanceMicrosecondTimestamp(baseInstantInMicros, by: (1000000 * i) + (1000 * j))
|
|
addVisitForSite(site, intoHistory: history, from: .local, atTime: visitTime)
|
|
addVisitForSite(site, intoHistory: history, from: .remote, atTime: visitTime)
|
|
}
|
|
}
|
|
|
|
(0..<bookmarkCount).forEach { i in
|
|
let modifiedTime = advanceMicrosecondTimestamp(baseInstantInMicros, by: (1000000 * i))
|
|
let bookmarkSite = Site(url: "http://bookmark-\(i)/", title: "\(i) Bookmark")
|
|
bookmarkSite.guid = "bookmark-\(i)"
|
|
|
|
addVisitForSite(bookmarkSite, intoHistory: history, from: .local, atTime: modifiedTime)
|
|
addVisitForSite(bookmarkSite, intoHistory: history, from: .remote, atTime: modifiedTime)
|
|
addVisitForSite(bookmarkSite, intoHistory: history, from: .local, atTime: modifiedTime)
|
|
addVisitForSite(bookmarkSite, intoHistory: history, from: .remote, atTime: modifiedTime)
|
|
let pageA = PageMetadata(id: nil, siteURL: bookmarkSite.url, mediaURL: "http://image.com",
|
|
title: bookmarkSite.title, description: "Test Description", type: nil, providerName: nil, mediaDataURI: nil, cacheImages: false)
|
|
metadata.storeMetadata(pageA, forPageURL: bookmarkSite.url.asURL!, expireAt: Date.now() + 3000).succeeded()
|
|
bookmarks.local.addToMobileBookmarks(URL(string:"http://bookmark-\(i)/")!, title: "\(i) Bookmark", favicon: nil).succeeded()
|
|
}
|
|
}
|