Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions tests/password-policy.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { PostgrestError } from '@supabase/supabase-js'
import { randomUUID } from 'node:crypto'
import { afterAll, beforeAll, describe, expect, it } from 'vitest'

Expand Down Expand Up @@ -51,7 +50,7 @@ afterAll(async () => {
await getSupabaseClient().from('stripe_info').delete().eq('customer_id', customerId)
})

describe('Password Policy Configuration via SDK', () => {
describe('password Policy Configuration via SDK', () => {
it('enable password policy with all requirements via direct update', async () => {
const policyConfig = {
enabled: true,
Expand Down Expand Up @@ -278,6 +277,7 @@ describe('[POST] /private/validate_password_compliance', () => {
if (disableError)
throw disableError

let testError: Error | null = null
try {
const response = await fetch(`${BASE_URL}/private/validate_password_compliance`, {
headers,
Expand All @@ -293,13 +293,25 @@ describe('[POST] /private/validate_password_compliance', () => {
const responseData = await response.json() as { error: string }
expect(responseData.error).toBe('no_policy')
}
catch (error) {
testError = error as Error
}
finally {
const { error } = await getSupabaseClient()
const { error: restoreError } = await getSupabaseClient()
.from('orgs')
.update({ password_policy_config: policyConfig })
.eq('id', ORG_ID)
if (error)
throw error

// If restore failed, throw it (but preserve test failure if there was one)
if (restoreError) {
if (testError)
throw new Error(`Test failed AND restore failed: ${testError.message} | Restore error: ${restoreError.message}`)
throw restoreError
Comment on lines 299 to +309
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The finally block can still mask the original test failure if the restore update(...) call rejects/throws (network/client exception) before restoreError is checked. Consider wrapping the restore operation in its own try/catch and, when both the test and restore fail, throw an AggregateError (or use Error with cause) so the original assertion stack trace is preserved instead of replacing it with a new Error built from messages.

Copilot uses AI. Check for mistakes.
}

// Re-throw original test error if any
if (testError)
throw testError
}
})

Expand Down Expand Up @@ -460,7 +472,7 @@ describe('[GET] /private/check_org_members_password_policy', () => {
})
})

describe('Password Policy Enforcement Integration', () => {
describe('password Policy Enforcement Integration', () => {
const orgWithPolicyId = randomUUID()
const orgWithPolicyName = `Pwd Policy Integration Org ${randomUUID()}`
const orgWithPolicyCustomerId = `cus_pwd_int_${orgWithPolicyId}`
Expand Down Expand Up @@ -546,18 +558,28 @@ describe('Password Policy Enforcement Integration', () => {
describe('user_password_compliance table', () => {
it('can insert compliance record via service role', async () => {
// Get the policy hash
const { data: org } = await getSupabaseClient()
const { data: org, error: orgError } = await getSupabaseClient()
.from('orgs')
.select('password_policy_config')
.eq('id', ORG_ID)
.single()

expect(orgError).toBeNull()
expect(org?.password_policy_config).not.toBeNull()
const policyConfig = org?.password_policy_config
if (policyConfig == null)
throw new Error('Expected password_policy_config to be set for test org')

// Use the same RPC that production uses to compute the password policy hash
const { data: rpcResult } = await getSupabaseClient().rpc('get_password_policy_hash', {
policy_config: org?.password_policy_config,
const { data: rpcResult, error: rpcError } = await getSupabaseClient().rpc('get_password_policy_hash', {
policy_config: policyConfig,
})

const policyHash = (rpcResult as string | null) ?? 'test_hash'
expect(rpcError).toBeNull()
expect(rpcResult).not.toBeNull()
expect(typeof rpcResult).toBe('string')
Comment on lines +567 to +580
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expect(org?.password_policy_config).not.toBeNull() and expect(rpcResult).not.toBeNull() will still pass when the value is undefined (because undefined !== null). Use an assertion that also rejects undefined (e.g., assert org is truthy and then access org.password_policy_config, and assert rpcResult is defined/string) so the test fails at the right place with a clear signal.

Copilot uses AI. Check for mistakes.

const policyHash = rpcResult as string

const { error } = await getSupabaseClient()
.from('user_password_compliance')
Expand Down