Skip to content

Commit 0742498

Browse files
committed
Reject --due "" with --starts-on; add starts_on smoke assertion
Move the clearDue+startsOn conflict check after clear detection so --due "" --starts-on "value" is caught alongside --no-due --starts-on. Add missing starts_on assertion to the field preservation smoke test.
1 parent 9637ea2 commit 0742498

3 files changed

Lines changed: 16 additions & 5 deletions

File tree

e2e/smoke/smoke_todos_write.bats

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ setup_file() {
116116
assert_success
117117
assert_json_value '.data.content' 'Renamed title'
118118
assert_json_value '.data.due_on' '2026-06-15'
119+
assert_json_value '.data.starts_on' '2026-06-01'
119120
assert_json_value '.data.description' 'Original description'
120121

121122
# Clean up

internal/commands/todos.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -996,16 +996,17 @@ Clear a field by passing its --no- flag or an empty value:
996996
if noDescription && strings.TrimSpace(description) != "" {
997997
return output.ErrUsage("--no-description and --description cannot be used together")
998998
}
999-
if noDue && strings.TrimSpace(startsOn) != "" {
1000-
return output.ErrUsage("--no-due and --starts-on cannot be used together (Basecamp requires a due date when a start date is set)")
1001-
}
1002-
1003999
// Detect clear intent: explicit --no-X flag or empty value via --X ""
10041000
clearDue := noDue || (cmd.Flags().Changed("due") && strings.TrimSpace(due) == "")
10051001
clearStarts := noStartsOn || (cmd.Flags().Changed("starts-on") && strings.TrimSpace(startsOn) == "")
10061002
clearDescription := noDescription || (cmd.Flags().Changed("description") && strings.TrimSpace(description) == "")
10071003
needsClear := clearDue || clearStarts || clearDescription
10081004

1005+
// Clearing due while setting starts is contradictory (Basecamp enforces starts <= due)
1006+
if clearDue && strings.TrimSpace(startsOn) != "" {
1007+
return output.ErrUsage("cannot clear due date and set start date together (Basecamp requires a due date when a start date is set)")
1008+
}
1009+
10091010
// Positional title: args[1:] joined
10101011
positionalTitle := strings.Join(args[1:], " ")
10111012

internal/commands/todos_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1635,7 +1635,16 @@ func TestTodosUpdateConflictingNoDueAndStartsOn(t *testing.T) {
16351635
cmd := NewTodosCmd()
16361636
err := executeTodosCommand(cmd, app, "update", "999", "--no-due", "--starts-on", "next monday")
16371637
require.Error(t, err)
1638-
assert.Contains(t, err.Error(), "--no-due and --starts-on cannot be used together")
1638+
assert.Contains(t, err.Error(), "cannot clear due date and set start date together")
1639+
}
1640+
1641+
func TestTodosUpdateConflictingEmptyDueAndStartsOn(t *testing.T) {
1642+
app, _ := setupTodosTestApp(t)
1643+
1644+
cmd := NewTodosCmd()
1645+
err := executeTodosCommand(cmd, app, "update", "999", "--due", "", "--starts-on", "next monday")
1646+
require.Error(t, err)
1647+
assert.Contains(t, err.Error(), "cannot clear due date and set start date together")
16391648
}
16401649

16411650
func TestTodosUpdateClearWithSetCombined(t *testing.T) {

0 commit comments

Comments
 (0)