mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-10-13 03:37:12 +02:00
feat: add Safari browser support with history extraction (#564)
* feat: add Safari browser support with history extraction * fix: use correlated subquery to ensure title matches latest visit
This commit is contained in:
1 parent
26817b44d5
commit
509cdc2468
11 files changed
+639
No files matched your search
@@ -0,0 +1,105 @@
|
||||
package safari
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func setupSafariHistoryDB(t *testing.T) string {
|
||||
t.Helper()
|
||||
return createTestDB(t, "History.db",
|
||||
[]string{safariHistoryItemsSchema, safariHistoryVisitsSchema},
|
||||
insertHistoryItem(1, "https://github.com", "github.com", 100),
|
||||
insertHistoryItem(2, "https://go.dev", "go.dev", 50),
|
||||
insertHistoryItem(3, "https://example.com", "example.com", 200),
|
||||
// Item 1 has two visits — extractHistories must deduplicate.
|
||||
insertHistoryVisit(1, 1, 704067600.0, "GitHub"),
|
||||
insertHistoryVisit(2, 1, 705067600.0, "GitHub - Latest"),
|
||||
insertHistoryVisit(3, 2, 703067600.0, "The Go Programming Language"),
|
||||
insertHistoryVisit(4, 3, 700067600.0, "Example Domain"),
|
||||
)
|
||||
}
|
||||
|
||||
func TestExtractHistories(t *testing.T) {
|
||||
path := setupSafariHistoryDB(t)
|
||||
|
||||
got, err := extractHistories(path)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, got, 3)
|
||||
|
||||
// Sorted by visit count descending (most visited first).
|
||||
assert.Equal(t, 200, got[0].VisitCount)
|
||||
assert.Equal(t, 100, got[1].VisitCount)
|
||||
assert.Equal(t, 50, got[2].VisitCount)
|
||||
|
||||
// Verify field mapping.
|
||||
assert.Equal(t, "https://example.com", got[0].URL)
|
||||
assert.Equal(t, "https://github.com", got[1].URL)
|
||||
assert.Equal(t, "https://go.dev", got[2].URL)
|
||||
assert.False(t, got[0].LastVisit.IsZero())
|
||||
}
|
||||
|
||||
func TestExtractHistories_Dedup(t *testing.T) {
|
||||
path := setupSafariHistoryDB(t)
|
||||
|
||||
got, err := extractHistories(path)
|
||||
require.NoError(t, err)
|
||||
// 3 history_items, not 4 visits.
|
||||
require.Len(t, got, 3)
|
||||
|
||||
// GitHub (item 1) should have the later visit_time and its title.
|
||||
for _, h := range got {
|
||||
if h.URL == "https://github.com" {
|
||||
// 705067600 + 978307200 = 1683374800 (unix)
|
||||
assert.Equal(t, int64(1683374800), h.LastVisit.Unix())
|
||||
// Title must come from the latest visit row, not an arbitrary one.
|
||||
assert.Equal(t, "GitHub - Latest", h.Title)
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatal("expected https://github.com in results")
|
||||
}
|
||||
|
||||
func TestCountHistories(t *testing.T) {
|
||||
path := setupSafariHistoryDB(t)
|
||||
|
||||
count, err := countHistories(path)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 3, count)
|
||||
}
|
||||
|
||||
func TestCountHistories_Empty(t *testing.T) {
|
||||
path := createTestDB(t, "History.db",
|
||||
[]string{safariHistoryItemsSchema, safariHistoryVisitsSchema})
|
||||
|
||||
count, err := countHistories(path)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, count)
|
||||
}
|
||||
|
||||
func TestExtractHistories_NullTitle(t *testing.T) {
|
||||
path := createTestDB(t, "History.db",
|
||||
[]string{safariHistoryItemsSchema, safariHistoryVisitsSchema},
|
||||
insertHistoryItem(1, "https://null.test", "null.test", 1),
|
||||
// Visit with NULL title — COALESCE should return empty string.
|
||||
`INSERT INTO history_visits (id, history_item, visit_time) VALUES (1, 1, 700000000.0)`,
|
||||
)
|
||||
|
||||
got, err := extractHistories(path)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, got, 1)
|
||||
assert.Equal(t, "https://null.test", got[0].URL)
|
||||
assert.Empty(t, got[0].Title)
|
||||
}
|
||||
|
||||
func TestCoredataTimestamp(t *testing.T) {
|
||||
// 0 Core Data epoch = 2001-01-01 00:00:00 UTC = Unix 978307200
|
||||
ts := coredataTimestamp(0)
|
||||
assert.Equal(t, int64(978307200), ts.Unix())
|
||||
|
||||
// Known value: 700000000 Core Data = 1678307200 Unix
|
||||
ts2 := coredataTimestamp(700000000)
|
||||
assert.Equal(t, int64(1678307200), ts2.Unix())
|
||||
}
|
||||
Reference in new issue
Block a user