Add phone login support and member import functionality
Features: - Support login via phone number or email (LoginRequest) - Add members:import-roster command for Excel roster import - Merge survey emails with roster data Code Quality (Phase 1-4): - Add database locking for balance calculation - Add self-approval checks for finance workflow - Create service layer (FinanceDocumentApprovalService, PaymentVerificationService) - Add HasAccountingEntries and HasApprovalWorkflow traits - Create FormRequest classes for validation - Add status-badge component - Define authorization gates in AuthServiceProvider - Add accounting config file Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ use Tests\Traits\SeedsRolesAndPermissions;
|
||||
* Finance Email Content Tests
|
||||
*
|
||||
* Tests email content for finance document-related notifications.
|
||||
* Uses new workflow: Secretary → Chair → Board
|
||||
*/
|
||||
class FinanceEmailContentTest extends TestCase
|
||||
{
|
||||
@@ -33,80 +34,80 @@ class FinanceEmailContentTest extends TestCase
|
||||
*/
|
||||
public function test_finance_document_submitted_email(): void
|
||||
{
|
||||
$accountant = $this->createAccountant();
|
||||
$requester = $this->createAdmin();
|
||||
|
||||
$this->actingAs($accountant)->post(
|
||||
route('admin.finance-documents.store'),
|
||||
$this->actingAs($requester)->post(
|
||||
route('admin.finance.store'),
|
||||
$this->getValidFinanceDocumentData(['title' => 'Test Finance Request'])
|
||||
);
|
||||
|
||||
// Verify email was queued (if system sends submission notifications)
|
||||
$this->assertTrue(true);
|
||||
// Verify document was created
|
||||
$this->assertDatabaseHas('finance_documents', ['title' => 'Test Finance Request']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test finance document approved by cashier email
|
||||
* Test finance document approved by secretary email
|
||||
*/
|
||||
public function test_finance_document_approved_by_cashier_email(): void
|
||||
public function test_finance_document_approved_by_secretary_email(): void
|
||||
{
|
||||
$cashier = $this->createCashier();
|
||||
$secretary = $this->createSecretary();
|
||||
$document = $this->createFinanceDocument([
|
||||
'status' => FinanceDocument::STATUS_PENDING,
|
||||
]);
|
||||
|
||||
$this->actingAs($cashier)->post(
|
||||
route('admin.finance-documents.approve', $document)
|
||||
$this->actingAs($secretary)->post(
|
||||
route('admin.finance.approve', $document)
|
||||
);
|
||||
|
||||
// Verify approval notification was triggered
|
||||
$document->refresh();
|
||||
$this->assertEquals(FinanceDocument::STATUS_APPROVED_CASHIER, $document->status);
|
||||
$this->assertEquals(FinanceDocument::STATUS_APPROVED_SECRETARY, $document->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test finance document approved by accountant email
|
||||
* Test finance document approved by chair email
|
||||
*/
|
||||
public function test_finance_document_approved_by_accountant_email(): void
|
||||
{
|
||||
$accountant = $this->createAccountant();
|
||||
$document = $this->createDocumentAtStage('cashier_approved');
|
||||
|
||||
$this->actingAs($accountant)->post(
|
||||
route('admin.finance-documents.approve', $document)
|
||||
);
|
||||
|
||||
$document->refresh();
|
||||
$this->assertEquals(FinanceDocument::STATUS_APPROVED_ACCOUNTANT, $document->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test finance document fully approved email
|
||||
*/
|
||||
public function test_finance_document_fully_approved_email(): void
|
||||
public function test_finance_document_approved_by_chair_email(): void
|
||||
{
|
||||
$chair = $this->createChair();
|
||||
$document = $this->createDocumentAtStage('accountant_approved');
|
||||
$document = $this->createDocumentAtStage('secretary_approved', ['amount' => 25000]);
|
||||
|
||||
$this->actingAs($chair)->post(
|
||||
route('admin.finance-documents.approve', $document)
|
||||
route('admin.finance.approve', $document)
|
||||
);
|
||||
|
||||
$document->refresh();
|
||||
$this->assertEquals(FinanceDocument::STATUS_APPROVED_CHAIR, $document->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test finance document fully approved by board email
|
||||
*/
|
||||
public function test_finance_document_fully_approved_by_board_email(): void
|
||||
{
|
||||
$boardMember = $this->createBoardMember();
|
||||
$document = $this->createDocumentAtStage('chair_approved', ['amount' => 75000]);
|
||||
|
||||
$this->actingAs($boardMember)->post(
|
||||
route('admin.finance.approve', $document)
|
||||
);
|
||||
|
||||
$document->refresh();
|
||||
$this->assertEquals(FinanceDocument::STATUS_APPROVED_BOARD, $document->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test finance document rejected email
|
||||
*/
|
||||
public function test_finance_document_rejected_email(): void
|
||||
{
|
||||
$cashier = $this->createCashier();
|
||||
$secretary = $this->createSecretary();
|
||||
$document = $this->createFinanceDocument([
|
||||
'status' => FinanceDocument::STATUS_PENDING,
|
||||
]);
|
||||
|
||||
$this->actingAs($cashier)->post(
|
||||
route('admin.finance-documents.reject', $document),
|
||||
$this->actingAs($secretary)->post(
|
||||
route('admin.finance.reject', $document),
|
||||
['rejection_reason' => 'Insufficient documentation']
|
||||
);
|
||||
|
||||
@@ -141,48 +142,6 @@ class FinanceEmailContentTest extends TestCase
|
||||
$this->assertEquals('Office Supplies Purchase', $document->title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test email contains approval notes
|
||||
*/
|
||||
public function test_email_contains_approval_notes(): void
|
||||
{
|
||||
$cashier = $this->createCashier();
|
||||
$document = $this->createFinanceDocument([
|
||||
'status' => FinanceDocument::STATUS_PENDING,
|
||||
]);
|
||||
|
||||
$this->actingAs($cashier)->post(
|
||||
route('admin.finance-documents.approve', $document),
|
||||
['notes' => 'Approved after verification']
|
||||
);
|
||||
|
||||
// Notes should be stored if the controller supports it
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test email sent to all approvers
|
||||
*/
|
||||
public function test_email_sent_to_all_approvers(): void
|
||||
{
|
||||
$cashier = $this->createCashier(['email' => 'cashier@test.com']);
|
||||
$accountant = $this->createAccountant(['email' => 'accountant@test.com']);
|
||||
$chair = $this->createChair(['email' => 'chair@test.com']);
|
||||
|
||||
$document = $this->createFinanceDocument([
|
||||
'status' => FinanceDocument::STATUS_PENDING,
|
||||
]);
|
||||
|
||||
// Approval should trigger notifications to next approver
|
||||
$this->actingAs($cashier)->post(
|
||||
route('admin.finance-documents.approve', $document)
|
||||
);
|
||||
|
||||
// Accountant should be notified
|
||||
$document->refresh();
|
||||
$this->assertEquals(FinanceDocument::STATUS_APPROVED_CASHIER, $document->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test email template renders correctly
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user