//go:build clamav // +build clamav package services import ( "context" "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" ) // TestUploadValidator_ClamAV_EICAR_Rejected est un test d'intégration optionnel // qui nécessite ClamAV en cours d'exécution. // Pour exécuter: go test -tags=clamav ./internal/services -run TestUploadValidator_ClamAV_EICAR_Rejected // MOD-P1-001: Test que le fichier EICAR (test virus standard) est rejeté func TestUploadValidator_ClamAV_EICAR_Rejected(t *testing.T) { // Vérifier que ClamAV est disponible clamavAddr := os.Getenv("CLAMAV_ADDRESS") if clamavAddr == "" { clamavAddr = "localhost:3310" } logger, _ := zap.NewDevelopment() // Configuration avec ClamAV enabled config := &UploadConfig{ MaxAudioSize: 100 * 1024 * 1024, MaxImageSize: 10 * 1024 * 1024, MaxVideoSize: 500 * 1024 * 1024, AllowedAudioTypes: []string{"application/octet-stream"}, // EICAR sera détecté comme octet-stream AllowedImageTypes: []string{"image/jpeg"}, AllowedVideoTypes: []string{"video/mp4"}, ClamAVEnabled: true, ClamAVAddress: clamavAddr, QuarantineDir: "/tmp/quarantine", } validator, err := NewUploadValidator(config, logger) require.NoError(t, err, "NewUploadValidator should succeed when ClamAV is available") require.NotNil(t, validator) require.False(t, validator.clamAVRequiredButUnavailable, "ClamAV should be available") // Créer un fichier EICAR (test virus standard) // EICAR test file content (68 bytes) eicarContent := []byte("X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*") // Créer un FileHeader avec le contenu EICAR fileHeader := createTestFileHeader(t, "eicar.com", eicarContent) // MOD-P1-001: ValidateFile doit rejeter le fichier EICAR result, err := validator.ValidateFile(context.Background(), fileHeader, "audio") // Vérifier que le fichier est rejeté require.Error(t, err, "ValidateFile should return error for EICAR file") assert.Contains(t, err.Error(), "clamav_infected", "Error should indicate virus detected") assert.NotNil(t, result, "Result should not be nil") assert.False(t, result.Valid, "File should be marked as invalid") assert.True(t, result.Quarantined, "File should be quarantined") assert.Contains(t, result.Error, "Virus detected", "Error message should mention virus detected") } // TestUploadValidator_ClamAV_CleanFile_Accepted vérifie qu'un fichier propre est accepté // MOD-P1-001: Test qu'un fichier non infecté passe le scan ClamAV func TestUploadValidator_ClamAV_CleanFile_Accepted(t *testing.T) { // Vérifier que ClamAV est disponible clamavAddr := os.Getenv("CLAMAV_ADDRESS") if clamavAddr == "" { clamavAddr = "localhost:3310" } logger, _ := zap.NewDevelopment() // Configuration avec ClamAV enabled config := &UploadConfig{ MaxAudioSize: 100 * 1024 * 1024, MaxImageSize: 10 * 1024 * 1024, MaxVideoSize: 500 * 1024 * 1024, AllowedAudioTypes: []string{"application/octet-stream"}, AllowedImageTypes: []string{"image/jpeg"}, AllowedVideoTypes: []string{"video/mp4"}, ClamAVEnabled: true, ClamAVAddress: clamavAddr, QuarantineDir: "/tmp/quarantine", } validator, err := NewUploadValidator(config, logger) require.NoError(t, err) require.NotNil(t, validator) // Créer un fichier propre (contenu binaire simple) cleanContent := []byte{0xFF, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00} // Header MP3 valide fileHeader := createTestFileHeader(t, "clean_file.mp3", cleanContent) // ValidateFile devrait réussir (fichier propre) result, err := validator.ValidateFile(context.Background(), fileHeader, "audio") // Le fichier peut échouer pour d'autres raisons (extension, etc.) mais pas pour virus if err != nil { assert.NotContains(t, err.Error(), "clamav_infected", "Error should not mention virus for clean file") assert.NotContains(t, err.Error(), "clamav_scan_error", "Error should not mention scan error for clean file") } _ = result }