BCards/src/BCards.IntegrationTests/Tests/PageCreationTests.cs
2025-07-14 23:21:25 -03:00

238 lines
9.7 KiB
C#

using Xunit;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;
using BCards.Web.Models;
using BCards.Web.ViewModels;
using BCards.IntegrationTests.Fixtures;
using BCards.IntegrationTests.Helpers;
using System.Net.Http.Json;
namespace BCards.IntegrationTests.Tests;
public class PageCreationTests : IClassFixture<BCardsWebApplicationFactory>, IAsyncLifetime
{
private readonly BCardsWebApplicationFactory _factory;
private readonly HttpClient _client;
private MongoDbTestFixture _dbFixture = null!;
public PageCreationTests(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 CreatePage_WithBasicPlan_ShouldAllowUpTo5Links()
{
// Arrange
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
var authenticatedClient = await AuthenticationHelper.CreateAuthenticatedClientAsync(_factory, user);
// Act - Create a page with 5 links (should succeed)
var pageData = new
{
DisplayName = "Test Business Page",
Category = "tecnologia",
BusinessType = "company",
Bio = "A test business page",
Slug = "test-business",
SelectedTheme = "minimalist",
Links = new[]
{
new { Title = "Website", Url = "https://example.com", Description = "Main website", Icon = "fas fa-globe" },
new { Title = "Email", Url = "mailto:contact@example.com", Description = "Contact email", Icon = "fas fa-envelope" },
new { Title = "Phone", Url = "tel:+5511999999999", Description = "Contact phone", Icon = "fas fa-phone" },
new { Title = "LinkedIn", Url = "https://linkedin.com/company/example", Description = "LinkedIn profile", Icon = "fab fa-linkedin" },
new { Title = "Instagram", Url = "https://instagram.com/example", Description = "Instagram profile", Icon = "fab fa-instagram" }
}
};
var createResponse = await authenticatedClient.PostAsJsonAsync("/Admin/ManagePage", pageData);
// Assert
createResponse.IsSuccessStatusCode.Should().BeTrue("Basic plan should allow 5 links");
// Verify page was created in database
var createdPages = await _dbFixture.GetUserPagesAsync(user.Id);
createdPages.Should().HaveCount(1);
var createdPage = createdPages.First();
createdPage.DisplayName.Should().Be("Test Business Page");
createdPage.Category.Should().Be("tecnologia");
createdPage.Status.Should().Be(PageStatus.Creating);
createdPage.Links.Should().HaveCount(5);
}
[Fact]
public async Task CreatePage_WithBasicPlanExceedingLimits_ShouldFail()
{
// Arrange
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
var authenticatedClient = await AuthenticationHelper.CreateAuthenticatedClientAsync(_factory, user);
// Act - Try to create a page with 6 links (should fail for Basic plan)
var pageData = new
{
DisplayName = "Test Page Exceeding Limits",
Category = "tecnologia",
BusinessType = "individual",
Bio = "A test page with too many links",
Slug = "test-exceeding",
SelectedTheme = "minimalist",
Links = new[]
{
new { Title = "Link 1", Url = "https://example1.com", Description = "Link 1", Icon = "fas fa-link" },
new { Title = "Link 2", Url = "https://example2.com", Description = "Link 2", Icon = "fas fa-link" },
new { Title = "Link 3", Url = "https://example3.com", Description = "Link 3", Icon = "fas fa-link" },
new { Title = "Link 4", Url = "https://example4.com", Description = "Link 4", Icon = "fas fa-link" },
new { Title = "Link 5", Url = "https://example5.com", Description = "Link 5", Icon = "fas fa-link" },
new { Title = "Link 6", Url = "https://example6.com", Description = "Link 6", Icon = "fas fa-link" } // This should fail
}
};
var createResponse = await authenticatedClient.PostAsJsonAsync("/Admin/ManagePage", pageData);
// Assert
createResponse.IsSuccessStatusCode.Should().BeFalse("Basic plan should not allow more than 5 links");
// Verify no page was created
var createdPages = await _dbFixture.GetUserPagesAsync(user.Id);
createdPages.Should().BeEmpty();
}
[Fact]
public async Task CreatePage_ShouldStartInCreatingStatus()
{
// Arrange
var user = await _dbFixture.CreateTestUserAsync(PlanType.Basic);
var authenticatedClient = await AuthenticationHelper.CreateAuthenticatedClientAsync(_factory, user);
// Act
var pageData = new
{
DisplayName = "New Page",
Category = "pessoal",
BusinessType = "individual",
Bio = "Test page bio",
Slug = "new-page",
SelectedTheme = "minimalist",
Links = new[]
{
new { Title = "Portfolio", Url = "https://myportfolio.com", Description = "My work", Icon = "fas fa-briefcase" }
}
};
var createResponse = await authenticatedClient.PostAsJsonAsync("/Admin/ManagePage", pageData);
// Assert
createResponse.IsSuccessStatusCode.Should().BeTrue();
var createdPages = await _dbFixture.GetUserPagesAsync(user.Id);
var page = createdPages.First();
page.Status.Should().Be(PageStatus.Creating);
page.PreviewToken.Should().NotBeNullOrEmpty("Creating pages should have preview tokens");
page.PreviewTokenExpiry.Should().BeAfter(DateTime.UtcNow.AddHours(3), "Preview token should be valid for ~4 hours");
}
[Fact]
public async Task CreatePage_WithTrialPlan_ShouldAllowOnePageOnly()
{
// Arrange
var user = await _dbFixture.CreateTestUserAsync(PlanType.Trial);
var authenticatedClient = await AuthenticationHelper.CreateAuthenticatedClientAsync(_factory, user);
// Act - Create first page (should succeed)
var firstPageData = new
{
DisplayName = "First Trial Page",
Category = "pessoal",
BusinessType = "individual",
Bio = "First page in trial",
Slug = "first-trial",
SelectedTheme = "minimalist",
Links = new[]
{
new { Title = "Website", Url = "https://example.com", Description = "My website", Icon = "fas fa-globe" }
}
};
var firstResponse = await authenticatedClient.PostAsJsonAsync("/Admin/ManagePage", firstPageData);
firstResponse.IsSuccessStatusCode.Should().BeTrue("Trial should allow first page");
// Act - Try to create second page (should fail)
var secondPageData = new
{
DisplayName = "Second Trial Page",
Category = "tecnologia",
BusinessType = "individual",
Bio = "Second page in trial - should fail",
Slug = "second-trial",
SelectedTheme = "minimalist",
Links = new[]
{
new { Title = "LinkedIn", Url = "https://linkedin.com/in/test", Description = "LinkedIn", Icon = "fab fa-linkedin" }
}
};
var secondResponse = await authenticatedClient.PostAsJsonAsync("/Admin/ManagePage", secondPageData);
// Assert
secondResponse.IsSuccessStatusCode.Should().BeFalse("Trial should not allow second page");
var createdPages = await _dbFixture.GetUserPagesAsync(user.Id);
createdPages.Should().HaveCount(1, "Trial should only have one page");
}
[Fact]
public async Task CreatePage_ShouldGenerateUniqueSlug()
{
// Arrange
var user = await _dbFixture.CreateTestUserAsync(PlanType.Professional);
var authenticatedClient = await AuthenticationHelper.CreateAuthenticatedClientAsync(_factory, user);
// Create first page with specific slug
await _dbFixture.CreateTestUserPageAsync(user.Id, PageStatus.Active, "tecnologia", 3, 1, "test-slug");
// Act - Try to create another page with same name (should get different slug)
var pageData = new
{
DisplayName = "Test Page", // Same display name, should generate different slug
Category = "tecnologia",
BusinessType = "individual",
Bio = "Another test page",
Slug = "test-slug", // Try to use same slug
SelectedTheme = "minimalist",
Links = new[]
{
new { Title = "Website", Url = "https://example.com", Description = "Website", Icon = "fas fa-globe" }
}
};
var createResponse = await authenticatedClient.PostAsJsonAsync("/Admin/ManagePage", pageData);
// Assert
createResponse.IsSuccessStatusCode.Should().BeTrue();
var userPages = await _dbFixture.GetUserPagesAsync(user.Id);
userPages.Should().HaveCount(2);
var slugs = userPages.Select(p => p.Slug).ToList();
slugs.Should().OnlyHaveUniqueItems("All pages should have unique slugs");
slugs.Should().Contain("test-slug");
slugs.Should().Contain(slug => slug.StartsWith("test-slug-") || slug == "test-page");
}
}