orgs.test.ts52 lines · main
1import { describe, expect, test } from 'bun:test';
2
3import { ORG_LIMIT_BY_TIER, slugFromEmail } from './orgs.js';
4
5describe('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
28describe('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});