module/Application/test/Controller/Api/PictureControllerTest.php
<?php
namespace ApplicationTest\Controller\Api;
use Application\Controller\Api\ItemController;
use Application\Controller\Api\PictureController;
use Application\DuplicateFinder;
use Application\Model\CarOfDay;
use Application\Test\AbstractHttpControllerTestCase;
use ApplicationTest\Data;
use Exception;
use Laminas\Http\Header\Location;
use Laminas\Http\PhpEnvironment\Request;
use Laminas\Http\Response;
use Laminas\Json\Json;
use function copy;
use function count;
use function explode;
use function sys_get_temp_dir;
use function tempnam;
use const UPLOAD_ERR_OK;
class PictureControllerTest extends AbstractHttpControllerTestCase
{
protected string $applicationConfigPath = __DIR__ . '/../../../../../config/application.config.php';
private function mockDuplicateFinder(): void
{
$serviceManager = $this->getApplicationServiceLocator();
$tables = $serviceManager->get('TableManager');
$mock = $this->getMockBuilder(DuplicateFinder::class)
->onlyMethods(['indexImage'])
->setConstructorArgs([
$serviceManager->get('RabbitMQ'),
$tables->get('df_distance'),
])
->getMock();
$mock->method('indexImage');
$serviceManager->setService(DuplicateFinder::class, $mock);
}
/**
* @throws Exception
*/
private function addPictureToItem(int $vehicleId): int
{
$this->reset();
$this->mockDuplicateFinder();
/** @var Request $request */
$request = $this->getRequest();
$request->getHeaders()
->addHeader(Data::getAdminAuthHeader(
$this->getApplicationServiceLocator()->get('Config')['keycloak']
))
->addHeaderLine('Content-Type', 'multipart/form-data');
$request->getServer()->set('REMOTE_ADDR', '127.0.0.1');
$file = tempnam(sys_get_temp_dir(), 'upl');
$filename = 'test.jpg';
copy(__DIR__ . '/../../_files/' . $filename, $file);
$request->getFiles()->fromArray([
'file' => [
'tmp_name' => $file,
'name' => $filename,
'error' => UPLOAD_ERR_OK,
'type' => 'image/jpeg',
],
]);
$this->dispatch('https://www.autowp.ru/api/picture', Request::METHOD_POST, [
'item_id' => $vehicleId,
]);
$this->assertResponseStatusCode(201);
$this->assertModuleName('application');
$this->assertControllerName(PictureController::class);
$this->assertMatchedRouteName('api/picture/post');
$this->assertActionName('post');
/** @var Response $response */
$response = $this->getResponse();
/** @var Location $location */
$location = $response->getHeaders()->get('Location');
$uri = $location->uri();
$parts = explode('/', $uri->getPath());
return (int) $parts[count($parts) - 1];
}
/**
* @throws Exception
*/
private function createItem(array $params): int
{
$this->reset();
/** @var Request $request */
$request = $this->getRequest();
$request->getHeaders()->addHeader(Data::getAdminAuthHeader(
$this->getApplicationServiceLocator()->get('Config')['keycloak']
));
$this->dispatch('https://www.autowp.ru/api/item', Request::METHOD_POST, $params);
$this->assertResponseStatusCode(201);
$this->assertModuleName('application');
$this->assertControllerName(ItemController::class);
$this->assertMatchedRouteName('api/item/post');
$this->assertActionName('post');
/** @var Response $response */
$response = $this->getResponse();
/** @var Location $location */
$location = $response->getHeaders()->get('Location');
$uri = $location->uri();
$parts = explode('/', $uri->getPath());
return (int) $parts[count($parts) - 1];
}
/**
* @throws Exception
*/
private function getItemById(int $itemId): array
{
$this->reset();
/** @var Request $request */
$request = $this->getRequest();
$request->getHeaders()->addHeader(Data::getAdminAuthHeader(
$this->getApplicationServiceLocator()->get('Config')['keycloak']
));
$this->dispatch('https://www.autowp.ru/api/item/' . $itemId, Request::METHOD_GET, [
'fields' => 'total_pictures,begin_year,end_year',
]);
$this->assertResponseStatusCode(200);
$this->assertModuleName('application');
$this->assertControllerName(ItemController::class);
$this->assertMatchedRouteName('api/item/item/get');
$this->assertActionName('item');
return Json::decode($this->getResponse()->getContent(), Json::TYPE_ARRAY);
}
/**
* @throws Exception
*/
private function acceptPicture(int $pictureId): void
{
$this->reset();
/** @var Request $request */
$request = $this->getRequest();
$request->getHeaders()->addHeader(Data::getAdminAuthHeader(
$this->getApplicationServiceLocator()->get('Config')['keycloak']
));
$this->dispatch(
'https://www.autowp.ru/api/picture/' . $pictureId,
Request::METHOD_PUT,
['status' => 'accepted']
);
$this->assertResponseStatusCode(200);
$this->assertModuleName('application');
$this->assertControllerName(PictureController::class);
$this->assertMatchedRouteName('api/picture/picture/update');
$this->assertActionName('update');
}
public function testGetList(): void
{
/** @var Request $request */
$request = $this->getRequest();
$request->getHeaders()->addHeader(Data::getAdminAuthHeader(
$this->getApplicationServiceLocator()->get('Config')['keycloak']
));
$this->dispatch('http://www.autowp.ru/api/picture', Request::METHOD_GET, [
'fields' => 'owner,thumb_medium,add_date,exif,image,items.item.name_html,'
. 'items.item.brands.name_html,special_name,copyrights,'
. 'change_status_user,rights,moder_votes,moder_voted,'
. 'is_last,views,accepted_count,similar.picture.thumb_medium,'
. 'replaceable,siblings.name_text,ip.rights,ip.blacklist',
'limit' => 100,
]);
$this->assertResponseStatusCode(200);
$this->assertModuleName('application');
$this->assertControllerName(PictureController::class);
$this->assertMatchedRouteName('api/picture/index');
$this->assertResponseHeaderContains('Content-Type', 'application/json; charset=utf-8');
$json = Json::decode($this->getResponse()->getContent(), Json::TYPE_ARRAY);
$this->assertNotEmpty($json);
}
public function testRandomPicture(): void
{
$this->dispatch('http://www.autowp.ru/api/picture/random-picture', 'GET');
$this->assertResponseStatusCode(200);
$this->assertModuleName('application');
$this->assertControllerName(PictureController::class);
$this->assertMatchedRouteName('api/picture/random_picture');
$this->assertResponseHeaderContains('Content-Type', 'application/json; charset=utf-8');
$json = Json::decode($this->getResponse()->getContent(), Json::TYPE_ARRAY);
$this->assertArrayHasKey('status', $json);
$this->assertTrue($json['status']);
$this->assertArrayHasKey('url', $json);
$this->assertArrayHasKey('name', $json);
$this->assertArrayHasKey('page', $json);
}
public function testNewPicture(): void
{
$this->dispatch('http://www.autowp.ru/api/picture/new-picture', 'GET');
$this->assertResponseStatusCode(200);
$this->assertModuleName('application');
$this->assertControllerName(PictureController::class);
$this->assertMatchedRouteName('api/picture/new-picture');
$this->assertResponseHeaderContains('Content-Type', 'application/json; charset=utf-8');
$json = Json::decode($this->getResponse()->getContent(), Json::TYPE_ARRAY);
$this->assertArrayHasKey('status', $json);
$this->assertTrue($json['status']);
$this->assertArrayHasKey('url', $json);
$this->assertArrayHasKey('name', $json);
$this->assertArrayHasKey('page', $json);
}
public function testCarOfDayPicture(): void
{
$itemOfDay = $this->getApplicationServiceLocator()->get(CarOfDay::class);
$row = $itemOfDay->getCurrent();
$itemId = $row ? $row['item_id'] : null;
if (! $itemId) {
$itemId = $this->createItem([
'item_type_id' => 1,
'name' => 'Peugeot 407 Coupe "Car of the day"',
'begin_year' => 2006,
'end_year' => 2012,
]);
}
$item = $this->getItemById($itemId);
$this->assertArrayHasKey('total_pictures', $item);
for ($i = $item['total_pictures']; $i < 5; $i++) {
$pictureId = $this->addPictureToItem($item['id']);
$this->acceptPicture($pictureId);
}
$this->reset();
$this->dispatch('http://www.autowp.ru/api/picture/car-of-day-picture', 'GET');
$this->assertResponseStatusCode(200);
$this->assertModuleName('application');
$this->assertControllerName(PictureController::class);
$this->assertMatchedRouteName('api/picture/car-of-day-picture');
$this->assertResponseHeaderContains('Content-Type', 'application/json; charset=utf-8');
$json = Json::decode($this->getResponse()->getContent(), Json::TYPE_ARRAY);
$this->assertArrayHasKey('status', $json);
$this->assertTrue($json['status']);
$this->assertArrayHasKey('url', $json);
$this->assertArrayHasKey('name', $json);
$this->assertArrayHasKey('page', $json);
}
}