diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java index 8b01a636a..352d12d6b 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java @@ -13,13 +13,34 @@ public interface PlaylistLocalItem extends LocalItem { long getDisplayIndex(); + /** + * Merge localPlaylists and remotePlaylists by the display index. + * If two items have the same display index, sort them in {@code CASE_INSENSITIVE_ORDER}. + * + * @param localPlaylists local playlists in the display index order + * @param remotePlaylists remote playlists in the display index order + * @return merged playlists + */ static List merge( final List localPlaylists, final List remotePlaylists) { - // The playlists from the database must be in the display index order. - // Merge localPlaylists and remotePlaylists by display index. - // If two items have the same display index, sort them in CASE_INSENSITIVE_ORDER. + for (int i = 1; i < localPlaylists.size(); i++) { + if (localPlaylists.get(i).getDisplayIndex() + < localPlaylists.get(i - 1).getDisplayIndex()) { + throw new IllegalArgumentException( + "localPlaylists is not in the display index order"); + } + } + + for (int i = 1; i < remotePlaylists.size(); i++) { + if (remotePlaylists.get(i).getDisplayIndex() + < remotePlaylists.get(i - 1).getDisplayIndex()) { + throw new IllegalArgumentException( + "remotePlaylists is not in the display index order"); + } + } + // This algorithm is similar to the merge operation in merge sort. final List result = new ArrayList<>( diff --git a/app/src/test/java/org/schabi/newpipe/database/playlist/PlaylistLocalItemTest.java b/app/src/test/java/org/schabi/newpipe/database/playlist/PlaylistLocalItemTest.java index e5f717144..98f611037 100644 --- a/app/src/test/java/org/schabi/newpipe/database/playlist/PlaylistLocalItemTest.java +++ b/app/src/test/java/org/schabi/newpipe/database/playlist/PlaylistLocalItemTest.java @@ -24,16 +24,26 @@ public class PlaylistLocalItemTest { 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(1, "name1", "", 0, 1)); localPlaylists.add(new PlaylistMetadataEntry(2, "name2", "", 1, 1)); - localPlaylists.add(new PlaylistMetadataEntry(3, "name3", "", 0, 1)); + localPlaylists.add(new PlaylistMetadataEntry(3, "name3", "", 3, 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()); + assertEquals(3, mergedPlaylists.get(2).getDisplayIndex()); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidLocalPlaylists() { + 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)); + PlaylistLocalItem.merge(localPlaylists, remotePlaylists); } @Test @@ -41,18 +51,31 @@ public class PlaylistLocalItemTest { final List localPlaylists = new ArrayList<>(); final List remotePlaylists = new ArrayList<>(); remotePlaylists.add(new PlaylistRemoteEntity( - 1, "name1", "url1", "", "", 2, 1L)); + 1, "name1", "url1", "", "", 1, 1L)); remotePlaylists.add(new PlaylistRemoteEntity( - 2, "name2", "url2", "", "", 1, 1L)); + 2, "name2", "url2", "", "", 2, 1L)); remotePlaylists.add(new PlaylistRemoteEntity( - 3, "name3", "url3", "", "", 0, 1L)); + 3, "name3", "url3", "", "", 4, 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()); + assertEquals(1, mergedPlaylists.get(0).getDisplayIndex()); + assertEquals(2, mergedPlaylists.get(1).getDisplayIndex()); + assertEquals(4, mergedPlaylists.get(2).getDisplayIndex()); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidRemotePlaylists() { + final List localPlaylists = new ArrayList<>(); + final List remotePlaylists = new ArrayList<>(); + remotePlaylists.add(new PlaylistRemoteEntity( + 1, "name1", "url1", "", "", 1, 1L)); + remotePlaylists.add(new PlaylistRemoteEntity( + 2, "name2", "url2", "", "", 3, 1L)); + remotePlaylists.add(new PlaylistRemoteEntity( + 3, "name3", "url3", "", "", 0, 1L)); + PlaylistLocalItem.merge(localPlaylists, remotePlaylists); } @Test