Linter.utils.test.tsx68 lines · main
| 1 | import { describe, expect, it } from 'vitest' |
| 2 | |
| 3 | import { lintInfoMap } from './Linter.utils' |
| 4 | import { Lint } from '@/data/lint/lint-query' |
| 5 | |
| 6 | const projectRef = 'abc' |
| 7 | const trickySchema = 'a&b=c' |
| 8 | const trickyName = 'd e+f' |
| 9 | |
| 10 | describe('Linter.utils lintInfoMap link encoding', () => { |
| 11 | const cases: Array<{ name: string; nameParam?: string; hasSchema: boolean }> = [ |
| 12 | { name: 'unindexed_foreign_keys', hasSchema: true }, |
| 13 | { name: 'unused_index', nameParam: 'table', hasSchema: true }, |
| 14 | { name: 'multiple_permissive_policies', nameParam: 'search', hasSchema: true }, |
| 15 | { name: 'policy_exists_rls_disabled', nameParam: 'search', hasSchema: true }, |
| 16 | { name: 'rls_enabled_no_policy', nameParam: 'search', hasSchema: true }, |
| 17 | { name: 'duplicate_index', nameParam: 'table', hasSchema: true }, |
| 18 | { name: 'function_search_path_mutable', nameParam: 'search', hasSchema: true }, |
| 19 | { name: 'rls_disabled_in_public', nameParam: 'search', hasSchema: true }, |
| 20 | { name: 'extension_in_public', nameParam: 'filter', hasSchema: false }, |
| 21 | { name: 'sensitive_columns_exposed', nameParam: 'table', hasSchema: true }, |
| 22 | { name: 'rls_policy_always_true', nameParam: 'search', hasSchema: true }, |
| 23 | { name: 'pg_graphql_anon_table_exposed', nameParam: 'table', hasSchema: true }, |
| 24 | { name: 'pg_graphql_authenticated_table_exposed', nameParam: 'table', hasSchema: true }, |
| 25 | { name: 'anon_security_definer_function_executable', nameParam: 'search', hasSchema: true }, |
| 26 | { |
| 27 | name: 'authenticated_security_definer_function_executable', |
| 28 | nameParam: 'search', |
| 29 | hasSchema: true, |
| 30 | }, |
| 31 | ] |
| 32 | |
| 33 | for (const { name, nameParam, hasSchema } of cases) { |
| 34 | it(`preserves special characters in metadata for ${name}`, () => { |
| 35 | const info = lintInfoMap.find((entry) => entry.name === name) |
| 36 | expect(info, `expected ${name} in lintInfoMap`).toBeDefined() |
| 37 | |
| 38 | const url = info!.link({ |
| 39 | projectRef, |
| 40 | metadata: { |
| 41 | schema: trickySchema, |
| 42 | name: trickyName, |
| 43 | } as unknown as Lint['metadata'], |
| 44 | }) |
| 45 | |
| 46 | const parsed = new URL(url, 'http://example.com') |
| 47 | |
| 48 | if (hasSchema) { |
| 49 | expect(parsed.searchParams.get('schema')).toBe(trickySchema) |
| 50 | } |
| 51 | if (nameParam) { |
| 52 | expect(parsed.searchParams.get(nameParam)).toBe(trickyName) |
| 53 | } |
| 54 | }) |
| 55 | } |
| 56 | |
| 57 | it('preserves slash and space in bucket_id for public_bucket_allows_listing', () => { |
| 58 | const info = lintInfoMap.find((entry) => entry.name === 'public_bucket_allows_listing') |
| 59 | expect(info).toBeDefined() |
| 60 | const url = info!.link({ |
| 61 | projectRef, |
| 62 | metadata: { |
| 63 | bucket_id: 'a/b c', |
| 64 | } as unknown as Lint['metadata'], |
| 65 | }) |
| 66 | expect(url).toBe('/project/abc/storage/files/buckets/a%2Fb%20c') |
| 67 | }) |
| 68 | }) |