Skip to content

Commit

Permalink
Add AccountManager::find() (#10)
Browse files Browse the repository at this point in the history
Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
  • Loading branch information
vjik and samdark committed Aug 10, 2023
1 parent 9b55874 commit 80fc5a6
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Domain/Account/AccountChartId.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ public function __construct(
public string $value
) {
}

public function isEqualTo(AccountChartId $id): bool
{
return $this->value === $id->value;
}
}
22 changes: 22 additions & 0 deletions src/Domain/Account/AccountFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace PhpFinance\DoubleEntry\Domain\Account;

final class AccountFilter
{
private ?AccountChartId $accountChartId = null;

public function getAccountChartId(): ?AccountChartId
{
return $this->accountChartId;
}

public function withAccountChartId(?AccountChartId $accountChartId): self
{
$new = clone $this;
$new->accountChartId = $accountChartId;
return $new;
}
}
9 changes: 9 additions & 0 deletions src/Domain/Account/AccountManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ public function get(AccountId $id): Account
return $this->accountRepository->get($id);
}

/**
* @return Account[]
* @psalm-return list<Account>
*/
public function find(?AccountFilter $filter = null): array
{
return $this->accountRepository->find($filter ?? new AccountFilter());
}

public function exists(AccountId $id): bool
{
return $this->accountRepository->exists($id);
Expand Down
6 changes: 6 additions & 0 deletions src/Domain/Account/AccountRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ interface AccountRepositoryInterface
*/
public function get(AccountId $id): Account;

/**
* @return Account[]
* @psalm-return list<Account>
*/
public function find(AccountFilter $filter): array;

public function exists(AccountId $id): bool;

public function hasChildren(Account $account): bool;
Expand Down
55 changes: 55 additions & 0 deletions tests/Account/AbstractAccountManagerTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace PhpFinance\DoubleEntry\Tests\Account;

use PhpFinance\DoubleEntry\Domain\Account\Account;
use PhpFinance\DoubleEntry\Domain\Account\AccountChartId;
use PhpFinance\DoubleEntry\Domain\Account\AccountFilter;
use PhpFinance\DoubleEntry\Domain\Account\AccountId;
use PhpFinance\DoubleEntry\Domain\Account\AccountManager;
use PhpFinance\DoubleEntry\Domain\Account\AccountRepositoryInterface;
Expand All @@ -13,6 +15,7 @@
use PhpFinance\DoubleEntry\Domain\Posting\Posting;
use PhpFinance\DoubleEntry\Domain\Posting\PostingRepositoryInterface;
use PhpFinance\DoubleEntry\Tests\Support\TestFactory;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

abstract class AbstractAccountManagerTestCase extends TestCase
Expand All @@ -29,6 +32,58 @@ public function testGet(): void
$this->assertSame($result, $account);
}

public function testFind(): void
{
$accountManager = $this->createAccountManager(
accountRepository: $this->createAccountRepository(
TestFactory::createAccount('id1', 'chartA'),
TestFactory::createAccount('id2', 'chartB'),
TestFactory::createAccount('id3', 'chartA'),
),
);

$resultAccountIds = array_map(
static fn(Account $account) => $account->id->value,
$accountManager->find(),
);

$this->assertSame(['id1', 'id2', 'id3'], $resultAccountIds);
}

public static function dataFindWithFilter(): array
{
return [
[['id1', 'id2', 'id3', 'id4', 'id5', 'id6', 'id7'], null],
[['id1', 'id2', 'id3', 'id4', 'id5', 'id6', 'id7'], new AccountFilter()],
[['id1', 'id3', 'id4', 'id7'], (new AccountFilter())->withAccountChartId(new AccountChartId('chartA'))],
[['id6'], (new AccountFilter())->withAccountChartId(new AccountChartId('chartC'))],
[[], (new AccountFilter())->withAccountChartId(new AccountChartId('chartNotExist'))],
];
}

#[DataProvider('dataFindWithFilter')]
public function testFindWithFilter(array $expectedAccountIds, ?AccountFilter $filter): void
{
$accountManager = $this->createAccountManager(
accountRepository: $this->createAccountRepository(
TestFactory::createAccount('id1', 'chartA'),
TestFactory::createAccount('id2', 'chartB'),
TestFactory::createAccount('id3', 'chartA'),
TestFactory::createAccount('id4', 'chartA'),
TestFactory::createAccount('id5', 'chartB'),
TestFactory::createAccount('id6', 'chartC'),
TestFactory::createAccount('id7', 'chartA'),
),
);

$resultAccountIds = array_map(
static fn(Account $account) => $account->id->value,
$accountManager->find($filter),
);

$this->assertSame($expectedAccountIds, $resultAccountIds);
}

public function testSave(): void
{
$accountRepository = $this->createAccountRepository();
Expand Down
34 changes: 34 additions & 0 deletions tests/Account/AccountChartIdTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace PhpFinance\DoubleEntry\Tests\Account;

use PhpFinance\DoubleEntry\Domain\Account\AccountChartId;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class AccountChartIdTest extends TestCase
{
public static function dataIsEqualTo(): array
{
return [
'equal' => [
true,
new AccountChartId('7'),
new AccountChartId('7'),
],
'non-equal' => [
false,
new AccountChartId('7'),
new AccountChartId('42'),
],
];
}

#[DataProvider('dataIsEqualTo')]
public function testIsEqualTo(bool $expected, AccountChartId $id1, AccountChartId $id2): void
{
$this->assertSame($expected, $id1->isEqualTo($id2));
}
}
36 changes: 36 additions & 0 deletions tests/Account/AccountFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace PhpFinance\DoubleEntry\Tests\Account;

use PhpFinance\DoubleEntry\Domain\Account\AccountChartId;
use PhpFinance\DoubleEntry\Domain\Account\AccountFilter;
use PHPUnit\Framework\TestCase;

final class AccountFilterTest extends TestCase
{
public function testDefaultValues(): void
{
$filter = new AccountFilter();

$this->assertNull($filter->getAccountChartId());
}

public function testValues(): void
{
$accountChartId = new AccountChartId('test-chart-id');

$filter = (new AccountFilter())
->withAccountChartId($accountChartId);

$this->assertSame($accountChartId->value, $filter->getAccountChartId()->value);
}

public function testImmutability(): void
{
$filter = new AccountFilter();

$this->assertNotSame($filter, $filter->withAccountChartId(new AccountChartId('test-chart-id')));
}
}
13 changes: 13 additions & 0 deletions tests/Support/InMemoryAccountRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace PhpFinance\DoubleEntry\Tests\Support;

use PhpFinance\DoubleEntry\Domain\Account\Account;
use PhpFinance\DoubleEntry\Domain\Account\AccountFilter;
use PhpFinance\DoubleEntry\Domain\Account\AccountId;
use PhpFinance\DoubleEntry\Domain\Account\AccountRepositoryInterface;
use PhpFinance\DoubleEntry\Domain\Account\Exception\AccountNotFoundException;
Expand Down Expand Up @@ -33,6 +34,18 @@ public function get(AccountId $id): Account
return $this->accounts[$id->value] ?? throw new AccountNotFoundException();
}

public function find(AccountFilter $filter): array
{
return array_values(
array_filter(
$this->accounts,
static function (Account $account) use ($filter): bool {
return $filter->getAccountChartId() === null || $account->chartId->isEqualTo($filter->getAccountChartId());
}
)
);
}

public function exists(AccountId $id): bool
{
return array_key_exists($id->value, $this->accounts);
Expand Down

0 comments on commit 80fc5a6

Please sign in to comment.