YouTubeProviderTest::testProvider()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\MediaBundle\Tests\Provider;
15
16
use Buzz\Browser;
17
use Buzz\Message\AbstractMessage;
18
use Buzz\Message\Response;
19
use Gaufrette\Adapter;
20
use Gaufrette\File;
21
use Gaufrette\Filesystem;
22
use Imagine\Image\Box;
23
use Sonata\AdminBundle\Admin\AdminInterface;
24
use Sonata\AdminBundle\Form\FormMapper;
25
use Sonata\MediaBundle\CDN\Server;
26
use Sonata\MediaBundle\Generator\IdGenerator;
27
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
28
use Sonata\MediaBundle\Provider\MediaProviderInterface;
29
use Sonata\MediaBundle\Provider\YouTubeProvider;
30
use Sonata\MediaBundle\Resizer\ResizerInterface;
31
use Sonata\MediaBundle\Tests\Entity\Media;
32
use Sonata\MediaBundle\Thumbnail\FormatThumbnail;
33
34
class YouTubeProviderTest extends AbstractProviderTest
35
{
36
    public function getProvider(?Browser $browser = null): MediaProviderInterface
37
    {
38
        if (!$browser) {
39
            $browser = $this->createMock(Browser::class);
40
        }
41
42
        $resizer = $this->createMock(ResizerInterface::class);
43
        $resizer->method('resize')->willReturn(true);
44
        $resizer->method('getBox')->willReturn(new Box(100, 100));
45
46
        $adapter = $this->createMock(Adapter::class);
47
48
        $filesystem = $this->getMockBuilder(Filesystem::class)
49
            ->onlyMethods(['get'])
50
            ->setConstructorArgs([$adapter])
51
            ->getMock();
52
        $file = $this->getMockBuilder(File::class)
53
            ->setConstructorArgs(['foo', $filesystem])
54
            ->getMock();
55
        $filesystem->method('get')->willReturn($file);
56
57
        $cdn = new Server('/uploads/media');
58
59
        $generator = new IdGenerator();
60
61
        $thumbnail = new FormatThumbnail('jpg');
62
63
        $metadata = $this->createMock(MetadataBuilderInterface::class);
64
65
        $provider = new YouTubeProvider('youtube', $filesystem, $cdn, $generator, $thumbnail, $browser, $metadata);
66
        $provider->setResizer($resizer);
67
68
        return $provider;
69
    }
70
71
    public function testProvider(): void
72
    {
73
        $provider = $this->getProvider();
74
75
        $media = new Media();
76
        $media->setName('Nono le petit robot');
77
        $media->setProviderName('youtube');
78
        $media->setProviderReference('BDYAbAtaDzA');
79
        $media->setContext('default');
80
        $media->setProviderMetadata(json_decode('{"provider_url": "http:\/\/www.youtube.com\/", "title": "Nono le petit robot", "html": "<object width=\"425\" height=\"344\"><param name=\"movie\" value=\"http:\/\/www.youtube.com\/v\/BDYAbAtaDzA?fs=1\"><\/param><param name=\"allowFullScreen\" value=\"true\"><\/param><param name=\"allowscriptaccess\" value=\"always\"><\/param><embed src=\"http:\/\/www.youtube.com\/v\/BDYAbAtaDzA?fs=1\" type=\"application\/x-shockwave-flash\" width=\"425\" height=\"344\" allowscriptaccess=\"always\" allowfullscreen=\"true\"><\/embed><\/object>", "author_name": "timan38", "height": 344, "thumbnail_width": 480, "width": 425, "version": "1.0", "author_url": "http:\/\/www.youtube.com\/user\/timan38", "provider_name": "YouTube", "thumbnail_url": "http:\/\/i3.ytimg.com\/vi\/BDYAbAtaDzA\/hqdefault.jpg", "type": "video", "thumbnail_height": 360}', true));
81
82
        $media->setId(1023457);
83
84
        $this->assertSame('http://i3.ytimg.com/vi/BDYAbAtaDzA/hqdefault.jpg', $provider->getReferenceImage($media));
85
86
        $this->assertSame('default/0011/24', $provider->generatePath($media));
87
        $this->assertSame('/uploads/media/default/0011/24/thumb_1023457_big.jpg', $provider->generatePublicUrl($media, 'big'));
88
    }
89
90
    public function testThumbnail(): void
91
    {
92
        $response = $this->createMock(AbstractMessage::class);
93
        $response->expects($this->once())->method('getContent')->willReturn('content');
94
95
        $browser = $this->createMock(Browser::class);
96
97
        $browser->expects($this->once())->method('get')->willReturn($response);
98
99
        $provider = $this->getProvider($browser);
100
101
        $media = new Media();
102
        $media->setProviderName('youtube');
103
        $media->setProviderReference('BDYAbAtaDzA');
104
        $media->setContext('default');
105
        $media->setProviderMetadata(json_decode('{"provider_url": "http:\/\/www.youtube.com\/", "title": "Nono le petit robot", "html": "<object width=\"425\" height=\"344\"><param name=\"movie\" value=\"http:\/\/www.youtube.com\/v\/BDYAbAtaDzA?fs=1\"><\/param><param name=\"allowFullScreen\" value=\"true\"><\/param><param name=\"allowscriptaccess\" value=\"always\"><\/param><embed src=\"http:\/\/www.youtube.com\/v\/BDYAbAtaDzA?fs=1\" type=\"application\/x-shockwave-flash\" width=\"425\" height=\"344\" allowscriptaccess=\"always\" allowfullscreen=\"true\"><\/embed><\/object>", "author_name": "timan38", "height": 344, "thumbnail_width": 480, "width": 425, "version": "1.0", "author_url": "http:\/\/www.youtube.com\/user\/timan38", "provider_name": "YouTube", "thumbnail_url": "http:\/\/i3.ytimg.com\/vi\/BDYAbAtaDzA\/hqdefault.jpg", "type": "video", "thumbnail_height": 360}', true));
106
107
        $media->setId(1023457);
108
109
        $this->assertTrue($provider->requireThumbnails());
110
111
        $provider->addFormat('big', ['width' => 200, 'height' => 100, 'constraint' => true]);
112
113
        $this->assertNotEmpty($provider->getFormats(), '::getFormats() return an array');
114
115
        $provider->generateThumbnails($media);
116
117
        $this->assertSame('default/0011/24/thumb_1023457_big.jpg', $provider->generatePrivateUrl($media, 'big'));
118
    }
119
120
    public function testTransformWithSig(): void
121
    {
122
        $response = new Response();
123
        $response->setContent(file_get_contents(__DIR__.'/../fixtures/valid_youtube.txt'));
124
125
        $browser = $this->createMock(Browser::class);
126
        $browser->expects($this->once())->method('get')->willReturn($response);
127
128
        $provider = $this->getProvider($browser);
129
130
        $provider->addFormat('big', ['width' => 200, 'height' => 100, 'constraint' => true]);
131
132
        $media = new Media();
133
        $media->setContext('default');
134
        $media->setBinaryContent('BDYAbAtaDzA');
135
        $media->setId(1023456);
136
137
        // pre persist the media
138
        $provider->transform($media);
139
140
        $this->assertSame('Nono le petit robot', $media->getName(), '::getName() return the file name');
141
        $this->assertSame('BDYAbAtaDzA', $media->getProviderReference(), '::getProviderReference() is set');
142
    }
143
144
    /**
145
     * @dataProvider getUrls
146
     */
147
    public function testTransformWithUrl(string $url): void
148
    {
149
        $response = new Response();
150
        $response->setContent(file_get_contents(__DIR__.'/../fixtures/valid_youtube.txt'));
151
152
        $browser = $this->createMock(Browser::class);
153
        $browser->expects($this->once())->method('get')->willReturn($response);
154
155
        $provider = $this->getProvider($browser);
156
157
        $provider->addFormat('big', ['width' => 200, 'height' => 100, 'constraint' => true]);
158
159
        $media = new Media();
160
        $media->setContext('default');
161
        $media->setBinaryContent($url);
162
        $media->setId(1023456);
163
164
        // pre persist the media
165
        $provider->transform($media);
166
167
        $this->assertSame('Nono le petit robot', $media->getName(), '::getName() return the file name');
168
        $this->assertSame('BDYAbAtaDzA', $media->getProviderReference(), '::getProviderReference() is set');
169
    }
170
171
    public static function getUrls(): array
172
    {
173
        return [
174
        ['BDYAbAtaDzA'],
175
        ['http://www.youtube.com/watch?v=BDYAbAtaDzA&feature=feedrec_grec_index'],
176
        ['http://www.youtube.com/v/BDYAbAtaDzA?fs=1&amp;hl=en_US&amp;rel=0'],
177
        ['http://www.youtube.com/watch?v=BDYAbAtaDzA#t=0m10s'],
178
        ['http://www.youtube.com/embed/BDYAbAtaDzA?rel=0'],
179
        ['http://www.youtube.com/watch?v=BDYAbAtaDzA'],
180
        ['http://www.m.youtube.com/watch?v=BDYAbAtaDzA'],
181
        ['http://m.youtube.com/watch?v=BDYAbAtaDzA'],
182
        ['https://www.m.youtube.com/watch?v=BDYAbAtaDzA'],
183
        ['https://m.youtube.com/watch?v=BDYAbAtaDzA'],
184
        ['http://youtu.be/BDYAbAtaDzA'],
185
        ];
186
    }
187
188
    public function testGetMetadataException(): void
189
    {
190
        $this->expectException(\RuntimeException::class);
191
        $this->expectExceptionMessage('Unable to retrieve the video information for :BDYAbAtaDzA');
192
        $this->expectExceptionCode(12);
193
194
        $response = new Response();
195
        $response->setContent(file_get_contents(__DIR__.'/../fixtures/valid_youtube.txt'));
196
197
        $browser = $this->createMock(Browser::class);
198
        $browser->expects($this->once())->method('get')->will($this->throwException(new \RuntimeException('First error on get', 12)));
199
200
        $provider = $this->getProvider($browser);
201
202
        $provider->addFormat('big', ['width' => 200, 'height' => 100, 'constraint' => true]);
203
204
        $media = new Media();
205
        $media->setBinaryContent('BDYAbAtaDzA');
206
        $media->setId(1023456);
207
208
        $method = new \ReflectionMethod($provider, 'getMetadata');
209
        $method->setAccessible(true);
210
211
        $method->invokeArgs($provider, [$media, 'BDYAbAtaDzA']);
212
    }
213
214
    public function testForm(): void
215
    {
216
        $provider = $this->getProvider();
217
218
        $admin = $this->createMock(AdminInterface::class);
219
        $admin
220
            ->method('trans')
221
            ->willReturn('message');
222
223
        $formMapper = $this->createMock(FormMapper::class);
224
        $formMapper->expects($this->exactly(8))
225
            ->method('add')
226
            ->willReturn(null);
227
228
        $provider->buildCreateForm($formMapper);
229
230
        $provider->buildEditForm($formMapper);
231
    }
232
233
    public function testHelperProperties(): void
234
    {
235
        $provider = $this->getProvider();
236
237
        $provider->addFormat('admin', ['width' => 100]);
238
        $media = new Media();
239
        $media->setName('Les tests');
240
        $media->setProviderReference('ASDASDAS.png');
241
        $media->setId(10);
242
        $media->setHeight(100);
243
        $media->setWidth(100);
244
245
        $properties = $provider->getHelperProperties($media, 'admin');
246
247
        $this->assertIsArray($properties);
248
        $this->assertSame(100, $properties['player_parameters']['height']);
249
        $this->assertSame(100, $properties['player_parameters']['width']);
250
    }
251
252
    public function testGetReferenceUrl(): void
253
    {
254
        $media = new Media();
255
        $media->setProviderReference('123456');
256
        $this->assertSame('https://www.youtube.com/watch?v=123456', $this->getProvider()->getReferenceUrl($media));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Sonata\MediaBundle\Provider\MediaProviderInterface as the method getReferenceUrl() does only exist in the following implementations of said interface: Sonata\MediaBundle\Provider\DailyMotionProvider, Sonata\MediaBundle\Provider\VimeoProvider, Sonata\MediaBundle\Provider\YouTubeProvider.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
257
    }
258
259
    public function testMetadata(): void
260
    {
261
        $provider = $this->getProvider();
262
263
        $this->assertSame('youtube', $provider->getProviderMetadata()->getTitle());
264
        $this->assertSame('youtube.description', $provider->getProviderMetadata()->getDescription());
265
        $this->assertNotNull($provider->getProviderMetadata()->getImage());
266
        $this->assertSame('fa fa-youtube', $provider->getProviderMetadata()->getOption('class'));
267
        $this->assertSame('SonataMediaBundle', $provider->getProviderMetadata()->getDomain());
268
    }
269
}
270