Files
pgsql-jellyfin/tests/Emby.Server.Implementations.Tests/AppBase/ConfigurationHelperTests.cs
wjones e81c127514 Add JSON config, DB-backed library options, and docs
- 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
2026-04-30 12:25:24 -04:00

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);
}
}
}
}