计票实时公开

This commit is contained in:
biss committed 2026-09-11 19:38:43 +08:00
1 parent e96a56314f
commit 2d38c9cb60
16 files changed
+232 -38

No files matched your search

@@ -9,6 +9,7 @@ using ElectionSystem.Api.Modules.Election.Domain;
using ElectionSystem.Api.Modules.OfflineCounting.Domain;
using ElectionSystem.Api.Modules.OfflineCounting;
using ElectionSystem.Api.Modules.Results;
using ElectionSystem.Api.Modules.PublicBoard;
using System.Text;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
@@ -162,6 +163,34 @@ public sealed class PersistenceModelTests
Assert.Equal(new[] { a.Id }, summary.WinnerOptionIds);
}
[Fact]
public void Public_result_projection_hides_candidate_totals_until_allowed_and_keeps_them_for_final_results()
{
var election = new ElectionActivity { Name = "测试投票", RegionId = Guid.NewGuid(), Status = ElectionActivityStatus.Counting, VotingStartsAtUtc = DateTime.UtcNow.AddHours(-2), VotingEndsAtUtc = DateTime.UtcNow.AddHours(-1), CountingEndsAtUtc = DateTime.UtcNow.AddHours(1), CreatedByUserId = Guid.NewGuid(), PublishLiveParticipation = true, PublishLiveCandidateTotals = false };
var contest = new ContestResult(Guid.NewGuid(), "主任", [new OptionResult(Guid.NewGuid(), "甲", 18)], 3, 2, 1, 18, [], false);
var snapshot = new ElectionResultSnapshot(election, [contest]);
var live = PublicElectionResultsProjection.Create(snapshot, DateTime.UtcNow);
Assert.True(PublicElectionResultsProjection.IsAvailable(election));
Assert.Equal(24, live.Participation);
Assert.Null(live.Contests);
election.Status = ElectionActivityStatus.PublishedResults;
var final = PublicElectionResultsProjection.Create(new ElectionResultSnapshot(election, [contest]), DateTime.UtcNow);
Assert.Single(final.Contests!);
}
[Fact]
public void Public_result_projection_rejects_non_public_live_elections()
{
var election = new ElectionActivity { Name = "测试投票", RegionId = Guid.NewGuid(), Status = ElectionActivityStatus.Counting, VotingStartsAtUtc = DateTime.UtcNow.AddHours(-2), VotingEndsAtUtc = DateTime.UtcNow.AddHours(-1), CountingEndsAtUtc = DateTime.UtcNow.AddHours(1), CreatedByUserId = Guid.NewGuid(), PublishLiveParticipation = false };
Assert.False(PublicElectionResultsProjection.IsAvailable(election));
Assert.Throws<InvalidOperationException>(() => PublicElectionResultsProjection.Create(new ElectionResultSnapshot(election, []), DateTime.UtcNow));
}
[Fact]
public void Missing_selections_are_calculated_from_counted_ballots_and_required_choices()
{