From 22ab9ebb2f3e5956112b2a0f55532e484d8f4b2b Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 5 Apr 2015 19:43:20 +0200 Subject: [PATCH] Included tests for the category controller. --- app/Http/Controllers/BudgetController.php | 2 +- app/Http/Controllers/CategoryController.php | 56 ++--- .../Category/CategoryRepository.php | 81 ++++++- .../Category/CategoryRepositoryInterface.php | 37 ++++ tests/controllers/CategoryControllerTest.php | 199 ++++++++++++++++++ tests/factories/all.php | 9 + 6 files changed, 341 insertions(+), 43 deletions(-) create mode 100644 tests/controllers/CategoryControllerTest.php diff --git a/app/Http/Controllers/BudgetController.php b/app/Http/Controllers/BudgetController.php index 7545517016..92078806b0 100644 --- a/app/Http/Controllers/BudgetController.php +++ b/app/Http/Controllers/BudgetController.php @@ -155,7 +155,7 @@ class BudgetController extends Controller $start = Session::get('start', Carbon::now()->startOfMonth()); $end = Session::get('end', Carbon::now()->startOfMonth()); $list = $repository->getWithoutBudget($start, $end); - $subTitle = 'Transactions without a budget in ' . $start->format('F Y'); + $subTitle = 'Transactions without a budget between ' . $start->format('jS F Y') . ' and ' . $end->format('jS F Y'); return view('budgets.noBudget', compact('list', 'subTitle')); } diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index b664ec6566..105959bc54 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -10,8 +10,8 @@ use Illuminate\Pagination\LengthAwarePaginator; use Input; use Redirect; use Session; -use View; use URL; +use View; /** * Class CategoryController @@ -96,21 +96,15 @@ class CategoryController extends Controller /** * @return $this + * */ - public function index() + public function index(CategoryRepositoryInterface $repository) { - $categories = Auth::user()->categories()->orderBy('name', 'ASC')->get(); + $categories = $repository->getCategories(); $categories->each( - function (Category $category) { - $latest = $category->transactionjournals() - ->orderBy('transaction_journals.date', 'DESC') - ->orderBy('transaction_journals.order', 'ASC') - ->orderBy('transaction_journals.id', 'DESC') - ->first(); - if ($latest) { - $category->lastActivity = $latest->date; - } + function (Category $category) use ($repository) { + $category->lastActivity = $repository->getLatestActivity($category); } ); @@ -120,21 +114,11 @@ class CategoryController extends Controller /** * @return \Illuminate\View\View */ - public function noCategory() + public function noCategory(CategoryRepositoryInterface $repository) { - $start = Session::get('start', Carbon::now()->startOfMonth()); - $end = Session::get('end', Carbon::now()->startOfMonth()); - $list = Auth::user() - ->transactionjournals() - ->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') - ->whereNull('category_transaction_journal.id') - ->before($end) - ->after($start) - ->orderBy('transaction_journals.date', 'DESC') - ->orderBy('transaction_journals.order', 'ASC') - ->orderBy('transaction_journals.id', 'DESC') - ->get(['transaction_journals.*']); - + $start = Session::get('start', Carbon::now()->startOfMonth()); + $end = Session::get('end', Carbon::now()->startOfMonth()); + $list = $repository->getWithoutCategory($start, $end); $subTitle = 'Transactions without a category between ' . $start->format('jS F Y') . ' and ' . $end->format('jS F Y'); return view('categories.noCategory', compact('list', 'subTitle')); @@ -149,17 +133,9 @@ class CategoryController extends Controller { $hideCategory = true; // used in list. $page = intval(Input::get('page')); - $offset = $page > 0 ? $page * 50 : 0; - $set = $category->transactionJournals()->withRelevantData()->take(50)->offset($offset) - ->orderBy('transaction_journals.date', 'DESC') - ->orderBy('transaction_journals.order', 'ASC') - ->orderBy('transaction_journals.id', 'DESC') - ->get( - ['transaction_journals.*'] - ); - $count = $category->transactionJournals()->count(); - - $journals = new LengthAwarePaginator($set, $count, 50, $page); + $set = $repository->getJournals($category, $page); + $count = $repository->countJournals($category); + $journals = new LengthAwarePaginator($set, $count, 50, $page); return view('categories.show', compact('category', 'journals', 'hideCategory')); } @@ -182,11 +158,8 @@ class CategoryController extends Controller if (intval(Input::get('create_another')) === 1) { Session::put('categories.create.fromStore', true); - return Redirect::route('categories.create')->withInput(); - } - if (intval(Input::get('create_another')) === 1) { - return Redirect::route('categories.create'); + return Redirect::route('categories.create')->withInput(); } return Redirect::route('categories.index'); @@ -212,6 +185,7 @@ class CategoryController extends Controller if (intval(Input::get('return_to_edit')) === 1) { Session::put('categories.edit.fromUpdate', true); + return Redirect::route('categories.edit', $category->id); } diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php index 437fb2da69..3b8710a3f4 100644 --- a/app/Repositories/Category/CategoryRepository.php +++ b/app/Repositories/Category/CategoryRepository.php @@ -2,7 +2,10 @@ namespace FireflyIII\Repositories\Category; +use Auth; +use Carbon\Carbon; use FireflyIII\Models\Category; +use Illuminate\Support\Collection; /** * Class CategoryRepository @@ -12,6 +15,17 @@ use FireflyIII\Models\Category; class CategoryRepository implements CategoryRepositoryInterface { + /** + * @param Category $category + * + * @return int + */ + public function countJournals(Category $category) + { + return $category->transactionJournals()->count(); + + } + /** * @param Category $category * @@ -24,6 +38,72 @@ class CategoryRepository implements CategoryRepositoryInterface return true; } + /** + * @return Collection + */ + public function getCategories() + { + return Auth::user()->categories()->orderBy('name', 'ASC')->get(); + } + + /** + * @param Category $category + * @param int $page + * + * @return Collection + */ + public function getJournals(Category $category, $page) + { + $offset = $page > 0 ? $page * 50 : 0; + + return $category->transactionJournals()->withRelevantData()->take(50)->offset($offset) + ->orderBy('transaction_journals.date', 'DESC') + ->orderBy('transaction_journals.order', 'ASC') + ->orderBy('transaction_journals.id', 'DESC') + ->get( + ['transaction_journals.*'] + ); + + } + + /** + * @param Category $category + * + * @return Carbon|null + */ + public function getLatestActivity(Category $category) + { + $latest = $category->transactionjournals() + ->orderBy('transaction_journals.date', 'DESC') + ->orderBy('transaction_journals.order', 'ASC') + ->orderBy('transaction_journals.id', 'DESC') + ->first(); + if ($latest) { + return $latest->date; + } + + return null; + } + + /** + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getWithoutCategory(Carbon $start, Carbon $end) + { + return Auth::user() + ->transactionjournals() + ->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') + ->whereNull('category_transaction_journal.id') + ->before($end) + ->after($start) + ->orderBy('transaction_journals.date', 'DESC') + ->orderBy('transaction_journals.order', 'ASC') + ->orderBy('transaction_journals.id', 'DESC') + ->get(['transaction_journals.*']); + } /** * @param array $data @@ -57,5 +137,4 @@ class CategoryRepository implements CategoryRepositoryInterface return $category; } - } diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php index 7e4871a378..33ba5cc1d1 100644 --- a/app/Repositories/Category/CategoryRepositoryInterface.php +++ b/app/Repositories/Category/CategoryRepositoryInterface.php @@ -2,7 +2,9 @@ namespace FireflyIII\Repositories\Category; +use Carbon\Carbon; use FireflyIII\Models\Category; +use Illuminate\Support\Collection; /** * Interface CategoryRepositoryInterface @@ -11,6 +13,13 @@ use FireflyIII\Models\Category; */ interface CategoryRepositoryInterface { + /** + * @param Category $category + * + * @return int + */ + public function countJournals(Category $category); + /** * @param Category $category * @@ -18,6 +27,34 @@ interface CategoryRepositoryInterface */ public function destroy(Category $category); + /** + * @return Collection + */ + public function getCategories(); + + /** + * @param Category $category + * @param int $page + * + * @return Collection + */ + public function getJournals(Category $category, $page); + + /** + * @param Category $category + * + * @return Carbon|null + */ + public function getLatestActivity(Category $category); + + /** + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getWithoutCategory(Carbon $start, Carbon $end); + /** * @param array $data * diff --git a/tests/controllers/CategoryControllerTest.php b/tests/controllers/CategoryControllerTest.php new file mode 100644 index 0000000000..33119cc388 --- /dev/null +++ b/tests/controllers/CategoryControllerTest.php @@ -0,0 +1,199 @@ +be($category->user); + + $this->call('GET', '/categories/create'); + $this->assertResponseOk(); + $this->assertViewHas('subTitle', 'Create a new category'); + } + + public function testDelete() + { + + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $this->be($category->user); + + $this->call('GET', '/categories/delete/' . $category->id); + $this->assertResponseOk(); + $this->assertViewHas('subTitle', 'Delete category' . e($category->name) . '"'); + } + + public function testDestroy() + { + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $this->be($category->user); + + $repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); + $repository->shouldReceive('destroy'); + + $this->call('POST', '/categories/destroy/' . $category->id, ['_token' => 'replaceMe']); + $this->assertResponseStatus(302); + $this->assertSessionHas('success', 'The category "' . e($category->name) . '" was deleted.'); + } + + public function testEdit() + { + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $this->be($category->user); + + $this->call('GET', '/categories/edit/' . $category->id); + $this->assertResponseOk(); + $this->assertViewHas('subTitle', 'Edit category "' . e($category->name) . '"'); + } + + public function testIndex() + { + $collection = new Collection; + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $this->be($category->user); + $collection->push($category); + + Amount::shouldReceive('getCurrencyCode')->andReturn('xx'); + + $repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); + $repository->shouldReceive('getCategories')->andReturn($collection); + $repository->shouldReceive('getLatestActivity')->andReturn(new Carbon); + + $this->call('GET', '/categories'); + $this->assertResponseOk(); + $this->assertViewHas('categories'); + } + + public function testNoCategory() + { + $collection = new Collection; + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $this->be($journal->user); + $collection->push($journal); + + Amount::shouldReceive('format')->andReturn('xx'); + Amount::shouldReceive('getCurrencyCode')->andReturn('xx'); + + + $repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); + $repository->shouldReceive('getWithoutCategory')->andReturn($repository); + + $this->call('GET', '/categories/list/noCategory'); + $this->assertResponseOk(); + $this->assertViewHas('subTitle'); + + + } + + public function testShow() + { + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $collection = new Collection; + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $this->be($category->user); + $collection->push($journal); + + $repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); + + $repository->shouldReceive('getJournals')->andReturn($collection); + $repository->shouldReceive('countJournals')->andReturn(1); + + Amount::shouldReceive('format')->andReturn('xx'); + Amount::shouldReceive('getCurrencyCode')->andReturn('xx'); + + $this->call('GET', '/categories/show/' . $category->id); + $this->assertResponseOk(); + $this->assertViewHas('hideCategory', true); + + } + + public function testStore() + { + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); + + $repository->shouldReceive('store')->andReturn($category); + $this->be($category->user); + + $this->call('POST', '/categories/store', ['_token' => 'replaceMe', 'name' => 'Bla bla #' . rand(1, 1000)]); + $this->assertResponseStatus(302); + $this->assertSessionHas('success', 'New category "' . $category->name . '" stored!'); + } + + // + public function testStoreAndRedirect() + { + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); + + $repository->shouldReceive('store')->andReturn($category); + $this->be($category->user); + + $this->call('POST', '/categories/store', ['_token' => 'replaceMe', 'create_another' => 1, 'name' => 'Bla bla #' . rand(1, 1000)]); + $this->assertResponseStatus(302); + $this->assertSessionHas('success', 'New category "' . $category->name . '" stored!'); + } + + public function testUpdate() + { + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); + + $repository->shouldReceive('update')->andReturn($category); + $this->be($category->user); + + $this->call('POST', '/categories/update/' . $category->id, ['_token' => 'replaceMe', 'name' => 'Bla bla #' . rand(1, 1000)]); + $this->assertResponseStatus(302); + $this->assertSessionHas('success', 'Category "' . $category->name . '" updated.'); + } + + public function testUpdateAndRedirect() + { + $category = FactoryMuffin::create('FireflyIII\Models\Category'); + $repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); + + $repository->shouldReceive('update')->andReturn($category); + $this->be($category->user); + + $this->call('POST', '/categories/update/' . $category->id, ['_token' => 'replaceMe', 'return_to_edit' => 1, 'name' => 'Bla bla #' . rand(1, 1000)]); + $this->assertResponseStatus(302); + $this->assertSessionHas('success', 'Category "' . $category->name . '" updated.'); + } +} \ No newline at end of file diff --git a/tests/factories/all.php b/tests/factories/all.php index 4caa0bd864..d551718cdb 100644 --- a/tests/factories/all.php +++ b/tests/factories/all.php @@ -76,6 +76,15 @@ FactoryMuffin::define( ] ); +FactoryMuffin::define( + 'FireflyIII\Models\Category', + [ + 'user_id' => 'factory|FireflyIII\User', + 'name' => 'sentence', + 'encrypted' => 1, + ] +); + FactoryMuffin::define( 'FireflyIII\Models\LimitRepetition', [