mirror of
https://github.com/StarFleetCPTN/GoMFT.git
synced 2026-11-05 11:37:26 +01:00
feat: Implement storage provider management functionality
- Added new routes and handlers for managing storage providers, including creation, editing, and deletion. - Introduced a new StorageProvider form component for user input. - Enhanced the database schema to support storage provider references in transfer configurations. - Implemented encryption for sensitive fields in storage provider data. - Added tests for storage provider API endpoints and integration with the database. - Updated frontend components to support storage provider selection and testing.
This commit is contained in:
1 parent
88d0ac815a
commit
31871bd16e
59 files changed
+15842
-594
No files matched your search
@@ -0,0 +1,416 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var testDB *gorm.DB
|
||||
|
||||
// setupTestDB sets up a SQLite in-memory database for testing
|
||||
func setupTestDB(t *testing.T) *DB {
|
||||
var err error
|
||||
testDB, err = gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open in-memory SQLite database: %v", err)
|
||||
}
|
||||
|
||||
// Create a minimal TransferConfig struct for testing
|
||||
type TransferConfig struct {
|
||||
ID uint `gorm:"primarykey"`
|
||||
SourceProviderID uint `gorm:"index"`
|
||||
DestinationProviderID uint `gorm:"index"`
|
||||
}
|
||||
|
||||
// Create the necessary tables
|
||||
err = testDB.AutoMigrate(&StorageProvider{}, &TransferConfig{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to migrate tables: %v", err)
|
||||
}
|
||||
|
||||
return &DB{DB: testDB}
|
||||
}
|
||||
|
||||
// cleanupTestDB cleans up the test database after each test
|
||||
func cleanupTestDB(t *testing.T) {
|
||||
sqlDB, err := testDB.DB()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get SQL DB: %v", err)
|
||||
}
|
||||
sqlDB.Close()
|
||||
}
|
||||
|
||||
// TestStorageProviderCRUD tests the complete CRUD cycle for a StorageProvider
|
||||
func TestStorageProviderCRUD(t *testing.T) {
|
||||
db := setupTestDB(t)
|
||||
defer cleanupTestDB(t)
|
||||
|
||||
// Create a test provider
|
||||
provider := &StorageProvider{
|
||||
Name: "Test SFTP",
|
||||
Type: ProviderTypeSFTP,
|
||||
Host: "example.com",
|
||||
Port: 22,
|
||||
Username: "user",
|
||||
Password: "password",
|
||||
CreatedBy: 1,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
|
||||
// Test Create
|
||||
err := db.CreateStorageProvider(provider)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create storage provider: %v", err)
|
||||
}
|
||||
if provider.ID == 0 {
|
||||
t.Fatal("Expected provider ID to be set after creation")
|
||||
}
|
||||
|
||||
// Test Get
|
||||
retrievedProvider, err := db.GetStorageProvider(provider.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get storage provider: %v", err)
|
||||
}
|
||||
if retrievedProvider.ID != provider.ID {
|
||||
t.Errorf("Expected provider ID %d, got %d", provider.ID, retrievedProvider.ID)
|
||||
}
|
||||
if retrievedProvider.Name != "Test SFTP" {
|
||||
t.Errorf("Expected name 'Test SFTP', got '%s'", retrievedProvider.Name)
|
||||
}
|
||||
if retrievedProvider.Type != ProviderTypeSFTP {
|
||||
t.Errorf("Expected type '%s', got '%s'", ProviderTypeSFTP, retrievedProvider.Type)
|
||||
}
|
||||
|
||||
// Test Update
|
||||
retrievedProvider.Name = "Updated SFTP"
|
||||
retrievedProvider.Host = "updated.example.com"
|
||||
// Make sure we keep the required fields for validation
|
||||
retrievedProvider.Port = 22
|
||||
retrievedProvider.Username = "user"
|
||||
retrievedProvider.Password = "password"
|
||||
err = db.UpdateStorageProvider(retrievedProvider)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to update storage provider: %v", err)
|
||||
}
|
||||
|
||||
// Verify update
|
||||
updatedProvider, err := db.GetStorageProvider(provider.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get updated storage provider: %v", err)
|
||||
}
|
||||
if updatedProvider.Name != "Updated SFTP" {
|
||||
t.Errorf("Expected updated name 'Updated SFTP', got '%s'", updatedProvider.Name)
|
||||
}
|
||||
if updatedProvider.Host != "updated.example.com" {
|
||||
t.Errorf("Expected updated host 'updated.example.com', got '%s'", updatedProvider.Host)
|
||||
}
|
||||
|
||||
// Test Delete
|
||||
err = db.DeleteStorageProvider(provider.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to delete storage provider: %v", err)
|
||||
}
|
||||
|
||||
// Verify deletion
|
||||
_, err = db.GetStorageProvider(provider.ID)
|
||||
if err == nil {
|
||||
t.Error("Expected error when getting deleted provider, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
// TestStorageProviderGetAll tests retrieving all storage providers for a user
|
||||
func TestStorageProviderGetAll(t *testing.T) {
|
||||
db := setupTestDB(t)
|
||||
defer cleanupTestDB(t)
|
||||
|
||||
// Create multiple providers for the same user
|
||||
providers := []*StorageProvider{
|
||||
{
|
||||
Name: "SFTP Provider",
|
||||
Type: ProviderTypeSFTP,
|
||||
Host: "sftp.example.com",
|
||||
Port: 22,
|
||||
Username: "sftpuser",
|
||||
Password: "pass",
|
||||
CreatedBy: 1,
|
||||
},
|
||||
{
|
||||
Name: "S3 Provider",
|
||||
Type: ProviderTypeS3,
|
||||
AccessKey: "accesskey",
|
||||
SecretKey: "secretkey",
|
||||
Region: "us-west-1",
|
||||
CreatedBy: 1,
|
||||
},
|
||||
{
|
||||
Name: "OneDrive Provider",
|
||||
Type: ProviderTypeOneDrive,
|
||||
ClientID: "clientid",
|
||||
ClientSecret: "clientsecret",
|
||||
CreatedBy: 1,
|
||||
},
|
||||
{
|
||||
Name: "Another User's Provider",
|
||||
Type: ProviderTypeSFTP,
|
||||
Host: "other.example.com",
|
||||
Port: 22, // Added required port for SFTP
|
||||
Username: "otheruser", // Added required username for SFTP
|
||||
Password: "otherpass", // Added required password for SFTP
|
||||
CreatedBy: 2, // Different user
|
||||
},
|
||||
}
|
||||
|
||||
// Create all providers
|
||||
for _, p := range providers {
|
||||
err := db.CreateStorageProvider(p)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create provider %s: %v", p.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test GetStorageProviders
|
||||
userProviders, err := db.GetStorageProviders(1)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get storage providers: %v", err)
|
||||
}
|
||||
|
||||
// Check the results
|
||||
if len(userProviders) != 3 {
|
||||
t.Errorf("Expected 3 providers for user 1, got %d", len(userProviders))
|
||||
}
|
||||
}
|
||||
|
||||
// TestStorageProviderGetByType tests retrieving storage providers by type
|
||||
func TestStorageProviderGetByType(t *testing.T) {
|
||||
db := setupTestDB(t)
|
||||
defer cleanupTestDB(t)
|
||||
|
||||
// Create providers of different types
|
||||
providers := []*StorageProvider{
|
||||
{
|
||||
Name: "SFTP Provider 1",
|
||||
Type: ProviderTypeSFTP,
|
||||
Host: "sftp1.example.com",
|
||||
Port: 22, // Added required port for SFTP
|
||||
Username: "user1", // Added required username for SFTP
|
||||
Password: "pass1", // Added required password for SFTP
|
||||
CreatedBy: 1,
|
||||
},
|
||||
{
|
||||
Name: "SFTP Provider 2",
|
||||
Type: ProviderTypeSFTP,
|
||||
Host: "sftp2.example.com",
|
||||
Port: 22, // Added required port for SFTP
|
||||
Username: "user2", // Added required username for SFTP
|
||||
Password: "pass2", // Added required password for SFTP
|
||||
CreatedBy: 1,
|
||||
},
|
||||
{
|
||||
Name: "S3 Provider",
|
||||
Type: ProviderTypeS3,
|
||||
AccessKey: "accesskey",
|
||||
SecretKey: "secretkey", // Added required secret key for S3
|
||||
Region: "us-west-1", // Added required region for S3
|
||||
CreatedBy: 1,
|
||||
},
|
||||
}
|
||||
|
||||
// Create all providers
|
||||
for _, p := range providers {
|
||||
err := db.CreateStorageProvider(p)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create provider %s: %v", p.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test GetStorageProvidersByType
|
||||
sftpProviders, err := db.GetStorageProvidersByType(1, ProviderTypeSFTP)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get SFTP providers: %v", err)
|
||||
}
|
||||
|
||||
// Check the results
|
||||
if len(sftpProviders) != 2 {
|
||||
t.Errorf("Expected 2 SFTP providers, got %d", len(sftpProviders))
|
||||
}
|
||||
for _, p := range sftpProviders {
|
||||
if p.Type != ProviderTypeSFTP {
|
||||
t.Errorf("Expected provider type SFTP, got %s", p.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestStorageProviderValidationOnSave tests that validation is called before saving
|
||||
func TestStorageProviderValidationOnSave(t *testing.T) {
|
||||
db := setupTestDB(t)
|
||||
defer cleanupTestDB(t)
|
||||
|
||||
// Create a provider with invalid data (missing host for SFTP)
|
||||
invalidProvider := &StorageProvider{
|
||||
Name: "Invalid SFTP",
|
||||
Type: ProviderTypeSFTP,
|
||||
Port: 22,
|
||||
Username: "user",
|
||||
Password: "pass",
|
||||
CreatedBy: 1,
|
||||
}
|
||||
|
||||
// Test CreateStorageProvider with validation
|
||||
err := db.CreateStorageProvider(invalidProvider)
|
||||
if err == nil {
|
||||
t.Fatal("Expected validation error for invalid provider, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
// TestStorageProviderCount tests counting providers for a user
|
||||
func TestStorageProviderCount(t *testing.T) {
|
||||
db := setupTestDB(t)
|
||||
defer cleanupTestDB(t)
|
||||
|
||||
// Create multiple providers for different users
|
||||
providers := []*StorageProvider{
|
||||
{
|
||||
Name: "User 1 Provider 1",
|
||||
Type: ProviderTypeSFTP,
|
||||
Host: "host1.example.com",
|
||||
Port: 22, // Added required port for SFTP
|
||||
Username: "user1", // Added required username for SFTP
|
||||
Password: "pass1", // Added required password for SFTP
|
||||
CreatedBy: 1,
|
||||
},
|
||||
{
|
||||
Name: "User 1 Provider 2",
|
||||
Type: ProviderTypeS3,
|
||||
AccessKey: "accesskey",
|
||||
SecretKey: "secretkey", // Added required secret key for S3
|
||||
Region: "us-west-1", // Added required region for S3
|
||||
CreatedBy: 1,
|
||||
},
|
||||
{
|
||||
Name: "User 2 Provider",
|
||||
Type: ProviderTypeSFTP,
|
||||
Host: "host2.example.com",
|
||||
Port: 22, // Added required port for SFTP
|
||||
Username: "user2", // Added required username for SFTP
|
||||
Password: "pass2", // Added required password for SFTP
|
||||
CreatedBy: 2,
|
||||
},
|
||||
}
|
||||
|
||||
// Create all providers
|
||||
for _, p := range providers {
|
||||
// Skip validation for this test since we're just testing count
|
||||
err := testDB.Create(p).Error
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create provider %s: %v", p.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test CountStorageProviders
|
||||
count, err := db.CountStorageProviders(1)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to count storage providers: %v", err)
|
||||
}
|
||||
|
||||
// Check the result
|
||||
if count != 2 {
|
||||
t.Errorf("Expected count 2 for user 1, got %d", count)
|
||||
}
|
||||
|
||||
count, err = db.CountStorageProviders(2)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to count storage providers: %v", err)
|
||||
}
|
||||
|
||||
// Check the result
|
||||
if count != 1 {
|
||||
t.Errorf("Expected count 1 for user 2, got %d", count)
|
||||
}
|
||||
}
|
||||
|
||||
// TestHelperMethods tests the helper methods on StorageProvider
|
||||
func TestHelperMethods(t *testing.T) {
|
||||
// Test GetPassiveMode and SetPassiveMode
|
||||
t.Run("PassiveMode", func(t *testing.T) {
|
||||
provider := &StorageProvider{}
|
||||
|
||||
// Default value
|
||||
if !provider.GetPassiveMode() {
|
||||
t.Error("Expected default PassiveMode to be true")
|
||||
}
|
||||
|
||||
// Set to false
|
||||
provider.SetPassiveMode(false)
|
||||
if provider.GetPassiveMode() {
|
||||
t.Error("Expected PassiveMode to be false after setting")
|
||||
}
|
||||
|
||||
// Set to true
|
||||
provider.SetPassiveMode(true)
|
||||
if !provider.GetPassiveMode() {
|
||||
t.Error("Expected PassiveMode to be true after setting")
|
||||
}
|
||||
})
|
||||
|
||||
// Test GetReadOnly and SetReadOnly
|
||||
t.Run("ReadOnly", func(t *testing.T) {
|
||||
provider := &StorageProvider{}
|
||||
|
||||
// Default value
|
||||
if provider.GetReadOnly() {
|
||||
t.Error("Expected default ReadOnly to be false")
|
||||
}
|
||||
|
||||
// Set to true
|
||||
provider.SetReadOnly(true)
|
||||
if !provider.GetReadOnly() {
|
||||
t.Error("Expected ReadOnly to be true after setting")
|
||||
}
|
||||
})
|
||||
|
||||
// Test GetAuthenticated and SetAuthenticated
|
||||
t.Run("Authenticated", func(t *testing.T) {
|
||||
provider := &StorageProvider{}
|
||||
|
||||
// Default value
|
||||
if provider.GetAuthenticated() {
|
||||
t.Error("Expected default Authenticated to be false")
|
||||
}
|
||||
|
||||
// Set to true
|
||||
provider.SetAuthenticated(true)
|
||||
if !provider.GetAuthenticated() {
|
||||
t.Error("Expected Authenticated to be true after setting")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestIsOAuthProvider tests the IsOAuthProvider method
|
||||
func TestIsOAuthProvider(t *testing.T) {
|
||||
tests := []struct {
|
||||
providerType StorageProviderType
|
||||
isOAuth bool
|
||||
}{
|
||||
{ProviderTypeSFTP, false},
|
||||
{ProviderTypeS3, false},
|
||||
{ProviderTypeFTP, false},
|
||||
{ProviderTypeSMB, false},
|
||||
{ProviderTypeOneDrive, true},
|
||||
{ProviderTypeGoogleDrive, true},
|
||||
{ProviderTypeGooglePhoto, true},
|
||||
{ProviderTypeLocal, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(string(tt.providerType), func(t *testing.T) {
|
||||
provider := &StorageProvider{Type: tt.providerType}
|
||||
if provider.IsOAuthProvider() != tt.isOAuth {
|
||||
t.Errorf("IsOAuthProvider() for %s = %v, want %v", tt.providerType, provider.IsOAuthProvider(), tt.isOAuth)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user