Databsae service refactoring. Warning, loses stars and listens stats

This commit is contained in:
emeric
2021-12-04 15:25:09 +01:00
parent 97aba4ae82
commit 0cf6b2159e
160 changed files with 6047 additions and 3477 deletions
+68 -116
View File
@@ -21,13 +21,14 @@
using namespace Database;
TEST_F(DatabaseFixture, SingleArtist)
TEST_F(DatabaseFixture, Artist)
{
{
auto transaction {session.createSharedTransaction()};
EXPECT_FALSE(Artist::exists(session, 35));
EXPECT_FALSE(Artist::exists(session, 0));
EXPECT_FALSE(Artist::exists(session, 1));
EXPECT_EQ(Artist::getCount(session), 0);
}
ScopedArtist artist {session, "MyArtist"};
@@ -40,22 +41,23 @@ TEST_F(DatabaseFixture, SingleArtist)
EXPECT_EQ(artist.get()->getId(), artist.getId());
EXPECT_TRUE(Artist::exists(session, artist.getId()));
EXPECT_EQ(Artist::getCount(session), 1);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Artist::getAll(session, Artist::SortMethod::ByName)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
auto artists {Artist::find(session, Artist::FindParameters {})};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
artists = Artist::getAllOrphans(session);
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
artists = Artist::findAllOrphans(session, Range {});
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
}
}
TEST_F(DatabaseFixture, SingleTrackSingleArtist)
TEST_F(DatabaseFixture, Artist_singleTrack)
{
ScopedTrack track {session, "MyTrack"};
ScopedArtist artist {session, "MyArtist"};
@@ -68,7 +70,7 @@ TEST_F(DatabaseFixture, SingleTrackSingleArtist)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Artist::getAllOrphans(session).empty());
EXPECT_TRUE(Artist::findAllOrphans(session, Range {}).results.empty());
}
{
@@ -102,7 +104,7 @@ TEST_F(DatabaseFixture, SingleTrackSingleArtist)
}
}
TEST_F(DatabaseFixture, SingleTrackSingleArtistMultiRoles)
TEST_F(DatabaseFixture, Artist_singleTracktMultiRoles)
{
ScopedTrack track {session, "MyTrack"};
ScopedArtist artist {session, "MyArtist"};
@@ -116,17 +118,16 @@ TEST_F(DatabaseFixture, SingleTrackSingleArtistMultiRoles)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Artist::getAllOrphans(session).empty());
EXPECT_TRUE(Artist::findAllOrphans(session, Range {}).results.empty());
}
{
auto transaction {session.createSharedTransaction()};
bool hasMore{};
EXPECT_EQ(Artist::getByFilter(session, {}, {}, std::nullopt, Artist::SortMethod::ByName, std::nullopt, hasMore).size(), 1);
EXPECT_EQ(Artist::getByFilter(session, {}, {}, TrackArtistLinkType::Artist, Artist::SortMethod::ByName, std::nullopt, hasMore).size(), 1);
EXPECT_EQ(Artist::getByFilter(session, {}, {}, TrackArtistLinkType::ReleaseArtist, Artist::SortMethod::ByName, std::nullopt, hasMore).size(), 1);
EXPECT_EQ(Artist::getByFilter(session, {}, {}, TrackArtistLinkType::Writer, Artist::SortMethod::ByName, std::nullopt, hasMore).size(), 1);
EXPECT_TRUE(Artist::getByFilter(session, {}, {}, TrackArtistLinkType::Composer, Artist::SortMethod::ByName, std::nullopt, hasMore).empty());
EXPECT_EQ(Artist::find(session, Artist::FindParameters {}).results.size(), 1);
EXPECT_EQ(Artist::find(session, Artist::FindParameters {}.setLinkType(TrackArtistLinkType::Artist)).results.size(), 1);
EXPECT_EQ(Artist::find(session, Artist::FindParameters {}.setLinkType(TrackArtistLinkType::ReleaseArtist)).results.size(), 1);
EXPECT_EQ(Artist::find(session, Artist::FindParameters {}.setLinkType(TrackArtistLinkType::Writer)).results.size(), 1);
EXPECT_EQ(Artist::find(session, Artist::FindParameters {}.setLinkType(TrackArtistLinkType::Composer)).results.size(), 0);
}
{
@@ -149,7 +150,7 @@ TEST_F(DatabaseFixture, SingleTrackSingleArtistMultiRoles)
}
}
TEST_F(DatabaseFixture,SingleTrackMultiArtists)
TEST_F(DatabaseFixture, Artist_singleTrackMultiArtists)
{
ScopedTrack track {session, "track"};
ScopedArtist artist1 {session, "artist1"};
@@ -165,7 +166,7 @@ TEST_F(DatabaseFixture,SingleTrackMultiArtists)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Artist::getAllOrphans(session).empty());
EXPECT_TRUE(Artist::findAllOrphans(session, Range {}).results.empty());
}
{
@@ -179,8 +180,8 @@ TEST_F(DatabaseFixture,SingleTrackMultiArtists)
EXPECT_EQ(track->getArtists({}).size(), 2);
EXPECT_EQ(track->getArtists({TrackArtistLinkType::Artist}).size(), 2);
EXPECT_TRUE(track->getArtists({TrackArtistLinkType::ReleaseArtist}).empty());
EXPECT_EQ(Artist::getAll(session, Artist::SortMethod::ByName).size(), 2);
EXPECT_EQ(Artist::getAllIds(session).size(), 2);
EXPECT_EQ(Artist::find(session, Artist::FindParameters {}).results.size(), 2);
EXPECT_EQ(Artist::find(session, Artist::FindParameters {}.setSortMethod(ArtistSortMethod::Random)).results.size(), 2);
}
{
@@ -196,7 +197,7 @@ TEST_F(DatabaseFixture,SingleTrackMultiArtists)
}
}
TEST_F(DatabaseFixture, SingleArtistSearchByName)
TEST_F(DatabaseFixture, Artist_findByName)
{
ScopedArtist artist {session, "AAA"};
ScopedTrack track {session, "MyTrack"}; // filters does not work on orphans
@@ -210,22 +211,22 @@ TEST_F(DatabaseFixture, SingleArtistSearchByName)
{
auto transaction {session.createSharedTransaction()};
bool more {};
EXPECT_TRUE(Artist::getByFilter(session, {}, {"N"}, std::nullopt, Artist::SortMethod::ByName, std::nullopt, more).empty());
EXPECT_TRUE(Artist::find(session, Artist::FindParameters {}.setKeywords({"N"})).results.empty());
const auto artistsByAAA {Artist::Artist::getByFilter(session, {}, {"A"}, std::nullopt, Artist::SortMethod::ByName, std::nullopt, more)};
ASSERT_EQ(artistsByAAA.size(), 1);
EXPECT_EQ(artistsByAAA.front()->getId(), artist.getId());
const auto artistsByAAA {Artist::find(session, Artist::FindParameters {}.setKeywords({"A"}))};
ASSERT_EQ(artistsByAAA.results.size(), 1);
EXPECT_EQ(artistsByAAA.results.front(), artist.getId());
const auto artistsByZZZ {Artist::Artist::getByFilter(session, {}, {"Z"}, std::nullopt, Artist::SortMethod::ByName, std::nullopt, more)};
ASSERT_EQ(artistsByZZZ.size(), 1);
EXPECT_EQ(artistsByZZZ.front()->getId(), artist.getId());
const auto artistsByZZZ {Artist::Artist::find(session, Artist::FindParameters {}.setKeywords({"Z"}))};
ASSERT_EQ(artistsByZZZ.results.size(), 1);
EXPECT_EQ(artistsByZZZ.results.front(), artist.getId());
EXPECT_TRUE(Artist::getByName(session, "NNN").empty());
EXPECT_TRUE(Artist::find(session, "NNN").empty());
EXPECT_EQ(Artist::find(session, "AAA").size(), 1);
}
}
TEST_F(DatabaseFixture, MultipleArtistsSearchByNameEscaped)
TEST_F(DatabaseFixture, Artist_findByNameEscaped)
{
ScopedArtist artist1 {session, "MyArtist%"};
ScopedArtist artist2 {session, "%MyArtist"};
@@ -238,70 +239,55 @@ TEST_F(DatabaseFixture, MultipleArtistsSearchByNameEscaped)
{
auto transaction {session.createSharedTransaction()};
{
const auto artists {Artist::getByName(session, "MyArtist%")};
const auto artists {Artist::find(session, "MyArtist%")};
ASSERT_TRUE(artists.size() == 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
EXPECT_TRUE(Artist::getByName(session, "MyArtistFoo").empty());
EXPECT_TRUE(Artist::find(session, "MyArtistFoo").empty());
}
{
const auto artists {Artist::getByName(session, "%MyArtist")};
const auto artists {Artist::find(session, "%MyArtist")};
ASSERT_TRUE(artists.size() == 1);
EXPECT_EQ(artists.front()->getId(), artist2.getId());
EXPECT_TRUE(Artist::getByName(session, "FooMyArtist").empty());
EXPECT_TRUE(Artist::find(session, "FooMyArtist").empty());
}
{
const auto artists {Artist::getByName(session, "%_MyArtist")};
const auto artists {Artist::find(session, "%_MyArtist")};
ASSERT_TRUE(artists.size() == 1);
ASSERT_EQ(artists.front()->getId(), artist3.getId());
EXPECT_TRUE(Artist::getByName(session, "%CMyArtist").empty());
EXPECT_TRUE(Artist::find(session, "%CMyArtist").empty());
}
}
// get by filter only works with tracks links...
ScopedTrack track {session, "MyTrack"}; // filters does not work on orphans
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track.get(), artist1.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track.get(), artist2.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track.get(), artist3.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track.get(), artist4.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track.get(), artist5.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track.get(), artist6.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
bool more;
{
const auto artists {Artist::getByFilter(session, {}, {"MyArtist"}, std::nullopt, Artist::SortMethod::ByName, std::nullopt, more)};
EXPECT_EQ(artists.size(), 6);
const auto artists {Artist::find(session, Artist::FindParameters {}.setKeywords({"MyArtist"}))};
EXPECT_EQ(artists.results.size(), 6);
}
{
const auto artists {Artist::getByFilter(session, {}, {"MyArtist%"}, std::nullopt, Artist::SortMethod::ByName, std::nullopt, more)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist1.getId());
EXPECT_EQ(artists[1]->getId(), artist4.getId());
const auto artists {Artist::find(session, Artist::FindParameters {}.setKeywords({"MyArtist%"}).setSortMethod(ArtistSortMethod::ByName))};
ASSERT_EQ(artists.results.size(), 2);
EXPECT_EQ(artists.results[0], artist1.getId());
EXPECT_EQ(artists.results[1], artist4.getId());
}
{
const auto artists {Artist::getByFilter(session, {}, {"%MyArtist"}, std::nullopt, Artist::SortMethod::ByName, std::nullopt, more)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist2.getId());
EXPECT_EQ(artists[1]->getId(), artist5.getId());
const auto artists {Artist::find(session, Artist::FindParameters {}.setKeywords({"%MyArtist"}).setSortMethod(ArtistSortMethod::ByName))};
ASSERT_EQ(artists.results.size(), 2);
EXPECT_EQ(artists.results[0], artist2.getId());
EXPECT_EQ(artists.results[1], artist5.getId());
}
{
const auto artists {Artist::getByFilter(session, {}, {"_MyArtist"}, std::nullopt, Artist::SortMethod::ByName, std::nullopt, more)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists[0]->getId(), artist3.getId());
const auto artists {Artist::find(session, Artist::FindParameters {}.setKeywords({"_MyArtist"}).setSortMethod(ArtistSortMethod::ByName))};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results[0], artist3.getId());
}
}
}
TEST_F(DatabaseFixture, MultiArtistsSortMethod)
TEST_F(DatabaseFixture, Artist_sortMethod)
{
ScopedArtist artistA {session, "artistA"};
ScopedArtist artistB {session, "artistB"};
@@ -316,20 +302,20 @@ TEST_F(DatabaseFixture, MultiArtistsSortMethod)
{
auto transaction {session.createSharedTransaction()};
auto allArtistsByName {Artist::getAll(session, Artist::SortMethod::ByName)};
auto allArtistsBySortName {Artist::getAll(session, Artist::SortMethod::BySortName)};
auto allArtistsByName {Artist::find(session, Artist::FindParameters {}.setSortMethod(ArtistSortMethod::ByName))};
auto allArtistsBySortName {Artist::find(session, Artist::FindParameters {}.setSortMethod(ArtistSortMethod::BySortName))};
ASSERT_EQ(allArtistsByName.size(), 2);
EXPECT_EQ(allArtistsByName.front()->getId(), artistA.getId());
EXPECT_EQ(allArtistsByName.back()->getId(), artistB.getId());
ASSERT_EQ(allArtistsByName.results.size(), 2);
EXPECT_EQ(allArtistsByName.results.front(), artistA.getId());
EXPECT_EQ(allArtistsByName.results.back(), artistB.getId());
ASSERT_EQ(allArtistsBySortName.size(), 2);
EXPECT_EQ(allArtistsBySortName.front()->getId(), artistB.getId());
EXPECT_EQ(allArtistsBySortName.back()->getId(), artistA.getId());
ASSERT_EQ(allArtistsBySortName.results.size(), 2);
EXPECT_EQ(allArtistsBySortName.results.front(), artistB.getId());
EXPECT_EQ(allArtistsBySortName.results.back(), artistA.getId());
}
}
TEST_F(DatabaseFixture, SingleArtistNonReleaseTracks)
TEST_F(DatabaseFixture, Artist_nonReleaseTracks)
{
ScopedArtist artist {session, "artist"};
ScopedTrack track1 {session, "MyTrack1"};
@@ -340,9 +326,8 @@ TEST_F(DatabaseFixture, SingleArtistNonReleaseTracks)
auto transaction {session.createSharedTransaction()};
EXPECT_FALSE(artist->hasNonReleaseTracks(std::nullopt));
bool moreResults;
const auto tracks {artist->getNonReleaseTracks(std::nullopt, std::nullopt, moreResults )};
EXPECT_EQ(tracks.size(), 0);
const auto tracks {artist->getNonReleaseTracks(std::nullopt, Range {})};
EXPECT_EQ(tracks.results.size(), 0);
}
{
@@ -358,44 +343,11 @@ TEST_F(DatabaseFixture, SingleArtistNonReleaseTracks)
{
auto transaction {session.createSharedTransaction()};
bool moreResults;
const auto tracks {artist->getNonReleaseTracks(std::nullopt, std::nullopt, moreResults )};
const auto tracks {artist->getNonReleaseTracks(std::nullopt, Range {})};
EXPECT_TRUE(artist->hasNonReleaseTracks(std::nullopt));
EXPECT_FALSE(moreResults);
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track2.getId());
}
}
TEST_F(DatabaseFixture, SingleStarredArtist)
{
ScopedArtist artist {session, "MyArtist"};
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
{
auto transaction {session.createUniqueTransaction()};
EXPECT_FALSE(user->isStarred(artist.get()));
}
{
auto transaction {session.createUniqueTransaction()};
auto trackArtistLink {TrackArtistLink::create(session, track.get(), artist.get(), TrackArtistLinkType::Artist)};
user.get().modify()->star(artist.get());
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(user->isStarred(artist.get()));
bool hasMore {};
auto artists {Artist::getStarred(session, user.get(), {}, std::nullopt, Artist::SortMethod::BySortName, std::nullopt, hasMore)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
EXPECT_FALSE(hasMore);
EXPECT_FALSE(tracks.moreResults);
ASSERT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results.front()->getId(), track2.getId());
}
}
@@ -2,9 +2,17 @@
add_executable(test-database
Artist.cpp
Cluster.cpp
Common.cpp
DatabaseTest.cpp
Listen.cpp
Release.cpp
StarredArtist.cpp
StarredRelease.cpp
StarredTrack.cpp
Track.cpp
TrackBookmark.cpp
TrackFeatures.cpp
TrackList.cpp
)
target_link_libraries(test-database PRIVATE
+185 -186
View File
@@ -24,60 +24,73 @@
using namespace Database;
TEST_F(DatabaseFixture, SingleCluster)
TEST_F(DatabaseFixture, Cluster)
{
{
auto transaction {session.createUniqueTransaction()};
EXPECT_EQ(Cluster::getCount(session), 0);
EXPECT_EQ(ClusterType::getCount(session), 0);
}
ScopedClusterType clusterType {session, "MyType"};
{
auto transaction {session.createUniqueTransaction()};
EXPECT_EQ(ClusterType::getCount(session), 1);
}
{
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
{
auto transaction {session.createUniqueTransaction()};
auto clusters {Cluster::getAll(session)};
ASSERT_EQ(clusters.size(), 1);
EXPECT_EQ(clusters.front()->getId(), cluster.getId());
EXPECT_EQ(clusters.front()->getType()->getId(), clusterType.getId());
EXPECT_EQ(Cluster::getCount(session), 1);
EXPECT_EQ(cluster->getType()->getId(), clusterType.getId());
clusters = Cluster::getAllOrphans(session);
ASSERT_EQ(clusters.size(), 1);
EXPECT_EQ(clusters.front()->getId(), cluster.getId());
auto clusters {Cluster::find(session, Range {})};
ASSERT_EQ(clusters.results.size(), 1);
EXPECT_EQ(clusters.results.front(), cluster.getId());
auto clusterTypes {ClusterType::getAll(session)};
ASSERT_EQ(clusterTypes.size(), 1);
EXPECT_EQ(clusterTypes.front()->getId(), clusterType.getId());
clusters = Cluster::findOrphans(session, Range {});
ASSERT_EQ(clusters.results.size(), 1);
EXPECT_EQ(clusters.results.front(), cluster.getId());
clusterTypes = ClusterType::getAllUsed(session);
ASSERT_EQ(clusterTypes.size(), 1);
EXPECT_EQ(clusterTypes.front()->getId(), clusterType.getId());
auto clusterTypes {ClusterType::find(session, Range {})};
ASSERT_EQ(clusterTypes.results.size(), 1);
EXPECT_EQ(clusterTypes.results.front(), clusterType.getId());
clusterTypes = ClusterType::getAllOrphans(session);
EXPECT_TRUE(clusterTypes.empty());
clusterTypes = ClusterType::findUsed(session, Range {});
ASSERT_EQ(clusterTypes.results.size(), 1);
EXPECT_EQ(clusterTypes.results.front(), clusterType.getId());
clusterTypes = ClusterType::findOrphans(session, Range {});
EXPECT_TRUE(clusterTypes.results.empty());
}
}
{
auto transaction {session.createUniqueTransaction()};
auto clusterTypes {ClusterType::getAllOrphans(session)};
ASSERT_EQ(clusterTypes.size(), 1);
EXPECT_EQ(clusterTypes.front()->getId(), clusterType.getId());
auto clusterTypes {ClusterType::findOrphans(session, Range {})};
ASSERT_EQ(clusterTypes.results.size(), 1);
EXPECT_EQ(clusterTypes.results.front(), clusterType.getId());
ASSERT_TRUE(ClusterType::getAllUsed(session).empty());
ASSERT_TRUE(ClusterType::findUsed(session, Range {}).results.empty());
}
}
TEST_F(DatabaseFixture, SingleTrackSingleCluster)
TEST_F(DatabaseFixture, Cluster_singleTrack)
{
ScopedTrack track {session, "MyTrack"};
ScopedClusterType clusterType {session, "MyClusterType"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Cluster::getAllOrphans(session).empty());
auto clusterTypes {ClusterType::getAllOrphans(session)};
ASSERT_EQ(clusterTypes.size(), 1);
EXPECT_EQ(clusterTypes.front()->getId(), clusterType.getId());
EXPECT_TRUE(Cluster::findOrphans(session, Range {}).results.empty());
auto clusterTypes {ClusterType::findOrphans(session, Range {})};
ASSERT_EQ(clusterTypes.results.size(), 1);
EXPECT_EQ(clusterTypes.results.front(), clusterType.getId());
}
ScopedCluster cluster1 {session, clusterType.lockAndGet(), "MyCluster1"};
@@ -85,17 +98,12 @@ TEST_F(DatabaseFixture, SingleTrackSingleCluster)
{
auto transaction {session.createSharedTransaction()};
auto clusters {Cluster::getAllOrphans(session)};
EXPECT_EQ(clusters.size(), 2);
auto clusters {Cluster::findOrphans(session, Range {})};
EXPECT_EQ(clusters.results.size(), 2);
EXPECT_TRUE(track->getClusters().empty());
EXPECT_TRUE(track->getClusterIds().empty());
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Track::getAllIdsWithClusters(session).empty());
}
{
auto transaction {session.createUniqueTransaction()};
@@ -104,29 +112,22 @@ TEST_F(DatabaseFixture, SingleTrackSingleCluster)
{
auto transaction {session.createSharedTransaction()};
auto tracks {Track::getAllIdsWithClusters(session)};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front(), track.getId());
}
auto clusters {Cluster::findOrphans(session, Range {})};
ASSERT_EQ(clusters.results.size(), 1);
EXPECT_EQ(clusters.results.front(), cluster2.getId());
{
auto transaction {session.createSharedTransaction()};
auto clusters {Cluster::getAllOrphans(session)};
ASSERT_EQ(clusters.size(), 1);
EXPECT_EQ(clusters.front()->getId(), cluster2.getId());
EXPECT_TRUE(ClusterType::getAllOrphans(session).empty());
EXPECT_TRUE(ClusterType::findOrphans(session, Range {}).results.empty());
}
{
auto transaction {session.createSharedTransaction()};
auto tracks {Track::getByClusters(session, {cluster1.getId()})};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track.getId());
auto tracks {Track::find(session, Track::FindParameters {}.setClusters({cluster1.getId()}))};
ASSERT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results.front(), track.getId());
tracks = Track::getByClusters(session, {cluster2.getId()});
EXPECT_TRUE(tracks.empty());
tracks = Track::find(session, Track::FindParameters {}.setClusters({cluster2.getId()}));
EXPECT_TRUE(tracks.results.empty());
}
{
@@ -142,7 +143,7 @@ TEST_F(DatabaseFixture, SingleTrackSingleCluster)
}
}
TEST_F(DatabaseFixture, MultipleTracksSingleCluster)
TEST_F(DatabaseFixture, Cluster_multiTracks)
{
std::list<ScopedTrack> tracks;
ScopedClusterType clusterType {session, "MyClusterType"};
@@ -160,19 +161,19 @@ TEST_F(DatabaseFixture, MultipleTracksSingleCluster)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Cluster::getAllOrphans(session).empty());
EXPECT_TRUE(Cluster::findOrphans(session, Range {}).results.empty());
EXPECT_EQ(cluster->getTracksCount(), tracks.size());
for (auto trackCluster : cluster->getTracks())
for (TrackId trackId : cluster->getTracks(Range {}).results)
{
auto it {std::find_if(std::cbegin(tracks), std::cend(tracks), [&](const ScopedTrack& track) { return trackCluster->getId() == track.getId(); })};
auto it {std::find_if(std::cbegin(tracks), std::cend(tracks), [&](const ScopedTrack& track) { return trackId == track.getId(); })};
EXPECT_TRUE(it != std::cend(tracks));
}
}
}
TEST_F(DatabaseFixture, MultipleTracksMultipleClustersTopRelease)
TEST_F(DatabaseFixture, Cluster_multiTracksMultipleClustersTopRelease)
{
ScopedClusterType clusterType {session, "ClusterType"};
ScopedCluster cluster1 {session, clusterType.lockAndGet(), "Cluster1"};
@@ -268,16 +269,25 @@ TEST_F(DatabaseFixture, MultipleTracksMultipleClustersTopRelease)
}
}
TEST_F(DatabaseFixture,SingleTrackSingleReleaseSingleCluster)
TEST_F(DatabaseFixture, Cluster_singleTrackSingleReleaseSingleCluster)
{
ScopedTrack track {session, "MyTrackFile"};
ScopedRelease release {session, "MyRelease"};
ScopedClusterType clusterType {session, "MyClusterType"};
ScopedCluster cluster {session, clusterType .lockAndGet(), "MyCluster"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Release::getAllIdsWithClusters(session).empty());
EXPECT_TRUE(Cluster::findOrphans(session, Range {}).results.empty());
}
ScopedClusterType clusterType {session, "MyClusterType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
ScopedCluster unusedCluster {session, clusterType.lockAndGet(), "MyClusterUnused"};
{
auto transaction {session.createSharedTransaction()};
ASSERT_EQ(Cluster::findOrphans(session, Range {}).results.size(), 2);
EXPECT_TRUE(Release::find(session, Release::FindParameters {}.setClusters({unusedCluster.getId()})).results.empty());
EXPECT_EQ(Release::find(session, Release::FindParameters {}).results.size(), 1);
}
{
@@ -289,24 +299,27 @@ TEST_F(DatabaseFixture,SingleTrackSingleReleaseSingleCluster)
{
auto transaction {session.createSharedTransaction()};
auto releases {Release::getAllIdsWithClusters(session)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front(), release.getId());
{
auto clusters {Cluster::findOrphans(session, Range {})};
ASSERT_EQ(clusters.results.size(), 1);
EXPECT_EQ(clusters.results.front(), unusedCluster.getId());
}
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Cluster::getAllOrphans(session).empty());
EXPECT_TRUE(Release::getAllOrphans(session).empty());
auto releases {Release::find(session, Release::FindParameters {}.setClusters({cluster.getId()}))};
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results.front(), release.getId());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Release::getByClusters(session, {cluster.getId()})};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release.getId());
auto releases {Release::find(session, Release::FindParameters {}.setClusters({unusedCluster.getId()}))};
EXPECT_EQ(releases.results.size(), 0);
}
{
@@ -314,6 +327,8 @@ TEST_F(DatabaseFixture,SingleTrackSingleReleaseSingleCluster)
EXPECT_EQ(cluster->getReleasesCount(), 1);
EXPECT_EQ(cluster->getTracksCount(), 1);
EXPECT_EQ(unusedCluster->getReleasesCount(), 0);
EXPECT_EQ(unusedCluster->getTracksCount(), 0);
}
}
@@ -334,10 +349,10 @@ TEST_F(DatabaseFixture, SingleTrackSingleArtistMultiClusters)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(ClusterType::getAllOrphans(session).empty());
EXPECT_EQ(Cluster::getAllOrphans(session).size(), 2);
EXPECT_TRUE(Release::getAllOrphans(session).empty());
EXPECT_TRUE(Artist::getAllOrphans(session).empty());
EXPECT_TRUE(ClusterType::findOrphans(session, Range {}).results.empty());
EXPECT_EQ(Cluster::findOrphans(session, Range {}).results.size(), 2);
EXPECT_TRUE(Release::findOrphans(session, Range {}).results.empty());
EXPECT_TRUE(Artist::findAllOrphans(session, Range {}).results.empty());
}
{
@@ -349,12 +364,12 @@ TEST_F(DatabaseFixture, SingleTrackSingleArtistMultiClusters)
{
auto transaction {session.createSharedTransaction()};
auto artists {Artist::getByClusters(session, {cluster1.getId()}, Artist::SortMethod::ByName)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
auto artists {Artist::find(session, Artist::FindParameters {}.setClusters({cluster1.getId()}))};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
EXPECT_TRUE(Artist::getByClusters(session, {cluster2.getId()}, Artist::SortMethod::ByName).empty());
EXPECT_TRUE(Artist::getByClusters(session, {cluster3.getId()}, Artist::SortMethod::ByName).empty());
EXPECT_TRUE(Artist::find(session, Artist::FindParameters {}.setClusters({cluster2.getId()})).results.empty());
EXPECT_TRUE(Artist::find(session, Artist::FindParameters {}.setClusters({cluster3.getId()})).results.empty());
cluster2.get().modify()->addTrack(track.get());
}
@@ -362,19 +377,19 @@ TEST_F(DatabaseFixture, SingleTrackSingleArtistMultiClusters)
{
auto transaction {session.createSharedTransaction()};
auto artists {Artist::getByClusters(session, {cluster1.getId()}, Artist::SortMethod::ByName)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
auto artists {Artist::find(session, Artist::FindParameters {}.setClusters({cluster1.getId()}))};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
artists = Artist::getByClusters(session, {cluster2.getId()}, Artist::SortMethod::ByName);
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
artists = Artist::find(session, Artist::FindParameters {}.setClusters({cluster2.getId()}));
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
artists = Artist::getByClusters(session, {cluster1.getId(), cluster2.getId()}, Artist::SortMethod::ByName);
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
artists = Artist::find(session, Artist::FindParameters {}.setClusters({cluster1.getId()}));
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
EXPECT_TRUE(Artist::getByClusters(session, {cluster3.getId()}, Artist::SortMethod::ByName).empty());
EXPECT_TRUE(Artist::find(session, Artist::FindParameters {}.setClusters({cluster3.getId()})).results.empty());
}
}
@@ -395,17 +410,17 @@ TEST_F(DatabaseFixture, SingleTrackSingleArtistMultiRolesMultiClusters)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Cluster::getAllOrphans(session).empty());
EXPECT_TRUE(Release::getAllOrphans(session).empty());
EXPECT_TRUE(Artist::getAllOrphans(session).empty());
EXPECT_TRUE(Cluster::findOrphans(session, Range {}).results.empty());
EXPECT_TRUE(Release::findOrphans(session, Range {}).results.empty());
EXPECT_TRUE(Artist::findAllOrphans(session, Range {}).results.empty());
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Artist::getByClusters(session, {cluster.getId()}, Artist::SortMethod::ByName)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
auto artists {Artist::find(session, Artist::FindParameters {}.setClusters({cluster.getId()}))};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
}
}
@@ -435,8 +450,8 @@ TEST_F(DatabaseFixture, MultiTracksSingleArtistMultiClusters)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Cluster::getAllOrphans(session).empty());
EXPECT_TRUE(Artist::getAllOrphans(session).empty());
EXPECT_TRUE(Cluster::findOrphans(session, Range {}).results.empty());
EXPECT_TRUE(Artist::findAllOrphans(session, Range {}).results.empty());
}
{
@@ -445,9 +460,9 @@ TEST_F(DatabaseFixture, MultiTracksSingleArtistMultiClusters)
std::vector<ClusterId> clusterIds;
std::transform(std::cbegin(clusters), std::cend(clusters), std::back_inserter(clusterIds), [](const ScopedCluster& cluster) { return cluster.getId(); });
auto artists {Artist::getByClusters(session, clusterIds, Artist::SortMethod::ByName)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
auto artists {Artist::find(session, Artist::FindParameters {}.setClusters(clusterIds))};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
}
}
@@ -471,15 +486,11 @@ TEST_F(DatabaseFixture, MultipleTracksSingleClusterSimilarity)
{
auto transaction {session.createSharedTransaction()};
const auto similarTracks {Track::getSimilarTracks(session, {tracks.front().getId()})};
EXPECT_EQ(similarTracks.size(), tracks.size() - 1);
for (auto similarTrack : similarTracks)
const auto similarTracks {Track::findSimilarTracks(session, {tracks.front().getId()}, Range {})};
EXPECT_EQ(similarTracks.results.size(), tracks.size() - 1);
for (const TrackId similarTrackId : similarTracks.results)
{
EXPECT_TRUE(std::find_if(std::next(std::cbegin(tracks), 1), std::cend(tracks),
[&](const ScopedTrack& track)
{
return similarTrack->getId() == track.getId();
}) != std::cend(tracks));
EXPECT_TRUE(std::find_if(std::next(std::cbegin(tracks), 1), std::cend(tracks), [&](const auto& track) { return similarTrackId == track.getId(); }) != std::cend(tracks));
}
}
}
@@ -516,17 +527,17 @@ TEST_F(DatabaseFixture, MultipleTracksMultipleClustersSimilarity)
auto transaction {session.createSharedTransaction()};
{
auto similarTracks {Track::getSimilarTracks(session, {tracks.back().getId()}, 0, 4)};
EXPECT_EQ(similarTracks.size(), 4);
for (auto similarTrack : similarTracks)
EXPECT_TRUE(std::find_if(std::next(std::cbegin(tracks), 5), std::next(std::cend(tracks), -1), [&](const ScopedTrack& track) { return similarTrack->getId() == track.getId(); }) != std::cend(tracks));
auto similarTracks {Track::findSimilarTracks(session, {tracks.back().getId()}, Range {0, 4})};
EXPECT_EQ(similarTracks.results.size(), 4);
for (const TrackId similarTrackId : similarTracks.results)
EXPECT_TRUE(std::find_if(std::next(std::cbegin(tracks), 5), std::next(std::cend(tracks), -1), [&](const auto& track) { return similarTrackId == track.getId(); }) != std::cend(tracks));
}
{
auto similarTracks {Track::getSimilarTracks(session, {tracks.front().getId()})};
EXPECT_EQ(similarTracks.size(), tracks.size() - 1);
for (auto similarTrack : similarTracks)
EXPECT_TRUE(std::find_if(std::next(std::cbegin(tracks), 1), std::cend(tracks), [&](const ScopedTrack& track) { return similarTrack->getId() == track.getId(); }) != std::cend(tracks));
auto similarTracks {Track::findSimilarTracks(session, {tracks.front().getId()}, Range {})};
EXPECT_EQ(similarTracks.results.size(), tracks.size() - 1);
for (const TrackId similarTrackId : similarTracks.results)
EXPECT_TRUE(std::find_if(std::next(std::cbegin(tracks), 1), std::cend(tracks), [&](const auto& track) { return similarTrackId == track.getId(); }) != std::cend(tracks));
}
}
}
@@ -539,11 +550,6 @@ TEST_F(DatabaseFixture, SingleTrackSingleReleaseSingleArtistSingleCluster)
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Artist::getAllIdsWithClusters(session).empty());
}
{
auto transaction {session.createUniqueTransaction()};
@@ -555,25 +561,18 @@ TEST_F(DatabaseFixture, SingleTrackSingleReleaseSingleArtistSingleCluster)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Cluster::getAllOrphans(session).empty());
EXPECT_TRUE(ClusterType::getAllOrphans(session).empty());
EXPECT_TRUE(Artist::getAllOrphans(session).empty());
EXPECT_TRUE(Release::getAllOrphans(session).empty());
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Artist::getAllIdsWithClusters(session)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front(), artist.getId());
EXPECT_TRUE(Cluster::findOrphans(session, Range {}).results.empty());
EXPECT_TRUE(ClusterType::findOrphans(session, Range {}).results.empty());
EXPECT_TRUE(Artist::findAllOrphans(session, Range {}).results.empty());
EXPECT_TRUE(Release::findOrphans(session, Range {}).results.empty());
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Artist::getByClusters(session, {cluster.getId()}, Artist::SortMethod::ByName)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist.getId());
auto artists {Artist::find(session, Artist::FindParameters {}.setClusters({cluster.getId()}))};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist.getId());
auto releases {artist->getReleases()};
ASSERT_EQ(releases.size(), 1);
@@ -735,9 +734,9 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
EXPECT_TRUE(trackList->getArtistsReverse({}, std::nullopt, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getReleasesReverse({}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getTracksReverse({}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getArtistsOrderedByRecentFirst({}, std::nullopt, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getReleasesOrderedByRecentFirst({}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults).empty());
}
{
@@ -750,15 +749,15 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
const auto releases {trackList->getReleasesReverse({}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size() , 1);
EXPECT_EQ(releases.front()->getId(), release1.getId());
const auto tracks {trackList->getTracksReverse({}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track1.getId());
}
@@ -767,15 +766,15 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({cluster1.getId()}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({cluster1.getId()}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
const auto releases {trackList->getReleasesReverse({cluster1.getId()}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({cluster1.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release1.getId());
const auto tracks {trackList->getTracksReverse({cluster1.getId()}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({cluster1.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track1.getId());
}
@@ -784,15 +783,15 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({cluster3.getId()}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({cluster3.getId()}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
const auto releases {trackList->getReleasesReverse({cluster3.getId()}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({cluster3.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release1.getId());
const auto tracks {trackList->getTracksReverse({cluster3.getId()}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({cluster3.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track1.getId());
}
@@ -801,7 +800,7 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({cluster1.getId()}, TrackArtistLinkType::Artist, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({cluster1.getId()}, TrackArtistLinkType::Artist, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
}
@@ -810,7 +809,7 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({}, TrackArtistLinkType::Artist, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({}, TrackArtistLinkType::Artist, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
}
@@ -819,11 +818,11 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
EXPECT_TRUE(trackList->getArtistsReverse({cluster2.getId()}, std::nullopt, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getReleasesReverse({cluster2.getId()}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getTracksReverse({cluster2.getId()}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getArtistsOrderedByRecentFirst({cluster2.getId()}, std::nullopt, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getReleasesOrderedByRecentFirst({cluster2.getId()}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getTracksOrderedByRecentFirst({cluster2.getId()}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getArtistsReverse({}, TrackArtistLinkType::ReleaseArtist, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getArtistsOrderedByRecentFirst({}, TrackArtistLinkType::ReleaseArtist, std::nullopt, moreResults).empty());
}
{
@@ -836,17 +835,17 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist2.getId());
EXPECT_EQ(artists[1]->getId(), artist1.getId());
const auto releases {trackList->getReleasesReverse({}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release2.getId());
EXPECT_EQ(releases[1]->getId(), release1.getId());
const auto tracks {trackList->getTracksReverse({}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track2.getId());
EXPECT_EQ(tracks[1]->getId(),track1.getId());
@@ -856,17 +855,17 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({cluster3.getId()}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({cluster3.getId()}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist2.getId());
EXPECT_EQ(artists[1]->getId(), artist1.getId());
const auto releases {trackList->getReleasesReverse({cluster3.getId()}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({cluster3.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release2.getId());
EXPECT_EQ(releases[1]->getId(), release1.getId());
const auto tracks {trackList->getTracksReverse({cluster3.getId()}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({cluster3.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track2.getId());
EXPECT_EQ(tracks[1]->getId(), track1.getId());
@@ -876,15 +875,15 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({cluster1.getId()}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({cluster1.getId()}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
const auto releases {trackList->getReleasesReverse({cluster1.getId()}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({cluster1.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release1.getId());
const auto tracks {trackList->getTracksReverse({cluster1.getId()}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({cluster1.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track1.getId());
}
@@ -893,15 +892,15 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({cluster2.getId()}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({cluster2.getId()}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist2.getId());
const auto releases {trackList->getReleasesReverse({cluster2.getId()}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({cluster2.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release2.getId());
const auto tracks {trackList->getTracksReverse({cluster2.getId()}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({cluster2.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track2.getId());
}
@@ -916,17 +915,17 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist1.getId());
EXPECT_EQ(artists[1]->getId(), artist2.getId());
const auto releases {trackList->getReleasesReverse({}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release1.getId());
EXPECT_EQ(releases[1]->getId(), release2.getId());
const auto tracks {trackList->getTracksReverse({}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track1.getId());
EXPECT_EQ(tracks[1]->getId(), track2.getId());
@@ -936,17 +935,17 @@ TEST_F(DatabaseFixture, SingleTrackListMultipleTrackMultiClustersRecentlyPlayed)
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({cluster3.getId()}, std::nullopt, std::nullopt, moreResults)};
const auto artists {trackList->getArtistsOrderedByRecentFirst({cluster3.getId()}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist1.getId());
EXPECT_EQ(artists[1]->getId(), artist2.getId());
const auto releases {trackList->getReleasesReverse({cluster3.getId()}, std::nullopt, moreResults)};
const auto releases {trackList->getReleasesOrderedByRecentFirst({cluster3.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release1.getId());
EXPECT_EQ(releases[1]->getId(), release2.getId());
const auto tracks {trackList->getTracksReverse({cluster3.getId()}, std::nullopt, moreResults)};
const auto tracks {trackList->getTracksOrderedByRecentFirst({cluster3.getId()}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track1.getId());
EXPECT_EQ(tracks[1]->getId(), track2.getId());
@@ -964,9 +963,9 @@ TEST_F(DatabaseFixture, MultipleTracksMultipleArtistsMultiClusters)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(artist1->getSimilarArtists().empty());
EXPECT_TRUE(artist2->getSimilarArtists().empty());
EXPECT_TRUE(artist3->getSimilarArtists().empty());
EXPECT_TRUE(artist1->findSimilarArtists().results.empty());
EXPECT_TRUE(artist2->findSimilarArtists().results.empty());
EXPECT_TRUE(artist3->findSimilarArtists().results.empty());
}
std::list<ScopedTrack> tracks;
@@ -998,38 +997,38 @@ TEST_F(DatabaseFixture, MultipleTracksMultipleArtistsMultiClusters)
auto transaction {session.createSharedTransaction()};
{
auto artists {artist1->getSimilarArtists()};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist2.getId());
auto artists {artist1->findSimilarArtists()};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist2.getId());
}
{
auto artists {artist1->getSimilarArtists({TrackArtistLinkType::Artist})};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist2.getId());
auto artists {artist1->findSimilarArtists({TrackArtistLinkType::Artist})};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist2.getId());
}
{
auto artists {artist1->getSimilarArtists({TrackArtistLinkType::ReleaseArtist})};
EXPECT_EQ(artists.empty(), 1);
auto artists {artist1->findSimilarArtists({TrackArtistLinkType::ReleaseArtist})};
EXPECT_EQ(artists.results.empty(), 1);
}
{
auto artists {artist1->getSimilarArtists({TrackArtistLinkType::Artist, TrackArtistLinkType::ReleaseArtist})};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist2.getId());
auto artists {artist1->findSimilarArtists({TrackArtistLinkType::Artist, TrackArtistLinkType::ReleaseArtist})};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results.front(), artist2.getId());
}
{
auto artists {artist1->getSimilarArtists({TrackArtistLinkType::Composer})};
EXPECT_TRUE(artists.empty());
auto artists {artist1->findSimilarArtists({TrackArtistLinkType::Composer})};
EXPECT_TRUE(artists.results.empty());
}
{
auto artists {artist2->getSimilarArtists()};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist1.getId());
EXPECT_EQ(artists[1]->getId(), artist3.getId());
auto artists {artist2->findSimilarArtists()};
ASSERT_EQ(artists.results.size(), 2);
EXPECT_EQ(artists.results[0], artist1.getId());
EXPECT_EQ(artists.results[1], artist3.getId());
}
}
}
+211
View File
@@ -0,0 +1,211 @@
/*
* Copyright (C) 2021 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Common.hpp"
#include "services/database/Artist.hpp"
#include "services/database/Cluster.hpp"
#include "services/database/Db.hpp"
#include "services/database/Listen.hpp"
#include "services/database/Release.hpp"
#include "services/database/Session.hpp"
#include "services/database/StarredArtist.hpp"
#include "services/database/StarredRelease.hpp"
#include "services/database/StarredTrack.hpp"
#include "services/database/Track.hpp"
#include "services/database/TrackArtistLink.hpp"
#include "services/database/TrackBookmark.hpp"
#include "services/database/TrackList.hpp"
#include "services/database/Types.hpp"
#include "services/database/User.hpp"
TmpDatabase::TmpDatabase()
: _tmpFile {std::tmpnam(nullptr)}
, _fileDeleter {_tmpFile}
, _db {_tmpFile}
{
}
Database::Db&
TmpDatabase::getDb()
{
return _db;
}
DatabaseFixture::~DatabaseFixture()
{
testDatabaseEmpty();
}
void
DatabaseFixture::SetUpTestCase()
{
_tmpDb = std::make_unique<TmpDatabase>();
{
Database::Session s {_tmpDb->getDb()};
s.prepareTables();
s.optimize();
// remove default created entries
{
auto transaction {s.createUniqueTransaction()};
auto clusterTypes {Database::ClusterType::find(s, Database::Range {})};
for (auto clusterTypeId : clusterTypes.results)
{
auto clusterType {Database::ClusterType::find(s, clusterTypeId)};
clusterType.remove();
}
}
}
}
void
DatabaseFixture::TearDownTestCase()
{
_tmpDb.reset();
}
void
DatabaseFixture::testDatabaseEmpty()
{
using namespace Database;
auto uniqueTransaction {session.createUniqueTransaction()};
EXPECT_EQ(Artist::getCount(session), 0);
EXPECT_EQ(Cluster::getCount(session), 0);
EXPECT_EQ(ClusterType::getCount(session), 0);
EXPECT_EQ(Listen::getCount(session), 0);
EXPECT_EQ(Release::getCount(session), 0);
EXPECT_EQ(StarredArtist::getCount(session), 0);
EXPECT_EQ(StarredRelease::getCount(session), 0);
EXPECT_EQ(StarredTrack::getCount(session), 0);
EXPECT_EQ(Track::getCount(session), 0);
EXPECT_EQ(TrackBookmark::getCount(session), 0);
EXPECT_EQ(TrackList::getCount(session), 0);
EXPECT_EQ(User::getCount(session), 0);
}
TEST_F(DatabaseFixture, Common_subRangeEmpty)
{
using namespace Database;
RangeResults<int> results;
results.range = Range {0, 0};
results.results = {};
results.moreResults = false;
{
auto subRange {results.getSubRange(Range {0, 0})};
EXPECT_FALSE(subRange.moreResults);
ASSERT_EQ(subRange.results.size(), 0);
EXPECT_EQ(subRange.range, Range {});
}
{
auto subRange {results.getSubRange(Range {0, 1})};
EXPECT_FALSE(subRange.moreResults);
ASSERT_EQ(subRange.results.size(), 0);
}
}
TEST_F(DatabaseFixture, Common_IdType)
{
using namespace Database;
{
const IdType id{};
EXPECT_FALSE(id.isValid());
}
{
const IdType id{0};
EXPECT_TRUE(id.isValid());
}
{
const IdType id1{0};
const IdType id2{0};
EXPECT_EQ(id1, id2);
}
{
const IdType id1{0};
const IdType id2{1};
EXPECT_NE(id1, id2);
EXPECT_LT(id1, id2);
EXPECT_GT(id2, id1);
}
}
TEST_F(DatabaseFixture, Common_subRange)
{
using namespace Database;
RangeResults<int> results;
results.range = Range {0, 2};
results.results = {5, 6};
results.moreResults = false;
{
auto subRange {results.getSubRange(Range {0, 1})};
EXPECT_TRUE(subRange.moreResults);
ASSERT_EQ(subRange.results.size(), 1);
EXPECT_EQ(subRange.results.front(), 5);
}
{
auto subRange {results.getSubRange(Range {1, 1})};
EXPECT_FALSE(subRange.moreResults);
ASSERT_EQ(subRange.results.size(), 1);
EXPECT_EQ(subRange.results.front(), 6);
}
{
auto subRange {results.getSubRange(Range {0, 2})};
EXPECT_FALSE(subRange.moreResults);
ASSERT_EQ(subRange.results.size(), 2);
EXPECT_EQ(subRange.results.front(), 5);
EXPECT_EQ(subRange.results.back(), 6);
}
{
auto subRange {results.getSubRange(Range {})};
EXPECT_FALSE(subRange.moreResults);
ASSERT_EQ(subRange.results.size(), 2);
EXPECT_EQ(subRange.results.front(), 5);
EXPECT_EQ(subRange.results.back(), 6);
EXPECT_EQ(subRange.range, results.range);
}
{
auto subRange {results.getSubRange(Range {1, 0})};
EXPECT_FALSE(subRange.moreResults);
ASSERT_EQ(subRange.results.size(), 1);
EXPECT_EQ(subRange.results.front(), 6);
const Range expectedRange {1, 1};
EXPECT_EQ(subRange.range, expectedRange);
}
{
auto subRange {results.getSubRange(Range {3, 2})};
EXPECT_FALSE(subRange.moreResults);
ASSERT_EQ(subRange.results.size(), 0);
const Range expectedRange {2, 0};
EXPECT_EQ(subRange.range, expectedRange);
}
}
+14 -46
View File
@@ -27,11 +27,13 @@
#include "services/database/Artist.hpp"
#include "services/database/Cluster.hpp"
#include "services/database/Db.hpp"
#include "services/database/Listen.hpp"
#include "services/database/Release.hpp"
#include "services/database/Session.hpp"
#include "services/database/Track.hpp"
#include "services/database/TrackArtistLink.hpp"
#include "services/database/TrackBookmark.hpp"
#include "services/database/TrackFeatures.hpp"
#include "services/database/TrackList.hpp"
#include "services/database/Types.hpp"
#include "services/database/User.hpp"
@@ -57,7 +59,7 @@ class ScopedEntity
{
auto transaction {_session.createUniqueTransaction()};
auto entity {T::getById(_session, _id)};
auto entity {T::find(_session, _id)};
entity.remove();
}
@@ -76,7 +78,7 @@ class ScopedEntity
{
_session.checkSharedLocked();
auto entity {T::getById(_session, _id)};
auto entity {T::find(_session, _id)};
EXPECT_TRUE(entity);
return entity;
}
@@ -98,7 +100,6 @@ using ScopedCluster = ScopedEntity<Database::Cluster>;
using ScopedClusterType = ScopedEntity<Database::ClusterType>;
using ScopedRelease = ScopedEntity<Database::Release>;
using ScopedTrack = ScopedEntity<Database::Track>;
using ScopedTrackBookmark = ScopedEntity<Database::TrackBookmark>;
using ScopedTrackList = ScopedEntity<Database::TrackList>;
using ScopedUser = ScopedEntity<Database::User>;
@@ -120,60 +121,27 @@ class ScopedFileDeleter final
class TmpDatabase final
{
public:
Database::Db& getDb() { return _db; }
TmpDatabase ();
Database::Db& getDb();
private:
const std::filesystem::path _tmpFile {std::tmpnam(nullptr)};
ScopedFileDeleter fileDeleter {_tmpFile};
Database::Db _db {_tmpFile};
const std::filesystem::path _tmpFile;
ScopedFileDeleter _fileDeleter;
Database::Db _db;
};
class DatabaseFixture : public ::testing::Test
{
public:
~DatabaseFixture()
{
testDatabaseEmpty();
}
~DatabaseFixture();
public:
static void SetUpTestCase()
{
_tmpDb = std::make_unique<TmpDatabase>();
{
Database::Session s {_tmpDb->getDb()};
s.prepareTables();
s.optimize();
// remove default created entries
{
auto transaction {s.createUniqueTransaction()};
auto clusterTypes {Database::ClusterType::getAll(s)};
for (auto& clusterType : clusterTypes)
clusterType.remove();
}
}
}
static void TearDownTestCase()
{
_tmpDb.reset();
}
static void SetUpTestCase();
static void TearDownTestCase();
private:
void testDatabaseEmpty()
{
auto uniqueTransaction {session.createUniqueTransaction()};
EXPECT_TRUE(Database::Artist::getAll(session, Database::Artist::SortMethod::ByName).empty());
EXPECT_TRUE(Database::Cluster::getAll(session).empty());
EXPECT_TRUE(Database::ClusterType::getAll(session).empty());
EXPECT_TRUE(Database::Release::getAll(session).empty());
EXPECT_TRUE(Database::Track::getAll(session).empty());
EXPECT_TRUE(Database::TrackBookmark::getAll(session).empty());
EXPECT_TRUE(Database::TrackList::getAll(session).empty());
EXPECT_TRUE(Database::User::getAll(session).empty());
}
void testDatabaseEmpty();
static inline std::unique_ptr<TmpDatabase> _tmpDb {};
@@ -42,8 +42,8 @@ TEST_F(DatabaseFixture, MultiTracksSingleArtistSingleRelease)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Release::getAllOrphans(session).empty());
EXPECT_TRUE(Artist::getAllOrphans(session).empty());
EXPECT_TRUE(Release::findOrphans(session, Range {}).results.empty());
EXPECT_TRUE(Artist::findAllOrphans(session, Range {}).results.empty());
}
{
@@ -89,8 +89,8 @@ TEST_F(DatabaseFixture, SingleUser)
{
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(User::getAll(session).empty());
EXPECT_TRUE(User::getAllIds(session).empty());
EXPECT_TRUE(User::find(session, Range {}).results.empty());
EXPECT_EQ(User::getCount(session), 0);
}
ScopedUser user {session, "MyUser"};
@@ -98,214 +98,8 @@ TEST_F(DatabaseFixture, SingleUser)
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(user->getQueuedTrackList(session)->getCount(), 0);
EXPECT_EQ(User::getAll(session).size(), 1);
EXPECT_EQ(User::getAllIds(session).size(), 1);
}
}
TEST_F(DatabaseFixture, SingleTrackList)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
{
auto transaction {session.createSharedTransaction()};
auto trackLists {TrackList::getAll(session, user.get(), TrackList::Type::Playlist)};
ASSERT_EQ(trackLists.size(), 1);
EXPECT_EQ(trackLists.front()->getId(), trackList.getId());
}
}
TEST_F(DatabaseFixture, SingleTrackListMultipleTrack)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
std::list<ScopedTrack> tracks;
for (std::size_t i {}; i < 10; ++i)
{
tracks.emplace_back(session, "MyTrack" + std::to_string(i));
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, tracks.back().get(), trackList.get());
}
{
auto transaction {session.createSharedTransaction()};
ASSERT_EQ(trackList->getCount(), tracks.size());
const auto trackIds {trackList->getTrackIds()};
for (auto trackId : trackIds)
EXPECT_TRUE(std::any_of(std::cbegin(tracks), std::cend(tracks), [trackId](const ScopedTrack& track) { return track.getId() == trackId; }));
}
}
TEST_F(DatabaseFixture, SingleTrackListMultipleTrackDateTime)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedTrack track3 {session, "MyTrack3"};
{
Wt::WDateTime now {Wt::WDateTime::currentDateTime()};
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track1.get(), trackList.get(), now);
TrackListEntry::create(session, track2.get(), trackList.get(), now.addSecs(-1));
TrackListEntry::create(session, track3.get(), trackList.get(), now.addSecs(1));
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults;
const auto tracks {trackList.get()->getTracksReverse({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 3);
EXPECT_EQ(tracks.front()->getId(), track3.getId());
EXPECT_EQ(tracks.back()->getId(), track2.getId());
}
}
TEST_F(DatabaseFixture, SingleTrackListMultipleTrackRecentlyPlayed)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MyTrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack1"};
ScopedArtist artist1 {session, "MyArtist1"};
ScopedArtist artist2 {session, "MyArtist2"};
ScopedRelease release1 {session, "MyRelease1"};
ScopedRelease release2 {session, "MyRelease2"};
const Wt::WDateTime now {Wt::WDateTime::currentDateTime()};
{
auto transaction {session.createUniqueTransaction()};
track1.get().modify()->setRelease(release1.get());
track2.get().modify()->setRelease(release2.get());
TrackArtistLink::create(session, track1.get(), artist1.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track2.get(), artist2.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
EXPECT_TRUE(trackList->getArtistsReverse({}, std::nullopt, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getReleasesReverse({}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getTracksReverse({}, std::nullopt, moreResults).empty());
}
{
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track1.get(), trackList.get(), now);
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
const auto releases {trackList->getReleasesReverse({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release1.getId());
const auto tracks {trackList->getTracksReverse({}, std::nullopt, moreResults)};
EXPECT_EQ(tracks.size(), 1);
}
{
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track2.get(), trackList.get(), now.addSecs(1));
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist2.getId());
EXPECT_EQ(artists[1]->getId(), artist1.getId());
const auto releases {trackList->getReleasesReverse({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release2.getId());
EXPECT_EQ(releases[1]->getId(), release1.getId());
const auto tracks {trackList->getTracksReverse({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track2.getId());
EXPECT_EQ(tracks[1]->getId(), track1.getId());
}
{
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track1.get(), trackList.get(), now.addSecs(2));
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsReverse({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist1.getId());
EXPECT_EQ(artists[1]->getId(), artist2.getId());
const auto releases {trackList->getReleasesReverse({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release1.getId());
EXPECT_EQ(releases[1]->getId(), release2.getId());
const auto tracks {trackList->getTracksReverse({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track1.getId());
EXPECT_EQ(tracks[1]->getId(), track2.getId());
}
}
TEST_F(DatabaseFixture, SingleTrackSingleUserSingleBookmark)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedTrackBookmark bookmark {session, user.lockAndGet(), track.lockAndGet()};
{
auto transaction {session.createUniqueTransaction()};
bookmark.get().modify()->setComment("MyComment");
bookmark.get().modify()->setOffset(std::chrono::milliseconds {5});
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(TrackBookmark::getAll(session).size(), 1);
const auto bookmarks {TrackBookmark::getByUser(session, user.get())};
ASSERT_EQ(bookmarks.size(), 1);
EXPECT_EQ(bookmarks.back(), bookmark.get());
}
{
auto transaction {session.createSharedTransaction()};
auto userBookmark {TrackBookmark::getByUser(session, user.get(), track.get())};
ASSERT_TRUE(userBookmark);
EXPECT_EQ(userBookmark, bookmark.get());
EXPECT_EQ(userBookmark->getOffset(), std::chrono::milliseconds {5});
EXPECT_EQ(userBookmark->getComment(), "MyComment");
EXPECT_EQ(User::find(session, Range {}).results.size(), 1);
EXPECT_EQ(User::getCount(session), 1);
}
}
+892
View File
@@ -0,0 +1,892 @@
/*
* Copyright (C) 2021 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Common.hpp"
#include "services/database/Listen.hpp"
using namespace Database;
using ScopedListen = ScopedEntity<Database::Listen>;
TEST_F(DatabaseFixture, Listen_getAll)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(Listen::getCount(session), 0);
}
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}}};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(Listen::getCount(session), 1);
}
{
auto transaction {session.createUniqueTransaction()};
ScopedListen listen2 {session, user.get(), track.get(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{13, 0, 1}}};
EXPECT_EQ(Listen::getCount(session), 2);
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(Listen::getCount(session), 1);
}
}
TEST_F(DatabaseFixture, Listen_get)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}}};
{
auto transaction {session.createSharedTransaction()};
auto listens {Listen::find(session, user->getId(), Scrobbler::ListenBrainz)};
EXPECT_EQ(listens.results.size(), 0);
}
{
auto transaction {session.createSharedTransaction()};
auto listens {Listen::find(session, user->getId(), Scrobbler::Internal)};
EXPECT_EQ(listens.moreResults, false);
ASSERT_EQ(listens.results.size(), 1);
EXPECT_EQ(listens.results.front()->getId(), listen->getId());
}
}
TEST_F(DatabaseFixture, Listen_get_multi)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedListen listen3 {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 3}}};
ScopedListen listen1 {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}}};
ScopedListen listen2 {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 2}}};
{
auto transaction {session.createSharedTransaction()};
auto listens {Listen::find(session, user->getId(), Scrobbler::Internal)};
ASSERT_EQ(listens.results.size(), 3);
EXPECT_EQ(listens.results[0]->getId(), listen1.getId());
EXPECT_EQ(listens.results[1]->getId(), listen2.getId());
EXPECT_EQ(listens.results[2]->getId(), listen3.getId());
}
}
TEST_F(DatabaseFixture, Listen_get_byDateTime)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime1 {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
const Wt::WDateTime dateTime2 {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 2}};
ASSERT_GT(dateTime2, dateTime1);
ScopedListen listen1 {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime1};
ScopedListen listen2 {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime2};
{
auto transaction {session.createSharedTransaction()};
{
Listen::pointer listen {Listen::find(session, user.getId(), track.getId(), Scrobbler::Internal, dateTime1)};
ASSERT_TRUE(listen);
EXPECT_EQ(listen->getId(), listen1.getId());
}
{
Listen::pointer listen {Listen::find(session, user.getId(), track.getId(), Scrobbler::Internal, dateTime2)};
ASSERT_TRUE(listen);
EXPECT_EQ(listen->getId(), listen2.getId());
}
{
Listen::pointer listen {Listen::find(session, user.getId(), track.getId(), Scrobbler::Internal, dateTime2.addSecs(56))};
EXPECT_FALSE(listen);
}
}
}
TEST_F(DatabaseFixture, Listen_getTopArtists)
{
ScopedTrack track1 {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime1 {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedListen listen1 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime1};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
EXPECT_EQ(artists.results.size(), 0);
EXPECT_EQ(artists.moreResults, false);
}
ScopedTrack track2 {session, "MyTrack2"};
ScopedArtist artist1 {session, "MyArtist1"};
ScopedListen listen2 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime1.addSecs(1)};
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track2.get(), artist1.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results[0], artist1->getId());
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::ListenBrainz, {}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 0);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, TrackArtistLinkType::Producer)};
EXPECT_EQ(artists.results.size(), 0);
}
{
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {cluster->getId()}, std::nullopt)};
EXPECT_EQ(artists.results.size(), 0);
}
}
}
TEST_F(DatabaseFixture, Listen_getTopArtists_multi)
{
ScopedUser user {session, "MyUser"};
ScopedTrack track1 {session, "MyTrack1"};
ScopedArtist artist1 {session, "MyArtist1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedArtist artist2 {session, "MyArtist2"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track1.get(), artist1.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track2.get(), artist2.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
EXPECT_EQ(artists.results.size(), 0);
}
ScopedListen listen1 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(1)};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results[0], artist1->getId());
}
ScopedListen listen2 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(2)};
ScopedListen listen3 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(3)};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 2);
EXPECT_EQ(artists.results[0], artist2->getId());
EXPECT_EQ(artists.results[1], artist1->getId());
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt, Range {0, 1})};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.moreResults, true);
EXPECT_EQ(artists.results[0], artist2->getId());
}
}
TEST_F(DatabaseFixture, Listen_getTopArtists_cluster)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedArtist artist {session, "MyArtist"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track.get(), artist.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {cluster.getId()}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 0);
}
{
auto transaction {session.createUniqueTransaction()};
cluster.get().modify()->addTrack(track.get());
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {cluster.getId()}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results[0], artist.getId());
}
}
TEST_F(DatabaseFixture, Listen_getTopReleases)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedRelease release {session, "MyRelease"};
{
auto transaction {session.createSharedTransaction()};
track.get().modify()->setRelease(release.get());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
EXPECT_EQ(releases.results.size(), 0);
}
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results[0], release.getId());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getTopReleases(session, user->getId(), Scrobbler::ListenBrainz, {})};
EXPECT_EQ(releases.moreResults, false);
EXPECT_EQ(releases.results.size(), 0);
}
}
TEST_F(DatabaseFixture, Listen_getTopReleases_multi)
{
ScopedTrack track1 {session, "MyTrack"};
ScopedTrack track2 {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedListen listen1 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedRelease release1 {session, "MyRelease1"};
ScopedRelease release2 {session, "MyRelease2"};
{
auto transaction {session.createSharedTransaction()};
track1.get().modify()->setRelease(release1.get());
track2.get().modify()->setRelease(release2.get());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results[0], release1.getId());
}
ScopedListen listen2 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedListen listen3 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], release2.getId());
EXPECT_EQ(releases.results[1], release1.getId());
}
ScopedListen listen4 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedListen listen5 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], release1.getId());
EXPECT_EQ(releases.results[1], release2.getId());
}
}
TEST_F(DatabaseFixture, Listen_getTopReleases_cluster)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
ScopedRelease release {session, "MyRelease"};
{
auto transaction {session.createSharedTransaction()};
track.get().modify()->setRelease(release.get());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(releases.results.size(), 0);
}
{
auto transaction {session.createUniqueTransaction()};
cluster.get().modify()->addTrack(track.get());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results[0], release.getId());
}
}
TEST_F(DatabaseFixture, Listen_getTopTracks)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 0);
}
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results[0], track.getId());
}
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getTopTracks(session, user->getId(), Scrobbler::ListenBrainz, {})};
EXPECT_EQ(tracks.moreResults, false);
EXPECT_EQ(tracks.results.size(), 0);
}
}
TEST_F(DatabaseFixture, Listen_getTopTrack_multi)
{
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedListen listen1 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results[0], track1.getId());
}
ScopedListen listen2 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedListen listen3 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], track2.getId());
EXPECT_EQ(tracks.results[1], track1.getId());
}
ScopedListen listen4 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedListen listen5 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], track1.getId());
EXPECT_EQ(tracks.results[1], track2.getId());
}
}
TEST_F(DatabaseFixture, Listen_getTopTracks_cluster)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(tracks.results.size(), 0);
}
{
auto transaction {session.createUniqueTransaction()};
cluster.get().modify()->addTrack(track.get());
}
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results[0], track.getId());
}
}
TEST_F(DatabaseFixture, Listen_getRecentArtists)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedArtist artist {session, "MyArtist"};
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track.get(), artist.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
EXPECT_EQ(artists.results.size(), 0);
EXPECT_EQ(artists.moreResults, false);
}
const Wt::WDateTime dateTime {Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1}};
ScopedListen listen1 {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results[0], artist->getId());
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::ListenBrainz, {}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 0);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, TrackArtistLinkType::Producer)};
EXPECT_EQ(artists.results.size(), 0);
}
{
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {cluster->getId()}, std::nullopt)};
EXPECT_EQ(artists.results.size(), 0);
}
}
}
TEST_F(DatabaseFixture, Listen_getRecentArtists_multi)
{
ScopedUser user {session, "MyUser"};
ScopedTrack track1 {session, "MyTrack1"};
ScopedArtist artist1 {session, "MyArtist1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedArtist artist2 {session, "MyArtist2"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track1.get(), artist1.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track2.get(), artist2.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
EXPECT_EQ(artists.results.size(), 0);
}
ScopedListen listen1 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(1)};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results[0], artist1->getId());
}
ScopedListen listen2 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(2)};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 2);
EXPECT_EQ(artists.results[0], artist2->getId());
EXPECT_EQ(artists.results[1], artist1->getId());
}
ScopedListen listen3 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(-1)};
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt, Range {0, 1})};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.moreResults, true);
EXPECT_EQ(artists.results[0], artist2->getId());
}
}
TEST_F(DatabaseFixture, Listen_getRecentArtists_cluster)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedArtist artist {session, "MyArtist"};
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track.get(), artist.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {cluster.getId()}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 0);
}
{
auto transaction {session.createUniqueTransaction()};
cluster.get().modify()->addTrack(track.get());
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {cluster.getId()}, std::nullopt)};
ASSERT_EQ(artists.results.size(), 1);
EXPECT_EQ(artists.results[0], artist.getId());
}
}
TEST_F(DatabaseFixture, Listen_getRecentReleases)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedRelease release {session, "MyRelease"};
{
auto transaction {session.createSharedTransaction()};
track.get().modify()->setRelease(release.get());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 0);
}
const Wt::WDateTime dateTime {Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1}};
ScopedListen listen1 {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results[0], release.getId());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::ListenBrainz, {})};
EXPECT_EQ(releases.moreResults, false);
EXPECT_EQ(releases.results.size(), 0);
}
}
TEST_F(DatabaseFixture, Listen_getRecentReleases_multi)
{
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedUser user {session, "MyUser"};
ScopedRelease release1 {session, "MyRelease1"};
ScopedRelease release2 {session, "MyRelease2"};
{
auto transaction {session.createSharedTransaction()};
track1.get().modify()->setRelease(release1.get());
track2.get().modify()->setRelease(release2.get());
}
const Wt::WDateTime dateTime {Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1}};
ScopedListen listen1 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results[0], release2.getId());
}
ScopedListen listen2 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(1)};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], release1.getId());
EXPECT_EQ(releases.results[1], release2.getId());
}
ScopedListen listen3 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(2)};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], release2.getId());
EXPECT_EQ(releases.results[1], release1.getId());
}
ScopedListen listen4 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(-1)};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(releases.moreResults, false);
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], release2.getId());
EXPECT_EQ(releases.results[1], release1.getId());
}
}
TEST_F(DatabaseFixture, Listen_getRecentReleases_cluster)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
ScopedRelease release {session, "MyRelease"};
{
auto transaction {session.createSharedTransaction()};
track.get().modify()->setRelease(release.get());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(releases.results.size(), 0);
}
const Wt::WDateTime dateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1}};
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(releases.results.size(), 0);
}
{
auto transaction {session.createUniqueTransaction()};
cluster.get().modify()->addTrack(track.get());
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results[0], release.getId());
}
}
TEST_F(DatabaseFixture, Listen_getRecentTracks)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 0);
}
const Wt::WDateTime dateTime {Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1}};
ScopedListen listen1 {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results[0], track.getId());
}
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::ListenBrainz, {})};
EXPECT_EQ(tracks.moreResults, false);
EXPECT_EQ(tracks.results.size(), 0);
}
}
TEST_F(DatabaseFixture, Listen_getRecentTracks_multi)
{
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1}};
ScopedListen listen1 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results[0], track2.getId());
}
ScopedListen listen2 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(1)};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], track1.getId());
EXPECT_EQ(tracks.results[1], track2.getId());
}
ScopedListen listen3 {session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(2)};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], track2.getId());
EXPECT_EQ(tracks.results[1], track1.getId());
}
ScopedListen listen4 {session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(-1)};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {})};
EXPECT_EQ(tracks.moreResults, false);
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], track2.getId());
EXPECT_EQ(tracks.results[1], track1.getId());
}
}
TEST_F(DatabaseFixture, Listen_getRecentTracks_cluster)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1}};
ScopedListen listen {session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime};
ScopedClusterType clusterType {session, "MyType"};
ScopedCluster cluster {session, clusterType.lockAndGet(), "MyCluster"};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(tracks.results.size(), 0);
}
{
auto transaction {session.createUniqueTransaction()};
cluster.get().modify()->addTrack(track.get());
}
{
auto transaction {session.createSharedTransaction()};
auto tracks {Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {cluster.getId()})};
EXPECT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results[0], track.getId());
}
}
+68 -65
View File
@@ -21,11 +21,12 @@
using namespace Database;
TEST_F(DatabaseFixture, SingleRelease)
TEST_F(DatabaseFixture, Release)
{
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(Release::getCount(session), 0);
EXPECT_FALSE(Release::exists(session, 0));
EXPECT_FALSE(Release::exists(session, 1));
}
@@ -35,20 +36,23 @@ TEST_F(DatabaseFixture, SingleRelease)
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(Release::getCount(session), 1);
EXPECT_TRUE(Release::exists(session, release.getId()));
auto releases {Release::getAllOrphans(session)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release.getId());
auto releases {Release::findOrphans(session, Range {})};
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results.front(), release.getId());
releases = Release::getAll(session);
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release.getId());
EXPECT_EQ(release->getDuration(), std::chrono::seconds {0});
{
auto releases {Release::find(session, Release::FindParameters {})};
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results.front(), release.getId());
EXPECT_EQ(release->getDuration(), std::chrono::seconds {0});
}
}
}
TEST_F(DatabaseFixture, SingleTrackSingleRelease)
TEST_F(DatabaseFixture, Release_singleTrack)
{
ScopedRelease release {session, "MyRelease"};
@@ -64,7 +68,7 @@ TEST_F(DatabaseFixture, SingleTrackSingleRelease)
{
auto transaction {session.createSharedTransaction()};
EXPECT_TRUE(Release::getAllOrphans(session).empty());
EXPECT_TRUE(Release::findOrphans(session, Range {}).results.empty());
EXPECT_EQ(release->getTracksCount(), 1);
ASSERT_EQ(release->getTracks().size(), 1);
@@ -80,19 +84,19 @@ TEST_F(DatabaseFixture, SingleTrackSingleRelease)
{
auto transaction {session.createUniqueTransaction()};
auto tracks {Track::getByNameAndReleaseName(session, "MyTrackName", "MyReleaseName")};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track.getId());
auto tracks {Track::findByNameAndReleaseName(session, "MyTrackName", "MyReleaseName")};
ASSERT_EQ(tracks.results.size(), 1);
EXPECT_EQ(tracks.results.front(), track.getId());
}
{
auto transaction {session.createUniqueTransaction()};
auto tracks {Track::getByNameAndReleaseName(session, "MyTrackName", "MyReleaseFoo")};
EXPECT_EQ(tracks.size(), 0);
auto tracks {Track::findByNameAndReleaseName(session, "MyTrackName", "MyReleaseFoo")};
EXPECT_EQ(tracks.results.size(), 0);
}
{
auto transaction {session.createUniqueTransaction()};
auto tracks {Track::getByNameAndReleaseName(session, "MyTrackFoo", "MyReleaseName")};
EXPECT_EQ(tracks.size(), 0);
auto tracks {Track::findByNameAndReleaseName(session, "MyTrackFoo", "MyReleaseName")};
EXPECT_EQ(tracks.results.size(), 0);
}
}
@@ -101,9 +105,9 @@ TEST_F(DatabaseFixture, SingleTrackSingleRelease)
EXPECT_TRUE(release->getTracks().empty());
auto releases {Release::getAllOrphans(session)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release.getId());
auto releases {Release::findOrphans(session, Range {})};
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results.front(), release.getId());
}
}
@@ -138,38 +142,37 @@ TEST_F(DatabaseFixture, MulitpleReleaseSearchByName)
{
auto transaction {session.createSharedTransaction()};
bool more;
{
const auto releases {Release::getByFilter(session, {}, {"Release"}, std::nullopt, more)};
EXPECT_EQ(releases.size(), 6);
const auto releases {Release::find(session, Release::FindParameters {}.setKeywords({"Release"}))};
EXPECT_EQ(releases.results.size(), 6);
}
{
const auto releases {Release::getByFilter(session, {}, {"MyRelease"}, std::nullopt, more)};
EXPECT_EQ(releases.size(), 5);
EXPECT_TRUE(std::none_of(std::cbegin(releases), std::cend(releases), [&](const Release::pointer& release) { return release->getId() == release6.getId(); }));
const auto releases {Release::find(session, Release::FindParameters {}.setKeywords({"MyRelease"}))};
ASSERT_EQ(releases.results.size(), 5);
EXPECT_TRUE(std::none_of(std::cbegin(releases.results), std::cend(releases.results), [&](const ReleaseId releaseId) { return releaseId == release6.getId(); }));
}
{
const auto releases {Release::getByFilter(session, {}, {"MyRelease%"}, std::nullopt, more)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release2.getId());
EXPECT_EQ(releases[1]->getId(), release4.getId());
const auto releases {Release::find(session, Release::FindParameters {}.setKeywords({"MyRelease%"}))};
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], release2.getId());
EXPECT_EQ(releases.results[1], release4.getId());
}
{
const auto releases {Release::getByFilter(session, {}, {"%MyRelease"}, std::nullopt, more)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release3.getId());
EXPECT_EQ(releases[1]->getId(), release5.getId());
const auto releases {Release::find(session, Release::FindParameters {}.setKeywords({"%MyRelease"}))};
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], release3.getId());
EXPECT_EQ(releases.results[1], release5.getId());
}
{
const auto releases {Release::getByFilter(session, {}, {"Foo%MyRelease"}, std::nullopt, more)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases[0]->getId(), release5.getId());
const auto releases {Release::find(session, Release::FindParameters {}.setKeywords({"Foo%MyRelease"}))};
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results[0], release5.getId());
}
{
const auto releases {Release::getByFilter(session, {}, {"MyRelease%Foo"}, std::nullopt, more)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases[0]->getId(), release4.getId());
const auto releases {Release::find(session, Release::FindParameters {}.setKeywords({"MyRelease%Foo"}))};
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results[0], release4.getId());
}
}
}
@@ -323,8 +326,8 @@ TEST_F(DatabaseFixture, MultiTracksSingleReleaseDate)
{
auto transaction {session.createSharedTransaction()};
const auto releases {Release::getByYear(session, 0, 3000)};
EXPECT_EQ(releases.size(), 0);
const auto releases {Release::find(session, Release::FindParameters {}.setDateRange(DateRange::fromYearRange(0, 3000)))};
EXPECT_EQ(releases.results.size(), 0);
}
{
@@ -348,48 +351,48 @@ TEST_F(DatabaseFixture, MultiTracksSingleReleaseDate)
{
auto transaction {session.createSharedTransaction()};
auto releases {Release::getByYear(session, 1950, 2000)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release1.getId());
auto releases {Release::find(session, Release::FindParameters {}.setDateRange(DateRange::fromYearRange(1950, 2000)))};
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results.front(), release1.getId());
releases = Release::getByYear(session, 1994, 1994);
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release1.getId());
releases = Release::find(session, Release::FindParameters {}.setDateRange(DateRange::fromYearRange(1994, 1994)));
ASSERT_EQ(releases.results.size(), 1);
EXPECT_EQ(releases.results.front(), release1.getId());
releases = Release::getByYear(session, 1993, 1993);
ASSERT_EQ(releases.size(), 0);
releases = Release::find(session, Release::FindParameters {}.setDateRange(DateRange::fromYearRange(1993, 1993)));
ASSERT_EQ(releases.results.size(), 0);
}
}
TEST_F(DatabaseFixture, SingleStarredRelease)
TEST_F(DatabaseFixture, Release_writtenAfter)
{
ScopedRelease release {session, "MyRelease"};
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_FALSE(user->isStarred(release.get()));
}
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 1}, Wt::WTime {12, 30, 20}};
{
auto transaction {session.createUniqueTransaction()};
track.get().modify()->setLastWriteTime(dateTime);
track.get().modify()->setRelease(release.get());
user.get().modify()->star(release.get());
}
{
auto transaction {session.createSharedTransaction()};
const auto releases {Release::find(session, Release::FindParameters {})};
EXPECT_EQ(releases.results.size(), 1);
}
EXPECT_TRUE(user->isStarred(release.get()));
{
auto transaction {session.createSharedTransaction()};
const auto releases {Release::find(session, Release::FindParameters {}.setWrittenAfter(dateTime.addSecs(-1)))};
EXPECT_EQ(releases.results.size(), 1);
}
bool hasMore {};
auto releases {Release::getStarred(session, user.get(), {}, std::nullopt, hasMore)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release.getId());
EXPECT_FALSE(hasMore);
{
auto transaction {session.createSharedTransaction()};
const auto releases {Release::find(session, Release::FindParameters {}.setWrittenAfter(dateTime.addSecs(+1)))};
EXPECT_EQ(releases.results.size(), 0);
}
}
@@ -0,0 +1,109 @@
/*
* Copyright (C) 2021 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Common.hpp"
#include "services/database/StarredArtist.hpp"
using namespace Database;
using ScopedStarredArtist = ScopedEntity<Database::StarredArtist>;
TEST_F(DatabaseFixture, StarredArtist)
{
ScopedArtist artist {session, "MyArtist"};
ScopedUser user {session, "MyUser"};
ScopedUser user2 {session, "MyUser2"};
{
auto transaction {session.createSharedTransaction()};
auto starredArtist {StarredArtist::find(session, artist->getId(), user->getId(), Scrobbler::Internal)};
EXPECT_FALSE(starredArtist);
EXPECT_EQ(StarredArtist::getCount(session), 0);
auto artists {Artist::find(session, Artist::FindParameters {})};
EXPECT_EQ(artists.results.size(), 1);
}
ScopedStarredArtist starredArtist {session, artist.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
{
auto transaction {session.createSharedTransaction()};
auto gotArtist {StarredArtist::find(session, artist->getId(), user->getId(), Scrobbler::Internal)};
EXPECT_EQ(gotArtist->getId(), starredArtist->getId());
EXPECT_EQ(StarredArtist::getCount(session), 1);
}
{
auto transaction {session.createSharedTransaction()};
auto artists {Artist::find(session, Artist::FindParameters {})};
EXPECT_EQ(artists.results.size(), 1);
artists = Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
EXPECT_EQ(artists.results.size(), 1);
artists = Artist::find(session, Artist::FindParameters {}.setStarringUser(user2.getId(), Scrobbler::Internal));
EXPECT_EQ(artists.results.size(), 0);
}
}
TEST_F(DatabaseFixture, StarredArtist_dateTime)
{
ScopedArtist artist1 {session, "MyArtist1"};
ScopedArtist artist2 {session, "MyArtist2"};
ScopedUser user {session, "MyUser"};
ScopedStarredArtist starredArtist1 {session, artist1.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
ScopedStarredArtist starredArtist2 {session, artist2.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1}};
{
auto transaction {session.createSharedTransaction()};
auto artists {Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
EXPECT_EQ(artists.results.size(), 2);
}
{
auto transaction {session.createUniqueTransaction()};
starredArtist1.get().modify()->setDateTime(dateTime);
starredArtist2.get().modify()->setDateTime(dateTime.addSecs(-1));
auto artists {Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
.setSortMethod(ArtistSortMethod::StarredDateDesc))};
ASSERT_EQ(artists.results.size(), 2);
EXPECT_EQ(artists.results[0], starredArtist1->getArtist()->getId());
EXPECT_EQ(artists.results[1], starredArtist2->getArtist()->getId());
}
{
auto transaction {session.createUniqueTransaction()};
starredArtist1.get().modify()->setDateTime(dateTime);
starredArtist2.get().modify()->setDateTime(dateTime.addSecs(1));
auto artists {Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
.setSortMethod(ArtistSortMethod::StarredDateDesc))};
ASSERT_EQ(artists.results.size(), 2);
EXPECT_EQ(artists.results[0], starredArtist2->getArtist()->getId());
EXPECT_EQ(artists.results[1], starredArtist1->getArtist()->getId());
}
}
@@ -0,0 +1,109 @@
/*
* Copyright (C) 2021 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Common.hpp"
#include "services/database/StarredRelease.hpp"
using namespace Database;
using ScopedStarredRelease = ScopedEntity<Database::StarredRelease>;
TEST_F(DatabaseFixture, StarredRelease)
{
ScopedRelease release {session, "MyRelease"};
ScopedUser user {session, "MyUser"};
ScopedUser user2 {session, "MyUser2"};
{
auto transaction {session.createSharedTransaction()};
auto starredRelease {StarredRelease::find(session, release->getId(), user->getId(), Scrobbler::Internal)};
EXPECT_FALSE(starredRelease);
EXPECT_EQ(StarredRelease::getCount(session), 0);
auto releases {Release::find(session, Release::FindParameters {})};
EXPECT_EQ(releases.results.size(), 1);
}
ScopedStarredRelease starredRelease {session, release.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
{
auto transaction {session.createSharedTransaction()};
auto gotRelease {StarredRelease::find(session, release->getId(), user->getId(), Scrobbler::Internal)};
EXPECT_EQ(gotRelease->getId(), starredRelease->getId());
EXPECT_EQ(StarredRelease::getCount(session), 1);
}
{
auto transaction {session.createSharedTransaction()};
auto releases {Release::find(session, Release::FindParameters {})};
EXPECT_EQ(releases.results.size(), 1);
releases = Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
EXPECT_EQ(releases.results.size(), 1);
releases = Release::find(session, Release::FindParameters {}.setStarringUser(user2.getId(), Scrobbler::Internal));
EXPECT_EQ(releases.results.size(), 0);
}
}
TEST_F(DatabaseFixture, StarredRelease_dateTime)
{
ScopedRelease release1 {session, "MyRelease1"};
ScopedRelease release2 {session, "MyRelease2"};
ScopedUser user {session, "MyUser"};
ScopedStarredRelease starredRelease1 {session, release1.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
ScopedStarredRelease starredRelease2 {session, release2.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1}};
{
auto transaction {session.createSharedTransaction()};
auto releases {Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
EXPECT_EQ(releases.results.size(), 2);
}
{
auto transaction {session.createUniqueTransaction()};
starredRelease1.get().modify()->setDateTime(dateTime);
starredRelease2.get().modify()->setDateTime(dateTime.addSecs(-1));
auto releases {Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
.setSortMethod(ReleaseSortMethod::StarredDateDesc))};
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], starredRelease1->getRelease()->getId());
EXPECT_EQ(releases.results[1], starredRelease2->getRelease()->getId());
}
{
auto transaction {session.createUniqueTransaction()};
starredRelease1.get().modify()->setDateTime(dateTime);
starredRelease2.get().modify()->setDateTime(dateTime.addSecs(1));
auto releases {Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
.setSortMethod(ReleaseSortMethod::StarredDateDesc))};
ASSERT_EQ(releases.results.size(), 2);
EXPECT_EQ(releases.results[0], starredRelease2->getRelease()->getId());
EXPECT_EQ(releases.results[1], starredRelease1->getRelease()->getId());
}
}
@@ -0,0 +1,109 @@
/*
* Copyright (C) 2021 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Common.hpp"
#include "services/database/StarredTrack.hpp"
using namespace Database;
using ScopedStarredTrack = ScopedEntity<Database::StarredTrack>;
TEST_F(DatabaseFixture, StarredTrack)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
ScopedUser user2 {session, "MyUser2"};
{
auto transaction {session.createSharedTransaction()};
auto starredTrack {StarredTrack::find(session, track->getId(), user->getId(), Scrobbler::Internal)};
EXPECT_FALSE(starredTrack);
EXPECT_EQ(StarredTrack::getCount(session), 0);
auto tracks {Track::find(session, Track::FindParameters {})};
EXPECT_EQ(tracks.results.size(), 1);
}
ScopedStarredTrack starredTrack {session, track.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
{
auto transaction {session.createSharedTransaction()};
auto gotTrack {StarredTrack::find(session, track->getId(), user->getId(), Scrobbler::Internal)};
EXPECT_EQ(gotTrack->getId(), starredTrack->getId());
EXPECT_EQ(StarredTrack::getCount(session), 1);
}
{
auto transaction {session.createSharedTransaction()};
auto tracks {Track::find(session, Track::FindParameters {})};
EXPECT_EQ(tracks.results.size(), 1);
tracks = Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
EXPECT_EQ(tracks.results.size(), 1);
tracks = Track::find(session, Track::FindParameters {}.setStarringUser(user2.getId(), Scrobbler::Internal));
EXPECT_EQ(tracks.results.size(), 0);
}
}
TEST_F(DatabaseFixture, StarredTrack_dateTime)
{
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedUser user {session, "MyUser"};
ScopedStarredTrack starredTrack1 {session, track1.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
ScopedStarredTrack starredTrack2 {session, track2.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1}};
{
auto transaction {session.createSharedTransaction()};
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
EXPECT_EQ(tracks.results.size(), 2);
}
{
auto transaction {session.createUniqueTransaction()};
starredTrack1.get().modify()->setDateTime(dateTime);
starredTrack2.get().modify()->setDateTime(dateTime.addSecs(-1));
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
.setSortMethod(TrackSortMethod::StarredDateDesc))};
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], starredTrack1->getTrack()->getId());
EXPECT_EQ(tracks.results[1], starredTrack2->getTrack()->getId());
}
{
auto transaction {session.createUniqueTransaction()};
starredTrack1.get().modify()->setDateTime(dateTime);
starredTrack2.get().modify()->setDateTime(dateTime.addSecs(1));
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
.setSortMethod(TrackSortMethod::StarredDateDesc))};
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], starredTrack2->getTrack()->getId());
EXPECT_EQ(tracks.results[1], starredTrack1->getTrack()->getId());
}
}
+34 -37
View File
@@ -23,10 +23,11 @@
using namespace Database;
TEST_F(DatabaseFixture, SingleTrack)
TEST_F(DatabaseFixture, Track)
{
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(Track::find(session, Track::FindParameters {}).results.size(), 0);
EXPECT_EQ(Track::getCount(session), 0);
EXPECT_FALSE(Track::exists(session, 0));
}
@@ -36,16 +37,16 @@ TEST_F(DatabaseFixture, SingleTrack)
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(Track::getAll(session).size(), 1);
EXPECT_EQ(Track::find(session, Track::FindParameters {}).results.size(), 1);
EXPECT_EQ(Track::getCount(session), 1);
EXPECT_TRUE(Track::exists(session, track.getId()));
auto myTrack {Track::getById(session, track.getId())};
auto myTrack {Track::find(session, track.getId())};
ASSERT_TRUE(myTrack);
EXPECT_EQ(myTrack->getId(), track.getId());
}
}
TEST_F(DatabaseFixture, MultipleTracksSearchByFilter)
TEST_F(DatabaseFixture, Track_findByKeywords)
{
ScopedTrack track1 {session, ""};
ScopedTrack track2 {session, ""};
@@ -67,32 +68,31 @@ TEST_F(DatabaseFixture, MultipleTracksSearchByFilter)
{
auto transaction {session.createSharedTransaction()};
bool more;
{
const auto tracks {Track::getByFilter(session, {}, {"Track"}, std::nullopt, more)};
EXPECT_EQ(tracks.size(), 6);
const auto tracks {Track::find(session, Track::FindParameters {}.setKeywords({"Track"}))};
EXPECT_EQ(tracks.results.size(), 6);
}
{
const auto tracks {Track::getByFilter(session, {}, {"MyTrack"}, std::nullopt, more)};
EXPECT_EQ(tracks.size(), 5);
EXPECT_TRUE(std::none_of(std::cbegin(tracks), std::cend(tracks), [&](const Track::pointer& track) { return track->getId() == track6.getId(); }));
const auto tracks {Track::find(session, Track::FindParameters {}.setKeywords({"MyTrack"}))};
EXPECT_EQ(tracks.results.size(), 5);
EXPECT_TRUE(std::none_of(std::cbegin(tracks.results), std::cend(tracks.results), [&](const TrackId trackId) { return trackId == track6.getId(); }));
}
{
const auto tracks {Track::getByFilter(session, {}, {"MyTrack%"}, std::nullopt, more)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track2.getId());
EXPECT_EQ(tracks[1]->getId(), track3.getId());
const auto tracks {Track::find(session, Track::FindParameters {}.setKeywords({"MyTrack%"}))};
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], track2.getId());
EXPECT_EQ(tracks.results[1], track3.getId());
}
{
const auto tracks {Track::getByFilter(session, {}, {"%MyTrack"}, std::nullopt, more)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track4.getId());
EXPECT_EQ(tracks[1]->getId(), track5.getId());
const auto tracks {Track::find(session, Track::FindParameters {}.setKeywords({"%MyTrack"}))};
ASSERT_EQ(tracks.results.size(), 2);
EXPECT_EQ(tracks.results[0], track4.getId());
EXPECT_EQ(tracks.results[1], track5.getId());
}
}
}
TEST_F(DatabaseFixture, SingleTrackDate)
TEST_F(DatabaseFixture, Track_date)
{
ScopedTrack track {session, "MyTrack"};
@@ -115,36 +115,33 @@ TEST_F(DatabaseFixture, SingleTrackDate)
}
}
TEST_F(DatabaseFixture, SingleStarredTrack)
TEST_F(DatabaseFixture, Track_writtenAfter)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 1}, Wt::WTime {12, 30, 20}};
{
auto transaction {session.createUniqueTransaction()};
EXPECT_FALSE(user->isStarred(track.get()));
track.get().modify()->setLastWriteTime(dateTime);
}
{
auto transaction {session.createUniqueTransaction()};
user.get().modify()->star(track.get());
auto transaction {session.createSharedTransaction()};
const auto tracks {Track::find(session, Track::FindParameters {})};
EXPECT_EQ(tracks.results.size(), 1);
}
{
auto transaction {session.createUniqueTransaction()};
auto transaction {session.createSharedTransaction()};
const auto tracks {Track::find(session, Track::FindParameters {}.setWrittenAfter(dateTime.addSecs(-1)))};
EXPECT_EQ(tracks.results.size(), 1);
}
EXPECT_TRUE(user->isStarred(track.get()));
bool hasMore {};
auto tracks {Track::getStarred(session, user.get(), {}, std::nullopt, hasMore)};
ASSERT_EQ(tracks.size(), 1);
EXPECT_EQ(tracks.front()->getId(), track.getId());
EXPECT_FALSE(hasMore);
{
auto transaction {session.createSharedTransaction()};
const auto tracks {Track::find(session, Track::FindParameters {}.setWrittenAfter(dateTime.addSecs(+1)))};
EXPECT_EQ(tracks.results.size(), 0);
}
}
@@ -0,0 +1,66 @@
/*
* Copyright (C) 2021 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Common.hpp"
#include "services/database/TrackBookmark.hpp"
using ScopedTrackBookmark = ScopedEntity<Database::TrackBookmark>;
using namespace Database;
TEST_F(DatabaseFixture, TrackBookmark)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(TrackBookmark::getCount(session), 0);
}
ScopedTrackBookmark bookmark {session, user.lockAndGet(), track.lockAndGet()};
{
auto transaction {session.createUniqueTransaction()};
bookmark.get().modify()->setComment("MyComment");
bookmark.get().modify()->setOffset(std::chrono::milliseconds {5});
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(TrackBookmark::getCount(session), 1);
const auto bookmarks {TrackBookmark::find(session, user.getId(), Range {})};
ASSERT_EQ(bookmarks.results.size(), 1);
EXPECT_EQ(bookmarks.results.front(), bookmark.getId());
}
{
auto transaction {session.createSharedTransaction()};
auto userBookmark {TrackBookmark::find(session, user.getId(), track.getId())};
ASSERT_TRUE(userBookmark);
EXPECT_EQ(userBookmark, bookmark.get());
EXPECT_EQ(userBookmark->getOffset(), std::chrono::milliseconds {5});
EXPECT_EQ(userBookmark->getComment(), "MyComment");
}
}
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2021 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Common.hpp"
#include "services/database/TrackFeatures.hpp"
using ScopedTrackFeatures = ScopedEntity<Database::TrackFeatures>;
using namespace Database;
TEST_F(DatabaseFixture, TrackFeatures)
{
ScopedTrack track {session, "MyTrack"};
ScopedUser user {session, "MyUser"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(TrackFeatures::getCount(session), 0);
}
ScopedTrackFeatures trackFeatures {session, track.lockAndGet(), ""};
{
auto transaction {session.createUniqueTransaction()};
EXPECT_EQ(TrackFeatures::getCount(session), 1);
auto allTrackFeatures {TrackFeatures::find(session, Range {})};
ASSERT_EQ(allTrackFeatures.results.size(), 1);
EXPECT_EQ(allTrackFeatures.results.front(), trackFeatures.getId());
}
}
@@ -0,0 +1,366 @@
/*
* Copyright (C) 2019 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <list>
#include "Common.hpp"
using namespace Database;
TEST_F(DatabaseFixture, SingleTrackList)
{
ScopedUser user {session, "MyUser"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(TrackList::getCount(session), 0);
}
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(TrackList::getCount(session), 1);
}
}
TEST_F(DatabaseFixture, SingleTrackListMultipleTrack)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
std::list<ScopedTrack> tracks;
for (std::size_t i {}; i < 10; ++i)
{
tracks.emplace_back(session, "MyTrack" + std::to_string(i));
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, tracks.back().get(), trackList.get());
}
{
auto transaction {session.createSharedTransaction()};
ASSERT_EQ(trackList->getCount(), tracks.size());
const auto trackIds {trackList->getTrackIds()};
ASSERT_EQ(trackIds.size(), tracks.size());
// Same order
std::size_t i {};
for (const ScopedTrack& track : tracks)
EXPECT_EQ(track.getId(), trackIds[i++]);
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto reverseTracks {trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(reverseTracks.size(), tracks.size());
// Reverse order
ASSERT_TRUE(tracks.size() > 0);
std::size_t i {tracks.size() - 1};
for (const ScopedTrack& track : tracks)
EXPECT_EQ(track.getId(), reverseTracks[i--]->getId());
}
}
TEST_F(DatabaseFixture, SingleTrackListMultipleTrackDateTime)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedTrack track3 {session, "MyTrack3"};
{
Wt::WDateTime now {Wt::WDateTime::currentDateTime()};
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track1.get(), trackList.get(), now);
TrackListEntry::create(session, track2.get(), trackList.get(), now.addSecs(-1));
TrackListEntry::create(session, track3.get(), trackList.get(), now.addSecs(1));
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults;
const auto tracks {trackList.get()->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 3);
EXPECT_EQ(tracks.front()->getId(), track3.getId());
EXPECT_EQ(tracks.back()->getId(), track2.getId());
}
}
TEST_F(DatabaseFixture, SingleTrackListMultipleTrackRecentlyPlayed)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MyTrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack1"};
ScopedArtist artist1 {session, "MyArtist1"};
ScopedArtist artist2 {session, "MyArtist2"};
ScopedRelease release1 {session, "MyRelease1"};
ScopedRelease release2 {session, "MyRelease2"};
const Wt::WDateTime now {Wt::WDateTime::currentDateTime()};
{
auto transaction {session.createUniqueTransaction()};
track1.get().modify()->setRelease(release1.get());
track2.get().modify()->setRelease(release2.get());
TrackArtistLink::create(session, track1.get(), artist1.get(), TrackArtistLinkType::Artist);
TrackArtistLink::create(session, track2.get(), artist2.get(), TrackArtistLinkType::Artist);
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
EXPECT_TRUE(trackList->getArtistsOrderedByRecentFirst({}, std::nullopt, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getReleasesOrderedByRecentFirst({}, std::nullopt, moreResults).empty());
EXPECT_TRUE(trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults).empty());
}
{
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track1.get(), trackList.get(), now);
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsOrderedByRecentFirst({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
const auto releases {trackList->getReleasesOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front()->getId(), release1.getId());
const auto tracks {trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults)};
EXPECT_EQ(tracks.size(), 1);
}
{
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track2.get(), trackList.get(), now.addSecs(1));
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsOrderedByRecentFirst({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist2.getId());
EXPECT_EQ(artists[1]->getId(), artist1.getId());
const auto releases {trackList->getReleasesOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release2.getId());
EXPECT_EQ(releases[1]->getId(), release1.getId());
const auto tracks {trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track2.getId());
EXPECT_EQ(tracks[1]->getId(), track1.getId());
}
{
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track1.get(), trackList.get(), now.addSecs(2));
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtistsOrderedByRecentFirst({}, std::nullopt, std::nullopt, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists[0]->getId(), artist1.getId());
EXPECT_EQ(artists[1]->getId(), artist2.getId());
const auto releases {trackList->getReleasesOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(releases.size(), 2);
EXPECT_EQ(releases[0]->getId(), release1.getId());
EXPECT_EQ(releases[1]->getId(), release2.getId());
const auto tracks {trackList->getTracksOrderedByRecentFirst({}, std::nullopt, moreResults)};
ASSERT_EQ(tracks.size(), 2);
EXPECT_EQ(tracks[0]->getId(), track1.getId());
EXPECT_EQ(tracks[1]->getId(), track2.getId());
}
}
TEST_F(DatabaseFixture, SingleTrackList_getArtists)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack2"};
ScopedRelease release {session, "MyRelease"};
ScopedArtist artist1 {session, "MyArtist1"};
ScopedArtist artist2 {session, "MyArtist2"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(trackList->getCount(), 0);
bool moreResults {};
const auto artists {trackList->getArtists({} /*clusters*/, std::nullopt /* linkType */, ArtistSortMethod::ByName, std::nullopt /* range */, moreResults)};
ASSERT_TRUE(artists.empty());
}
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track1.get(), artist1.get(), TrackArtistLinkType::Artist);
TrackListEntry::create(session, track1.get(), trackList.get());
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(trackList->getCount(), 1);
bool moreResults {};
const auto artists {trackList->getArtists({} /*clusters*/, std::nullopt /* linkType */, ArtistSortMethod::ByName, std::nullopt /* range */, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtists({} /*clusters*/, TrackArtistLinkType::ReleaseArtist, ArtistSortMethod::ByName, std::nullopt /* range */, moreResults)};
EXPECT_TRUE(artists.empty());
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtists({} /*clusters*/, TrackArtistLinkType::Artist, ArtistSortMethod::ByName, std::nullopt /* range */, moreResults)};
ASSERT_EQ(artists.size(), 1);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
}
{
auto transaction {session.createUniqueTransaction()};
TrackArtistLink::create(session, track2.get(), artist2.get(), TrackArtistLinkType::Artist);
TrackListEntry::create(session, track2.get(), trackList.get());
artist1.get().modify()->setSortName("ZZZ");
artist2.get().modify()->setSortName("AAA");
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtists({} /*clusters*/, TrackArtistLinkType::Artist, ArtistSortMethod::ByName, std::nullopt /* range */, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists.front()->getId(), artist1.getId());
EXPECT_EQ(artists.back()->getId(), artist2.getId());
}
{
auto transaction {session.createSharedTransaction()};
bool moreResults {};
const auto artists {trackList->getArtists({} /*clusters*/, TrackArtistLinkType::Artist, ArtistSortMethod::BySortName, std::nullopt /* range */, moreResults)};
ASSERT_EQ(artists.size(), 2);
EXPECT_EQ(artists.front()->getId(), artist2.getId());
EXPECT_EQ(artists.back()->getId(), artist1.getId());
}
}
TEST_F(DatabaseFixture, SingleTrackList_getReleases)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
ScopedTrack track {session, "MyTrack"};
ScopedRelease release {session, "MyRelease"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(trackList->getCount(), 0);
bool moreResults {};
const auto releases {trackList->getReleases({} /*clusters*/, std::nullopt /* range */, moreResults)};
ASSERT_TRUE(releases.empty());
}
{
auto transaction {session.createUniqueTransaction()};
track.get().modify()->setRelease(release.get());
TrackListEntry::create(session, track.get(), trackList.get());
}
{
auto transaction {session.createSharedTransaction()};
ASSERT_EQ(trackList->getCount(), 1);
bool moreResults {};
const auto releases {trackList->getReleases({} /*clusters*/, std::nullopt /* range */, moreResults)};
ASSERT_EQ(releases.size(), 1);
ASSERT_EQ(releases.front()->getId(), release->getId());
}
}
TEST_F(DatabaseFixture, SingleTrackList_getTracks)
{
ScopedUser user {session, "MyUser"};
ScopedTrackList trackList {session, "MytrackList", TrackList::Type::Playlist, false, user.lockAndGet()};
ScopedTrack track1 {session, "MyTrack1"};
ScopedTrack track2 {session, "MyTrack1"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(trackList->getCount(), 0);
bool moreResults {};
const auto tracks {trackList->getTracks({} /*clusters*/, std::nullopt /* range */, moreResults)};
ASSERT_TRUE(tracks.empty());
}
{
auto transaction {session.createUniqueTransaction()};
TrackListEntry::create(session, track1.get(), trackList.get());
TrackListEntry::create(session, track2.get(), trackList.get());
TrackListEntry::create(session, track1.get(), trackList.get());
}
{
auto transaction {session.createSharedTransaction()};
ASSERT_EQ(trackList->getCount(), 3);
bool moreResults {};
const auto tracks {trackList->getTracks({} /*clusters*/, std::nullopt /* range */, moreResults)};
ASSERT_EQ(tracks.size(), 2);
ASSERT_EQ(tracks[0]->getId(), track1->getId());
ASSERT_EQ(tracks[1]->getId(), track2->getId());
}
}