mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
c650aabbef
My agent added `//nolint:testpackage` to a test file on one of my PRs. Again. This PR cleans it up across the entire repo and updates the in-repo conventions so future agents stop doing it. The repo already has a precedent for white-box tests that need to touch unexported symbols: `*_internal_test.go` (145+ existing files). The `testpackage` linter's default `skip-regexp` exempts that filename suffix, so the `//nolint:testpackage` directive is unnecessary in every case where someone reached for it. This PR renames 51 such files to `*_internal_test.go` via `git mv` so blame and history follow, and strips the dead directive from 2 files that were already correctly named (`coderd/oauth2provider/authorize_internal_test.go`, `coderd/x/chatd/advisor_internal_test.go`). `.claude/docs/TESTING.md` now documents the rule explicitly under *Test Package Naming*, which is imported into the root `AGENTS.md` via `@.claude/docs/TESTING.md`. The rule: prefer `package foo_test`; if you need internal access, rename the file to `*_internal_test.go` rather than adding a nolint directive.
133 lines
4.5 KiB
Go
133 lines
4.5 KiB
Go
package chatd
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/coder/coder/v2/codersdk"
|
|
)
|
|
|
|
func TestComputeUsagePeriodBounds(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
newYork, err := time.LoadLocation("America/New_York")
|
|
if err != nil {
|
|
t.Fatalf("load America/New_York: %v", err)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
now time.Time
|
|
period codersdk.ChatUsageLimitPeriod
|
|
wantStart time.Time
|
|
wantEnd time.Time
|
|
}{
|
|
{
|
|
name: "day/mid_day",
|
|
now: time.Date(2025, time.June, 15, 14, 30, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodDay,
|
|
wantStart: time.Date(2025, time.June, 15, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.June, 16, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "day/midnight_exactly",
|
|
now: time.Date(2025, time.June, 15, 0, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodDay,
|
|
wantStart: time.Date(2025, time.June, 15, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.June, 16, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "day/end_of_day",
|
|
now: time.Date(2025, time.June, 15, 23, 59, 59, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodDay,
|
|
wantStart: time.Date(2025, time.June, 15, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.June, 16, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "week/wednesday",
|
|
now: time.Date(2025, time.June, 11, 10, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodWeek,
|
|
wantStart: time.Date(2025, time.June, 9, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.June, 16, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "week/monday",
|
|
now: time.Date(2025, time.June, 9, 0, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodWeek,
|
|
wantStart: time.Date(2025, time.June, 9, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.June, 16, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "week/sunday",
|
|
now: time.Date(2025, time.June, 15, 23, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodWeek,
|
|
wantStart: time.Date(2025, time.June, 9, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.June, 16, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "week/year_boundary",
|
|
now: time.Date(2024, time.December, 31, 12, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodWeek,
|
|
wantStart: time.Date(2024, time.December, 30, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.January, 6, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "month/mid_month",
|
|
now: time.Date(2025, time.June, 15, 0, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodMonth,
|
|
wantStart: time.Date(2025, time.June, 1, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.July, 1, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "month/first_day",
|
|
now: time.Date(2025, time.June, 1, 0, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodMonth,
|
|
wantStart: time.Date(2025, time.June, 1, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.July, 1, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "month/last_day",
|
|
now: time.Date(2025, time.June, 30, 23, 59, 59, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodMonth,
|
|
wantStart: time.Date(2025, time.June, 1, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.July, 1, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "month/february",
|
|
now: time.Date(2025, time.February, 15, 12, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodMonth,
|
|
wantStart: time.Date(2025, time.February, 1, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.March, 1, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "month/leap_year_february",
|
|
now: time.Date(2024, time.February, 29, 12, 0, 0, 0, time.UTC),
|
|
period: codersdk.ChatUsageLimitPeriodMonth,
|
|
wantStart: time.Date(2024, time.February, 1, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2024, time.March, 1, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
{
|
|
name: "day/non_utc_timezone",
|
|
now: time.Date(2025, time.June, 15, 22, 0, 0, 0, newYork),
|
|
period: codersdk.ChatUsageLimitPeriodDay,
|
|
wantStart: time.Date(2025, time.June, 16, 0, 0, 0, 0, time.UTC),
|
|
wantEnd: time.Date(2025, time.June, 17, 0, 0, 0, 0, time.UTC),
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
tc := tc
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
start, end := ComputeUsagePeriodBounds(tc.now, tc.period)
|
|
if !start.Equal(tc.wantStart) {
|
|
t.Errorf("start: got %v, want %v", start, tc.wantStart)
|
|
}
|
|
if !end.Equal(tc.wantEnd) {
|
|
t.Errorf("end: got %v, want %v", end, tc.wantEnd)
|
|
}
|
|
})
|
|
}
|
|
}
|