mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 00:32:40 +00:00
midnightReset gated shame DMs on LastActionDate + a fallback busy check
for active expedition / combat session. Players running on background
autopilot got shamed at midnight: dnd_zone_cmd.go gates markActedToday
on !compact (to keep autopilot out of streak credit), so LastActionDate
stayed stale; and if the autopilot's expedition completed / extracted /
got force-extracted before midnight, the busy check also missed it
(getActiveExpedition only matches status='active').
Switch the reaper to loadAdvDailyActivity — the same oracle the daily
report uses, which unions adventure_activity_log + dnd_zone_run +
dnd_expedition_log. Three explicit branches:
- engaged (LastActionDate today/yesterday or legacy counters bumped)
→ streak bumps, LastActionDate restamped
- activity-without-tap (autopilot beats, expedition log, or live
active expedition/combat as safety net) → hold: no bump, no shame,
no decay
- truly idle → shame DM + streak halve
The old busy branch bumped streak; new behavior holds. Aligns autopilot
days with mid-fight-at-midnight days: both engaged earlier but typed
nothing today, neither pumps the streak.
Tests cover all three branches + the death-window early-return.
146 lines
4.4 KiB
Go
146 lines
4.4 KiB
Go
package plugin
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"gogobee/internal/db"
|
|
|
|
"maunium.net/go/mautrix/id"
|
|
)
|
|
|
|
// TestMidnightReset_Branching exercises the three idle-reaper branches:
|
|
// - engaged: LastActionDate stamped today/yesterday → streak bumps
|
|
// - activity-without-tap: autopilot/background activity logged today but
|
|
// no LastActionDate stamp → streak holds, no shame DM, no decay
|
|
// - truly idle: nothing anywhere → streak halves, StreakDecayed=true
|
|
//
|
|
// Regression guard for the autopilot bug: a player who let the background
|
|
// auto-run walk an expedition all day used to get shamed at midnight because
|
|
// markActedToday is gated on !compact at dnd_zone_cmd.go.
|
|
func TestMidnightReset_Branching(t *testing.T) {
|
|
dir := t.TempDir()
|
|
db.Close()
|
|
if err := db.Init(dir); err != nil {
|
|
t.Fatalf("db.Init: %v", err)
|
|
}
|
|
t.Cleanup(db.Close)
|
|
|
|
today := time.Now().UTC().Format("2006-01-02")
|
|
yesterday := time.Now().UTC().Add(-24 * time.Hour).Format("2006-01-02")
|
|
|
|
mk := func(uid, lastAction string, streak int) id.UserID {
|
|
u := id.UserID(uid)
|
|
if err := createAdvCharacter(u, uid); err != nil {
|
|
t.Fatalf("createAdvCharacter %s: %v", uid, err)
|
|
}
|
|
c, err := loadAdvCharacter(u)
|
|
if err != nil {
|
|
t.Fatalf("load %s: %v", uid, err)
|
|
}
|
|
c.LastActionDate = lastAction
|
|
c.CurrentStreak = streak
|
|
c.BestStreak = streak
|
|
if err := saveAdvCharacter(c); err != nil {
|
|
t.Fatalf("save %s: %v", uid, err)
|
|
}
|
|
return u
|
|
}
|
|
|
|
engaged := mk("@engaged:example", yesterday, 5)
|
|
autopilot := mk("@autopilot:example", "2020-01-01", 7)
|
|
idle := mk("@idle:example", "2020-01-01", 8)
|
|
|
|
// Simulate autopilot activity: a legacy activity-log row dated today.
|
|
// loadAdvDailyActivity unions this in, so the reaper sees the player as
|
|
// "had activity" without their LastActionDate being current.
|
|
if _, err := db.Get().Exec(
|
|
`INSERT INTO adventure_activity_log
|
|
(user_id, activity_type, location, outcome, loot_value, xp_gained, flavor_key, logged_at)
|
|
VALUES (?, 'zone', 'Test Zone', 'in_progress', 0, 0, '', CURRENT_TIMESTAMP)`,
|
|
string(autopilot),
|
|
); err != nil {
|
|
t.Fatalf("insert activity row: %v", err)
|
|
}
|
|
|
|
p := &AdventurePlugin{}
|
|
if err := p.midnightReset(); err != nil {
|
|
t.Fatalf("midnightReset: %v", err)
|
|
}
|
|
|
|
// Engaged → streak bumped, LastActionDate restamped to today, no decay.
|
|
if c, _ := loadAdvCharacter(engaged); c != nil {
|
|
if c.CurrentStreak != 6 {
|
|
t.Errorf("engaged: streak = %d, want 6", c.CurrentStreak)
|
|
}
|
|
if c.LastActionDate != today {
|
|
t.Errorf("engaged: LastActionDate = %q, want %q", c.LastActionDate, today)
|
|
}
|
|
if c.StreakDecayed {
|
|
t.Error("engaged: StreakDecayed = true, want false")
|
|
}
|
|
}
|
|
|
|
// Autopilot → hold. Streak unchanged, LastActionDate stays stale, no decay.
|
|
if c, _ := loadAdvCharacter(autopilot); c != nil {
|
|
if c.CurrentStreak != 7 {
|
|
t.Errorf("autopilot: streak = %d, want 7 (held)", c.CurrentStreak)
|
|
}
|
|
if c.StreakDecayed {
|
|
t.Error("autopilot: StreakDecayed = true, want false (shamed by mistake)")
|
|
}
|
|
if c.LastActionDate == today {
|
|
t.Errorf("autopilot: LastActionDate restamped to today — autopilot must not credit streak via LastActionDate")
|
|
}
|
|
}
|
|
|
|
// Idle → shame DM (no-op without Matrix client) + streak halved + decay flagged.
|
|
if c, _ := loadAdvCharacter(idle); c != nil {
|
|
if c.CurrentStreak != 4 {
|
|
t.Errorf("idle: streak = %d, want 4 (halved from 8)", c.CurrentStreak)
|
|
}
|
|
if !c.StreakDecayed {
|
|
t.Error("idle: StreakDecayed = false, want true")
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestMidnightReset_DeathWindowSkips: a player who died today/yesterday is
|
|
// left untouched — no shame, no streak change, no decay flag.
|
|
func TestMidnightReset_DeathWindowSkips(t *testing.T) {
|
|
dir := t.TempDir()
|
|
db.Close()
|
|
if err := db.Init(dir); err != nil {
|
|
t.Fatalf("db.Init: %v", err)
|
|
}
|
|
t.Cleanup(db.Close)
|
|
|
|
today := time.Now().UTC().Format("2006-01-02")
|
|
|
|
u := id.UserID("@dead:example")
|
|
if err := createAdvCharacter(u, "dead"); err != nil {
|
|
t.Fatalf("createAdvCharacter: %v", err)
|
|
}
|
|
c, _ := loadAdvCharacter(u)
|
|
c.LastActionDate = "2020-01-01"
|
|
c.CurrentStreak = 10
|
|
c.BestStreak = 10
|
|
c.LastDeathDate = today
|
|
if err := saveAdvCharacter(c); err != nil {
|
|
t.Fatalf("save: %v", err)
|
|
}
|
|
|
|
p := &AdventurePlugin{}
|
|
if err := p.midnightReset(); err != nil {
|
|
t.Fatalf("midnightReset: %v", err)
|
|
}
|
|
|
|
got, _ := loadAdvCharacter(u)
|
|
if got.CurrentStreak != 10 {
|
|
t.Errorf("dead: streak = %d, want 10 (untouched)", got.CurrentStreak)
|
|
}
|
|
if got.StreakDecayed {
|
|
t.Error("dead: StreakDecayed = true, want false")
|
|
}
|
|
}
|