feat: CI/CD pipeline setup complete - Ansible playbooks updated, secrets configured, workflow ready
This commit is contained in:
194
tests/Unit/Framework/LiveComponents/Polling/PollServiceTest.php
Normal file
194
tests/Unit/Framework/LiveComponents/Polling/PollServiceTest.php
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\LiveComponents\Polling\PollService;
|
||||
use App\Framework\LiveComponents\Attributes\Poll;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\Discovery\Results\AttributeRegistry;
|
||||
use App\Framework\Discovery\ValueObjects\DiscoveredAttribute;
|
||||
use App\Framework\Discovery\ValueObjects\AttributeTarget;
|
||||
use App\Framework\Core\ValueObjects\ClassName;
|
||||
use App\Framework\Core\ValueObjects\MethodName;
|
||||
use App\Framework\DI\Container;
|
||||
|
||||
describe('PollService', function () {
|
||||
beforeEach(function () {
|
||||
// Create mock container
|
||||
$this->container = Mockery::mock(Container::class);
|
||||
|
||||
// Create attribute registry with test poll
|
||||
$this->attributeRegistry = new AttributeRegistry();
|
||||
|
||||
$this->testPoll = new DiscoveredAttribute(
|
||||
className: ClassName::create('App\\Test\\TestComponent'),
|
||||
attributeClass: Poll::class,
|
||||
target: AttributeTarget::METHOD,
|
||||
methodName: MethodName::create('checkData'),
|
||||
arguments: [
|
||||
'interval' => 2000,
|
||||
'enabled' => true,
|
||||
'event' => 'test.checked',
|
||||
'stopOnError' => false
|
||||
]
|
||||
);
|
||||
|
||||
$this->attributeRegistry->add(Poll::class, $this->testPoll);
|
||||
|
||||
// Create discovery registry
|
||||
$this->discoveryRegistry = new DiscoveryRegistry(
|
||||
attributes: $this->attributeRegistry
|
||||
);
|
||||
|
||||
// Create service
|
||||
$this->pollService = new PollService(
|
||||
$this->discoveryRegistry,
|
||||
$this->container
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
Mockery::close();
|
||||
});
|
||||
|
||||
it('finds all polls from discovery registry', function () {
|
||||
$polls = $this->pollService->getAllPolls();
|
||||
|
||||
expect($polls)->toHaveCount(1);
|
||||
expect($polls[0]['poll'])->toBeInstanceOf(Poll::class);
|
||||
expect($polls[0]['discovered'])->toBeInstanceOf(DiscoveredAttribute::class);
|
||||
});
|
||||
|
||||
it('reconstructs poll attribute from arguments', function () {
|
||||
$polls = $this->pollService->getAllPolls();
|
||||
$poll = $polls[0]['poll'];
|
||||
|
||||
expect($poll->interval)->toBe(2000);
|
||||
expect($poll->enabled)->toBeTrue();
|
||||
expect($poll->event)->toBe('test.checked');
|
||||
expect($poll->stopOnError)->toBeFalse();
|
||||
});
|
||||
|
||||
it('gets polls for specific class', function () {
|
||||
$polls = $this->pollService->getPollsForClass('App\\Test\\TestComponent');
|
||||
|
||||
expect($polls)->toHaveCount(1);
|
||||
expect($polls[0]['method'])->toBe('checkData');
|
||||
expect($polls[0]['poll']->interval)->toBe(2000);
|
||||
});
|
||||
|
||||
it('returns empty array for class without polls', function () {
|
||||
$polls = $this->pollService->getPollsForClass('App\\Test\\NonExistent');
|
||||
|
||||
expect($polls)->toBeEmpty();
|
||||
});
|
||||
|
||||
it('finds specific poll by class and method', function () {
|
||||
$poll = $this->pollService->findPoll(
|
||||
'App\\Test\\TestComponent',
|
||||
'checkData'
|
||||
);
|
||||
|
||||
expect($poll)->toBeInstanceOf(Poll::class);
|
||||
expect($poll->interval)->toBe(2000);
|
||||
});
|
||||
|
||||
it('returns null for non-existent poll', function () {
|
||||
$poll = $this->pollService->findPoll(
|
||||
'App\\Test\\TestComponent',
|
||||
'nonExistentMethod'
|
||||
);
|
||||
|
||||
expect($poll)->toBeNull();
|
||||
});
|
||||
|
||||
it('checks if method is pollable', function () {
|
||||
expect($this->pollService->isPollable(
|
||||
'App\\Test\\TestComponent',
|
||||
'checkData'
|
||||
))->toBeTrue();
|
||||
|
||||
expect($this->pollService->isPollable(
|
||||
'App\\Test\\TestComponent',
|
||||
'nonExistentMethod'
|
||||
))->toBeFalse();
|
||||
});
|
||||
|
||||
it('counts total polls', function () {
|
||||
expect($this->pollService->getPollCount())->toBe(1);
|
||||
});
|
||||
|
||||
it('gets only enabled polls', function () {
|
||||
// Add disabled poll
|
||||
$disabledPoll = new DiscoveredAttribute(
|
||||
className: ClassName::create('App\\Test\\DisabledComponent'),
|
||||
attributeClass: Poll::class,
|
||||
target: AttributeTarget::METHOD,
|
||||
methodName: MethodName::create('disabledMethod'),
|
||||
arguments: [
|
||||
'interval' => 1000,
|
||||
'enabled' => false
|
||||
]
|
||||
);
|
||||
|
||||
$this->attributeRegistry->add(Poll::class, $disabledPoll);
|
||||
|
||||
$enabledPolls = $this->pollService->getEnabledPolls();
|
||||
|
||||
expect($enabledPolls)->toHaveCount(1);
|
||||
expect($enabledPolls[0]['poll']->enabled)->toBeTrue();
|
||||
});
|
||||
|
||||
it('executes poll method via container', function () {
|
||||
$mockComponent = new class {
|
||||
public function checkData(): array
|
||||
{
|
||||
return ['status' => 'ok'];
|
||||
}
|
||||
};
|
||||
|
||||
$this->container->shouldReceive('get')
|
||||
->with('App\\Test\\TestComponent')
|
||||
->andReturn($mockComponent);
|
||||
|
||||
$result = $this->pollService->executePoll(
|
||||
'App\\Test\\TestComponent',
|
||||
'checkData'
|
||||
);
|
||||
|
||||
expect($result)->toBe(['status' => 'ok']);
|
||||
});
|
||||
|
||||
it('throws exception for non-existent method', function () {
|
||||
$mockComponent = new class {
|
||||
// No checkData method
|
||||
};
|
||||
|
||||
$this->container->shouldReceive('get')
|
||||
->with('App\\Test\\TestComponent')
|
||||
->andReturn($mockComponent);
|
||||
|
||||
$this->pollService->executePoll(
|
||||
'App\\Test\\TestComponent',
|
||||
'checkData'
|
||||
);
|
||||
})->throws(BadMethodCallException::class);
|
||||
|
||||
it('wraps execution errors', function () {
|
||||
$mockComponent = new class {
|
||||
public function checkData(): array
|
||||
{
|
||||
throw new RuntimeException('Internal error');
|
||||
}
|
||||
};
|
||||
|
||||
$this->container->shouldReceive('get')
|
||||
->with('App\\Test\\TestComponent')
|
||||
->andReturn($mockComponent);
|
||||
|
||||
$this->pollService->executePoll(
|
||||
'App\\Test\\TestComponent',
|
||||
'checkData'
|
||||
);
|
||||
})->throws(RuntimeException::class, 'Failed to execute poll');
|
||||
});
|
||||
Reference in New Issue
Block a user