204 lines
8.5 KiB
C#
204 lines
8.5 KiB
C#
using Xunit;
|
|
using FluentAssertions;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using MongoDB.Driver;
|
|
using BCards.Web.Models;
|
|
using BCards.Web.ViewModels;
|
|
using BCards.Web.Services;
|
|
using BCards.IntegrationTests.Fixtures;
|
|
using BCards.IntegrationTests.Helpers;
|
|
using System.Net;
|
|
|
|
namespace BCards.IntegrationTests.Tests;
|
|
|
|
public class ModerationWorkflowTests : IClassFixture<BCardsWebApplicationFactory>, IAsyncLifetime
|
|
{
|
|
private readonly BCardsWebApplicationFactory _factory;
|
|
private readonly HttpClient _client;
|
|
private MongoDbTestFixture _dbFixture = null!;
|
|
|
|
public ModerationWorkflowTests(BCardsWebApplicationFactory factory)
|
|
{
|
|
_factory = factory;
|
|
_client = _factory.CreateClient();
|
|
}
|
|
|
|
public async Task InitializeAsync()
|
|
{
|
|
using var scope = _factory.Services.CreateScope();
|
|
var database = scope.ServiceProvider.GetRequiredService<IMongoDatabase>();
|
|
_dbFixture = new MongoDbTestFixture(database);
|
|
|
|
await _factory.CleanDatabaseAsync();
|
|
await _dbFixture.InitializeTestDataAsync();
|
|
}
|
|
|
|
public Task DisposeAsync() => Task.CompletedTask;
|
|
|
|
[Fact]
|
|
public async Task SubmitPageForModeration_ShouldChangeStatusToPendingModeration()
|
|
{
|
|
// Arrange
|
|
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
|
|
var page = await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.Creating, "tecnologia", 3, 1);
|
|
var authenticatedClient = await AuthenticationHelper.CreateAuthenticatedClientAsync(_factory, user);
|
|
|
|
// Act - Submit page for moderation
|
|
var response = await authenticatedClient.PostAsync($"/Admin/SubmitForModeration/{page.Id}", null);
|
|
|
|
// Assert
|
|
response.IsSuccessStatusCode.Should().BeTrue();
|
|
|
|
// Verify page status changed in database
|
|
var updatedPages = await _dbFixture.GetUserPagesAsync(user.Id);
|
|
var updatedPage = updatedPages.First();
|
|
|
|
updatedPage.Status.Should().Be(PageStatus.PendingModeration);
|
|
updatedPage.ModerationAttempts.Should().BeGreaterThan(0);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SubmitPageForModeration_WithoutActiveLinks_ShouldFail()
|
|
{
|
|
// Arrange
|
|
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
|
|
var page = await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.Creating, "tecnologia", 0, 0); // No links
|
|
var authenticatedClient = await AuthenticationHelper.CreateAuthenticatedClientAsync(_factory, user);
|
|
|
|
// Act
|
|
var response = await authenticatedClient.PostAsync($"/Admin/SubmitForModeration/{page.Id}", null);
|
|
|
|
// Assert
|
|
response.IsSuccessStatusCode.Should().BeFalse();
|
|
|
|
// Verify page status didn't change
|
|
var updatedPages = await _dbFixture.GetUserPagesAsync(user.Id);
|
|
var updatedPage = updatedPages.First();
|
|
|
|
updatedPage.Status.Should().Be(PageStatus.Creating);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ApprovePage_ShouldChangeStatusToActive()
|
|
{
|
|
// Arrange
|
|
using var scope = _factory.Services.CreateScope();
|
|
var moderationService = scope.ServiceProvider.GetRequiredService<IModerationService>();
|
|
|
|
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
|
|
var page = await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.PendingModeration, "tecnologia", 3, 1);
|
|
|
|
// Act - Approve the page
|
|
await moderationService.ApprovePageAsync(page.Id, "test-moderator-id", "Page looks good");
|
|
|
|
// Assert
|
|
var updatedPages = await _dbFixture.GetUserPagesAsync(user.Id);
|
|
var updatedPage = updatedPages.First();
|
|
|
|
updatedPage.Status.Should().Be(PageStatus.Active);
|
|
updatedPage.ApprovedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromMinutes(1));
|
|
updatedPage.ModerationHistory.Should().HaveCount(1);
|
|
updatedPage.ModerationHistory.First().Status.Should().Be("approved");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RejectPage_ShouldChangeStatusToRejected()
|
|
{
|
|
// Arrange
|
|
using var scope = _factory.Services.CreateScope();
|
|
var moderationService = scope.ServiceProvider.GetRequiredService<IModerationService>();
|
|
|
|
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
|
|
var page = await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.PendingModeration, "tecnologia", 3, 1);
|
|
|
|
// Act - Reject the page
|
|
await moderationService.RejectPageAsync(page.Id, "test-moderator-id", "Inappropriate content", new List<string> { "spam", "offensive" });
|
|
|
|
// Assert
|
|
var updatedPages = await _dbFixture.GetUserPagesAsync(user.Id);
|
|
var updatedPage = updatedPages.First();
|
|
|
|
updatedPage.Status.Should().Be(PageStatus.Inactive); // First rejection goes to Inactive
|
|
updatedPage.ModerationHistory.Should().HaveCount(1);
|
|
|
|
var rejectionHistory = updatedPage.ModerationHistory.First();
|
|
rejectionHistory.Status.Should().Be("rejected");
|
|
rejectionHistory.Reason.Should().Be("Inappropriate content");
|
|
rejectionHistory.Issues.Should().Contain("spam");
|
|
rejectionHistory.Issues.Should().Contain("offensive");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task AccessApprovedPage_WithoutPreviewToken_ShouldSucceed()
|
|
{
|
|
// Arrange
|
|
using var scope = _factory.Services.CreateScope();
|
|
var moderationService = scope.ServiceProvider.GetRequiredService<IModerationService>();
|
|
|
|
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
|
|
var page = await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.PendingModeration, "tecnologia", 3, 1);
|
|
|
|
// Approve the page
|
|
await moderationService.ApprovePageAsync(page.Id, "test-moderator-id", "Approved");
|
|
|
|
// Act - Access the page without preview token
|
|
var response = await _client.GetAsync($"/page/{page.Category}/{page.Slug}");
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
|
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
content.Should().Contain(page.DisplayName);
|
|
content.Should().NotContain("MODO PREVIEW"); // Should not show preview banner
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetPendingModerationPages_ShouldReturnCorrectPages()
|
|
{
|
|
// Arrange
|
|
using var scope = _factory.Services.CreateScope();
|
|
var moderationService = scope.ServiceProvider.GetRequiredService<IModerationService>();
|
|
|
|
var user1 = await _dbFixture.CreateTestUserAsync(PlanType.Basic, "user1@example.com");
|
|
var user2 = await _dbFixture.CreateTestUserAsync(PlanType.Basic, "user2@example.com");
|
|
|
|
// Create pages in different statuses
|
|
await _dbFixture.CreateTestUserPageAsync(user1.Id, PageStatus.PendingModeration, "tecnologia", 3, 1);
|
|
await _dbFixture.CreateTestUserPageAsync(user2.Id, PageStatus.PendingModeration, "negocios", 4, 2);
|
|
await _dbFixture.CreateTestUserPageAsync(user1.Id, PageStatus.Creating, "pessoal", 2, 0); // Should not appear
|
|
await _dbFixture.CreateTestUserPageAsync(user2.Id, PageStatus.Active, "saude", 5, 1); // Should not appear
|
|
|
|
// Act
|
|
var pendingPages = await moderationService.GetPendingModerationAsync();
|
|
|
|
// Assert
|
|
pendingPages.Should().HaveCount(2);
|
|
pendingPages.Should().OnlyContain(p => p.Status == PageStatus.PendingModeration);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ModerationStats_ShouldReturnCorrectCounts()
|
|
{
|
|
// Arrange
|
|
using var scope = _factory.Services.CreateScope();
|
|
var moderationService = scope.ServiceProvider.GetRequiredService<IModerationService>();
|
|
|
|
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
|
|
|
|
// Create pages with different statuses
|
|
var pendingPage1 = await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.PendingModeration, "tecnologia", 3, 1);
|
|
var pendingPage2 = await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.PendingModeration, "negocios", 3, 1);
|
|
var activePage = await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.PendingModeration, "pessoal", 3, 1);
|
|
|
|
// Approve one page today
|
|
await moderationService.ApprovePageAsync(activePage.Id, "moderator", "Good");
|
|
|
|
// Act
|
|
var stats = await moderationService.GetModerationStatsAsync();
|
|
|
|
// Assert
|
|
stats["pending"].Should().Be(2);
|
|
stats["approvedToday"].Should().Be(1);
|
|
stats["rejectedToday"].Should().Be(0);
|
|
}
|
|
} |