diff options
Diffstat (limited to 'pse-server/src/test/java/org/psesquared/server/episode')
3 files changed, 417 insertions, 0 deletions
diff --git a/pse-server/src/test/java/org/psesquared/server/episode/actions/api/data/access/EpisodeActionDaoTests.java b/pse-server/src/test/java/org/psesquared/server/episode/actions/api/data/access/EpisodeActionDaoTests.java new file mode 100644 index 0000000..3448330 --- /dev/null +++ b/pse-server/src/test/java/org/psesquared/server/episode/actions/api/data/access/EpisodeActionDaoTests.java @@ -0,0 +1,20 @@ +package org.psesquared.server.episode.actions.api.data.access; + +import org.junit.jupiter.api.Test; +import org.psesquared.server.BaseTest; +import org.psesquared.server.model.User; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class EpisodeActionDaoTests extends BaseTest { + + @Test + public void deleteUserTest() { + String username = "testUser0"; + User user = authenticationDao.findByUsername(username).orElseThrow(); + assertEquals(numberOfEpisodesPerSubscription * numberOfSubscriptionsPerUser, episodeActionDao.findByUserUsername(username).size()); + authenticationDao.delete(user); + assertEquals(0, episodeActionDao.findByUserUsername(username).size()); + } + +} diff --git a/pse-server/src/test/java/org/psesquared/server/episode/actions/api/data/access/EpisodeDaoTests.java b/pse-server/src/test/java/org/psesquared/server/episode/actions/api/data/access/EpisodeDaoTests.java new file mode 100644 index 0000000..6c1d70f --- /dev/null +++ b/pse-server/src/test/java/org/psesquared/server/episode/actions/api/data/access/EpisodeDaoTests.java @@ -0,0 +1,29 @@ +package org.psesquared.server.episode.actions.api.data.access; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.File; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.psesquared.server.BaseTest; +import org.psesquared.server.model.Subscription; + +public class EpisodeDaoTests extends BaseTest { + + @Test + public void deleteCascadeTest() { + String username = "testUser0"; + assertDoesNotThrow(() -> authenticationDao.findByUsername(username).orElseThrow()); + String subscriptionsUrl = new File("testfeeds/testPodcast0.xml").toURI().toString(); + Subscription subscription = subscriptionDao.findByUrl(subscriptionsUrl).orElseThrow(); + assertDoesNotThrow(() -> subscription.getEpisodes()); + Assertions.assertEquals(numberOfEpisodesPerSubscription, + episodeActionDao.findByUserUsernameAndEpisodeSubscriptionUrl(username, subscriptionsUrl).size()); + episodeDao.deleteAll(subscription.getEpisodes()); + Assertions.assertEquals(0, + episodeActionDao.findByUserUsernameAndEpisodeSubscriptionUrl(username, subscriptionsUrl).size()); + } + +} diff --git a/pse-server/src/test/java/org/psesquared/server/episode/actions/api/service/EpisodeActionServiceTests.java b/pse-server/src/test/java/org/psesquared/server/episode/actions/api/service/EpisodeActionServiceTests.java new file mode 100644 index 0000000..75dd110 --- /dev/null +++ b/pse-server/src/test/java/org/psesquared/server/episode/actions/api/service/EpisodeActionServiceTests.java @@ -0,0 +1,368 @@ +package org.psesquared.server.episode.actions.api.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.psesquared.server.BaseTest; +import org.psesquared.server.episode.actions.api.controller.EpisodeActionPost; +import org.psesquared.server.model.Action; +import org.psesquared.server.model.Episode; +import org.psesquared.server.model.EpisodeAction; +import org.psesquared.server.model.Subscription; +import org.psesquared.server.model.User; +import org.springframework.beans.factory.annotation.Autowired; + +public class EpisodeActionServiceTests extends BaseTest { + + @Autowired + private EpisodeActionService episodeActionService; + + @Test + public void addEpisodeActionsTest1() { + // episodeActionPosts zu Subscriptions und Episoden hinzufügen, die noch nicht + // existieren + List<EpisodeActionPost> episodeActionPosts = new ArrayList<>(); + String username = "testUser0"; + Assertions.assertEquals(numberOfEpisodesPerSubscription * numberOfSubscriptionsPerUser, + episodeActionDao.findByUserUsername(username).size()); + int numberOfNewEpisodes = 2; + for (int i = 0; i < numberOfNewEpisodes; i++) { + episodeActionPosts.add(EpisodeActionPost.builder() + .podcastUrl(new File("testfeeds/newTestSubscription1.xml").toURI().toString()) + .episodeUrl(String.format("/testfeeds/newTestSubscription1/episode%d.mp3", i)) + .title("testEpisode" + i) + .guid(UUID.randomUUID().toString()) + .total(10 * i) + .episodeAction(EpisodeAction.builder() + .timestamp(LocalDateTime.now()) + .action(Action.PLAY) + .started(i) + .position(i + 3) + .build()) + .build()); + } + episodeActionService.addEpisodeActions(username, episodeActionPosts); + + Assertions.assertEquals(numberOfSubscriptionsPerUser * numberOfEpisodesPerSubscription + numberOfNewEpisodes, + episodeActionDao.findByUserUsername(username).size()); + } + + @Test + public void addEpisodeActionsTest2() { + // Alte EpisodeAction durch neuere Überschreiben + + final String username = "testUser0"; + final String episodeUrl = "/testfeeds/testPodcast0/episode0.mp3"; + final User user = authenticationDao.findByUsername(username).orElseThrow(); + + EpisodeAction oldEpisodeActionTest = episodeActionDao + .findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY).orElseThrow(); + List<EpisodeActionPost> episodeActionPosts = new ArrayList<>(); + episodeActionPosts.add(EpisodeActionPost.builder() + .podcastUrl(oldEpisodeActionTest.getEpisode().getSubscription().getUrl()) + .episodeUrl(oldEpisodeActionTest.getEpisode().getUrl()) + .title(oldEpisodeActionTest.getEpisode().getTitle()) + .guid(oldEpisodeActionTest.getEpisode().getGuid()) + .total(oldEpisodeActionTest.getEpisode().getTotal()) + .episodeAction(EpisodeAction.builder() + .timestamp(LocalDateTime.ofEpochSecond( + oldEpisodeActionTest.getTimestamp().toEpochSecond(ZoneOffset.UTC) + 1, + 0, + ZoneOffset.UTC)) + .action(Action.PLAY) + .started(oldEpisodeActionTest.getStarted()) + .position(oldEpisodeActionTest.getPosition()) + .build()) + .build()); + + LocalDateTime oldTimestamp = episodeActionDao.findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY) + .orElseThrow().getTimestamp(); + episodeActionService.addEpisodeActions(user.getUsername(), episodeActionPosts); + LocalDateTime newTimestamp = episodeActionDao.findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY) + .orElseThrow().getTimestamp(); + assertNotEquals(oldTimestamp, newTimestamp); + } + + @Test + public void addEpisodeActionTest3() { + // EpisodeActions nicht nach Timestamp sortiert + // Überschreibe EpisodeAction durch neueste Action + + final String username = "testUser0"; + final String episodeUrl = "/testfeeds/testPodcast0/episode0.mp3"; + final User user = authenticationDao.findByUsername(username).orElseThrow(); + + EpisodeAction oldEpisodeActionTest = episodeActionDao + .findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY).orElseThrow(); + List<EpisodeActionPost> episodeActionPosts = new ArrayList<>(); + episodeActionPosts.add(EpisodeActionPost.builder() + .podcastUrl(oldEpisodeActionTest.getEpisode().getSubscription().getUrl()) + .episodeUrl(oldEpisodeActionTest.getEpisode().getUrl()) + .title(oldEpisodeActionTest.getEpisode().getTitle()) + .guid(oldEpisodeActionTest.getEpisode().getGuid()) + .total(oldEpisodeActionTest.getEpisode().getTotal()) + .episodeAction(EpisodeAction.builder() + .timestamp(LocalDateTime.ofEpochSecond( + oldEpisodeActionTest.getTimestamp().toEpochSecond(ZoneOffset.UTC) + 2, + 0, + ZoneOffset.UTC)) + .action(Action.PLAY) + .started(oldEpisodeActionTest.getStarted()) + .position(oldEpisodeActionTest.getPosition()) + .build()) + .build()); + + episodeActionPosts.add(EpisodeActionPost.builder() + .podcastUrl(oldEpisodeActionTest.getEpisode().getSubscription().getUrl()) + .episodeUrl(oldEpisodeActionTest.getEpisode().getUrl()) + .title(oldEpisodeActionTest.getEpisode().getTitle()) + .guid(oldEpisodeActionTest.getEpisode().getGuid()) + .total(oldEpisodeActionTest.getEpisode().getTotal()) + .episodeAction(EpisodeAction.builder() + .timestamp(LocalDateTime.ofEpochSecond( + oldEpisodeActionTest.getTimestamp().toEpochSecond(ZoneOffset.UTC) + 1, + 0, + ZoneOffset.UTC)) + .action(Action.PLAY) + .started(oldEpisodeActionTest.getStarted()) + .position(oldEpisodeActionTest.getPosition()) + .build()) + .build()); + + episodeActionPosts.add(EpisodeActionPost.builder() + .podcastUrl(oldEpisodeActionTest.getEpisode().getSubscription().getUrl()) + .episodeUrl(oldEpisodeActionTest.getEpisode().getUrl()) + .title(oldEpisodeActionTest.getEpisode().getTitle()) + .guid(oldEpisodeActionTest.getEpisode().getGuid()) + .total(oldEpisodeActionTest.getEpisode().getTotal()) + .episodeAction(EpisodeAction.builder() + .timestamp(LocalDateTime.ofEpochSecond( + oldEpisodeActionTest.getTimestamp().toEpochSecond(ZoneOffset.UTC) + 3, + 0, + ZoneOffset.UTC)) + .action(Action.PLAY) + .started(oldEpisodeActionTest.getStarted()) + .position(oldEpisodeActionTest.getPosition()) + .build()) + .build()); + + LocalDateTime oldTimestamp = episodeActionDao.findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY) + .orElseThrow().getTimestamp(); + episodeActionService.addEpisodeActions(user.getUsername(), episodeActionPosts); + LocalDateTime newTimestamp = episodeActionDao.findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY) + .orElseThrow().getTimestamp(); + assertTrue(newTimestamp.isAfter(oldTimestamp)); + assertEquals(3, (int) ChronoUnit.SECONDS.between(oldTimestamp, newTimestamp)); + } + + @Test + public void addEpisodeActionsTest4() { + // Ignoriere Episode Action, die nicht PLAY als Action hat + + final String username = "testUser0"; + final String episodeUrl = "/testfeeds/testPodcast0/episode0.mp3"; + final User user = authenticationDao.findByUsername(username).orElseThrow(); + + EpisodeAction oldEpisodeActionTest = episodeActionDao + .findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY).orElseThrow(); + List<EpisodeActionPost> episodeActionPosts = new ArrayList<>(); + episodeActionPosts.add(EpisodeActionPost.builder() + .podcastUrl(oldEpisodeActionTest.getEpisode().getSubscription().getUrl()) + .episodeUrl(oldEpisodeActionTest.getEpisode().getUrl()) + .title(oldEpisodeActionTest.getEpisode().getTitle()) + .guid(oldEpisodeActionTest.getEpisode().getGuid()) + .total(oldEpisodeActionTest.getEpisode().getTotal()) + .episodeAction(EpisodeAction.builder() + .timestamp(LocalDateTime.ofEpochSecond( + oldEpisodeActionTest.getTimestamp().toEpochSecond(ZoneOffset.UTC) + 1, + 0, + ZoneOffset.UTC)) + .action(Action.DOWNLOAD) + .started(oldEpisodeActionTest.getStarted()) + .position(oldEpisodeActionTest.getPosition()) + .build()) + .build()); + + LocalDateTime oldTimestamp = episodeActionDao.findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY) + .orElseThrow().getTimestamp(); + episodeActionService.addEpisodeActions(user.getUsername(), episodeActionPosts); + LocalDateTime newTimestamp = episodeActionDao.findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY) + .orElseThrow().getTimestamp(); + assertEquals(oldTimestamp, newTimestamp); + } + + @Test + public void addEpisodeActionsTest5() { + // Episode in Datenbank ohne GUID, EpisodeAction mit selbem Link mit GUID + + final String username = "testUser0"; + final String podcastName = new File("testfeeds/testPodcast0.xml").toURI().toString(); + final String episodeBaseUrl = "/testfeeds/testPodcast0/episode"; + final User user = authenticationDao.findByUsername(username).orElseThrow(); + + final int episodeIndex = numberOfEpisodesPerSubscription; + + // Setup - Episode ohne GUID einfügen + Optional<Subscription> savedSubscription = subscriptionDao.findByUrl(podcastName); + assertTrue(savedSubscription.isPresent()); + + final String episodeUrl = episodeBaseUrl + episodeIndex + ".mp3"; + + Episode newEpisode = new Episode(); + newEpisode.setSubscription(savedSubscription.get()); + newEpisode.setUrl(episodeUrl); + newEpisode.setTotal((episodeIndex + 1) * 100); + newEpisode.setTitle("testEpisode" + episodeIndex); + + episodeDao.save(newEpisode); + Optional<Episode> savedEpisode = episodeDao.findByUrl(episodeUrl); + assertTrue(savedEpisode.isPresent()); + assertNull(savedEpisode.get().getGuid()); + + EpisodeAction episodeAction = new EpisodeAction(); + episodeAction.setEpisode(newEpisode); + episodeAction.setAction(Action.PLAY); + episodeAction.setUser(user); + episodeAction.setTimestamp(LocalDateTime.ofEpochSecond( + LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + (long) episodeIndex * 1000000, + 0, + ZoneOffset.UTC)); + episodeAction.setStarted((episodeIndex + 1)); + episodeAction.setPosition((episodeIndex + 1) * 10); + + episodeActionDao.save(episodeAction); + Optional<EpisodeAction> savedEpisodeAction = episodeActionDao.findById(episodeAction.getId()); + assertTrue(savedEpisodeAction.isPresent()); + + EpisodeAction oldEpisodeActionTest = episodeActionDao + .findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY).orElseThrow(); + List<EpisodeActionPost> episodeActionPosts = new ArrayList<>(); + episodeActionPosts.add(EpisodeActionPost.builder() + .podcastUrl(oldEpisodeActionTest.getEpisode().getSubscription().getUrl()) + .episodeUrl(oldEpisodeActionTest.getEpisode().getUrl()) + .title(oldEpisodeActionTest.getEpisode().getTitle()) + .guid("Alphabet") + .total(oldEpisodeActionTest.getEpisode().getTotal()) + .episodeAction(EpisodeAction.builder() + .timestamp(LocalDateTime.ofEpochSecond( + oldEpisodeActionTest.getTimestamp().toEpochSecond(ZoneOffset.UTC) + 1, + 0, + ZoneOffset.UTC)) + .action(Action.PLAY) + .started(oldEpisodeActionTest.getStarted()) + .position(oldEpisodeActionTest.getPosition()) + .build()) + .build()); + + LocalDateTime oldTimestamp = episodeActionDao + .findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY) + .orElseThrow().getTimestamp(); + episodeActionService.addEpisodeActions(user.getUsername(), episodeActionPosts); + LocalDateTime newTimestamp = episodeActionDao + .findByUserAndEpisodeUrlAndAction(user, episodeUrl, Action.PLAY) + .orElseThrow().getTimestamp(); + assertNotEquals(oldTimestamp, newTimestamp); + savedEpisode = episodeDao.findByUrl(episodeUrl); + assertTrue(savedEpisode.isPresent()); + assertEquals("Alphabet", savedEpisode.get().getGuid()); + } + + @Test + public void addEpisodeActionsTest6() { + // Episode nicht in Datenbank, EpisodeAction mit neuer Episode + + final String username = "testUser0"; + final String podcastName = new File("testfeeds/testPodcast0.xml").toURI().toString(); + final String episodeBaseUrl = "/testfeeds/testPodcast0/episode"; + final User user = authenticationDao.findByUsername(username).orElseThrow(); + + final int episodeIndex = numberOfEpisodesPerSubscription; + + // Setup - Episode ohne GUID einfügen + Optional<Subscription> savedSubscription = subscriptionDao.findByUrl(podcastName); + assertTrue(savedSubscription.isPresent()); + + final String episodeUrl = episodeBaseUrl + episodeIndex + ".mp3"; + + Optional<Episode> noEpisode = episodeDao.findByUrl(episodeUrl); + assertFalse(noEpisode.isPresent()); + + List<EpisodeActionPost> episodeActionPosts = new ArrayList<>(); + episodeActionPosts.add(EpisodeActionPost.builder() + .podcastUrl(podcastName) + .episodeUrl(episodeUrl) + .title("testEpisode" + episodeIndex) + .guid("Alphabet") + .total((episodeIndex + 1) * 100) + .episodeAction(EpisodeAction.builder() + .timestamp(LocalDateTime.ofEpochSecond( + LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + (long) episodeIndex * 1000000, + 0, + ZoneOffset.UTC)) + .action(Action.PLAY) + .started((episodeIndex + 1)) + .position((episodeIndex + 1) * 10) + .build()) + .build()); + episodeActionService.addEpisodeActions(user.getUsername(), episodeActionPosts); + noEpisode = episodeDao.findByUrl(episodeUrl); + assertTrue(noEpisode.isPresent()); + } + + @Test + public void getEpisodeActionsTest() { + String username = "testUser0"; + List<EpisodeActionPost> episodeActionPosts = episodeActionService.getEpisodeActions(username); + assertEquals(numberOfSubscriptionsPerUser * numberOfEpisodesPerSubscription, episodeActionPosts.size()); + } + + @Test + public void getEpisodeActionsOfPodcastTest() { + String username = "testUser0"; + String subscriptionUrl = new File("testfeeds/testPodcast0.xml").toURI().toString(); + List<EpisodeActionPost> episodeActionPosts = episodeActionService.getEpisodeActionsOfPodcast(username, + subscriptionUrl); + assertEquals(numberOfEpisodesPerSubscription, episodeActionPosts.size()); + } + + @Test + public void getEpisodeActionsSinceTest() { + String username = "testUser0"; + // Jede Episode in einer Subscription hat einen Timestamp von zusätzlichen + // 1000000 zur Zeit 0 + int factor = 2; + int timeDifference = 1000000; + int numberOfEpisodes = numberOfSubscriptionsPerUser * numberOfEpisodesPerSubscription; + long since = factor * timeDifference; + List<EpisodeActionPost> episodeActionPosts = episodeActionService.getEpisodeActionsSince(username, since); + assertEquals(numberOfEpisodes - factor * numberOfSubscriptionsPerUser, episodeActionPosts.size()); + } + + @Test + public void getEpisodeActionsOfPodcastSinceTest() { + String username = "testUser0"; + String subscriptionUrl = new File("testfeeds/testPodcast0.xml").toURI().toString(); + // Jede EpisodeAction in einer Subscription hat einen Timestamp von zusätzlichen + // 1000000 zur Zeit 0 + int factor = 1; + int timeDifference = 1000000; + long since = factor * timeDifference; + List<EpisodeActionPost> episodeActionPosts = episodeActionService.getEpisodeActionsOfPodcastSince(username, + subscriptionUrl, since); + assertEquals(numberOfEpisodesPerSubscription - factor, episodeActionPosts.size()); + } +} |