mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 08:13:37 +00:00
feat: Add unit tests for validation storage functionality
- Introduced comprehensive unit tests for the validation storage module, covering functions such as writeValidation, readValidation, getAllValidations, deleteValidation, and others. - Implemented tests to ensure correct behavior for validation creation, retrieval, deletion, and freshness checks. - Enhanced test coverage for edge cases, including handling of non-existent validations and directory structure validation.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { getElectronAPI } from '@/lib/electron';
|
||||
import type { Project, StoredValidation } from '@/lib/electron';
|
||||
|
||||
@@ -8,71 +8,26 @@ import type { Project, StoredValidation } from '@/lib/electron';
|
||||
*/
|
||||
export function useUnviewedValidations(currentProject: Project | null) {
|
||||
const [count, setCount] = useState(0);
|
||||
const projectPathRef = useRef<string | null>(null);
|
||||
|
||||
// Load initial count
|
||||
// Keep project path in ref for use in async functions
|
||||
useEffect(() => {
|
||||
if (!currentProject?.path) {
|
||||
setCount(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const loadCount = async () => {
|
||||
try {
|
||||
const api = getElectronAPI();
|
||||
if (api.github?.getValidations) {
|
||||
const result = await api.github.getValidations(currentProject.path);
|
||||
if (result.success && result.validations) {
|
||||
const unviewed = result.validations.filter((v: StoredValidation) => {
|
||||
if (v.viewedAt) return false;
|
||||
// Check if not stale (< 24 hours)
|
||||
const hoursSince =
|
||||
(Date.now() - new Date(v.validatedAt).getTime()) / (1000 * 60 * 60);
|
||||
return hoursSince <= 24;
|
||||
});
|
||||
setCount(unviewed.length);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[useUnviewedValidations] Failed to load count:', err);
|
||||
}
|
||||
};
|
||||
|
||||
loadCount();
|
||||
|
||||
// Subscribe to validation events to update count
|
||||
const api = getElectronAPI();
|
||||
if (api.github?.onValidationEvent) {
|
||||
const unsubscribe = api.github.onValidationEvent((event) => {
|
||||
if (event.projectPath === currentProject.path) {
|
||||
if (event.type === 'issue_validation_complete') {
|
||||
// New validation completed - increment count
|
||||
setCount((prev) => prev + 1);
|
||||
} else if (event.type === 'issue_validation_viewed') {
|
||||
// Validation was viewed - decrement count
|
||||
setCount((prev) => Math.max(0, prev - 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
return () => unsubscribe();
|
||||
}
|
||||
projectPathRef.current = currentProject?.path ?? null;
|
||||
}, [currentProject?.path]);
|
||||
|
||||
// Function to decrement count when a validation is viewed
|
||||
const decrementCount = useCallback(() => {
|
||||
setCount((prev) => Math.max(0, prev - 1));
|
||||
}, []);
|
||||
|
||||
// Function to refresh count (e.g., after marking as viewed)
|
||||
const refreshCount = useCallback(async () => {
|
||||
if (!currentProject?.path) return;
|
||||
// Fetch and update count from server
|
||||
const fetchUnviewedCount = useCallback(async () => {
|
||||
const projectPath = projectPathRef.current;
|
||||
if (!projectPath) return;
|
||||
|
||||
try {
|
||||
const api = getElectronAPI();
|
||||
if (api.github?.getValidations) {
|
||||
const result = await api.github.getValidations(currentProject.path);
|
||||
const result = await api.github.getValidations(projectPath);
|
||||
if (result.success && result.validations) {
|
||||
const unviewed = result.validations.filter((v: StoredValidation) => {
|
||||
if (v.viewedAt) return false;
|
||||
// Check if not stale (< 24 hours)
|
||||
const hoursSince = (Date.now() - new Date(v.validatedAt).getTime()) / (1000 * 60 * 60);
|
||||
return hoursSince <= 24;
|
||||
});
|
||||
@@ -80,9 +35,45 @@ export function useUnviewedValidations(currentProject: Project | null) {
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[useUnviewedValidations] Failed to refresh count:', err);
|
||||
console.error('[useUnviewedValidations] Failed to load count:', err);
|
||||
}
|
||||
}, [currentProject?.path]);
|
||||
}, []);
|
||||
|
||||
// Load initial count and subscribe to events
|
||||
useEffect(() => {
|
||||
if (!currentProject?.path) {
|
||||
setCount(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load initial count
|
||||
fetchUnviewedCount();
|
||||
|
||||
// Subscribe to validation events to update count
|
||||
const api = getElectronAPI();
|
||||
if (api.github?.onValidationEvent) {
|
||||
const unsubscribe = api.github.onValidationEvent((event) => {
|
||||
if (event.projectPath === currentProject.path) {
|
||||
if (event.type === 'issue_validation_complete') {
|
||||
// New validation completed - refresh count from server for consistency
|
||||
fetchUnviewedCount();
|
||||
} else if (event.type === 'issue_validation_viewed') {
|
||||
// Validation was viewed - refresh count from server for consistency
|
||||
fetchUnviewedCount();
|
||||
}
|
||||
}
|
||||
});
|
||||
return () => unsubscribe();
|
||||
}
|
||||
}, [currentProject?.path, fetchUnviewedCount]);
|
||||
|
||||
// Function to decrement count when a validation is viewed
|
||||
const decrementCount = useCallback(() => {
|
||||
setCount((prev) => Math.max(0, prev - 1));
|
||||
}, []);
|
||||
|
||||
// Expose refreshCount as an alias to fetchUnviewedCount for external use
|
||||
const refreshCount = fetchUnviewedCount;
|
||||
|
||||
return { count, decrementCount, refreshCount };
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ export function GitHubIssuesView() {
|
||||
|
||||
const unsubscribe = api.github.onValidationEvent(handleValidationEvent);
|
||||
return () => unsubscribe();
|
||||
}, [currentProject?.path, selectedIssue, showValidationDialog, validationModel, muteDoneSound]);
|
||||
}, [currentProject?.path, selectedIssue, showValidationDialog, muteDoneSound]);
|
||||
|
||||
// Cleanup audio element on unmount to prevent memory leaks
|
||||
useEffect(() => {
|
||||
@@ -803,7 +803,7 @@ function IssueRow({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-start gap-3 p-3 cursor-pointer hover:bg-accent/50 transition-colors',
|
||||
'group flex items-start gap-3 p-3 cursor-pointer hover:bg-accent/50 transition-colors',
|
||||
isSelected && 'bg-accent'
|
||||
)}
|
||||
onClick={onClick}
|
||||
|
||||
Reference in New Issue
Block a user