Hide inserted estimates from client list; redirect anon to /signin

Estimates with status Inserted (provider hasn't worked on them yet)
were showing up in the client's "Mes devis à valider" list. The
asclient endpoint now requires ProviderValidationDate to be set, so
only estimates the provider has actually established and submitted
are visible to the client. The asprovider endpoint is unchanged
(providers still need to see incoming unprocessed requests).

Also fix the anonymous-access redirect on Yavsc.Org: the application
cookie's LoginPath defaulted to /Account/Login, which has no
controller. Anonymous hits to a restricted page now redirect to the
real /signin endpoint (with /signout and /Account/AccessDenied set
to match the existing controller routes).

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Paul Schneider 2026-09-21 14:38:49 +01:00
commit 22c33c5388
Signed by: notazof
GPG key ID: AD4B9B545FBD7D12
4 changed files with 70 additions and 3 deletions

View file

@ -209,9 +209,12 @@ public sealed class EstimateApiControllerTests : IClassFixture<ApiWebServerFixtu
/// <summary>
/// Seeds an estimate owned by alice (the provider) for the given
/// client, optionally already validated by the client.
/// client, optionally already validated by the client. By default the
/// estimate is also provider-validated (i.e. the provider has submitted
/// it); pass <paramref name="providerValidated"/> = false to seed a
/// freshly inserted request the provider hasn't worked on yet.
/// </summary>
private long SeedEstimate(string clientId, bool clientValidated)
private long SeedEstimate(string clientId, bool clientValidated, bool providerValidated = true)
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
@ -229,6 +232,7 @@ public sealed class EstimateApiControllerTests : IClassFixture<ApiWebServerFixtu
{
new() { Name = "Prestation", Description = "Prestation de base", Count = 1, UnitaryCost = 120m, Currency = "EUR" },
},
ProviderValidationDate = providerValidated ? DateTime.UtcNow : default,
ClientValidationDate = clientValidated ? DateTime.UtcNow : default,
};
db.Estimates.Add(estimate);
@ -259,6 +263,26 @@ public sealed class EstimateApiControllerTests : IClassFixture<ApiWebServerFixtu
Assert.Equal("alice", item.GetProperty("ownerId").GetString());
}
[Fact]
public async Task GetOngoingEstimatesAsClient_excludes_inserted_requests_not_yet_provider_validated()
{
_fixture.ResetAndSeedActivityGraph();
var submittedId = SeedEstimate(clientId: "bob", clientValidated: false); // provider submitted: visible
SeedEstimate(clientId: "bob", clientValidated: false, providerValidated: false); // inserted, not worked on: excluded
using var http = NewClient("bob");
var response = await http.GetAsync("/api/v1/estimate/asclient", TestContext.Current.CancellationToken);
var body = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
Assert.True(response.StatusCode == HttpStatusCode.OK, $"Unexpected status {(int)response.StatusCode} ({response.StatusCode}): {body}");
using var doc = JsonDocument.Parse(body);
var items = doc.RootElement.EnumerateArray().ToArray();
var item = Assert.Single(items);
Assert.Equal(submittedId, item.GetProperty("id").GetInt64());
}
[Fact]
public async Task GetOngoingEstimatesAsProvider_returns_only_ongoing_estimates_established_by_the_provider()
{