<commit_before><?php

namespace CultuurNet\UDB3\ReadModel\Index;

use Broadway\Domain\DateTime;
use Broadway\Domain\DomainMessage;
use Broadway\Domain\Metadata;
use CultuurNet\UDB3\Cdb\CreatedByToUserIdResolverInterface;
use CultuurNet\UDB3\Event\Events\EventDeleted;
use CultuurNet\UDB3\Event\Events\EventImportedFromUDB2;
use CultuurNet\UDB3\Event\Events\EventProjectedToJSONLD;
use CultuurNet\UDB3\Offer\IriOfferIdentifier;
use CultuurNet\UDB3\Offer\IriOfferIdentifierFactoryInterface;
use CultuurNet\UDB3\Offer\OfferType;
use CultuurNet\UDB3\Organizer\Events\OrganizerImportedFromUDB2;
use CultuurNet\UDB3\Place\Events\PlaceDeleted;
use CultuurNet\UDB3\Place\Events\PlaceImportedFromUDB2;
use CultuurNet\UDB3\Place\Events\PlaceImportedFromUDB2Event;
use CultuurNet\UDB3\Place\Events\PlaceProjectedToJSONLD;
use Guzzle\Common\Event;
use ValueObjects\Web\Domain;
use ValueObjects\Web\Url;

class ProjectorTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var RepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    private $repository;

    /**
     * @var CreatedByToUserIdResolverInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    private $userIdResolver;

    /**
     * @var Projector
     */
    private $projector;

    /**
     * @var IriOfferIdentifierFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    private $iriOfferIdentifierFactory;

    const DATETIME = '2015-08-07T12:01:00.034024+00:00';

    public function setUp()
    {
        $this->repository = $this->getMock(RepositoryInterface::class);
        $this->userIdResolver = $this->getMock(CreatedByToUserIdResolverInterface::class);
        $this->iriOfferIdentifierFactory = $this->getMock(IriOfferIdentifierFactoryInterface::class);

        $this->projector = new Projector(
            $this->repository,
            $this->userIdResolver,
            Domain::specifyType('omd.be'),
            Domain::specifyType('udb.be'),
            $this->iriOfferIdentifierFactory
        );
    }

    /**
     * @test
     */
    public function it_updates_the_index_with_events_imported_from_udb2()
    {
        $this->userIdResolver->expects($this->once())
            ->method('resolveCreatedByToUserId')
            ->willReturn('user-id-one-two-three');

        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                '123-456',
                EntityType::EVENT(),
                'user-id-one-two-three',
                'GALLERY TRAEGHE exhibition Janine de Coninck \'BLACK AND WHITE\' 1 - 9 November 2014',
                '8000',
                Domain::specifyType('udb.be'),
                new \DateTime(
                    '2014-09-08T09:10:16',
                    new \DateTimeZone('Europe/Brussels')
                )
            );

        $this->projector->handle(
            $this->domainMessage(
                new EventImportedFromUDB2(
                    '123-456',
                    file_get_contents(__DIR__ . '/event.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.2/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_should_update_the_index_when_importing_a_place_from_udb2_event()
    {
        $this->userIdResolver->expects($this->once())
            ->method('resolveCreatedByToUserId')
            ->willReturn('user-id-one-two-three');

        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                'place-lace-ace-ce',
                EntityType::PLACE(),
                'user-id-one-two-three',
                'stuuuk',
                '3000',
                Domain::specifyType('udb.be'),
                new \DateTime(
                    '2016-02-19T10:36:26+0100',
                    new \DateTimeZone('Europe/Brussels')
                )
            );

        $this->projector->handle(
            $this->domainMessage(
                new PlaceImportedFromUDB2Event(
                    'place-lace-ace-ce',
                    file_get_contents(__DIR__ . '/place.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.3/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_ignores_events_imported_from_udb2_without_a_title()
    {
        $this->repository->expects($this->never())
            ->method('updateIndex');

        $this->projector->handle(
            $this->domainMessage(
                new EventImportedFromUDB2(
                    '123-456',
                    file_get_contents(__DIR__ . '/event-with-empty-title.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.2/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_should_add_an_indexed_item_when_importing_a_place_from_udb2()
    {
        $this->userIdResolver->expects($this->once())
            ->method('resolveCreatedByToUserId')
            ->willReturn('user-id-one-two-three');

        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                'place-lace-ace-ce',
                EntityType::PLACE(),
                'user-id-one-two-three',
                'CC Palethe',
                '3900',
                Domain::specifyType('udb.be'),
                new \DateTime(
                    '2010-01-06T13:33:06+0100',
                    new \DateTimeZone('Europe/Brussels')
                )
            );

        $this->projector->handle(
            $this->domainMessage(
                new PlaceImportedFromUDB2(
                    'place-lace-ace-ce',
                    file_get_contents(__DIR__ . '/udb2_place.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.2/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_should_add_an_indexed_item_when_importing_an_organizer_from_udb2()
    {
        $this->userIdResolver->expects($this->once())
            ->method('resolveCreatedByToUserId')
            ->willReturn('user-id-one-two-three');

        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                'some-orga-nizer-id',
                EntityType::ORGANIZER(),
                'user-id-one-two-three',
                'DE Studio',
                '',
                Domain::specifyType('udb.be'),
                new \DateTime(
                    '2010-01-06T13:46:00+0100',
                    new \DateTimeZone('Europe/Brussels')
                )
            );

        $this->projector->handle(
            $this->domainMessage(
                new OrganizerImportedFromUDB2(
                    'some-orga-nizer-id',
                    file_get_contents(__DIR__ . '/udb2_organizer.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.2/FINAL'
                )
            )
        );
    }

    /**
     * @test
     * @dataProvider indexUpdateEventsDataProvider
     */
    public function it_should_set_the_update_date_when_indexed_items_change(
        DomainMessage $domainMessage,
        $itemId
    ) {
        $this->iriOfferIdentifierFactory
            ->method('fromIri')
            ->willReturn(new IriOfferIdentifier(
                Url::fromNative('http://du.de/1'),
                $itemId,
                OfferType::EVENT()
            ));

        $this->repository->expects($this->once())
            ->method('setUpdateDate')
            ->with($itemId, new \DateTime(self::DATETIME));

        $this->projector->handle($domainMessage);
    }

    public function indexUpdateEventsDataProvider()
    {
        return array(
            array(
                $this->domainMessage(
                    new PlaceProjectedToJSONLD(
                        'http://du.de/place/6ecf5da4-220d-4486-9327-17c7ec8fa070'
                    )
                ),
                '6ecf5da4-220d-4486-9327-17c7ec8fa070'
            ),
            array(
                $this->domainMessage(
                    new EventProjectedToJSONLD(
                        'http://du.de/event/6ecf5da4-220d-4486-9327-17c7ec8fa070'
                    )
                ),
                '6ecf5da4-220d-4486-9327-17c7ec8fa070'
            ),
        );
    }

    /**
     * @test
     */
    public function it_should_remove_the_index_of_deleted_events()
    {
        $this->repository->expects($this->once())
            ->method('deleteIndex')
            ->with('6ecf5da4-220d-4486-9327-17c7ec8fa070');

        $this->projector->handle(
            $this->domainMessage(
                new EventDeleted('6ecf5da4-220d-4486-9327-17c7ec8fa070')
            )
        );
    }

    /**
     * @test
     */
    public function it_should_remove_the_index_of_deleted_places()
    {
        $this->repository->expects($this->once())
            ->method('deleteIndex')
            ->with('6ecf5da4-220d-4486-9327-17c7ec8fa070');

        $this->projector->handle(
            $this->domainMessage(
                new PlaceDeleted('6ecf5da4-220d-4486-9327-17c7ec8fa070')
            )
        );
    }

    /**
     * @param mixed $payload
     * @return DomainMessage
     */
    private function domainMessage($payload)
    {
        return new DomainMessage(
            '123',
            1,
            new Metadata(),
            $payload,
            DateTime::fromString(self::DATETIME)
        );
    }
}<commit_msg>III-1325: Test if an index is projected when offers are created<commit_after><?php

namespace CultuurNet\UDB3\ReadModel\Index;

use Broadway\Domain\DateTime;
use Broadway\Domain\DomainMessage;
use Broadway\Domain\Metadata;
use CultuurNet\UDB3\Address\Address;
use CultuurNet\UDB3\Address\Locality;
use CultuurNet\UDB3\Address\PostalCode;
use CultuurNet\UDB3\Address\Street;
use CultuurNet\UDB3\Calendar;
use CultuurNet\UDB3\Cdb\CreatedByToUserIdResolverInterface;
use CultuurNet\UDB3\Event\Events\EventCreated;
use CultuurNet\UDB3\Event\Events\EventDeleted;
use CultuurNet\UDB3\Event\Events\EventImportedFromUDB2;
use CultuurNet\UDB3\Event\Events\EventProjectedToJSONLD;
use CultuurNet\UDB3\Event\EventType;
use CultuurNet\UDB3\Location\Location;
use CultuurNet\UDB3\Offer\IriOfferIdentifier;
use CultuurNet\UDB3\Offer\IriOfferIdentifierFactoryInterface;
use CultuurNet\UDB3\Offer\OfferType;
use CultuurNet\UDB3\Organizer\Events\OrganizerImportedFromUDB2;
use CultuurNet\UDB3\Place\Events\PlaceCreated;
use CultuurNet\UDB3\Place\Events\PlaceDeleted;
use CultuurNet\UDB3\Place\Events\PlaceImportedFromUDB2;
use CultuurNet\UDB3\Place\Events\PlaceImportedFromUDB2Event;
use CultuurNet\UDB3\Place\Events\PlaceProjectedToJSONLD;
use CultuurNet\UDB3\Theme;
use CultuurNet\UDB3\Title;
use ValueObjects\Geography\Country;
use ValueObjects\Web\Domain;
use ValueObjects\Web\Url;
use ValueObjects\String\String as StringLiteral;

class ProjectorTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var RepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    private $repository;

    /**
     * @var CreatedByToUserIdResolverInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    private $userIdResolver;

    /**
     * @var Projector
     */
    private $projector;

    /**
     * @var IriOfferIdentifierFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    private $iriOfferIdentifierFactory;

    const DATETIME = '2015-08-07T12:01:00.034024+00:00';

    public function setUp()
    {
        $this->repository = $this->getMock(RepositoryInterface::class);
        $this->userIdResolver = $this->getMock(CreatedByToUserIdResolverInterface::class);
        $this->iriOfferIdentifierFactory = $this->getMock(IriOfferIdentifierFactoryInterface::class);

        $this->projector = new Projector(
            $this->repository,
            $this->userIdResolver,
            Domain::specifyType('omd.be'),
            Domain::specifyType('udb.be'),
            $this->iriOfferIdentifierFactory
        );
    }

    /**
     * @test
     */
    public function it_updates_the_index_with_events_imported_from_udb2()
    {
        $this->userIdResolver->expects($this->once())
            ->method('resolveCreatedByToUserId')
            ->willReturn('user-id-one-two-three');

        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                '123-456',
                EntityType::EVENT(),
                'user-id-one-two-three',
                'GALLERY TRAEGHE exhibition Janine de Coninck \'BLACK AND WHITE\' 1 - 9 November 2014',
                '8000',
                Domain::specifyType('udb.be'),
                new \DateTime(
                    '2014-09-08T09:10:16',
                    new \DateTimeZone('Europe/Brussels')
                )
            );

        $this->projector->handle(
            $this->domainMessage(
                new EventImportedFromUDB2(
                    '123-456',
                    file_get_contents(__DIR__ . '/event.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.2/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_should_update_the_index_when_importing_a_place_from_udb2_event()
    {
        $this->userIdResolver->expects($this->once())
            ->method('resolveCreatedByToUserId')
            ->willReturn('user-id-one-two-three');

        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                'place-lace-ace-ce',
                EntityType::PLACE(),
                'user-id-one-two-three',
                'stuuuk',
                '3000',
                Domain::specifyType('udb.be'),
                new \DateTime(
                    '2016-02-19T10:36:26+0100',
                    new \DateTimeZone('Europe/Brussels')
                )
            );

        $this->projector->handle(
            $this->domainMessage(
                new PlaceImportedFromUDB2Event(
                    'place-lace-ace-ce',
                    file_get_contents(__DIR__ . '/place.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.3/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_ignores_events_imported_from_udb2_without_a_title()
    {
        $this->repository->expects($this->never())
            ->method('updateIndex');

        $this->projector->handle(
            $this->domainMessage(
                new EventImportedFromUDB2(
                    '123-456',
                    file_get_contents(__DIR__ . '/event-with-empty-title.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.2/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_should_add_an_indexed_item_when_importing_a_place_from_udb2()
    {
        $this->userIdResolver->expects($this->once())
            ->method('resolveCreatedByToUserId')
            ->willReturn('user-id-one-two-three');

        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                'place-lace-ace-ce',
                EntityType::PLACE(),
                'user-id-one-two-three',
                '<NAME>',
                '3900',
                Domain::specifyType('udb.be'),
                new \DateTime(
                    '2010-01-06T13:33:06+0100',
                    new \DateTimeZone('Europe/Brussels')
                )
            );

        $this->projector->handle(
            $this->domainMessage(
                new PlaceImportedFromUDB2(
                    'place-lace-ace-ce',
                    file_get_contents(__DIR__ . '/udb2_place.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.2/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_should_add_an_indexed_item_when_importing_an_organizer_from_udb2()
    {
        $this->userIdResolver->expects($this->once())
            ->method('resolveCreatedByToUserId')
            ->willReturn('user-id-one-two-three');

        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                'some-orga-nizer-id',
                EntityType::ORGANIZER(),
                'user-id-one-two-three',
                'DE Studio',
                '',
                Domain::specifyType('udb.be'),
                new \DateTime(
                    '2010-01-06T13:46:00+0100',
                    new \DateTimeZone('Europe/Brussels')
                )
            );

        $this->projector->handle(
            $this->domainMessage(
                new OrganizerImportedFromUDB2(
                    'some-orga-nizer-id',
                    file_get_contents(__DIR__ . '/udb2_organizer.xml'),
                    'http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.2/FINAL'
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_should_add_an_indexed_item_when_an_event_is_created()
    {
        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                'f2b227c5-4756-49f6-a25d-8286b6a2351f',
                EntityType::EVENT(),
                '1adf21b4-711d-4e33-b9ef-c96843582a56',
                'Algorave',
                '9630',
                Domain::specifyType('omd.be'),
                $this->anything()
            );

        $this->projector->handle(
            $this->domainMessage(
                new EventCreated(
                    'f2b227c5-4756-49f6-a25d-8286b6a2351f',
                    new Title('Algorave'),
                    new EventType('0.50.4.0.0', 'concert'),
                    new Location(
                        '335be568-aaf0-4147-80b6-9267daafe23b',
                        new StringLiteral('Repeteerkot'),
                        new Address(
                            new Street('Kerkstraat 69'),
                            new PostalCode('9630'),
                            new Locality('Zottegem'),
                            Country::fromNative('BE')
                        )
                    ),
                    new Calendar(
                        'permanent'
                    ),
                    new Theme('themeid', 'theme_label')
                )
            )
        );
    }

    /**
     * @test
     */
    public function it_should_add_an_indexed_item_when_a_place_is_created()
    {
        $this->repository->expects($this->once())
            ->method('updateIndex')
            ->with(
                'f2b227c5-4756-49f6-a25d-8286b6a2351f',
                EntityType::PLACE(),
                '1adf21b4-711d-4e33-b9ef-c96843582a56',
                'Algorave',
                '9630',
                Domain::specifyType('omd.be'),
                $this->anything()
            );

        $this->projector->handle(
            $this->domainMessage(
                new PlaceCreated(
                    'f2b227c5-4756-49f6-a25d-8286b6a2351f',
                    new Title('Algorave'),
                    new EventType('0.50.4.0.0', 'concert'),
                    new Address(
                        new Street('Kerkstraat 69'),
                        new PostalCode('9630'),
                        new Locality('Zottegem'),
                        Country::fromNative('BE')
                    ),
                    new Calendar(
                        'permanent'
                    ),
                    new Theme('themeid', 'theme_label')
                )
            )
        );
    }

    /**
     * @test
     * @dataProvider indexUpdateEventsDataProvider
     */
    public function it_should_set_the_update_date_when_indexed_items_change(
        DomainMessage $domainMessage,
        $itemId
    ) {
        $this->iriOfferIdentifierFactory
            ->method('fromIri')
            ->willReturn(new IriOfferIdentifier(
                Url::fromNative('http://du.de/1'),
                $itemId,
                OfferType::EVENT()
            ));

        $this->repository->expects($this->once())
            ->method('setUpdateDate')
            ->with($itemId, new \DateTime(self::DATETIME));

        $this->projector->handle($domainMessage);
    }

    public function indexUpdateEventsDataProvider()
    {
        return array(
            array(
                $this->domainMessage(
                    new PlaceProjectedToJSONLD(
                        'http://du.de/place/6ecf5da4-220d-4486-9327-17c7ec8fa070'
                    )
                ),
                '6ecf5da4-220d-4486-9327-17c7ec8fa070'
            ),
            array(
                $this->domainMessage(
                    new EventProjectedToJSONLD(
                        'http://du.de/event/6ecf5da4-220d-4486-9327-17c7ec8fa070'
                    )
                ),
                '6ecf5da4-220d-4486-9327-17c7ec8fa070'
            ),
        );
    }

    /**
     * @test
     */
    public function it_should_remove_the_index_of_deleted_events()
    {
        $this->repository->expects($this->once())
            ->method('deleteIndex')
            ->with('6ecf5da4-220d-4486-9327-17c7ec8fa070');

        $this->projector->handle(
            $this->domainMessage(
                new EventDeleted('6ecf5da4-220d-4486-9327-17c7ec8fa070')
            )
        );
    }

    /**
     * @test
     */
    public function it_should_remove_the_index_of_deleted_places()
    {
        $this->repository->expects($this->once())
            ->method('deleteIndex')
            ->with('6ecf5da4-220d-4486-9327-17c7ec8fa070');

        $this->projector->handle(
            $this->domainMessage(
                new PlaceDeleted('6ecf5da4-220d-4486-9327-17c7ec8fa070')
            )
        );
    }

    /**
     * @param mixed $payload
     * @return DomainMessage
     */
    private function domainMessage($payload)
    {
        return new DomainMessage(
            '123',
            1,
            new Metadata([
                'user_id' => '1adf21b4-711d-4e33-b9ef-c96843582a56'
            ]),
            $payload,
            DateTime::fromString(self::DATETIME)
        );
    }
}
{'fraction_non_alphanumeric': 0.12357304668413806, 'fraction_numerical': 0.040065739794785234, 'mean_word_length': 1.5910921855219242, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 217, 'https://': 0, 'lorem ipsum': 0, 'www.': 10, 'xml': 10}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5655094', 'n_tokens_mistral': 7371, 'n_tokens_neox': 6679, 'n_words': 722}