package io.delphiplatform.api.v3.rdb.service.spotify import io.delphiplatform.api.v3.model.spotify.ChartTrackMetricsDimension import io.delphiplatform.api.v3.model.spotify.SpotifyTrackChartsSearchResult import io.delphiplatform.api.v3.rdb.entity.spotify.SpotifyChartDateTrackKey import io.delphiplatform.api.v3.rdb.entity.spotify.SpotifyChartTrackEntity import io.delphiplatform.api.v3.rdb.entity.spotify.SpotifyChartTrackId import io.delphiplatform.api.v3.view.util.Params import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever import java.time.LocalDate import java.util.* internal class SpotifyTracksChartAdditionsServiceTest { private val chartTrackService: SpotifyChartTrackService = mock() private val tracksChartService: SpotifyTracksChartsService = mock() private val tracksChartChangesService: SpotifyTracksChartChangesService = mock() private val service = SpotifyTracksChartAdditionsService( chartTrackService, tracksChartService, tracksChartChangesService ) private val date1 = LocalDate.of(2020, 1, 1) private val date2 = LocalDate.of(2020, 1, 2) private val chart1 = "chart1" private val us = "US" private val isrc1 = "isrc1" private val isrc2 = "isrc2" private val track1 = "track1" private val track2 = "track2" private val track3 = "track3" @Test fun test_spotifyChartTracksAdditions_metricsDimensionTrackId() { val requestedDate = date2 val requestedPreviousDate = date1 val defaultDailyPrevDate = requestedDate.minusDays(1) val defaultWeeklyPrevDate = requestedDate.minusDays(7) val inputParams = Params.builder() .chartTrackMetricsDimension(ChartTrackMetricsDimension.TRACK_ID) .trackId(mutableListOf(track1)) .date(requestedDate) .previousDate(requestedPreviousDate) .build() whenever( tracksChartChangesService.getRequestedDateOrDefault( inputParams.date, inputParams.isrc, inputParams.trackId, ) ).thenReturn(requestedDate) whenever( tracksChartChangesService.getDefaultPreviousDateDaily(requestedDate) ).thenReturn(defaultDailyPrevDate) whenever( tracksChartChangesService.getDefaultPreviousDateWeekly(requestedDate) ).thenReturn(defaultWeeklyPrevDate) //track1 exists for requestedPreviousDate and WONT be returned as addition val chartTrack1 = createChartTrack(requestedPreviousDate, track1, chart1, isrc1) whenever( chartTrackService.findTrackMetricsByDateConsideringChartBreakdown( Collections.emptySet(), inputParams.trackId, inputParams.isrc, requestedPreviousDate, defaultDailyPrevDate, defaultWeeklyPrevDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) ).thenReturn( mutableListOf( chartTrack1 ) ) //prepare track1 id with date adjusted to requestedDate, just for mocking needs val excludedCharTrack = SpotifyChartDateTrackKey() excludedCharTrack.chartDate = requestedDate excludedCharTrack.spotifyChartId = chartTrack1.id.spotifyChartId excludedCharTrack.spotifyTrackId = chartTrack1.spotifyTrackId //track2 exists only for requestedDate and WILL be returned as addition val delta = mutableListOf( createChartTrack(requestedDate, track2, chart1, isrc1) ) whenever( chartTrackService.findTrackMetrics( mutableSetOf(excludedCharTrack), inputParams.trackId, inputParams.isrc, requestedDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) ).thenReturn(delta) val searchResults = mutableListOf(SpotifyTrackChartsSearchResult.builder().build()) whenever( tracksChartService.getSpotifyTrackChartsSearchResults( inputParams.trackStateIncludes, inputParams.chartTrackMetricsDimension, delta ) ).thenReturn(searchResults) val additions = service.getSpotifyChartTracksAdditions(inputParams) verify(chartTrackService).findTrackMetricsByDateConsideringChartBreakdown( Collections.emptySet(), inputParams.trackId, inputParams.isrc, requestedPreviousDate, defaultDailyPrevDate, defaultWeeklyPrevDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) verify(chartTrackService).findTrackMetrics( mutableSetOf(excludedCharTrack), inputParams.trackId, inputParams.isrc, requestedDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) verify(tracksChartService).getSpotifyTrackChartsSearchResults( inputParams.trackStateIncludes, inputParams.chartTrackMetricsDimension, delta ) Assertions.assertEquals(searchResults, additions) verifyNoMoreInteractions(tracksChartService, chartTrackService) } @Test fun test_spotifyChartTracksAdditions_metricsDimensionTrackId_emptyPreviousDate() { val requestedDate = date2 val defaultDailyPrevDate = requestedDate.minusDays(1) val defaultWeeklyPrevDate = requestedDate.minusDays(7) val inputParams = Params.builder() .chartTrackMetricsDimension(ChartTrackMetricsDimension.TRACK_ID) .trackId(mutableListOf(track1)) .date(requestedDate) .previousDate(null) .build() whenever( tracksChartChangesService.getRequestedDateOrDefault( inputParams.date, inputParams.isrc, inputParams.trackId, ) ).thenReturn(requestedDate) whenever( tracksChartChangesService.getDefaultPreviousDateDaily(requestedDate) ).thenReturn(defaultDailyPrevDate) whenever( tracksChartChangesService.getDefaultPreviousDateWeekly(requestedDate) ).thenReturn(defaultWeeklyPrevDate) //track1 exists for requestedPreviousDate and WONT be returned as addition val chartTrack1 = createChartTrack(defaultDailyPrevDate, track1, chart1, isrc1) whenever( chartTrackService.findTrackMetricsByDateConsideringChartBreakdown( Collections.emptySet(), inputParams.trackId, inputParams.isrc, null, defaultDailyPrevDate, defaultWeeklyPrevDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) ).thenReturn( mutableListOf( chartTrack1 ) ) //prepare track1 id with date adjusted to requestedDate, just for mocking needs val excludedCharTrack = SpotifyChartDateTrackKey() excludedCharTrack.chartDate = requestedDate excludedCharTrack.spotifyChartId = chartTrack1.id.spotifyChartId excludedCharTrack.spotifyTrackId = chartTrack1.spotifyTrackId //track2 exists only for requestedDate and WILL be returned as addition val delta = mutableListOf( createChartTrack(requestedDate, track2, chart1, isrc1) ) whenever( chartTrackService.findTrackMetrics( mutableSetOf(excludedCharTrack), inputParams.trackId, inputParams.isrc, requestedDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) ).thenReturn(delta) val searchResults = mutableListOf(SpotifyTrackChartsSearchResult.builder().build()) whenever( tracksChartService.getSpotifyTrackChartsSearchResults( inputParams.trackStateIncludes, inputParams.chartTrackMetricsDimension, delta ) ).thenReturn(searchResults) val additions = service.getSpotifyChartTracksAdditions(inputParams) verify(chartTrackService).findTrackMetricsByDateConsideringChartBreakdown( Collections.emptySet(), inputParams.trackId, inputParams.isrc, null, defaultDailyPrevDate, defaultWeeklyPrevDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) verify(chartTrackService).findTrackMetrics( mutableSetOf(excludedCharTrack), inputParams.trackId, inputParams.isrc, requestedDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) verify(tracksChartService).getSpotifyTrackChartsSearchResults( inputParams.trackStateIncludes, inputParams.chartTrackMetricsDimension, delta ) Assertions.assertEquals(searchResults, additions) verifyNoMoreInteractions(tracksChartService, chartTrackService) } /** * date1 - t1 - isrc1 * date2 - t2 - isrc1 * date2 - t3 - isrc2 * * expected addition - only t3 for metrics dimension - ISRC */ @Test fun test_spotifyChartTracksAdditions_metricsDimensionIsrc() { val requestedDate = date2 val requestedPreviousDate = date1 val defaultDailyPrevDate = requestedDate.minusDays(1) val defaultWeeklyPrevDate = requestedDate.minusDays(7) val inputParams = Params.builder() .chartTrackMetricsDimension(ChartTrackMetricsDimension.ISRC) .isrc(mutableListOf(isrc1)) .date(requestedDate) .previousDate(requestedPreviousDate) .build() whenever( tracksChartChangesService.getRequestedDateOrDefault( inputParams.date, inputParams.isrc, inputParams.trackId, ) ).thenReturn(requestedDate) whenever( tracksChartChangesService.getDefaultPreviousDateDaily(requestedDate) ).thenReturn(defaultDailyPrevDate) whenever( tracksChartChangesService.getDefaultPreviousDateWeekly(requestedDate) ).thenReturn(defaultWeeklyPrevDate) //track1 exists for requestedPreviousDate and WONT be returned as addition val chartTrack1 = createChartTrack(requestedPreviousDate, track1, chart1, isrc1) whenever( chartTrackService.findTrackMetricsByDateConsideringChartBreakdown( Collections.emptySet(), inputParams.trackId, inputParams.isrc, requestedPreviousDate, defaultDailyPrevDate, defaultWeeklyPrevDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) ).thenReturn(mutableListOf(chartTrack1)) val excludedCharTrack1 = SpotifyChartDateTrackKey() excludedCharTrack1.chartDate = requestedDate excludedCharTrack1.spotifyChartId = chartTrack1.id.spotifyChartId excludedCharTrack1.spotifyTrackId = chartTrack1.spotifyTrackId //track2 is a 'sibling by isrc' of track1 but 'exists' at requestedDate val excludedCharTrack2 = SpotifyChartDateTrackKey() excludedCharTrack2.chartDate = requestedDate excludedCharTrack2.spotifyChartId = chartTrack1.id.spotifyChartId excludedCharTrack2.spotifyTrackId = track2 whenever(chartTrackService.findTrackKeysWithSameIsrcWithinChartForDate(mutableSetOf(chartTrack1.chartDateTrackKey), requestedDate)) .thenReturn(mutableSetOf(excludedCharTrack2)) //track1 exists at requestedPreviousDate //track2 exists at requestedDate but is 'isrc sibling' of track1 //thus both will be excluded val excludedChartTrackKeys = mutableSetOf(excludedCharTrack1, excludedCharTrack2) //track3 exists only for requestedDate and WILL be returned as addition val delta = mutableListOf(createChartTrack(requestedDate, track3, chart1, isrc2)) whenever( chartTrackService.findTrackMetrics( excludedChartTrackKeys, inputParams.trackId, inputParams.isrc, requestedDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) ).thenReturn(delta) val searchResults = mutableListOf(SpotifyTrackChartsSearchResult.builder().build()) whenever( tracksChartService.getSpotifyTrackChartsSearchResults( inputParams.trackStateIncludes, inputParams.chartTrackMetricsDimension, delta ) ).thenReturn(searchResults) val additions = service.getSpotifyChartTracksAdditions(inputParams) verify(chartTrackService).findTrackMetricsByDateConsideringChartBreakdown( Collections.emptySet(), inputParams.trackId, inputParams.isrc, requestedPreviousDate, defaultDailyPrevDate, defaultWeeklyPrevDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) verify(chartTrackService).findTrackKeysWithSameIsrcWithinChartForDate(mutableSetOf(chartTrack1.chartDateTrackKey), requestedDate) verify(chartTrackService).findTrackMetrics( excludedChartTrackKeys, inputParams.trackId, inputParams.isrc, requestedDate, inputParams.minPosition, inputParams.maxPosition, inputParams.minRank, inputParams.maxRank, inputParams.countryCode, inputParams.breakdowns, inputParams.types, inputParams.chartTrackMetricsDimension ) verify(tracksChartService).getSpotifyTrackChartsSearchResults( inputParams.trackStateIncludes, inputParams.chartTrackMetricsDimension, delta ) Assertions.assertEquals(searchResults, additions) verifyNoMoreInteractions(tracksChartService, chartTrackService) } private fun createChartTrack( chartDate: LocalDate, trackId: String, chartId: String = chart1, isrc: String = isrc1 ): SpotifyChartTrackEntity { val spotifyChartTrackEntity = SpotifyChartTrackEntity() val spotifyChartTrackId = SpotifyChartTrackId() spotifyChartTrackId.chartDate = chartDate spotifyChartTrackId.spotifyChartId = chartId spotifyChartTrackId.currentPosition = 10 val spotifyChartDateTrackKey = SpotifyChartDateTrackKey() spotifyChartDateTrackKey.chartDate = chartDate spotifyChartDateTrackKey.spotifyChartId = chartId spotifyChartDateTrackKey.spotifyTrackId = trackId spotifyChartTrackEntity.id = spotifyChartTrackId spotifyChartTrackEntity.chartDateTrackKey = spotifyChartDateTrackKey spotifyChartTrackEntity.spotifyChartId = chartId spotifyChartTrackEntity.spotifyTrackId = trackId spotifyChartTrackEntity.spotifyCountryId = us spotifyChartTrackEntity.chartDate = chartDate spotifyChartTrackEntity.currentPosition = 10 spotifyChartTrackEntity.isExit = false spotifyChartTrackEntity.isEntry = false spotifyChartTrackEntity.isReentry = false spotifyChartTrackEntity.prevPosition = 20 spotifyChartTrackEntity.isrc = isrc spotifyChartTrackEntity.isrcPrevPosition = 15 return spotifyChartTrackEntity } }