@@ -394,6 +394,7 @@ func TestRuntimeHelpersAndSubcommands(t *testing.T) {
394394 require .NoError (t , rt .runMembers ([]string {"search" , "pet" }))
395395 require .NoError (t , rt .runMembers ([]string {"list" }))
396396 rt .now = func () time.Time { return time .Date (2026 , 3 , 8 , 12 , 0 , 0 , 0 , time .UTC ) }
397+ require .NoError (t , rt .runMessages ([]string {"--channel" , "#general" , "--hours" , "6" , "--last" , "1" }))
397398 require .NoError (t , rt .runMessages ([]string {"--channel" , "#general" , "--days" , "7" , "--all" }))
398399 require .NoError (t , rt .runMessages ([]string {"--channel" , "#general" , "--days" , "7" , "--all" , "--include-empty" }))
399400 require .NoError (t , rt .runMentions ([]string {"--channel" , "#general" , "--target" , "u2" }))
@@ -405,12 +406,186 @@ func TestRuntimeHelpersAndSubcommands(t *testing.T) {
405406 }))
406407}
407408
409+ func TestRunMembersShowUsesDefaultGuildForAmbiguousQuery (t * testing.T ) {
410+ t .Parallel ()
411+
412+ ctx := context .Background ()
413+ dir := t .TempDir ()
414+ cfgPath := filepath .Join (dir , "config.toml" )
415+ dbPath := filepath .Join (dir , "discrawl.db" )
416+
417+ cfg := config .Default ()
418+ cfg .DBPath = dbPath
419+ cfg .DefaultGuildID = "g1"
420+ require .NoError (t , config .Write (cfgPath , cfg ))
421+
422+ s , err := store .Open (ctx , dbPath )
423+ require .NoError (t , err )
424+ require .NoError (t , s .UpsertChannel (ctx , store.ChannelRecord {ID : "c1" , GuildID : "g1" , Kind : "text" , Name : "general" , RawJSON : `{}` }))
425+ require .NoError (t , s .UpsertMember (ctx , store.MemberRecord {
426+ GuildID : "g1" ,
427+ UserID : "u1" ,
428+ Username : "same" ,
429+ DisplayName : "Same" ,
430+ RoleIDsJSON : `[]` ,
431+ RawJSON : `{"github":"steipete"}` ,
432+ }))
433+ require .NoError (t , s .UpsertMember (ctx , store.MemberRecord {
434+ GuildID : "g2" ,
435+ UserID : "u2" ,
436+ Username : "same" ,
437+ DisplayName : "Same" ,
438+ RoleIDsJSON : `[]` ,
439+ RawJSON : `{"github":"other"}` ,
440+ }))
441+ require .NoError (t , s .UpsertMessage (ctx , store.MessageRecord {
442+ ID : "m1" ,
443+ GuildID : "g1" ,
444+ ChannelID : "c1" ,
445+ ChannelName : "general" ,
446+ AuthorID : "u1" ,
447+ AuthorName : "Same" ,
448+ MessageType : 0 ,
449+ CreatedAt : time .Now ().UTC ().Format (time .RFC3339Nano ),
450+ Content : "hello" ,
451+ NormalizedContent : "hello" ,
452+ RawJSON : `{}` ,
453+ }))
454+ require .NoError (t , s .Close ())
455+
456+ var out bytes.Buffer
457+ rt := & runtime {
458+ ctx : ctx ,
459+ configPath : cfgPath ,
460+ stdout : & out ,
461+ stderr : & bytes.Buffer {},
462+ logger : discardLogger (),
463+ }
464+ require .NoError (t , rt .withServices (false , func () error {
465+ return rt .runMembers ([]string {"show" , "same" })
466+ }))
467+ require .Contains (t , out .String (), "guild=g1" )
468+ require .Contains (t , out .String (), "github=steipete" )
469+ }
470+
471+ func TestRunMembersShowReturnsListWhenStillAmbiguous (t * testing.T ) {
472+ t .Parallel ()
473+
474+ ctx := context .Background ()
475+ dir := t .TempDir ()
476+ cfgPath := filepath .Join (dir , "config.toml" )
477+ dbPath := filepath .Join (dir , "discrawl.db" )
478+
479+ cfg := config .Default ()
480+ cfg .DBPath = dbPath
481+ require .NoError (t , config .Write (cfgPath , cfg ))
482+
483+ s , err := store .Open (ctx , dbPath )
484+ require .NoError (t , err )
485+ require .NoError (t , s .UpsertMember (ctx , store.MemberRecord {GuildID : "g1" , UserID : "u1" , Username : "same" , DisplayName : "Same" , RoleIDsJSON : `[]` , RawJSON : `{}` }))
486+ require .NoError (t , s .UpsertMember (ctx , store.MemberRecord {GuildID : "g2" , UserID : "u2" , Username : "same" , DisplayName : "Same" , RoleIDsJSON : `[]` , RawJSON : `{}` }))
487+ require .NoError (t , s .Close ())
488+
489+ var out bytes.Buffer
490+ rt := & runtime {
491+ ctx : ctx ,
492+ configPath : cfgPath ,
493+ stdout : & out ,
494+ stderr : & bytes.Buffer {},
495+ logger : discardLogger (),
496+ }
497+ require .NoError (t , rt .withServices (false , func () error {
498+ return rt .runMembers ([]string {"show" , "same" })
499+ }))
500+ require .Contains (t , out .String (), "GUILD" )
501+ require .Contains (t , out .String (), "u1" )
502+ require .Contains (t , out .String (), "u2" )
503+ }
504+
505+ func TestRunMessagesSyncTargetsResolvedChannel (t * testing.T ) {
506+ ctx := context .Background ()
507+ dir := t .TempDir ()
508+ cfgPath := filepath .Join (dir , "config.toml" )
509+ dbPath := filepath .Join (dir , "discrawl.db" )
510+ t .Setenv (config .DefaultTokenEnv , "env-token" )
511+
512+ cfg := config .Default ()
513+ cfg .DBPath = dbPath
514+ cfg .DefaultGuildID = "g1"
515+ require .NoError (t , config .Write (cfgPath , cfg ))
516+
517+ s , err := store .Open (ctx , dbPath )
518+ require .NoError (t , err )
519+ require .NoError (t , s .UpsertChannel (ctx , store.ChannelRecord {ID : "c1" , GuildID : "g1" , Kind : "text" , Name : "general" , RawJSON : `{}` }))
520+ require .NoError (t , s .Close ())
521+
522+ fakeSync := & fakeSyncService {}
523+ rt := & runtime {
524+ ctx : ctx ,
525+ configPath : cfgPath ,
526+ stdout : & bytes.Buffer {},
527+ stderr : & bytes.Buffer {},
528+ logger : discardLogger (),
529+ openStore : store .Open ,
530+ newDiscord : func (config.Config ) (discordClient , error ) { return & fakeDiscordClient {}, nil },
531+ newSyncer : func (syncer.Client , * store.Store , * slog.Logger ) syncService {
532+ return fakeSync
533+ },
534+ }
535+ rt .now = func () time.Time { return time .Date (2026 , 3 , 8 , 12 , 0 , 0 , 0 , time .UTC ) }
536+
537+ require .NoError (t , rt .withServices (true , func () error {
538+ return rt .runMessages ([]string {"--channel" , "#general" , "--hours" , "6" , "--last" , "1" , "--sync" })
539+ }))
540+ require .Equal (t , []string {"g1" }, fakeSync .lastSync .GuildIDs )
541+ require .Equal (t , []string {"c1" }, fakeSync .lastSync .ChannelIDs )
542+ }
543+
544+ func TestRunMessagesSyncFallsBackToGuildSyncForUnknownChannel (t * testing.T ) {
545+ ctx := context .Background ()
546+ dir := t .TempDir ()
547+ cfgPath := filepath .Join (dir , "config.toml" )
548+ dbPath := filepath .Join (dir , "discrawl.db" )
549+ t .Setenv (config .DefaultTokenEnv , "env-token" )
550+
551+ cfg := config .Default ()
552+ cfg .DBPath = dbPath
553+ cfg .DefaultGuildID = "g1"
554+ require .NoError (t , config .Write (cfgPath , cfg ))
555+
556+ fakeSync := & fakeSyncService {}
557+ rt := & runtime {
558+ ctx : ctx ,
559+ configPath : cfgPath ,
560+ stdout : & bytes.Buffer {},
561+ stderr : & bytes.Buffer {},
562+ logger : discardLogger (),
563+ openStore : store .Open ,
564+ newDiscord : func (config.Config ) (discordClient , error ) { return & fakeDiscordClient {}, nil },
565+ newSyncer : func (syncer.Client , * store.Store , * slog.Logger ) syncService {
566+ return fakeSync
567+ },
568+ }
569+
570+ require .NoError (t , rt .withServices (true , func () error {
571+ return rt .runMessages ([]string {"--channel" , "new-channel" , "--days" , "1" , "--sync" })
572+ }))
573+ require .Equal (t , []string {"g1" }, fakeSync .lastSync .GuildIDs )
574+ require .Empty (t , fakeSync .lastSync .ChannelIDs )
575+ }
576+
408577func TestRunMentionsValidation (t * testing.T ) {
409578 t .Parallel ()
410579
411580 rt := & runtime {stderr : & bytes.Buffer {}}
412581 rt .now = func () time.Time { return time .Date (2026 , 3 , 8 , 12 , 0 , 0 , 0 , time .UTC ) }
413582
583+ require .Equal (t , 2 , ExitCode (rt .runMessages ([]string {"--hours" , "-1" , "--channel" , "general" })))
584+ require .Equal (t , 2 , ExitCode (rt .runMessages ([]string {"--hours" , "1" , "--days" , "1" , "--channel" , "general" })))
585+ require .Equal (t , 2 , ExitCode (rt .runMessages ([]string {"--hours" , "1" , "--since" , "2026-03-01T00:00:00Z" , "--channel" , "general" })))
586+ require .Equal (t , 2 , ExitCode (rt .runMessages ([]string {"--last" , "-1" , "--channel" , "general" })))
587+ require .Equal (t , 2 , ExitCode (rt .runMessages ([]string {"--last" , "1" , "--limit" , "20" , "--channel" , "general" })))
588+ require .Equal (t , 2 , ExitCode (rt .runMessages ([]string {"--last" , "1" , "--all" , "--channel" , "general" })))
414589 require .Equal (t , 2 , ExitCode (rt .runMentions ([]string {"--days" , "-1" , "--target" , "u1" })))
415590 require .Equal (t , 2 , ExitCode (rt .runMentions ([]string {"--days" , "1" , "--since" , "2026-03-01T00:00:00Z" , "--target" , "u1" })))
416591 require .Equal (t , 2 , ExitCode (rt .runMentions ([]string {"--since" , "bad" , "--target" , "u1" })))
0 commit comments