<?php

namespace PeytzMail\Tests;

use PeytzMail\PeytzMail;
use PeytzMail\Entity\TrackingEvents;

class TrackingEventsTest extends TestCase
{
    protected $mailinglist = 'foo-bar-list';

    public function testWithInvalidSubscriberEvent()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\InvalidArgumentException',
            '[Peytz Mail] Event parameter should be either unsubscribes or subscribes.'
        );

        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->getSubscriberTrackingEvents($this->mailinglist, 'invalid-event');

    }

    public function testWithInvalidSubscriberType()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\InvalidArgumentException',
            '[Peytz Mail] Types parameter should be backend, confirm, frontend, profile, api.'
        );

        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->getSubscriberTrackingEvents($this->mailinglist, 'subscribes', array('foo', 'bar', 'baz'));
    }

    public function testWithInvalidSubscriberSortingType()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\InvalidArgumentException',
            '[Peytz Mail] Sorting parameter should be from_id, period_start and/or period_end.'
        );

        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->getSubscriberTrackingEvents($this->mailinglist, 'subscribes', array(), array('invalid-sorting-type' => 'value'));
    }

    public function testWeGotSubscriberTrackingEvents()
    {
        $json = <<<JSON
{
    "current_page"  : 1,
    "total_records" : 2,
    "total_pages"   : 1,
    "next_page"     : null,
    "unsubscribes"  : [
        {
            "created"       : "2013-10-17T14:47:08+02:00",
            "email"         : "john.smith@example.com",
            "track_id"      : "525fdc4c2ceb65693c00008a",
            "foreign_id"    : "",
            "subscriber_id" : "john-smith-example-com",
            "type"          : "complaint"
        },
        {
            "created"       : "2013-10-17T13:41:58+02:00",
            "email"         : "jane.smith@example.com",
            "track_id"      : "525fdc4c2ceb65693c00008a",
            "foreign_id"    : "",
            "subscriber_id" : "jane-smith-example-com",
            "type"          : "frontend"
        }
    ]
}
JSON;

        $event = 'unsubscribes';

        $peytzMail      = new PeytzMail($this->getMockClientReturns($json));
        $trackingEvents = $peytzMail->getSubscriberTrackingEvents($this->mailinglist, $event, array(), array('from_id' => '524047a20f912c5ca3000001'));

        $this->assertInstanceOf('\\PeytzMail\\Entity\\TrackingEvents', $trackingEvents);
        $this->assertSame(1, $trackingEvents->currentPage);
        $this->assertSame(2, $trackingEvents->totalRecords);
        $this->assertSame(1, $trackingEvents->totalPages);
        $this->assertNull($trackingEvents->nextPage);

        $this->assertTrue(is_array($trackingEvents->$event));
        $this->assertCount($trackingEvents->totalRecords, $trackingEvents->$event);

        $trackingEvent = $trackingEvents->$event;
        $this->assertInstanceOf('\\PeytzMail\\Entity\\TrackingEvent', $trackingEvent = $trackingEvent[0]);
        $this->assertSame('525fdc4c2ceb65693c00008a', $trackingEvent->trackId);
        $this->assertSame('john-smith-example-com', $trackingEvent->subscriberId);
        $this->assertSame('john.smith@example.com', $trackingEvent->email);
        $this->assertEmpty($trackingEvent->foreignId);
        $this->assertInstanceOf('\\DateTime', $trackingEvent->created);
        $this->assertSame('2013-10-17T14:47:08+02:00', $trackingEvent->created->format(DATE_RFC3339));
        $this->assertSame('complaint', $trackingEvent->type);

        $trackingEvent = $trackingEvents->$event;
        $this->assertInstanceOf('\\PeytzMail\\Entity\\TrackingEvent', $trackingEvent = $trackingEvent[1]);
        $this->assertSame('525fdc4c2ceb65693c00008a', $trackingEvent->trackId);
        $this->assertSame('jane-smith-example-com', $trackingEvent->subscriberId);
        $this->assertSame('jane.smith@example.com', $trackingEvent->email);
        $this->assertEmpty($trackingEvent->foreignId);
        $this->assertInstanceOf('\\DateTime', $trackingEvent->created);
        $this->assertSame('2013-10-17T13:41:58+02:00', $trackingEvent->created->format(DATE_RFC3339));
        $this->assertSame('frontend', $trackingEvent->type);

    }

    public function testWithANotExistingSubscriberPage()
    {
        $json = <<<JSON
{
    "subscribes"    : [
    ],
    "current_page"  : 10000,
    "total_records" : 228243,
    "total_pages"   : 457,
    "next_page"     : null
}
JSON;

        $event = 'subscribes';

        $peytzMail      = new PeytzMail($this->getMockClientReturns($json));
        $trackingEvents = $peytzMail->getSubscriberTrackingEvents($this->mailinglist, $event, array(), array(), 10000);

        $this->assertInstanceOf('\\PeytzMail\\Entity\\TrackingEvents', $trackingEvents);
        $this->assertSame(10000, $trackingEvents->currentPage);
        $this->assertSame(228243, $trackingEvents->totalRecords);
        $this->assertSame(457, $trackingEvents->totalPages);
        $this->assertNull($trackingEvents->nextPage);

        $this->assertTrue(is_array($trackingEvents->$event));
        $this->assertEmpty($trackingEvents->$event);
    }

    public function testWithInvalidUserEventEvent()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\InvalidArgumentException',
            '[Peytz Mail] Event parameter should be either clicks or opens.'
        );

        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->getUserEventTrackingEvents($this->mailinglist, 'invalid-event');

    }

    public function testWithInvalidUserEventSortingType()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\InvalidArgumentException',
            '[Peytz Mail] Sorting parameter should be from_id, period_start and/or period_end.'
        );

        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->getUserEventTrackingEvents($this->mailinglist, 'clicks', array(), array('invalid-sorting-type' => 'value'));
    }

    public function testWeGotUserEventTrackingEvents()
    {
        $json = <<<JSON
{
    "current_page"  : 1,
    "total_records" : 2,
    "total_pages"   : 1,
    "next_page"     : null,
    "clicks"        : [
        {
            "created"       : "2013-10-17T14:47:08+02:00",
            "email"         : "john.smith@example.com",
            "track_id"      : "525fdc4c2ceb65693c00008a",
            "foreign_id"    : "",
            "subscriber_id" : "john-smith-example-com",
            "newsletter_id" : "my-newsletter"
        },
        {
            "created"       : "2013-10-17T13:41:58+02:00",
            "email"         : "jane.smith@example.com",
            "track_id"      : "525fdc4c2ceb65693c00008a",
            "foreign_id"    : "",
            "subscriber_id" : "jane-smith-example-com",
            "newsletter_id" : "my-newsletter"
        }
  ]
}
JSON;

        $event = 'clicks';

        $peytzMail      = new PeytzMail($this->getMockClientReturns($json));
        $trackingEvents = $peytzMail->getUserEventTrackingEvents($this->mailinglist, $event, array('my-newsletter'), array('from_id' => '525fdc4c2ceb65693c00008a'));

        $this->assertInstanceOf('\\PeytzMail\\Entity\\TrackingEvents', $trackingEvents);
        $this->assertSame(1, $trackingEvents->currentPage);
        $this->assertSame(2, $trackingEvents->totalRecords);
        $this->assertSame(1, $trackingEvents->totalPages);
        $this->assertNull($trackingEvents->nextPage);

        $this->assertTrue(is_array($trackingEvents->$event));
        $this->assertCount($trackingEvents->totalRecords, $trackingEvents->$event);

        $trackingEvent = $trackingEvents->$event;
        $this->assertInstanceOf('\\PeytzMail\\Entity\\TrackingEvent', $trackingEvent = $trackingEvent[0]);
        $this->assertSame('525fdc4c2ceb65693c00008a', $trackingEvent->trackId);
        $this->assertSame('john-smith-example-com', $trackingEvent->subscriberId);
        $this->assertSame('john.smith@example.com', $trackingEvent->email);
        $this->assertEmpty($trackingEvent->foreignId);
        $this->assertInstanceOf('\\DateTime', $trackingEvent->created);
        $this->assertSame('2013-10-17T14:47:08+02:00', $trackingEvent->created->format(DATE_RFC3339));
        $this->assertSame('my-newsletter', $trackingEvent->newsletterId);

        $trackingEvent = $trackingEvents->$event;
        $this->assertInstanceOf('\\PeytzMail\\Entity\\TrackingEvent', $trackingEvent = $trackingEvent[1]);
        $this->assertSame('525fdc4c2ceb65693c00008a', $trackingEvent->trackId);
        $this->assertSame('jane-smith-example-com', $trackingEvent->subscriberId);
        $this->assertSame('jane.smith@example.com', $trackingEvent->email);
        $this->assertEmpty($trackingEvent->foreignId);
        $this->assertInstanceOf('\\DateTime', $trackingEvent->created);
        $this->assertSame('2013-10-17T13:41:58+02:00', $trackingEvent->created->format(DATE_RFC3339));
        $this->assertSame('my-newsletter', $trackingEvent->newsletterId);
    }

    public function testWithANotExistingUserEventPage()
    {
        $json = <<<JSON
{
    "opens" : [
    ],
    "current_page"  : 10000,
    "total_records" : 52333,
    "total_pages"   : 105,
    "next_page"     : null
}
JSON;

        $event = 'opens';

        $peytzMail      = new PeytzMail($this->getMockClientReturns($json));
        $trackingEvents = $peytzMail->getUserEventTrackingEvents($this->mailinglist, $event, array(), array(), 10000);

        $this->assertInstanceOf('\\PeytzMail\\Entity\\TrackingEvents', $trackingEvents);
        $this->assertSame(10000, $trackingEvents->currentPage);
        $this->assertSame(52333, $trackingEvents->totalRecords);
        $this->assertSame(105, $trackingEvents->totalPages);
        $this->assertNull($trackingEvents->nextPage);

        $this->assertTrue(is_array($trackingEvents->$event));
        $this->assertEmpty($trackingEvents->$event);

    }
}
