Unittest/mediaprovider (#251)
Implemented integration tests for music items
This commit is contained in:
parent
d746f6643f
commit
080b5809f3
|
@ -30,6 +30,7 @@ import org.xbmc.kore.jsonrpc.type.LibraryType;
|
|||
import org.xbmc.kore.jsonrpc.type.VideoType;
|
||||
import org.xbmc.kore.provider.MediaContract;
|
||||
import org.xbmc.kore.provider.MediaProvider;
|
||||
import org.xbmc.kore.service.library.SyncMusic;
|
||||
import org.xbmc.kore.service.library.SyncUtils;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
|
||||
|
@ -45,12 +46,12 @@ public class Database {
|
|||
mediaProvider.onCreate();
|
||||
|
||||
HostInfo hostInfo = addHost(context);
|
||||
|
||||
SyncMusic syncMusic = new SyncMusic(hostInfo.getId(), null);
|
||||
insertMovies(context, hostInfo.getId());
|
||||
insertArtists(context, hostInfo.getId());
|
||||
insertGenres(context, hostInfo.getId());
|
||||
insertAlbums(context, hostInfo.getId());
|
||||
insertSongs(context, hostInfo.getId());
|
||||
insertArtists(context, syncMusic);
|
||||
insertGenres(context, syncMusic);
|
||||
insertAlbums(context, syncMusic);
|
||||
insertSongs(context, syncMusic);
|
||||
|
||||
return hostInfo;
|
||||
}
|
||||
|
@ -96,86 +97,34 @@ public class Database {
|
|||
context.getContentResolver().bulkInsert(MediaContract.MovieCast.CONTENT_URI, movieCastValuesBatch);
|
||||
}
|
||||
|
||||
private static void insertArtists(Context context, int hostId) throws ApiException, IOException {
|
||||
private static void insertArtists(Context context, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
AudioLibrary.GetArtists getArtists = new AudioLibrary.GetArtists(false);
|
||||
String result = Utils.readFile(context, "AudioLibrary.GetArtists.json");
|
||||
ArrayList<AudioType.DetailsArtist> artistList = (ArrayList) getArtists.resultFromJson(result).items;
|
||||
|
||||
ContentValues artistValuesBatch[] = new ContentValues[artistList.size()];
|
||||
for (int i = 0; i < artistList.size(); i++) {
|
||||
AudioType.DetailsArtist artist = artistList.get(i);
|
||||
artistValuesBatch[i] = SyncUtils.contentValuesFromArtist(hostId, artist);
|
||||
}
|
||||
|
||||
context.getContentResolver().bulkInsert(MediaContract.Artists.CONTENT_URI, artistValuesBatch);
|
||||
syncMusic.insertArtists(artistList, context.getContentResolver());
|
||||
}
|
||||
|
||||
private static void insertGenres(Context context, int hostId) throws ApiException, IOException {
|
||||
private static void insertGenres(Context context, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
AudioLibrary.GetGenres getGenres = new AudioLibrary.GetGenres();
|
||||
ArrayList<LibraryType.DetailsGenre> genreList = (ArrayList) getGenres.resultFromJson(Utils.readFile(context, "AudioLibrary.GetGenres.json"));
|
||||
|
||||
ContentValues genresValuesBatch[] = new ContentValues[genreList.size()];
|
||||
for (int i = 0; i < genreList.size(); i++) {
|
||||
LibraryType.DetailsGenre genre = genreList.get(i);
|
||||
genresValuesBatch[i] = SyncUtils.contentValuesFromAudioGenre(hostId, genre);
|
||||
}
|
||||
|
||||
context.getContentResolver().bulkInsert(MediaContract.AudioGenres.CONTENT_URI, genresValuesBatch);
|
||||
syncMusic.insertGenresItems(genreList, context.getContentResolver());
|
||||
}
|
||||
|
||||
private static void insertAlbums(Context context, int hostId) throws ApiException, IOException {
|
||||
private static void insertAlbums(Context context, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
AudioLibrary.GetAlbums getAlbums = new AudioLibrary.GetAlbums();
|
||||
String result = Utils.readFile(context, "AudioLibrary.GetAlbums.json");
|
||||
ArrayList<AudioType.DetailsAlbum> albumList = (ArrayList) getAlbums.resultFromJson(result).items;
|
||||
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
|
||||
ContentValues albumValuesBatch[] = new ContentValues[albumList.size()];
|
||||
int artistsCount = 0, genresCount = 0;
|
||||
for (int i = 0; i < albumList.size(); i++) {
|
||||
AudioType.DetailsAlbum album = albumList.get(i);
|
||||
albumValuesBatch[i] = SyncUtils.contentValuesFromAlbum(hostId, album);
|
||||
|
||||
artistsCount += album.artistid.size();
|
||||
genresCount += album.genreid.size();
|
||||
}
|
||||
contentResolver.bulkInsert(MediaContract.Albums.CONTENT_URI, albumValuesBatch);
|
||||
|
||||
// Iterate on each album, collect the artists and the genres and insert them
|
||||
ContentValues albumArtistsValuesBatch[] = new ContentValues[artistsCount];
|
||||
ContentValues albumGenresValuesBatch[] = new ContentValues[genresCount];
|
||||
int artistCount = 0, genreCount = 0;
|
||||
for (AudioType.DetailsAlbum album : albumList) {
|
||||
for (int artistId : album.artistid) {
|
||||
albumArtistsValuesBatch[artistCount] = new ContentValues();
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.HOST_ID, hostId);
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.ALBUMID, album.albumid);
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.ARTISTID, artistId);
|
||||
artistCount++;
|
||||
}
|
||||
|
||||
for (int genreId : album.genreid) {
|
||||
albumGenresValuesBatch[genreCount] = new ContentValues();
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.HOST_ID, hostId);
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.ALBUMID, album.albumid);
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.GENREID, genreId);
|
||||
genreCount++;
|
||||
}
|
||||
}
|
||||
|
||||
contentResolver.bulkInsert(MediaContract.AlbumArtists.CONTENT_URI, albumArtistsValuesBatch);
|
||||
contentResolver.bulkInsert(MediaContract.AlbumGenres.CONTENT_URI, albumGenresValuesBatch);
|
||||
syncMusic.insertAlbumsItems(albumList, context.getContentResolver());
|
||||
}
|
||||
|
||||
private static void insertSongs(Context context, int hostId) throws ApiException, IOException {
|
||||
private static void insertSongs(Context context, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
AudioLibrary.GetSongs getSongs = new AudioLibrary.GetSongs();
|
||||
ArrayList<AudioType.DetailsSong> songList = (ArrayList) getSongs.resultFromJson(Utils.readFile(context, "AudioLibrary.GetSongs.json")).items;
|
||||
ArrayList<AudioType.DetailsSong> songList = (ArrayList)
|
||||
getSongs.resultFromJson(Utils.readFile(context, "AudioLibrary.GetSongs.json")).items;
|
||||
|
||||
ContentValues songValuesBatch[] = new ContentValues[songList.size()];
|
||||
for (int i = 0; i < songList.size(); i++) {
|
||||
AudioType.DetailsSong song = songList.get(i);
|
||||
songValuesBatch[i] = SyncUtils.contentValuesFromSong(hostId, song);
|
||||
}
|
||||
context.getContentResolver().bulkInsert(MediaContract.Songs.CONTENT_URI, songValuesBatch);
|
||||
syncMusic.insertSongsItems(songList, context.getContentResolver());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2016 Martijn Brekhof. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.xbmc.kore.testhelpers;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import org.xbmc.kore.ui.SongsListFragment;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestUtils {
|
||||
/**
|
||||
* Tests if cursor contains all numbers from ids given column index.
|
||||
* @param cursor
|
||||
* @param columnIndex
|
||||
* @param numbers
|
||||
*/
|
||||
public static void testCursorContainsNumbers(Cursor cursor, int columnIndex, int... numbers) {
|
||||
HashMap<Integer, Boolean> idsFound = new HashMap<>();
|
||||
for(int number : numbers) {
|
||||
idsFound.put(number, false);
|
||||
}
|
||||
|
||||
assertTrue(cursor.moveToFirst());
|
||||
do {
|
||||
idsFound.put(cursor.getInt(columnIndex), true);
|
||||
} while(cursor.moveToNext());
|
||||
|
||||
for(Map.Entry<Integer, Boolean> entry : idsFound.entrySet() ) {
|
||||
int key = entry.getKey();
|
||||
assertTrue("Id " + key + " not found", entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if cursor contains all numbers from start until end for given column index.
|
||||
* @param columnIndex
|
||||
* @param cursor
|
||||
* @param start
|
||||
* @param end
|
||||
*/
|
||||
public static void testCursorContainsRange(Cursor cursor, int columnIndex, int start, int end) {
|
||||
HashMap<Integer, Boolean> idsFound = new HashMap<>();
|
||||
for(int i = start; i <= end; i++) {
|
||||
idsFound.put(i, false);
|
||||
}
|
||||
|
||||
assertTrue(cursor.moveToFirst());
|
||||
do {
|
||||
idsFound.put(cursor.getInt(columnIndex), true);
|
||||
} while(cursor.moveToNext());
|
||||
|
||||
for(Map.Entry<Integer, Boolean> entry : idsFound.entrySet() ) {
|
||||
int key = entry.getKey();
|
||||
assertTrue("Id " + key + " not found", entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ package org.xbmc.kore.testhelpers;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.os.IBinder;
|
||||
import android.support.test.rule.ActivityTestRule;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
|
@ -92,6 +93,15 @@ public class Utils {
|
|||
isInitialized = false;
|
||||
}
|
||||
|
||||
public static String cursorToString(Cursor cursor) {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
for (String name : cursor.getColumnNames()) {
|
||||
int index = cursor.getColumnIndex(name);
|
||||
stringBuffer.append(name + "=" + cursor.getString(index) + "\n");
|
||||
}
|
||||
return stringBuffer.toString();
|
||||
}
|
||||
|
||||
private static void disableAnimations() {
|
||||
int permStatus = context.checkCallingOrSelfPermission(ANIMATION_PERMISSION);
|
||||
if (permStatus == PackageManager.PERMISSION_GRANTED) {
|
||||
|
@ -127,4 +137,16 @@ public class Utils {
|
|||
Log.e("SystemAnimations", "Could not change animation scale to " + animationScale + " :'(");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean moveCursorTo(Cursor cursor, int index, int item) {
|
||||
if (( cursor == null ) || ( ! cursor.moveToFirst() ))
|
||||
return false;
|
||||
|
||||
do {
|
||||
if ( cursor.getInt(index) == item )
|
||||
return true;
|
||||
} while (cursor.moveToNext());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* Copyright 2016 Martijn Brekhof. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.xbmc.kore.tests.mediaprovider;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.test.rule.ActivityTestRule;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.xbmc.kore.host.HostInfo;
|
||||
import org.xbmc.kore.provider.MediaContract;
|
||||
import org.xbmc.kore.testhelpers.Database;
|
||||
import org.xbmc.kore.testhelpers.TestUtils;
|
||||
import org.xbmc.kore.testhelpers.Utils;
|
||||
import org.xbmc.kore.ui.MoviesActivity;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class MediaProviderMusicTest {
|
||||
private static HostInfo hostInfo;
|
||||
private static Context context;
|
||||
private ContentResolver contentResolver;
|
||||
|
||||
/**
|
||||
* Note that the activity MoviesActivity is only needed for context and is not tested
|
||||
*/
|
||||
@Rule
|
||||
public ActivityTestRule<MoviesActivity> mActivityRule = new ActivityTestRule<>(
|
||||
MoviesActivity.class);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
context = mActivityRule.getActivity();
|
||||
|
||||
if (hostInfo == null) // We only need to fill the database the first time
|
||||
hostInfo = Database.fill(context);
|
||||
|
||||
contentResolver = mActivityRule.getActivity().getContentResolver();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanup() {
|
||||
Database.flush(context, hostInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAllArtistsTest() {
|
||||
Uri uri = MediaContract.Artists.buildArtistsListUri(hostInfo.getId());
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Artist.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 227, cursor.getCount());
|
||||
TestUtils.testCursorContainsRange(cursor, cursor.getColumnIndex(MediaContract.ArtistsColumns.ARTISTID),
|
||||
1, 94);
|
||||
//Artist id 95 should be missing
|
||||
TestUtils.testCursorContainsRange(cursor, cursor.getColumnIndex(MediaContract.ArtistsColumns.ARTISTID),
|
||||
96, 228);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryArtistTest() {
|
||||
Uri uri = MediaContract.Artists.buildArtistUri(hostInfo.getId(), TestValues.Artist.artistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Artist.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
TestValues.Artist.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAllAlbumsTest() {
|
||||
Uri uri = MediaContract.Albums.buildAlbumsListUri(hostInfo.getId());
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 232, cursor.getCount());
|
||||
int columnIndex = cursor.getColumnIndex(MediaContract.AlbumsColumns.ALBUMID);
|
||||
TestUtils.testCursorContainsRange(cursor, columnIndex, 1, 75);
|
||||
TestUtils.testCursorContainsRange(cursor, columnIndex, 77, 82);
|
||||
TestUtils.testCursorContainsRange(cursor, columnIndex, 84, 234);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAlbumTest() {
|
||||
Uri uri = MediaContract.Albums.buildAlbumUri(hostInfo.getId(), TestValues.Album.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
TestValues.Album.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAlbumsForArtistTest() {
|
||||
Uri uri = MediaContract.AlbumArtists.buildAlbumsForArtistListUri(hostInfo.getId(),
|
||||
TestValues.Artist.artistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
TestValues.Album.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAlbumsForGenreTest() {
|
||||
int genreId = 13;
|
||||
Uri uri = MediaContract.AlbumGenres.buildAlbumsForGenreListUri(hostInfo.getId(), genreId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 31, cursor.getCount());
|
||||
TestUtils.testCursorContainsNumbers(cursor, cursor.getColumnIndex(MediaContract.Albums.ALBUMID),
|
||||
28, 43, 47, 66, 100);
|
||||
TestUtils.testCursorContainsRange(cursor, cursor.getColumnIndex(MediaContract.Albums.ALBUMID),
|
||||
50, 55);
|
||||
TestUtils.testCursorContainsRange(cursor, cursor.getColumnIndex(MediaContract.Albums.ALBUMID),
|
||||
201, 220);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAlbumSongsTest() {
|
||||
Uri uri = MediaContract.Songs.buildAlbumSongsListUri(hostInfo.getId(), TestValues.Album.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, new String[] {MediaContract.Songs.SONGID}, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 17, cursor.getCount());
|
||||
TestUtils.testCursorContainsRange(cursor, cursor.getColumnIndex(MediaContract.SongsColumns.SONGID),
|
||||
96, 112);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAlbumWithoutArtist() {
|
||||
Uri uri = MediaContract.Albums.buildAlbumUri(hostInfo.getId(),
|
||||
TestValues.AlbumWithoutArtist.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.AlbumWithoutArtist.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
TestValues.AlbumWithoutArtist.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAlbumWithMultipleArtists() {
|
||||
Uri uri = MediaContract.Albums.buildAlbumUri(hostInfo.getId(),
|
||||
TestValues.AlbumWithMultipleArtists.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.AlbumWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
TestValues.AlbumWithMultipleArtists.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryArtistSongsTest() {
|
||||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(), TestValues.ArtistSong.artistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.ArtistSong.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 17, cursor.getCount());
|
||||
TestUtils.testCursorContainsRange(cursor, cursor.getColumnIndex(MediaContract.SongsColumns.SONGID),
|
||||
96, 112);
|
||||
assertTrue(Utils.moveCursorTo(cursor, cursor.getColumnIndex(MediaContract.Songs.SONGID),
|
||||
TestValues.ArtistSong.songId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void querySongWithArtistWithoutAlbumTest() {
|
||||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(),
|
||||
TestValues.SongWithArtistWithoutAlbum.artistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.SongWithArtistWithoutAlbum.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
Utils.cursorToString(cursor);
|
||||
TestValues.SongWithArtistWithoutAlbum.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryFirstArtistSongWithMultipleArtistsTest() {
|
||||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(),
|
||||
TestValues.SongWithMultipleArtists.firstArtistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.SongWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
TestValues.SongWithMultipleArtists.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void querySecondArtistSongWithMultipleArtistsTest() {
|
||||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(),
|
||||
TestValues.SongWithMultipleArtists.secondArtistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.SongWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
TestValues.SongWithMultipleArtists.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryThirdArtistSongWithMultipleArtistsTest() {
|
||||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(),
|
||||
TestValues.SongWithMultipleArtists.thirdArtistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri,
|
||||
TestValues.SongWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
TestValues.SongWithMultipleArtists.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAllSongsTest() {
|
||||
Uri uri = MediaContract.Songs.buildSongsListUri(hostInfo.getId());
|
||||
|
||||
Cursor cursor = contentResolver.query(uri,
|
||||
TestValues.ArtistSong.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1804, cursor.getCount());
|
||||
TestUtils.testCursorContainsRange(cursor, cursor.getColumnIndex(MediaContract.Songs.SONGID),
|
||||
1, 1804);
|
||||
|
||||
//Test if list also contains a song WITH an album AND an artist
|
||||
assertTrue(Utils.moveCursorTo(cursor, cursor.getColumnIndex(MediaContract.Songs.SONGID),
|
||||
TestValues.SongWithAlbumAndArtist.songId));
|
||||
TestValues.SongWithAlbumAndArtist.test(cursor);
|
||||
|
||||
//Test if list also contains a song WITHOUT an album but WITH an artist
|
||||
assertTrue(Utils.moveCursorTo(cursor, cursor.getColumnIndex(MediaContract.Songs.SONGID),
|
||||
TestValues.SongWithArtistWithoutAlbum.songId));
|
||||
TestValues.SongWithArtistWithoutAlbum.test(cursor);
|
||||
|
||||
//Test if list also contains a song WITH an album but WITHOUT an artist
|
||||
assertTrue(Utils.moveCursorTo(cursor, cursor.getColumnIndex(MediaContract.Songs.SONGID),
|
||||
TestValues.SongWithAlbumWithoutArtist.songId));
|
||||
TestValues.SongWithAlbumWithoutArtist.test(cursor);
|
||||
|
||||
//Test if list contains a song WITH MULTIPLE artists
|
||||
assertTrue(Utils.moveCursorTo(cursor, cursor.getColumnIndex(MediaContract.Songs.SONGID),
|
||||
TestValues.SongWithMultipleArtists.songId));
|
||||
TestValues.SongWithMultipleArtists.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAlbumWithMultipleArtistsTest() {
|
||||
Uri uri = MediaContract.Albums.buildAlbumUri(hostInfo.getId(),
|
||||
TestValues.AlbumWithMultipleArtists.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri,
|
||||
TestValues.AlbumWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
LogUtils.LOGD("MediaProviderMusicTest", Utils.cursorToString(cursor));
|
||||
TestValues.AlbumWithMultipleArtists.test(cursor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryAllGenresTest() {
|
||||
Uri uri = MediaContract.AudioGenres.buildAudioGenresListUri(hostInfo.getId());
|
||||
|
||||
Cursor cursor = contentResolver.query(uri,
|
||||
new String[] {MediaContract.AudioGenresColumns.GENREID},
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 39, cursor.getCount());
|
||||
TestUtils.testCursorContainsRange(cursor,
|
||||
cursor.getColumnIndex(MediaContract.AudioGenresColumns.GENREID),
|
||||
1, 39);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Copyright 2016 Martijn Brekhof. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.xbmc.kore.tests.mediaprovider;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import org.xbmc.kore.provider.MediaContract;
|
||||
import org.xbmc.kore.provider.MediaDatabase;
|
||||
import org.xbmc.kore.provider.MediaProvider;
|
||||
import org.xbmc.kore.ui.AlbumListFragment;
|
||||
import org.xbmc.kore.ui.ArtistListFragment;
|
||||
import org.xbmc.kore.ui.ArtistOverviewFragment;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestValues {
|
||||
public static class Artist {
|
||||
public static int artistId = 13;
|
||||
public static String artist = "Bernstein, Charles";
|
||||
|
||||
public static String[] PROJECTION = MediaContract.Artists.ALL_COLUMNS;
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
assertEquals(TestValues.Artist.artistId, cursor.getInt(cursor.getColumnIndex(MediaContract.ArtistsColumns.ARTISTID)));
|
||||
assertEquals(TestValues.Artist.artist, cursor.getString(cursor.getColumnIndex(MediaContract.ArtistsColumns.ARTIST)));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Album {
|
||||
public static int albumId = 13;
|
||||
public static String title = "The Entity";
|
||||
public static String displayArtist = "Bernstein, Charles";
|
||||
public static int year = 1982;
|
||||
public static String genre = "Soundtrack";
|
||||
|
||||
public static String[] PROJECTION = MediaContract.Albums.ALL_COLUMNS;
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
int resultAlbumId = cursor.getInt(cursor.getColumnIndex(MediaContract.AlbumsColumns.ALBUMID));
|
||||
assertEquals(albumId, resultAlbumId);
|
||||
String resultTitle = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.TITLE));
|
||||
assertEquals(title, resultTitle);
|
||||
String resultArtist = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.DISPLAYARTIST));
|
||||
assertEquals(displayArtist, resultArtist);
|
||||
String resultGenre = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.GENRE));
|
||||
assertEquals(genre, resultGenre);
|
||||
int resultYear = cursor.getInt(cursor.getColumnIndex(MediaContract.AlbumsColumns.YEAR));
|
||||
assertEquals(year, resultYear);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AlbumWithoutArtist {
|
||||
public static int albumId = 82;
|
||||
public static String title = "The Album";
|
||||
public static String displayArtist = "";
|
||||
public static int year = 0;
|
||||
public static String genre = "";
|
||||
|
||||
public static String[] PROJECTION = MediaContract.Albums.ALL_COLUMNS;
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
int resultAlbumId = cursor.getInt(cursor.getColumnIndex(MediaContract.AlbumsColumns.ALBUMID));
|
||||
assertEquals(albumId, resultAlbumId);
|
||||
String resultTitle = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.TITLE));
|
||||
assertEquals(title, resultTitle);
|
||||
String resultArtist = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.DISPLAYARTIST));
|
||||
assertEquals(displayArtist, resultArtist);
|
||||
String resultGenre = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.GENRE));
|
||||
assertEquals(genre, resultGenre);
|
||||
int resultYear = cursor.getInt(cursor.getColumnIndex(MediaContract.AlbumsColumns.YEAR));
|
||||
assertEquals(year, resultYear);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AlbumWithMultipleArtists {
|
||||
public static int albumId = 234;
|
||||
public static String title = "ThreeArtistsAlbum";
|
||||
public static String displayArtist = "First artist / Second artist / Third artist";
|
||||
public static int year = 0;
|
||||
public static String genre = "";
|
||||
|
||||
public static String[] PROJECTION = MediaContract.Albums.ALL_COLUMNS;
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
int resultAlbumId = cursor.getInt(cursor.getColumnIndex(MediaContract.AlbumsColumns.ALBUMID));
|
||||
assertEquals(albumId, resultAlbumId);
|
||||
String resultTitle = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.TITLE));
|
||||
assertEquals(title, resultTitle);
|
||||
String resultArtist = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.DISPLAYARTIST));
|
||||
assertEquals(displayArtist, resultArtist);
|
||||
String resultGenre = cursor.getString(cursor.getColumnIndex(MediaContract.AlbumsColumns.GENRE));
|
||||
assertEquals(genre, resultGenre);
|
||||
int resultYear = cursor.getInt(cursor.getColumnIndex(MediaContract.AlbumsColumns.YEAR));
|
||||
assertEquals(year, resultYear);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ArtistSong {
|
||||
public static int songId = 96;
|
||||
public static int artistId = Artist.artistId;
|
||||
public static int albumId = Album.albumId;
|
||||
public static String title = "Intro & Main Title";
|
||||
public static String[] PROJECTION = new String[] { MediaContract.Songs.SONGID,
|
||||
MediaContract.Songs.TITLE,
|
||||
MediaContract.Songs.ALBUMID,
|
||||
MediaContract.SongArtists.ARTISTID,
|
||||
MediaContract.Artists.ARTIST };
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
assertEquals(songId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.SONGID)));
|
||||
assertEquals(title, cursor.getString(cursor.getColumnIndex(MediaContract.Songs.TITLE)));
|
||||
assertEquals(albumId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.ALBUMID)));
|
||||
assertEquals(artistId, cursor.getInt(cursor.getColumnIndex(MediaContract.SongArtists.ARTISTID)));
|
||||
}
|
||||
}
|
||||
|
||||
public static class SongWithAlbumAndArtist {
|
||||
public static int songId = 1487;
|
||||
public static int artistId = 195;
|
||||
public static int albumId = 201;
|
||||
public static String title = "The Lone Ranger (William Tell Overture)";
|
||||
|
||||
public static String[] PROJECTION = ArtistSong.PROJECTION;
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
assertEquals(songId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.SONGID)));
|
||||
assertEquals(title, cursor.getString(cursor.getColumnIndex(MediaContract.Songs.TITLE)));
|
||||
assertEquals(albumId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.ALBUMID)));
|
||||
assertEquals(artistId, cursor.getInt(cursor.getColumnIndex(MediaContract.SongArtists.ARTISTID)));
|
||||
}
|
||||
}
|
||||
|
||||
public static class SongWithAlbumWithoutArtist {
|
||||
public static int songId = 1219;
|
||||
public static int artistId = 0;
|
||||
public static String title = "Unknown";
|
||||
public static int albumId = 82;
|
||||
|
||||
public static String[] PROJECTION = ArtistSong.PROJECTION;
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
assertEquals(songId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.SONGID)));
|
||||
assertEquals(title, cursor.getString(cursor.getColumnIndex(MediaContract.Songs.TITLE)));
|
||||
assertEquals(albumId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.ALBUMID)));
|
||||
assertEquals(artistId, cursor.getInt(cursor.getColumnIndex(MediaContract.SongArtists.ARTISTID)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class SongWithArtistWithoutAlbum {
|
||||
public static int songId = 1128;
|
||||
public static int artistId = 73;
|
||||
public static int albumId = 76;
|
||||
public static String title = "Unknown";
|
||||
|
||||
public static String[] PROJECTION = ArtistSong.PROJECTION;
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
assertEquals(songId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.SONGID)));
|
||||
assertEquals(title, cursor.getString(cursor.getColumnIndex(MediaContract.Songs.TITLE)));
|
||||
assertEquals(albumId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.ALBUMID)));
|
||||
assertEquals(artistId, cursor.getInt(cursor.getColumnIndex(MediaContract.SongArtists.ARTISTID)));
|
||||
}
|
||||
}
|
||||
|
||||
public static class SongWithMultipleArtists {
|
||||
public static int songId = 1804;
|
||||
public static int firstArtistId = 226;
|
||||
public static int secondArtistId = 227;
|
||||
public static int thirdArtistId = 228;
|
||||
public static int albumId = 234;
|
||||
public static String title = "threeartists";
|
||||
|
||||
public static String[] PROJECTION = ArtistSong.PROJECTION;
|
||||
|
||||
public static void test(Cursor cursor) {
|
||||
assertEquals(songId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.SONGID)));
|
||||
assertEquals(title, cursor.getString(cursor.getColumnIndex(MediaContract.Songs.TITLE)));
|
||||
assertEquals(albumId, cursor.getInt(cursor.getColumnIndex(MediaContract.Songs.ALBUMID)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,8 +49,8 @@ public class RestoreSearchQueryViewPagerTest {
|
|||
private final int ARTIST_SEARCH_QUERY_LIST_SIZE = 2;
|
||||
private final String ALBUMS_SEARCH_QUERY = "tes";
|
||||
private final int ALBUM_SEARCH_QUERY_LIST_SIZE = 3;
|
||||
private final int ARTIST_COMPLETE_LIST_SIZE = 224;
|
||||
private final int ALBUM_COMPLETE_LIST_SIZE = 231;
|
||||
private final int ARTIST_COMPLETE_LIST_SIZE = 227;
|
||||
private final int ALBUM_COMPLETE_LIST_SIZE = 232;
|
||||
|
||||
private LoaderIdlingResource loaderIdlingResource;
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
"jsonrpc" : "2.0",
|
||||
"result" : {
|
||||
"limits" : {
|
||||
"total" : 231,
|
||||
"total" : 232,
|
||||
"start" : 0,
|
||||
"end" : 231
|
||||
"end" : 234
|
||||
},
|
||||
"albums" : [
|
||||
{
|
||||
|
@ -7538,6 +7538,41 @@
|
|||
"theme" : [],
|
||||
"musicbrainzalbumid" : "",
|
||||
"playcount" : 0
|
||||
},
|
||||
{
|
||||
"musicbrainzalbumid" : "",
|
||||
"description" : "",
|
||||
"artist" : [
|
||||
"First artist",
|
||||
"Second artist",
|
||||
"Third artist"
|
||||
],
|
||||
"type" : "",
|
||||
"title" : "ThreeArtistsAlbum",
|
||||
"label" : "ThreeArtistsAlbum",
|
||||
"rating" : 0,
|
||||
"albumlabel" : "",
|
||||
"playcount" : 0,
|
||||
"albumid" : 234,
|
||||
"thumbnail" : "",
|
||||
"genreid" : [],
|
||||
"artistid" : [
|
||||
226,
|
||||
227,
|
||||
228
|
||||
],
|
||||
"mood" : [],
|
||||
"theme" : [],
|
||||
"genre" : [],
|
||||
"displayartist" : "First artist / Second artist / Third artist",
|
||||
"style" : [],
|
||||
"fanart" : "",
|
||||
"year" : 0,
|
||||
"musicbrainzalbumartistid" : [
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -4482,11 +4482,71 @@
|
|||
"fanart" : "",
|
||||
"mood" : [],
|
||||
"style" : []
|
||||
},
|
||||
{
|
||||
"description" : "",
|
||||
"disbanded" : "",
|
||||
"artist" : "First artist",
|
||||
"instrument" : [],
|
||||
"label" : "First artist",
|
||||
"born" : "",
|
||||
"yearsactive" : [],
|
||||
"genre" : [],
|
||||
"thumbnail" : "",
|
||||
"mood" : [],
|
||||
"artistid" : 226,
|
||||
"musicbrainzartistid" : [
|
||||
""
|
||||
],
|
||||
"died" : "",
|
||||
"formed" : "",
|
||||
"style" : [],
|
||||
"fanart" : ""
|
||||
},
|
||||
{
|
||||
"description" : "",
|
||||
"disbanded" : "",
|
||||
"artist" : "Second artist",
|
||||
"instrument" : [],
|
||||
"label" : "Second artist",
|
||||
"born" : "",
|
||||
"yearsactive" : [],
|
||||
"genre" : [],
|
||||
"thumbnail" : "",
|
||||
"mood" : [],
|
||||
"artistid" : 227,
|
||||
"musicbrainzartistid" : [
|
||||
""
|
||||
],
|
||||
"died" : "",
|
||||
"formed" : "",
|
||||
"style" : [],
|
||||
"fanart" : ""
|
||||
},
|
||||
{
|
||||
"description" : "",
|
||||
"disbanded" : "",
|
||||
"artist" : "Third artist",
|
||||
"instrument" : [],
|
||||
"label" : "Third artist",
|
||||
"born" : "",
|
||||
"yearsactive" : [],
|
||||
"genre" : [],
|
||||
"thumbnail" : "",
|
||||
"mood" : [],
|
||||
"artistid" : 228,
|
||||
"musicbrainzartistid" : [
|
||||
""
|
||||
],
|
||||
"died" : "",
|
||||
"formed" : "",
|
||||
"style" : [],
|
||||
"fanart" : ""
|
||||
}
|
||||
],
|
||||
"limits" : {
|
||||
"total" : 224,
|
||||
"end" : 224,
|
||||
"total" : 227,
|
||||
"end" : 228,
|
||||
"start" : 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75109,12 +75109,58 @@
|
|||
"songid" : 1618,
|
||||
"title" : "Reel - Upstairs in a Tent",
|
||||
"album" : "Ireland's Best Fiddle Tunes Disk 2"
|
||||
},
|
||||
{
|
||||
"musicbrainzalbumartistid" : [],
|
||||
"year" : 0,
|
||||
"albumartistid" : [
|
||||
226,
|
||||
227,
|
||||
228
|
||||
],
|
||||
"disc" : 0,
|
||||
"musicbrainztrackid" : "",
|
||||
"fanart" : "",
|
||||
"file" : "/Users/martijn/Projects/dummymediafiles/media/music/ThreeArtists/ThreeArtistsAlbum/01-threeartists.mp3",
|
||||
"genre" : [],
|
||||
"displayartist" : "First artist / Second artist / Third artist",
|
||||
"comment" : "",
|
||||
"musicbrainzartistid" : [],
|
||||
"artistid" : [
|
||||
226,
|
||||
227,
|
||||
228
|
||||
],
|
||||
"lastplayed" : "",
|
||||
"songid" : 1804,
|
||||
"playcount" : 0,
|
||||
"thumbnail" : "",
|
||||
"albumartist" : [
|
||||
"First artist",
|
||||
"Second artist",
|
||||
"Third artist"
|
||||
],
|
||||
"albumid" : 234,
|
||||
"genreid" : [],
|
||||
"track" : 1,
|
||||
"label" : "threeartists",
|
||||
"title" : "threeartists",
|
||||
"rating" : 0,
|
||||
"artist" : [
|
||||
"First artist",
|
||||
"Second artist",
|
||||
"Third artist"
|
||||
],
|
||||
"lyrics" : "",
|
||||
"duration" : 5,
|
||||
"album" : "ThreeArtistsAlbum",
|
||||
"musicbrainzalbumid" : ""
|
||||
}
|
||||
],
|
||||
"limits" : {
|
||||
"end" : 1803,
|
||||
"end" : 1804,
|
||||
"start" : 0,
|
||||
"total" : 1803
|
||||
"total" : 1804
|
||||
}
|
||||
},
|
||||
"jsonrpc" : "2.0"
|
||||
|
|
|
@ -805,7 +805,7 @@ public class MediaProvider extends ContentProvider {
|
|||
* {@link MediaContract} fields that are fully qualified with a specific
|
||||
* parent {@link MediaDatabase.Tables}. Used when needed to work around SQL ambiguity.
|
||||
*/
|
||||
private interface Qualified {
|
||||
public interface Qualified {
|
||||
String ALBUM_ARTISTS_HOST_ID =
|
||||
MediaDatabase.Tables.ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.HOST_ID;
|
||||
String ALBUM_ARTISTS_ARTISTID =
|
||||
|
|
|
@ -86,6 +86,7 @@ public class SyncMusic extends SyncItem {
|
|||
AudioType.FieldsArtists.FANART,
|
||||
AudioType.FieldsArtists.THUMBNAIL
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets all artists recursively and forwards the call to Genres
|
||||
* Genres->Albums->Songs
|
||||
|
@ -115,13 +116,7 @@ public class SyncMusic extends SyncItem {
|
|||
// First delete all music info
|
||||
if (startIdx == 0) deleteMusicInfo(contentResolver, hostId);
|
||||
|
||||
// Insert artists
|
||||
ContentValues artistValuesBatch[] = new ContentValues[items.size()];
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
AudioType.DetailsArtist artist = items.get(i);
|
||||
artistValuesBatch[i] = SyncUtils.contentValuesFromArtist(hostId, artist);
|
||||
}
|
||||
contentResolver.bulkInsert(MediaContract.Artists.CONTENT_URI, artistValuesBatch);
|
||||
insertArtists(items, contentResolver);
|
||||
|
||||
if (moreItemsAvailable(limitsReturned)) {
|
||||
LogUtils.LOGD(TAG, "chainCallSyncArtists: More results on media center, recursing.");
|
||||
|
@ -151,6 +146,8 @@ public class SyncMusic extends SyncItem {
|
|||
where, new String[]{String.valueOf(hostId)});
|
||||
contentResolver.delete(MediaContract.AlbumGenres.CONTENT_URI,
|
||||
where, new String[]{String.valueOf(hostId)});
|
||||
contentResolver.delete(MediaContract.SongArtists.CONTENT_URI,
|
||||
where, new String[]{String.valueOf(hostId)});
|
||||
contentResolver.delete(MediaContract.Songs.CONTENT_URI,
|
||||
where, new String[]{String.valueOf(hostId)});
|
||||
contentResolver.delete(MediaContract.AudioGenres.CONTENT_URI,
|
||||
|
@ -178,16 +175,9 @@ public class SyncMusic extends SyncItem {
|
|||
action.execute(hostConnection, new ApiCallback<List<LibraryType.DetailsGenre>>() {
|
||||
@Override
|
||||
public void onSuccess(List<LibraryType.DetailsGenre> result) {
|
||||
if (result == null) result = new ArrayList<>(0); // Safeguard
|
||||
ContentValues genresValuesBatch[] = new ContentValues[result.size()];
|
||||
if (result != null)
|
||||
insertGenresItems(result, contentResolver);
|
||||
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
LibraryType.DetailsGenre genre = result.get(i);
|
||||
genresValuesBatch[i] = SyncUtils.contentValuesFromAudioGenre(hostId, genre);
|
||||
}
|
||||
|
||||
// Insert the genres and proceed to albums
|
||||
contentResolver.bulkInsert(MediaContract.AudioGenres.CONTENT_URI, genresValuesBatch);
|
||||
chainCallSyncAlbums(orchestrator, hostConnection, callbackHandler, contentResolver, 0);
|
||||
}
|
||||
|
||||
|
@ -240,44 +230,7 @@ public class SyncMusic extends SyncItem {
|
|||
}
|
||||
|
||||
// Insert the partial results
|
||||
ContentValues albumValuesBatch[] = new ContentValues[items.size()];
|
||||
int artistsCount = 0, genresCount = 0;
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
AudioType.DetailsAlbum album = items.get(i);
|
||||
albumValuesBatch[i] = SyncUtils.contentValuesFromAlbum(hostId, album);
|
||||
|
||||
artistsCount += album.artistid.size();
|
||||
genresCount += album.genreid.size();
|
||||
}
|
||||
contentResolver.bulkInsert(MediaContract.Albums.CONTENT_URI, albumValuesBatch);
|
||||
|
||||
LogUtils.LOGD(TAG, "Finished inserting albums in: " +
|
||||
(System.currentTimeMillis() - albumSyncStartTime));
|
||||
|
||||
// Iterate on each album, collect the artists and the genres and insert them
|
||||
ContentValues albumArtistsValuesBatch[] = new ContentValues[artistsCount];
|
||||
ContentValues albumGenresValuesBatch[] = new ContentValues[genresCount];
|
||||
int artistCount = 0, genreCount = 0;
|
||||
for (AudioType.DetailsAlbum album : items) {
|
||||
for (int artistId : album.artistid) {
|
||||
albumArtistsValuesBatch[artistCount] = new ContentValues();
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.HOST_ID, hostId);
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.ALBUMID, album.albumid);
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.ARTISTID, artistId);
|
||||
artistCount++;
|
||||
}
|
||||
|
||||
for (int genreId : album.genreid) {
|
||||
albumGenresValuesBatch[genreCount] = new ContentValues();
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.HOST_ID, hostId);
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.ALBUMID, album.albumid);
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.GENREID, genreId);
|
||||
genreCount++;
|
||||
}
|
||||
}
|
||||
|
||||
contentResolver.bulkInsert(MediaContract.AlbumArtists.CONTENT_URI, albumArtistsValuesBatch);
|
||||
contentResolver.bulkInsert(MediaContract.AlbumGenres.CONTENT_URI, albumGenresValuesBatch);
|
||||
insertAlbumsItems(items, contentResolver);
|
||||
|
||||
LogUtils.LOGD(TAG, "Finished inserting artists and genres in: " +
|
||||
(System.currentTimeMillis() - albumSyncStartTime));
|
||||
|
@ -346,29 +299,8 @@ public class SyncMusic extends SyncItem {
|
|||
limitsReturned = result.limits;
|
||||
}
|
||||
|
||||
int totalArtistsCount = 0;
|
||||
// Save partial results to DB
|
||||
ContentValues songValuesBatch[] = new ContentValues[items.size()];
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
AudioType.DetailsSong song = items.get(i);
|
||||
songValuesBatch[i] = SyncUtils.contentValuesFromSong(hostId, song);
|
||||
totalArtistsCount += song.artistid.size();
|
||||
}
|
||||
contentResolver.bulkInsert(MediaContract.Songs.CONTENT_URI, songValuesBatch);
|
||||
|
||||
// Iterate on each song, collect the artists and insert them
|
||||
ContentValues songArtistsValuesBatch[] = new ContentValues[totalArtistsCount];
|
||||
int artistCount = 0;
|
||||
for (AudioType.DetailsSong song : items) {
|
||||
for (int artistId : song.artistid) {
|
||||
songArtistsValuesBatch[artistCount] = new ContentValues();
|
||||
songArtistsValuesBatch[artistCount].put(MediaContract.SongArtists.HOST_ID, hostId);
|
||||
songArtistsValuesBatch[artistCount].put(MediaContract.SongArtists.SONGID, song.songid);
|
||||
songArtistsValuesBatch[artistCount].put(MediaContract.SongArtists.ARTISTID, artistId);
|
||||
artistCount++;
|
||||
}
|
||||
}
|
||||
contentResolver.bulkInsert(MediaContract.SongArtists.CONTENT_URI, songArtistsValuesBatch);
|
||||
insertSongsItems(items, contentResolver);
|
||||
|
||||
if (moreItemsAvailable(limitsReturned)) {
|
||||
LogUtils.LOGD(TAG, "chainCallSyncSongs: More results on media center, recursing.");
|
||||
|
@ -384,12 +316,98 @@ public class SyncMusic extends SyncItem {
|
|||
|
||||
@Override
|
||||
public void onError(int errorCode, String description) {
|
||||
// Ok, something bad happend, just quit
|
||||
// Ok, something bad happened, just quit
|
||||
orchestrator.syncItemFailed(errorCode, description);
|
||||
}
|
||||
}, callbackHandler);
|
||||
}
|
||||
|
||||
public void insertArtists(List<AudioType.DetailsArtist> items, ContentResolver contentResolver) {
|
||||
ContentValues artistValuesBatch[] = new ContentValues[items.size()];
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
AudioType.DetailsArtist artist = items.get(i);
|
||||
artistValuesBatch[i] = SyncUtils.contentValuesFromArtist(hostId, artist);
|
||||
}
|
||||
contentResolver.bulkInsert(MediaContract.Artists.CONTENT_URI, artistValuesBatch);
|
||||
}
|
||||
|
||||
public void insertGenresItems(List<LibraryType.DetailsGenre> items, ContentResolver contentResolver) {
|
||||
ContentValues genresValuesBatch[] = new ContentValues[items.size()];
|
||||
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
LibraryType.DetailsGenre genre = items.get(i);
|
||||
genresValuesBatch[i] = SyncUtils.contentValuesFromAudioGenre(hostId, genre);
|
||||
}
|
||||
|
||||
// Insert the genres and proceed to albums
|
||||
contentResolver.bulkInsert(MediaContract.AudioGenres.CONTENT_URI, genresValuesBatch);
|
||||
}
|
||||
|
||||
public void insertAlbumsItems(List<AudioType.DetailsAlbum> items, ContentResolver contentResolver) {
|
||||
ContentValues albumValuesBatch[] = new ContentValues[items.size()];
|
||||
int artistsCount = 0, genresCount = 0;
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
AudioType.DetailsAlbum album = items.get(i);
|
||||
albumValuesBatch[i] = SyncUtils.contentValuesFromAlbum(hostId, album);
|
||||
|
||||
artistsCount += album.artistid.size();
|
||||
genresCount += album.genreid.size();
|
||||
}
|
||||
contentResolver.bulkInsert(MediaContract.Albums.CONTENT_URI, albumValuesBatch);
|
||||
|
||||
// Iterate on each album, collect the artists and the genres and insert them
|
||||
ContentValues albumArtistsValuesBatch[] = new ContentValues[artistsCount];
|
||||
ContentValues albumGenresValuesBatch[] = new ContentValues[genresCount];
|
||||
int artistCount = 0, genreCount = 0;
|
||||
for (AudioType.DetailsAlbum album : items) {
|
||||
for (int artistId : album.artistid) {
|
||||
albumArtistsValuesBatch[artistCount] = new ContentValues();
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.HOST_ID, hostId);
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.ALBUMID, album.albumid);
|
||||
albumArtistsValuesBatch[artistCount].put(MediaContract.AlbumArtists.ARTISTID, artistId);
|
||||
artistCount++;
|
||||
}
|
||||
|
||||
for (int genreId : album.genreid) {
|
||||
albumGenresValuesBatch[genreCount] = new ContentValues();
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.HOST_ID, hostId);
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.ALBUMID, album.albumid);
|
||||
albumGenresValuesBatch[genreCount].put(MediaContract.AlbumGenres.GENREID, genreId);
|
||||
genreCount++;
|
||||
}
|
||||
}
|
||||
|
||||
contentResolver.bulkInsert(MediaContract.AlbumArtists.CONTENT_URI, albumArtistsValuesBatch);
|
||||
contentResolver.bulkInsert(MediaContract.AlbumGenres.CONTENT_URI, albumGenresValuesBatch);
|
||||
}
|
||||
|
||||
public void insertSongsItems(List<AudioType.DetailsSong> items, ContentResolver contentResolver) {
|
||||
ContentValues songValuesBatch[] = new ContentValues[items.size()];
|
||||
int totalArtistsCount = 0;
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
AudioType.DetailsSong song = items.get(i);
|
||||
songValuesBatch[i] = SyncUtils.contentValuesFromSong(hostId, song);
|
||||
|
||||
totalArtistsCount += song.artistid.size();
|
||||
}
|
||||
contentResolver.bulkInsert(MediaContract.Songs.CONTENT_URI, songValuesBatch);
|
||||
|
||||
// Iterate on each song, collect the artists and insert them
|
||||
ContentValues songArtistsValuesBatch[] = new ContentValues[totalArtistsCount];
|
||||
int artistCount = 0;
|
||||
for (AudioType.DetailsSong song : items) {
|
||||
for (int artistId : song.artistid) {
|
||||
songArtistsValuesBatch[artistCount] = new ContentValues();
|
||||
songArtistsValuesBatch[artistCount].put(MediaContract.SongArtists.HOST_ID, hostId);
|
||||
songArtistsValuesBatch[artistCount].put(MediaContract.SongArtists.SONGID, song.songid);
|
||||
songArtistsValuesBatch[artistCount].put(MediaContract.SongArtists.ARTISTID, artistId);
|
||||
artistCount++;
|
||||
}
|
||||
}
|
||||
|
||||
contentResolver.bulkInsert(MediaContract.SongArtists.CONTENT_URI, songArtistsValuesBatch);
|
||||
}
|
||||
|
||||
private boolean moreItemsAvailable(ListType.LimitsReturned limitsReturned) {
|
||||
boolean moreItemsAvailable = false;
|
||||
if (limitsReturned != null) {
|
||||
|
|
|
@ -710,7 +710,7 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
|
|||
/**
|
||||
* Album details query parameters.
|
||||
*/
|
||||
private interface AlbumDetailsQuery {
|
||||
public interface AlbumDetailsQuery {
|
||||
String[] PROJECTION = {
|
||||
BaseColumns._ID,
|
||||
MediaContract.Albums.TITLE,
|
||||
|
@ -739,7 +739,7 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
|
|||
/**
|
||||
* Movie cast list query parameters.
|
||||
*/
|
||||
private interface AlbumSongsListQuery {
|
||||
public interface AlbumSongsListQuery {
|
||||
String[] PROJECTION = {
|
||||
BaseColumns._ID,
|
||||
MediaContract.Songs.TITLE,
|
||||
|
|
|
@ -163,7 +163,7 @@ public class AlbumListFragment extends AbstractCursorListFragment {
|
|||
/**
|
||||
* Album list query parameters.
|
||||
*/
|
||||
private interface AlbumListQuery {
|
||||
public interface AlbumListQuery {
|
||||
String[] PROJECTION = {
|
||||
BaseColumns._ID,
|
||||
MediaContract.Albums.ALBUMID,
|
||||
|
|
|
@ -108,7 +108,7 @@ public class AudioGenresListFragment extends AbstractCursorListFragment {
|
|||
/**
|
||||
* Audio genres list query parameters.
|
||||
*/
|
||||
private interface AudioGenreListQuery {
|
||||
public interface AudioGenreListQuery {
|
||||
String[] PROJECTION = {
|
||||
BaseColumns._ID,
|
||||
MediaContract.AudioGenres.GENREID,
|
||||
|
|
|
@ -134,7 +134,7 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
/**
|
||||
* Album songs list query parameters.
|
||||
*/
|
||||
private interface SongsListQuery {
|
||||
public interface SongsListQuery {
|
||||
String[] PROJECTION = {
|
||||
MediaDatabase.Tables.SONGS + "." + BaseColumns._ID,
|
||||
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.TITLE,
|
||||
|
|
|
@ -76,6 +76,22 @@ public class Utils {
|
|||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Concats a list of integers...
|
||||
* @param list
|
||||
* @param delimiter
|
||||
* @return
|
||||
*/
|
||||
public static String listIntegerConcat(List<Integer> list, String delimiter) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (Integer item : list) {
|
||||
if (!first) builder.append(delimiter);
|
||||
builder.append(item);
|
||||
first = false;
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link Context#startActivity(Intent)} with the given <b>implicit</b> {@link Intent}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# JSON Tools
|
||||
|
||||
Here you will find perl scripts that can be used to retrieve JSON responses from a Kodi instance.
|
||||
The scripts are primarily used to create the JSON source files needed by the instrumentation tests.
|
||||
|
||||
|
||||
## Getting json responses
|
||||
|
||||
Currently there are two scripts available to get media details from a Kodi instance.
|
||||
|
||||
* `getmovies.pl`: retrieves movie details
|
||||
* `getmusic.pl`: retrieves music details
|
||||
|
||||
By default the scripts connect to Kodi running on the same machine (`127.0.0.1`) on port `8080`.
|
||||
If you need to contact a Kodi instance on a different port and/or IP-address change the
|
||||
following line in each script:
|
||||
|
||||
```
|
||||
my $url = "http://127.0.0.1:8080/jsonrpc";
|
||||
```
|
||||
|
||||
## Generating test values
|
||||
|
||||
The instrumentation tests require some values such as "total number of songs", "list of artistids", "genre ids", etc. etc.
|
||||
To generate these values from the JSON files, you can run
|
||||
`gentestnumbers.pl`. This script expects the JSON files to be located in the same directory you execute the script.
|
||||
It also assumes the names of the JSON files are the same as generated by `getmovies.pl` and `getmusic.pl`.
|
|
@ -0,0 +1,283 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright 2016 Martijn Brekhof. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cpanel::JSON::XS qw(encode_json decode_json);
|
||||
|
||||
sub printRanges($\@) {
|
||||
my $key = shift;
|
||||
my $arg = shift;
|
||||
my $count = 0;
|
||||
|
||||
my @list = @{$arg};
|
||||
my $current;
|
||||
for (my $i = 1; $i < @list; $i++) {
|
||||
$current = $list[$i]->{$key};
|
||||
my $prev = $list[$i-1]->{$key};
|
||||
if ( $current - $prev == 1 ) {
|
||||
$count++;
|
||||
} else {
|
||||
if ( $count == 0 ) {
|
||||
print $prev;
|
||||
} else {
|
||||
print $prev - $count . "-" . $prev;
|
||||
}
|
||||
print " ";
|
||||
$count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $count == 0 ) {
|
||||
print $current;
|
||||
} else {
|
||||
print $current - $count . "-" . $current;
|
||||
}
|
||||
}
|
||||
|
||||
sub decodeJson($) {
|
||||
my $filename = shift;
|
||||
local $/ = undef;
|
||||
open (FH, $filename) or die "Error opening file $filename\n";
|
||||
my $json_hash = decode_json(<FH>);
|
||||
close FH;
|
||||
return $json_hash;
|
||||
}
|
||||
|
||||
sub printSong(\%) {
|
||||
my $song = shift;
|
||||
print "title: " . $song->{"title"} . "\n";
|
||||
|
||||
print "artistid: ";
|
||||
for my $artistid ( @{$song->{"artistid"}} ) {
|
||||
print $artistid . " ";
|
||||
}
|
||||
print "\n";
|
||||
|
||||
print "albumid: " . $song->{"albumid"} . "\n";
|
||||
print "songid: " . $song->{"songid"} . "\n";
|
||||
}
|
||||
|
||||
|
||||
sub printAlbum(\%) {
|
||||
my $album = shift;
|
||||
|
||||
print "title: " . $album->{"title"} . "\n";
|
||||
print "albumid: " . $album->{"albumid"} . "\n";
|
||||
print "displayartist: " . $album->{"displayartist"} . "\n";
|
||||
print "year: " . $album->{"year"} . "\n";
|
||||
print "genre: " . @{$album->{"genre"}} . "\n";
|
||||
}
|
||||
|
||||
|
||||
sub getArtists($) {
|
||||
my $json_hash = shift;
|
||||
return $json_hash->{"result"}->{"artists"};
|
||||
}
|
||||
|
||||
sub getArtist($$) {
|
||||
my $json_hash = shift;
|
||||
my $artistid = shift;
|
||||
|
||||
my $artists = getArtists($json_hash);
|
||||
for my $artist (@{$artists}) {
|
||||
if ( $artistid == $artist->{"artistid"} ) {
|
||||
return $artist;
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub getAlbums($) {
|
||||
my $json_hash = shift;
|
||||
return $json_hash->{"result"}->{"albums"};
|
||||
}
|
||||
|
||||
sub getAlbum($$) {
|
||||
my $json_hash = shift;
|
||||
my $albumid = shift;
|
||||
|
||||
my $albums = getAlbums($json_hash);
|
||||
for my $album (@{$albums}) {
|
||||
if ( $albumid == $album->{"albumid"}) {
|
||||
return $album;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub getAlbumsForGenre($$) {
|
||||
my $json_hash = shift;
|
||||
my $genreid = shift;
|
||||
|
||||
my @result;
|
||||
|
||||
my $albums = getAlbums($json_hash);
|
||||
for my $album (@{$albums}) {
|
||||
for my $albumGenreId (@{$album->{"genreid"}}) {
|
||||
if ( $albumGenreId == $genreid ) {
|
||||
push @result, $album;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return @result;
|
||||
}
|
||||
|
||||
sub getSongs(%) {
|
||||
my $json_hash = shift;
|
||||
return $json_hash->{"result"}->{"songs"};
|
||||
}
|
||||
|
||||
sub getSong(\%$) {
|
||||
my $json_hash = shift;
|
||||
my $songid = shift;
|
||||
|
||||
my $songs = getSongs($json_hash);
|
||||
for my $song (@{$songs}) {
|
||||
if ( $songid == $song->{"songid"}) {
|
||||
return $song;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub printArtistTestNumbers($) {
|
||||
my $artistid = shift;
|
||||
|
||||
my $json_hash = decodeJson( "AudioLibrary.GetArtists.json" );
|
||||
my $result = getArtists($json_hash);
|
||||
print "Amount of artists: ", scalar @{$result}, "\n\n";
|
||||
|
||||
print "Artist ids: ";
|
||||
my @artists = sort {$a->{"artistid"} <=> $b->{"artistid"}} @{$result};
|
||||
printRanges("artistid", @artists);
|
||||
print "\n\n";
|
||||
|
||||
print "Artist with artistId $artistid\n";
|
||||
my $artist = getArtist($json_hash, $artistid);
|
||||
print "artist: " . $artist->{"artist"} . "\n";
|
||||
print "artistid: " . $artist->{"artistid"} . "\n";
|
||||
print "\n\n";
|
||||
}
|
||||
|
||||
sub printAlbumTestNumbers($$) {
|
||||
my $albumid = shift;
|
||||
my $genreid = shift;
|
||||
my $json_hash = decodeJson( "AudioLibrary.GetAlbums.json" );
|
||||
my $result = getAlbums($json_hash);
|
||||
print "Amount of albums: ", scalar @{$result}, "\n\n";
|
||||
|
||||
print "Album ids: ";
|
||||
my @albums = sort {$a->{"albumid"} <=> $b->{"albumid"}} @{$result};
|
||||
printRanges("albumid", @albums);
|
||||
print "\n\n";
|
||||
|
||||
print "Albums for genre id $genreid: ";
|
||||
my @result = getAlbumsForGenre( $json_hash, $genreid );
|
||||
@albums = sort {$a->{"albumid"} <=> $b->{"albumid"}} @result;
|
||||
printRanges("albumid", @albums);
|
||||
print "\n\n";
|
||||
|
||||
print "Album with albumId $albumid\n";
|
||||
my $album = getAlbum($json_hash, $albumid);
|
||||
printAlbum(%$album);
|
||||
print "\n\n";
|
||||
}
|
||||
|
||||
sub printSongTestNumbers($$) {
|
||||
my $artistid = shift;
|
||||
my $albumid = shift;
|
||||
|
||||
my $json_hash = decodeJson( "AudioLibrary.GetSongs.json" );
|
||||
my $result = getSongs($json_hash);
|
||||
print "Amount of songs: ", scalar @{$result}, "\n\n";
|
||||
|
||||
my @songsforartist;
|
||||
my @songsforalbum;
|
||||
|
||||
print "Song ids: ";
|
||||
|
||||
my @songids = sort {$a->{"songid"} <=> $b->{"songid"}} @{$result};
|
||||
printRanges("songid", @songids);
|
||||
|
||||
for my $song (@songids) {
|
||||
for my $id (@{$song->{"artistid"}}) {
|
||||
if ( $id == $artistid ) {
|
||||
push @songsforartist, $song;
|
||||
}
|
||||
}
|
||||
if ( $song->{"albumid"} == $albumid ) {
|
||||
push @songsforalbum, $song;
|
||||
}
|
||||
}
|
||||
print "\n\n";
|
||||
|
||||
print "Songs for artistid " . $artistid . ": total=" . scalar @songsforartist . ": ids=";
|
||||
printRanges("songid", @songsforartist);
|
||||
print "\n\n";
|
||||
|
||||
print "Songs for albumid " . $albumid . ": total=" . scalar @songsforalbum . ": ids=";
|
||||
printRanges("songid", @songsforalbum);
|
||||
print "\n\n";
|
||||
}
|
||||
|
||||
sub printSongCornerCases() {
|
||||
|
||||
my $json_hash = decodeJson( "AudioLibrary.GetSongs.json" );
|
||||
|
||||
print "Song with album and artist\n";
|
||||
my $song = getSong(%$json_hash, 1487);
|
||||
printSong(%$song);
|
||||
print "\n\n";
|
||||
|
||||
print "Songs with album but without artist\n";
|
||||
$song = getSong(%$json_hash, 1219);
|
||||
printSong(%$song);
|
||||
print "\n\n";
|
||||
|
||||
print "Song without album but with artist\n";
|
||||
$song = getSong(%$json_hash, 1128);
|
||||
printSong(%$song);
|
||||
|
||||
print "\n\n";
|
||||
|
||||
print "Song with multiple artists\n";
|
||||
$song = getSong(%$json_hash, 1804);
|
||||
printSong(%$song);
|
||||
}
|
||||
|
||||
sub printAlbumCornerCases() {
|
||||
my $json_hash = decodeJson( "AudioLibrary.GetAlbums.json" );
|
||||
|
||||
print "Album without an artist\n";
|
||||
my $album = getAlbum($json_hash, 82);
|
||||
printAlbum(%$album);
|
||||
print "\n\n";
|
||||
|
||||
print "Album with multiple artists\n";
|
||||
$album = getAlbum($json_hash, 234);
|
||||
printAlbum(%$album);
|
||||
print "\n\n";
|
||||
}
|
||||
|
||||
printArtistTestNumbers(13);
|
||||
|
||||
printAlbumTestNumbers(13, 13);
|
||||
printAlbumCornerCases();
|
||||
|
||||
printSongTestNumbers(13, 13);
|
||||
|
||||
printSongCornerCases();
|
Loading…
Reference in New Issue