- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
182 lines
5.7 KiB
PHP
182 lines
5.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* LiveComponent Testing Example: CounterComponent
|
|
*
|
|
* Demonstrates usage of Pest helper functions for LiveComponent testing:
|
|
* - mountComponent() - Mount component with initial state
|
|
* - callAction() - Execute component actions
|
|
* - callActionWithFragments() - Execute actions with fragment updates
|
|
* - Custom Expectations: toHaveState, toContainHtml, toHaveDispatchedEvent
|
|
*/
|
|
|
|
use function Pest\LiveComponents\mountComponent;
|
|
use function Pest\LiveComponents\callAction;
|
|
|
|
describe('CounterComponent', function () {
|
|
it('renders initial counter state', function () {
|
|
$component = mountComponent('counter:test', ['count' => 0]);
|
|
|
|
expect($component['html'])
|
|
->toContainHtml('Count: 0');
|
|
|
|
expect($component['state'])
|
|
->toHaveState(['count' => 0, 'lastUpdate' => null]);
|
|
});
|
|
|
|
it('renders with custom initial count', function () {
|
|
$component = mountComponent('counter:test', ['count' => 42]);
|
|
|
|
expect($component['html'])
|
|
->toContainHtml('Count: 42');
|
|
|
|
expect($component['state'])
|
|
->toHaveStateKey('count', 42);
|
|
});
|
|
|
|
it('increments counter on action', function () {
|
|
$component = mountComponent('counter:test', ['count' => 5]);
|
|
|
|
$result = callAction($component, 'increment');
|
|
|
|
expect($result['state'])
|
|
->toHaveStateKey('count', 6);
|
|
|
|
expect($result['html'])
|
|
->toContainHtml('Count: 6');
|
|
});
|
|
|
|
it('decrements counter on action', function () {
|
|
$component = mountComponent('counter:test', ['count' => 5]);
|
|
|
|
$result = callAction($component, 'decrement');
|
|
|
|
expect($result['state'])
|
|
->toHaveStateKey('count', 4);
|
|
|
|
expect($result['html'])
|
|
->toContainHtml('Count: 4');
|
|
});
|
|
|
|
it('prevents negative counts on decrement', function () {
|
|
$component = mountComponent('counter:test', ['count' => 0]);
|
|
|
|
$result = callAction($component, 'decrement');
|
|
|
|
expect($result['state'])
|
|
->toHaveStateKey('count', 0); // Should stay at 0, not go negative
|
|
});
|
|
|
|
it('resets counter to zero', function () {
|
|
$component = mountComponent('counter:test', ['count' => 42]);
|
|
|
|
$result = callAction($component, 'reset');
|
|
|
|
expect($result['state'])
|
|
->toHaveStateKey('count', 0);
|
|
});
|
|
|
|
it('adds custom amount to counter', function () {
|
|
$component = mountComponent('counter:test', ['count' => 10]);
|
|
|
|
$result = callAction($component, 'addAmount', ['amount' => 15]);
|
|
|
|
expect($result['state'])
|
|
->toHaveStateKey('count', 25);
|
|
});
|
|
|
|
it('prevents negative counts when adding negative amount', function () {
|
|
$component = mountComponent('counter:test', ['count' => 5]);
|
|
|
|
$result = callAction($component, 'addAmount', ['amount' => -10]);
|
|
|
|
expect($result['state'])
|
|
->toHaveStateKey('count', 0); // Should be capped at 0
|
|
});
|
|
|
|
it('dispatches counter:changed event on increment', function () {
|
|
$component = mountComponent('counter:test', ['count' => 5]);
|
|
|
|
$result = callAction($component, 'increment');
|
|
|
|
expect($result['events'])
|
|
->toHaveDispatchedEvent('counter:changed');
|
|
});
|
|
|
|
it('dispatches counter:changed event with correct data', function () {
|
|
$component = mountComponent('counter:test', ['count' => 5]);
|
|
|
|
$result = callAction($component, 'increment');
|
|
|
|
expect($result['events'])
|
|
->toHaveDispatchedEventWithData('counter:changed', [
|
|
'component_id' => 'counter:test',
|
|
'old_value' => 5,
|
|
'new_value' => 6,
|
|
'change' => '+1',
|
|
]);
|
|
});
|
|
|
|
it('dispatches milestone event at multiples of 10', function () {
|
|
$component = mountComponent('counter:test', ['count' => 9]);
|
|
|
|
$result = callAction($component, 'increment');
|
|
|
|
expect($result['events'])
|
|
->toHaveDispatchedEvent('counter:milestone');
|
|
});
|
|
|
|
it('does not dispatch milestone event when not at multiple of 10', function () {
|
|
$component = mountComponent('counter:test', ['count' => 8]);
|
|
|
|
$result = callAction($component, 'increment');
|
|
|
|
// Should have counter:changed but not milestone
|
|
expect($result['events'])->toHaveDispatchedEvent('counter:changed');
|
|
|
|
$hasMilestone = false;
|
|
foreach ($result['events'] as $event) {
|
|
if ($event->name === 'counter:milestone') {
|
|
$hasMilestone = true;
|
|
}
|
|
}
|
|
|
|
expect($hasMilestone)->toBeFalse();
|
|
});
|
|
|
|
it('dispatches reset event on reset action', function () {
|
|
$component = mountComponent('counter:test', ['count' => 42]);
|
|
|
|
$result = callAction($component, 'reset');
|
|
|
|
expect($result['events'])
|
|
->toHaveDispatchedEventWithData('counter:reset', [
|
|
'component_id' => 'counter:test',
|
|
'previous_value' => 42,
|
|
]);
|
|
});
|
|
|
|
it('maintains component identity across actions', function () {
|
|
$component = mountComponent('counter:test');
|
|
|
|
$result1 = callAction($component, 'increment');
|
|
$result2 = callAction($result1, 'increment');
|
|
|
|
expect($result2['componentId'])->toBe('counter:test');
|
|
expect($result2['state']['count'])->toBe(2);
|
|
});
|
|
|
|
it('chains multiple actions correctly', function () {
|
|
$component = mountComponent('counter:test', ['count' => 0]);
|
|
|
|
$result = callAction($component, 'increment');
|
|
$result = callAction($result, 'increment');
|
|
$result = callAction($result, 'increment');
|
|
$result = callAction($result, 'decrement');
|
|
|
|
expect($result['state']['count'])->toBe(2);
|
|
});
|
|
});
|