diff --git a/services/ads-analytics-service-net/tests/AdsAnalyticsService.FunctionalTests/Controllers/AnalyticsMetricsControllerTests.cs b/services/ads-analytics-service-net/tests/AdsAnalyticsService.FunctionalTests/Controllers/AnalyticsMetricsControllerTests.cs
new file mode 100644
index 00000000..1da90381
--- /dev/null
+++ b/services/ads-analytics-service-net/tests/AdsAnalyticsService.FunctionalTests/Controllers/AnalyticsMetricsControllerTests.cs
@@ -0,0 +1,44 @@
+using System.Net;
+using FluentAssertions;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Xunit;
+
+namespace AdsAnalyticsService.FunctionalTests.Controllers;
+
+///
+/// EN: Functional tests for analytics metrics and health endpoints.
+/// VI: Functional tests cho endpoint metrics analytics và health.
+///
+public class AnalyticsMetricsControllerTests : IClassFixture
+{
+ private readonly HttpClient _client;
+
+ public AnalyticsMetricsControllerTests(CustomWebApplicationFactory factory)
+ {
+ _client = factory.CreateClient(new WebApplicationFactoryClientOptions
+ {
+ AllowAutoRedirect = false,
+ });
+ }
+
+ [Fact]
+ public async Task GetCampaignMetrics_WithUnknownCampaign_ShouldReturnNotFound()
+ {
+ // Act
+ var response = await _client.GetAsync(
+ $"/api/v1/ads-analytics/campaigns/{Guid.NewGuid()}/metrics");
+
+ // Assert
+ response.StatusCode.Should().Be(HttpStatusCode.NotFound);
+ }
+
+ [Fact]
+ public async Task HealthCheck_ShouldReturnHealthy()
+ {
+ // Act
+ var response = await _client.GetAsync("/health/live");
+
+ // Assert
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+}
diff --git a/services/ads-analytics-service-net/tests/AdsAnalyticsService.FunctionalTests/Controllers/SamplesControllerTests.cs b/services/ads-analytics-service-net/tests/AdsAnalyticsService.FunctionalTests/Controllers/SamplesControllerTests.cs
deleted file mode 100644
index 31fa743e..00000000
--- a/services/ads-analytics-service-net/tests/AdsAnalyticsService.FunctionalTests/Controllers/SamplesControllerTests.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System.Net;
-using System.Net.Http.Json;
-using FluentAssertions;
-using Microsoft.AspNetCore.Mvc.Testing;
-using Xunit;
-
-namespace AdsAnalyticsService.FunctionalTests.Controllers;
-
-///
-/// EN: Functional tests for Samples API endpoints.
-/// VI: Functional tests cho các endpoints API Samples.
-///
-public class SamplesControllerTests : IClassFixture
-{
- private readonly HttpClient _client;
-
- public SamplesControllerTests(CustomWebApplicationFactory factory)
- {
- _client = factory.CreateClient(new WebApplicationFactoryClientOptions
- {
- AllowAutoRedirect = false
- });
- }
-
- [Fact]
- public async Task GetSamples_ShouldReturnOkWithEmptyList()
- {
- // Act
- var response = await _client.GetAsync("/api/v1/samples");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.OK);
- var content = await response.Content.ReadFromJsonAsync>>();
- content?.Success.Should().BeTrue();
- }
-
- [Fact]
- public async Task CreateSample_WithValidData_ShouldReturnCreated()
- {
- // Arrange
- var request = new { Name = "Test Sample", Description = "Test Description" };
-
- // Act
- var response = await _client.PostAsJsonAsync("/api/v1/samples", request);
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.Created);
- var content = await response.Content.ReadFromJsonAsync>();
- content?.Success.Should().BeTrue();
- content?.Data?.Id.Should().NotBeEmpty();
- }
-
- [Fact]
- public async Task GetSample_WithInvalidId_ShouldReturnNotFound()
- {
- // Arrange
- var invalidId = Guid.NewGuid();
-
- // Act
- var response = await _client.GetAsync($"/api/v1/samples/{invalidId}");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.NotFound);
- }
-
- [Fact]
- public async Task HealthCheck_ShouldReturnHealthy()
- {
- // Act
- var response = await _client.GetAsync("/health/live");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.OK);
- }
-
- // EN: Helper DTOs for deserialization
- // VI: Helper DTOs để deserialize
- private record ApiResponse(bool Success, T? Data);
- private record CreateSampleResult(Guid Id);
-}
diff --git a/services/ads-manager-service-net/tests/AdsManagerService.FunctionalTests/Controllers/CampaignsControllerTests.cs b/services/ads-manager-service-net/tests/AdsManagerService.FunctionalTests/Controllers/CampaignsControllerTests.cs
new file mode 100644
index 00000000..8a20f6b5
--- /dev/null
+++ b/services/ads-manager-service-net/tests/AdsManagerService.FunctionalTests/Controllers/CampaignsControllerTests.cs
@@ -0,0 +1,43 @@
+using System.Net;
+using FluentAssertions;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Xunit;
+
+namespace AdsManagerService.FunctionalTests.Controllers;
+
+///
+/// EN: Functional tests for campaign listing and health endpoints.
+/// VI: Functional tests cho endpoint danh sách campaign và health.
+///
+public class CampaignsControllerTests : IClassFixture
+{
+ private readonly HttpClient _client;
+
+ public CampaignsControllerTests(CustomWebApplicationFactory factory)
+ {
+ _client = factory.CreateClient(new WebApplicationFactoryClientOptions
+ {
+ AllowAutoRedirect = false,
+ });
+ }
+
+ [Fact]
+ public async Task ListCampaigns_ShouldReturnOk()
+ {
+ // Act
+ var response = await _client.GetAsync("/api/v1/ads-manager/campaigns");
+
+ // Assert
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ [Fact]
+ public async Task HealthCheck_ShouldReturnHealthy()
+ {
+ // Act
+ var response = await _client.GetAsync("/health/live");
+
+ // Assert
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+}
diff --git a/services/ads-manager-service-net/tests/AdsManagerService.FunctionalTests/Controllers/SamplesControllerTests.cs b/services/ads-manager-service-net/tests/AdsManagerService.FunctionalTests/Controllers/SamplesControllerTests.cs
deleted file mode 100644
index 5c40ae2b..00000000
--- a/services/ads-manager-service-net/tests/AdsManagerService.FunctionalTests/Controllers/SamplesControllerTests.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System.Net;
-using System.Net.Http.Json;
-using FluentAssertions;
-using Microsoft.AspNetCore.Mvc.Testing;
-using Xunit;
-
-namespace AdsManagerService.FunctionalTests.Controllers;
-
-///
-/// EN: Functional tests for Samples API endpoints.
-/// VI: Functional tests cho các endpoints API Samples.
-///
-public class SamplesControllerTests : IClassFixture
-{
- private readonly HttpClient _client;
-
- public SamplesControllerTests(CustomWebApplicationFactory factory)
- {
- _client = factory.CreateClient(new WebApplicationFactoryClientOptions
- {
- AllowAutoRedirect = false
- });
- }
-
- [Fact]
- public async Task GetSamples_ShouldReturnOkWithEmptyList()
- {
- // Act
- var response = await _client.GetAsync("/api/v1/samples");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.OK);
- var content = await response.Content.ReadFromJsonAsync>>();
- content?.Success.Should().BeTrue();
- }
-
- [Fact]
- public async Task CreateSample_WithValidData_ShouldReturnCreated()
- {
- // Arrange
- var request = new { Name = "Test Sample", Description = "Test Description" };
-
- // Act
- var response = await _client.PostAsJsonAsync("/api/v1/samples", request);
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.Created);
- var content = await response.Content.ReadFromJsonAsync>();
- content?.Success.Should().BeTrue();
- content?.Data?.Id.Should().NotBeEmpty();
- }
-
- [Fact]
- public async Task GetSample_WithInvalidId_ShouldReturnNotFound()
- {
- // Arrange
- var invalidId = Guid.NewGuid();
-
- // Act
- var response = await _client.GetAsync($"/api/v1/samples/{invalidId}");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.NotFound);
- }
-
- [Fact]
- public async Task HealthCheck_ShouldReturnHealthy()
- {
- // Act
- var response = await _client.GetAsync("/health/live");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.OK);
- }
-
- // EN: Helper DTOs for deserialization
- // VI: Helper DTOs để deserialize
- private record ApiResponse(bool Success, T? Data);
- private record CreateSampleResult(Guid Id);
-}
diff --git a/services/ads-tracking-service-net/tests/AdsTrackingService.FunctionalTests/Controllers/PixelsControllerTests.cs b/services/ads-tracking-service-net/tests/AdsTrackingService.FunctionalTests/Controllers/PixelsControllerTests.cs
new file mode 100644
index 00000000..80f41814
--- /dev/null
+++ b/services/ads-tracking-service-net/tests/AdsTrackingService.FunctionalTests/Controllers/PixelsControllerTests.cs
@@ -0,0 +1,44 @@
+using System.Net;
+using FluentAssertions;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Xunit;
+
+namespace AdsTrackingService.FunctionalTests.Controllers;
+
+///
+/// EN: Functional tests for tracking pixel and health endpoints.
+/// VI: Functional tests cho endpoint tracking pixel và health.
+///
+public class PixelsControllerTests : IClassFixture
+{
+ private readonly HttpClient _client;
+
+ public PixelsControllerTests(CustomWebApplicationFactory factory)
+ {
+ _client = factory.CreateClient(new WebApplicationFactoryClientOptions
+ {
+ AllowAutoRedirect = false,
+ });
+ }
+
+ [Fact]
+ public async Task GetPixelCode_WithUnknownAdvertiser_ShouldReturnNotFound()
+ {
+ // Act
+ var response = await _client.GetAsync(
+ $"/api/v1/ads-tracking/pixels/{Guid.NewGuid()}");
+
+ // Assert
+ response.StatusCode.Should().Be(HttpStatusCode.NotFound);
+ }
+
+ [Fact]
+ public async Task HealthCheck_ShouldReturnHealthy()
+ {
+ // Act
+ var response = await _client.GetAsync("/health/live");
+
+ // Assert
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+}
diff --git a/services/ads-tracking-service-net/tests/AdsTrackingService.FunctionalTests/Controllers/SamplesControllerTests.cs b/services/ads-tracking-service-net/tests/AdsTrackingService.FunctionalTests/Controllers/SamplesControllerTests.cs
deleted file mode 100644
index 5ae5f542..00000000
--- a/services/ads-tracking-service-net/tests/AdsTrackingService.FunctionalTests/Controllers/SamplesControllerTests.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System.Net;
-using System.Net.Http.Json;
-using FluentAssertions;
-using Microsoft.AspNetCore.Mvc.Testing;
-using Xunit;
-
-namespace AdsTrackingService.FunctionalTests.Controllers;
-
-///
-/// EN: Functional tests for Samples API endpoints.
-/// VI: Functional tests cho các endpoints API Samples.
-///
-public class SamplesControllerTests : IClassFixture
-{
- private readonly HttpClient _client;
-
- public SamplesControllerTests(CustomWebApplicationFactory factory)
- {
- _client = factory.CreateClient(new WebApplicationFactoryClientOptions
- {
- AllowAutoRedirect = false
- });
- }
-
- [Fact]
- public async Task GetSamples_ShouldReturnOkWithEmptyList()
- {
- // Act
- var response = await _client.GetAsync("/api/v1/samples");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.OK);
- var content = await response.Content.ReadFromJsonAsync>>();
- content?.Success.Should().BeTrue();
- }
-
- [Fact]
- public async Task CreateSample_WithValidData_ShouldReturnCreated()
- {
- // Arrange
- var request = new { Name = "Test Sample", Description = "Test Description" };
-
- // Act
- var response = await _client.PostAsJsonAsync("/api/v1/samples", request);
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.Created);
- var content = await response.Content.ReadFromJsonAsync>();
- content?.Success.Should().BeTrue();
- content?.Data?.Id.Should().NotBeEmpty();
- }
-
- [Fact]
- public async Task GetSample_WithInvalidId_ShouldReturnNotFound()
- {
- // Arrange
- var invalidId = Guid.NewGuid();
-
- // Act
- var response = await _client.GetAsync($"/api/v1/samples/{invalidId}");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.NotFound);
- }
-
- [Fact]
- public async Task HealthCheck_ShouldReturnHealthy()
- {
- // Act
- var response = await _client.GetAsync("/health/live");
-
- // Assert
- response.StatusCode.Should().Be(HttpStatusCode.OK);
- }
-
- // EN: Helper DTOs for deserialization
- // VI: Helper DTOs để deserialize
- private record ApiResponse(bool Success, T? Data);
- private record CreateSampleResult(Guid Id);
-}