Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:

steps:
- uses: actions/checkout@v3
- name: set up JDK 17
- name: set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '17'
java-version: '21'
distribution: 'temurin'
cache: gradle

Expand Down
6 changes: 6 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,10 @@ dependencies {
implementation libs.codeview
implementation libs.hilt.android
annotationProcessor libs.hilt.compiler

// Testing
testImplementation 'junit:junit:4.13.2'
testImplementation 'androidx.arch.core:core-testing:2.2.0'
testImplementation 'org.mockito:mockito-core:5.12.0'
testImplementation 'org.mockito:mockito-inline:5.2.0'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.d4rk.androidtutorials.java.data.repository;

import com.d4rk.androidtutorials.java.data.model.PromotedApp;
import com.d4rk.androidtutorials.java.data.source.HomeLocalDataSource;
import com.d4rk.androidtutorials.java.data.source.HomeRemoteDataSource;

import org.junit.Test;

import java.util.List;

import static org.junit.Assert.*;

public class DefaultHomeRepositoryTest {

private static class FakeHomeLocalDataSource implements HomeLocalDataSource {
@Override
public String getPlayStoreUrl() {
return "play";
}

@Override
public String getAppPlayStoreUrl(String packageName) {
return "play/" + packageName;
}

@Override
public String getDailyTip() {
return "tip";
}
}

private static class FakeHomeRemoteDataSource implements HomeRemoteDataSource {
private final List<PromotedApp> apps;
boolean called = false;

FakeHomeRemoteDataSource(List<PromotedApp> apps) {
this.apps = apps;
}

@Override
public void fetchPromotedApps(PromotedAppsCallback callback) {
called = true;
callback.onResult(apps);
}
}

@Test
public void repositoryDelegatesToDataSources() {
List<PromotedApp> promoted = List.of(new PromotedApp("Name", "pkg", "icon"));
FakeHomeRemoteDataSource remote = new FakeHomeRemoteDataSource(promoted);
FakeHomeLocalDataSource local = new FakeHomeLocalDataSource();

DefaultHomeRepository repository = new DefaultHomeRepository(remote, local);

assertEquals("play", repository.getPlayStoreUrl());
assertEquals("play/pkg", repository.getAppPlayStoreUrl("pkg"));
assertEquals("tip", repository.getDailyTip());

final List<PromotedApp>[] result = new List[1];
repository.fetchPromotedApps(apps -> result[0] = apps);
assertTrue(remote.called);
assertEquals(promoted, result[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.d4rk.androidtutorials.java.data.repository;

import com.d4rk.androidtutorials.java.data.model.QuizQuestion;
import com.d4rk.androidtutorials.java.data.source.QuizLocalDataSource;

import org.junit.Test;

import java.util.List;

import static org.junit.Assert.*;

public class DefaultQuizRepositoryTest {

private static class FakeQuizLocalDataSource implements QuizLocalDataSource {
private final List<QuizQuestion> questions;

FakeQuizLocalDataSource(List<QuizQuestion> questions) {
this.questions = questions;
}

@Override
public List<QuizQuestion> loadQuestions() {
return questions;
}
}

@Test
public void loadQuestionsReturnsLocalData() {
List<QuizQuestion> expected = List.of(
new QuizQuestion("Q", new String[]{"A", "B"}, 0)
);
FakeQuizLocalDataSource local = new FakeQuizLocalDataSource(expected);
DefaultQuizRepository repository = new DefaultQuizRepository(local);
assertEquals(expected, repository.loadQuestions());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.d4rk.androidtutorials.java.ui.screens.home;

import android.app.Application;

import androidx.arch.core.executor.testing.InstantTaskExecutorRule;

import com.d4rk.androidtutorials.java.R;
import com.d4rk.androidtutorials.java.data.model.PromotedApp;
import com.d4rk.androidtutorials.java.data.repository.HomeRepository;
import com.d4rk.androidtutorials.java.domain.home.GetDailyTipUseCase;
import com.d4rk.androidtutorials.java.domain.home.GetPromotedAppsUseCase;

import org.junit.Rule;
import org.junit.Test;

import java.util.List;

import static org.junit.Assert.*;

import org.mockito.Mockito;

public class HomeViewModelTest {

@Rule
public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule();


static class FakeHomeRepository implements HomeRepository {
final String dailyTip;
final List<PromotedApp> apps;

FakeHomeRepository(String dailyTip, List<PromotedApp> apps) {
this.dailyTip = dailyTip;
this.apps = apps;
}

@Override public String getPlayStoreUrl() { return ""; }
@Override public String getAppPlayStoreUrl(String packageName) { return ""; }
@Override public String getDailyTip() { return dailyTip; }
@Override public void fetchPromotedApps(PromotedAppsCallback callback) { callback.onResult(apps); }
}

@Test
public void uiStateUpdatesWithData() {
List<PromotedApp> promoted = List.of(new PromotedApp("App", "pkg", "icon"));
FakeHomeRepository repo = new FakeHomeRepository("tip", promoted);
Application app = Mockito.mock(Application.class);
Mockito.when(app.getString(R.string.announcement_title)).thenReturn("Title");
Mockito.when(app.getString(R.string.announcement_subtitle)).thenReturn("Subtitle");
HomeViewModel viewModel = new HomeViewModel(app, repo,
new GetDailyTipUseCase(repo), new GetPromotedAppsUseCase(repo));

HomeUiState state = viewModel.getUiState().getValue();
assertNotNull(state);
assertEquals("Title", state.announcementTitle());
assertEquals("Subtitle", state.announcementSubtitle());
assertEquals("tip", state.dailyTip());
assertEquals(promoted, state.promotedApps());
}

@Test
public void uiStateHandlesEmptyPromotedApps() {
FakeHomeRepository repo = new FakeHomeRepository("tip", List.of());
Application app = Mockito.mock(Application.class);
Mockito.when(app.getString(R.string.announcement_title)).thenReturn("Title");
Mockito.when(app.getString(R.string.announcement_subtitle)).thenReturn("Subtitle");
HomeViewModel viewModel = new HomeViewModel(app, repo,
new GetDailyTipUseCase(repo), new GetPromotedAppsUseCase(repo));

HomeUiState state = viewModel.getUiState().getValue();
assertNotNull(state);
assertTrue(state.promotedApps().isEmpty());
}
}