46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { canManageBilling, canManageMembers, canUseFeature, roleRank, seatLimit, slugifyOrg, withinSeats } from '@/lib/org';
|
|
|
|
describe('org roles', () => {
|
|
it('ranks owner > admin > member', () => {
|
|
expect(roleRank('owner')).toBeGreaterThan(roleRank('admin'));
|
|
expect(roleRank('admin')).toBeGreaterThan(roleRank('member'));
|
|
});
|
|
|
|
it('lets owners and admins manage members, but not members', () => {
|
|
expect(canManageMembers('owner')).toBe(true);
|
|
expect(canManageMembers('admin')).toBe(true);
|
|
expect(canManageMembers('member')).toBe(false);
|
|
expect(canManageMembers('nonsense')).toBe(false);
|
|
});
|
|
|
|
it('restricts billing to the owner', () => {
|
|
expect(canManageBilling('owner')).toBe(true);
|
|
expect(canManageBilling('admin')).toBe(false);
|
|
expect(canManageBilling('member')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('seats and features', () => {
|
|
it('caps seats by plan', () => {
|
|
expect(seatLimit('free')).toBe(2);
|
|
expect(seatLimit('pro')).toBe(25);
|
|
expect(withinSeats('free', 1)).toBe(true);
|
|
expect(withinSeats('free', 2)).toBe(false);
|
|
expect(withinSeats('pro', 24)).toBe(true);
|
|
});
|
|
|
|
it('gates reports behind Pro', () => {
|
|
expect(canUseFeature('free', 'reports')).toBe(false);
|
|
expect(canUseFeature('pro', 'reports')).toBe(true);
|
|
expect(canUseFeature('free', 'dashboard')).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('slugifyOrg', () => {
|
|
it('produces a url-safe slug', () => {
|
|
expect(slugifyOrg('Acme Inc.')).toBe('acme-inc');
|
|
expect(slugifyOrg(' Мы ')).toBe('');
|
|
});
|
|
});
|