orgs.test.ts52 lines · main
| 1 | import { describe, expect, test } from 'bun:test'; |
| 2 | |
| 3 | import { ORG_LIMIT_BY_TIER, slugFromEmail } from './orgs.js'; |
| 4 | |
| 5 | describe('ORG_LIMIT_BY_TIER', () => { |
| 6 | test('free caps at 1 (personal only, no team creation)', () => { |
| 7 | expect(ORG_LIMIT_BY_TIER.free).toBe(1); |
| 8 | }); |
| 9 | |
| 10 | test('pro is unlimited — paying users can create as many teams as they need', () => { |
| 11 | // Industry norm: Vercel, GitHub, Netlify all allow unlimited teams |
| 12 | // on paid tiers. Convex doesn't surface a team count at all (their |
| 13 | // pricing is per-developer-seat). Briven matches this convention |
| 14 | // so a Pro subscriber can have multiple separate team workspaces. |
| 15 | expect(ORG_LIMIT_BY_TIER.pro).toBe(Infinity); |
| 16 | }); |
| 17 | |
| 18 | test('team is unlimited', () => { |
| 19 | expect(ORG_LIMIT_BY_TIER.team).toBe(Infinity); |
| 20 | }); |
| 21 | |
| 22 | test('caps are monotonically non-decreasing free → pro → team', () => { |
| 23 | expect(ORG_LIMIT_BY_TIER.free).toBeLessThanOrEqual(ORG_LIMIT_BY_TIER.pro); |
| 24 | expect(ORG_LIMIT_BY_TIER.pro).toBeLessThanOrEqual(ORG_LIMIT_BY_TIER.team); |
| 25 | }); |
| 26 | }); |
| 27 | |
| 28 | describe('slugFromEmail', () => { |
| 29 | test('lowercases and keeps alphanumeric local-part', () => { |
| 30 | expect(slugFromEmail('Alice@example.com')).toBe('alice'); |
| 31 | }); |
| 32 | |
| 33 | test('replaces dots and plus tags with single dashes', () => { |
| 34 | expect(slugFromEmail('alice.smith+work@example.com')).toBe('alice-smith-work'); |
| 35 | }); |
| 36 | |
| 37 | test('strips edge dashes that come from leading/trailing punctuation', () => { |
| 38 | expect(slugFromEmail('-alice-@example.com')).toBe('alice'); |
| 39 | }); |
| 40 | |
| 41 | test('returns empty string for empty local-part', () => { |
| 42 | expect(slugFromEmail('@example.com')).toBe(''); |
| 43 | }); |
| 44 | |
| 45 | test('returns empty string for an entirely non-alnum local-part', () => { |
| 46 | expect(slugFromEmail('...@example.com')).toBe(''); |
| 47 | }); |
| 48 | |
| 49 | test('handles missing @ gracefully (whole input treated as local-part)', () => { |
| 50 | expect(slugFromEmail('plainstring')).toBe('plainstring'); |
| 51 | }); |
| 52 | }); |