JitDbAccess.utils.test.ts152 lines · main
1import dayjs from 'dayjs'
2import { describe, expect, it } from 'vitest'
3
4import type { JitUserRuleDraft } from './JitDbAccess.types'
5import {
6 computeStatusFromGrants,
7 createEmptyGrant,
8 getInvalidIpRangeRows,
9 getJitMemberOptions,
10 getRelativeDatetimeByMode,
11 serializeDraftRolesForGrantMutation,
12} from './JitDbAccess.utils'
13import type { OrganizationMembersData } from '@/data/organizations/organization-members-query'
14
15describe('jitDbAccess.utils', () => {
16 it('returns empty expiry string for never/custom-only fallback modes', () => {
17 expect(getRelativeDatetimeByMode('never')).toBe('')
18 expect(getRelativeDatetimeByMode('custom')).toBe('')
19 })
20
21 it('creates future datetimes for preset expiry modes', () => {
22 const inOneHour = dayjs(getRelativeDatetimeByMode('1h'))
23 expect(inOneHour.isValid()).toBe(true)
24 expect(inOneHour.isAfter(dayjs())).toBe(true)
25 })
26
27 it('computes active and expired status counts including IP counts', () => {
28 const activeGrant = {
29 ...createEmptyGrant('role_active'),
30 enabled: true,
31 hasExpiry: true,
32 expiry: dayjs().add(1, 'day').toISOString(),
33 ipRanges: [{ value: '192.0.2.0/24' }],
34 }
35
36 const expiredGrant = {
37 ...createEmptyGrant('role_expired'),
38 enabled: true,
39 hasExpiry: true,
40 expiry: dayjs().subtract(1, 'day').toISOString(),
41 ipRanges: [{ value: '203.0.113.0/24' }],
42 }
43
44 const perpetualGrant = {
45 ...createEmptyGrant('role_never'),
46 enabled: true,
47 hasExpiry: false,
48 expiryMode: 'never' as const,
49 expiry: '',
50 }
51
52 expect(computeStatusFromGrants([activeGrant, expiredGrant, perpetualGrant])).toEqual({
53 active: 2,
54 expired: 1,
55 activeIp: 1,
56 expiredIp: 1,
57 })
58 })
59
60 it('returns invalid CIDRs from repeated input rows', () => {
61 expect(
62 getInvalidIpRangeRows([
63 { value: '192.0.2.0/24' },
64 { value: 'not-a-cidr' },
65 { value: '10.0.0.1/33' },
66 { value: '2001:db8::/64' },
67 { value: '2001:db8::/129' },
68 ])
69 ).toEqual(['not-a-cidr', '10.0.0.1/33', '2001:db8::/129'])
70 })
71})
72
73describe('serializeDraftRolesForGrantMutation', () => {
74 it('serializes role expiry and IP restrictions for grant mutation payload', () => {
75 const expiry = '2026-06-01T12:00:00.000Z'
76 const draft: JitUserRuleDraft = {
77 memberId: 'user-1',
78 grants: [
79 {
80 ...createEmptyGrant('postgres'),
81 enabled: true,
82 branchesOnly: true,
83 hasExpiry: true,
84 expiryMode: 'custom',
85 expiry,
86 ipRanges: [{ value: '192.0.2.0/24' }, { value: ' ' }, { value: '2001:db8::/64' }],
87 },
88 {
89 ...createEmptyGrant('briven_read_only_user'),
90 enabled: true,
91 hasExpiry: false,
92 expiryMode: 'never',
93 expiry: '',
94 },
95 {
96 ...createEmptyGrant('ignored_disabled'),
97 enabled: false,
98 },
99 ],
100 }
101
102 expect(serializeDraftRolesForGrantMutation(draft)).toEqual([
103 {
104 role: 'postgres',
105 branches_only: true,
106 expires_at: dayjs(expiry).unix(),
107 allowed_networks: {
108 allowed_cidrs: [{ cidr: '192.0.2.0/24' }],
109 allowed_cidrs_v6: [{ cidr: '2001:db8::/64' }],
110 },
111 },
112 {
113 role: 'briven_read_only_user',
114 },
115 ])
116 })
117})
118
119describe('getJitMemberOptions', () => {
120 it('excludes invited org members without gotrue IDs from selectable options', () => {
121 const organizationMembers: OrganizationMembersData = [
122 {
123 gotrue_id: 'de305d54-75b4-431b-adb2-eb6b9e546014',
124 primary_email: 'active@example.com',
125 username: 'Active User',
126 is_sso_user: false,
127 mfa_enabled: false,
128 metadata: {},
129 role_ids: [],
130 },
131 {
132 gotrue_id: '',
133 invited_id: 123,
134 invited_at: '2026-03-01T00:00:00.000Z',
135 primary_email: 'expired-invite@example.com',
136 username: 'e',
137 is_sso_user: false,
138 mfa_enabled: false,
139 metadata: {},
140 role_ids: [],
141 },
142 ]
143
144 expect(getJitMemberOptions(organizationMembers, [])).toEqual([
145 {
146 id: 'de305d54-75b4-431b-adb2-eb6b9e546014',
147 email: 'active@example.com',
148 name: 'Active User',
149 },
150 ])
151 })
152})