e81c127514
- Add JSON-based config loading with XML fallback for DB and library options - Implement LibraryOptionsRepository with EF Core, migrations, and entity - Update CollectionFolder to use DB-backed options with XML fallback/backfill - Register repository in DI and initialize at startup - Use EF execution strategy for transactional DB operations - Suppress code analysis warnings in .csproj and test files - Add DATABASE_MIGRATION.md, LIBRARY_OPTIONS_DB_DESIGN.md, and WEBSOCKET_AUTHENTICATION.md - Add database.json.example and improve migration docs - Add tests for JSON config loader and update test naming warnings
204 lines
6.7 KiB
C#
204 lines
6.7 KiB
C#
// <copyright file="ConfigurationHelperTests.cs" company="PlaceholderCompany">
|
|
// Copyright (c) PlaceholderCompany. All rights reserved.
|
|
// </copyright>
|
|
|
|
namespace Emby.Server.Implementations.Tests.AppBase;
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Text.Json;
|
|
using Emby.Server.Implementations.AppBase;
|
|
using Jellyfin.Database.Implementations.DbConfiguration;
|
|
using Jellyfin.Extensions.Json;
|
|
using Xunit;
|
|
|
|
/// <summary>
|
|
/// Tests for the ConfigurationHelper JSON loading functionality.
|
|
/// </summary>
|
|
public class ConfigurationHelperTests
|
|
{
|
|
[Fact]
|
|
public void GetJsonConfiguration_ValidJsonFile_DeserializesCorrectly()
|
|
{
|
|
// Arrange
|
|
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
var jsonPath = Path.Combine(tempDir, "test-config.json");
|
|
|
|
var testConfig = new DatabaseConfigurationOptions
|
|
{
|
|
DatabaseType = "Jellyfin-PostgreSQL",
|
|
LockingBehavior = DatabaseLockingBehaviorTypes.NoLock
|
|
};
|
|
|
|
Directory.CreateDirectory(tempDir);
|
|
var json = JsonSerializer.Serialize(testConfig, JsonDefaults.Options);
|
|
File.WriteAllText(jsonPath, json);
|
|
|
|
try
|
|
{
|
|
// Act
|
|
var result = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal("Jellyfin-PostgreSQL", result.DatabaseType);
|
|
Assert.Equal(DatabaseLockingBehaviorTypes.NoLock, result.LockingBehavior);
|
|
}
|
|
finally
|
|
{
|
|
// Cleanup
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void GetJsonConfiguration_MissingFile_CreatesDefaultAndReturnsIt()
|
|
{
|
|
// Arrange
|
|
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
var jsonPath = Path.Combine(tempDir, "test-config.json");
|
|
|
|
try
|
|
{
|
|
// Act
|
|
var result = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.True(File.Exists(jsonPath), "JSON file should be created");
|
|
|
|
// Verify the file is valid JSON
|
|
var fileContent = File.ReadAllText(jsonPath);
|
|
var deserialized = JsonSerializer.Deserialize<DatabaseConfigurationOptions>(fileContent, JsonDefaults.Options);
|
|
Assert.NotNull(deserialized);
|
|
}
|
|
finally
|
|
{
|
|
// Cleanup
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void GetJsonConfiguration_WithCustomProviderOptions_PreservesSettings()
|
|
{
|
|
// Arrange
|
|
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
var jsonPath = Path.Combine(tempDir, "test-config.json");
|
|
|
|
var testConfig = new DatabaseConfigurationOptions
|
|
{
|
|
DatabaseType = "Jellyfin-PostgreSQL",
|
|
LockingBehavior = DatabaseLockingBehaviorTypes.Pessimistic,
|
|
CustomProviderOptions = new CustomDatabaseOptions
|
|
{
|
|
PluginName = "Jellyfin-PostgreSQL",
|
|
PluginAssembly = "Jellyfin.Database.Providers.Postgres",
|
|
ConnectionString = "Host=localhost;Port=5432;Database=jellyfin;Username=jellyfin;Password=secret"
|
|
}
|
|
};
|
|
|
|
Directory.CreateDirectory(tempDir);
|
|
var json = JsonSerializer.Serialize(testConfig, JsonDefaults.Options);
|
|
File.WriteAllText(jsonPath, json);
|
|
|
|
try
|
|
{
|
|
// Act
|
|
var result = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal("Jellyfin-PostgreSQL", result.DatabaseType);
|
|
Assert.Equal(DatabaseLockingBehaviorTypes.Pessimistic, result.LockingBehavior);
|
|
Assert.NotNull(result.CustomProviderOptions);
|
|
Assert.Equal("Jellyfin-PostgreSQL", result.CustomProviderOptions.PluginName);
|
|
Assert.Equal("Host=localhost;Port=5432;Database=jellyfin;Username=jellyfin;Password=secret",
|
|
result.CustomProviderOptions.ConnectionString);
|
|
}
|
|
finally
|
|
{
|
|
// Cleanup
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void GetJsonConfiguration_InvalidJson_CreatesDefault()
|
|
{
|
|
// Arrange
|
|
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
var jsonPath = Path.Combine(tempDir, "test-config.json");
|
|
|
|
Directory.CreateDirectory(tempDir);
|
|
File.WriteAllText(jsonPath, "{ invalid json");
|
|
|
|
try
|
|
{
|
|
// Act
|
|
var result = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);
|
|
|
|
// Assert - should get default instance on invalid JSON
|
|
Assert.NotNull(result);
|
|
}
|
|
finally
|
|
{
|
|
// Cleanup
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void GetJsonConfiguration_RoundTrip_PreservesData()
|
|
{
|
|
// Arrange
|
|
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
var jsonPath = Path.Combine(tempDir, "test-config.json");
|
|
|
|
var originalConfig = new DatabaseConfigurationOptions
|
|
{
|
|
DatabaseType = "Jellyfin-PostgreSQL",
|
|
LockingBehavior = DatabaseLockingBehaviorTypes.Optimistic
|
|
};
|
|
|
|
Directory.CreateDirectory(tempDir);
|
|
|
|
try
|
|
{
|
|
// Act - First load should create the file
|
|
var result1 = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);
|
|
|
|
// Modify and verify round-trip
|
|
var json = JsonSerializer.Serialize(originalConfig, JsonDefaults.Options);
|
|
File.WriteAllText(jsonPath, json);
|
|
|
|
var result2 = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);
|
|
|
|
// Assert
|
|
Assert.NotNull(result2);
|
|
Assert.Equal("Jellyfin-PostgreSQL", result2.DatabaseType);
|
|
Assert.Equal(DatabaseLockingBehaviorTypes.Optimistic, result2.LockingBehavior);
|
|
}
|
|
finally
|
|
{
|
|
// Cleanup
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
}
|