Completed
Pull Request — master (#19)
by Tim
03:07
created

getTrueRandomTestCampaignCollection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\BannerServer\Tests\Unit\Controller;
6
7
use Symfony\Component\Asset\Packages;
8
use Symfony\Component\HttpFoundation\RedirectResponse;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use WMDE\BannerServer\Controller\BannerSelectionController;
12
use WMDE\BannerServer\Entity\BannerSelection\Banner;
13
use WMDE\BannerServer\Entity\BannerSelection\Bucket;
14
use WMDE\BannerServer\Entity\BannerSelection\Campaign;
15
use WMDE\BannerServer\Entity\BannerSelection\CampaignCollection;
16
use WMDE\BannerServer\Entity\BannerSelection\ImpressionThreshold;
17
use WMDE\BannerServer\UseCase\BannerSelection\BannerSelectionUseCase;
18
use WMDE\BannerServer\UseCase\BannerSelection\Visitor;
19
use WMDE\BannerServer\Utils\RandomInteger;
20
21
class BannerSelectionControllerTest extends \PHPUnit\Framework\TestCase {
22
23
	private const VISITOR_TEST_IMPRESSION_COUNT = 5;
24
	private const VISITOR_TEST_BUCKET = 'test_bucket';
25
	private const VISITOR_TEST_DONATION_HISTORY = false;
26
27
	private function getTestbucket(): Bucket {
28
		return new Bucket(
29
			'test',
30
			new Banner( 'TestMain' )
31
		);
32
	}
33
34
	private function getTrueRandomTestCampaign(): Campaign {
35
		return new Campaign(
36
			'C18_WMDE_Test',
37
			new \DateTime( '2000-01-01 00:00:00' ),
38
			new \DateTime( '2099-12-31 23:59:59' ),
39
			1,
40
			new RandomInteger(),
41
			$this->getTestbucket()
42
		);
43
	}
44
45
	private function getTrueRandomTestCampaignCollection(): CampaignCollection {
46
		return new CampaignCollection(
47
			$this->getTrueRandomTestCampaign()
48
		);
49
	}
50
51
	private function getTestRequest(): Request {
52
		return new Request(
53
			[],
54
			[],
55
			[],
56
			[
57
				BannerSelectionController::IMPRESSION_COUNT_COOKIE => self::VISITOR_TEST_IMPRESSION_COUNT,
58
				BannerSelectionController::BUCKET_COOKIE => self::VISITOR_TEST_BUCKET,
59
				BannerSelectionController::DONATED_COOKIE => self::VISITOR_TEST_DONATION_HISTORY ]
60
		);
61
	}
62
63
	private function getTestVisitor(): Visitor {
64
		return new Visitor(
65
			self::VISITOR_TEST_IMPRESSION_COUNT,
66
			self::VISITOR_TEST_BUCKET,
67
			self::VISITOR_TEST_DONATION_HISTORY
68
		);
69
	}
70
71
	private function getFirstTimeVisitor(): Visitor {
72
		return new Visitor(
73
			0,
74
			null,
75
			false
76
		);
77
	}
78
79
	private function getMockAssets(): Packages {
80
		$mockAssets = $this->createMock( Packages::class );
81
		$mockAssets->method( 'getUrl' )->willReturnArgument( 0 );
82
		return $mockAssets;
83
	}
84
85
	public function test_given_controller_receives_cookies_values_are_passed_onto_use_case() {
86
		$mockUseCase = $this->createMock( BannerSelectionUseCase::class );
87
		$mockUseCase->expects( $this->once() )->method( 'provideBannerRequest' )->with( $this->getTestVisitor() );
88
		$controller = new BannerSelectionController( $mockUseCase, $this->getMockAssets() );
89
		$controller->selectBanner( $this->getTestRequest() );
90
	}
91
92
	public function test_given_no_cookies_passed_through_request_controller_assigns_default_values() {
93
		$mockUseCase = $this->createMock( BannerSelectionUseCase::class );
94
		$mockUseCase->expects( $this->once() )->method( 'provideBannerRequest' )->with( $this->getFirstTimeVisitor() );
95
		$controller = new BannerSelectionController( $mockUseCase, $this->getMockAssets() );
96
		$controller->selectBanner( new Request() );
97
	}
98
99
	public function test_given_no_cookies_passed_through_request_controller_creates_cookies_with_updated_default_values() {
100
		$testUseCase = new BannerSelectionUseCase(
101
			$this->getTrueRandomTestCampaignCollection(),
102
			new ImpressionThreshold( 10 )
103
		);
104
		$controller = new BannerSelectionController( $testUseCase, $this->getMockAssets() );
105
		$response = $controller->selectBanner( new Request() );
106
107
		$cookies = $response->headers->getCookies();
108
109
		$this->assertEquals( 2, count( $cookies ) );
110
111
		$this->assertEquals( BannerSelectionController::BUCKET_COOKIE, $cookies[0]->getName() );
112
		$this->assertEquals( 'test', $cookies[0]->getValue() );
113
		$this->assertEquals(
114
			( new \DateTime( '2099-12-31 23:59:59' ) )->modify( '+2 week' )->getTimestamp(),
115
			$cookies[0]->getExpiresTime(),
116
			'Cookie life-time should be the campaign expiration date plus two weeks.'
117
		);
118
119
		$this->assertEquals( BannerSelectionController::IMPRESSION_COUNT_COOKIE, $cookies[1]->getName() );
120
		$this->assertEquals( '1', $cookies[1]->getValue() );
121
		$this->assertEquals(
122
			( new \DateTime( '2099-12-31 23:59:59' ) )->modify( '+2 week' )->getTimestamp(),
123
			$cookies[1]->getExpiresTime(),
124
			'Cookie life-time should be the campaign expiration date plus two weeks.'
125
		);
126
	}
127
128
	public function test_given_banner_is_to_be_shown_redirect_response_is_returned() {
129
		$testUseCase = new BannerSelectionUseCase(
130
			$this->getTrueRandomTestCampaignCollection(),
131
			new ImpressionThreshold( 10 )
132
		);
133
		$controller = new BannerSelectionController( $testUseCase, $this->getMockAssets() );
134
		$response = $controller->selectBanner( new Request() );
135
136
		$this->assertInstanceOf( RedirectResponse::class, $response );
137
		$this->assertEquals( 'banners/TestMain.js', $response->headers->get( 'location' ) );
138
	}
139
140
	public function test_given_impression_limit_is_reached_no_content_response_is_returned() {
141
		$testUseCase = new BannerSelectionUseCase(
142
			$this->getTrueRandomTestCampaignCollection(),
143
			new ImpressionThreshold( self::VISITOR_TEST_IMPRESSION_COUNT )
144
		);
145
		$controller = new BannerSelectionController( $testUseCase, $this->getMockAssets() );
146
		$response = $controller->selectBanner( $this->getTestRequest() );
147
148
		$this->assertEquals( Response::HTTP_NO_CONTENT, $response->getStatusCode() );
149
	}
150
}
151