mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Fix some tests for account API
This commit is contained in:
parent
668b169a5e
commit
7118abe28d
@ -68,6 +68,7 @@ class StoreController extends Controller
|
||||
public function store(StoreRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getAllAccountData();
|
||||
$this->repository->resetAccountOrder();
|
||||
$account = $this->repository->store($data);
|
||||
$manager = $this->getManager();
|
||||
|
||||
|
@ -80,7 +80,7 @@ class StoreRequest extends FormRequest
|
||||
// append Location information.
|
||||
$data = $this->appendLocationData($data, null);
|
||||
|
||||
if ('liability' === $data['account_type']) {
|
||||
if ('liability' === $data['account_type'] || 'liabilities' === $data['account_type']) {
|
||||
$data['opening_balance'] = bcmul($this->string('liability_amount'), '-1');
|
||||
$data['opening_balance_date'] = $this->date('liability_start_date');
|
||||
$data['account_type'] = $this->string('liability_type');
|
||||
|
@ -195,7 +195,7 @@ class UpdateRequest extends FormRequest
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
$this->validateOneRecurrenceTransaction($validator);
|
||||
//$this->validateOneRecurrenceTransaction($validator);
|
||||
$this->validateOneRepetitionUpdate($validator);
|
||||
$this->validateRecurrenceRepetition($validator);
|
||||
$this->validateRepetitionMoment($validator);
|
||||
|
@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
@ -62,16 +61,7 @@ class FixAccountOrder extends Command
|
||||
$users = User::get();
|
||||
foreach ($users as $user) {
|
||||
$this->repository->setUser($user);
|
||||
$sets = [
|
||||
[AccountType::DEFAULT, AccountType::ASSET],
|
||||
[AccountType::EXPENSE, AccountType::BENEFICIARY],
|
||||
[AccountType::REVENUE],
|
||||
[AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE],
|
||||
[AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION],
|
||||
];
|
||||
foreach ($sets as $set) {
|
||||
$this->repository->resetAccountOrder($set);
|
||||
}
|
||||
$this->repository->resetAccountOrder();
|
||||
}
|
||||
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
|
@ -30,6 +30,7 @@ use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Services\Internal\Support\AccountServiceTrait;
|
||||
use FireflyIII\Services\Internal\Support\LocationServiceTrait;
|
||||
use FireflyIII\Services\Internal\Update\AccountUpdateService;
|
||||
use FireflyIII\User;
|
||||
use Log;
|
||||
|
||||
@ -73,9 +74,10 @@ class AccountFactory
|
||||
public function create(array $data): Account
|
||||
{
|
||||
$type = $this->getAccountType($data['account_type_id'] ?? null, $data['account_type'] ?? null);
|
||||
|
||||
if (null === $type) {
|
||||
throw new FireflyException(sprintf('AccountFactory::create() was unable to find account type #%d ("%s").', $data['account_type_id'] ?? null, $data['account_type'] ?? null));
|
||||
throw new FireflyException(
|
||||
sprintf('AccountFactory::create() was unable to find account type #%d ("%s").', $data['account_type_id'] ?? null, $data['account_type'] ?? null)
|
||||
);
|
||||
}
|
||||
|
||||
$data['iban'] = $this->filterIban($data['iban'] ?? null);
|
||||
@ -85,8 +87,13 @@ class AccountFactory
|
||||
$return = $this->find($data['name'], $type->type);
|
||||
|
||||
if (null === $return) {
|
||||
$this->accountRepository->resetAccountOrder();
|
||||
|
||||
// create it:
|
||||
$databaseData = ['user_id' => $this->user->id, 'account_type_id' => $type->id, 'name' => $data['name'], 'order' => $data['order'] ?? 0, 'virtual_balance' => $data['virtual_balance'] ?? null, 'active' => true === $data['active'], 'iban' => $data['iban'],];
|
||||
$databaseData = ['user_id' => $this->user->id,
|
||||
'account_type_id' => $type->id,
|
||||
'name' => $data['name'], 'order' => 0,
|
||||
'virtual_balance' => $data['virtual_balance'] ?? null, 'active' => true === $data['active'], 'iban' => $data['iban'],];
|
||||
|
||||
$currency = $this->getCurrency((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null));
|
||||
unset($data['currency_code']);
|
||||
@ -118,6 +125,15 @@ class AccountFactory
|
||||
|
||||
// store location
|
||||
$this->storeNewLocation($return, $data);
|
||||
|
||||
// set new order:
|
||||
if (array_key_exists('order', $data)) {
|
||||
$maxOrder = $this->accountRepository->maxOrder([$type->type]);
|
||||
$order = $data['order'] > $maxOrder ? $maxOrder+1 : $data['order'];
|
||||
$update = new AccountUpdateService;
|
||||
$update->setUser($return->user);
|
||||
$return = $update->updateAccountOrder($return,['order' => $order]);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
@ -152,7 +168,10 @@ class AccountFactory
|
||||
|
||||
if (null === $return) {
|
||||
Log::debug('Found nothing. Will create a new one.');
|
||||
$return = $this->create(['user_id' => $this->user->id, 'name' => $accountName, 'account_type_id' => $type->id, 'account_type' => null, 'virtual_balance' => '0', 'iban' => null, 'active' => true,]);
|
||||
$return = $this->create(
|
||||
['user_id' => $this->user->id, 'name' => $accountName, 'account_type_id' => $type->id, 'account_type' => null, 'virtual_balance' => '0',
|
||||
'iban' => null, 'active' => true,]
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
@ -136,7 +136,7 @@ class IndexController extends Controller
|
||||
|
||||
if (1 === random_int(0, 20)) {
|
||||
Log::debug('Will reset order.');
|
||||
$this->repository->resetAccountOrder($types);
|
||||
$this->repository->resetAccountOrder();
|
||||
}
|
||||
|
||||
$collection = $this->repository->getActiveAccountsByType($types);
|
||||
|
@ -586,17 +586,26 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function resetAccountOrder(array $types): void
|
||||
public function resetAccountOrder(): void
|
||||
{
|
||||
$list = $this->getAccountsByType($types);
|
||||
/**
|
||||
* @var int $index
|
||||
* @var Account $account
|
||||
*/
|
||||
foreach ($list as $index => $account) {
|
||||
$account->order = $index + 1;
|
||||
$sets = [
|
||||
[AccountType::DEFAULT, AccountType::ASSET],
|
||||
[AccountType::EXPENSE, AccountType::BENEFICIARY],
|
||||
[AccountType::REVENUE],
|
||||
[AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE],
|
||||
[AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION],
|
||||
];
|
||||
foreach ($sets as $set) {
|
||||
$list = $this->getAccountsByType($set);
|
||||
$index = 1;
|
||||
foreach ($list as $account) {
|
||||
if ($index !== $account->order) {
|
||||
$account->order = $index;
|
||||
$account->save();
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -753,4 +762,12 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
return $service->update($account, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function maxOrder(array $types): int
|
||||
{
|
||||
return (int)$this->getAccountsByType($types)->max('order');
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,13 @@ interface AccountRepositoryInterface
|
||||
*/
|
||||
public function count(array $types): int;
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function maxOrder(array $types): int;
|
||||
|
||||
/**
|
||||
* Moved here from account CRUD.
|
||||
*
|
||||
@ -256,10 +263,8 @@ interface AccountRepositoryInterface
|
||||
|
||||
/**
|
||||
* Reset order types of the mentioned accounts.
|
||||
*
|
||||
* @param array $types
|
||||
*/
|
||||
public function resetAccountOrder(array $types): void;
|
||||
public function resetAccountOrder(): void;
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
|
@ -461,7 +461,8 @@ trait ModifiesPiggyBanks
|
||||
$user = $this->user;
|
||||
$user->piggyBanks()->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder)
|
||||
->where('piggy_banks.id', '!=', $piggyBank->id)
|
||||
->update(['piggy_banks.order' => DB::raw('piggy_banks.order-1')]);
|
||||
->decrement('piggybanks.order',1);
|
||||
|
||||
$piggyBank->order = $newOrder;
|
||||
$piggyBank->save();
|
||||
}
|
||||
@ -474,7 +475,8 @@ trait ModifiesPiggyBanks
|
||||
$user = $this->user;
|
||||
$user->piggyBanks()->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder)
|
||||
->where('piggy_banks.id', '!=', $piggyBank->id)
|
||||
->update(['piggy_banks.order' => DB::raw('piggy_banks.order+1')]);
|
||||
->increment('piggybanks.order',1);
|
||||
|
||||
$piggyBank->order = $newOrder;
|
||||
$piggyBank->save();
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\RuleGroup;
|
||||
|
||||
use DB;
|
||||
use Exception;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
@ -458,14 +457,14 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
|
||||
if ($newOrder > $oldOrder) {
|
||||
$this->user->ruleGroups()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder)
|
||||
->where('rule_groups.id', '!=', $ruleGroup->id)
|
||||
->update(['order' => DB::raw('rule_groups.order-1')]);
|
||||
->decrement('rule_groups.order', 1);
|
||||
$ruleGroup->order = $newOrder;
|
||||
$ruleGroup->save();
|
||||
}
|
||||
if ($newOrder < $oldOrder) {
|
||||
$this->user->ruleGroups()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder)
|
||||
->where('rule_groups.id', '!=', $ruleGroup->id)
|
||||
->update(['order' => DB::raw('rule_groups.order+1')]);
|
||||
->increment('rule_groups.order', 1);
|
||||
$ruleGroup->order = $newOrder;
|
||||
$ruleGroup->save();
|
||||
}
|
||||
|
@ -83,7 +83,6 @@ trait AccountServiceTrait
|
||||
public function updateMetaData(Account $account, array $data): void
|
||||
{
|
||||
$fields = $this->validFields;
|
||||
|
||||
if ($account->accountType->type === AccountType::ASSET) {
|
||||
$fields = $this->validAssetFields;
|
||||
}
|
||||
|
@ -52,9 +52,6 @@ class AccountUpdateService
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
// TODO move to configuration.
|
||||
$this->canHaveVirtual = [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD];
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
@ -63,6 +60,14 @@ class AccountUpdateService
|
||||
$this->validFields = ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update account data.
|
||||
*
|
||||
@ -73,6 +78,7 @@ class AccountUpdateService
|
||||
*/
|
||||
public function update(Account $account, array $data): Account
|
||||
{
|
||||
Log::debug(sprintf('Now in %s',__METHOD__));
|
||||
$this->accountRepository->setUser($account->user);
|
||||
$this->user = $account->user;
|
||||
$account = $this->updateAccount($account, $data);
|
||||
@ -126,7 +132,7 @@ class AccountUpdateService
|
||||
}
|
||||
|
||||
// update virtual balance (could be set to zero if empty string).
|
||||
if (null !== $data['virtual_balance']) {
|
||||
if (array_key_exists('virtual_balance', $data) && null !== $data['virtual_balance']) {
|
||||
$account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance'];
|
||||
}
|
||||
|
||||
@ -175,7 +181,7 @@ class AccountUpdateService
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
private function updateAccountOrder(Account $account, array $data): Account
|
||||
public function updateAccountOrder(Account $account, array $data): Account
|
||||
{
|
||||
// skip if no order info
|
||||
if (!array_key_exists('order', $data) || $data['order'] === $account->order) {
|
||||
@ -195,20 +201,20 @@ class AccountUpdateService
|
||||
}
|
||||
|
||||
if ($newOrder > $oldOrder) {
|
||||
$this->user->accounts()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder)
|
||||
$this->user->accounts()->where('accounts.order', '<=', $newOrder)->where('accounts.order', '>', $oldOrder)
|
||||
->where('accounts.id', '!=', $account->id)
|
||||
->whereIn('accounts.account_type_id', $list)
|
||||
->update(['order' => DB::raw('accounts.order-1')]);
|
||||
->decrement('order', 1);
|
||||
$account->order = $newOrder;
|
||||
$account->save();
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
$this->user->accounts()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder)
|
||||
$this->user->accounts()->where('accounts.order', '>=', $newOrder)->where('accounts.order', '<', $oldOrder)
|
||||
->where('accounts.id', '!=', $account->id)
|
||||
->whereIn('accounts.account_type_id', $list)
|
||||
->update(['order' => DB::raw('accounts.order+1')]);
|
||||
->increment('order',1);
|
||||
$account->order = $newOrder;
|
||||
$account->save();
|
||||
|
||||
|
@ -185,14 +185,14 @@ class BillUpdateService
|
||||
if ($newOrder > $oldOrder) {
|
||||
$this->user->bills()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder)
|
||||
->where('bills.id', '!=', $bill->id)
|
||||
->update(['order' => DB::raw('bills.order-1')]);
|
||||
->decrement('bills.order',1);
|
||||
$bill->order = $newOrder;
|
||||
$bill->save();
|
||||
}
|
||||
if ($newOrder < $oldOrder) {
|
||||
$this->user->bills()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder)
|
||||
->where('bills.id', '!=', $bill->id)
|
||||
->update(['order' => DB::raw('bills.order+1')]);
|
||||
->increment('bills.order',1);
|
||||
$bill->order = $newOrder;
|
||||
$bill->save();
|
||||
}
|
||||
|
@ -223,10 +223,6 @@ class Amount
|
||||
*/
|
||||
public function getAllCurrencies(): Collection
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
|
||||
}
|
||||
|
||||
return TransactionCurrency::orderBy('code', 'ASC')->get();
|
||||
}
|
||||
|
||||
@ -235,10 +231,6 @@ class Amount
|
||||
*/
|
||||
public function getCurrencies(): Collection
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
|
||||
}
|
||||
|
||||
return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
|
||||
}
|
||||
|
||||
@ -247,9 +239,6 @@ class Amount
|
||||
*/
|
||||
public function getCurrencyCode(): string
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
|
||||
}
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('getCurrencyCode');
|
||||
if ($cache->has()) {
|
||||
@ -273,9 +262,6 @@ class Amount
|
||||
*/
|
||||
public function getDefaultCurrency(): TransactionCurrency
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
|
||||
}
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
@ -287,10 +273,6 @@ class Amount
|
||||
*/
|
||||
public function getSystemCurrency(): TransactionCurrency
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
|
||||
}
|
||||
|
||||
return TransactionCurrency::where('code', 'EUR')->first();
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,6 @@ class FireflyConfig
|
||||
*/
|
||||
public function delete(string $name): void
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s("%s") should NOT be called in the TEST environment!', __METHOD__, $name));
|
||||
}
|
||||
$fullName = 'ff-config-' . $name;
|
||||
if (Cache::has($fullName)) {
|
||||
Cache::forget($fullName);
|
||||
@ -75,9 +72,6 @@ class FireflyConfig
|
||||
*/
|
||||
public function get(string $name, $default = null): ?Configuration
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s("%s") should NOT be called in the TEST environment!', __METHOD__, $name));
|
||||
}
|
||||
$fullName = 'ff-config-' . $name;
|
||||
if (Cache::has($fullName)) {
|
||||
return Cache::get($fullName);
|
||||
@ -111,9 +105,7 @@ class FireflyConfig
|
||||
*/
|
||||
public function getFresh(string $name, $default = null): ?Configuration
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
|
||||
}
|
||||
|
||||
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
|
||||
if ($config) {
|
||||
|
||||
@ -135,9 +127,6 @@ class FireflyConfig
|
||||
*/
|
||||
public function put(string $name, $value): Configuration
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
|
||||
}
|
||||
|
||||
return $this->set($name, $value);
|
||||
}
|
||||
@ -151,9 +140,6 @@ class FireflyConfig
|
||||
*/
|
||||
public function set(string $name, $value): Configuration
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
|
||||
}
|
||||
/** @var Configuration $config */
|
||||
try {
|
||||
$config = Configuration::whereName($name)->first();
|
||||
|
@ -62,9 +62,6 @@ class TransactionGroupTwig extends AbstractExtension
|
||||
return new TwigFunction(
|
||||
'journalGetMetaDate',
|
||||
static function (int $journalId, string $metaField) {
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning('Twig TransactionGroup::journalGetMetaDate should NOT be called in the TEST environment!');
|
||||
}
|
||||
$entry = DB::table('journal_meta')
|
||||
->where('name', $metaField)
|
||||
->where('transaction_journal_id', $journalId)
|
||||
@ -87,9 +84,6 @@ class TransactionGroupTwig extends AbstractExtension
|
||||
return new TwigFunction(
|
||||
'journalGetMetaField',
|
||||
static function (int $journalId, string $metaField) {
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning('Twig TransactionGroup::journalGetMetaField should NOT be called in the TEST environment!');
|
||||
}
|
||||
$entry = DB::table('journal_meta')
|
||||
->where('name', $metaField)
|
||||
->where('transaction_journal_id', $journalId)
|
||||
|
@ -91,7 +91,7 @@ class AccountTransformer extends AbstractTransformer
|
||||
'created_at' => $account->created_at->toAtomString(),
|
||||
'updated_at' => $account->updated_at->toAtomString(),
|
||||
'active' => $account->active,
|
||||
'order' => $account->order,
|
||||
'order' => (int) $account->order,
|
||||
'name' => $account->name,
|
||||
'type' => strtolower($accountType),
|
||||
'account_role' => $accountRole,
|
||||
|
@ -100,7 +100,8 @@
|
||||
"pragmarx/google2fa": "^8.0",
|
||||
"predis/predis": "^1.1",
|
||||
"ramsey/uuid": "^4.1",
|
||||
"rcrowe/twigbridge": "^0.12.1"
|
||||
"rcrowe/twigbridge": "^0.12.1",
|
||||
"spatie/data-transfer-object": "^2.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.3",
|
||||
@ -108,7 +109,6 @@
|
||||
"ergebnis/phpstan-rules": "^0.15.0",
|
||||
"filp/whoops": "2.*",
|
||||
"fakerphp/faker": "1.*",
|
||||
"johnkary/phpunit-speedtrap": "^3.1",
|
||||
"mockery/mockery": "1.*",
|
||||
"nunomaduro/larastan": "^0.7.0",
|
||||
"phpstan/phpstan": "^0.12.34",
|
||||
@ -125,6 +125,7 @@
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FireflyIII\\": "app/",
|
||||
"Domain\\": "domain/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
|
61
composer.lock
generated
61
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "5d5b27d4e58ebc72b63359767f4c5763",
|
||||
"content-hash": "7294670d4c743796b6929563ab61451d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@ -4285,6 +4285,65 @@
|
||||
},
|
||||
"time": "2020-10-14T18:14:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/data-transfer-object",
|
||||
"version": "2.8.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/data-transfer-object.git",
|
||||
"reference": "2625a59566804ec63f01947d85947336237cbda6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/2625a59566804ec63f01947d85947336237cbda6",
|
||||
"reference": "2625a59566804ec63f01947d85947336237cbda6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"suggest": {
|
||||
"phpstan/phpstan": "Take advantage of checkUninitializedProperties with \\Spatie\\DataTransferObject\\PHPstan\\PropertiesAreAlwaysInitializedExtension"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\DataTransferObject\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brent Roose",
|
||||
"email": "brent@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Data transfer objects with batteries included",
|
||||
"homepage": "https://github.com/spatie/data-transfer-object",
|
||||
"keywords": [
|
||||
"data-transfer-object",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/data-transfer-object/issues",
|
||||
"source": "https://github.com/spatie/data-transfer-object/tree/2.8.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.patreon.com/spatie",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-12T08:46:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.2.7",
|
||||
|
@ -54,8 +54,8 @@ use FireflyIII\Support\Binder\CLIToken;
|
||||
use FireflyIII\Support\Binder\CurrencyCode;
|
||||
use FireflyIII\Support\Binder\Date;
|
||||
use FireflyIII\Support\Binder\DynamicConfigKey;
|
||||
use FireflyIII\Support\Binder\JournalList;
|
||||
use FireflyIII\Support\Binder\EitherConfigKey;
|
||||
use FireflyIII\Support\Binder\JournalList;
|
||||
use FireflyIII\Support\Binder\TagList;
|
||||
use FireflyIII\Support\Binder\TagOrId;
|
||||
use FireflyIII\TransactionRules\Actions\AddTag;
|
||||
@ -258,6 +258,9 @@ return [
|
||||
'initial' => [AccountType::INITIAL_BALANCE],
|
||||
'import' => [AccountType::IMPORT],
|
||||
'reconcile' => [AccountType::RECONCILIATION],
|
||||
'loan' => [AccountType::LOAN],
|
||||
'debt' => [AccountType::DEBT],
|
||||
'mortgage' => [AccountType::MORTGAGE],
|
||||
'liabilities' => [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE, AccountType::CREDITCARD],
|
||||
'liability' => [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE, AccountType::CREDITCARD],
|
||||
],
|
||||
|
15
phpunit.xml
15
phpunit.xml
@ -34,20 +34,9 @@
|
||||
<directory suffix=".php">./app</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<listeners>
|
||||
<listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener">
|
||||
<arguments>
|
||||
<array>
|
||||
<element key="slowThreshold">
|
||||
<integer>1000</integer>
|
||||
</element>
|
||||
</array>
|
||||
</arguments>
|
||||
</listener>
|
||||
</listeners>
|
||||
<testsuites>
|
||||
<testsuite name="Feature">
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
<testsuite name="Api">
|
||||
<directory suffix="Test.php">./tests/Api/Models/Account</directory>
|
||||
</testsuite>
|
||||
|
||||
<!--
|
||||
|
238
tests/Api/Models/Account/StoreControllerTest.php
Normal file
238
tests/Api/Models/Account/StoreControllerTest.php
Normal file
@ -0,0 +1,238 @@
|
||||
<?php
|
||||
/*
|
||||
* StoreControllerTest.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Tests\Api\Models\Account;
|
||||
|
||||
|
||||
use Faker\Factory;
|
||||
use Laravel\Passport\Passport;
|
||||
use Log;
|
||||
use Tests\TestCase;
|
||||
use Tests\Traits\CollectsValues;
|
||||
use Tests\Traits\RandomValues;
|
||||
use Tests\Traits\TestHelpers;
|
||||
|
||||
/**
|
||||
* Class StoreControllerTest
|
||||
*/
|
||||
class StoreControllerTest extends TestCase
|
||||
{
|
||||
use RandomValues, TestHelpers, CollectsValues;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
Passport::actingAs($this->user());
|
||||
Log::info(sprintf('Now in %s.', get_class($this)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $submission
|
||||
*
|
||||
* @dataProvider storeAccountDataProvider
|
||||
*/
|
||||
public function testStore(array $submission): void
|
||||
{
|
||||
// run account store with a minimal data set:
|
||||
$route = 'api.v1.accounts.store';
|
||||
$this->submitAndCompare($route, $submission);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function storeAccountDataProvider(): array
|
||||
{
|
||||
$minimalSets = $this->minimalSets();
|
||||
$optionalSets = $this->optionalSets();
|
||||
$regenConfig = [
|
||||
'name' => function () {
|
||||
$faker = Factory::create();
|
||||
|
||||
return $faker->name;
|
||||
},
|
||||
'iban' => function () {
|
||||
$faker = Factory::create();
|
||||
|
||||
return $faker->iban();
|
||||
},
|
||||
'account_number' => function () {
|
||||
$faker = Factory::create();
|
||||
|
||||
return $faker->iban();
|
||||
},
|
||||
];
|
||||
|
||||
return $this->genericDataProvider($minimalSets, $optionalSets, $regenConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \array[][]
|
||||
*/
|
||||
private function optionalSets(): array
|
||||
{
|
||||
$faker = Factory::create();
|
||||
$currencies = [
|
||||
1 => 'EUR',
|
||||
2 => 'HUF',
|
||||
3 => 'GBP',
|
||||
4 => 'UAH',
|
||||
];
|
||||
$rand = rand(1, 4);
|
||||
|
||||
return [
|
||||
'active' => [
|
||||
'fields' => [
|
||||
'active' => $faker->boolean,
|
||||
],
|
||||
],
|
||||
// 'iban' => [
|
||||
// 'fields' => [
|
||||
// 'iban' => $faker->iban(),
|
||||
// ],
|
||||
// ],
|
||||
// 'bic' => [
|
||||
// 'fields' => [
|
||||
// 'bic' => $faker->swiftBicNumber,
|
||||
// ],
|
||||
// ],
|
||||
// 'account_number' => [
|
||||
// 'fields' => [
|
||||
// 'account_number' => $faker->iban(),
|
||||
// ],
|
||||
// ],
|
||||
// 'ob' => [
|
||||
// 'fields' => [
|
||||
// 'opening_balance' => $this->getRandomAmount(),
|
||||
// 'opening_balance_date' => $this->getRandomDateString(),
|
||||
// ],
|
||||
// ],
|
||||
// 'virtual_balance' => [
|
||||
// 'fields' => [
|
||||
// 'virtual_balance' => $this->getRandomAmount(),
|
||||
// ],
|
||||
// ],
|
||||
// 'currency_id' => [
|
||||
// 'fields' => [
|
||||
// 'currency_id' => $rand,
|
||||
// ],
|
||||
// ],
|
||||
// 'currency_code' => [
|
||||
// 'fields' => [
|
||||
// 'currency_code' => $currencies[$rand],
|
||||
// ],
|
||||
// ],
|
||||
// 'order' => [
|
||||
// 'fields' => [
|
||||
// 'order' => $faker->numberBetween(1, 5),
|
||||
// ],
|
||||
// ],
|
||||
// 'include_net_worth' => [
|
||||
// 'fields' => [
|
||||
// 'include_net_worth' => $faker->boolean,
|
||||
// ],
|
||||
// ],
|
||||
// 'notes' => [
|
||||
// 'fields' => [
|
||||
// 'notes' => join(' ', $faker->words(5)),
|
||||
// ],
|
||||
// ],
|
||||
// 'location' => [
|
||||
// 'fields' => [
|
||||
// 'latitude' => $faker->latitude,
|
||||
// 'longitude' => $faker->longitude,
|
||||
// 'zoom_level' => $faker->numberBetween(1, 10),
|
||||
// ],
|
||||
// ],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function minimalSets(): array
|
||||
{
|
||||
$faker = Factory::create();
|
||||
|
||||
return [
|
||||
'asset' => [
|
||||
'fields' => [
|
||||
'name' => $faker->name . join(' ', $faker->words(2)),
|
||||
'type' => 'asset',
|
||||
'account_role' => $this->randomAccountRole(),
|
||||
],
|
||||
],
|
||||
'expense' => [
|
||||
'fields' => [
|
||||
'name' => $faker->name,
|
||||
'type' => 'expense',
|
||||
],
|
||||
],
|
||||
'liability' => [
|
||||
'fields' => [
|
||||
'name' => $faker->name,
|
||||
'type' => 'liabilities',
|
||||
'liability_type' => $this->randomLiabilityType(),
|
||||
'liability_amount' => $this->getRandomAmount(),
|
||||
'liability_start_date' => $this->getRandomDateString(),
|
||||
'interest' => $this->getRandomPercentage(),
|
||||
'interest_period' => $this->getRandomInterestPeriod(),
|
||||
],
|
||||
],
|
||||
'cc' => [
|
||||
'fields' => [
|
||||
'name' => $faker->name,
|
||||
'type' => 'asset',
|
||||
'account_role' => 'ccAsset',
|
||||
'credit_card_type' => 'monthlyFull',
|
||||
'monthly_payment_date' => $this->getRandomDateString(),
|
||||
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $area
|
||||
* @param string $left
|
||||
* @param string $right
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function ignoreCombination(string $area, string $left, string $right): bool
|
||||
{
|
||||
Log::debug(sprintf('Must ignore %s: %s vs %s?', $area, $left, $right));
|
||||
if ('store-account' === $area) {
|
||||
if ('expense' === $left && in_array($right, ['virtual_balance', 'opening_balance', 'opening_balance_date'])) {
|
||||
Log::debug('Yes');
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log::debug('NO');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
53
tests/Api/Models/Account/UpdateControllerTest.php
Normal file
53
tests/Api/Models/Account/UpdateControllerTest.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/*
|
||||
* UpdateControllerTest.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Tests\Api\Models\Account;
|
||||
|
||||
|
||||
use Laravel\Passport\Passport;
|
||||
use Tests\TestCase;
|
||||
use Log;
|
||||
|
||||
|
||||
/**
|
||||
* Class UpdateControllerTest
|
||||
*/
|
||||
class UpdateControllerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
Passport::actingAs($this->user());
|
||||
Log::info(sprintf('Now in %s.', get_class($this)));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function testUpdate(): void {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -33,8 +33,6 @@ abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
use CreatesApplication, CollectsValues;
|
||||
|
||||
// MocksDefaultValues TestHelpers
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
@ -50,197 +50,208 @@ trait CollectsValues
|
||||
{
|
||||
return User::where('email', 'james@firefly')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function nonAdminUser(): User
|
||||
{
|
||||
return User::where('email', 'no_admin@firefly')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Budget
|
||||
*/
|
||||
public function getRandomBudget(): Budget
|
||||
{
|
||||
return $this->user()->budgets()->inRandomOrder()->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Category
|
||||
*/
|
||||
public function getRandomCategory(): Category
|
||||
{
|
||||
return $this->user()->categories()->inRandomOrder()->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Bill
|
||||
*/
|
||||
public function getRandomBill(): Bill
|
||||
{
|
||||
return $this->user()->bills()->inRandomOrder()->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function getRandomPiggyBank(): PiggyBank
|
||||
{
|
||||
return $this->user()->piggyBanks()->inRandomOrder()->first();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Tag
|
||||
*/
|
||||
public function getRandomTag(): Tag
|
||||
{
|
||||
return $this->user()->tags()->inRandomOrder()->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function getRandomWithdrawal(): TransactionJournal
|
||||
{
|
||||
return $this->getRandomJournal(TransactionType::WITHDRAWAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function getRandomTransfer(): TransactionJournal
|
||||
{
|
||||
return $this->getRandomJournal(TransactionType::TRANSFER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function getRandomDeposit(): TransactionJournal
|
||||
{
|
||||
return $this->getRandomJournal(TransactionType::DEPOSIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return TransactionJournal
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getRandomJournal(string $type): TransactionJournal
|
||||
{
|
||||
$query = DB::table('transactions')
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->where('transaction_journals.user_id', $this->user()->id)
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->where('transaction_types.type', $type)
|
||||
->groupBy('transactions.transaction_journal_id')
|
||||
->having('ct', '=', 2)
|
||||
->inRandomOrder()->take(1);
|
||||
$result = $query->get(
|
||||
[
|
||||
'transactions.transaction_journal_id',
|
||||
'transaction_journals.transaction_type_id',
|
||||
DB::raw('COUNT(transaction_journal_id) as ct'),
|
||||
]
|
||||
)->first();
|
||||
if (null === $result) {
|
||||
throw new FireflyException(sprintf('Cannot find suitable journal "%s" to use.', $type));
|
||||
}
|
||||
|
||||
return TransactionJournal::find((int) $result->transaction_journal_id);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function getEuro(): TransactionCurrency
|
||||
{
|
||||
return TransactionCurrency::whereCode('EUR')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function getDollar(): TransactionCurrency
|
||||
{
|
||||
return TransactionCurrency::whereCode('USD')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $except
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function getRandomAsset(?int $except = null): Account
|
||||
{
|
||||
return $this->getRandomAccount(AccountType::ASSET, $except);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $except
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function getRandomDebt(?int $except = null): Account
|
||||
{
|
||||
return $this->getRandomAccount(AccountType::DEBT, $except);
|
||||
}
|
||||
/**
|
||||
* @param int|null $except
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function getRandomLoan(?int $except = null): Account
|
||||
{
|
||||
return $this->getRandomAccount(AccountType::LOAN, $except);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $except
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function getRandomRevenue(?int $except = null): Account
|
||||
{
|
||||
return $this->getRandomAccount(AccountType::REVENUE, $except);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $except
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function getRandomExpense(?int $except = null): Account
|
||||
{
|
||||
return $this->getRandomAccount(AccountType::EXPENSE, $except);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @param int|null $except
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
private function getRandomAccount(string $type, ?int $except): Account
|
||||
{
|
||||
$query = Account::
|
||||
leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->whereNull('accounts.deleted_at')
|
||||
->where('accounts.user_id', $this->user()->id)
|
||||
->where('account_types.type', $type)
|
||||
->inRandomOrder()->take(1);
|
||||
if (null !== $except) {
|
||||
$query->where('accounts.id', '!=', $except);
|
||||
}
|
||||
return $query->first(['accounts.*']);
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * @return User
|
||||
// */
|
||||
// public function nonAdminUser(): User
|
||||
// {
|
||||
// return User::where('email', 'no_admin@firefly')->first();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return Budget
|
||||
// */
|
||||
// public function getRandomBudget(): Budget
|
||||
// {
|
||||
// return $this->user()->budgets()->inRandomOrder()->first();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return Category
|
||||
// */
|
||||
// public function getRandomCategory(): Category
|
||||
// {
|
||||
// return $this->user()->categories()->inRandomOrder()->first();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return Bill
|
||||
// */
|
||||
// public function getRandomBill(): Bill
|
||||
// {
|
||||
// return $this->user()->bills()->inRandomOrder()->first();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return PiggyBank
|
||||
// */
|
||||
// public function getRandomPiggyBank(): PiggyBank
|
||||
// {
|
||||
// return $this->user()->piggyBanks()->inRandomOrder()->first();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * @return Tag
|
||||
// */
|
||||
// public function getRandomTag(): Tag
|
||||
// {
|
||||
// return $this->user()->tags()->inRandomOrder()->first();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return TransactionJournal
|
||||
// */
|
||||
// public function getRandomWithdrawal(): TransactionJournal
|
||||
// {
|
||||
// return $this->getRandomJournal(TransactionType::WITHDRAWAL);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return TransactionJournal
|
||||
// */
|
||||
// public function getRandomTransfer(): TransactionJournal
|
||||
// {
|
||||
// return $this->getRandomJournal(TransactionType::TRANSFER);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return TransactionJournal
|
||||
// */
|
||||
// public function getRandomDeposit(): TransactionJournal
|
||||
// {
|
||||
// return $this->getRandomJournal(TransactionType::DEPOSIT);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param string $type
|
||||
// *
|
||||
// * @return TransactionJournal
|
||||
// * @throws FireflyException
|
||||
// */
|
||||
// private function getRandomJournal(string $type): TransactionJournal
|
||||
// {
|
||||
// $query = DB::table('transactions')
|
||||
// ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
// ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
// ->where('transaction_journals.user_id', $this->user()->id)
|
||||
// ->whereNull('transaction_journals.deleted_at')
|
||||
// ->whereNull('transactions.deleted_at')
|
||||
// ->where('transaction_types.type', $type)
|
||||
// ->groupBy('transactions.transaction_journal_id')
|
||||
// ->having('ct', '=', 2)
|
||||
// ->inRandomOrder()->take(1);
|
||||
// $result = $query->get(
|
||||
// [
|
||||
// 'transactions.transaction_journal_id',
|
||||
// 'transaction_journals.transaction_type_id',
|
||||
// DB::raw('COUNT(transaction_journal_id) as ct'),
|
||||
// ]
|
||||
// )->first();
|
||||
// if (null === $result) {
|
||||
// throw new FireflyException(sprintf('Cannot find suitable journal "%s" to use.', $type));
|
||||
// }
|
||||
//
|
||||
// return TransactionJournal::find((int)$result->transaction_journal_id);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return TransactionCurrency
|
||||
// */
|
||||
// public function getEuro(): TransactionCurrency
|
||||
// {
|
||||
// return TransactionCurrency::whereCode('EUR')->first();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return TransactionCurrency
|
||||
// */
|
||||
// public function getRandomCurrency(): TransactionCurrency
|
||||
// {
|
||||
// return TransactionCurrency::where('code', '!=', 'EUR')->inRandomOrder()->first();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return TransactionCurrency
|
||||
// */
|
||||
// public function getDollar(): TransactionCurrency
|
||||
// {
|
||||
// return TransactionCurrency::whereCode('USD')->first();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param int|null $except
|
||||
// *
|
||||
// * @return Account
|
||||
// */
|
||||
// public function getRandomAsset(?int $except = null): Account
|
||||
// {
|
||||
// return $this->getRandomAccount(AccountType::ASSET, $except);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param int|null $except
|
||||
// *
|
||||
// * @return Account
|
||||
// */
|
||||
// public function getRandomDebt(?int $except = null): Account
|
||||
// {
|
||||
// return $this->getRandomAccount(AccountType::DEBT, $except);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param int|null $except
|
||||
// *
|
||||
// * @return Account
|
||||
// */
|
||||
// public function getRandomLoan(?int $except = null): Account
|
||||
// {
|
||||
// return $this->getRandomAccount(AccountType::LOAN, $except);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param int|null $except
|
||||
// *
|
||||
// * @return Account
|
||||
// */
|
||||
// public function getRandomRevenue(?int $except = null): Account
|
||||
// {
|
||||
// return $this->getRandomAccount(AccountType::REVENUE, $except);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param int|null $except
|
||||
// *
|
||||
// * @return Account
|
||||
// */
|
||||
// public function getRandomExpense(?int $except = null): Account
|
||||
// {
|
||||
// return $this->getRandomAccount(AccountType::EXPENSE, $except);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param string $type
|
||||
// *
|
||||
// * @param int|null $except
|
||||
// *
|
||||
// * @return Account
|
||||
// */
|
||||
// private function getRandomAccount(string $type, ?int $except): Account
|
||||
// {
|
||||
// $query = Account::
|
||||
// leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
// ->whereNull('accounts.deleted_at')
|
||||
// ->where('accounts.user_id', $this->user()->id)
|
||||
// ->where('account_types.type', $type)
|
||||
// ->inRandomOrder()->take(1);
|
||||
// if (null !== $except) {
|
||||
// $query->where('accounts.id', '!=', $except);
|
||||
// }
|
||||
//
|
||||
// return $query->first(['accounts.*']);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
34
tests/Traits/FakeValues.php
Normal file
34
tests/Traits/FakeValues.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*
|
||||
* FakeValues.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Tests\Traits;
|
||||
|
||||
|
||||
trait FakeValues
|
||||
{
|
||||
// /**
|
||||
// * @return string
|
||||
// */
|
||||
// protected function fakeName(): string {
|
||||
// return '';
|
||||
// }
|
||||
|
||||
}
|
@ -31,17 +31,17 @@ use FireflyConfig;
|
||||
*/
|
||||
trait MocksDefaultValues
|
||||
{
|
||||
public function mockDefaultConfiguration(): void
|
||||
{
|
||||
|
||||
$falseConfig = new Configuration;
|
||||
$falseConfig->data = false;
|
||||
|
||||
$idConfig = new Configuration;
|
||||
$idConfig->data = 'abc';
|
||||
|
||||
FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->andReturn($falseConfig);
|
||||
FireflyConfig::shouldReceive('get')->withArgs(['installation_id', null])->andReturn($idConfig);
|
||||
}
|
||||
// public function mockDefaultConfiguration(): void
|
||||
// {
|
||||
//
|
||||
// $falseConfig = new Configuration;
|
||||
// $falseConfig->data = false;
|
||||
//
|
||||
// $idConfig = new Configuration;
|
||||
// $idConfig->data = 'abc';
|
||||
//
|
||||
// FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->andReturn($falseConfig);
|
||||
// FireflyConfig::shouldReceive('get')->withArgs(['installation_id', null])->andReturn($idConfig);
|
||||
// }
|
||||
|
||||
}
|
||||
|
126
tests/Traits/RandomValues.php
Normal file
126
tests/Traits/RandomValues.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/*
|
||||
* RandomValues.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Tests\Traits;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
/**
|
||||
* Trait RandomValues
|
||||
*/
|
||||
trait RandomValues
|
||||
{
|
||||
/**
|
||||
* @param $k
|
||||
* @param $xs
|
||||
*
|
||||
* @return array|array[]
|
||||
*/
|
||||
protected function combinationsOf($k, $xs): array
|
||||
{
|
||||
if ($k === 0) {
|
||||
return [[]];
|
||||
}
|
||||
if (count($xs) === 0) {
|
||||
return [];
|
||||
}
|
||||
$x = $xs[0];
|
||||
$xs1 = array_slice($xs, 1, count($xs) - 1);
|
||||
$res1 = $this->combinationsOf($k - 1, $xs1);
|
||||
for ($i = 0; $i < count($res1); $i++) {
|
||||
array_splice($res1[$i], 0, 0, $x);
|
||||
}
|
||||
$res2 = $this->combinationsOf($k, $xs1);
|
||||
|
||||
return array_merge($res1, $res2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function randomAccountRole(): string
|
||||
{
|
||||
return $this->randomFromArray(['defaultAsset', 'sharedAsset', 'savingAsset']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function randomLiabilityType(): string
|
||||
{
|
||||
return $this->randomFromArray(['loan', 'debt', 'mortgage']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getRandomCurrencyCode(): string
|
||||
{
|
||||
return $this->randomFromArray(['EUR', 'USD', 'GBP']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getRandomAmount(): string
|
||||
{
|
||||
return number_format(rand(1000, 100000) / 100, '2', '.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getRandomDateString(): string
|
||||
{
|
||||
$date = Carbon::now();
|
||||
$date->subDays(rand(10, 100));
|
||||
|
||||
return $date->format('Y-m-d');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getRandomPercentage(): string
|
||||
{
|
||||
return rand(1, 10000) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getRandomInterestPeriod(): string
|
||||
{
|
||||
return $this->randomFromArray(['daily', 'monthly', 'yearly']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function randomFromArray(array $array)
|
||||
{
|
||||
return $array[rand(0, count($array) - 1)];
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Traits;
|
||||
|
||||
use Exception;
|
||||
use Log;
|
||||
|
||||
@ -30,6 +31,51 @@ use Log;
|
||||
*/
|
||||
trait TestHelpers
|
||||
{
|
||||
/**
|
||||
* @param array $minimalSets
|
||||
* @param array $startOptionalSets
|
||||
* @param array $regenConfig
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function genericDataProvider(array $minimalSets, array $startOptionalSets, array $regenConfig): array
|
||||
{
|
||||
$submissions = [];
|
||||
foreach ($minimalSets as $set) {
|
||||
$body = [];
|
||||
foreach ($set['fields'] as $field => $value) {
|
||||
$body[$field] = $value;
|
||||
}
|
||||
// minimal set is part of all submissions:
|
||||
$submissions[] = [$body];
|
||||
|
||||
// then loop and add fields:
|
||||
$optionalSets = $startOptionalSets;
|
||||
$keys = array_keys($optionalSets);
|
||||
$submissions = [];
|
||||
for ($i = 1; $i <= count($keys); $i++) {
|
||||
$combinations = $this->combinationsOf($i, $keys);
|
||||
// expand body with N extra fields:
|
||||
foreach ($combinations as $extraFields) {
|
||||
$second = $body;
|
||||
foreach ($extraFields as $extraField) {
|
||||
// now loop optional sets on $extraField and add whatever the config is:
|
||||
foreach ($optionalSets[$extraField]['fields'] as $newField => $newValue) {
|
||||
$second[$newField] = $newValue;
|
||||
}
|
||||
}
|
||||
|
||||
$second = $this->regenerateValues($second, $regenConfig);
|
||||
$submissions[] = [$second];
|
||||
}
|
||||
}
|
||||
unset($second);
|
||||
}
|
||||
|
||||
return $submissions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
@ -45,4 +91,123 @@ trait TestHelpers
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $set
|
||||
* @param $opts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function regenerateValues($set, $opts): array
|
||||
{
|
||||
foreach ($opts as $key => $func) {
|
||||
if (array_key_exists($key, $set)) {
|
||||
$set[$key] = $func();
|
||||
}
|
||||
}
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
protected function submitAndCompare(string $route, array $submission): void {
|
||||
// submit!
|
||||
$response = $this->post(route($route), $submission, ['Accept' => 'application/json']);
|
||||
$responseBody = $response->content();
|
||||
$responseJson = json_decode($responseBody, true);
|
||||
$message = sprintf('Status code is %d and body is %s', $response->getStatusCode(), $responseBody);
|
||||
$this->assertEquals($response->getStatusCode(), 200, $message);
|
||||
$response->assertHeader('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
// compare results:
|
||||
foreach ($responseJson['data']['attributes'] as $returnName => $returnValue) {
|
||||
if (array_key_exists($returnName, $submission)) {
|
||||
if ($this->ignoreCombination('store-account', $submission['type'], $returnName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$message = sprintf(
|
||||
"Return value '%s' of key '%s' does not match submitted value '%s'.\n%s\n%s", $returnValue, $returnName, $submission[$returnName],
|
||||
json_encode($submission), $responseBody
|
||||
);
|
||||
$this->assertEquals($returnValue, $submission[$returnName], $message);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @param array $minimalSets
|
||||
* @param array $startOptionalSets
|
||||
* @param array $regenConfig
|
||||
*/
|
||||
protected function runBasicStoreTest(string $route, array $minimalSets, array $startOptionalSets, array $regenConfig): void
|
||||
{
|
||||
// test API
|
||||
foreach ($minimalSets as $set) {
|
||||
$body = [];
|
||||
foreach ($set['fields'] as $field => $value) {
|
||||
$body[$field] = $value;
|
||||
}
|
||||
// submit minimal set:
|
||||
Log::debug(sprintf('Submitting: %s', json_encode($body)));
|
||||
$response = $this->post(route($route), $body, ['Accept' => 'application/json']);
|
||||
$response->assertStatus(200);
|
||||
$response->assertHeader('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
// then loop and add fields:
|
||||
$optionalSets = $startOptionalSets;
|
||||
$keys = array_keys($optionalSets);
|
||||
$submissions = [];
|
||||
for ($i = 1; $i <= count($keys); $i++) {
|
||||
$combinations = $this->combinationsOf($i, $keys);
|
||||
// expand body with N extra fields:
|
||||
foreach ($combinations as $extraFields) {
|
||||
$second = $body;
|
||||
foreach ($extraFields as $extraField) {
|
||||
// now loop optional sets on $extraField and add whatever the config is:
|
||||
foreach ($optionalSets[$extraField]['fields'] as $newField => $newValue) {
|
||||
$second[$newField] = $newValue;
|
||||
}
|
||||
}
|
||||
|
||||
$second = $this->regenerateValues($second, $regenConfig);
|
||||
$submissions[] = $second;
|
||||
}
|
||||
}
|
||||
unset($second);
|
||||
|
||||
// count and progress maybe
|
||||
|
||||
// all submissions counted and submitted:
|
||||
foreach ($submissions as $submission) {
|
||||
Log::debug(sprintf('Submitting: %s', json_encode($submission)));
|
||||
|
||||
// submit again!
|
||||
$response = $this->post(route($route), $submission, ['Accept' => 'application/json']);
|
||||
$responseBody = $response->content();
|
||||
$responseJson = json_decode($responseBody, true);
|
||||
$message = sprintf('Status code is %d and body is %s', $response->getStatusCode(), $responseBody);
|
||||
$this->assertEquals($response->getStatusCode(), 200, $message);
|
||||
$response->assertHeader('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
// compare results:
|
||||
foreach ($responseJson['data']['attributes'] as $returnName => $returnValue) {
|
||||
if (array_key_exists($returnName, $submission)) {
|
||||
if ($this->ignoreCombination('store-account', $submission['type'], $returnName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$message = sprintf(
|
||||
"Return value '%s' of key '%s' does not match submitted value '%s'.\n%s\n%s", $returnValue, $returnName, $submission[$returnName],
|
||||
json_encode($submission), $responseBody
|
||||
);
|
||||
$this->assertEquals($returnValue, $submission[$returnName], $message);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user