mirror of
https://github.com/mihonapp/mihon.git
synced 2025-10-28 21:07:57 +01:00
Partial migration of data package to Kotlin
This commit is contained in:
15
app/src/test/java/eu/kanade/tachiyomi/CustomBuildConfig.java
Normal file
15
app/src/test/java/eu/kanade/tachiyomi/CustomBuildConfig.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package eu.kanade.tachiyomi;
|
||||
|
||||
public class CustomBuildConfig {
|
||||
public static final boolean DEBUG = Boolean.parseBoolean("true");
|
||||
public static final String APPLICATION_ID = "eu.kanade.tachiyomi";
|
||||
public static final String BUILD_TYPE = "debug";
|
||||
public static final String FLAVOR = "";
|
||||
public static final int VERSION_CODE = 4;
|
||||
public static final String VERSION_NAME = "0.1.3";
|
||||
// Fields from default config.
|
||||
public static final String BUILD_TIME = "2016-02-19T14:49Z";
|
||||
public static final String COMMIT_COUNT = "482";
|
||||
public static final String COMMIT_SHA = "e52c498";
|
||||
public static final boolean INCLUDE_UPDATER = true;
|
||||
}
|
||||
@@ -1,9 +1,24 @@
|
||||
package eu.kanade.tachiyomi;
|
||||
|
||||
import eu.kanade.tachiyomi.injection.component.DaggerAppComponent;
|
||||
import eu.kanade.tachiyomi.injection.module.AppModule;
|
||||
|
||||
public class TestApp extends App {
|
||||
|
||||
@Override
|
||||
protected DaggerAppComponent.Builder prepareAppComponent() {
|
||||
return DaggerAppComponent.builder()
|
||||
.appModule(new AppModule(this))
|
||||
.dataModule(new TestDataModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupEventBus() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupAcra() {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
29
app/src/test/java/eu/kanade/tachiyomi/TestDataModule.java
Normal file
29
app/src/test/java/eu/kanade/tachiyomi/TestDataModule.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package eu.kanade.tachiyomi;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
|
||||
import eu.kanade.tachiyomi.data.network.NetworkHelper;
|
||||
import eu.kanade.tachiyomi.data.source.SourceManager;
|
||||
import eu.kanade.tachiyomi.injection.module.DataModule;
|
||||
|
||||
public class TestDataModule extends DataModule {
|
||||
|
||||
@Override
|
||||
public DatabaseHelper provideDatabaseHelper(Application app) {
|
||||
return Mockito.mock(DatabaseHelper.class, Mockito.RETURNS_DEEP_STUBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkHelper provideNetworkHelper(Application app) {
|
||||
return Mockito.mock(NetworkHelper.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceManager provideSourceManager(Application app) {
|
||||
return Mockito.mock(SourceManager.class, Mockito.RETURNS_DEEP_STUBS);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package eu.kanade.tachiyomi;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Created by len on 1/10/15.
|
||||
*/
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface UseModule {
|
||||
Class value();
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package eu.kanade.tachiyomi.data.library;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.assertj.core.data.Offset;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowAlarmManager;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.shadows.ShadowPendingIntent;
|
||||
|
||||
import eu.kanade.tachiyomi.CustomBuildConfig;
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
@Config(constants = CustomBuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class LibraryUpdateAlarmTest {
|
||||
|
||||
ShadowApplication app;
|
||||
Context context;
|
||||
ShadowAlarmManager alarmManager;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
app = ShadowApplication.getInstance();
|
||||
context = spy(app.getApplicationContext());
|
||||
|
||||
alarmManager = shadowOf((AlarmManager) context.getSystemService(Context.ALARM_SERVICE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLibraryIntentHandling() {
|
||||
Intent intent = new Intent(LibraryUpdateAlarm.LIBRARY_UPDATE_ACTION);
|
||||
assertThat(app.hasReceiverForIntent(intent)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlarmIsNotStarted() {
|
||||
assertThat(alarmManager.getNextScheduledAlarm()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlarmIsNotStartedWhenBootReceivedAndSettingZero() {
|
||||
LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();
|
||||
alarm.onReceive(context, new Intent(Intent.ACTION_BOOT_COMPLETED));
|
||||
|
||||
assertThat(alarmManager.getNextScheduledAlarm()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlarmIsStartedWhenBootReceivedAndSettingNotZero() {
|
||||
PreferencesHelper prefs = new PreferencesHelper(context);
|
||||
prefs.libraryUpdateInterval().set(1);
|
||||
|
||||
LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();
|
||||
alarm.onReceive(context, new Intent(Intent.ACTION_BOOT_COMPLETED));
|
||||
|
||||
assertThat(alarmManager.getNextScheduledAlarm()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlyOneAlarmExists() {
|
||||
PreferencesHelper prefs = new PreferencesHelper(context);
|
||||
prefs.libraryUpdateInterval().set(1);
|
||||
|
||||
LibraryUpdateAlarm.startAlarm(context);
|
||||
LibraryUpdateAlarm.startAlarm(context);
|
||||
LibraryUpdateAlarm.startAlarm(context);
|
||||
|
||||
assertThat(alarmManager.getScheduledAlarms()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLibraryWillBeUpdatedWhenAlarmFired() {
|
||||
PreferencesHelper prefs = new PreferencesHelper(context);
|
||||
prefs.libraryUpdateInterval().set(1);
|
||||
|
||||
Intent expectedIntent = new Intent(context, LibraryUpdateAlarm.class);
|
||||
expectedIntent.setAction(LibraryUpdateAlarm.LIBRARY_UPDATE_ACTION);
|
||||
|
||||
LibraryUpdateAlarm.startAlarm(context);
|
||||
|
||||
ShadowAlarmManager.ScheduledAlarm scheduledAlarm = alarmManager.getNextScheduledAlarm();
|
||||
ShadowPendingIntent pendingIntent = shadowOf(scheduledAlarm.operation);
|
||||
assertThat(pendingIntent.isBroadcastIntent()).isTrue();
|
||||
assertThat(pendingIntent.getSavedIntents()).hasSize(1);
|
||||
assertThat(expectedIntent.getComponent()).isEqualTo(pendingIntent.getSavedIntents()[0].getComponent());
|
||||
assertThat(expectedIntent.getAction()).isEqualTo(pendingIntent.getSavedIntents()[0].getAction());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLibraryUpdateServiceIsStartedWhenUpdateIntentIsReceived() {
|
||||
Intent intent = new Intent(context, LibraryUpdateService.class);
|
||||
assertThat(app.getNextStartedService()).isNotEqualTo(intent);
|
||||
|
||||
LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();
|
||||
alarm.onReceive(context, new Intent(LibraryUpdateAlarm.LIBRARY_UPDATE_ACTION));
|
||||
|
||||
assertThat(app.getNextStartedService()).isEqualTo(intent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiverDoesntReactToNullActions() {
|
||||
PreferencesHelper prefs = new PreferencesHelper(context);
|
||||
prefs.libraryUpdateInterval().set(1);
|
||||
|
||||
Intent intent = new Intent(context, LibraryUpdateService.class);
|
||||
|
||||
LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();
|
||||
alarm.onReceive(context, new Intent());
|
||||
|
||||
assertThat(app.getNextStartedService()).isNotEqualTo(intent);
|
||||
assertThat(alarmManager.getScheduledAlarms()).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlarmFiresCloseToDesiredTime() {
|
||||
int hours = 2;
|
||||
LibraryUpdateAlarm.startAlarm(context, hours);
|
||||
|
||||
long shouldRunAt = SystemClock.elapsedRealtime() + (hours * 60 * 60 * 1000);
|
||||
|
||||
// Margin error of 3 seconds
|
||||
Offset<Long> offset = Offset.offset(3 * 1000L);
|
||||
|
||||
assertThat(alarmManager.getNextScheduledAlarm().triggerAtTime).isCloseTo(shouldRunAt, offset);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package eu.kanade.tachiyomi.data.library;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import eu.kanade.tachiyomi.CustomBuildConfig;
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter;
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga;
|
||||
import eu.kanade.tachiyomi.data.source.base.Source;
|
||||
import rx.Observable;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Config(constants = CustomBuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class LibraryUpdateServiceTest {
|
||||
|
||||
ShadowApplication app;
|
||||
Context context;
|
||||
LibraryUpdateService service;
|
||||
Source source;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
app = ShadowApplication.getInstance();
|
||||
context = app.getApplicationContext();
|
||||
service = Robolectric.setupService(LibraryUpdateService.class);
|
||||
source = mock(Source.class);
|
||||
when(service.sourceManager.get(anyInt())).thenReturn(source);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartCommand() {
|
||||
service.onStartCommand(new Intent(), 0, 0);
|
||||
verify(service.db).getFavoriteMangas();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLifecycle() {
|
||||
// Smoke test
|
||||
Robolectric.buildService(LibraryUpdateService.class)
|
||||
.attach()
|
||||
.create()
|
||||
.startCommand(0, 0)
|
||||
.destroy()
|
||||
.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateManga() {
|
||||
Manga manga = Manga.create("manga1");
|
||||
List<Chapter> chapters = createChapters("/chapter1", "/chapter2");
|
||||
|
||||
when(source.pullChaptersFromNetwork(manga.url)).thenReturn(Observable.just(chapters));
|
||||
when(service.db.insertOrRemoveChapters(manga, chapters))
|
||||
.thenReturn(Observable.just(Pair.create(2, 0)));
|
||||
|
||||
service.updateManga(manga).subscribe();
|
||||
|
||||
verify(service.db).insertOrRemoveChapters(manga, chapters);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContinuesUpdatingWhenAMangaFails() {
|
||||
Manga manga1 = Manga.create("manga1");
|
||||
Manga manga2 = Manga.create("manga2");
|
||||
Manga manga3 = Manga.create("manga3");
|
||||
|
||||
List<Manga> favManga = createManga("manga1", "manga2", "manga3");
|
||||
|
||||
List<Chapter> chapters = createChapters("/chapter1", "/chapter2");
|
||||
List<Chapter> chapters3 = createChapters("/achapter1", "/achapter2");
|
||||
|
||||
when(service.db.getFavoriteMangas().executeAsBlocking()).thenReturn(favManga);
|
||||
|
||||
// One of the updates will fail
|
||||
when(source.pullChaptersFromNetwork("manga1")).thenReturn(Observable.just(chapters));
|
||||
when(source.pullChaptersFromNetwork("manga2")).thenReturn(Observable.error(new Exception()));
|
||||
when(source.pullChaptersFromNetwork("manga3")).thenReturn(Observable.just(chapters3));
|
||||
|
||||
when(service.db.insertOrRemoveChapters(manga1, chapters)).thenReturn(Observable.just(Pair.create(2, 0)));
|
||||
when(service.db.insertOrRemoveChapters(manga3, chapters)).thenReturn(Observable.just(Pair.create(2, 0)));
|
||||
|
||||
service.updateLibrary().subscribe();
|
||||
|
||||
// There are 3 network attempts and 2 insertions (1 request failed)
|
||||
verify(source, times(3)).pullChaptersFromNetwork(any());
|
||||
verify(service.db, times(2)).insertOrRemoveChapters(any(), any());
|
||||
verify(service.db, never()).insertOrRemoveChapters(eq(manga2), any());
|
||||
}
|
||||
|
||||
private List<Chapter> createChapters(String... urls) {
|
||||
List<Chapter> list = new ArrayList<>();
|
||||
for (String url : urls) {
|
||||
Chapter c = Chapter.create();
|
||||
c.url = url;
|
||||
list.add(c);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<Manga> createManga(String... urls) {
|
||||
List<Manga> list = new ArrayList<>();
|
||||
for (String url : urls) {
|
||||
Manga m = Manga.create(url);
|
||||
list.add(m);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user