CaiWuXiTong/tests/Unit/CourierAgreementSignatureLayoutTest.php

109 lines
6.0 KiB
PHP

<?php
namespace Tests\Unit;
use App\Models\Business\CourierAgreementSignature;
use App\Support\CourierAgreementPdf;
use DOMElement;
use Illuminate\Foundation\Testing\TestCase;
use Tests\CreatesApplication;
class CourierAgreementSignatureLayoutTest extends TestCase
{
use CreatesApplication;
public function test_cooperation_signature_page_fits_two_seals_and_separate_handwritten_signatures(): void
{
[$frames, $pageCount] = $this->renderLayout('cooperation-contract');
$seals = array_values(array_filter($frames, fn ($frame) => $frame['class'] === 'contract-signatures__blank'));
$handwriting = array_values(array_filter($frames, fn ($frame) => $frame['class'] === 'contract-signatures__handwriting'));
$this->assertCount(2, $seals);
$this->assertCount(2, $handwriting);
$this->assertGreaterThan(1, $pageCount);
foreach ($seals as $index => $seal) {
$this->assertGreaterThanOrEqual(159, $seal['width']);
$this->assertGreaterThanOrEqual(159, $seal['height']);
$this->assertSame($pageCount, $seal['page']);
$this->assertGreaterThanOrEqual(75, $handwriting[$index]['height']);
$this->assertGreaterThanOrEqual($seal['y'] + $seal['height'], $handwriting[$index]['y']);
}
$this->assertLessThanOrEqual($seals[1]['x'], $seals[0]['x'] + $seals[0]['width']);
foreach ($frames as $frame) {
$this->assertSame($pageCount, $frame['page'], 'Both parties and their dates must stay on the signature page.');
$this->assertLessThan(806, $frame['y'] + $frame['height']);
}
}
public function test_other_agreements_keep_full_size_seal_spaces_and_dates_together(): void
{
foreach (['account-proof', 'account-change', 'entity-change', 'shared-contract', 'authorization'] as $type) {
[$frames, $pageCount] = $this->renderLayout($type);
$seals = array_values(array_filter($frames, fn ($frame) => $frame['class'] === 'sign-grid__blank'));
$this->assertCount(in_array($type, ['entity-change', 'authorization'], true) ? 2 : 1, $seals);
foreach ($seals as $seal) {
$this->assertGreaterThanOrEqual(159, $seal['width'], $type);
$this->assertGreaterThanOrEqual(159, $seal['height'], $type);
}
foreach ($frames as $frame) {
$this->assertSame($pageCount, $frame['page'], "$type signature spaces and dates must stay together.");
$this->assertLessThan(806, $frame['y'] + $frame['height'], $type);
}
}
}
private function renderLayout(string $type): array
{
$payload = [
'company_full_name' => '示例甲方公司', 'signature_date' => '2026-10-11',
'account_proof_effective_date' => '2026-10-11',
'account_proof_account_name' => '示例合作公司', 'account_proof_bank_name' => '示例银行',
'account_proof_bank_account' => '0000000000000000',
'account_change_date' => '2026-10-11', 'old_account_name' => '原收款人',
'old_account_number' => '0000000000000000', 'old_account_stop_date' => '2026-10-11',
'new_account_effective_date' => '2026-10-11', 'new_account_name' => '新收款人',
'new_bank_name' => '示例银行', 'new_bank_account' => '0000000000000000',
'former_company_name' => '示例原公司', 'former_legal_representative' => '原法人',
'entity_change_date' => '2026-10-11', 'changed_company_name' => '示例新公司',
'changed_company_start_date' => '2026-10-11', 'secondary_operator_name' => '新法人',
'contract_partner_name' => '示例合作公司', 'shared_courier_names' => ['示例快递'],
'cooperation_party_a_name' => '示例甲方公司', 'cooperation_party_a_phone' => '00000000000',
'cooperation_party_b_name' => '示例乙方公司', 'cooperation_party_b_phone' => '00000000000',
'cooperation_party_b_signing_place' => '江苏省南京市鼓楼区',
'cooperation_start_date' => '2026-10-11', 'cooperation_end_date' => '2027-10-10',
'principal_name' => '示例委托方', 'principal_id_number' => 'EXAMPLE-ID',
'trustee_name' => '示例受托方', 'trustee_id_number' => 'EXAMPLE-ID',
'authorization_items' => ['1', '2', '3', '4'], 'bill_counterparty' => '示例对账方',
'loan_counterparty' => '示例借支方', 'payment_counterparty' => '示例付款方',
'authorization_start_date' => '2026-10-11', 'authorization_end_date' => '2027-10-10',
];
$signature = new CourierAgreementSignature([
'business_no' => 'AGR-LAYOUT-TEST', 'template_code' => CourierAgreementSignature::DOCUMENTS[$type]['code'],
'document_type' => $type, 'payload' => $payload,
]);
$frames = [];
$pdf = app('dompdf.wrapper');
$this->app->instance('dompdf.wrapper', $pdf);
$pdf->getDomPDF()->setCallbacks([[
'event' => 'end_frame',
'f' => function ($frame) use (&$frames, $pdf): void {
$node = $frame->get_node();
if (! $node instanceof DOMElement || ! preg_match('/(?:blank|handwriting|sign-grid__line|contract-signatures__title|contract-signatures__line)/', $node->getAttribute('class'))) {
return;
}
$position = $frame->get_position();
$frames[] = [
'class' => $node->getAttribute('class'),
'page' => $pdf->getDomPDF()->getCanvas()->get_page_number(),
'x' => $position['x'], 'y' => $position['y'],
'width' => $frame->get_margin_width(), 'height' => $frame->get_margin_height(),
];
},
]]);
app(CourierAgreementPdf::class)->render($signature);
$this->app->forgetInstance('dompdf.wrapper');
return [$frames, $pdf->getDomPDF()->getCanvas()->get_page_count()];
}
}