chore: remediate 61 Go linting issues and tighten pre-commit config
Complete lint remediation addressing errcheck, gosec, and staticcheck violations across backend test files. Tighten pre-commit configuration to prevent future blind spots. Key Changes: - Fix 61 Go linting issues (errcheck, gosec G115/G301/G304/G306, bodyclose) - Add proper error handling for json.Unmarshal, os.Setenv, db.Close(), w.Write() - Fix gosec G115 integer overflow with strconv.FormatUint - Add #nosec annotations with justifications for test fixtures - Fix SecurityService goroutine leaks (add Close() calls) - Fix CrowdSec tar.gz non-deterministic ordering with sorted keys Pre-commit Hardening: - Remove test file exclusion from golangci-lint hook - Add gosec to .golangci-fast.yml with critical checks (G101, G110, G305) - Replace broad .golangci.yml exclusions with targeted path-specific rules - Test files now linted on every commit Test Fixes: - Fix emergency route count assertions (1→2 for dual-port setup) - Fix DNS provider service tests with proper mock setup - Fix certificate service tests with deterministic behavior Backend: 27 packages pass, 83.5% coverage Frontend: 0 lint warnings, 0 TypeScript errors Pre-commit: All 14 hooks pass (~37s)
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
|
||||
import ImportSitesModal from './ImportSitesModal'
|
||||
import { vi } from 'vitest'
|
||||
import { CaddyFile } from '../api/import'
|
||||
|
||||
// Mock the upload API used by the component
|
||||
const mockUpload = vi.fn()
|
||||
vi.mock('../api/import', () => ({
|
||||
uploadCaddyfilesMulti: (...args: unknown[]) => mockUpload(...(args as any[])),
|
||||
uploadCaddyfilesMulti: (files: CaddyFile[]) => mockUpload(files),
|
||||
}))
|
||||
|
||||
describe('ImportSitesModal', () => {
|
||||
|
||||
@@ -40,7 +40,7 @@ export default function ImportSitesModal({ visible, onClose, onUploaded }: Props
|
||||
try {
|
||||
const text = await files[i].text()
|
||||
newSites.push({ filename: files[i].name, content: text })
|
||||
} catch (_err) {
|
||||
} catch {
|
||||
// ignore read errors for individual files
|
||||
newSites.push({ filename: files[i].name, content: '' })
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import userEvent from '@testing-library/user-event'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import DNSProviderForm from '../DNSProviderForm'
|
||||
import { defaultProviderSchemas } from '../../data/dnsProviderSchemas'
|
||||
import type { DNSProvider } from '../../api/dnsProviders'
|
||||
|
||||
// Mock hooks used by DNSProviderForm
|
||||
vi.mock('../../hooks/useDNSProviders', () => ({
|
||||
@@ -47,7 +48,7 @@ describe('DNSProviderForm — Script provider (accessibility)', () => {
|
||||
})
|
||||
|
||||
it('renders Script Path when editing an existing script provider (not required)', async () => {
|
||||
const existingProvider = {
|
||||
const existingProvider: DNSProvider = {
|
||||
id: 1,
|
||||
uuid: 'p-1',
|
||||
name: 'local-script',
|
||||
@@ -64,7 +65,7 @@ describe('DNSProviderForm — Script provider (accessibility)', () => {
|
||||
}
|
||||
|
||||
renderWithClient(
|
||||
<DNSProviderForm open={true} onOpenChange={() => {}} provider={existingProvider as any} onSuccess={() => {}} />
|
||||
<DNSProviderForm open={true} onOpenChange={() => {}} provider={existingProvider} onSuccess={() => {}} />
|
||||
)
|
||||
|
||||
// Since provider prop is provided, providerType should be pre-populated and the field rendered
|
||||
|
||||
@@ -76,9 +76,13 @@ export const AuthProvider: FC<{ children: ReactNode }> = ({ children }) => {
|
||||
old_password: oldPassword,
|
||||
new_password: newPassword,
|
||||
});
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
// Extract error message from API response
|
||||
const message = error.response?.data?.error || error.message || 'Password change failed';
|
||||
const message = error instanceof Error
|
||||
? error.message
|
||||
: typeof error === 'object' && error !== null && 'response' in error
|
||||
? (error as { response?: { data?: { error?: string } } }).response?.data?.error || 'Password change failed'
|
||||
: 'Password change failed';
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import { QueryClientProvider } from '@tanstack/react-query'
|
||||
|
||||
import * as api from '../../api/import'
|
||||
import { useImport } from '../useImport'
|
||||
import type { ImportSession, ImportPreview } from '../../api/import'
|
||||
|
||||
vi.mock('../../api/import', () => ({
|
||||
uploadCaddyfile: vi.fn(),
|
||||
@@ -58,14 +59,18 @@ describe('useImport (unit)', () => {
|
||||
})
|
||||
|
||||
it('enables preview query when session state is pending', async () => {
|
||||
const session = {
|
||||
const session: ImportSession = {
|
||||
id: 's-pending',
|
||||
state: 'pending' as const,
|
||||
state: 'pending',
|
||||
created_at: '2026-01-31T00:00:00.000Z',
|
||||
updated_at: '2026-01-31T00:00:00.000Z',
|
||||
}
|
||||
vi.mocked(api.getImportStatus).mockResolvedValue({ has_pending: true, session })
|
||||
vi.mocked(api.getImportPreview).mockResolvedValue({ session, preview: { hosts: [], conflicts: [], errors: [] } } as any)
|
||||
const mockPreviewResponse: ImportPreview = {
|
||||
session,
|
||||
preview: { hosts: [], conflicts: [], errors: [] }
|
||||
}
|
||||
vi.mocked(api.getImportPreview).mockResolvedValue(mockPreviewResponse)
|
||||
|
||||
const { result } = renderHook(() => useImport(), { wrapper })
|
||||
|
||||
@@ -74,12 +79,12 @@ describe('useImport (unit)', () => {
|
||||
})
|
||||
|
||||
it('upload stores immediate uploadPreview and exposes preview', async () => {
|
||||
const mockPreview = {
|
||||
const mockPreview: ImportPreview = {
|
||||
session: { id: 's1', state: 'reviewing', created_at: '2026-01-31T00:00:00.000Z', updated_at: '2026-01-31T00:00:00.000Z' },
|
||||
preview: { hosts: [], conflicts: [], errors: [] },
|
||||
}
|
||||
vi.mocked(api.getImportStatus).mockResolvedValue({ has_pending: false })
|
||||
vi.mocked(api.uploadCaddyfile).mockResolvedValue(mockPreview as any)
|
||||
vi.mocked(api.uploadCaddyfile).mockResolvedValue(mockPreview)
|
||||
|
||||
const { result } = renderHook(() => useImport(), { wrapper })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user