<?php

namespace Opentalent\OtCore\Tests\Unit\Domain\Repository;


class EventRepositoryTest extends AbstractApiRepositoryTestCase
{
    const TESTED_CLASS = "Opentalent\OtCore\Domain\Repository\EventRepository";

    /**
     * findById should return an Event object matching the given id
     *
     * @test
     */
    public function findById() {
        $event_id = 2;

        $expected_uri = "api/public/events?_format=json&filter%5Bwhere%5D%5Bid%5D=2&page=1&totalItems=1&itemsPerPage=8";
        $this->injectClientFor($expected_uri);

        $actual = $this->repository->findById($event_id);
        $this->assertEquals($event_id, $actual->getId());
    }

    /**
     * findByOrganizationId should return an ApiPagedCollection object containing
     * the event(s) matching the given organizationId
     *
     * @test
     */
    public function findByOrganizationId() {
        $organization_id = 1;

        $expected_uri = "api/public/events?_format=json&organizationId=1&page=1&filter%5Border%5D%5B0%5D%5BdatetimeStart%5D=ASC&itemsPerPage=8";
        $this->injectClientFor($expected_uri);

        $actual = $this->repository->findByOrganizationId($organization_id);
        $this->assertEquals($organization_id, $actual->getMembers()[0]->getOrganizationId());
    }

    /**
     * findByOrganizationId should return an ApiPagedCollection object containing
     * the event(s) matching the given organizationId
     *
     * @test
     */
    public function findByOrganizationIdWithParams() {
        $organization_id = 1;

        $expected_uri = "api/public/events?_format=json&organizationId=1&page=1&itemsPerPage=1&filter%5Bwhere%5D%5BdatetimeEnd%5D%5Bgte%5D=2021-01-01T00%3A00%3A00%2B00%3A00&filter%5Bwhere%5D%5BdatetimeEnd%5D%5Blte%5D=2021-01-31T00%3A00%3A00%2B00%3A00&filter%5Border%5D%5B0%5D%5BdatetimeStart%5D=ASC";
        $this->injectClientFor($expected_uri);

        $actual = $this->repository->findByOrganizationId(
            $organization_id,
            new \DateTime('2021-01-01'),
            new \DateTime('2021-01-31'),
            $limit=1,
            $page=1
        );
        $this->assertEquals($organization_id, $actual->getMembers()[0]->getOrganizationId());
    }

    /**
     * findParentsByOrganizationId should return an ApiPagedCollection object containing
     * the event(s) of the parent of the given organization
     *
     * @test
     */
    public function findParentsByOrganizationId() {
        $organization_id = 1;

        $expected_uri = "api/public/events?_format=json&organizationId=1&page=1&filter%5Border%5D%5B0%5D%5BdatetimeStart%5D=ASC&parent=1&itemsPerPage=8";
        $this->injectClientFor($expected_uri);

        $actual = $this->repository->findParentsByOrganizationId($organization_id);
        $this->assertEquals($organization_id, $actual->getMembers()[0]->getOrganizationId());
    }

    /**
     * findParentsByOrganizationId should return an ApiPagedCollection object containing
     * the event(s) of the parent of the given organization
     *
     * @test
     */
    public function findParentsByOrganizationIdWithParams() {
        $organization_id = 1;

        $expected_uri = "api/public/events?_format=json&organizationId=1&page=1&itemsPerPage=1&filter%5Bwhere%5D%5BdatetimeEnd%5D%5Bgte%5D=2021-01-01T00%3A00%3A00%2B00%3A00&filter%5Bwhere%5D%5BdatetimeEnd%5D%5Blte%5D=2021-01-31T00%3A00%3A00%2B00%3A00&filter%5Border%5D%5B0%5D%5BdatetimeStart%5D=ASC&parent=1";
        $this->injectClientFor($expected_uri);

        $actual = $this->repository->findParentsByOrganizationId(
            $organization_id,
            new \DateTime('2021-01-01'),
            new \DateTime('2021-01-31'),
            $limit=1,
            $page=1
        );
        $this->assertEquals($organization_id, $actual->getMembers()[0]->getOrganizationId());
    }

    /**
     * findParentsByOrganizationId should return an ApiPagedCollection object containing
     * the event(s) of the parent of the given organization
     *
     * @test
     */
    public function findChildrenByOrganizationId() {
        $organization_id = 1;

        $expected_uri = "api/public/events?_format=json&organizationId=1&filter%5Border%5D%5B0%5D%5BdatetimeStart%5D=ASC&children=1&itemsPerPage=8";
        $this->injectClientFor($expected_uri);

        $actual = $this->repository->findChildrenByOrganizationId($organization_id);
        $this->assertEquals($organization_id, $actual->getMembers()[0]->getOrganizationId());
    }

    /**
     * findParentsByOrganizationId should return an ApiPagedCollection object containing
     * the event(s) of the parent of the given organization
     *
     * @test
     */
    public function findChildrenByOrganizationIdWithParams() {
        $organization_id = 1;

        $expected_uri = "api/public/events?_format=json&organizationId=1&itemsPerPage=1&filter%5Bwhere%5D%5BdatetimeEnd%5D%5Bgte%5D=2021-01-01T00%3A00%3A00%2B00%3A00&filter%5Bwhere%5D%5BdatetimeEnd%5D%5Blte%5D=2021-01-31T00%3A00%3A00%2B00%3A00&filter%5Border%5D%5B0%5D%5BdatetimeStart%5D=ASC&children=1";
        $this->injectClientFor($expected_uri);

        $actual = $this->repository->findChildrenByOrganizationId(
            $organization_id,
            new \DateTime('2021-01-01'),
            new \DateTime('2021-01-31'),
            $limit=1,
            $page=1
        );
        $this->assertEquals($organization_id, $actual->getMembers()[0]->getOrganizationId());
    }

    /**
     * searchBy should return an ApiPagedCollection object containing
     * the event(s) matching the criteria
     *
     * @test
     */
    public function searchBy() {
        $organization_id = 1;

        $expected_uri = "api/public/events?_format=json&organizationId=1&filter%5Border%5D%5B0%5D%5BdatetimeStart%5D=ASC&filter%5Bwhere%5D%5Bid%5D=1&itemsPerPage=8";
        $this->injectClientFor($expected_uri);

        $actual = $this->repository->searchBy($organization_id, ['filter[where][id]' => 1]);
        $this->assertEquals($organization_id, $actual->getMembers()[0]->getOrganizationId());
    }

    /**
     * memberToObject should return null if the given
     * member has not the good type
     *
     * @test
     */
    public function memberToObjectError() {
        $this->assertEquals(
            null,
            $this->callMemberToObject(['@type' => 'Invalid'])
        );
    }

}
