fix(config): preserve explicit mention_only=false in GroupTriggerConfig
GroupTriggerConfig.MentionOnly was tagged `json:"mention_only,omitempty"`.
Because Go's bool zero value is false, `omitempty` silently drops the field
whenever a user sets it to false. On the next LoadConfig, the missing field
is filled from defaultChannels() (defaults.go:483-484), which hardcodes
`{"mention_only": true}` for channels like LINE and Matrix. LoadConfig then
calls `defer SaveConfig(...)` on any migration branch (config.go:1042,
1083, 1122), writing `true` back to disk.
Net effect: users who explicitly opt out of mention-only mode see their
setting silently revert to true after any upgrade or version migration.
DiscordConfig.MentionOnly already uses the plain `json:"mention_only"` tag
for this reason; this change aligns GroupTriggerConfig with the same
convention.
Add a regression test that fails pre-patch (JSON round-trips to `{}`) and
passes post-patch (explicit false survives marshal/unmarshal).
This commit is contained in:
parent
72f30c58e9
commit
f13b37309d
2 changed files with 49 additions and 1 deletions
|
|
@ -307,7 +307,12 @@ func (d *AgentDefaults) GetModelName() string {
|
|||
|
||||
// GroupTriggerConfig controls when the bot responds in group chats.
|
||||
type GroupTriggerConfig struct {
|
||||
MentionOnly bool `json:"mention_only,omitempty"`
|
||||
// MentionOnly must always serialize so an explicit `false` survives the
|
||||
// LoadConfig → SaveConfig roundtrip in migration paths (config.go:1042,
|
||||
// 1083, 1122). With `,omitempty`, Go would omit the bool zero value and
|
||||
// defaultChannels() would re-inject the hardcoded `true` default
|
||||
// (defaults.go:483-484), silently reverting the user's choice.
|
||||
MentionOnly bool `json:"mention_only"`
|
||||
Prefixes []string `json:"prefixes,omitempty"`
|
||||
}
|
||||
|
||||
|
|
|
|||
43
pkg/config/group_trigger_mention_only_test.go
Normal file
43
pkg/config/group_trigger_mention_only_test.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestGroupTriggerConfig_MentionOnly_False_Roundtrips documents the regression
|
||||
// where an explicit `mention_only: false` is silently lost on a JSON roundtrip
|
||||
// because the struct tag `json:"mention_only,omitempty"` causes Go to omit the
|
||||
// field whenever its value equals the bool zero value (false).
|
||||
//
|
||||
// Chain of damage in production:
|
||||
// 1. User edits config.json and sets "mention_only": false.
|
||||
// 2. Gateway loads config → LoadConfig triggers defer SaveConfig on any
|
||||
// migration path (config.go:1042/1083/1122).
|
||||
// 3. SaveConfig re-marshals the struct. `,omitempty` drops the false field.
|
||||
// 4. The next load merges with defaultChannels() (defaults.go:483-484),
|
||||
// which hardcodes `{"mention_only": true}` for the "line" channel.
|
||||
// 5. User's explicit false silently becomes true.
|
||||
//
|
||||
// The fix is to remove `,omitempty` from the tag so false always serializes,
|
||||
// matching the pattern already used by DiscordConfig.MentionOnly (no omitempty).
|
||||
func TestGroupTriggerConfig_MentionOnly_False_Roundtrips(t *testing.T) {
|
||||
original := GroupTriggerConfig{MentionOnly: false}
|
||||
|
||||
data, err := json.Marshal(original)
|
||||
require.NoError(t, err)
|
||||
|
||||
// The bug: with `,omitempty`, the false field is omitted entirely, so the
|
||||
// JSON becomes "{}" and the user's explicit choice is indistinguishable
|
||||
// from "never set". A caller that fills in defaults for missing fields
|
||||
// will then replace false with true.
|
||||
assert.Contains(t, string(data), `"mention_only":false`,
|
||||
"explicit false must serialize — otherwise defaults logic overwrites it; see defaults.go:483-484")
|
||||
|
||||
var decoded GroupTriggerConfig
|
||||
require.NoError(t, json.Unmarshal(data, &decoded))
|
||||
assert.False(t, decoded.MentionOnly, "mention_only should survive roundtrip as false")
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue