wip: zen lite

This commit is contained in:
Frank
2026-02-24 04:45:39 -05:00
parent cda2af2589
commit fb6d201ee0
41 changed files with 4127 additions and 432 deletions

View File

@@ -0,0 +1,76 @@
import { describe, expect, test } from "bun:test"
import { getWeekBounds, getMonthlyBounds } from "../src/util/date"
describe("util.date.getWeekBounds", () => {
test("returns a Monday-based week for Sunday dates", () => {
const date = new Date("2026-01-18T12:00:00Z")
const bounds = getWeekBounds(date)
expect(bounds.start.toISOString()).toBe("2026-01-12T00:00:00.000Z")
expect(bounds.end.toISOString()).toBe("2026-01-19T00:00:00.000Z")
})
test("returns a seven day window", () => {
const date = new Date("2026-01-14T12:00:00Z")
const bounds = getWeekBounds(date)
const span = bounds.end.getTime() - bounds.start.getTime()
expect(span).toBe(7 * 24 * 60 * 60 * 1000)
})
})
describe("util.date.getMonthlyBounds", () => {
test("resets on subscription day mid-month", () => {
const now = new Date("2026-03-20T10:00:00Z")
const subscribed = new Date("2026-01-15T08:00:00Z")
const bounds = getMonthlyBounds(now, subscribed)
expect(bounds.start.toISOString()).toBe("2026-03-15T08:00:00.000Z")
expect(bounds.end.toISOString()).toBe("2026-04-15T08:00:00.000Z")
})
test("before subscription day in current month uses previous month anchor", () => {
const now = new Date("2026-03-10T10:00:00Z")
const subscribed = new Date("2026-01-15T08:00:00Z")
const bounds = getMonthlyBounds(now, subscribed)
expect(bounds.start.toISOString()).toBe("2026-02-15T08:00:00.000Z")
expect(bounds.end.toISOString()).toBe("2026-03-15T08:00:00.000Z")
})
test("clamps day for short months", () => {
const now = new Date("2026-03-01T10:00:00Z")
const subscribed = new Date("2026-01-31T12:00:00Z")
const bounds = getMonthlyBounds(now, subscribed)
expect(bounds.start.toISOString()).toBe("2026-02-28T12:00:00.000Z")
expect(bounds.end.toISOString()).toBe("2026-03-31T12:00:00.000Z")
})
test("handles subscription on the 1st", () => {
const now = new Date("2026-04-15T00:00:00Z")
const subscribed = new Date("2026-01-01T00:00:00Z")
const bounds = getMonthlyBounds(now, subscribed)
expect(bounds.start.toISOString()).toBe("2026-04-01T00:00:00.000Z")
expect(bounds.end.toISOString()).toBe("2026-05-01T00:00:00.000Z")
})
test("exactly on the reset boundary uses current period", () => {
const now = new Date("2026-03-15T08:00:00Z")
const subscribed = new Date("2026-01-15T08:00:00Z")
const bounds = getMonthlyBounds(now, subscribed)
expect(bounds.start.toISOString()).toBe("2026-03-15T08:00:00.000Z")
expect(bounds.end.toISOString()).toBe("2026-04-15T08:00:00.000Z")
})
test("february to march with day 30 subscription", () => {
const now = new Date("2026-02-15T06:00:00Z")
const subscribed = new Date("2025-12-30T06:00:00Z")
const bounds = getMonthlyBounds(now, subscribed)
expect(bounds.start.toISOString()).toBe("2026-01-30T06:00:00.000Z")
expect(bounds.end.toISOString()).toBe("2026-02-28T06:00:00.000Z")
})
})

View File

@@ -0,0 +1,106 @@
import { describe, expect, test, setSystemTime, afterEach } from "bun:test"
import { Subscription } from "../src/subscription"
import { centsToMicroCents } from "../src/util/price"
afterEach(() => {
setSystemTime()
})
describe("Subscription.analyzeMonthlyUsage", () => {
const subscribed = new Date("2026-01-15T08:00:00Z")
test("returns ok with 0% when usage was last updated before current period", () => {
setSystemTime(new Date("2026-03-20T10:00:00Z"))
const result = Subscription.analyzeMonthlyUsage({
limit: 10,
usage: centsToMicroCents(500),
timeUpdated: new Date("2026-02-10T00:00:00Z"),
timeSubscribed: subscribed,
})
expect(result.status).toBe("ok")
expect(result.usagePercent).toBe(0)
// reset should be seconds until 2026-04-15T08:00:00Z
const expected = Math.ceil(
(new Date("2026-04-15T08:00:00Z").getTime() - new Date("2026-03-20T10:00:00Z").getTime()) / 1000,
)
expect(result.resetInSec).toBe(expected)
})
test("returns ok with usage percent when under limit", () => {
setSystemTime(new Date("2026-03-20T10:00:00Z"))
const limit = 10 // $10
const half = centsToMicroCents(10 * 100) / 2
const result = Subscription.analyzeMonthlyUsage({
limit,
usage: half,
timeUpdated: new Date("2026-03-18T00:00:00Z"),
timeSubscribed: subscribed,
})
expect(result.status).toBe("ok")
expect(result.usagePercent).toBe(50)
})
test("returns rate-limited when at or over limit", () => {
setSystemTime(new Date("2026-03-20T10:00:00Z"))
const limit = 10
const result = Subscription.analyzeMonthlyUsage({
limit,
usage: centsToMicroCents(limit * 100),
timeUpdated: new Date("2026-03-18T00:00:00Z"),
timeSubscribed: subscribed,
})
expect(result.status).toBe("rate-limited")
expect(result.usagePercent).toBe(100)
})
test("resets usage when crossing monthly boundary", () => {
// subscribed on 15th, now is April 16th — period is Apr 15 to May 15
// timeUpdated is March 20 (previous period)
setSystemTime(new Date("2026-04-16T10:00:00Z"))
const result = Subscription.analyzeMonthlyUsage({
limit: 10,
usage: centsToMicroCents(10 * 100),
timeUpdated: new Date("2026-03-20T00:00:00Z"),
timeSubscribed: subscribed,
})
expect(result.status).toBe("ok")
expect(result.usagePercent).toBe(0)
})
test("caps usage percent at 100", () => {
setSystemTime(new Date("2026-03-20T10:00:00Z"))
const limit = 10
const result = Subscription.analyzeMonthlyUsage({
limit,
usage: centsToMicroCents(limit * 100) - 1,
timeUpdated: new Date("2026-03-18T00:00:00Z"),
timeSubscribed: subscribed,
})
expect(result.status).toBe("ok")
expect(result.usagePercent).toBeLessThanOrEqual(100)
})
test("handles subscription day 31 in short month", () => {
const sub31 = new Date("2026-01-31T12:00:00Z")
// now is March 1 — period should be Feb 28 to Mar 31
setSystemTime(new Date("2026-03-01T10:00:00Z"))
const result = Subscription.analyzeMonthlyUsage({
limit: 10,
usage: 0,
timeUpdated: new Date("2026-03-01T09:00:00Z"),
timeSubscribed: sub31,
})
expect(result.status).toBe("ok")
expect(result.usagePercent).toBe(0)
const expected = Math.ceil(
(new Date("2026-03-31T12:00:00Z").getTime() - new Date("2026-03-01T10:00:00Z").getTime()) / 1000,
)
expect(result.resetInSec).toBe(expected)
})
})