Skip to content

Commit 066dbbe

Browse files
Merge pull request #232 from MihaiCristianCondrea/codex/add-test-cases-for-repository-methods
Add delegation tests for DefaultHomeRepository
2 parents 137ec51 + 1a2e154 commit 066dbbe

File tree

2 files changed

+118
-18
lines changed

2 files changed

+118
-18
lines changed

app/src/main/java/com/d4rk/androidtutorials/java/data/repository/DefaultHomeRepository.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.d4rk.androidtutorials.java.data.repository;
22

3+
import com.d4rk.androidtutorials.java.data.model.PromotedApp;
34
import com.d4rk.androidtutorials.java.data.source.HomeLocalDataSource;
45
import com.d4rk.androidtutorials.java.data.source.HomeRemoteDataSource;
56

7+
import java.util.List;
8+
import java.util.concurrent.atomic.AtomicBoolean;
9+
610
/**
711
* Default implementation of {@link HomeRepository} combining local and remote sources.
812
*/
@@ -34,6 +38,15 @@ public String dailyTip() {
3438

3539
@Override
3640
public void fetchPromotedApps(PromotedAppsCallback callback) {
37-
remoteDataSource.fetchPromotedApps(callback::onResult);
41+
remoteDataSource.fetchPromotedApps(new HomeRemoteDataSource.PromotedAppsCallback() {
42+
private final AtomicBoolean dispatched = new AtomicBoolean(false);
43+
44+
@Override
45+
public void onResult(List<PromotedApp> apps) {
46+
if (dispatched.compareAndSet(false, true)) {
47+
callback.onResult(apps);
48+
}
49+
}
50+
});
3851
}
3952
}
Lines changed: 104 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.d4rk.androidtutorials.java.data.repository;
22

33
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertFalse;
45
import static org.junit.Assert.assertTrue;
56

67
import com.d4rk.androidtutorials.java.data.model.PromotedApp;
@@ -9,58 +10,144 @@
910

1011
import org.junit.Test;
1112

13+
import java.util.Collections;
1214
import java.util.List;
15+
import java.util.concurrent.atomic.AtomicInteger;
1316
import java.util.concurrent.atomic.AtomicReference;
1417

1518
public class DefaultHomeRepositoryTest {
1619

20+
private static final List<PromotedApp> PROMOTED_APPS =
21+
List.of(new PromotedApp("Name", "pkg", "icon"));
22+
1723
@Test
18-
public void repositoryDelegatesToDataSources() {
19-
List<PromotedApp> promoted = List.of(new PromotedApp("Name", "pkg", "icon"));
20-
FakeHomeRemoteDataSource remote = new FakeHomeRemoteDataSource(promoted);
21-
FakeHomeLocalDataSource local = new FakeHomeLocalDataSource();
24+
public void getPlayStoreUrlDelegatesToLocalSource() {
25+
SpyHomeLocalDataSource local = new SpyHomeLocalDataSource();
26+
RecordingHomeRemoteDataSource remote =
27+
new RecordingHomeRemoteDataSource(Collections.emptyList());
28+
DefaultHomeRepository repository = new DefaultHomeRepository(remote, local);
2229

30+
String result = repository.getPlayStoreUrl();
31+
32+
assertEquals("play", result);
33+
assertTrue(local.playStoreUrlCalled);
34+
assertFalse(local.appPlayStoreUrlCalled);
35+
assertFalse(local.dailyTipCalled);
36+
assertFalse(remote.fetchCalled);
37+
}
38+
39+
@Test
40+
public void getAppPlayStoreUrlDelegatesToLocalSource() {
41+
SpyHomeLocalDataSource local = new SpyHomeLocalDataSource();
42+
RecordingHomeRemoteDataSource remote =
43+
new RecordingHomeRemoteDataSource(Collections.emptyList());
2344
DefaultHomeRepository repository = new DefaultHomeRepository(remote, local);
2445

25-
assertEquals("play", repository.getPlayStoreUrl());
26-
assertEquals("play/pkg", repository.getAppPlayStoreUrl("pkg"));
27-
assertEquals("tip", repository.dailyTip());
46+
String packageName = "pkg";
47+
String result = repository.getAppPlayStoreUrl(packageName);
48+
49+
assertEquals("play/pkg", result);
50+
assertTrue(local.appPlayStoreUrlCalled);
51+
assertEquals(packageName, local.lastRequestedPackage);
52+
assertFalse(local.playStoreUrlCalled);
53+
assertFalse(local.dailyTipCalled);
54+
assertFalse(remote.fetchCalled);
55+
}
56+
57+
@Test
58+
public void dailyTipDelegatesToLocalSource() {
59+
SpyHomeLocalDataSource local = new SpyHomeLocalDataSource();
60+
RecordingHomeRemoteDataSource remote =
61+
new RecordingHomeRemoteDataSource(Collections.emptyList());
62+
DefaultHomeRepository repository = new DefaultHomeRepository(remote, local);
63+
64+
String result = repository.dailyTip();
65+
66+
assertEquals("tip", result);
67+
assertTrue(local.dailyTipCalled);
68+
assertFalse(local.playStoreUrlCalled);
69+
assertFalse(local.appPlayStoreUrlCalled);
70+
assertFalse(remote.fetchCalled);
71+
}
72+
73+
@Test
74+
public void fetchPromotedAppsDelegatesToRemoteSource() {
75+
SpyHomeLocalDataSource local = new SpyHomeLocalDataSource();
76+
RecordingHomeRemoteDataSource remote =
77+
new RecordingHomeRemoteDataSource(List.of(PROMOTED_APPS));
78+
DefaultHomeRepository repository = new DefaultHomeRepository(remote, local);
2879

2980
AtomicReference<List<PromotedApp>> result = new AtomicReference<>();
3081
repository.fetchPromotedApps(result::set);
31-
assertTrue(remote.called);
32-
assertEquals(promoted, result.get());
82+
83+
assertTrue(remote.fetchCalled);
84+
assertEquals(PROMOTED_APPS, result.get());
85+
assertFalse(local.playStoreUrlCalled);
86+
assertFalse(local.appPlayStoreUrlCalled);
87+
assertFalse(local.dailyTipCalled);
3388
}
3489

35-
private static class FakeHomeLocalDataSource implements HomeLocalDataSource {
90+
@Test
91+
public void fetchPromotedAppsEmitsOnlyFirstRemoteResponse() {
92+
SpyHomeLocalDataSource local = new SpyHomeLocalDataSource();
93+
List<PromotedApp> secondResponse =
94+
List.of(new PromotedApp("Second", "second.pkg", "secondIcon"));
95+
RecordingHomeRemoteDataSource remote =
96+
new RecordingHomeRemoteDataSource(List.of(PROMOTED_APPS, secondResponse));
97+
DefaultHomeRepository repository = new DefaultHomeRepository(remote, local);
98+
99+
AtomicInteger callbackCount = new AtomicInteger();
100+
AtomicReference<List<PromotedApp>> result = new AtomicReference<>();
101+
repository.fetchPromotedApps(apps -> {
102+
callbackCount.incrementAndGet();
103+
result.set(apps);
104+
});
105+
106+
assertTrue(remote.fetchCalled);
107+
assertEquals(1, callbackCount.get());
108+
assertEquals(PROMOTED_APPS, result.get());
109+
}
110+
111+
private static class SpyHomeLocalDataSource implements HomeLocalDataSource {
112+
boolean playStoreUrlCalled;
113+
boolean appPlayStoreUrlCalled;
114+
boolean dailyTipCalled;
115+
String lastRequestedPackage;
116+
36117
@Override
37118
public String getPlayStoreUrl() {
119+
playStoreUrlCalled = true;
38120
return "play";
39121
}
40122

41123
@Override
42124
public String getAppPlayStoreUrl(String packageName) {
125+
appPlayStoreUrlCalled = true;
126+
lastRequestedPackage = packageName;
43127
return "play/" + packageName;
44128
}
45129

46130
@Override
47131
public String getDailyTip() {
132+
dailyTipCalled = true;
48133
return "tip";
49134
}
50135
}
51136

52-
private static class FakeHomeRemoteDataSource implements HomeRemoteDataSource {
53-
private final List<PromotedApp> apps;
54-
boolean called = false;
137+
private static class RecordingHomeRemoteDataSource implements HomeRemoteDataSource {
138+
private final List<List<PromotedApp>> responses;
139+
boolean fetchCalled;
55140

56-
FakeHomeRemoteDataSource(List<PromotedApp> apps) {
57-
this.apps = apps;
141+
RecordingHomeRemoteDataSource(List<List<PromotedApp>> responses) {
142+
this.responses = responses;
58143
}
59144

60145
@Override
61146
public void fetchPromotedApps(PromotedAppsCallback callback) {
62-
called = true;
63-
callback.onResult(apps);
147+
fetchCalled = true;
148+
for (List<PromotedApp> response : responses) {
149+
callback.onResult(response);
150+
}
64151
}
65152
}
66153
}

0 commit comments

Comments
 (0)