Skip to content
Snippets Groups Projects
QuestsTest.php 8.67 KiB
Newer Older
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
<?php

namespace App\Tests;

use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use App\DataFixtures\GenreFixture;
use App\DataFixtures\QuestFixture;
use App\DataFixtures\TagsFixture;
use App\DataFixtures\ThemesFixture;
use App\DataFixtures\UserFixture;
use App\Repository\AppointmentRepository;
use App\Repository\FavoriteRepository;
use App\Repository\ReviewRepository;
use Liip\TestFixturesBundle\Services\DatabaseToolCollection;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

class QuestsTest extends ApiTestCase
{
    private static ?string $token = null;
    private static int $questId = 1;

    /**
     * @throws TransportExceptionInterface
     * @throws ServerExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws ClientExceptionInterface
     */
    protected function setUp(): void
    {
        $this->loadFixtures();

        $this->login();
    }

    /**
     * Тестирование избранного
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    public function testFavorite(): void
    {
        $this->testFavoriteAdd();
        $this->testFavoriteRemove();
    }

    /**
     * Добавление квеста в избранное
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    private function testFavoriteAdd(): void
    {
        $request = [
            'id' => self::$questId,
        ];

        $this->request('/api/quest/favorite/add', $request);

        /** @var FavoriteRepository $favoriteRepository */
        $favoriteRepository = static::getContainer()->get(FavoriteRepository::class);
        if ($favorite = $favoriteRepository->find(1)) {
            $quest = $favorite->getQuest();
            $user = $favorite->getRelatedUser();
            if ($quest && $user) {
                if ($quest->getId() !== self::$questId || $user->getId() !== 1) {
                    self::fail('Не добавлено в избранное');
                }
            } else {
                self::fail('Не добавлено в избранное');
            }
        } else {
            self::fail('Не добавлено в избранное');
        }
    }

    /**
     * Удаление квеста из избранного
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    private function testFavoriteRemove(): void
    {
        $request = [
            'id' => self::$questId,
        ];

        $this->request('/api/quest/favorite/remove', $request);

        /** @var FavoriteRepository $favoriteRepository */
        $favoriteRepository = static::getContainer()->get(FavoriteRepository::class);
        if ($favoriteRepository->find(1)) {
            self::fail('Не удалено из избранного');
        }
    }

    /**
     * Тестирование записи на квест
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    public function testSubscribe(): void
    {
        $this->testQuestSubscribe();
        $this->testQuestUnsubscribe();
    }

    /**
     * Запись на квест
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    private function testQuestSubscribe(): void
    {
        $request = [
            'id' => self::$questId,
        ];

        $this->request('/api/quest/subscribe', $request);

        /** @var AppointmentRepository $appointmentRepository */
        $appointmentRepository = static::getContainer()->get(AppointmentRepository::class);
        if (!$appointmentRepository->find(1)) {
            self::fail('Запись на квест не добавлена');
        }
    }

    /**
     * Отмена записи на квест
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    private function testQuestUnsubscribe(): void
    {
        $request = [
            'id' => self::$questId,
        ];

        $this->request('/api/quest/unsubscribe', $request);
        /** @var AppointmentRepository $appointmentRepository */
        $appointmentRepository = static::getContainer()->get(AppointmentRepository::class);
        if ($appointmentRepository->find(1)) {
            self::fail('Запись на квест не отменена');
        }
    }

    /**
     * Тестирование отзывов
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    public function testReview(): void
    {
        $this->testReviewAdd();
        $this->testReviewUpdate();
        $this->testReviewRemove();
    }

    /**
     * Добавление отзыва на квест
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    private function testReviewAdd(): void
    {
        $request = [
            'text' => 'Отзыв на квест',
            'quest_id' => self::$questId,
            'rating' => rand(1, 10),
        ];

        $this->request('/api/quest/review/create', $request);

        /** @var ReviewRepository $reviewRepository */
        $reviewRepository = static::getContainer()->get(ReviewRepository::class);
        if (!$reviewRepository->find(1)) {
            self::fail('Отзыв не добавлен');
        }
    }

    /**
     * Обновление отзыва квеста
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    private function testReviewUpdate(): void
    {
        $request = [
            'text' => 'Обновленный отзыв на квест',
            'review_id' => 1,
            'rating' => rand(1, 10),
        ];

        $this->request('/api/quest/review/update', $request);
        /** @var ReviewRepository $reviewRepository */
        $reviewRepository = static::getContainer()->get(ReviewRepository::class);
        if ($review = $reviewRepository->find(1)) {
            if ($review->getText() !== $request['text']) {
                self::fail('Отзыв не изменен');
            }
        }
    }

    /**
     * Удаление отзыва квеста
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    private function testReviewRemove(): void
    {
        $request = [
            'id' => 1
        ];

        $this->request('/api/quest/review/delete', $request);

        /** @var ReviewRepository $reviewRepository */
        $reviewRepository = static::getContainer()->get(ReviewRepository::class);
        if ($reviewRepository->find(1)) {
            self::fail('Отзыв не удален');
        }
    }

    /**
     * Получение токена
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     * @throws ClientExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     */
    private function login(): void
    {
        $response = static::createClient()->request('POST', '/api/login', [
            'headers' => ['Content-Type' => 'application/json'],
            'json' => [
                'email' => UserFixture::EMAIL,
                'password' => UserFixture::PASSWORD,
            ],
        ]);

        self::assertResponseStatusCodeSame(200);

        self::assertArrayHasKey('token', $response->toArray()['data']);

        self::$token = $response->toArray()['data']['token'];

        self::assertResponseIsSuccessful();
    }

    private function loadFixtures(): void
    {
        $databaseTool = static::getContainer()->get(DatabaseToolCollection::class)->get();

        $databaseTool->loadFixtures([
            UserFixture::class,
            GenreFixture::class,
            ThemesFixture::class,
            TagsFixture::class,
            QuestFixture::class,
        ]);
    }

    /**
     * Запрос
     *
     * @param string $url
     * @param array $request
     *
     * @return void
     *
     * @throws TransportExceptionInterface
     */
    private function request(string $url, array $request): void
    {
        static::createClient()->request('POST', $url, [
            'headers' => [
                'Content-Type' => 'application/json',
                'Authorization' => 'Bearer ' . self::$token
            ],
            'json' => $request
        ]);

        self::assertResponseStatusCodeSame(200);

        self::assertResponseIsSuccessful();
    }
}