diff --git a/app/Http/Controllers/Recurring/EditController.php b/app/Http/Controllers/Recurring/EditController.php index ebae84cf4d..c77733b9c0 100644 --- a/app/Http/Controllers/Recurring/EditController.php +++ b/app/Http/Controllers/Recurring/EditController.php @@ -105,10 +105,10 @@ class EditController extends Controller 'times' => (string)trans('firefly.repeat_times'), ]; if (null !== $recurrence->repeat_until) { - $repetitionEnd = 'until_date'; + $repetitionEnd = 'until_date'; // @codeCoverageIgnore } if ($recurrence->repetitions > 0) { - $repetitionEnd = 'times'; + $repetitionEnd = 'times'; // @codeCoverageIgnore } $weekendResponses = [ diff --git a/app/Http/Controllers/Report/AccountController.php b/app/Http/Controllers/Report/AccountController.php index 01b67723af..2f7e9f524e 100644 --- a/app/Http/Controllers/Report/AccountController.php +++ b/app/Http/Controllers/Report/AccountController.php @@ -63,10 +63,12 @@ class AccountController extends Controller $accountReport = $accountTasker->getAccountReport($accounts, $start, $end); try { $result = view('reports.partials.accounts', compact('accountReport'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.accounts: %s', $e->getMessage())); $result = 'Could not render view.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; diff --git a/app/Http/Controllers/Report/BalanceController.php b/app/Http/Controllers/Report/BalanceController.php index 1c08c89f27..0993cf4541 100644 --- a/app/Http/Controllers/Report/BalanceController.php +++ b/app/Http/Controllers/Report/BalanceController.php @@ -61,10 +61,12 @@ class BalanceController extends Controller $balance = $helper->getBalanceReport($accounts, $start, $end); try { $result = view('reports.partials.balance', compact('balance'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.balance: %s', $e->getMessage())); $result = 'Could not render view.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; diff --git a/app/Http/Controllers/Report/BudgetController.php b/app/Http/Controllers/Report/BudgetController.php index 3eddbc2839..d16ba0c81e 100644 --- a/app/Http/Controllers/Report/BudgetController.php +++ b/app/Http/Controllers/Report/BudgetController.php @@ -63,10 +63,12 @@ class BudgetController extends Controller $budgets = $helper->getBudgetReport($start, $end, $accounts); try { $result = view('reports.partials.budgets', compact('budgets'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.budgets: %s', $e->getMessage())); $result = 'Could not render view.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; @@ -103,10 +105,12 @@ class BudgetController extends Controller $periods = app('navigation')->listOfPeriods($start, $end); try { $result = view('reports.partials.budget-period', compact('report', 'periods'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); $result = 'Could not render view.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; diff --git a/app/Http/Controllers/Report/CategoryController.php b/app/Http/Controllers/Report/CategoryController.php index 7214d556cb..941a851d78 100644 --- a/app/Http/Controllers/Report/CategoryController.php +++ b/app/Http/Controllers/Report/CategoryController.php @@ -67,10 +67,12 @@ class CategoryController extends Controller $periods = app('navigation')->listOfPeriods($start, $end); try { $result = view('reports.partials.category-period', compact('report', 'periods'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage())); $result = 'An error prevented Firefly III from rendering. Apologies.'; } + // @codeCoverageIgnoreEnd $cache->store($result); @@ -107,10 +109,12 @@ class CategoryController extends Controller $periods = app('navigation')->listOfPeriods($start, $end); try { $result = view('reports.partials.category-period', compact('report', 'periods'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage())); $result = 'An error prevented Firefly III from rendering. Apologies.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; @@ -160,10 +164,12 @@ class CategoryController extends Controller try { $result = view('reports.partials.categories', compact('report'))->render(); $cache->store($result); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage())); $result = 'An error prevented Firefly III from rendering. Apologies.'; } + // @codeCoverageIgnoreEnd return $result; } diff --git a/app/Http/Controllers/Report/ExpenseController.php b/app/Http/Controllers/Report/ExpenseController.php index 2e2b3a9429..73de303fe2 100644 --- a/app/Http/Controllers/Report/ExpenseController.php +++ b/app/Http/Controllers/Report/ExpenseController.php @@ -107,10 +107,12 @@ class ExpenseController extends Controller } try { $result = view('reports.partials.exp-budgets', compact('together'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Could not render category::budget: %s', $e->getMessage())); $result = 'An error prevented Firefly III from rendering. Apologies.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; @@ -170,10 +172,12 @@ class ExpenseController extends Controller } try { $result = view('reports.partials.exp-categories', compact('together'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage())); $result = 'An error prevented Firefly III from rendering. Apologies.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; @@ -220,10 +224,12 @@ class ExpenseController extends Controller } try { $result = view('reports.partials.exp-not-grouped', compact('result'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage())); $result = 'An error prevented Firefly III from rendering. Apologies.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; @@ -271,10 +277,12 @@ class ExpenseController extends Controller ); try { $result = view('reports.partials.top-transactions', compact('sorted'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Could not render category::topExpense: %s', $e->getMessage())); $result = 'An error prevented Firefly III from rendering. Apologies.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; @@ -320,10 +328,12 @@ class ExpenseController extends Controller ); try { $result = view('reports.partials.top-transactions', compact('sorted'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Could not render category::topIncome: %s', $e->getMessage())); $result = 'An error prevented Firefly III from rendering. Apologies.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; diff --git a/app/Http/Controllers/Report/OperationsController.php b/app/Http/Controllers/Report/OperationsController.php index 383629446b..8b8eca74c1 100644 --- a/app/Http/Controllers/Report/OperationsController.php +++ b/app/Http/Controllers/Report/OperationsController.php @@ -81,10 +81,12 @@ class OperationsController extends Controller $type = 'expense-entry'; try { $result = view('reports.partials.income-expenses', compact('entries', 'type'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.income-expense: %s', $e->getMessage())); $result = 'Could not render view.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; @@ -114,10 +116,12 @@ class OperationsController extends Controller $type = 'income-entry'; try { $result = view('reports.partials.income-expenses', compact('entries', 'type'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.income-expenses: %s', $e->getMessage())); $result = 'Could not render view.'; } + // @codeCoverageIgnoreEnd $cache->store($result); @@ -166,10 +170,12 @@ class OperationsController extends Controller ); try { $result = view('reports.partials.operations', compact('incomeSum', 'expensesSum'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.operations: %s', $e->getMessage())); $result = 'Could not render view.'; } + // @codeCoverageIgnoreEnd $cache->store($result); return $result; diff --git a/app/Http/Controllers/Rule/CreateController.php b/app/Http/Controllers/Rule/CreateController.php index 2cc5c1eb06..3656586d6f 100644 --- a/app/Http/Controllers/Rule/CreateController.php +++ b/app/Http/Controllers/Rule/CreateController.php @@ -258,10 +258,13 @@ class CreateController extends Controller 'count' => $index + 1, ] )->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { + Log::debug(sprintf('Throwable was thrown in getTriggersForBill(): %s', $e->getMessage())); Log::debug($e->getTraceAsString()); $string = ''; + // @codeCoverageIgnoreEnd } if ('' !== $string) { $result[] = $string; diff --git a/app/Http/Controllers/System/CronController.php b/app/Http/Controllers/System/CronController.php index 46a50c8384..33e57aa517 100644 --- a/app/Http/Controllers/System/CronController.php +++ b/app/Http/Controllers/System/CronController.php @@ -49,7 +49,8 @@ class CronController */ private function runRecurring(): string { - $recurring = new RecurringCronjob; + /** @var RecurringCronjob $recurring */ + $recurring = app(RecurringCronjob::class); try { $result = $recurring->fire(); } catch (FireflyException $e) { diff --git a/app/Http/Requests/RecurrenceFormRequest.php b/app/Http/Requests/RecurrenceFormRequest.php index a20ffccbe1..c28d22ff58 100644 --- a/app/Http/Requests/RecurrenceFormRequest.php +++ b/app/Http/Requests/RecurrenceFormRequest.php @@ -118,7 +118,7 @@ class RecurrenceFormRequest extends Request // fill in source and destination account data switch ($this->string('transaction_type')) { default: - throw new FireflyException(sprintf('Cannot handle transaction type "%s"', $this->string('transaction_type'))); + throw new FireflyException(sprintf('Cannot handle transaction type "%s"', $this->string('transaction_type'))); // @codeCoverageIgnore case 'withdrawal': $return['transactions'][0]['source_id'] = $this->integer('source_id'); $return['transactions'][0]['destination_name'] = $this->string('destination_name'); @@ -227,8 +227,6 @@ class RecurrenceFormRequest extends Request $rules['title'] = 'required|between:1,255|uniqueObjectForUser:recurrences,title,' . $recurrence->id; $rules['first_date'] = 'required|date'; } - - return $rules; } diff --git a/tests/Api/V1/Controllers/TransactionControllerTest.php b/tests/Api/V1/Controllers/TransactionControllerTest.php index 876e83f842..f4480aa2d7 100644 --- a/tests/Api/V1/Controllers/TransactionControllerTest.php +++ b/tests/Api/V1/Controllers/TransactionControllerTest.php @@ -28,9 +28,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Collector\TransactionCollector; use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Filter\NegativeAmountFilter; -use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Illuminate\Support\Collection; @@ -46,7 +44,7 @@ class TransactionControllerTest extends TestCase /** * */ - public function setUp() + public function setUp(): void { parent::setUp(); Passport::actingAs($this->user()); @@ -1329,16 +1327,8 @@ class TransactionControllerTest extends TestCase */ public function testShowDeposit(): void { - $loop = 0; - do { - /** @var TransactionJournal $journal */ - $journal = $this->user()->transactionJournals()->inRandomOrder()->where('transaction_type_id', 2)->whereNull('deleted_at')->first(); - $count = $journal->transactions()->count(); - $loop++; - } while ($count !== 2 && $loop < 30); - $transaction = $journal->transactions()->first(); - - + $deposit = $this->getRandomDeposit(); + $transaction = $deposit->transactions()->first(); $accountRepos = $this->mock(AccountRepositoryInterface::class); $accountRepos->shouldReceive('setUser'); $accountRepos->shouldReceive('getAccountsByType') @@ -1350,7 +1340,7 @@ class TransactionControllerTest extends TestCase $collector->setUser($this->user()); $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); $collector->setAllAssetAccounts(); - $collector->setJournals(new Collection([$journal])); + $collector->setJournals(new Collection([$deposit])); $collector->setLimit(5)->setPage(1); $transactions = $collector->getTransactions(); @@ -1374,7 +1364,7 @@ class TransactionControllerTest extends TestCase [ 'data' => [[ 'attributes' => [ - 'description' => $journal->description, + 'description' => $deposit->description, 'type' => 'Deposit', ], ]], @@ -1393,15 +1383,7 @@ class TransactionControllerTest extends TestCase */ public function testShowWithdrawal(): void { - $loop = 0; - do { - // this is kind of cheating but OK. - /** @var TransactionJournal $journal */ - $journal = $this->user()->transactionJournals()->inRandomOrder()->where('transaction_type_id', 1)->whereNull('deleted_at')->first(); - $count = $journal->transactions()->count(); - $loop++; - } while ($count !== 2 && $loop < 30); - /** @var Transaction $transaction */ + $journal = $this->getRandomWithdrawal(); $transaction = $journal->transactions()->first(); $transaction->description = null; $transaction->save(); @@ -2441,7 +2423,7 @@ class TransactionControllerTest extends TestCase $accountRepos->shouldReceive('setUser'); $accountRepos->shouldReceive('getAccountsById')->withArgs([[$account->id]])->andReturn(new Collection([$account])); - $data = [ + $data = [ 'description' => 'Some deposit #' . random_int(1, 10000), 'date' => '2018-01-01', 'transactions' => [ @@ -2452,12 +2434,7 @@ class TransactionControllerTest extends TestCase ], ], ]; - do { - /** @var TransactionJournal $deposit */ - $deposit = $this->user()->transactionJournals()->inRandomOrder()->where('transaction_type_id', 2)->first(); - $count = $deposit->transactions()->count(); - } while ($count !== 2); - + $deposit = $this->getRandomDeposit(); $transaction = $deposit->transactions()->first(); $repository->shouldReceive('setUser'); $repository->shouldReceive('update')->andReturn($deposit)->once(); @@ -2494,13 +2471,8 @@ class TransactionControllerTest extends TestCase ], ], ]; - do { - /** @var TransactionJournal $withdrawal */ - $withdrawal = $this->user()->transactionJournals()->inRandomOrder()->where('transaction_type_id', 1)->first(); - $count = $withdrawal->transactions()->count(); - } while ($count !== 2); - + $withdrawal = $this->getRandomWithdrawal(); $transaction = $withdrawal->transactions()->first(); $repository->shouldReceive('setUser'); $repository->shouldReceive('update')->andReturn($withdrawal)->once(); diff --git a/tests/Feature/Controllers/Recurring/CreateControllerTest.php b/tests/Feature/Controllers/Recurring/CreateControllerTest.php index c75543fe52..3fdd63d91a 100644 --- a/tests/Feature/Controllers/Recurring/CreateControllerTest.php +++ b/tests/Feature/Controllers/Recurring/CreateControllerTest.php @@ -28,6 +28,7 @@ use Carbon\Carbon; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; use Illuminate\Support\Collection; use Log; @@ -74,35 +75,189 @@ class CreateControllerTest extends TestCase $recurringRepos = $this->mock(RecurringRepositoryInterface::class); $budgetRepos = $this->mock(BudgetRepositoryInterface::class); $categoryRepos = $this->mock(CategoryRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); $tomorrow = Carbon::create()->addDays(2); - $recurrence = $this->user()->recurrences()->first(); + $recurrence = $this->user()->recurrences()->first(); $data = [ - 'title' => 'hello', + 'title' => 'hello' . random_int(1, 100000), 'first_date' => $tomorrow->format('Y-m-d'), 'repetition_type' => 'daily', 'skip' => 0, - 'recurring_description' => 'Some descr', + 'recurring_description' => 'Some descr' . random_int(1, 100000), 'active' => '1', 'apply_rules' => '1', + 'foreign_amount' => '1', + 'foreign_currency_id' => '2', // mandatory for transaction: 'transaction_description' => 'Some descr', 'transaction_type' => 'withdrawal', 'transaction_currency_id' => '1', 'amount' => '30', + // mandatory account info: 'source_id' => '1', - 'source_name' => '', - 'destination_id' => '', 'destination_name' => 'Some Expense', // optional fields: 'budget_id' => '1', 'category' => 'CategoryA', 'tags' => 'A,B,C', + 'create_another' => '1', + 'repetition_end' => 'times', + 'repetitions' => 3, + ]; - 'repetition_end' => 'times', - 'repetitions' => 3, + $recurringRepos->shouldReceive('store')->andReturn($recurrence)->once(); + + $this->be($this->user()); + $response = $this->post(route('recurring.store'), $data); + $response->assertStatus(302); + $response->assertSessionHas('success'); + } + + /** + * @covers \FireflyIII\Http\Controllers\Recurring\CreateController + * @covers \FireflyIII\Http\Requests\RecurrenceFormRequest + */ + public function testStoreDeposit(): void + { + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $categoryRepos = $this->mock(CategoryRepositoryInterface::class); + $tomorrow = Carbon::create()->addDays(2); + $recurrence = $this->user()->recurrences()->first(); + $data = [ + 'title' => 'hello' . random_int(1, 100000), + 'first_date' => $tomorrow->format('Y-m-d'), + 'repetition_type' => 'daily', + 'skip' => 0, + 'recurring_description' => 'Some descr' . random_int(1, 100000), + 'active' => '1', + 'apply_rules' => '1', + 'foreign_amount' => '1', + 'foreign_currency_id' => '2', + + // mandatory for transaction: + 'transaction_description' => 'Some descr', + 'transaction_type' => 'deposit', + 'transaction_currency_id' => '1', + 'amount' => '30', + + // mandatory account info: + 'source_id' => '2', + 'source_name' => 'Some source', + 'destination_id' => '1', + 'destination_name' => 'Some Expense', + + // optional fields: + 'budget_id' => '1', + 'category' => 'CategoryA', + 'tags' => 'A,B,C', + 'create_another' => '1', + 'repetition_end' => 'times', + 'repetitions' => 3, + ]; + + $recurringRepos->shouldReceive('store')->andReturn($recurrence)->once(); + + $this->be($this->user()); + $response = $this->post(route('recurring.store'), $data); + $response->assertStatus(302); + $response->assertSessionHas('success'); + } + + /** + * @covers \FireflyIII\Http\Controllers\Recurring\CreateController + * @covers \FireflyIII\Http\Requests\RecurrenceFormRequest + */ + public function testStoreTransfer(): void + { + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $categoryRepos = $this->mock(CategoryRepositoryInterface::class); + $tomorrow = Carbon::create()->addDays(2); + $recurrence = $this->user()->recurrences()->first(); + $data = [ + 'title' => 'hello' . random_int(1, 100000), + 'first_date' => $tomorrow->format('Y-m-d'), + 'repetition_type' => 'daily', + 'skip' => 0, + 'recurring_description' => 'Some descr' . random_int(1, 100000), + 'active' => '1', + 'apply_rules' => '1', + 'foreign_amount' => '1', + 'foreign_currency_id' => '2', + + // mandatory for transaction: + 'transaction_description' => 'Some descr', + 'transaction_type' => 'transfer', + 'transaction_currency_id' => '1', + 'amount' => '30', + + // mandatory account info: + 'source_id' => '2', + 'source_name' => 'Some source', + 'destination_id' => '1', + 'destination_name' => 'Some Expense', + + // optional fields: + 'budget_id' => '1', + 'category' => 'CategoryA', + 'tags' => 'A,B,C', + 'create_another' => '1', + 'repetition_end' => 'times', + 'repetitions' => 3, + ]; + + $recurringRepos->shouldReceive('store')->andReturn($recurrence)->once(); + + $this->be($this->user()); + $response = $this->post(route('recurring.store'), $data); + $response->assertStatus(302); + $response->assertSessionHas('success'); + } + + /** + * @covers \FireflyIII\Http\Controllers\Recurring\CreateController + * @covers \FireflyIII\Http\Requests\RecurrenceFormRequest + */ + public function testStoreUntilDate(): void + { + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $categoryRepos = $this->mock(CategoryRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $tomorrow = Carbon::create()->addDays(2); + $recurrence = $this->user()->recurrences()->first(); + $data = [ + 'title' => 'hello' . random_int(1, 100000), + 'first_date' => $tomorrow->format('Y-m-d'), + 'repetition_type' => 'daily', + 'skip' => 0, + 'recurring_description' => 'Some descr' . random_int(1, 100000), + 'active' => '1', + 'apply_rules' => '1', + 'foreign_amount' => '1', + 'foreign_currency_id' => '2', + + // mandatory for transaction: + 'transaction_description' => 'Some descr', + 'transaction_type' => 'withdrawal', + 'transaction_currency_id' => '1', + 'amount' => '30', + + // mandatory account info: + 'source_id' => '1', + 'destination_name' => 'Some Expense', + + // optional fields: + 'budget_id' => '1', + 'category' => 'CategoryA', + 'tags' => 'A,B,C', + 'create_another' => '1', + 'repetition_end' => 'until_date', + 'repeat_until' => $tomorrow->format('Y-m-d'), ]; $recurringRepos->shouldReceive('store')->andReturn($recurrence)->once(); diff --git a/tests/Feature/Controllers/Recurring/DeleteControllerTest.php b/tests/Feature/Controllers/Recurring/DeleteControllerTest.php new file mode 100644 index 0000000000..fadee7b0d3 --- /dev/null +++ b/tests/Feature/Controllers/Recurring/DeleteControllerTest.php @@ -0,0 +1,77 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Recurring; + +use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; +use Illuminate\Support\Collection; +use Log; +use Tests\TestCase; + +/** + * + * Class DeleteControllerTest + */ +class DeleteControllerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * @covers \FireflyIII\Http\Controllers\Recurring\DeleteController + */ + public function testDelete(): void + { + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $recurringRepos->shouldReceive('getTransactions')->andReturn(new Collection())->once(); + + + $this->be($this->user()); + $response = $this->get(route('recurring.delete', [1])); + $response->assertStatus(200); + $response->assertSee('