原生成绩查询、科目/总分排名、达线判断、等级计算及成绩单防伪码:[CandidateService.Results.cs (line 11)](C:/Users/BI/Documents/EIS-dotnet/src/Eis.Infrastructure/Candidate/CandidateService.Results.cs:11)
原生成绩复议提交,工作流、分配人与审计日志同事务写入。 原生准考证下载窗口校验及 HTML 文书生成:[CandidateAdmitCardRenderer.cs (line 9)](C:/Users/BI/Documents/EIS-dotnet/src/Eis.Infrastructure/Candidate/CandidateAdmitCardRenderer.cs:9) 三个路由已切换到 ASP.NET Core:[NativeCandidateEndpoints.cs (line 61)](C:/Users/BI/Documents/EIS-dotnet/src/Eis.Web/Candidate/NativeCandidateEndpoints.cs:61) 更新迁移说明:[MIGRATION.md (line 50)](C:/Users/BI/Documents/EIS-dotnet/MIGRATION.md:50)
This commit is contained in:
@@ -104,6 +104,28 @@ function Assert-JsonEquivalent {
|
||||
}
|
||||
}
|
||||
|
||||
function Assert-CandidateResultsEquivalent {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $Expected,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string] $Actual
|
||||
)
|
||||
|
||||
$expectedNode = [System.Text.Json.Nodes.JsonNode]::Parse($Expected)
|
||||
$actualNode = [System.Text.Json.Nodes.JsonNode]::Parse($Actual)
|
||||
foreach ($node in @($expectedNode, $actualNode)) {
|
||||
foreach ($summary in $node['summaries'].AsArray()) {
|
||||
$summary.AsObject().Remove('verificationQr') | Out-Null
|
||||
}
|
||||
}
|
||||
if (-not [System.Text.Json.Nodes.JsonNode]::DeepEquals($expectedNode, $actualNode)) {
|
||||
$difference = Find-JsonDifference -Expected $expectedNode -Actual $actualNode -Path '$'
|
||||
throw "Candidate route 'results' JSON payload differs from the legacy API at $difference"
|
||||
}
|
||||
}
|
||||
|
||||
function Find-JsonDifference {
|
||||
param(
|
||||
[AllowNull()]
|
||||
@@ -407,6 +429,51 @@ try {
|
||||
}
|
||||
Assert-JsonEquivalent -Expected $legacyCandidateResponse.Content -Actual $nativeCandidateResponse.Content -Label "Candidate route '$candidateRoute'"
|
||||
}
|
||||
$legacyCandidateResultsResponse = Invoke-WebRequest -Uri "$legacyBaseUrl/api/candidate/results" -WebSession $candidateSession
|
||||
$nativeCandidateResultsResponse = Invoke-WebRequest -Uri "$nativeAuthBaseUrl/api/candidate/results" -WebSession $nativeCandidateSession
|
||||
if ($nativeCandidateResultsResponse.Headers['X-EIS-Implementation'] -ne 'aspnet-core') {
|
||||
throw "Candidate route 'results' did not use the native ASP.NET Core endpoint"
|
||||
}
|
||||
Assert-CandidateResultsEquivalent -Expected $legacyCandidateResultsResponse.Content -Actual $nativeCandidateResultsResponse.Content
|
||||
$nativeCandidateResults = $nativeCandidateResultsResponse.Content | ConvertFrom-Json
|
||||
if (@($nativeCandidateResults.summaries | Where-Object { $_.verificationQr -match '^data:image/png;base64,' }).Count -eq 0) {
|
||||
throw 'Native candidate results did not include a local PNG verification QR code'
|
||||
}
|
||||
$appealableResult = @($nativeCandidateResults.results | Where-Object { $null -eq $_.appeal } | Select-Object -First 1)[0]
|
||||
if ($null -ne $appealableResult) {
|
||||
$shortAppeal = Invoke-WebRequest -Uri "$nativeAuthBaseUrl/api/candidate/results/$($appealableResult.id)/appeals" -Method Post -ContentType 'application/json' -Body '{"reason":"短"}' -WebSession $nativeCandidateSession -SkipHttpErrorCheck
|
||||
if ($shortAppeal.StatusCode -ne 400 -or $shortAppeal.Headers['X-EIS-Implementation'] -ne 'aspnet-core') {
|
||||
throw 'Native score appeal did not validate the minimum reason length'
|
||||
}
|
||||
$appealBody = @{ reason = '迁移冒烟验证:成绩与个人估分差异较大,请复核计分。' } | ConvertTo-Json -Compress
|
||||
$appealResponse = Invoke-WebRequest -Uri "$nativeAuthBaseUrl/api/candidate/results/$($appealableResult.id)/appeals" -Method Post -ContentType 'application/json' -Body $appealBody -WebSession $nativeCandidateSession
|
||||
$appeal = $appealResponse.Content | ConvertFrom-Json
|
||||
if ($appealResponse.StatusCode -ne 201 -or $appealResponse.Headers['X-EIS-Implementation'] -ne 'aspnet-core' -or $appeal.workflow.status -ne 'pending') {
|
||||
throw 'Native score appeal did not persist a pending workflow'
|
||||
}
|
||||
}
|
||||
$admitProcess = Start-TestProcess -FileName $nodeExecutable -ArgumentList @(
|
||||
'tests/helpers/prepare-candidate-admit-smoke.mjs', $smokeDatabasePath, '2026-HZ01-F-0001'
|
||||
) -Environment $nodeEnvironment
|
||||
if (-not $admitProcess.WaitForExit(10000)) {
|
||||
$admitProcess.Kill($true)
|
||||
throw 'Timed out while preparing the candidate admit-card smoke data'
|
||||
}
|
||||
$admitRegistrationId = $admitProcess.StandardOutput.ReadToEnd().Trim()
|
||||
$admitError = $admitProcess.StandardError.ReadToEnd()
|
||||
if ($admitProcess.ExitCode -ne 0 -or -not $admitRegistrationId) {
|
||||
throw "Could not prepare the candidate admit-card smoke data`n$admitError"
|
||||
}
|
||||
$admitProcess.Dispose()
|
||||
$legacyAdmitResponse = Invoke-WebRequest -Uri "$legacyBaseUrl/api/candidate/registrations/$admitRegistrationId/admit-card" -WebSession $candidateSession
|
||||
$nativeAdmitResponse = Invoke-WebRequest -Uri "$nativeAuthBaseUrl/api/candidate/registrations/$admitRegistrationId/admit-card" -WebSession $nativeCandidateSession
|
||||
if ($nativeAdmitResponse.StatusCode -ne 200 -or
|
||||
$nativeAdmitResponse.Headers['X-EIS-Implementation'] -ne 'aspnet-core' -or
|
||||
$nativeAdmitResponse.Headers['Content-Disposition'] -notmatch '^attachment;' -or
|
||||
$nativeAdmitResponse.Content -notmatch '考试考场序号' -or
|
||||
$nativeAdmitResponse.Content -ne $legacyAdmitResponse.Content) {
|
||||
throw 'Native admit-card download did not match the legacy HTML document'
|
||||
}
|
||||
|
||||
$registrationSchool = @($homePayload.schools | Select-Object -First 1)[0]
|
||||
$registrationClass = @($homePayload.classes | Where-Object schoolId -eq $registrationSchool.id | Select-Object -First 1)[0]
|
||||
@@ -631,6 +698,7 @@ try {
|
||||
NativeAuthentication = 'passed'
|
||||
NativeCandidateReads = 'passed'
|
||||
NativeCandidateWrites = 'passed'
|
||||
NativeCandidateDocuments = 'passed'
|
||||
} | Format-List
|
||||
}
|
||||
finally {
|
||||
|
||||
Reference in New Issue
Block a user