useQueryInsightsIssues.utils.test.ts101 lines · main
1import { safeSql } from '@supabase/pg-meta'
2import { describe, expect, it, vi } from 'vitest'
3
4import { hasIndexRecommendations } from '../../QueryPerformance/IndexAdvisor/index-advisor.utils'
5import type { QueryPerformanceRow } from '../../QueryPerformance/QueryPerformance.types'
6import { classifyQuery } from './useQueryInsightsIssues.utils'
7
8vi.mock('../../QueryPerformance/IndexAdvisor/index-advisor.utils', () => ({
9 hasIndexRecommendations: vi.fn(),
10}))
11
12const baseRow: QueryPerformanceRow = {
13 query: safeSql`SELECT * FROM users`,
14 calls: 10,
15 mean_time: 50,
16 min_time: 10,
17 max_time: 200,
18 total_time: 500,
19 prop_total_time: 5,
20 rows_read: 100,
21 cache_hit_rate: 1,
22 rolname: 'postgres',
23 application_name: 'test',
24 index_advisor_result: null,
25 _total_cache_hits: 0,
26 _total_cache_misses: 0,
27}
28
29describe('classifyQuery', () => {
30 it('returns error when index_advisor_result has errors', () => {
31 const row = {
32 ...baseRow,
33 index_advisor_result: {
34 errors: ['some error'],
35 index_statements: [],
36 startup_cost_before: 0,
37 startup_cost_after: 0,
38 total_cost_before: 0,
39 total_cost_after: 0,
40 },
41 }
42 const result = classifyQuery(row)
43 expect(result.issueType).toBe('error')
44 expect(result.hint).toBe('some error')
45 })
46
47 it('returns index when hasIndexRecommendations is true', () => {
48 vi.mocked(hasIndexRecommendations).mockReturnValue(true)
49 const row = {
50 ...baseRow,
51 index_advisor_result: {
52 errors: [],
53 index_statements: [safeSql`CREATE INDEX ...`],
54 startup_cost_before: 0,
55 startup_cost_after: 0,
56 total_cost_before: 0,
57 total_cost_after: 0,
58 },
59 }
60 const result = classifyQuery(row)
61 expect(result.issueType).toBe('index')
62 expect(result.hint).toContain('Missing index')
63 vi.mocked(hasIndexRecommendations).mockReset()
64 })
65
66 it('returns slow when mean_time exceeds threshold', () => {
67 vi.mocked(hasIndexRecommendations).mockReturnValue(false)
68 const row = { ...baseRow, mean_time: 300 }
69 const result = classifyQuery(row)
70 expect(result.issueType).toBe('slow')
71 expect(result.hint).toBe('Abnormally slow query detected')
72 vi.mocked(hasIndexRecommendations).mockReset()
73 })
74
75 it('returns null issue for healthy queries', () => {
76 vi.mocked(hasIndexRecommendations).mockReturnValue(false)
77 const row = { ...baseRow, mean_time: 50 }
78 const result = classifyQuery(row)
79 expect(result.issueType).toBeNull()
80 expect(result.hint).toBe('')
81 vi.mocked(hasIndexRecommendations).mockReset()
82 })
83
84 it('errors take priority over index recommendations', () => {
85 vi.mocked(hasIndexRecommendations).mockReturnValue(true)
86 const row = {
87 ...baseRow,
88 index_advisor_result: {
89 errors: ['critical error'],
90 index_statements: [safeSql`CREATE INDEX ...`],
91 startup_cost_before: 0,
92 startup_cost_after: 0,
93 total_cost_before: 0,
94 total_cost_after: 0,
95 },
96 }
97 const result = classifyQuery(row)
98 expect(result.issueType).toBe('error')
99 vi.mocked(hasIndexRecommendations).mockReset()
100 })
101})