diff --git a/app/src/main/java/nz/badradio/badradio/model/metadata/art/BandcampCrawler.kt b/app/src/main/java/nz/badradio/badradio/model/metadata/art/BandcampCrawler.kt index 3accbd8..f93c623 100644 --- a/app/src/main/java/nz/badradio/badradio/model/metadata/art/BandcampCrawler.kt +++ b/app/src/main/java/nz/badradio/badradio/model/metadata/art/BandcampCrawler.kt @@ -8,6 +8,9 @@ import okhttp3.Request import java.io.IOException class BandcampCrawler(val baseUrl: String) : IStreamingServiceCrawler { + companion object { + val canon = BandcampCrawler("https://bandcamp.com/") + } // search query: https://bandcamp.com/search?q=come%20and%20see%20cassyb&item_type=t diff --git a/app/src/main/java/nz/badradio/badradio/model/metadata/art/ITunesCrawler.kt b/app/src/main/java/nz/badradio/badradio/model/metadata/art/ITunesCrawler.kt index 2950ce6..6f7656c 100644 --- a/app/src/main/java/nz/badradio/badradio/model/metadata/art/ITunesCrawler.kt +++ b/app/src/main/java/nz/badradio/badradio/model/metadata/art/ITunesCrawler.kt @@ -8,16 +8,17 @@ import nz.badradio.badradio.utilities.moshi import okhttp3.Request import java.io.IOException -object ITunesCrawler : IStreamingServiceCrawler { +class ITunesCrawler(val baseUrl: String) : IStreamingServiceCrawler { + companion object { + val canon = ITunesCrawler("https://itunes.apple.com/search") + } // search query: https://itunes.apple.com/search?term=come%20and%20see%20cassyb&media=music&limit=1 - private const val urlBase = "https://itunes.apple.com/search" - @Throws(IOException::class, IndexOutOfBoundsException::class) override fun search(parent: IStreamingServiceDataObserver, songMetadata: SongMetadata) { val searchUrl = buildSearchUrl( - urlBase, + baseUrl, "term", songMetadata, mapOf( diff --git a/app/src/main/java/nz/badradio/badradio/model/metadata/art/SoundcloudCrawler.kt b/app/src/main/java/nz/badradio/badradio/model/metadata/art/SoundcloudCrawler.kt index 091ca8c..9658017 100644 --- a/app/src/main/java/nz/badradio/badradio/model/metadata/art/SoundcloudCrawler.kt +++ b/app/src/main/java/nz/badradio/badradio/model/metadata/art/SoundcloudCrawler.kt @@ -7,12 +7,14 @@ import nz.badradio.badradio.utilities.firstMatch import okhttp3.Request import java.io.IOException -object SoundcloudCrawler : IStreamingServiceCrawler { +class SoundcloudCrawler(val baseUrl: String) : IStreamingServiceCrawler { // search query: https://soundcloud.com/search/sounds?q=come%20and%20see%20cassyb - private const val urlBase = "https://soundcloud.com" - private const val searchEndpoint = "search/sounds" + companion object { + val canon = SoundcloudCrawler("https://soundcloud.com") + val searchEndpoint = "search/sounds" + } @Throws(IOException::class) override fun search(parent: IStreamingServiceDataObserver, songMetadata: SongMetadata) { @@ -28,7 +30,7 @@ object SoundcloudCrawler : IStreamingServiceCrawler { @Throws(IOException::class) fun getSongUrl(parent: IStreamingServiceDataObserver, songMetadata: SongMetadata): String { val searchURL = buildSearchUrl( - "$urlBase/$searchEndpoint", + "$baseUrl/$searchEndpoint", "q", songMetadata, ) @@ -52,7 +54,7 @@ object SoundcloudCrawler : IStreamingServiceCrawler { } val songUrlSuffix = match.groupValues[1] - return "$urlBase$songUrlSuffix" + return "$baseUrl$songUrlSuffix" } @Throws(IOException::class) diff --git a/app/src/main/java/nz/badradio/badradio/model/metadata/art/StreamingServiceCrawler.kt b/app/src/main/java/nz/badradio/badradio/model/metadata/art/StreamingServiceCrawler.kt index b92501a..19953b9 100644 --- a/app/src/main/java/nz/badradio/badradio/model/metadata/art/StreamingServiceCrawler.kt +++ b/app/src/main/java/nz/badradio/badradio/model/metadata/art/StreamingServiceCrawler.kt @@ -8,13 +8,10 @@ import nz.badradio.badradio.model.metadata.SongMetadata import java.io.IOException class StreamingServiceCrawler : IStreamingServiceDataObserver { - - private val bandcampBaseUrl = "https://bandcamp.com/" - private val crawlers = listOf( // ITunesCrawler, TODO: re-enable - BandcampCrawler(bandcampBaseUrl), - SoundcloudCrawler, + BandcampCrawler.canon, + SoundcloudCrawler.canon, ) private val albumArtUrls = mutableListOf() diff --git a/app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/BandcampCrawlerTests.kt b/app/src/test/java/nz/badradio/badradio/model/metadata/art/BandcampCrawlerTests.kt similarity index 82% rename from app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/BandcampCrawlerTests.kt rename to app/src/test/java/nz/badradio/badradio/model/metadata/art/BandcampCrawlerTests.kt index 920db30..c438e9c 100644 --- a/app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/BandcampCrawlerTests.kt +++ b/app/src/test/java/nz/badradio/badradio/model/metadata/art/BandcampCrawlerTests.kt @@ -1,8 +1,7 @@ -package nz.badradio.badradio.model.metadata.art.bandcamp +package nz.badradio.badradio.model.metadata.art import nz.badradio.badradio.model.metadata.SongMetadata -import nz.badradio.badradio.model.metadata.art.BandcampCrawler -import nz.badradio.badradio.model.metadata.art.IStreamingServiceDataObserver +import nz.badradio.badradio.model.metadata.art.StreamingServiceCrawlerTests.Companion.testDataDirectory import okhttp3.HttpUrl import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer @@ -29,19 +28,17 @@ class BandcampCrawlerTests { mockWebServer.shutdown() } - val responsesFilesDirectory = "src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp" - @Test fun testGetImageUrl() { var mockSearchResponseContent = File( - "${responsesFilesDirectory}/bandcamp_search_response.html", + "${testDataDirectory}/bandcamp_search_response.html", ).readText(Charsets.UTF_8) mockSearchResponseContent = mockSearchResponseContent .replace("https://cassyb.bandcamp.com", baseUrl.toString()) val mockSearchResponse = MockResponse().setBody(mockSearchResponseContent) mockWebServer.enqueue(mockSearchResponse) - val mockSongPageResponseContent = File("${responsesFilesDirectory}/bandcamp_song_page.html") + val mockSongPageResponseContent = File("${testDataDirectory}/bandcamp_song_page.html") .readText(Charsets.UTF_8) val mockSongPageResponse = MockResponse().setBody(mockSongPageResponseContent) mockWebServer.enqueue(mockSongPageResponse) @@ -64,7 +61,7 @@ class BandcampCrawlerTests { @Test fun testGetSongUrl() { val mockSearchResponseContent = File( - "${responsesFilesDirectory}/bandcamp_search_response.html", + "${testDataDirectory}/bandcamp_search_response.html", ).readText(Charsets.UTF_8) val mockSearchResponse = MockResponse().setBody(mockSearchResponseContent) mockWebServer.enqueue(mockSearchResponse) diff --git a/app/src/test/java/nz/badradio/badradio/model/metadata/art/ITunesCrawlerTests.kt b/app/src/test/java/nz/badradio/badradio/model/metadata/art/ITunesCrawlerTests.kt index 0f3dd85..274bcc0 100644 --- a/app/src/test/java/nz/badradio/badradio/model/metadata/art/ITunesCrawlerTests.kt +++ b/app/src/test/java/nz/badradio/badradio/model/metadata/art/ITunesCrawlerTests.kt @@ -1,14 +1,41 @@ package nz.badradio.badradio.model.metadata.art import nz.badradio.badradio.model.metadata.SongMetadata +import okhttp3.HttpUrl +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before import org.junit.Test +import java.io.File +import java.io.IOException class ITunesCrawlerTests { + lateinit var mockWebServer: MockWebServer + lateinit var baseUrl: HttpUrl + @Before + @Throws(IOException::class) + fun setUp() { + mockWebServer = MockWebServer() + baseUrl = mockWebServer.url("/") + } + + @After + @Throws(IOException::class) + fun tearDown() { + mockWebServer.shutdown() + } @Test fun testGetImageUrl() { + val mockSearchResponseContent = File( + "${StreamingServiceCrawlerTests.testDataDirectory}/itunes_search_response.html", + ).readText(Charsets.UTF_8) + val mockSearchResponse = MockResponse().setBody(mockSearchResponseContent) + mockWebServer.enqueue(mockSearchResponse) + var imageUrl = "" - ITunesCrawler.search( + ITunesCrawler(baseUrl.toString()).search( object : IStreamingServiceDataObserver { override fun notifyOfAlbumArtUrl(url: String) { imageUrl = url } override fun notifyOfSoundcloudUrl(url: String) { } diff --git a/app/src/test/java/nz/badradio/badradio/model/metadata/art/SoundcloudCrawlerTests.kt b/app/src/test/java/nz/badradio/badradio/model/metadata/art/SoundcloudCrawlerTests.kt index 3013464..b40f549 100644 --- a/app/src/test/java/nz/badradio/badradio/model/metadata/art/SoundcloudCrawlerTests.kt +++ b/app/src/test/java/nz/badradio/badradio/model/metadata/art/SoundcloudCrawlerTests.kt @@ -1,14 +1,46 @@ package nz.badradio.badradio.model.metadata.art import nz.badradio.badradio.model.metadata.SongMetadata +import okhttp3.HttpUrl +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before import org.junit.Test +import java.io.File +import java.io.IOException class SoundcloudCrawlerTests { + lateinit var mockWebServer: MockWebServer + lateinit var baseUrl: HttpUrl + @Before + @Throws(IOException::class) + fun setUp() { + mockWebServer = MockWebServer() + baseUrl = mockWebServer.url("/") + } + + @After + @Throws(IOException::class) + fun tearDown() { + mockWebServer.shutdown() + } @Test fun testGetImageUrl() { + var mockSearchResponseContent = File( + "${StreamingServiceCrawlerTests.testDataDirectory}/soundcloud_search_response.html", + ).readText(Charsets.UTF_8) + val mockSearchResponse = MockResponse().setBody(mockSearchResponseContent) + mockWebServer.enqueue(mockSearchResponse) + + val mockSongPageResponseContent = File("${StreamingServiceCrawlerTests.testDataDirectory}/soundcloud_song_page.html") + .readText(Charsets.UTF_8) + val mockSongPageResponse = MockResponse().setBody(mockSongPageResponseContent) + mockWebServer.enqueue(mockSongPageResponse) + var imageUrl = "" - SoundcloudCrawler.search( + SoundcloudCrawler(baseUrl.toString()).search( object : IStreamingServiceDataObserver { override fun notifyOfAlbumArtUrl(url: String) { imageUrl = url } override fun notifyOfSoundcloudUrl(url: String) { } @@ -24,7 +56,13 @@ class SoundcloudCrawlerTests { @Test fun testGetSongUrl() { - val songUrl = SoundcloudCrawler.getSongUrl( + val mockSearchResponseContent = File( + "${StreamingServiceCrawlerTests.testDataDirectory}/soundcloud_search_response.html", + ).readText(Charsets.UTF_8) + val mockSearchResponse = MockResponse().setBody(mockSearchResponseContent) + mockWebServer.enqueue(mockSearchResponse) + + val songUrl = SoundcloudCrawler(baseUrl.toString()).getSongUrl( object : IStreamingServiceDataObserver { override fun notifyOfAlbumArtUrl(url: String) { } override fun notifyOfSoundcloudUrl(url: String) { } @@ -32,7 +70,7 @@ class SoundcloudCrawlerTests { }, SongMetadata("come and see", "cassyb, north posse"), ) - assert(songUrl == "https://soundcloud.com/xxcassyb/come-and-see") { + assert(songUrl == "${baseUrl}/xxcassyb/come-and-see") { println("was $songUrl") } } diff --git a/app/src/test/java/nz/badradio/badradio/model/metadata/art/StreamingServiceCrawlerTests.kt b/app/src/test/java/nz/badradio/badradio/model/metadata/art/StreamingServiceCrawlerTests.kt index d94edb0..05c8390 100644 --- a/app/src/test/java/nz/badradio/badradio/model/metadata/art/StreamingServiceCrawlerTests.kt +++ b/app/src/test/java/nz/badradio/badradio/model/metadata/art/StreamingServiceCrawlerTests.kt @@ -20,4 +20,7 @@ class StreamingServiceCrawlerTests { assert(runSongMatchesMetadata("thissong", "thissong feat. collaborator")) } + companion object { + val testDataDirectory = "src/test/res" + } } \ No newline at end of file diff --git a/app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/test_bandcamp_responses.sh b/app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/test_bandcamp_responses.sh deleted file mode 100755 index 17088dd..0000000 --- a/app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/test_bandcamp_responses.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -function download_file() { - url="$1" - file_name="$2" - temp_file=/tmp/$file_name - - wget "$url" > $temp_file - - diff $temp_file $test_data_file -} - -download_file "https://bandcamp.com/search?q=come%20and%20see%20cassyb&item_type=t" bandcamp_search_response.html -download_file "https://cassyb.bandcamp.com/track/come-and-see-w-north-posse" bandcamp_song_page.html - diff --git a/app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/bandcamp_search_response.html b/app/src/test/res/bandcamp_search_response.html similarity index 100% rename from app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/bandcamp_search_response.html rename to app/src/test/res/bandcamp_search_response.html diff --git a/app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/bandcamp_song_page.html b/app/src/test/res/bandcamp_song_page.html similarity index 100% rename from app/src/test/java/nz/badradio/badradio/model/metadata/art/bandcamp/bandcamp_song_page.html rename to app/src/test/res/bandcamp_song_page.html diff --git a/app/src/test/res/itunes_search_response.html b/app/src/test/res/itunes_search_response.html new file mode 100644 index 0000000..e30811f --- /dev/null +++ b/app/src/test/res/itunes_search_response.html @@ -0,0 +1,11 @@ + + + +{ + "resultCount":1, + "results": [ +{"wrapperType":"track", "kind":"song", "artistId":1530227322, "collectionId":1616796837, "trackId":1616797117, "artistName":"North Posse", "collectionName":"Paris Robbery II", "trackName":"Come and See (feat. Cassyb)", "collectionCensoredName":"Paris Robbery II", "trackCensoredName":"Come and See (feat. Cassyb)", "artistViewUrl":"https://music.apple.com/us/artist/north-posse/1530227322?uo=4", "collectionViewUrl":"https://music.apple.com/us/album/come-and-see-feat-cassyb/1616796837?i=1616797117&uo=4", "trackViewUrl":"https://music.apple.com/us/album/come-and-see-feat-cassyb/1616796837?i=1616797117&uo=4", +"previewUrl":"https://audio-ssl.itunes.apple.com/itunes-assets/AudioPreview122/v4/db/1d/0d/db1d0d79-c2c7-be9c-80b0-af55b98b28cd/mzaf_11468037081690366165.plus.aac.p.m4a", "artworkUrl30":"https://is1-ssl.mzstatic.com/image/thumb/Music112/v4/b8/67/6d/b8676dfc-a60d-45b3-8136-a3e02e5db168/artwork.jpg/30x30bb.jpg", "artworkUrl60":"https://is1-ssl.mzstatic.com/image/thumb/Music112/v4/b8/67/6d/b8676dfc-a60d-45b3-8136-a3e02e5db168/artwork.jpg/60x60bb.jpg", "artworkUrl100":"https://is1-ssl.mzstatic.com/image/thumb/Music112/v4/b8/67/6d/b8676dfc-a60d-45b3-8136-a3e02e5db168/artwork.jpg/100x100bb.jpg", "collectionPrice":9.90, "trackPrice":0.99, "releaseDate":"2022-03-09T12:00:00Z", "collectionExplicitness":"explicit", "trackExplicitness":"explicit", "discCount":1, "discNumber":1, "trackCount":10, "trackNumber":10, "trackTimeMillis":165010, "country":"USA", "currency":"USD", "primaryGenreName":"Hip-Hop/Rap", "contentAdvisoryRating":"Explicit", "isStreamable":true}] +} + + diff --git a/app/src/test/res/soundcloud_search_response.html b/app/src/test/res/soundcloud_search_response.html new file mode 100644 index 0000000..2a2191f --- /dev/null +++ b/app/src/test/res/soundcloud_search_response.html @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + +come and see cassyb results on SoundCloud - Listen to music + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+

+Your current browser isn't compatible with SoundCloud.
+Please download one of our supported browsers. +Need help? +

+ +
+ +
+

Sorry! Something went wrong

+
+

Is your network connection unstable or browser outdated?

+
+ +
+ +

+Popular searches +

+
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/test/res/soundcloud_song_page.html b/app/src/test/res/soundcloud_song_page.html new file mode 100644 index 0000000..11f6b9c --- /dev/null +++ b/app/src/test/res/soundcloud_song_page.html @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + + + + +Stream COME AND SEE w/NORTH POSSE by cassyb | Listen online for free on SoundCloud + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+

+Your current browser isn't compatible with SoundCloud.
+Please download one of our supported browsers. +Need help? +

+ +
+ +
+

Sorry! Something went wrong

+
+

Is your network connection unstable or browser outdated?

+
+ +
+ +

+Popular searches +

+
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/test/res/test_bandcamp_responses.sh b/app/src/test/res/test_bandcamp_responses.sh new file mode 100755 index 0000000..1dfec78 --- /dev/null +++ b/app/src/test/res/test_bandcamp_responses.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +function check_api_response() { + url="$1" + file_name="$2" + temp_file=/tmp/$file_name + + wget "$url" > $temp_file + + diff $temp_file $test_data_file +} + +check_api_response "https://bandcamp.com/search?q=come%20and%20see%20cassyb&item_type=t" bandcamp_search_response.html +check_api_response "https://cassyb.bandcamp.com/track/come-and-see-w-north-posse" bandcamp_song_page.html + +check_api_response "https://itunes.apple.com/search?term=cassyb+come+and+see&media=music&limit=1" itunes_search_response.html + +check_api_response "https://soundcloud.com/search/sounds?q=come%20and%20see%20cassyb" soundcloud_search_response.html +check_api_response "" soundcloud_song_page.html +