I was trying to follow this tutorial with the pagination + unit test , it is failing and not sure how to fix it. Can any one help me . thanks in advance
AlbumController.php
<?php
namespace Album\Controller;
use Album\Model\AlbumTable;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;
use Album\Form\AlbumForm;
use Album\Model\Album;
class AlbumController extends AbstractActionController
{
// Add this property:
private $table;
// Add this constructor:
public function __construct(AlbumTable $table)
{
$this->table = $table;
}
public function indexAction()
{
// Grab the paginator from the AlbumTable:
$paginator = $this->table->fetchAll(true);
// Set the current page to what has been passed in query string,
// or to 1 if none is set, or the page is invalid:
$page = (int) $this->params()->fromQuery('page', 1);
$page = ($page < 1) ? 1 : $page;
$paginator->setCurrentPageNumber($page);
// Set the number of items per page to 10:
$paginator->setItemCountPerPage(10);
return new ViewModel(['paginator' => $paginator]);
}
public function addAction()
{
$form = new AlbumForm();
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if (! $request->isPost()) {
return ['form' => $form];
}
$album = new Album();
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if (! $form->isValid()) {
return ['form' => $form];
}
$album->exchangeArray($form->getData());
$this->table->saveAlbum($album);
return $this->redirect()->toRoute('album');
}
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (0 === $id) {
return $this->redirect()->toRoute('album', ['action' => 'add']);
}
// Retrieve the album with the specified id. Doing so raises
// an exception if the album is not found, which should result
// in redirecting to the landing page.
try {
$album = $this->table->getAlbum($id);
} catch (\Exception $e) {
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
$form = new AlbumForm();
$form->bind($album);
$form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
$viewData = ['id' => $id, 'form' => $form];
if (! $request->isPost()) {
return $viewData;
}
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if (! $form->isValid()) {
return $viewData;
}
try {
$this->table->saveAlbum($album);
} catch (\Exception $e) {
}
// Redirect to album list
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
public function deleteAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (! $id) {
return $this->redirect()->toRoute('album');
}
$request = $this->getRequest();
if ($request->isPost()) {
$del = $request->getPost('del', 'No');
if ($del == 'Yes') {
$id = (int) $request->getPost('id');
$this->table->deleteAlbum($id);
}
// Redirect to list of albums
return $this->redirect()->toRoute('album');
}
return [
'id' => $id,
'album' => $this->table->getAlbum($id),
];
}
}
AlbumControllerTest.php
<?php
namespace AlbumTest\Controller;
use Album\Controller\AlbumController;
use Album\Model\Album;
use Album\Model\AlbumTable;
use Laminas\ServiceManager\ServiceManager;
use Laminas\Stdlib\ArrayUtils;
use Laminas\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
class AlbumControllerTest extends AbstractHttpControllerTestCase
{
use ProphecyTrait;
protected $traceError = true;
protected $albumTable;
protected function setUp(): void
{
// The module configuration should still be applicable for tests.
// You can override configuration here with test case specific values,
// such as sample view templates, path stacks, module_listener_options,
// etc.
$configOverrides = [];
$applicationConfigPath = realpath(__DIR__ . '/../../../../config/application.config.php');
$this->setApplicationConfig(ArrayUtils::merge(// Grabbing the full application configuration:
include $applicationConfigPath,
$configOverrides
));
parent::setUp();
$this->configureServiceManager($this->getApplicationServiceLocator());
}
public function testIndexActionCanBeAccessed()
{
$this->albumTable->fetchAll()->willReturn([]);
$this->dispatch('/album');
$this->assertResponseStatusCode(200);
$this->assertModuleName('Album');
$this->assertControllerName(AlbumController::class);
$this->assertControllerClass('AlbumController');
$this->assertMatchedRouteName('album');
}
public function TestIndexActionCanNotBeAccessedDB()
{
$services = $this->getApplicationServiceLocator();
$config = $services->get('config');
unset($config['db']);
$services->setAllowOverride(true);
$services->setService('config', $config);
$services->setAllowOverride(false);
$this->dispatch('/album');
$this->assertResponseStatusCode(200);
$this->assertModuleName('Album');
$this->assertControllerName(AlbumController::class);
$this->assertControllerClass('AlbumController');
$this->assertMatchedRouteName('album');
}
protected function configureServiceManager(ServiceManager $services)
{
$services->setAllowOverride(true);
$services->setService('config', $this->updateConfig($services->get('config')));
$services->setService(AlbumTable::class, $this->mockAlbumTable()->reveal());
$services->setAllowOverride(false);
}
protected function updateConfig($config)
{
$config['db'] = [];
return $config;
}
protected function mockAlbumTable()
{
$this->albumTable = $this->prophesize(AlbumTable::class);
return $this->albumTable;
}
public function testAddActionRedirectsAfterValidPost()
{
$this->albumTable
->saveAlbum(Argument::type(Album::class))
->shouldBeCalled();
$postData = [
'title' => 'Led Zeppelin III',
'artist' => 'Led Zeppelin',
'id' => '',
];
$this->dispatch('/album/add', 'POST', $postData);
$this->assertResponseStatusCode(302);
$this->assertRedirectTo('/album');
}
}
Module.php
<?php
namespace Album;
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Db\ResultSet\ResultSet;
use Laminas\ModuleManager\Feature\ConfigProviderInterface;
use Laminas\Db\TableGateway\TableGateway;
class Module implements ConfigProviderInterface {
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
// Add this method:
public function getServiceConfig() {
return [
'factories' => [
Model\AlbumTable::class => function($container) {
$tableGateway = $container->get(Model\AlbumTableGateway::class);
return new Model\AlbumTable($tableGateway);
},
Model\AlbumTableGateway::class => function($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
],
];
}
public function getControllerConfig() {
return [
'factories' => [
Controller\AlbumController::class => function($container) {
return new Controller\AlbumController($container->get(Model\AlbumTable::class));
},
],
];
}
}
This code is perfectly working fine while I run through the browser and navigate to /album
and all the operation is working perfect like add. edit and delete and pagination as well but it fails for the unit test caese