Refactored integration tests to use robolectric (#302)
* Updated travis build to include running local tests for each PR * Removed unused methods from Utils.java * Moved all resources required by both local and instrumentation tests to testUtils * Added proguard rules for the test builds to prevent proguard from discarding the junit classes
This commit is contained in:
parent
eedd1e99b4
commit
bbda7df4aa
|
@ -6,12 +6,6 @@ env:
|
|||
matrix:
|
||||
- ANDROID_TARGET=android-22
|
||||
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- oracle-java8-installer
|
||||
|
||||
android:
|
||||
components:
|
||||
# following added as quick fix to get support for 23.0.3 build tools
|
||||
|
@ -31,4 +25,4 @@ android:
|
|||
before_script:
|
||||
|
||||
script:
|
||||
- ./gradlew assembleFullRelease
|
||||
- ./gradlew testFullDebugUnitTest assembleFullRelease
|
||||
|
|
|
@ -38,6 +38,19 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
fullDebug {
|
||||
assets.srcDirs = ['src/testUtils/assets']
|
||||
}
|
||||
test {
|
||||
java.srcDirs = ['src/test/java', 'src/testUtils/java']
|
||||
}
|
||||
instrumentationTest {
|
||||
java.srcDirs = ['src/testUtils/java']
|
||||
assets.srcDirs = ['src/testUtils/assets']
|
||||
}
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
full {
|
||||
}
|
||||
|
@ -45,6 +58,7 @@ android {
|
|||
instrumentationTest {
|
||||
applicationId "org.xbmc.kore.instrumentationtest"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
proguardFiles 'proguardTest-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,6 +124,10 @@ dependencies {
|
|||
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
|
||||
androidTestCompile 'com.android.support.test.espresso:espresso-idling-resource:2.2.2'
|
||||
androidTestCompile 'com.android.support:support-v13:23.4.0'
|
||||
instrumentationTestCompile 'junit:junit:4.12'
|
||||
|
||||
testCompile 'org.robolectric:robolectric:3.1.1'
|
||||
testCompile 'junit:junit:4.12'
|
||||
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
-keep class org.junit.** { *; }
|
||||
-dontwarn org.junit.**
|
||||
|
||||
-keep class junit.** { *; }
|
||||
-dontwarn junit.**
|
||||
|
||||
-keep class sun.misc.** { *; }
|
||||
-dontwarn sun.misc.**
|
|
@ -0,0 +1,19 @@
|
|||
Integration tests that need to be executed on an Android device.
|
||||
|
||||
## Run tests
|
||||
|
||||
You can run the tests as follows:
|
||||
|
||||
### Android Studio
|
||||
|
||||
1. Select build variant "instrumentationTestDebug"
|
||||
2. Set the (Project view)[https://developer.android.com/studio/projects/index.html] to Android
|
||||
3. Right-click on the directory "androidTest" and select "Run tests"
|
||||
|
||||
### Commandline
|
||||
|
||||
Run the following command from the top of the project:
|
||||
|
||||
./gradlew connectedInstrumentationTestDebugAndroidTest
|
||||
|
||||
This will run the tests on all connected devices in parallel
|
|
@ -18,7 +18,6 @@ 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;
|
||||
|
@ -27,10 +26,10 @@ import android.util.Log;
|
|||
import org.xbmc.kore.R;
|
||||
import org.xbmc.kore.host.HostInfo;
|
||||
import org.xbmc.kore.host.HostManager;
|
||||
import org.xbmc.kore.provider.MediaProvider;
|
||||
import org.xbmc.kore.testutils.Database;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class Utils {
|
||||
|
@ -45,20 +44,6 @@ public class Utils {
|
|||
private static HostInfo hostInfo;
|
||||
private static Context context;
|
||||
|
||||
public static String readFile(Context context, String filename) throws IOException {
|
||||
InputStream is = context.getAssets().open(filename);
|
||||
|
||||
int size = is.available();
|
||||
|
||||
byte[] buffer = new byte[size];
|
||||
|
||||
is.read(buffer);
|
||||
|
||||
is.close();
|
||||
|
||||
return new String(buffer, "UTF-8");
|
||||
}
|
||||
|
||||
public static void closeDrawer(final ActivityTestRule<?> activityTestRule) throws Throwable {
|
||||
activityTestRule.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
|
@ -77,7 +62,11 @@ public class Utils {
|
|||
|
||||
disableAnimations();
|
||||
|
||||
hostInfo = Database.fill(context);
|
||||
MediaProvider mediaProvider = new MediaProvider();
|
||||
mediaProvider.setContext(context);
|
||||
mediaProvider.onCreate();
|
||||
|
||||
hostInfo = Database.fill(context, context.getContentResolver());
|
||||
|
||||
HostManager.getInstance(context).switchHost(hostInfo);
|
||||
Utils.closeDrawer(activityTestRule);
|
||||
|
@ -86,22 +75,13 @@ public class Utils {
|
|||
}
|
||||
|
||||
public static void cleanup() {
|
||||
Database.flush(context, hostInfo);
|
||||
Database.flush(context.getContentResolver(), hostInfo);
|
||||
|
||||
enableAnimations();
|
||||
|
||||
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) {
|
||||
|
@ -137,16 +117,4 @@ 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,5 @@
|
|||
Resources required for the instrumentation tests in [androidTest](../androidTest)
|
||||
|
||||
**Note**: do not put any tests here! Put local tests
|
||||
that DO NOT need to be executed on an android device in [test](../test).
|
||||
Put tests that DO need to run on an android device in [androidTest](../androidTest).
|
|
@ -0,0 +1,17 @@
|
|||
Local tests that do NOT need to be executed on an Android device
|
||||
|
||||
## Run tests
|
||||
|
||||
You can run the tests as follows:
|
||||
|
||||
### Android Studio
|
||||
|
||||
1. Select build variant "instrumentationTestDebug"
|
||||
2. Set the (Project view)[https://developer.android.com/studio/projects/index.html] to Android
|
||||
3. Right-click on the directory "test" and select "Run tests"
|
||||
|
||||
### Commandline
|
||||
|
||||
Run the following command from the top of the project:
|
||||
|
||||
./gradlew testInstrumentationTestDebugUnitTest
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.provider.mediaprovider;
|
||||
|
||||
|
||||
import android.content.ContentResolver;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
import org.xbmc.kore.BuildConfig;
|
||||
import org.xbmc.kore.host.HostInfo;
|
||||
import org.xbmc.kore.provider.MediaProvider;
|
||||
import org.xbmc.kore.testutils.Database;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(constants = BuildConfig.class)
|
||||
@Ignore
|
||||
public class AbstractTestClass {
|
||||
protected static HostInfo hostInfo;
|
||||
protected static ShadowContentResolver shadowContentResolver;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MediaProvider provider = new MediaProvider();
|
||||
ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver();
|
||||
provider.onCreate();
|
||||
shadowContentResolver = Shadows.shadowOf(contentResolver);
|
||||
ShadowContentResolver.registerProvider("org.xbmc.kore.provider", provider);
|
||||
provider.onCreate();
|
||||
|
||||
hostInfo = Database.fill(RuntimeEnvironment.application, contentResolver);
|
||||
}
|
||||
}
|
|
@ -14,72 +14,27 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.xbmc.kore.tests.mediaprovider;
|
||||
package org.xbmc.kore.provider.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.provider.MediaProvider;
|
||||
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 org.xbmc.kore.testutils.CursorUtils;
|
||||
import org.xbmc.kore.testutils.TestUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.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);
|
||||
}
|
||||
public class MediaProviderMusicTest extends AbstractTestClass {
|
||||
|
||||
@Test
|
||||
public void queryAllArtistsTest() {
|
||||
Uri uri = MediaContract.Artists.buildArtistsListUri(hostInfo.getId());
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Artist.PROJECTION, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.Artist.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 227, cursor.getCount());
|
||||
|
@ -94,7 +49,7 @@ public class MediaProviderMusicTest {
|
|||
public void queryArtistTest() {
|
||||
Uri uri = MediaContract.Artists.buildArtistUri(hostInfo.getId(), TestValues.Artist.artistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Artist.PROJECTION, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.Artist.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
|
@ -106,7 +61,7 @@ public class MediaProviderMusicTest {
|
|||
public void queryAllAlbumsTest() {
|
||||
Uri uri = MediaContract.Albums.buildAlbumsListUri(hostInfo.getId());
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 232, cursor.getCount());
|
||||
|
@ -120,7 +75,7 @@ public class MediaProviderMusicTest {
|
|||
public void queryAlbumTest() {
|
||||
Uri uri = MediaContract.Albums.buildAlbumUri(hostInfo.getId(), TestValues.Album.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
|
@ -133,7 +88,7 @@ public class MediaProviderMusicTest {
|
|||
Uri uri = MediaContract.AlbumArtists.buildAlbumsForArtistListUri(hostInfo.getId(),
|
||||
TestValues.Artist.artistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
|
@ -146,7 +101,7 @@ public class MediaProviderMusicTest {
|
|||
int genreId = 13;
|
||||
Uri uri = MediaContract.AlbumGenres.buildAlbumsForGenreListUri(hostInfo.getId(), genreId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.Album.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 31, cursor.getCount());
|
||||
|
@ -162,7 +117,7 @@ public class MediaProviderMusicTest {
|
|||
public void queryAlbumSongsTest() {
|
||||
Uri uri = MediaContract.Songs.buildAlbumSongsListUri(hostInfo.getId(), TestValues.Album.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, new String[] {MediaProvider.Qualified.SONGS_SONGID}, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.query(uri, new String[] {MediaContract.Songs.SONGID}, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 17, cursor.getCount());
|
||||
|
@ -175,7 +130,7 @@ public class MediaProviderMusicTest {
|
|||
Uri uri = MediaContract.Albums.buildAlbumUri(hostInfo.getId(),
|
||||
TestValues.AlbumWithoutArtist.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.AlbumWithoutArtist.PROJECTION, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.AlbumWithoutArtist.PROJECTION, null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertEquals("cursor size ", 1, cursor.getCount());
|
||||
|
@ -188,7 +143,7 @@ public class MediaProviderMusicTest {
|
|||
Uri uri = MediaContract.Albums.buildAlbumUri(hostInfo.getId(),
|
||||
TestValues.AlbumWithMultipleArtists.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.AlbumWithMultipleArtists.PROJECTION,
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.AlbumWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
|
@ -201,13 +156,13 @@ public class MediaProviderMusicTest {
|
|||
public void queryArtistSongsTest() {
|
||||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(), TestValues.ArtistSong.artistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.ArtistSong.PROJECTION, null, null, null);
|
||||
Cursor cursor = shadowContentResolver.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),
|
||||
assertTrue(CursorUtils.moveCursorToFirstOccurrence(cursor, cursor.getColumnIndex(MediaContract.Songs.SONGID),
|
||||
TestValues.ArtistSong.songId));
|
||||
}
|
||||
|
||||
|
@ -216,13 +171,12 @@ public class MediaProviderMusicTest {
|
|||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(),
|
||||
TestValues.SongWithArtistWithoutAlbum.artistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.SongWithArtistWithoutAlbum.PROJECTION,
|
||||
Cursor cursor = shadowContentResolver.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);
|
||||
}
|
||||
|
||||
|
@ -231,7 +185,7 @@ public class MediaProviderMusicTest {
|
|||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(),
|
||||
TestValues.SongWithMultipleArtists.firstArtistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.SongWithMultipleArtists.PROJECTION,
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.SongWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
|
@ -245,7 +199,7 @@ public class MediaProviderMusicTest {
|
|||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(),
|
||||
TestValues.SongWithMultipleArtists.secondArtistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri, TestValues.SongWithMultipleArtists.PROJECTION,
|
||||
Cursor cursor = shadowContentResolver.query(uri, TestValues.SongWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
assertNotNull(cursor);
|
||||
|
@ -259,7 +213,7 @@ public class MediaProviderMusicTest {
|
|||
Uri uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(),
|
||||
TestValues.SongWithMultipleArtists.thirdArtistId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri,
|
||||
Cursor cursor = shadowContentResolver.query(uri,
|
||||
TestValues.SongWithMultipleArtists.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
|
@ -273,7 +227,7 @@ public class MediaProviderMusicTest {
|
|||
public void queryAllSongsTest() {
|
||||
Uri uri = MediaContract.Songs.buildSongsListUri(hostInfo.getId());
|
||||
|
||||
Cursor cursor = contentResolver.query(uri,
|
||||
Cursor cursor = shadowContentResolver.query(uri,
|
||||
TestValues.ArtistSong.PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
|
@ -283,22 +237,22 @@ public class MediaProviderMusicTest {
|
|||
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));
|
||||
assertTrue(CursorUtils.moveCursorToFirstOccurrence(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),
|
||||
assertTrue(CursorUtils.moveCursorToFirstOccurrence(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),
|
||||
assertTrue(CursorUtils.moveCursorToFirstOccurrence(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),
|
||||
assertTrue(CursorUtils.moveCursorToFirstOccurrence(cursor, cursor.getColumnIndex(MediaContract.Songs.SONGID),
|
||||
TestValues.SongWithMultipleArtists.songId));
|
||||
TestValues.SongWithMultipleArtists.test(cursor);
|
||||
}
|
||||
|
@ -308,14 +262,13 @@ public class MediaProviderMusicTest {
|
|||
Uri uri = MediaContract.Albums.buildAlbumUri(hostInfo.getId(),
|
||||
TestValues.AlbumWithMultipleArtists.albumId);
|
||||
|
||||
Cursor cursor = contentResolver.query(uri,
|
||||
Cursor cursor = shadowContentResolver.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);
|
||||
}
|
||||
|
||||
|
@ -323,7 +276,7 @@ public class MediaProviderMusicTest {
|
|||
public void queryAllGenresTest() {
|
||||
Uri uri = MediaContract.AudioGenres.buildAudioGenresListUri(hostInfo.getId());
|
||||
|
||||
Cursor cursor = contentResolver.query(uri,
|
||||
Cursor cursor = shadowContentResolver.query(uri,
|
||||
new String[] {MediaContract.AudioGenresColumns.GENREID},
|
||||
null, null, null);
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.xbmc.kore.tests.mediaprovider;
|
||||
package org.xbmc.kore.provider.mediaprovider;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
Resources required for both the local and instrumentation tests.
|
||||
|
||||
**Note**: do not put any tests here! Put local tests
|
||||
that DO NOT need to be executed on an android device in [test](../test).
|
||||
Put tests that DO need to run on an android device in [androidTest](../androidTest).
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.testutils;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
public class CursorUtils {
|
||||
/**
|
||||
* Converts the current row in cursor to a string with each line
|
||||
* containing a column name and value pair.
|
||||
* @param cursor
|
||||
* @return
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves cursor to first position item is found at column index
|
||||
* @param cursor
|
||||
* @param columnIndex
|
||||
* @param item integer to search for at given column index
|
||||
* @return true if item found, false otherwise
|
||||
*/
|
||||
public static boolean moveCursorToFirstOccurrence(Cursor cursor, int columnIndex, int item) {
|
||||
if (( cursor == null ) || ( ! cursor.moveToFirst() ))
|
||||
return false;
|
||||
|
||||
do {
|
||||
if ( cursor.getInt(columnIndex) == item )
|
||||
return true;
|
||||
} while (cursor.moveToNext());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the occurences item is found at given column index
|
||||
* @param cursor
|
||||
* @param columnIndex
|
||||
* @param item integer to search for at given column index
|
||||
* @return amount of occurences, -1 if an error occured
|
||||
*/
|
||||
public static int countOccurences(Cursor cursor, int columnIndex, int item) {
|
||||
if (( cursor == null ) || ( ! cursor.moveToFirst() ))
|
||||
return -1;
|
||||
|
||||
int count = 0;
|
||||
do {
|
||||
if ( cursor.getInt(columnIndex) == item )
|
||||
count++;
|
||||
} while (cursor.moveToNext());
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.xbmc.kore.testhelpers;
|
||||
package org.xbmc.kore.testutils;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
|
@ -30,7 +30,6 @@ import org.xbmc.kore.jsonrpc.type.AudioType;
|
|||
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;
|
||||
|
@ -41,34 +40,33 @@ import java.util.ArrayList;
|
|||
public class Database {
|
||||
public static final String TAG = LogUtils.makeLogTag(Database.class);
|
||||
|
||||
public static HostInfo fill(Context context) throws ApiException, IOException {
|
||||
MediaProvider mediaProvider = new MediaProvider();
|
||||
mediaProvider.setContext(context);
|
||||
mediaProvider.onCreate();
|
||||
|
||||
public static HostInfo fill(Context context, ContentResolver contentResolver) throws ApiException, IOException {
|
||||
HostInfo hostInfo = addHost(context);
|
||||
|
||||
SyncMusic syncMusic = new SyncMusic(hostInfo.getId(), null);
|
||||
insertMovies(context, hostInfo.getId());
|
||||
insertArtists(context, syncMusic);
|
||||
insertGenres(context, syncMusic);
|
||||
insertAlbums(context, syncMusic);
|
||||
insertSongs(context, syncMusic);
|
||||
|
||||
insertMovies(context, contentResolver, hostInfo.getId());
|
||||
insertArtists(context, contentResolver, syncMusic);
|
||||
insertGenres(context, contentResolver, syncMusic);
|
||||
insertAlbums(context, contentResolver, syncMusic);
|
||||
insertSongs(context, contentResolver, syncMusic);
|
||||
|
||||
return hostInfo;
|
||||
}
|
||||
|
||||
public static void flush(Context context, HostInfo hostInfo) {
|
||||
context.getContentResolver()
|
||||
.delete(MediaContract.Hosts.buildHostUri(hostInfo.getId()), null, null);
|
||||
public static void flush(ContentResolver contentResolver, HostInfo hostInfo) {
|
||||
contentResolver.delete(MediaContract.Hosts.buildHostUri(hostInfo.getId()), null, null);
|
||||
}
|
||||
|
||||
private static HostInfo addHost(Context context) {
|
||||
return HostManager.getInstance(context).addHost("TestHost", "127.0.0.1", 1, 80, 9090, null, null, "52:54:00:12:35:02", 9, false, 9777);
|
||||
return HostManager.getInstance(context).addHost("TestHost", "127.0.0.1", 1, 80, 9090, null,
|
||||
null, "52:54:00:12:35:02", 9, false, 9777);
|
||||
}
|
||||
|
||||
private static void insertMovies(Context context, int hostId) throws ApiException, IOException {
|
||||
public static void insertMovies(Context context, ContentResolver contentResolver, int hostId)
|
||||
throws ApiException, IOException {
|
||||
VideoLibrary.GetMovies getMovies = new VideoLibrary.GetMovies();
|
||||
String result = Utils.readFile(context, "Video.Details.Movie.json");
|
||||
String result = FileUtils.readFile(context, "Video.Details.Movie.json");
|
||||
ApiList<VideoType.DetailsMovie> movieList = getMovies.resultFromJson(result);
|
||||
|
||||
|
||||
|
@ -82,7 +80,7 @@ public class Database {
|
|||
castCount += movie.cast.size();
|
||||
}
|
||||
|
||||
context.getContentResolver().bulkInsert(MediaContract.Movies.CONTENT_URI, movieValuesBatch);
|
||||
contentResolver.bulkInsert(MediaContract.Movies.CONTENT_URI, movieValuesBatch);
|
||||
|
||||
ContentValues movieCastValuesBatch[] = new ContentValues[castCount];
|
||||
int count = 0;
|
||||
|
@ -95,37 +93,39 @@ public class Database {
|
|||
}
|
||||
}
|
||||
|
||||
context.getContentResolver().bulkInsert(MediaContract.MovieCast.CONTENT_URI, movieCastValuesBatch);
|
||||
contentResolver.bulkInsert(MediaContract.MovieCast.CONTENT_URI, movieCastValuesBatch);
|
||||
}
|
||||
|
||||
private static void insertArtists(Context context, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
private static void insertArtists(Context context, ContentResolver contentResolver, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
AudioLibrary.GetArtists getArtists = new AudioLibrary.GetArtists(false);
|
||||
String result = Utils.readFile(context, "AudioLibrary.GetArtists.json");
|
||||
String result = FileUtils.readFile(context, "AudioLibrary.GetArtists.json");
|
||||
ArrayList<AudioType.DetailsArtist> artistList = (ArrayList) getArtists.resultFromJson(result).items;
|
||||
|
||||
syncMusic.insertArtists(artistList, context.getContentResolver());
|
||||
syncMusic.insertArtists(artistList, contentResolver);
|
||||
}
|
||||
|
||||
private static void insertGenres(Context context, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
private static void insertGenres(Context context, ContentResolver contentResolver, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
AudioLibrary.GetGenres getGenres = new AudioLibrary.GetGenres();
|
||||
ArrayList<LibraryType.DetailsGenre> genreList = (ArrayList) getGenres.resultFromJson(Utils.readFile(context, "AudioLibrary.GetGenres.json"));
|
||||
ArrayList<LibraryType.DetailsGenre> genreList =
|
||||
(ArrayList) getGenres.resultFromJson(FileUtils.readFile(context,
|
||||
"AudioLibrary.GetGenres.json"));
|
||||
|
||||
syncMusic.insertGenresItems(genreList, context.getContentResolver());
|
||||
syncMusic.insertGenresItems(genreList, contentResolver);
|
||||
}
|
||||
|
||||
private static void insertAlbums(Context context, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
private static void insertAlbums(Context context, ContentResolver contentResolver, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
AudioLibrary.GetAlbums getAlbums = new AudioLibrary.GetAlbums();
|
||||
String result = Utils.readFile(context, "AudioLibrary.GetAlbums.json");
|
||||
String result = FileUtils.readFile(context, "AudioLibrary.GetAlbums.json");
|
||||
ArrayList<AudioType.DetailsAlbum> albumList = (ArrayList) getAlbums.resultFromJson(result).items;
|
||||
|
||||
syncMusic.insertAlbumsItems(albumList, context.getContentResolver());
|
||||
syncMusic.insertAlbumsItems(albumList, contentResolver);
|
||||
}
|
||||
|
||||
private static void insertSongs(Context context, SyncMusic syncMusic) throws ApiException, IOException {
|
||||
private static void insertSongs(Context context, ContentResolver contentResolver, 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;
|
||||
getSongs.resultFromJson(FileUtils.readFile(context, "AudioLibrary.GetSongs.json")).items;
|
||||
|
||||
syncMusic.insertSongsItems(songList, context.getContentResolver());
|
||||
syncMusic.insertSongsItems(songList, contentResolver);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FileUtils {
|
||||
public static String readFile(Context context, String filename) throws IOException {
|
||||
InputStream is = context.getAssets().open(filename);
|
||||
|
||||
int size = is.available();
|
||||
|
||||
byte[] buffer = new byte[size];
|
||||
|
||||
is.read(buffer);
|
||||
|
||||
is.close();
|
||||
|
||||
return new String(buffer, "UTF-8");
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.xbmc.kore.testhelpers;
|
||||
package org.xbmc.kore.testutils;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
Loading…
Reference in New Issue