diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt index 6d05a45bf..73b6313db 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt @@ -13,6 +13,8 @@ import org.junit.Assert.assertNull import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.schabi.newpipe.database.playlist.model.PlaylistEntity +import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity import org.schabi.newpipe.extractor.stream.StreamType @RunWith(AndroidJUnit4::class) @@ -21,13 +23,17 @@ class DatabaseMigrationTest { private const val DEFAULT_SERVICE_ID = 0 private const val DEFAULT_URL = "https://www.youtube.com/watch?v=cDphUib5iG4" private const val DEFAULT_TITLE = "Test Title" + private const val DEFAULT_NAME = "Test Name" private val DEFAULT_TYPE = StreamType.VIDEO_STREAM private const val DEFAULT_DURATION = 480L private const val DEFAULT_UPLOADER_NAME = "Uploader Test" private const val DEFAULT_THUMBNAIL = "https://example.com/example.jpg" - private const val DEFAULT_SECOND_SERVICE_ID = 0 + private const val DEFAULT_SECOND_SERVICE_ID = 1 private const val DEFAULT_SECOND_URL = "https://www.youtube.com/watch?v=ncQU6iBn5Fc" + + private const val DEFAULT_THIRD_SERVICE_ID = 2 + private const val DEFAULT_THIRD_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" } @get:Rule @@ -123,6 +129,90 @@ class DatabaseMigrationTest { assertNull(secondStreamFromMigratedDatabase.isUploadDateApproximation) } + @Test + fun migrateDatabaseFrom5to6() { + val databaseInV5 = testHelper.createDatabase(AppDatabase.DATABASE_NAME, Migrations.DB_VER_5) + + val localUid1: Long + val localUid2: Long + val remoteUid1: Long + val remoteUid2: Long + databaseInV5.run { + localUid1 = insert( + "playlists", SQLiteDatabase.CONFLICT_FAIL, + ContentValues().apply { + put("name", DEFAULT_NAME + "1") + put("thumbnail_url", DEFAULT_THUMBNAIL) + } + ) + localUid2 = insert( + "playlists", SQLiteDatabase.CONFLICT_FAIL, + ContentValues().apply { + put("name", DEFAULT_NAME + "2") + put("thumbnail_url", DEFAULT_THUMBNAIL) + } + ) + delete( + "playlists", "uid = ?", + Array(1) { localUid1 } + ) + remoteUid1 = insert( + "remote_playlists", SQLiteDatabase.CONFLICT_FAIL, + ContentValues().apply { + put("service_id", DEFAULT_SERVICE_ID) + put("url", DEFAULT_URL) + } + ) + remoteUid2 = insert( + "remote_playlists", SQLiteDatabase.CONFLICT_FAIL, + ContentValues().apply { + put("service_id", DEFAULT_SECOND_SERVICE_ID) + put("url", DEFAULT_SECOND_URL) + } + ) + delete( + "remote_playlists", "uid = ?", + Array(1) { remoteUid2 } + ) + close() + } + + testHelper.runMigrationsAndValidate( + AppDatabase.DATABASE_NAME, Migrations.DB_VER_6, + true, Migrations.MIGRATION_5_6 + ) + + val migratedDatabaseV6 = getMigratedDatabase() + var localListFromDB = migratedDatabaseV6.playlistDAO().all.blockingFirst() + var remoteListFromDB = migratedDatabaseV6.playlistRemoteDAO().all.blockingFirst() + + assertEquals(1, localListFromDB.size) + assertEquals(localUid2, localListFromDB[0].uid) + assertEquals(0, localListFromDB[0].displayIndex) + assertEquals(1, remoteListFromDB.size) + assertEquals(remoteUid1, remoteListFromDB[0].uid) + assertEquals(0, remoteListFromDB[0].displayIndex) + + val localUid3 = migratedDatabaseV6.playlistDAO().insert( + PlaylistEntity(DEFAULT_NAME + "3", DEFAULT_THUMBNAIL, -1) + ) + val remoteUid3 = migratedDatabaseV6.playlistRemoteDAO().insert( + PlaylistRemoteEntity( + DEFAULT_THIRD_SERVICE_ID, DEFAULT_NAME, DEFAULT_THIRD_URL, + DEFAULT_THUMBNAIL, DEFAULT_UPLOADER_NAME, -1, 10 + ) + ) + + localListFromDB = migratedDatabaseV6.playlistDAO().all.blockingFirst() + remoteListFromDB = migratedDatabaseV6.playlistRemoteDAO().all.blockingFirst() + assertEquals(2, localListFromDB.size) + assertEquals(localUid3, localListFromDB[1].uid) + assertEquals(-1, localListFromDB[1].displayIndex) + assertEquals(2, remoteListFromDB.size) + assertEquals(remoteUid3, remoteListFromDB[1].uid) + assertEquals(-1, remoteListFromDB[1].displayIndex) + } + private fun getMigratedDatabase(): AppDatabase { val database: AppDatabase = Room.databaseBuilder( ApplicationProvider.getApplicationContext(), diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index ceeb980c7..a79719525 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -385,7 +385,7 @@ public final class BookmarkFragment extends BaseLocalListFragment localPlaylists = new ArrayList<>(); + final List remotePlaylists = new ArrayList<>(); + final List mergedPlaylists = + PlaylistLocalItem.merge(localPlaylists, remotePlaylists); + + assertEquals(0, mergedPlaylists.size()); + } + + @Test + public void onlyLocalPlaylists() { + final List localPlaylists = new ArrayList<>(); + final List remotePlaylists = new ArrayList<>(); + localPlaylists.add(new PlaylistMetadataEntry(1, "name1", "", 2, 1)); + localPlaylists.add(new PlaylistMetadataEntry(2, "name2", "", 1, 1)); + localPlaylists.add(new PlaylistMetadataEntry(3, "name3", "", 0, 1)); + final List mergedPlaylists = + PlaylistLocalItem.merge(localPlaylists, remotePlaylists); + + assertEquals(3, mergedPlaylists.size()); + assertEquals(0, mergedPlaylists.get(0).getDisplayIndex()); + assertEquals(1, mergedPlaylists.get(1).getDisplayIndex()); + assertEquals(2, mergedPlaylists.get(2).getDisplayIndex()); + } + + @Test + public void onlyRemotePlaylists() { + final List localPlaylists = new ArrayList<>(); + final List remotePlaylists = new ArrayList<>(); + remotePlaylists.add(new PlaylistRemoteEntity( + 1, "name1", "url1", "", "", 2, 1L)); + remotePlaylists.add(new PlaylistRemoteEntity( + 2, "name2", "url2", "", "", 1, 1L)); + remotePlaylists.add(new PlaylistRemoteEntity( + 3, "name3", "url3", "", "", 0, 1L)); + final List mergedPlaylists = + PlaylistLocalItem.merge(localPlaylists, remotePlaylists); + + assertEquals(3, mergedPlaylists.size()); + assertEquals(0, mergedPlaylists.get(0).getDisplayIndex()); + assertEquals(1, mergedPlaylists.get(1).getDisplayIndex()); + assertEquals(2, mergedPlaylists.get(2).getDisplayIndex()); + } + + @Test + public void sameIndexWithDifferentName() { + final List localPlaylists = new ArrayList<>(); + final List remotePlaylists = new ArrayList<>(); + localPlaylists.add(new PlaylistMetadataEntry(1, "name1", "", 0, 1)); + localPlaylists.add(new PlaylistMetadataEntry(2, "name2", "", 1, 1)); + remotePlaylists.add(new PlaylistRemoteEntity( + 1, "name3", "url1", "", "", 0, 1L)); + remotePlaylists.add(new PlaylistRemoteEntity( + 2, "name4", "url2", "", "", 1, 1L)); + final List mergedPlaylists = + PlaylistLocalItem.merge(localPlaylists, remotePlaylists); + + assertEquals(4, mergedPlaylists.size()); + assertTrue(mergedPlaylists.get(0) instanceof PlaylistMetadataEntry); + assertEquals("name1", ((PlaylistMetadataEntry) mergedPlaylists.get(0)).name); + assertTrue(mergedPlaylists.get(1) instanceof PlaylistRemoteEntity); + assertEquals("name3", ((PlaylistRemoteEntity) mergedPlaylists.get(1)).getName()); + assertTrue(mergedPlaylists.get(2) instanceof PlaylistMetadataEntry); + assertEquals("name2", ((PlaylistMetadataEntry) mergedPlaylists.get(2)).name); + assertTrue(mergedPlaylists.get(3) instanceof PlaylistRemoteEntity); + assertEquals("name4", ((PlaylistRemoteEntity) mergedPlaylists.get(3)).getName()); + } + + @Test + public void sameNameWithDifferentIndex() { + final List localPlaylists = new ArrayList<>(); + final List remotePlaylists = new ArrayList<>(); + localPlaylists.add(new PlaylistMetadataEntry(1, "name1", "", 1, 1)); + localPlaylists.add(new PlaylistMetadataEntry(2, "name2", "", 3, 1)); + remotePlaylists.add(new PlaylistRemoteEntity( + 1, "name1", "url1", "", "", 0, 1L)); + remotePlaylists.add(new PlaylistRemoteEntity( + 2, "name2", "url2", "", "", 2, 1L)); + final List mergedPlaylists = + PlaylistLocalItem.merge(localPlaylists, remotePlaylists); + + assertEquals(4, mergedPlaylists.size()); + assertTrue(mergedPlaylists.get(0) instanceof PlaylistRemoteEntity); + assertEquals("name1", ((PlaylistRemoteEntity) mergedPlaylists.get(0)).getName()); + assertTrue(mergedPlaylists.get(1) instanceof PlaylistMetadataEntry); + assertEquals("name1", ((PlaylistMetadataEntry) mergedPlaylists.get(1)).name); + assertTrue(mergedPlaylists.get(2) instanceof PlaylistRemoteEntity); + assertEquals("name2", ((PlaylistRemoteEntity) mergedPlaylists.get(2)).getName()); + assertTrue(mergedPlaylists.get(3) instanceof PlaylistMetadataEntry); + assertEquals("name2", ((PlaylistMetadataEntry) mergedPlaylists.get(3)).name); + } +}