import { describe, it, expect } from 'vitest' import { buildUpdateQuery, getAllowedColumns } from '../../server/utils/queryBuilder.js' describe('queryBuilder', () => { describe('buildUpdateQuery', () => { it('builds valid UPDATE query for devices', () => { const { query, params } = buildUpdateQuery('devices', null, { name: 'Test Device', lat: 40.7128, }) expect(query).toBe('UPDATE devices SET name = ?, lat = ? WHERE id = ?') expect(params).toEqual(['Test Device', 40.7128]) }) it('builds valid UPDATE query for users', () => { const { query, params } = buildUpdateQuery('users', null, { role: 'admin', identifier: 'testuser', }) expect(query).toBe('UPDATE users SET role = ?, identifier = ? WHERE id = ?') expect(params).toEqual(['admin', 'testuser']) }) it('builds valid UPDATE query for pois', () => { const { query, params } = buildUpdateQuery('pois', null, { label: 'Test POI', lat: 40.7128, lng: -74.0060, }) expect(query).toBe('UPDATE pois SET label = ?, lat = ?, lng = ? WHERE id = ?') expect(params).toEqual(['Test POI', 40.7128, -74.0060]) }) it('returns empty query when no updates', () => { const { query, params } = buildUpdateQuery('devices', null, {}) expect(query).toBe('') expect(params).toEqual([]) }) it('throws error for unknown table', () => { expect(() => { buildUpdateQuery('unknown_table', null, { name: 'test' }) }).toThrow('Unknown table: unknown_table') }) it('throws error for invalid column name', () => { expect(() => { buildUpdateQuery('devices', null, { invalid_column: 'test' }) }).toThrow('Invalid column: invalid_column for table: devices') }) it('prevents SQL injection attempts in column names', () => { expect(() => { buildUpdateQuery('devices', null, { 'name\'; DROP TABLE devices; --': 'test' }) }).toThrow('Invalid column') }) it('allows custom allowedColumns set', () => { const customColumns = new Set(['name', 'custom_field']) const { query, params } = buildUpdateQuery('devices', customColumns, { name: 'Test', custom_field: 'value', }) expect(query).toBe('UPDATE devices SET name = ?, custom_field = ? WHERE id = ?') expect(params).toEqual(['Test', 'value']) }) it('rejects columns not in custom allowedColumns', () => { const customColumns = new Set(['name']) expect(() => { buildUpdateQuery('devices', customColumns, { name: 'Test', lat: 40.7128 }) }).toThrow('Invalid column: lat') }) }) describe('getAllowedColumns', () => { it('returns allowed columns for devices', () => { const columns = getAllowedColumns('devices') expect(columns).toBeInstanceOf(Set) expect(columns.has('name')).toBe(true) expect(columns.has('lat')).toBe(true) expect(columns.has('invalid')).toBe(false) }) it('returns allowed columns for users', () => { const columns = getAllowedColumns('users') expect(columns.has('role')).toBe(true) expect(columns.has('identifier')).toBe(true) }) it('returns allowed columns for pois', () => { const columns = getAllowedColumns('pois') expect(columns.has('label')).toBe(true) expect(columns.has('lat')).toBe(true) }) it('returns empty set for unknown table', () => { const columns = getAllowedColumns('unknown') expect(columns).toBeInstanceOf(Set) expect(columns.size).toBe(0) }) }) })