1<?php 2/* 3 * vim:set softtabstop=4 shiftwidth=4 expandtab: 4 * 5 * LICENSE: GNU Affero General Public License, version 3 (AGPL-3.0-or-later) 6 * Copyright 2001 - 2020 Ampache.org 7 * 8 * This program is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Affero General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Affero General Public License for more details. 17 * 18 * You should have received a copy of the GNU Affero General Public License 19 * along with this program. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22declare(strict_types=1); 23 24namespace Ampache\Module\Album\Export; 25 26use Ahc\Cli\IO\Interactor; 27use Ampache\Config\ConfigContainerInterface; 28use Ampache\Config\ConfigurationKeyEnum; 29use Ampache\MockeryTestCase; 30use Ampache\Repository\Model\Album; 31use Ampache\Repository\Model\Art; 32use Ampache\Repository\Model\Catalog; 33use Ampache\Repository\Model\ModelFactoryInterface; 34use Ampache\Repository\Model\Song; 35use Ampache\Module\Album\Export\Writer\MetadataWriterInterface; 36use Ampache\Repository\SongRepositoryInterface; 37use Mockery\MockInterface; 38use org\bovigo\vfs\vfsStream; 39use Psr\Log\LoggerInterface; 40 41class AlbumArtExporterTest extends MockeryTestCase 42{ 43 /** @var ConfigContainerInterface|MockInterface|null */ 44 private MockInterface $configContainer; 45 46 /** @var LoggerInterface|MockInterface|null */ 47 private MockInterface $logger; 48 49 /** @var ModelFactoryInterface|MockInterface|null */ 50 private MockInterface $modelFactory; 51 52 /** @var MockInterface|SongRepositoryInterface|null */ 53 private MockInterface $songRepository; 54 55 private ?AlbumArtExporter $subject; 56 57 public function setUp(): void 58 { 59 $this->configContainer = $this->mock(ConfigContainerInterface::class); 60 $this->logger = $this->mock(LoggerInterface::class); 61 $this->modelFactory = $this->mock(ModelFactoryInterface::class); 62 $this->songRepository = $this->mock(SongRepositoryInterface::class); 63 64 $this->subject = new AlbumArtExporter( 65 $this->configContainer, 66 $this->logger, 67 $this->modelFactory, 68 $this->songRepository 69 ); 70 } 71 72 public function testExportDoesNothingIfNoInfoExists(): void 73 { 74 $interacor = $this->mock(Interactor::class); 75 $catalog = $this->mock(Catalog::class); 76 $metadataWriter = $this->mock(MetadataWriterInterface::class); 77 $art = $this->mock(Art::class); 78 79 $albumId = 666; 80 81 $catalog->shouldReceive('get_album_ids') 82 ->withNoArgs() 83 ->once() 84 ->andReturn([(string) $albumId]); 85 86 $this->modelFactory->shouldReceive('createArt') 87 ->with($albumId) 88 ->once() 89 ->andReturn($art); 90 91 $art->shouldReceive('has_db_info') 92 ->withNoArgs() 93 ->once() 94 ->andReturnFalse(); 95 96 $this->subject->export( 97 $interacor, 98 $catalog, 99 $metadataWriter 100 ); 101 } 102 103 public function testExportThrowsExceptionIfFileCouldNotBeOpened(): void 104 { 105 $interactor = $this->mock(Interactor::class); 106 $catalog = $this->mock(Catalog::class); 107 $metadataWriter = $this->mock(MetadataWriterInterface::class); 108 $art = $this->mock(Art::class); 109 $album = $this->mock(Album::class); 110 $song = $this->mock(Song::class); 111 $fs_root = vfsStream::setup('', 0000); 112 113 $albumId = 666; 114 $songId = 42; 115 $file = $fs_root->url() . '/some-file'; 116 $raw_mime = '/some-raw-mime.png'; 117 118 $album->id = $albumId; 119 120 $this->expectException(Exception\AlbumArtExportException::class); 121 $this->expectExceptionMessage( 122 'Unable to open `vfs:/folder.some-raw-mime.png` for writing', 123 ); 124 125 $catalog->shouldReceive('get_album_ids') 126 ->withNoArgs() 127 ->once() 128 ->andReturn([(string) $albumId]); 129 130 $this->modelFactory->shouldReceive('createArt') 131 ->with($albumId) 132 ->once() 133 ->andReturn($art); 134 $this->modelFactory->shouldReceive('createAlbum') 135 ->with($albumId) 136 ->once() 137 ->andReturn($album); 138 $this->modelFactory->shouldReceive('createSong') 139 ->with($songId) 140 ->once() 141 ->andReturn($song); 142 143 $this->songRepository->shouldReceive('getByAlbum') 144 ->with($albumId, 1) 145 ->once() 146 ->andReturn([$songId]); 147 148 $art->shouldReceive('has_db_info') 149 ->withNoArgs() 150 ->once() 151 ->andReturnTrue(); 152 153 $this->configContainer->shouldReceive('get') 154 ->with(ConfigurationKeyEnum::ALBUM_ART_PREFERRED_FILENAME) 155 ->once() 156 ->andReturn(''); 157 158 $art->raw_mime = $raw_mime; 159 $song->file = $file; 160 161 $this->subject->export( 162 $interactor, 163 $catalog, 164 $metadataWriter 165 ); 166 } 167 168 public function testExportThrowsExceptionIfFileCouldNotBeWritten(): void 169 { 170 $interactor = $this->mock(Interactor::class); 171 $catalog = $this->mock(Catalog::class); 172 $metadataWriter = $this->mock(MetadataWriterInterface::class); 173 $art = $this->mock(Art::class); 174 $album = $this->mock(Album::class); 175 $song = $this->mock(Song::class); 176 $fs_root = vfsStream::setup(''); 177 $file = vfsStream::newFile('folder.png'); 178 179 $fs_root->addChild($file); 180 181 $albumId = 666; 182 $songId = 42; 183 $file_name = $fs_root->url() . '/some-file'; 184 $raw_mime = 'image/png'; 185 $raw_art = 'some-raw-bytes'; 186 187 $album->id = $albumId; 188 189 $catalog->shouldReceive('get_album_ids') 190 ->withNoArgs() 191 ->once() 192 ->andReturn([(string) $albumId]); 193 194 $this->modelFactory->shouldReceive('createArt') 195 ->with($albumId) 196 ->once() 197 ->andReturn($art); 198 $this->modelFactory->shouldReceive('createAlbum') 199 ->with($albumId) 200 ->once() 201 ->andReturn($album); 202 $this->modelFactory->shouldReceive('createSong') 203 ->with($songId) 204 ->once() 205 ->andReturn($song); 206 207 $this->songRepository->shouldReceive('getByAlbum') 208 ->with($albumId, 1) 209 ->once() 210 ->andReturn([$songId]); 211 212 $art->shouldReceive('has_db_info') 213 ->withNoArgs() 214 ->once() 215 ->andReturnTrue(); 216 217 $this->configContainer->shouldReceive('get') 218 ->with(ConfigurationKeyEnum::ALBUM_ART_PREFERRED_FILENAME) 219 ->once() 220 ->andReturn('//folder.png'); 221 222 $art->raw_mime = $raw_mime; 223 $art->raw = $raw_art; 224 $song->file = $file_name; 225 226 $metadataWriter->shouldReceive('write') 227 ->with( 228 $album, 229 'vfs:', 230 'vfs:///folder.png' 231 ) 232 ->once(); 233 234 $this->subject->export( 235 $interactor, 236 $catalog, 237 $metadataWriter 238 ); 239 240 $this->assertSame( 241 $raw_art, 242 $file->getContent() 243 ); 244 } 245} 246