| 1 | package analytics |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "errors" |
| 6 | "testing" |
| 7 | "time" |
| 8 | |
| 9 | "github.com/carlosframework/platform/internal/applog" |
| 10 | "github.com/carlosframework/platform/internal/release" |
| 11 | ) |
| 12 | |
| 13 | // TestAnalyticsKeysRefuseEmptyApp: the day-file builders refuse an empty |
| 14 | // app, account, box or date, and UpsertDay refuses before touching the |
| 15 | // store, so nothing lands under apps/<sqid>//analytics/. |
| 16 | func TestAnalyticsKeysRefuseEmptyApp(t *testing.T) { |
| 17 | for _, c := range []struct{ acct, app, box, date string }{ |
| 18 | {"bab", "", "box-a", "2026-10-16"}, |
| 19 | {"", "web", "box-a", "2026-10-16"}, |
| 20 | {"bab", "web", "", "2026-10-16"}, |
| 21 | {"bab", "web", "box-a", ""}, |
| 22 | {"bab", "web", "box-a", "2026/10/16"}, |
| 23 | } { |
| 24 | if k, err := DayKey(c.acct, c.app, c.box, c.date); !errors.Is(err, applog.ErrBadKeySegment) || k != "" { |
| 25 | t.Errorf("DayKey%+v = (%q, %v)", c, k, err) |
| 26 | } |
| 27 | } |
| 28 | if k, err := Prefix("bab", ""); !errors.Is(err, applog.ErrBadKeySegment) || k != "" { |
| 29 | t.Fatalf("Prefix = (%q, %v)", k, err) |
| 30 | } |
| 31 | if k, err := BoxPrefix("bab", "", "box-a"); !errors.Is(err, applog.ErrBadKeySegment) || k != "" { |
| 32 | t.Fatalf("BoxPrefix = (%q, %v)", k, err) |
| 33 | } |
| 34 | ctx := context.Background() |
| 35 | s := release.NewDirStore(t.TempDir()) |
| 36 | err := UpsertDay(ctx, s, "bab", "", Delta{Box: "box-a", Date: "2026-10-16", Seq: 1}) |
| 37 | if !errors.Is(err, applog.ErrBadKeySegment) { |
| 38 | t.Fatalf("UpsertDay = %v", err) |
| 39 | } |
| 40 | if keys, _ := s.List(ctx, "apps/"); len(keys) != 0 { |
| 41 | t.Fatalf("UpsertDay wrote %v", keys) |
| 42 | } |
| 43 | if _, err := ReadRange(ctx, s, "bab", "", time.Now(), time.Now()); !errors.Is(err, applog.ErrBadKeySegment) { |
| 44 | t.Fatalf("ReadRange = %v", err) |
| 45 | } |
| 46 | if got := must(t)(BoxPrefix("bab", "web", "box-a")); got != "apps/bab/web/analytics/box-a/days/" { |
| 47 | t.Fatalf("valid BoxPrefix moved: %q", got) |
| 48 | } |
| 49 | } |
| 50 | |