gosuki/firefox/firefox_test.go

506 lines
15 KiB
Go
Raw Normal View History

package firefox
import (
"os"
2022-12-05 02:59:22 +00:00
"strings"
"testing"
"git.sp4ke.xyz/sp4ke/gomark/browsers"
"git.sp4ke.xyz/sp4ke/gomark/database"
"git.sp4ke.xyz/sp4ke/gomark/index"
2022-12-10 01:49:30 +00:00
"git.sp4ke.xyz/sp4ke/gomark/logging"
"git.sp4ke.xyz/sp4ke/gomark/mozilla"
"git.sp4ke.xyz/sp4ke/gomark/parsing"
"git.sp4ke.xyz/sp4ke/gomark/tree"
"git.sp4ke.xyz/sp4ke/gomark/utils"
2022-12-05 02:59:22 +00:00
"github.com/chenhg5/collection"
"github.com/stretchr/testify/assert"
)
var ff Firefox
func TestMain(m *testing.M) {
ff = Firefox{
FirefoxConfig: &FirefoxConfig{
BrowserConfig: &browsers.BrowserConfig{
Name: "firefox",
Type: browsers.TFirefox,
BkFile: mozilla.PlacesFile,
BkDir: "testdata",
BufferDB: &database.DB{},
URLIndex: index.NewIndex(),
NodeTree: &tree.Node{Name: "root", Parent: nil, Type: tree.RootNode},
Stats: &parsing.Stats{},
},
},
2022-12-11 22:06:07 +00:00
tagMap: map[string]*tree.Node{},
2022-12-10 01:49:30 +00:00
folderMap: map[sqlid]*tree.Node{},
}
exitVal := m.Run()
os.Exit(exitVal)
}
2022-12-05 02:59:22 +00:00
func runPlacesTest(name string, t *testing.T, test func(t *testing.T)) {
bkPath, err := ff.BookmarkPath()
2022-12-10 01:49:30 +00:00
if err != nil {
t.Error(err)
}
2022-12-05 02:59:22 +00:00
2022-12-10 01:49:30 +00:00
ff.places, err = database.NewDB("places", bkPath, database.DBTypeFileDSN,
FFConfig.PlacesDSN).Init()
2022-12-05 02:59:22 +00:00
2022-12-10 01:49:30 +00:00
t.Cleanup(func() {
err = ff.places.Close()
if err != nil {
t.Error(err)
}
})
2022-12-05 02:59:22 +00:00
2022-12-10 01:49:30 +00:00
if err != nil {
t.Error(err)
}
2022-12-05 02:59:22 +00:00
2022-12-10 01:49:30 +00:00
t.Run(name, test)
2022-12-05 02:59:22 +00:00
}
func Test_addUrlNode(t *testing.T) {
2022-12-10 01:49:30 +00:00
testUrl := struct {
url string
id sqlid
title string
desc string
}{
url: "http://test-url.gomark",
id: 24,
title: "test url",
desc: "desc of test url",
}
// fetch url changes into places and bookmarks
// for each urlId/place
// if urlNode does not exists create it
// if urlNode exists find fetch it
// if urlNode exists put tag node as parent to this url
testNewUrl := "new urlNode: url is not yet in URLIndex"
t.Run(testNewUrl, func(t *testing.T) {
ok, urlNode := ff.addUrlNode(testUrl.url, testUrl.title, testUrl.desc)
if !ok {
t.Fatalf("expected %v, got %v", true, false)
}
if urlNode == nil {
t.Fatal("url node was not returned", testNewUrl)
}
2022-12-10 01:49:30 +00:00
_, ok = ff.URLIndex.Get(testUrl.url)
if !ok {
t.Fatal("url was not added to url index")
}
2022-12-10 01:49:30 +00:00
if !utils.Inlist(ff.URLIndexList, testUrl.url) {
t.Fatal("url was not added to url index list")
}
2022-12-10 01:49:30 +00:00
})
2022-12-10 01:49:30 +00:00
testUrlExists := "return existing urlNode found in URLIndex"
t.Run(testUrlExists, func(t *testing.T) {
_, origNode := ff.addUrlNode(testUrl.url, testUrl.title, testUrl.desc)
ok, urlNode := ff.addUrlNode(testUrl.url, testUrl.title, testUrl.desc)
if ok {
t.Fatalf("expected %v, got %v", false, true)
}
2022-12-10 01:49:30 +00:00
if urlNode == nil {
t.Fatal("existing url node was not returned from index")
}
2022-12-10 01:49:30 +00:00
if urlNode != origNode {
t.Fatal("existing node does not match retrieved node from url index")
}
2022-12-10 01:49:30 +00:00
_, ok = ff.URLIndex.Get(testUrl.url)
if !ok {
t.Fatal("url was not added to url index")
}
2022-12-10 01:49:30 +00:00
if !utils.Inlist(ff.URLIndexList, testUrl.url) {
t.Fatal("url was not added to url index list")
}
2022-12-10 01:49:30 +00:00
})
2022-12-10 01:49:30 +00:00
}
2022-12-10 01:49:30 +00:00
func Test_addFolderNode(t *testing.T) {
2022-12-10 01:49:30 +00:00
// Test cases
// 1. Adding a new folder under a root mozilla folder (parent = 2,3,5,6)
// 2. Adding a child folder
// 3. Adding a folder that we already saw before
2022-12-05 22:21:23 +00:00
2022-12-10 01:49:30 +00:00
//TODO: Print the folder tree in the test ?
2022-12-10 01:49:30 +00:00
t.Run("adding firefox root folder", func(t *testing.T){
testRootFolder := MozFolder{
Id: 3,
Parent: 1,
Title: "toolbar",
}
2022-12-10 01:49:30 +00:00
created, fNode := ff.addFolderNode(testRootFolder)
2022-12-10 01:49:30 +00:00
assert.True(t, created)
// root folder should have appropriate title
assert.Equal(t, fNode.Name, "Bookmarks Toolbar")
// Should be underneath root folder
assert.Equal(t, fNode.Parent, ff.NodeTree)
})
t.Run("add non existing folder with no parent", func(t *testing.T){
testFolder := MozFolder{
Id: 10,
Parent: 3, // folder under the Bookmarks Toolbar
Title: "Programming",
}
folderNodeCreated, folderNode := ff.addFolderNode(testFolder)
// we should have the following hierarchy
// -- ROOT
// |-- Bookmarks Toolbar
// |-- Programming
// We expect the folder was created
assert.True(t, folderNodeCreated)
// If we add the same folder, we should get the same node from
// the folderMap but no new folderNode is created
folderAdded, sameFolderNode := ff.addFolderNode(testFolder)
assert.False(t, folderAdded)
assert.Equal(t, sameFolderNode, folderNode)
assert.NotNil(t, folderNode, "folder was not created")
// Folder should not be added at the root of the tree
assert.NotEqual(t, folderNode.Parent, ff.NodeTree, "wront parent folder")
// Name of node should match title of scanned folder
assert.Equal(t, folderNode.Name, testFolder.Title, "parsing folder name")
})
}
2022-12-11 22:06:07 +00:00
// TODO: use tag name instead of id inside the map
2022-12-10 01:49:30 +00:00
func Test_addTagNode(t *testing.T) {
testTag := struct {
2022-12-11 22:06:07 +00:00
tagName string
2022-12-10 01:49:30 +00:00
tagType string
}{
2022-12-11 22:06:07 +00:00
tagName: "#test_tag",
2022-12-10 01:49:30 +00:00
tagType: "tag",
}
// Should return true with the new node
testName := "add new tag to root tree"
t.Run(testName, func(t *testing.T) {
2022-12-11 22:06:07 +00:00
ok, tagNode := ff.addTagNode(testTag.tagName)
2022-12-10 01:49:30 +00:00
if !ok {
t.Errorf("[%s] expected %v ,got %v", testName, true, false)
}
if tagNode == nil {
t.Fatalf("[%s] tag node was not returned", testName)
}
2022-12-11 22:06:07 +00:00
// "tags" branch should exist
// TagNode should be underneath "tags" branch
if tagNode.Parent.Parent != ff.NodeTree &&
tagNode.Name != "tags" {
2022-12-10 01:49:30 +00:00
t.Errorf("[%s] wrong parent root for tag", testName)
}
t.Run("should be in tagMap", func(t *testing.T) {
2022-12-11 22:06:07 +00:00
node, ok := ff.tagMap[testTag.tagName]
2022-12-10 01:49:30 +00:00
if !ok {
t.Error("tag node was not found in tagMap")
}
if node != tagNode {
t.Error("tag node different from the one added to tagMap")
}
})
t.Run("increment node count", func(t *testing.T) {
if ff.CurrentNodeCount != 1 {
t.Errorf("wrong node count")
}
})
})
// This should return false with the existing node and not add a new one
testName = "add existing tag to root tree"
t.Run(testName, func(t *testing.T) {
2022-12-11 22:06:07 +00:00
ff.addTagNode(testTag.tagName)
ok, tagNode := ff.addTagNode(testTag.tagName)
2022-12-10 01:49:30 +00:00
if tagNode == nil {
t.Fatalf("[%s] tag node was not returned", testName)
}
2022-12-11 22:06:07 +00:00
if tagNode.Parent.Name != TagsBranchName {
2022-12-10 01:49:30 +00:00
t.Errorf("[%s] wrong parent root for tag", testName)
}
if ok {
t.Errorf("[%s] expected %v ,got %v", testName, false, true)
}
})
}
func Test_fetchUrlChanges(t *testing.T) {
2022-12-10 01:49:30 +00:00
t.Error("split into small units")
}
2022-11-24 20:25:05 +00:00
func Test_PlaceBookmarkTimeParsing(t *testing.T) {
2022-12-10 01:49:30 +00:00
assert := assert.New(t)
pb := MergedPlaceBookmark{
BkLastModified: 1663878015759000,
}
2022-12-10 01:49:30 +00:00
res := pb.datetime().Format("2006-01-02 15:04:05.000000")
assert.Equal(res, "2022-09-22 20:20:15.759000", "wrong time in scanned bookmark")
}
2022-11-24 20:25:05 +00:00
// TODO!: integration test loading firefox bookmarks
2022-12-05 02:59:22 +00:00
func Test_scanBookmarks(t *testing.T) {
2022-12-11 22:06:07 +00:00
logging.SetMode(-1)
2022-12-10 01:49:30 +00:00
// expected data from testdata/places.sqlite
data := struct {
tags []string
folders []string // list of tags
bookmarkTags map[string][]string // list of folder names
}{ // list of urls which are bookmarked
tags: []string{"golang", "programming", "rust"},
folders: []string{
"menu", // Bookmarks Menu
"toolbar", // Bookmarks Toolbar
"tags", // Tags Virtual Folder
"unfiled", // Other Bookmarks
"mobile", // Mobile Bookmarks
"cooking",
"Travel",
"indian",
"GomarkMenu",
},
bookmarkTags: map[string][]string{
"https://based.cooking/": {"based"},
"https://go.dev/": {"golang", "programming"},
"https://www.rust-lang.org/": {"programming", "rust", "systems"},
"https://www.tasteofhome.com/article/indian-cooking/": {},
"http://gomark.io/": {"gomark"},
"https://www.budapestinfo.hu/": {"budapest"},
"https://www.fsf.org/": {"libre"},
},
}
t.Log("loading firefox bookmarks")
// First make sure bookmarks are scaned then verify they are loaded
// in CacheDB
runPlacesTest("find", t, func(t *testing.T) {
2022-12-11 22:06:07 +00:00
bookmarks, err := ff.scanBookmarks()
2022-12-10 01:49:30 +00:00
if err != nil {
t.Error(err)
}
2022-12-10 01:49:30 +00:00
// 1- find all tags defined by user
t.Run("all urls", func(t *testing.T) {
var urls []string
for _, bk := range bookmarks {
urls = utils.Extends(urls, bk.Url)
}
var testUrls []string
for url, _ := range data.bookmarkTags {
testUrls = append(testUrls, url)
}
testUrls = collection.Collect(testUrls).Unique().ToStringArray()
assert.ElementsMatch(t, urls, testUrls)
2022-12-11 22:06:07 +00:00
// all urls are in urlindex
for _, bk := range bookmarks {
_, inIndex := ff.URLIndex.Get(bk.Url)
assert.True(t, inIndex, "url should be in url index")
}
2022-12-10 01:49:30 +00:00
})
/*
2.find all folders
*/
t.Run("all folders", func(t *testing.T) {
var folders []string
for _, bk := range bookmarks {
folderS := strings.Split(bk.Folders, ",")
for _, f := range folderS {
folders = utils.Extends(folders, f)
}
}
assert.ElementsMatch(t, folders, data.folders)
})
/*
3. find all url bookmarks with their corresponding tags
- should get any user added bookmark (id > 12)
*/
t.Run("all tags", func(t *testing.T) {
bkTags := map[string][]string{}
for _, bk := range bookmarks {
bkTags[bk.Url] = collection.Collect(strings.Split(bk.Tags, ",")).
Unique().Filter(func(item, val interface{}) bool {
// Filter out empty ("") strings
if v, ok := val.(string); ok {
if v == "" {
return false
}
}
return true
}).ToStringArray()
}
assert.Equal(t, data.bookmarkTags, bkTags)
// t.Error("urls with their matching tags")
2022-12-11 22:06:07 +00:00
t.Run("should find all bookmarks that have tags AND within folders", func (t *testing.T){
for _, bk := range bookmarks{
if bk.Url == "https://www.fsf.org/" {
// should have `libre` tag and `Mobile Bookmarks` folder
assert.Equal(t, bk.ParentFolder, "mobile")
}
}
})
})
})
runPlacesTest("load bookmarks in node tree", t, func(t *testing.T){
bookmarks, err := ff.scanBookmarks()
if err != nil {
t.Error(err)
}
t.Run("find every url in the node tree", func(t *testing.T){
for _, bk := range bookmarks {
node, exists := ff.URLIndex.Get(bk.Url)
assert.True(t, exists, "url missing in URLIndex")
assert.True(t, tree.FindNode(node.(*tree.Node), ff.NodeTree), "url node missing from tree")
}
})
t.Run("url underneath the right folders", func(t *testing.T){
for _, bk := range bookmarks {
// folder, folderScanned := ff.folderScanMap[bk.ParentId]
// assert.True(t, folderScanned)
// Get the folder from tree node
folderNode, folderExists := ff.folderMap[bk.ParentId]
assert.True(t, folderExists)
urlNode, exists := ff.URLIndex.Get(bk.Url)
assert.True(t, exists, "url missing in URLIndex")
assert.Equal(t, urlNode.(*tree.Node).Parent.Name, bk.ParentFolder,
"wrong folder for <%s>", bk.Url)
// FIX: a url can be child of tag as well, we need to test if
// parent is a folder and right parent it will not be possible
// to have a url as child at 2 different spots as a node cannot
// have two parents
assert.True(t, urlNode.(*tree.Node).DirectChildOf(folderNode),
"missing folder for %s", bk.Url)
}
2022-12-10 01:49:30 +00:00
})
2022-12-11 22:06:07 +00:00
// tree.PrintTree(ff.NodeTree)
2022-12-10 01:49:30 +00:00
})
2022-11-24 20:25:05 +00:00
}
2022-12-05 22:21:23 +00:00
func Test_scanFolders(t *testing.T) {
2022-12-10 01:49:30 +00:00
logging.SetMode(-1)
folders := []string{
"menu", // Bookmarks Menu
"toolbar", // Bookmarks Toolbar
"tags", // Tags Virtual Folder
"unfiled", // Other Bookmarks
"mobile", // Mobile Bookmarks
2022-12-05 22:21:23 +00:00
"Mozilla Firefox",
2022-12-10 01:49:30 +00:00
"cooking",
"Travel",
"indian",
"GomarkMenu",
}
runPlacesTest("scan all folders", t, func(t *testing.T) {
// query all folders
2022-12-11 22:06:07 +00:00
scannedFolders, err := ff.scanFolders()
2022-12-10 01:49:30 +00:00
if err != nil {
t.Error(err)
}
2022-12-05 22:21:23 +00:00
// test that we loaded all folders
folderS := []string{}
for _, f := range scannedFolders {
folderS = utils.Extends(folderS, f.Title)
}
assert.ElementsMatch(t, folders, folderS)
2022-12-10 01:49:30 +00:00
// testing the tree
// folderMap should have 9 entries (id=4 is reserved for tags)
assert.Equal(t, len(ff.folderMap), 9, "not all nodes present in folderMap")
// test that folders are loaded into tree
// All folders can reach the root ancestor
for _, f := range ff.folderMap{
assert.Equal(t, ff.NodeTree, tree.Ancestor(f), "all folders attached to root")
//TEST: every folder in folderMap has a corresponding node in the tree
assert.True(t, tree.FindNode(f, ff.NodeTree), "folder nodes are attached to tree")
}
2022-12-05 22:21:23 +00:00
})
2022-11-24 20:25:05 +00:00
}
2022-11-24 20:25:05 +00:00
func Test_FindChangedBookmarks(t *testing.T) {
2022-12-05 22:21:23 +00:00
t.Error("should find all bookmarks modified/added since last change")
2022-11-24 20:25:05 +00:00
}