ArtistTests.cpp 16.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

23
24
25
26
#if HAVE_CONFIG_H
# include "config.h"
#endif

Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
27
28
#include "Tests.h"

29
30
31
#include "Artist.h"
#include "Album.h"
#include "AlbumTrack.h"
32
#include "Media.h"
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
33
34
35
36
37
38
39
40
41
42
43
44
45

class Artists : public Tests
{
};

TEST_F( Artists, Create )
{
    auto a = ml->createArtist( "Flying Otters" );
    ASSERT_NE( a, nullptr );
    ASSERT_EQ( a->name(), "Flying Otters" );

    Reload();

46
47
48
    auto a2 = ml->artist( "Flying Otters" );
    ASSERT_NE( a2, nullptr );
    ASSERT_EQ( a2->name(), "Flying Otters" );
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
49
50
}

51
52
53
54
55
56
57
58
59
60
TEST_F( Artists, CreateDefaults )
{
    // Ensure this won't fail due to duplicate insertions
    // We just reload, which will call the initialization routine again.
    // This is implicitely tested by all other tests, though it seems better
    // to have an explicit one. We might also just run the request twice from here
    // sometime in the future.
    Reload();
}

Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
61
62
63
64
65
66
67
68
69
70
71
72
TEST_F( Artists, ShortBio )
{
    auto a = ml->createArtist( "Raging Otters" );
    ASSERT_NE( a, nullptr );
    ASSERT_EQ( a->shortBio(), "" );

    std::string bio("An otter based post-rock band");
    a->setShortBio( bio );
    ASSERT_EQ( a->shortBio(), bio );

    Reload();

73
74
75
    auto a2 = ml->artist( "Raging Otters" );
    ASSERT_NE( a2, nullptr );
    ASSERT_EQ( a2->shortBio(), bio );
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
76
}
77

78
TEST_F( Artists, ArtworkMrl )
79
80
81
{
    auto a = ml->createArtist( "Dream seaotter" );
    ASSERT_NE( a, nullptr );
82
    ASSERT_EQ( a->artworkMrl(), "" );
83
84

    std::string artwork("/tmp/otter.png");
85
    a->setArtworkMrl( artwork, Thumbnail::Origin::UserProvided );
86
    ASSERT_EQ( a->artworkMrl(), artwork );
87
88
89
90
91

    Reload();

    auto a2 = ml->artist( "Dream seaotter" );
    ASSERT_NE( a2, nullptr );
92
    ASSERT_EQ( a2->artworkMrl(), artwork );
93
94
}

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
TEST_F( Artists, Thumbnail )
{
    auto a = ml->createArtist( "artist" );
    auto t = a->thumbnail();
    ASSERT_EQ( nullptr, t );

    std::string mrl = "/path/to/sea/otter/artwork.png";
    auto res = a->setArtworkMrl( mrl, Thumbnail::Origin::UserProvided );
    ASSERT_TRUE( res );

    t = a->thumbnail();
    ASSERT_NE( nullptr, t );
    ASSERT_EQ( mrl, t->mrl() );

    Reload();

    a = std::static_pointer_cast<Artist>( ml->artist( a->id() ) );
    t = a->thumbnail();
    ASSERT_NE( nullptr, t );
    ASSERT_EQ( mrl, t->mrl() );
}

117
// Test the number of albums based on the artist tracks
118
119
120
121
122
123
124
125
126
127
TEST_F( Artists, Albums )
{
    auto artist = ml->createArtist( "Cannibal Otters" );
    auto album1 = ml->createAlbum( "album1" );
    auto album2 = ml->createAlbum( "album2" );

    ASSERT_NE( artist, nullptr );
    ASSERT_NE( album1, nullptr );
    ASSERT_NE( album2, nullptr );

128
129
130
131
132
133
134
    auto media1 = ml->addFile( "track1.mp3" );
    ASSERT_NE( nullptr, media1 );
    album1->addTrack( media1, 1, 0, artist->id(), nullptr );
    auto media2 = ml->addFile( "track2.mp3" );
    ASSERT_NE( nullptr, media2 );
    album2->addTrack( media2, 1, 0, artist->id(), nullptr );

135
136
    album1->setAlbumArtist( artist );
    album2->setAlbumArtist( artist );
137

138
    auto albums = artist->albums( nullptr )->all();
139
140
141
142
    ASSERT_EQ( albums.size(), 2u );

    Reload();

143
    auto artist2 = ml->artist( "Cannibal Otters" );
144
    auto albums2 = artist2->albums( nullptr )->all();
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
    ASSERT_EQ( albums2.size(), 2u );
}

// Test the nb_album DB field (ie. we don't need to create tracks for this test)
TEST_F( Artists, NbAlbums )
{
    auto artist = ml->createArtist( "Cannibal Otters" );
    auto album1 = ml->createAlbum( "album1" );
    auto album2 = ml->createAlbum( "album2" );

    ASSERT_NE( artist, nullptr );
    ASSERT_NE( album1, nullptr );
    ASSERT_NE( album2, nullptr );

    album1->setAlbumArtist( artist );
    album2->setAlbumArtist( artist );

    auto nbAlbums = artist->nbAlbums();
    ASSERT_EQ( nbAlbums, 2u );

    Reload();

    auto artist2 = ml->artist( "Cannibal Otters" );
    nbAlbums = artist2->nbAlbums();
    ASSERT_EQ( nbAlbums, 2u );
170
}
171

172
173
174
175
176
177
178
TEST_F( Artists, AllSongs )
{
    auto artist = ml->createArtist( "Cannibal Otters" );
    ASSERT_NE( artist, nullptr );

    for (auto i = 1; i <= 3; ++i)
    {
179
        auto f = std::static_pointer_cast<Media>( ml->addMedia( "song" + std::to_string(i) + ".mp3" ) );
180
        auto res = artist->addMedia( *f );
181
182
183
        ASSERT_TRUE( res );
    }

184
    auto songs = artist->media( nullptr )->all();
185
186
187
188
189
    ASSERT_EQ( songs.size(), 3u );

    Reload();

    auto artist2 = ml->artist( "Cannibal Otters" );
190
    songs = artist2->media( nullptr )->all();
191
192
193
    ASSERT_EQ( songs.size(), 3u );
}

194
195
TEST_F( Artists, GetAll )
{
196
    auto artists = ml->artists( true, nullptr )->all();
197
198
199
    // Ensure we don't include Unknown Artist // Various Artists
    ASSERT_EQ( artists.size(), 0u );

200
201
202
    for ( int i = 0; i < 5; i++ )
    {
        auto a = ml->createArtist( std::to_string( i ) );
203
204
        auto alb = ml->createAlbum( std::to_string( i ) );
        ASSERT_NE( nullptr, alb );
205
        alb->setAlbumArtist( a );
206
207
        ASSERT_NE( a, nullptr );
    }
208
    artists = ml->artists( true, nullptr )->all();
209
210
211
212
    ASSERT_EQ( artists.size(), 5u );

    Reload();

213
    auto artists2 = ml->artists( true, nullptr )->all();
214
    ASSERT_EQ( artists2.size(), 5u );
215
}
216

217
218
TEST_F( Artists, GetAllNoAlbum )
{
219
    auto artists = ml->artists( true, nullptr )->all();
220
221
222
223
224
225
226
227
    // Ensure we don't include Unknown Artist // Various Artists
    ASSERT_EQ( artists.size(), 0u );

    for ( int i = 0; i < 3; i++ )
    {
        auto a = ml->createArtist( std::to_string( i ) );
        a->updateNbTrack( 1 );
    }
228
    artists = ml->artists( false, nullptr )->all();
229
230
231
232
    ASSERT_EQ( artists.size(), 0u );

    Reload();

233
    artists = ml->artists( false, nullptr )->all();
234
235
    ASSERT_EQ( artists.size(), 0u );

236
    artists = ml->artists( true, nullptr )->all();
237
238
239
    ASSERT_EQ( artists.size(), 3u );
}

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
TEST_F( Artists, UnknownAlbum )
{
    auto a = ml->createArtist( "Explotters in the sky" );
    auto album = a->unknownAlbum();
    auto album2 = a->unknownAlbum();

    ASSERT_NE( nullptr, album );
    ASSERT_NE( nullptr, album2 );
    ASSERT_EQ( album->id(), album2->id() );

    Reload();

    a = std::static_pointer_cast<Artist>( ml->artist( a->name() ) );
    album2 = a->unknownAlbum();
    ASSERT_NE( nullptr, album2 );
    ASSERT_EQ( album2->id(), album->id() );
}
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

TEST_F( Artists, MusicBrainzId )
{
    auto a = ml->createArtist( "Otters Never Say Die" );
    ASSERT_NE( a, nullptr );
    ASSERT_EQ( a->musicBrainzId(), "" );

    std::string mbId("{this-id-an-id}");
    a->setMusicBrainzId( mbId );
    ASSERT_EQ( a->musicBrainzId(), mbId );

    Reload();

    auto a2 = ml->artist( "Otters Never Say Die" );
    ASSERT_NE( a2, nullptr );
    ASSERT_EQ( a2->musicBrainzId(), mbId );
}
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
274
275
276

TEST_F( Artists, Search )
{
277
278
    auto a1 = ml->createArtist( "artist 1" );
    auto a2 = ml->createArtist( "artist 2" );
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
279
280
    ml->createArtist( "dream seaotter" );

281
    auto artists = ml->searchArtists( "artist", nullptr )->all();
282
283
284
285
    ASSERT_EQ( 2u, artists.size() );
    ASSERT_EQ( artists[0]->id(), a1->id() );
    ASSERT_EQ( artists[1]->id(), a2->id() );

286
287
    QueryParameters params { SortingCriteria::Default, true };
    artists = ml->searchArtists( "artist", &params )->all();
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
288
    ASSERT_EQ( 2u, artists.size() );
289
290
    ASSERT_EQ( artists[0]->id(), a2->id() );
    ASSERT_EQ( artists[1]->id(), a1->id() );
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
291
292
293
294
295
296
297
298
}

TEST_F( Artists, SearchAfterDelete )
{
    auto a = ml->createArtist( "artist 1" );
    ml->createArtist( "artist 2" );
    ml->createArtist( "dream seaotter" );

299
    auto artists = ml->searchArtists( "artist", nullptr )->all();
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
300
301
302
303
    ASSERT_EQ( 2u, artists.size() );

    ml->deleteArtist( a->id() );

304
    artists = ml->searchArtists( "artist", nullptr )->all();
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
305
306
    ASSERT_EQ( 1u, artists.size() );
}
307
308
309
310
311
312
313

TEST_F( Artists, SortMedia )
{
    auto artist = ml->createArtist( "Russian Otters" );

    for (auto i = 1; i <= 3; ++i)
    {
314
        auto f = std::static_pointer_cast<Media>( ml->addMedia( "song" + std::to_string(i) + ".mp3" ) );
315
316
317
318
319
        f->setDuration( 10 - i );
        f->save();
        artist->addMedia( *f );
    }

320
321
    QueryParameters params { SortingCriteria::Duration, false };
    auto tracks = artist->media( &params )->all();
322
323
324
325
326
    ASSERT_EQ( 3u, tracks.size() );
    ASSERT_EQ( "song3.mp3", tracks[0]->title() ); // Duration: 8
    ASSERT_EQ( "song2.mp3", tracks[1]->title() ); // Duration: 9
    ASSERT_EQ( "song1.mp3", tracks[2]->title() ); // Duration: 10

327
328
    params.desc = true;
    tracks = artist->media( &params )->all();
329
330
331
332
333
    ASSERT_EQ( 3u, tracks.size() );
    ASSERT_EQ( "song1.mp3", tracks[0]->title() );
    ASSERT_EQ( "song2.mp3", tracks[1]->title() );
    ASSERT_EQ( "song3.mp3", tracks[2]->title() );
}
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
TEST_F( Artists, SortMediaByAlbum )
{
    auto artist = ml->createArtist( "Russian Otters" );

    std::shared_ptr<Album> albums[] = {
        std::static_pointer_cast<Album>( ml->createAlbum( "album1" ) ),
        std::static_pointer_cast<Album>( ml->createAlbum( "album2" ) ),
    };
    // Iterate by track first to interleave ids and ensure we're sorting correctly
    for (auto iTrack = 1; iTrack <= 2; ++iTrack)
    {
        for ( auto iAlbum = 0; iAlbum < 2; ++iAlbum )
        {
            auto f = std::static_pointer_cast<Media>( ml->addMedia( "alb" +
                            std::to_string( iAlbum ) + "_song" + std::to_string(iTrack) + ".mp3" ) );
            artist->addMedia( *f );
351
            albums[iAlbum]->addTrack( f, iTrack, 0, artist->id(), nullptr );
352
353
354
        }
    }

355
356
    QueryParameters params { SortingCriteria::Album, false };
    auto tracks = artist->media( &params )->all();
357
358
359
360
361
362
    ASSERT_EQ( 4u, tracks.size() );
    ASSERT_EQ( "alb0_song1.mp3", tracks[0]->title() );
    ASSERT_EQ( "alb0_song2.mp3", tracks[1]->title() );
    ASSERT_EQ( "alb1_song1.mp3", tracks[2]->title() );
    ASSERT_EQ( "alb1_song2.mp3", tracks[3]->title() );

363
364
    params.desc = true;
    tracks = artist->media( &params )->all();
365
366
367
368
369
370
371
    ASSERT_EQ( 4u, tracks.size() );
    ASSERT_EQ( "alb1_song2.mp3", tracks[0]->title() );
    ASSERT_EQ( "alb1_song1.mp3", tracks[1]->title() );
    ASSERT_EQ( "alb0_song2.mp3", tracks[2]->title() );
    ASSERT_EQ( "alb0_song1.mp3", tracks[3]->title() );
}

372
373
374
375
TEST_F( Artists, SortAlbum )
{
    auto artist = ml->createArtist( "Dream Seaotter" );
    auto album1 = ml->createAlbum( "album1" );
376
377
    auto media1 = ml->addFile( "track1.mp3" );
    album1->addTrack( media1, 1, 0, artist->id(), nullptr );
378
379
    album1->setReleaseYear( 2000, false );
    auto album2 = ml->createAlbum( "album2" );
380
381
    auto media2 = ml->addFile( "track2.mp3" );
    album2->addTrack( media2, 1, 0, artist->id(), nullptr );
382
383
    album2->setReleaseYear( 1000, false );
    auto album3 = ml->createAlbum( "album3" );
384
385
    auto media3 = ml->addFile( "track2.mp3" );
    album3->addTrack( media3, 1, 0, artist->id(), nullptr );
386
387
    album3->setReleaseYear( 2000, false );

388
389
390
    album1->setAlbumArtist( artist );
    album2->setAlbumArtist( artist );
    album3->setAlbumArtist( artist );
391
392

    // Default order is by descending year, discriminated by lexical order
393
    auto albums = artist->albums( nullptr )->all();
394
395
396
397
398
    ASSERT_EQ( 3u, albums.size() );
    ASSERT_EQ( album1->id(), albums[0]->id() );
    ASSERT_EQ( album3->id(), albums[1]->id() );
    ASSERT_EQ( album2->id(), albums[2]->id() );

399
400
    QueryParameters params { SortingCriteria::Default, true };
    albums = artist->albums( &params )->all();
401
402
403
404
405
    ASSERT_EQ( 3u, albums.size() );
    ASSERT_EQ( album2->id(), albums[0]->id() );
    ASSERT_EQ( album1->id(), albums[1]->id() );
    ASSERT_EQ( album3->id(), albums[2]->id() );

406
407
408
    params.sort = SortingCriteria::Alpha;
    params.desc = false;
    albums = artist->albums( &params )->all();
409
410
411
412
413
    ASSERT_EQ( 3u, albums.size() );
    ASSERT_EQ( album1->id(), albums[0]->id() );
    ASSERT_EQ( album2->id(), albums[1]->id() );
    ASSERT_EQ( album3->id(), albums[2]->id() );

414
415
    params.desc = true;
    albums = artist->albums( &params )->all();
416
417
418
419
420
    ASSERT_EQ( 3u, albums.size() );
    ASSERT_EQ( album3->id(), albums[0]->id() );
    ASSERT_EQ( album2->id(), albums[1]->id() );
    ASSERT_EQ( album1->id(), albums[2]->id() );
}
421
422
423
424
425
426

TEST_F( Artists, Sort )
{
    // Keep in mind that artists are only listed when they are marked as album artist at least once
    auto a1 = ml->createArtist( "A" );
    auto alb1 = ml->createAlbum( "albumA" );
427
    alb1->setAlbumArtist( a1 );
428
429
    auto a2 = ml->createArtist( "B" );
    auto alb2 = ml->createAlbum( "albumB" );
430
    alb2->setAlbumArtist( a2 );
431

432
433
    QueryParameters params { SortingCriteria::Alpha, false };
    auto artists = ml->artists( true, &params )->all();
434
435
436
437
    ASSERT_EQ( 2u, artists.size() );
    ASSERT_EQ( a1->id(), artists[0]->id() );
    ASSERT_EQ( a2->id(), artists[1]->id() );

438
439
    params.desc = true;
    artists = ml->artists( true, &params )->all();
440
441
442
443
    ASSERT_EQ( 2u, artists.size() );
    ASSERT_EQ( a1->id(), artists[1]->id() );
    ASSERT_EQ( a2->id(), artists[0]->id() );
}
444
445
446
447
448
449
450

TEST_F( Artists, DeleteWhenNoAlbum )
{
    auto artist = ml->createArtist( "artist" );
    auto album = ml->createAlbum( "album 1" );
    album->setAlbumArtist( artist );
    auto m1 = std::static_pointer_cast<Media>( ml->addMedia( "track1.mp3" ) );
451
    auto track1 = album->addTrack( m1, 1, 1, artist->id(), nullptr );
452

453
    auto artists = ml->artists( true, nullptr )->all();
454
455
456
    ASSERT_EQ( 1u, artists.size() );

    ml->deleteTrack( track1->id() );
457
    artists = ml->artists( true, nullptr )->all();
458
459
460
461
    ASSERT_EQ( 0u, artists.size() );

    Reload();

462
    artists = ml->artists( true, nullptr )->all();
463
464
    ASSERT_EQ( 0u, artists.size() );
}
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485

TEST_F( Artists, UpdateNbTracks )
{
    auto artist = ml->createArtist( "artist" );
    ASSERT_EQ( 0u, artist->nbTracks() );
    artist->updateNbTrack( 1 );
    ASSERT_EQ( 1u, artist->nbTracks() );

    Reload();

    artist = std::static_pointer_cast<Artist>( ml->artist( artist->id() ) );
    ASSERT_EQ( 1u, artist->nbTracks() );

    artist->updateNbTrack( -1 );
    ASSERT_EQ( 0u, artist->nbTracks() );

    Reload();

    artist = std::static_pointer_cast<Artist>( ml->artist( artist->id() ) );
    ASSERT_EQ( 0u, artist->nbTracks() );
}
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

TEST_F( Artists, SortTracksMultiDisc )
{
    MediaPtr media[6];
    auto album = ml->createAlbum( "album" );
    auto artist = ml->createArtist( "artist" );
    for ( auto i = 0; i < 3; ++i )
    {
        auto j = i * 2;
        auto media1 = ml->addFile( "track_" + std::to_string( j ) + ".mp3" );
        auto media2 = ml->addFile( "track_" + std::to_string( j + 1 ) + ".mp3" );
        album->addTrack( media1, i, 1, artist->id(), nullptr );
        album->addTrack( media2, i, 2, artist->id(), nullptr );
        artist->addMedia( *media1 );
        artist->addMedia( *media2 );
        media[j] = media1;
        media[j + 1] = media2;
    }
    /*
     * media is now:
     * [ Disc 1 - Track 1 ]
     * [ Disc 2 - Track 1 ]
     * [ Disc 1 - Track 2 ]
     * [ Disc 2 - Track 2 ]
     * [ Disc 1 - Track 3 ]
     * [ Disc 2 - Track 3 ]
     */
513
514
    QueryParameters params { SortingCriteria::Album, false };
    auto tracks = artist->media( &params )->all();
515
516
517
518
519
520
521
522
    ASSERT_EQ( 6u, tracks.size() );
    ASSERT_EQ( media[0]->id(), tracks[0]->id() );
    ASSERT_EQ( media[2]->id(), tracks[1]->id() );
    ASSERT_EQ( media[4]->id(), tracks[2]->id() );
    ASSERT_EQ( media[1]->id(), tracks[3]->id() );
    ASSERT_EQ( media[3]->id(), tracks[4]->id() );
    ASSERT_EQ( media[5]->id(), tracks[5]->id() );

523
524
    params.desc = true;
    tracks = artist->media( &params )->all();
525
526
527
528
529
530
531
532
    ASSERT_EQ( media[5]->id(), tracks[0]->id() );
    ASSERT_EQ( media[3]->id(), tracks[1]->id() );
    ASSERT_EQ( media[1]->id(), tracks[2]->id() );
    ASSERT_EQ( media[4]->id(), tracks[3]->id() );
    ASSERT_EQ( media[2]->id(), tracks[4]->id() );
    ASSERT_EQ( media[0]->id(), tracks[5]->id() );
}

533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
TEST_F( Artists, Query )
{
    auto artist1 = ml->createArtist( "artist1" );
    artist1->updateNbTrack( 1 );
    auto artist2 = ml->createArtist( "artist2" );
    artist2->updateNbTrack( 1 );

    auto query = ml->artists( true, nullptr );
    auto artists = query->items( 1, 0 );
    ASSERT_EQ( 1u, artists.size() );
    ASSERT_EQ( artist1->id(), artists[0]->id() );
    artists = query->items( 1, 1 );
    ASSERT_EQ( 1u, artists.size() );
    ASSERT_EQ( artist2->id(), artists[0]->id() );
    artists = query->all();
    ASSERT_EQ( 2u, artists.size() );
}