veza/veza-backend-api/internal/services/upload_validator_integration_test.go

105 lines
3.9 KiB
Go

//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 clamdscan est disponible (exec)
clamdPath := os.Getenv("CLAMAV_CLAMD_PATH")
if clamdPath == "" {
clamdPath = "clamdscan"
}
logger, _ := zap.NewDevelopment()
// Configuration avec ClamAV enabled (utilise clamdscan exec)
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,
ClamAVClamdPath: clamdPath,
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) {
clamdPath := os.Getenv("CLAMAV_CLAMD_PATH")
if clamdPath == "" {
clamdPath = "clamdscan"
}
logger, _ := zap.NewDevelopment()
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,
ClamAVClamdPath: clamdPath,
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
}