@@ -544,17 +544,9 @@ func TestGetMasterKey(t *testing.T) {
544544// ---------------------------------------------------------------------------
545545
546546func TestExtract (t * testing.T ) {
547- // Shared fixture: profile with a real History database.
548547 dir := t .TempDir ()
549548 mkFile (dir , "Default" , "Preferences" )
550-
551- historyDB := createTestDB (t , "History" , urlsSchema ,
552- insertURL ("https://example.com" , "Example" , 5 , 13350000000000000 ),
553- )
554- profileDir := filepath .Join (dir , "Default" )
555- data , err := os .ReadFile (historyDB )
556- require .NoError (t , err )
557- require .NoError (t , os .WriteFile (filepath .Join (profileDir , "History" ), data , 0o644 ))
549+ installFile (t , filepath .Join (dir , "Default" ), setupHistoryDB (t ), "History" )
558550
559551 tests := []struct {
560552 name string
@@ -586,7 +578,8 @@ func TestExtract(t *testing.T) {
586578 result , err := browsers [0 ].Extract ([]types.Category {types .History })
587579 require .NoError (t , err )
588580 require .NotNil (t , result )
589- require .Len (t , result .Histories , 1 )
581+ require .Len (t , result .Histories , 3 )
582+ // setupHistoryDB: Example(200) > GitHub(100) > Go Dev(50)
590583 assert .Equal (t , "Example" , result .Histories [0 ].Title )
591584
592585 if tt .wantRetriever {
@@ -598,6 +591,87 @@ func TestExtract(t *testing.T) {
598591 }
599592}
600593
594+ // ---------------------------------------------------------------------------
595+ // CountEntries
596+ // ---------------------------------------------------------------------------
597+
598+ func TestCountEntries (t * testing.T ) {
599+ dir := t .TempDir ()
600+ mkFile (dir , "Default" , "Preferences" )
601+ installFile (t , filepath .Join (dir , "Default" ), setupHistoryDB (t ), "History" )
602+
603+ browsers , err := NewBrowsers (types.BrowserConfig {
604+ Name : "Test" , Kind : types .Chromium , UserDataDir : dir ,
605+ })
606+ require .NoError (t , err )
607+ require .Len (t , browsers , 1 )
608+
609+ // No retriever set — CountEntries should still work (no decryption needed).
610+ counts , err := browsers [0 ].CountEntries ([]types.Category {types .History , types .Download })
611+ require .NoError (t , err )
612+
613+ assert .Equal (t , 3 , counts [types .History ])
614+ // Download uses a different table in the same file; since we only
615+ // created the urls table (not downloads), the count query will fail
616+ // gracefully and return 0.
617+ assert .Equal (t , 0 , counts [types .Download ])
618+ }
619+
620+ func TestCountEntries_NoRetrieverNeeded (t * testing.T ) {
621+ dir := t .TempDir ()
622+ mkFile (dir , "Default" , "Preferences" )
623+ // Login Data normally needs master key to extract, but CountEntries skips decryption.
624+ installFile (t , filepath .Join (dir , "Default" ), setupLoginDB (t ), "Login Data" )
625+
626+ browsers , err := NewBrowsers (types.BrowserConfig {
627+ Name : "Test" , Kind : types .Chromium , UserDataDir : dir ,
628+ })
629+ require .NoError (t , err )
630+ require .Len (t , browsers , 1 )
631+
632+ // No retriever set — CountEntries succeeds without master key.
633+ counts , err := browsers [0 ].CountEntries ([]types.Category {types .Password })
634+ require .NoError (t , err )
635+ assert .Equal (t , 2 , counts [types .Password ])
636+ }
637+
638+ func TestCountCategory (t * testing.T ) {
639+ t .Run ("History" , func (t * testing.T ) {
640+ path := setupHistoryDB (t )
641+ b := & Browser {cfg : types.BrowserConfig {Kind : types .Chromium }}
642+ assert .Equal (t , 3 , b .countCategory (types .History , path ))
643+ })
644+
645+ t .Run ("Cookie" , func (t * testing.T ) {
646+ path := setupCookieDB (t )
647+ b := & Browser {cfg : types.BrowserConfig {Kind : types .Chromium }}
648+ assert .Equal (t , 2 , b .countCategory (types .Cookie , path ))
649+ })
650+
651+ t .Run ("Bookmark" , func (t * testing.T ) {
652+ path := setupBookmarkJSON (t )
653+ b := & Browser {cfg : types.BrowserConfig {Kind : types .Chromium }}
654+ assert .Equal (t , 3 , b .countCategory (types .Bookmark , path ))
655+ })
656+
657+ t .Run ("Extension_Opera" , func (t * testing.T ) {
658+ path := createTestJSON (t , "Secure Preferences" , `{
659+ "extensions": {
660+ "opsettings": {
661+ "ext1": {"location": 1, "manifest": {"name": "Ext", "version": "1.0"}}
662+ }
663+ }
664+ }` )
665+ b := & Browser {cfg : types.BrowserConfig {Kind : types .ChromiumOpera }}
666+ assert .Equal (t , 1 , b .countCategory (types .Extension , path ))
667+ })
668+
669+ t .Run ("FileNotFound" , func (t * testing.T ) {
670+ b := & Browser {cfg : types.BrowserConfig {Kind : types .Chromium }}
671+ assert .Equal (t , 0 , b .countCategory (types .History , "/nonexistent/path" ))
672+ })
673+ }
674+
601675// ---------------------------------------------------------------------------
602676// SetRetriever: verify *Browser satisfies the interface used by
603677// browser.pickFromConfigs for post-construction retriever injection.
0 commit comments