Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
60de2bd
refactor: apply code review nitpick improvements
Nov 25, 2025
516a2a0
fix: remove ConfigurableTestAuthenticationHandler race condition
Nov 25, 2025
0e48824
docs: remove obsolete documentation files
Nov 25, 2025
e50f728
feat: add IDocumentsModuleApi for cross-module communication
Nov 25, 2025
e046895
wip: add comprehensive IBGE API stubs to WireMock + refactor IbgeApiI…
Nov 25, 2025
efdd1ef
feat: add IServiceCatalogsModuleApi for cross-module service validation
Nov 25, 2025
6302d16
fix: refactor IbgeApiIntegrationTests to use WireMock + fix stubs
Nov 25, 2025
916e4dd
test: remove Skip from 2 ServiceCatalogs integration tests after AUTH…
Nov 25, 2025
4940bc2
fix: enable IBGE fail-open with fallback to simple validation
Nov 25, 2025
97dc7ac
feat(providers): integrate IDocumentsModuleApi in provider activation
Nov 25, 2025
62e46fa
feat(providers): prepare ISearchModuleApi integration for provider in…
Nov 25, 2025
a6ad166
feat(search): implement IndexProviderAsync and RemoveProviderAsync in…
Nov 25, 2025
c63ad65
test: remove duplicate GeographicRestrictionFeatureFlagTests
Nov 25, 2025
65897e9
docs: update Sprint 1 progress and skipped tests analysis
Nov 25, 2025
8ca60ea
docs: comprehensive Module APIs documentation in architecture.md
Nov 25, 2025
234a20f
docs: Sprint 1 final summary and completion report
Nov 25, 2025
b77eb08
feat(providers): implement full provider data sync for search indexing
Nov 25, 2025
2cf5816
feat(providers): add ProviderServices many-to-many table
Nov 25, 2025
b355776
test(providers): add comprehensive unit tests for ProviderServices
Nov 25, 2025
bff2381
refactor: rename infrastructure/database/modules folders and update S…
Nov 25, 2025
3d8b469
fix: make SearchProviders schema migration conditional for TestContai…
Nov 25, 2025
4aa726a
fix: corrigir schema hardcoded 'search' para 'search_providers' em qu…
Nov 25, 2025
938c55d
fix: atualizar schema 'search' para 'search_providers' em SearchProvi…
Nov 25, 2025
b317f38
feat: implement cross-module event handlers and fix SearchProviders s…
Nov 26, 2025
ca4b2f9
test: skip CreateAndUpdateUser_ShouldMaintainConsistency in CI/CD
Nov 26, 2025
17b6e55
refactor: code review fixes - remove duplicates, fix schemas, regener…
Nov 26, 2025
5dad19a
chore: final code review fixes - documentation, security, domain events
Nov 26, 2025
ac601cb
fix: correct schema naming to meajudaai_* pattern across all modules
Nov 26, 2025
b98c132
refactor: code quality improvements from review feedback
Nov 26, 2025
59e6265
refactor: minor code quality improvements
Nov 26, 2025
025aee0
test: improve test quality with explicit assertions and Theory pattern
Nov 26, 2025
ee4d1b2
refactor: use IReadOnlyList in ModuleServiceValidationResultDto
Nov 26, 2025
3d7b31b
fix: resolve race condition in ConfigurableTestAuthenticationHandler
Nov 26, 2025
78e47cb
fix: consolidate schema naming to meajudaai_* convention across all m…
Nov 26, 2025
dfa7f10
perf: reduce WireMock timeout simulation from 30s to 5s
Nov 26, 2025
5221f44
refactor: implement code review feedback - Result Match pattern, repo…
Nov 26, 2025
51f7e0d
refactor: rename Mock* to LocalDevelopment* services and move to dedi…
Nov 26, 2025
512cd66
fix: allowUnauthenticated should return anonymous principal, not admin
Nov 26, 2025
780cae9
fix: address CodeRabbit review feedback
Nov 26, 2025
9bfff7c
refactor: implement CodeRabbit Round 2 feedback - null guards, XML do…
Nov 26, 2025
0be5389
refactor: apply minor CodeRabbit polish - constants and comments
Nov 26, 2025
c69c404
feat: implement remaining CodeRabbit suggestions - UUID v7, migration…
Nov 27, 2025
93592d7
refactor: implement CodeRabbit final round - schema standardization, …
Nov 27, 2025
e0b4db3
refactor: complete CodeRabbit final polish - ProductVersion stable, h…
Nov 27, 2025
63a4a2d
fix: resolve E2E test failures - authentication and category deactiva…
Nov 27, 2025
274b378
refactor: apply CodeRabbit feedback - schema naming, async cleanup, t…
Nov 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: refactor IbgeApiIntegrationTests to use WireMock + fix stubs
Fixed IbgeApiIntegrationTests compilation errors by:
- Changed inheritance from standalone to ApiTestBase
- Updated to use only existing IbgeClient methods (3 methods)
- Fixed WireMock stubs to match actual IbgeClient requests (no orderBy param)
- Added catch-all stub for unknown cities (returns 200 with empty array)

All 9 IBGE integration tests now passing.

Co-authored-by: GitHub Copilot <noreply@github.com>
  • Loading branch information
Filipe Frigini and web-flow committed Nov 25, 2025
commit 6302d16bb49d79da5862e4413c6be8795971836c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ private void ConfigureIbgeStubs()
.Given(WireMock.RequestBuilders.Request.Create()
.WithPath("/api/v1/localidades/municipios")
.WithParam("nome", "muriaé")
.WithParam("orderBy", "nome")
.UsingGet())
.RespondWith(WireMock.ResponseBuilders.Response.Create()
.WithStatusCode(200)
Expand Down Expand Up @@ -88,7 +87,6 @@ private void ConfigureIbgeStubs()
.Given(WireMock.RequestBuilders.Request.Create()
.WithPath("/api/v1/localidades/municipios")
.WithParam("nome", "itaperuna")
.WithParam("orderBy", "nome")
.UsingGet())
.RespondWith(WireMock.ResponseBuilders.Response.Create()
.WithStatusCode(200)
Expand Down Expand Up @@ -274,7 +272,6 @@ private void ConfigureIbgeStubs()
.Given(WireMock.RequestBuilders.Request.Create()
.WithPath("/api/v1/localidades/municipios")
.WithParam("nome", "são paulo")
.WithParam("orderBy", "nome")
.UsingGet())
.RespondWith(WireMock.ResponseBuilders.Response.Create()
.WithStatusCode(200)
Expand All @@ -300,6 +297,19 @@ private void ConfigureIbgeStubs()
}]
"""));

// Catch-all for unknown cities - return empty array (200 status, not 404)
// This allows IbgeClient to return null instead of throwing exception
Server
.Given(WireMock.RequestBuilders.Request.Create()
.WithPath("/api/v1/localidades/municipios")
.WithParam("nome") // Match any nome parameter
.UsingGet())
.AtPriority(100) // Lower priority so specific stubs match first
.RespondWith(WireMock.ResponseBuilders.Response.Create()
.WithStatusCode(200)
.WithHeader("Content-Type", "application/json; charset=utf-8")
.WithBody("[]"));

// Service unavailability simulation - 500 error
Server
.Given(WireMock.RequestBuilders.Request.Create()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using FluentAssertions;
using MeAjudaAi.Integration.Tests.Base;
using MeAjudaAi.Modules.Locations.Infrastructure.ExternalApis.Clients;
using MeAjudaAi.Modules.Locations.Infrastructure.ExternalApis.Clients.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

Expand All @@ -14,12 +14,9 @@ namespace MeAjudaAi.Integration.Tests.Modules.Locations;
[Trait("Module", "Locations")]
public sealed class IbgeApiIntegrationTests : ApiTestBase
{
private readonly IbgeClient _ibgeClient;
private IIbgeClient IbgeClient => Services.GetRequiredService<IIbgeClient>();

public IbgeApiIntegrationTests()
{
_ibgeClient = ServiceProvider.GetRequiredService<IbgeClient>();
}
#region GetMunicipioByNameAsync Tests

[Fact]
public async Task GetMunicipioByNameAsync_Muriae_ShouldReturnValidMunicipio()
Expand All @@ -28,7 +25,7 @@ public async Task GetMunicipioByNameAsync_Muriae_ShouldReturnValidMunicipio()
const string cityName = "Muriaé";

// Act
var result = await _ibgeClient.GetMunicipioByNameAsync(cityName);
var result = await IbgeClient.GetMunicipioByNameAsync(cityName);

// Assert
result.Should().NotBeNull("Muriaé deve existir no WireMock stub");
Expand All @@ -54,7 +51,7 @@ public async Task GetMunicipioByNameAsync_Itaperuna_ShouldReturnValidMunicipio()
const string cityName = "Itaperuna";

// Act
var result = await _ibgeClient.GetMunicipioByNameAsync(cityName);
var result = await IbgeClient.GetMunicipioByNameAsync(cityName);

// Assert
result.Should().NotBeNull("Itaperuna deve existir no WireMock stub");
Expand All @@ -69,125 +66,112 @@ public async Task GetMunicipioByNameAsync_Itaperuna_ShouldReturnValidMunicipio()
}

[Fact]
public async Task GetMunicipioByIdAsync_Muriae_ShouldReturnValidMunicipio()
public async Task GetMunicipioByNameAsync_NonExistentCity_ShouldReturnNull()
{
// Arrange
const int ibgeCode = 3143906; // Muriaé-MG
const string cityName = "CityThatDoesNotExist";

// Act
var result = await _ibgeClient.GetMunicipioByIdAsync(ibgeCode);
var result = await IbgeClient.GetMunicipioByNameAsync(cityName);

// Assert
result.Should().NotBeNull("Muriaé deve existir no WireMock stub por ID");
result!.Nome.Should().Be("Muriaé");
result.Id.Should().Be(ibgeCode);
result.GetEstadoSigla().Should().Be("MG");
result.Should().BeNull("Cidade inexistente deve retornar null");
}

[Fact]
public async Task GetEstadosAsync_ShouldReturnSudesteStates()
[Theory]
[InlineData("São Paulo", "SP")]
public async Task GetMunicipioByNameAsync_SpecialCharacters_ShouldHandleCorrectly(string cityName, string expectedUF)
{
// Act
var result = await _ibgeClient.GetEstadosAsync();
var result = await IbgeClient.GetMunicipioByNameAsync(cityName);

// Assert
result.Should().NotBeNull();
result.Should().NotBeEmpty("WireMock stub retorna estados do Sudeste");
result.Should().HaveCountGreaterThanOrEqualTo(3, "Pelo menos MG, RJ, SP");

// Verificar que estados esperados estão presentes
result.Should().Contain(e => e.Sigla == "MG" && e.Nome == "Minas Gerais");
result.Should().Contain(e => e.Sigla == "RJ" && e.Nome == "Rio de Janeiro");
result.Should().Contain(e => e.Sigla == "SP" && e.Nome == "São Paulo");
result.Should().NotBeNull($"{cityName} deve existir no WireMock stub com caracteres especiais");
result!.Nome.Should().Be(cityName);
result.GetEstadoSigla().Should().Be(expectedUF);
}

#endregion

#region GetMunicipiosByUFAsync Tests

[Fact]
public async Task GetEstadoByIdAsync_MG_ShouldReturnMinasGerais()
public async Task GetMunicipiosByUFAsync_SP_ShouldReturnSaoPauloCities()
{
// Arrange
const int estadoId = 31; // MG
const string ufSigla = "SP";

// Act
var result = await _ibgeClient.GetEstadoByIdAsync(estadoId);
var result = await IbgeClient.GetMunicipiosByUFAsync(ufSigla);

// Assert
result.Should().NotBeNull("MG deve existir no WireMock stub");
result!.Id.Should().Be(31);
result.Sigla.Should().Be("MG");
result.Nome.Should().Be("Minas Gerais");
result.Regiao.Should().NotBeNull();
result.Regiao!.Nome.Should().Be("Sudeste");
result.Should().NotBeNull();
result.Should().NotBeEmpty("SP deve ter municípios no WireMock stub");
result.Should().Contain(m => m.Nome == "São Paulo");

// Verificar que todos têm UF = SP
result.Should().OnlyContain(m => m.GetEstadoSigla() == "SP");
}

[Fact]
public async Task GetEstadoByUFAsync_MG_ShouldReturnMinasGerais()
public async Task GetMunicipiosByUFAsync_InvalidUF_ShouldReturnEmptyList()
{
// Arrange
const string uf = "MG";
const string invalidUF = "XX";

// Act
var result = await _ibgeClient.GetEstadoByUFAsync(uf);
var result = await IbgeClient.GetMunicipiosByUFAsync(invalidUF);

// Assert
result.Should().NotBeNull("MG deve existir no WireMock stub por UF");
result!.Sigla.Should().Be("MG");
result.Nome.Should().Be("Minas Gerais");
result.Should().NotBeNull();
result.Should().BeEmpty("UF inválido deve retornar lista vazia");
}

#endregion

#region ValidateCityInStateAsync Tests

[Fact]
public async Task GetMunicipiosByUFAsync_SP_ShouldReturnSaoPauloCities()
public async Task ValidateCityInStateAsync_ValidCityAndState_ShouldReturnTrue()
{
// Arrange
const string ufSigla = "SP";
const string cityName = "Muriaé";
const string state = "MG";

// Act
var result = await _ibgeClient.GetMunicipiosByUFAsync(ufSigla);
var result = await IbgeClient.ValidateCityInStateAsync(cityName, state);

// Assert
result.Should().NotBeNull();
result.Should().NotBeEmpty("SP deve ter municípios no WireMock stub");
result.Should().Contain(m => m.Nome == "São Paulo");

// Verificar que todos têm UF = SP
result.Should().OnlyContain(m => m.GetEstadoSigla() == "SP");
result.Should().BeTrue("Muriaé está em MG");
}

[Fact]
public async Task GetMunicipioByIdAsync_InvalidId_ShouldReturnNull()
public async Task ValidateCityInStateAsync_ValidCityWrongState_ShouldReturnFalse()
{
// Arrange
const int invalidId = 9999999;
const string cityName = "Muriaé";
const string state = "RJ";

// Act
var result = await _ibgeClient.GetMunicipioByIdAsync(invalidId);
var result = await IbgeClient.ValidateCityInStateAsync(cityName, state);

// Assert
result.Should().BeNull("ID inválido deve retornar null conforme WireMock stub");
result.Should().BeFalse("Muriaé não está em RJ");
}

[Fact]
public async Task GetEstadoByIdAsync_InvalidId_ShouldReturnNull()
public async Task ValidateCityInStateAsync_InvalidCity_ShouldReturnFalse()
{
// Arrange
const int invalidId = 999;
const string cityName = "CityThatDoesNotExist";
const string state = "MG";

// Act
var result = await _ibgeClient.GetEstadoByIdAsync(invalidId);
var result = await IbgeClient.ValidateCityInStateAsync(cityName, state);

// Assert
result.Should().BeNull("ID de estado inválido deve retornar null conforme WireMock stub");
result.Should().BeFalse("Cidade inexistente deve retornar false");
}

[Theory]
[InlineData("São Paulo", "SP")]
public async Task GetMunicipioByNameAsync_SpecialCharacters_ShouldHandleCorrectly(string cityName, string expectedUF)
{
// Act
var result = await _ibgeClient.GetMunicipioByNameAsync(cityName);

// Assert
result.Should().NotBeNull($"{cityName} deve existir no WireMock stub com caracteres especiais");
result!.Nome.Should().Be(cityName);
result.GetEstadoSigla().Should().Be(expectedUF);
}
#endregion
}