diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterIPServiceGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterIPServiceGeneratorTests/GenerateAsyncTests.cs index 1b1fbe7d..5ae26c3c 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterIPServiceGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterIPServiceGeneratorTests/GenerateAsyncTests.cs @@ -6,7 +6,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.ClusterIPServiceGenerat /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated ClusterIP Service object. @@ -129,4 +129,4 @@ public async Task GenerateAsync_WithServiceWithoutName_ShouldThrowKubernetesGene // Act & Assert _ = await Assert.ThrowsAsync(() => generator.GenerateAsync(model, Path.GetTempFileName())); } -} \ No newline at end of file +} diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterRoleBindingGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterRoleBindingGeneratorTests/GenerateAsyncTests.cs index 79b7b753..cc98bb50 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterRoleBindingGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterRoleBindingGeneratorTests/GenerateAsyncTests.cs @@ -7,7 +7,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.ClusterRoleBindingGener /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeClusterRoleBinding object with all properties set. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterRoleGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterRoleGeneratorTests/GenerateAsyncTests.cs index 2bf5a636..0e16ccdc 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterRoleGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ClusterRoleGeneratorTests/GenerateAsyncTests.cs @@ -8,7 +8,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.ClusterRoleGeneratorTes /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeClusterRole object with basic rules. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ConfigMapGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ConfigMapGeneratorTests/GenerateAsyncTests.cs index 201d9f2c..ef9708f5 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ConfigMapGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ConfigMapGeneratorTests/GenerateAsyncTests.cs @@ -4,145 +4,112 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.ConfigMapGeneratorTests; - /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// - /// Verifies the generated NativeConfigMap object using kubectl create configmap with literal data. + /// Test data for valid ConfigMap generation scenarios. /// - /// - [Fact] - public async Task GenerateAsync_WithLiteralData_ShouldGenerateAValidConfigMap() - { - // Arrange - var generator = new ConfigMapGenerator(); - var model = new NativeConfigMap + public static TheoryData ValidConfigMapData => + new() { - Metadata = new Metadata { - Name = "test-config", - Namespace = "default" + new NativeConfigMap + { + Metadata = new Metadata { Name = "test-config", Namespace = "default" }, + Data = new Dictionary { ["key1"] = "value1", ["key2"] = "value2" } + }, + "config-map-literal.yaml" }, - Data = new Dictionary { - ["key1"] = "value1", - ["key2"] = "value2" + new NativeConfigMap + { + Metadata = new Metadata { Name = "test-config-hash" }, + Data = new Dictionary + { + ["database_url"] = "postgresql://localhost:5432/mydb", + ["api_key"] = "secret-api-key" + }, + AppendHash = true + }, + "config-map-literal-hash.yaml" + }, + { + new NativeConfigMap + { + Metadata = new Metadata { Name = "test-empty", Namespace = "default" }, + Data = new Dictionary() + }, + "config-map-empty.yaml" } }; - // Act - string fileName = "config-map-literal.yaml"; - string outputPath = Path.Combine(Path.GetTempPath(), fileName); - if (File.Exists(outputPath)) - File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - - // Assert - _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - - // Cleanup - File.Delete(outputPath); - } - /// - /// Verifies the generated NativeConfigMap object using kubectl create configmap with literal data and append hash. + /// Verifies the generated NativeConfigMap object with different configurations. /// + /// The ConfigMap model to test. + /// The expected output file name. /// - [Fact] - public async Task GenerateAsync_WithLiteralDataAndAppendHash_ShouldGenerateAValidConfigMap() + [Theory] + [MemberData(nameof(ValidConfigMapData))] + public async Task GenerateAsync_WithValidConfiguration_ShouldGenerateAValidConfigMap(NativeConfigMap model, string fileName) { // Arrange var generator = new ConfigMapGenerator(); - var model = new NativeConfigMap - { - Metadata = new Metadata - { - Name = "test-config-hash" - }, - Data = new Dictionary - { - ["database_url"] = "postgresql://localhost:5432/mydb", - ["api_key"] = "secret-api-key" - }, - AppendHash = true - }; - - // Act - string fileName = "config-map-literal-hash.yaml"; - string outputPath = Path.Combine(Path.GetTempPath(), fileName); - if (File.Exists(outputPath)) - File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - - // Assert - _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - // Cleanup - File.Delete(outputPath); + // Act & Assert + await GenerateAndVerifyAsync(generator, model, fileName); } /// - /// Verifies that a is thrown when the NativeConfigMap name is empty. + /// Verifies that a is thrown when the NativeConfigMap name is invalid. /// + /// The ConfigMap name to test. /// - [Fact] - public async Task GenerateAsync_WithEmptyConfigMapName_ShouldThrowKubernetesGeneratorException() + [Theory] + [InlineData("")] + [InlineData(null)] + public async Task GenerateAsync_WithInvalidConfigMapName_ShouldThrowKubernetesGeneratorException(string? name) { // Arrange var generator = new ConfigMapGenerator(); var model = new NativeConfigMap { - Metadata = new Metadata - { - Name = "" - }, - Data = new Dictionary - { - ["key"] = "value" - } + Metadata = new Metadata { Name = name! }, + Data = new Dictionary { ["key"] = "value" } }; // Act & Assert - _ = await Assert.ThrowsAsync(() => generator.GenerateAsync(model, Path.GetTempFileName())); + _ = await Assert.ThrowsAsync(() => + generator.GenerateAsync(model, Path.GetTempFileName())); } /// - /// Verifies the generated NativeConfigMap object with empty or null data creates an empty ConfigMap. - /// Tests that both empty dictionary and null data scenarios produce identical output. + /// Helper method to generate a file and verify its content. /// - /// - [Fact] - public async Task GenerateAsync_WithEmptyOrNullData_ShouldGenerateEmptyConfigMap() + /// The model type. + /// The generator type. + /// The generator instance. + /// The model to generate. + /// The file name for verification. + /// A task representing the async operation. + static async Task GenerateAndVerifyAsync( + TGenerator generator, + TModel model, + string fileName) + where TGenerator : IKubernetesGenerator { - // Arrange - var generator = new ConfigMapGenerator(); - var model = new NativeConfigMap - { - Metadata = new Metadata - { - Name = "test-empty", - Namespace = "default" - }, - Data = new Dictionary() // Empty dictionary (null produces same result) - }; - - // Act - string fileName = "config-map-empty.yaml"; string outputPath = Path.Combine(Path.GetTempPath(), fileName); if (File.Exists(outputPath)) File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - // Assert + await generator.GenerateAsync(model, outputPath).ConfigureAwait(false); + string fileContent = await File.ReadAllTextAsync(outputPath).ConfigureAwait(false); + _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - // Cleanup File.Delete(outputPath); } } diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/CronJobGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/CronJobGeneratorTests/GenerateAsyncTests.cs index 5a62e722..9a8b30ac 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/CronJobGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/CronJobGeneratorTests/GenerateAsyncTests.cs @@ -9,7 +9,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.CronJobGeneratorTests; /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeCronJob object with image and schedule. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DaemonSetGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DaemonSetGeneratorTests/GenerateAsyncTests.cs index d1a2fa29..9b391899 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DaemonSetGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DaemonSetGeneratorTests/GenerateAsyncTests.cs @@ -10,7 +10,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.DaemonSetGeneratorTests /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeDaemonSet object. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DeploymentGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DeploymentGeneratorTests/GenerateAsyncTests.cs index 264d4f11..d443470e 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DeploymentGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DeploymentGeneratorTests/GenerateAsyncTests.cs @@ -4,209 +4,143 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.DeploymentGeneratorTests; - /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// - /// Verifies the generated NativeDeployment object with basic configuration. + /// Test data for valid deployment generation scenarios. /// - /// - [Fact] - public async Task GenerateAsync_WithBasicConfiguration_ShouldGenerateAValidDeployment() - { - // Arrange - var generator = new DeploymentGenerator(); - var model = new NativeDeployment + public static TheoryData ValidDeploymentData => + new() { - Metadata = new Metadata { - Name = "my-deployment", - Namespace = "default" + new NativeDeployment + { + Metadata = new Metadata { Name = "my-deployment", Namespace = "default" }, + Spec = new NativeDeploymentSpec { Images = ["nginx"], Replicas = 3 } + }, + "deployment.yaml" }, - Spec = new NativeDeploymentSpec - { - Images = ["nginx"], - Replicas = 3 - } - }; - - // Act - string fileName = "deployment.yaml"; - string outputPath = Path.Combine(Path.GetTempPath(), fileName); - if (File.Exists(outputPath)) - File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - - // Assert - _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - - // Cleanup - File.Delete(outputPath); - } - - /// - /// Verifies the generated NativeDeployment with port and command. - /// - /// - [Fact] - public async Task GenerateAsync_WithPortAndCommand_ShouldGenerateAValidDeployment() - { - // Arrange - var generator = new DeploymentGenerator(); - var model = new NativeDeployment - { - Metadata = new Metadata { - Name = "my-app-deployment" + new NativeDeployment + { + Metadata = new Metadata { Name = "my-app-deployment" }, + Spec = new NativeDeploymentSpec + { + Images = ["busybox"], + Replicas = 2, + Port = 8080, + Command = ["echo", "hello", "world"] + } + }, + "app-deployment.yaml" }, - Spec = new NativeDeploymentSpec { - Images = ["busybox"], - Replicas = 2, - Port = 8080, - Command = ["echo", "hello", "world"] + new NativeDeployment + { + Metadata = new Metadata { Name = "multi-container-deployment" }, + Spec = new NativeDeploymentSpec { Images = ["nginx", "busybox", "ubuntu"], Replicas = 2 } + }, + "multi-deployment.yaml" } }; - // Act - string fileName = "app-deployment.yaml"; - string outputPath = Path.Combine(Path.GetTempPath(), fileName); - if (File.Exists(outputPath)) - File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - - // Assert - _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - - // Cleanup - File.Delete(outputPath); - } - /// - /// Verifies the generated NativeDeployment with multiple images (without command). + /// Verifies the generated NativeDeployment object with different configurations. /// + /// The deployment model to test. + /// The expected output file name. /// - [Fact] - public async Task GenerateAsync_WithMultipleImages_ShouldGenerateAValidDeployment() + [Theory] + [MemberData(nameof(ValidDeploymentData))] + public async Task GenerateAsync_WithValidConfiguration_ShouldGenerateAValidDeployment(NativeDeployment model, string fileName) { // Arrange var generator = new DeploymentGenerator(); - var model = new NativeDeployment - { - Metadata = new Metadata - { - Name = "multi-container-deployment" - }, - Spec = new NativeDeploymentSpec - { - Images = ["nginx", "busybox", "ubuntu"], - Replicas = 2 - } - }; - // Act - string fileName = "multi-deployment.yaml"; - string outputPath = Path.Combine(Path.GetTempPath(), fileName); - if (File.Exists(outputPath)) - File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - - // Assert - _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - - // Cleanup - File.Delete(outputPath); + // Act & Assert + await GenerateAndVerifyAsync(generator, model, fileName); } /// - /// Verifies that an exception is thrown when no name is provided. + /// Test data for exception scenarios. /// - /// - [Fact] - public async Task GenerateAsync_WithEmptyName_ShouldThrowException() - { - // Arrange - var generator = new DeploymentGenerator(); - var model = new NativeDeployment + public static TheoryData ExceptionData => + new() { - Metadata = new Metadata { - Name = string.Empty + new NativeDeployment + { + Metadata = new Metadata { Name = string.Empty }, + Spec = new NativeDeploymentSpec { Images = ["nginx"] } + }, + "A non-empty Deployment name must be provided" }, - Spec = new NativeDeploymentSpec { - Images = ["nginx"] + new NativeDeployment + { + Metadata = new Metadata { Name = "test-deployment" }, + Spec = new NativeDeploymentSpec { Images = ["nginx", "busybox"], Command = ["echo", "hello"] } + }, + "Cannot specify multiple images with a command" + }, + { + new NativeDeployment + { + Metadata = new Metadata { Name = "test-deployment" }, + Spec = new NativeDeploymentSpec { Images = [] } + }, + "At least one container image must be provided" } }; - // Act & Assert - var exception = await Assert.ThrowsAsync( - () => generator.GenerateAsync(model, "/tmp/test.yaml")); - - Assert.Contains("A non-empty Deployment name must be provided", exception.Message, StringComparison.Ordinal); - } - /// - /// Verifies that an exception is thrown when multiple images are provided with a command. + /// Verifies that exceptions are thrown for invalid configurations. /// + /// The deployment model to test. + /// Expected part of the exception message. /// - [Fact] - public async Task GenerateAsync_WithMultipleImagesAndCommand_ShouldThrowException() + [Theory] + [MemberData(nameof(ExceptionData))] + public async Task GenerateAsync_WithInvalidConfiguration_ShouldThrowException(NativeDeployment model, string expectedMessagePart) { // Arrange var generator = new DeploymentGenerator(); - var model = new NativeDeployment - { - Metadata = new Metadata - { - Name = "test-deployment" - }, - Spec = new NativeDeploymentSpec - { - Images = ["nginx", "busybox"], - Command = ["echo", "hello"] - } - }; // Act & Assert - var exception = await Assert.ThrowsAsync( - () => generator.GenerateAsync(model, "/tmp/test.yaml")); + var exception = await Assert.ThrowsAsync(() => + generator.GenerateAsync(model, "/tmp/test.yaml")); - Assert.Contains("Cannot specify multiple images with a command", exception.Message, StringComparison.Ordinal); + Assert.Contains(expectedMessagePart, exception.Message, StringComparison.Ordinal); } /// - /// Verifies that an exception is thrown when no images are provided. + /// Helper method to generate a file and verify its content. /// - /// - [Fact] - public async Task GenerateAsync_WithNoImages_ShouldThrowException() + /// The model type. + /// The generator type. + /// The generator instance. + /// The model to generate. + /// The file name for verification. + /// A task representing the async operation. + static async Task GenerateAndVerifyAsync( + TGenerator generator, + TModel model, + string fileName) + where TGenerator : IKubernetesGenerator { - // Arrange - var generator = new DeploymentGenerator(); - var model = new NativeDeployment - { - Metadata = new Metadata - { - Name = "test-deployment" - }, - Spec = new NativeDeploymentSpec - { - Images = [] - } - }; + string outputPath = Path.Combine(Path.GetTempPath(), fileName); + if (File.Exists(outputPath)) + File.Delete(outputPath); - // Act & Assert - var exception = await Assert.ThrowsAsync( - () => generator.GenerateAsync(model, "/tmp/test.yaml")); + await generator.GenerateAsync(model, outputPath).ConfigureAwait(false); + string fileContent = await File.ReadAllTextAsync(outputPath).ConfigureAwait(false); - Assert.Contains("At least one container image must be provided", exception.Message, StringComparison.Ordinal); + _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); + + File.Delete(outputPath); } } diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DockerRegistrySecretGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DockerRegistrySecretGeneratorTests/GenerateAsyncTests.cs index c80297bd..bd7d9237 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DockerRegistrySecretGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/DockerRegistrySecretGeneratorTests/GenerateAsyncTests.cs @@ -6,7 +6,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.DockerRegistrySecretGen /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated Docker registry Secret object. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ExternalNameServiceGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ExternalNameServiceGeneratorTests/GenerateAsyncTests.cs index 797f389d..8e76773c 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ExternalNameServiceGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ExternalNameServiceGeneratorTests/GenerateAsyncTests.cs @@ -6,7 +6,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.ExternalNameServiceGene /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated ExternalName Service object. @@ -93,4 +93,4 @@ public async Task GenerateAsync_WithExternalNameServiceWithoutExternalName_Shoul // Act & Assert _ = await Assert.ThrowsAsync(() => generator.GenerateAsync(model, Path.GetTempFileName())); } -} \ No newline at end of file +} diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/GenericSecretGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/GenericSecretGeneratorTests/GenerateAsyncTests.cs index 8594d0f5..337ca141 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/GenericSecretGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/GenericSecretGeneratorTests/GenerateAsyncTests.cs @@ -5,7 +5,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.GenericSecretGeneratorT /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated generic Secret object using NativeGenericSecret input. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/HorizontalPodAutoscalerGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/HorizontalPodAutoscalerGeneratorTests/GenerateAsyncTests.cs index 5fb18f83..b863bee7 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/HorizontalPodAutoscalerGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/HorizontalPodAutoscalerGeneratorTests/GenerateAsyncTests.cs @@ -8,7 +8,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.HorizontalPodAutoscaler /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeHorizontalPodAutoscaler object with full configuration. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/IngressGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/IngressGeneratorTests/GenerateAsyncTests.cs index fd5910c8..c1601c4e 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/IngressGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/IngressGeneratorTests/GenerateAsyncTests.cs @@ -7,7 +7,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.IngressGeneratorTests; /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeIngress object with basic properties. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/JobGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/JobGeneratorTests/GenerateAsyncTests.cs index 0181e7f8..784a680b 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/JobGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/JobGeneratorTests/GenerateAsyncTests.cs @@ -7,7 +7,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.JobGeneratorTests; /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeJob object with image. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/LoadBalancerServiceGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/LoadBalancerServiceGeneratorTests/GenerateAsyncTests.cs index 08f02b8a..fcd66557 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/LoadBalancerServiceGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/LoadBalancerServiceGeneratorTests/GenerateAsyncTests.cs @@ -6,7 +6,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.LoadBalancerServiceGene /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated LoadBalancer Service object. @@ -74,4 +74,4 @@ public async Task GenerateAsync_WithServiceWithoutName_ShouldThrowKubernetesGene // Act & Assert _ = await Assert.ThrowsAsync(() => generator.GenerateAsync(model, Path.GetTempFileName())); } -} \ No newline at end of file +} diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NamespaceGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NamespaceGeneratorTests/GenerateAsyncTests.cs index 3dad5da3..d8cc20ef 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NamespaceGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NamespaceGeneratorTests/GenerateAsyncTests.cs @@ -4,7 +4,6 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.NamespaceGeneratorTests; - /// /// Tests for the class. /// @@ -27,27 +26,19 @@ public async Task GenerateAsync_WithNamespaceModel_ShouldGenerateAValidNamespace } }; - // Act - string fileName = "namespace.yaml"; - string outputPath = Path.Combine(Path.GetTempPath(), fileName); - if (File.Exists(outputPath)) - File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - - // Assert - _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - - // Cleanup - File.Delete(outputPath); + // Act & Assert + await GenerateAndVerifyAsync(generator, model, "namespace.yaml"); } /// - /// Verifies that a is thrown when the namespace name is empty. + /// Verifies that a is thrown when the namespace name is invalid. /// + /// The namespace name to test. /// - [Fact] - public async Task GenerateAsync_WithEmptyNamespaceName_ShouldThrowKubernetesGeneratorException() + [Theory] + [InlineData("")] + [InlineData(null)] + public async Task GenerateAsync_WithInvalidNamespaceName_ShouldThrowKubernetesGeneratorException(string? name) { // Arrange var generator = new NamespaceGenerator(); @@ -55,11 +46,30 @@ public async Task GenerateAsync_WithEmptyNamespaceName_ShouldThrowKubernetesGene { Metadata = new ClusterScopedMetadata { - Name = "" + Name = name! } }; // Act & Assert - _ = await Assert.ThrowsAsync(() => generator.GenerateAsync(model, Path.GetTempFileName())); + _ = await Assert.ThrowsAsync(() => + generator.GenerateAsync(model, Path.GetTempFileName())); + } + + private static async Task GenerateAndVerifyAsync( + TGenerator generator, + TModel model, + string fileName) + where TGenerator : IKubernetesGenerator + { + string outputPath = Path.Combine(Path.GetTempPath(), fileName); + if (File.Exists(outputPath)) + File.Delete(outputPath); + + await generator.GenerateAsync(model, outputPath); + string fileContent = await File.ReadAllTextAsync(outputPath); + + _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); + + File.Delete(outputPath); } } diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NetworkPolicyGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NetworkPolicyGeneratorTests/GenerateAsyncTests.cs index fa8fff66..f73f7724 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NetworkPolicyGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NetworkPolicyGeneratorTests/GenerateAsyncTests.cs @@ -10,7 +10,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.NetworkPolicyGeneratorT /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeNetworkPolicy object with comprehensive features. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NodePortServiceGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NodePortServiceGeneratorTests/GenerateAsyncTests.cs index b26ede73..ff0b1e49 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NodePortServiceGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/NodePortServiceGeneratorTests/GenerateAsyncTests.cs @@ -6,7 +6,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.NodePortServiceGenerato /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NodePort Service object. @@ -75,4 +75,4 @@ public async Task GenerateAsync_WithServiceWithoutName_ShouldThrowKubernetesGene // Act & Assert _ = await Assert.ThrowsAsync(() => generator.GenerateAsync(model, Path.GetTempFileName())); } -} \ No newline at end of file +} diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PersistentVolumeClaimGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PersistentVolumeClaimGeneratorTests/GenerateAsyncTests.cs index da452a84..f784d14f 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PersistentVolumeClaimGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PersistentVolumeClaimGeneratorTests/GenerateAsyncTests.cs @@ -10,7 +10,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.PersistentVolumeClaimGe /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativePersistentVolumeClaim object with comprehensive properties set. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PersistentVolumeGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PersistentVolumeGeneratorTests/GenerateAsyncTests.cs index 3f51de60..39245c86 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PersistentVolumeGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PersistentVolumeGeneratorTests/GenerateAsyncTests.cs @@ -10,7 +10,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.PersistentVolumeGenerat /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativePersistentVolume object with all properties set. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PodDisruptionBudgetGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PodDisruptionBudgetGeneratorTests/GenerateAsyncTests.cs index 7b3a5415..83692590 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PodDisruptionBudgetGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PodDisruptionBudgetGeneratorTests/GenerateAsyncTests.cs @@ -7,7 +7,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.PodDisruptionBudgetGene /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativePodDisruptionBudget object with MinAvailable. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PodGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PodGeneratorTests/GenerateAsyncTests.cs index 40ee3a07..fa232e8b 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PodGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PodGeneratorTests/GenerateAsyncTests.cs @@ -8,7 +8,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.PodGeneratorTests; /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativePod object. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PriorityClassGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PriorityClassGeneratorTests/GenerateAsyncTests.cs index 5893c98d..7a8002cb 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PriorityClassGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/PriorityClassGeneratorTests/GenerateAsyncTests.cs @@ -7,7 +7,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.PriorityClassGeneratorT /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativePriorityClass object with all properties set. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ResourceQuotaGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ResourceQuotaGeneratorTests/GenerateAsyncTests.cs index 9ae23ed3..f043ed0f 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ResourceQuotaGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ResourceQuotaGeneratorTests/GenerateAsyncTests.cs @@ -7,7 +7,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.ResourceQuotaGeneratorT /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeResourceQuota object. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/RoleBindingGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/RoleBindingGeneratorTests/GenerateAsyncTests.cs index 047408da..35545d4b 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/RoleBindingGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/RoleBindingGeneratorTests/GenerateAsyncTests.cs @@ -7,7 +7,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.RoleBindingGeneratorTes /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeRoleBinding object with all properties set. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/RoleGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/RoleGeneratorTests/GenerateAsyncTests.cs index f0554f4c..d5dedb10 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/RoleGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/RoleGeneratorTests/GenerateAsyncTests.cs @@ -8,7 +8,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.RoleGeneratorTests; /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeRole object with basic permissions. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ServiceAccountGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ServiceAccountGeneratorTests/GenerateAsyncTests.cs index 5641c5e8..84fd30bd 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ServiceAccountGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/ServiceAccountGeneratorTests/GenerateAsyncTests.cs @@ -6,49 +6,28 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.ServiceAccountGenerator /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// - /// Verifies the generated ServiceAccount object with basic properties. + /// Test data for valid ServiceAccount generation scenarios. /// - /// - [Fact] - public async Task GenerateAsync_WithBasicProperties_ShouldGenerateAValidServiceAccount() - { - // Arrange - var generator = new ServiceAccountGenerator(); - var model = new V1ServiceAccount + public static TheoryData ValidServiceAccountData => + new() { - ApiVersion = "v1", - Kind = "ServiceAccount", - Metadata = new V1ObjectMeta - { - Name = "self-subject-review", - NamespaceProperty = "default" - } + { "self-subject-review", "default", "service-account.yaml" }, + { "simple-service-account", null, "service-account-no-namespace.yaml" } }; - // Act - string fileName = "service-account.yaml"; - string outputPath = Path.Combine(Path.GetTempPath(), fileName); - if (File.Exists(outputPath)) - File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - - // Assert - _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - - // Cleanup - File.Delete(outputPath); - } - /// - /// Verifies the generated ServiceAccount object with only name (no namespace). + /// Verifies the generated ServiceAccount object with different configurations. /// + /// The ServiceAccount name. + /// The namespace name (can be null). + /// The expected output file name. /// - [Fact] - public async Task GenerateAsync_WithNameOnly_ShouldGenerateAValidServiceAccount() + [Theory] + [MemberData(nameof(ValidServiceAccountData))] + public async Task GenerateAsync_WithValidConfiguration_ShouldGenerateAValidServiceAccount(string name, string? namespaceName, string fileName) { // Arrange var generator = new ServiceAccountGenerator(); @@ -58,23 +37,13 @@ public async Task GenerateAsync_WithNameOnly_ShouldGenerateAValidServiceAccount( Kind = "ServiceAccount", Metadata = new V1ObjectMeta { - Name = "simple-service-account" + Name = name, + NamespaceProperty = namespaceName } }; - // Act - string fileName = "service-account-no-namespace.yaml"; - string outputPath = Path.Combine(Path.GetTempPath(), fileName); - if (File.Exists(outputPath)) - File.Delete(outputPath); - await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); - - // Assert - _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); - - // Cleanup - File.Delete(outputPath); + // Act & Assert + await GenerateAndVerifyAsync(generator, model, fileName); } /// @@ -92,6 +61,34 @@ public async Task GenerateAsync_WithoutName_ShouldThrowKubernetesGeneratorExcept }; // Act & Assert - _ = await Assert.ThrowsAsync(() => generator.GenerateAsync(model, Path.GetTempFileName())); + _ = await Assert.ThrowsAsync(() => + generator.GenerateAsync(model, Path.GetTempFileName())); + } + + /// + /// Helper method to generate a file and verify its content. + /// + /// The model type. + /// The generator type. + /// The generator instance. + /// The model to generate. + /// The file name for verification. + /// A task representing the async operation. + static async Task GenerateAndVerifyAsync( + TGenerator generator, + TModel model, + string fileName) + where TGenerator : IKubernetesGenerator + { + string outputPath = Path.Combine(Path.GetTempPath(), fileName); + if (File.Exists(outputPath)) + File.Delete(outputPath); + + await generator.GenerateAsync(model, outputPath).ConfigureAwait(false); + string fileContent = await File.ReadAllTextAsync(outputPath).ConfigureAwait(false); + + _ = await Verify(fileContent, extension: "yaml").UseFileName(fileName); + + File.Delete(outputPath); } } diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/StatefulSetGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/StatefulSetGeneratorTests/GenerateAsyncTests.cs index d1728a56..22afe1e9 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/StatefulSetGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/StatefulSetGeneratorTests/GenerateAsyncTests.cs @@ -10,7 +10,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.StatefulSetGeneratorTes /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated NativeStatefulSet object with all properties set. diff --git a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/TLSSecretGeneratorTests/GenerateAsyncTests.cs b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/TLSSecretGeneratorTests/GenerateAsyncTests.cs index 77900447..160c3b65 100644 --- a/tests/DevantlerTech.KubernetesGenerator.Native.Tests/TLSSecretGeneratorTests/GenerateAsyncTests.cs +++ b/tests/DevantlerTech.KubernetesGenerator.Native.Tests/TLSSecretGeneratorTests/GenerateAsyncTests.cs @@ -6,7 +6,7 @@ namespace DevantlerTech.KubernetesGenerator.Native.Tests.TLSSecretGeneratorTests /// /// Tests for the class. /// -public sealed class GenerateAsyncTests +internal sealed class GenerateAsyncTests { /// /// Verifies the generated TLS Secret object with certificate and key content. @@ -34,7 +34,7 @@ public async Task GenerateAsync_WithTLSSecretFromContent_ShouldGenerateAValidTLS if (File.Exists(outputPath)) File.Delete(outputPath); await generator.GenerateAsync(model, outputPath); - string fileContent = await File.ReadAllTextAsync(outputPath); + string fileContent = await File.ReadAllTextAsync(outputPath).ConfigureAwait(false); // Assert if (!OperatingSystem.IsWindows())