Completed
Push — master ( b3520b...1dcb52 )
by Jeroen De
03:36
created

PsrCacheFileFetcherTest::newCachingFileFetcher()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace FileFetcher\Tests\Unit;
6
7
use FileFetcher\FileFetchingException;
8
use FileFetcher\InMemoryFileFetcher;
9
use FileFetcher\NullFileFetcher;
10
use FileFetcher\PsrCacheFileFetcher;
11
use FileFetcher\ThrowingFileFetcher;
12
use PHPUnit\Framework\TestCase;
13
use Psr\SimpleCache\CacheException;
14
use Psr\SimpleCache\CacheInterface;
15
16
/**
17
 * @covers \FileFetcher\PsrCacheFileFetcher
18
 *
19
 * @licence BSD-3-Clause
20
 * @author Jeroen De Dauw < [email protected] >
21
 */
22
class PsrCacheFileFetcherTest extends TestCase {
23
24
	private const FILE_URL = 'foo://bar';
25
	private const FILE_CONTENT = 'NyanData across the sky!';
26
27
	private $fileFetcher;
28
	private $cache;
29
	private $keyBuilder;
30
31
	public function setUp() {
32
		$this->fileFetcher = new InMemoryFileFetcher( [
33
			self::FILE_URL => self::FILE_CONTENT
34
		] );
35
36
		$this->cache = $this->newCacheWithFile();
37
38
		$this->keyBuilder = function( string $string ): string {
39
			return $string;
40
		};
41
	}
42
43
	private function newCacheWithFile(): CacheInterface {
44
		$cache = $this->createMock( CacheInterface::class );
45
46
		$cache->expects( $this->any() )
47
			->method( 'get' )
48
			->with( self::FILE_URL )
49
			->will( $this->returnValue( self::FILE_CONTENT ) );
50
51
		return $cache;
52
	}
53
54
	private function newCachingFileFetcher(): PsrCacheFileFetcher {
55
		return new PsrCacheFileFetcher(
56
			$this->fileFetcher,
57
			$this->cache,
58
			$this->keyBuilder
59
		);
60
	}
61
62
	public function testWhenFileIsNotCached_itGetsRetrieved() {
63
		$this->cache = $this->newNullCache();
64
65
		$this->assertSame(
66
			self::FILE_CONTENT,
67
			$this->newCachingFileFetcher()->fetchFile( self::FILE_URL )
68
		);
69
	}
70
71
	private function newNullCache(): CacheInterface {
72
		$cache = $this->createMock( CacheInterface::class );
73
74
		$cache->expects( $this->any() )
75
			->method( 'get' )
76
			->with( self::FILE_URL )
77
			->will( $this->returnValue( null ) );
78
79
		return $cache;
80
	}
81
82
	public function testWhenFileIsCached_cachedContentsGetsReturned() {
83
		$this->fileFetcher = new ThrowingFileFetcher();
84
85
		$this->assertSame(
86
			self::FILE_CONTENT,
87
			$this->newCachingFileFetcher()->fetchFile( self::FILE_URL )
88
		);
89
	}
90
91
	public function testWhenFileIsNotCached_fileContentsGetsCached() {
92
		$this->cache = $this->newNullCache();
93
94
		$this->cache->expects( $this->once() )
95
			->method( 'set' )
96
			->with(
97
				$this->equalTo( self::FILE_URL ),
98
				$this->equalTo( self::FILE_CONTENT )
99
			);
100
101
		$this->newCachingFileFetcher()->fetchFile( self::FILE_URL );
102
	}
103
104
	public function testWhenFetcherThrowsException_itIsNotCaught() {
105
		$this->cache = $this->newNullCache();
106
		$this->fileFetcher = new ThrowingFileFetcher();
107
		$fetcher = $this->newCachingFileFetcher();
108
109
		$this->expectException( FileFetchingException::class );
110
		$fetcher->fetchFile( self::FILE_URL );
111
	}
112
113
	public function testWhenCacheReadThrowsException_fileContentIsFetched() {
114
		$this->cache = $this->newCacheThatThrowsOnGet();
115
116
		$this->assertSame(
117
			self::FILE_CONTENT,
118
			$this->newCachingFileFetcher()->fetchFile( self::FILE_URL )
119
		);
120
	}
121
122
	private function newCacheThatThrowsOnGet(): CacheInterface {
123
		$cache = $this->createMock( CacheInterface::class );
124
125
		$cache->expects( $this->any() )
126
			->method( 'get' )
127
			->willThrowException( $this->newCacheException() );
128
129
		return $cache;
130
	}
131
132
	private function newCacheException(): \Exception {
133
		return new class() extends \Exception implements CacheException {
134
		};
135
	}
136
137
	public function testWhenCacheWriteThrowsException_fileContentIsReturned() {
138
		$this->cache = $this->newCacheThatThrowsOnSet();
139
140
		$this->assertSame(
141
			self::FILE_CONTENT,
142
			$this->newCachingFileFetcher()->fetchFile( self::FILE_URL )
143
		);
144
	}
145
146
	private function newCacheThatThrowsOnSet(): CacheInterface {
147
		$cache = $this->createMock( CacheInterface::class );
148
149
		$cache->expects( $this->any() )
150
			->method( 'set' )
151
			->willThrowException( $this->newCacheException() );
152
153
		return $cache;
154
	}
155
156
	/**
157
	 * @dataProvider cacheKeyProvider
158
	 */
159
	public function testCacheKeyBuilding( string $fileUrl, string $expectedCacheKey ) {
160
		$cache = $this->createMock( CacheInterface::class );
161
162
		$cache->expects( $this->once() )
163
			->method( 'get' )
164
			->with( $this->equalTo( $expectedCacheKey ) );
165
166
		$cache->expects( $this->once() )
167
			->method( 'set' )
168
			->with( $this->equalTo( $expectedCacheKey ) );
169
170
		$cachingFetcher = new PsrCacheFileFetcher(
171
			new InMemoryFileFetcher( [
172
				$fileUrl => self::FILE_CONTENT
173
			] ),
174
			$cache
175
		);
176
177
		$cachingFetcher->fetchFile( $fileUrl );
178
	}
179
180
	public function cacheKeyProvider() {
181
		yield [
182
			'https://www.entropywins.wtf/blog/wp-json/wp/v2/posts?per_page=10',
183
			'https___www_entropywins_wtf_blog_wp-json_wp_v2_posts_per_page_10-adbba'
184
		];
185
		yield [
186
			'/tmp',
187
			'_tmp-8c393'
188
		];
189
		yield [
190
			'http://localhost:8042/kittens.jpg',
191
			'http___localhost_8042_kittens_jpg-2f14e'
192
		];
193
		yield [
194
			'ÆntrøpyWins',
195
			'__ntr__pyWins-6e250'
196
		];
197
	}
198
199
}
200