Skip to content

Commit 78c019b

Browse files
committed
With tests
1 parent a53846e commit 78c019b

File tree

7 files changed

+283
-43
lines changed

7 files changed

+283
-43
lines changed

app/build.gradle

+5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ dependencies {
6464
testImplementation 'com.nhaarman:mockito-kotlin:1.5.0'
6565
testImplementation 'com.squareup.okhttp3:mockwebserver:3.10.0'
6666

67+
testImplementation 'org.powermock:powermock-api-mockito:1.6.2'
68+
testImplementation 'org.powermock:powermock-module-junit4-rule-agent:1.6.2'
69+
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.2'
70+
testImplementation 'org.powermock:powermock-module-junit4:1.6.2'
71+
6772
// Android testing
6873
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$KOTLIN_VERSION"
6974
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import javax.inject.Inject;
66
import javax.inject.Singleton;
77

8+
import androidx.core.text.HtmlCompat;
89
import fr.free.nrw.commons.mwapi.MediaWikiApi;
910
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
1011
import io.reactivex.Single;
@@ -47,10 +48,15 @@ public Single<Media> fetchMediaDetails(String filename) {
4748
});
4849
}
4950

51+
/**
52+
* Fetch talk page from the MediaWiki API
53+
* @param filename
54+
* @return
55+
*/
5056
private Single<String> getDiscussion(String filename) {
5157
return mediaWikiApi.fetchMediaByFilename(filename.replace("File", "File talk"))
5258
.flatMap(mediaResult -> mediaWikiApi.parseWikicode(mediaResult.getWikiSource()))
53-
.map(discussion -> Html.fromHtml(discussion).toString())
59+
.map(discussion -> HtmlCompat.fromHtml(discussion, HtmlCompat.FROM_HTML_MODE_LEGACY).toString())
5460
.onErrorReturn(throwable -> {
5561
Timber.e(throwable, "Error occurred while fetching discussion");
5662
return "";

app/src/main/java/fr/free/nrw/commons/delete/DeleteHelper.java

+9-29
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package fr.free.nrw.commons.delete;
22

3-
import android.app.NotificationManager;
4-
import android.app.PendingIntent;
53
import android.content.Context;
64
import android.content.Intent;
75
import android.net.Uri;
@@ -15,38 +13,34 @@
1513
import javax.inject.Singleton;
1614

1715
import androidx.appcompat.app.AlertDialog;
18-
import androidx.core.app.NotificationCompat;
1916
import fr.free.nrw.commons.BuildConfig;
20-
import fr.free.nrw.commons.CommonsApplication;
2117
import fr.free.nrw.commons.Media;
22-
import fr.free.nrw.commons.R;
2318
import fr.free.nrw.commons.auth.SessionManager;
2419
import fr.free.nrw.commons.mwapi.MediaWikiApi;
20+
import fr.free.nrw.commons.notification.NotificationHelper;
2521
import fr.free.nrw.commons.review.ReviewActivity;
2622
import fr.free.nrw.commons.utils.ViewUtil;
2723
import io.reactivex.Single;
2824
import timber.log.Timber;
2925

30-
import static androidx.core.app.NotificationCompat.DEFAULT_ALL;
31-
import static androidx.core.app.NotificationCompat.PRIORITY_HIGH;
26+
import static fr.free.nrw.commons.notification.NotificationHelper.NOTIFICATION_DELETE;
3227

3328
/**
3429
* Refactored async task to Rx
3530
*/
3631
@Singleton
3732
public class DeleteHelper {
38-
private static final int NOTIFICATION_DELETE = 1;
39-
4033
private final MediaWikiApi mwApi;
4134
private final SessionManager sessionManager;
42-
43-
private NotificationManager notificationManager;
44-
private NotificationCompat.Builder notificationBuilder;
35+
private final NotificationHelper notificationHelper;
4536

4637
@Inject
47-
public DeleteHelper(MediaWikiApi mwApi, SessionManager sessionManager) {
38+
public DeleteHelper(MediaWikiApi mwApi,
39+
SessionManager sessionManager,
40+
NotificationHelper notificationHelper) {
4841
this.mwApi = mwApi;
4942
this.sessionManager = sessionManager;
43+
this.notificationHelper = notificationHelper;
5044
}
5145

5246
/**
@@ -57,9 +51,6 @@ public DeleteHelper(MediaWikiApi mwApi, SessionManager sessionManager) {
5751
* @return
5852
*/
5953
public Single<Boolean> makeDeletion(Context context, Media media, String reason) {
60-
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
61-
notificationBuilder = new NotificationCompat.Builder(context, CommonsApplication.NOTIFICATION_CHANNEL_ID_ALL)
62-
.setOnlyAlertOnce(true);
6354
ViewUtil.showShortToast(context, "Trying to nominate " + media.getDisplayTitle() + " for deletion");
6455

6556
return Single.fromCallable(() -> delete(media, reason))
@@ -122,7 +113,7 @@ private boolean delete(Media media, String reason) {
122113
return true;
123114
}
124115

125-
public boolean showDeletionNotification(Context context, Media media, boolean result) {
116+
private boolean showDeletionNotification(Context context, Media media, boolean result) {
126117
String message;
127118
String title = "Nominating for Deletion";
128119

@@ -134,20 +125,9 @@ public boolean showDeletionNotification(Context context, Media media, boolean re
134125
message = "Could not request deletion.";
135126
}
136127

137-
notificationBuilder.setDefaults(DEFAULT_ALL)
138-
.setContentTitle(title)
139-
.setStyle(new NotificationCompat.BigTextStyle()
140-
.bigText(message))
141-
.setSmallIcon(R.drawable.ic_launcher)
142-
.setProgress(0, 0, false)
143-
.setOngoing(false)
144-
.setPriority(PRIORITY_HIGH);
145-
146128
String urlForDelete = BuildConfig.COMMONS_URL + "/wiki/Commons:Deletion_requests/File:" + media.getFilename();
147129
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlForDelete));
148-
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, browserIntent, PendingIntent.FLAG_UPDATE_CURRENT);
149-
notificationBuilder.setContentIntent(pendingIntent);
150-
notificationManager.notify(NOTIFICATION_DELETE, notificationBuilder.build());
130+
notificationHelper.showNotification(context, title, message, NOTIFICATION_DELETE, browserIntent);
151131
return result;
152132
}
153133

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package fr.free.nrw.commons.notification;
2+
3+
import android.app.NotificationManager;
4+
import android.app.PendingIntent;
5+
import android.content.Context;
6+
import android.content.Intent;
7+
8+
import javax.inject.Inject;
9+
import javax.inject.Singleton;
10+
11+
import androidx.core.app.NotificationCompat;
12+
import fr.free.nrw.commons.CommonsApplication;
13+
import fr.free.nrw.commons.R;
14+
15+
import static androidx.core.app.NotificationCompat.DEFAULT_ALL;
16+
import static androidx.core.app.NotificationCompat.PRIORITY_HIGH;
17+
18+
@Singleton
19+
public class NotificationHelper {
20+
21+
public static final int NOTIFICATION_DELETE = 1;
22+
23+
private NotificationManager notificationManager;
24+
private NotificationCompat.Builder notificationBuilder;
25+
26+
@Inject
27+
public NotificationHelper(Context context) {
28+
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
29+
notificationBuilder = new NotificationCompat
30+
.Builder(context, CommonsApplication.NOTIFICATION_CHANNEL_ID_ALL)
31+
.setOnlyAlertOnce(true);
32+
}
33+
34+
public void showNotification(Context context,
35+
String notificationTitle,
36+
String notificationMessage,
37+
int notificationId,
38+
Intent intent) {
39+
40+
notificationBuilder.setDefaults(DEFAULT_ALL)
41+
.setContentTitle(notificationTitle)
42+
.setStyle(new NotificationCompat.BigTextStyle()
43+
.bigText(notificationMessage))
44+
.setSmallIcon(R.drawable.ic_launcher)
45+
.setProgress(0, 0, false)
46+
.setOngoing(false)
47+
.setPriority(PRIORITY_HIGH);
48+
49+
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
50+
notificationBuilder.setContentIntent(pendingIntent);
51+
notificationManager.notify(notificationId, notificationBuilder.build());
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package fr.free.nrw.commons
2+
3+
import fr.free.nrw.commons.mwapi.MediaResult
4+
import fr.free.nrw.commons.mwapi.MediaWikiApi
5+
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
6+
import io.reactivex.Single
7+
import junit.framework.Assert.assertTrue
8+
import org.junit.Before
9+
import org.junit.Test
10+
import org.mockito.ArgumentMatchers
11+
import org.mockito.InjectMocks
12+
import org.mockito.Mock
13+
import org.mockito.Mockito.`when`
14+
import org.mockito.Mockito.mock
15+
import org.mockito.MockitoAnnotations
16+
17+
class MediaDataExtractorTest {
18+
19+
@Mock
20+
internal var mwApi: MediaWikiApi? = null
21+
22+
@Mock
23+
internal var okHttpJsonApiClient: OkHttpJsonApiClient? = null
24+
25+
@InjectMocks
26+
var mediaDataExtractor: MediaDataExtractor? = null
27+
28+
@Before
29+
@Throws(Exception::class)
30+
fun setUp() {
31+
MockitoAnnotations.initMocks(this)
32+
}
33+
34+
@Test
35+
fun fetchMediaDetails() {
36+
`when`(okHttpJsonApiClient!!.getMedia(ArgumentMatchers.anyString(), ArgumentMatchers.anyBoolean()))
37+
.thenReturn(Single.just(mock(Media::class.java)))
38+
39+
`when`(mwApi!!.pageExists(ArgumentMatchers.anyString()))
40+
.thenReturn(Single.just(true))
41+
42+
val mediaResult = mock(MediaResult::class.java)
43+
`when`(mediaResult.wikiSource).thenReturn("some wiki source")
44+
`when`(mwApi!!.fetchMediaByFilename(ArgumentMatchers.anyString()))
45+
.thenReturn(Single.just(mediaResult))
46+
47+
`when`(mwApi!!.parseWikicode(ArgumentMatchers.anyString()))
48+
.thenReturn(Single.just("discussion text"))
49+
50+
val fetchMediaDetails = mediaDataExtractor!!.fetchMediaDetails("test.jpg").blockingGet()
51+
52+
assertTrue(fetchMediaDetails is Media)
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package fr.free.nrw.commons.delete
2+
3+
import android.accounts.Account
4+
import android.content.Context
5+
import fr.free.nrw.commons.Media
6+
import fr.free.nrw.commons.auth.SessionManager
7+
import fr.free.nrw.commons.mwapi.MediaWikiApi
8+
import fr.free.nrw.commons.notification.NotificationHelper
9+
import fr.free.nrw.commons.utils.ViewUtil
10+
import junit.framework.Assert.assertFalse
11+
import junit.framework.Assert.assertTrue
12+
import org.junit.Test
13+
import org.junit.runner.RunWith
14+
import org.mockito.InjectMocks
15+
import org.mockito.Mock
16+
import org.mockito.Mockito.`when`
17+
import org.mockito.MockitoAnnotations
18+
import org.powermock.api.mockito.PowerMockito
19+
import org.powermock.core.classloader.annotations.PrepareForTest
20+
import org.powermock.modules.junit4.PowerMockRunner
21+
22+
@RunWith(PowerMockRunner::class)
23+
@PrepareForTest(ViewUtil::class)
24+
class DeleteHelperTest {
25+
26+
@Mock
27+
internal var mwApi: MediaWikiApi? = null
28+
29+
@Mock
30+
internal var sessionManager: SessionManager? = null
31+
32+
@Mock
33+
internal var notificationHelper: NotificationHelper? = null
34+
35+
@Mock
36+
internal var context: Context? = null
37+
38+
@Mock
39+
internal var media: Media? = null
40+
41+
@InjectMocks
42+
var deleteHelper: DeleteHelper? = null
43+
44+
@Test
45+
fun makeDeletion() {
46+
`when`(mwApi!!.editToken).thenReturn("token")
47+
`when`(sessionManager!!.authCookie).thenReturn("Mock cookie")
48+
`when`(sessionManager!!.currentAccount).thenReturn(Account("TestUser", "Test"))
49+
50+
MockitoAnnotations.initMocks(this)
51+
PowerMockito.mockStatic(ViewUtil::class.java)
52+
53+
`when`(media!!.displayTitle).thenReturn("Test file")
54+
`when`(media!!.filename).thenReturn("Test file.jpg")
55+
56+
val makeDeletion = deleteHelper!!.makeDeletion(context, media, "Test reason").blockingGet()
57+
assertTrue(makeDeletion)
58+
}
59+
60+
@Test
61+
fun makeDeletionForNullToken() {
62+
`when`(mwApi!!.editToken).thenReturn(null)
63+
`when`(sessionManager!!.authCookie).thenReturn("Mock cookie")
64+
`when`(sessionManager!!.currentAccount).thenReturn(Account("TestUser", "Test"))
65+
66+
MockitoAnnotations.initMocks(this)
67+
PowerMockito.mockStatic(ViewUtil::class.java)
68+
69+
`when`(media!!.displayTitle).thenReturn("Test file")
70+
`when`(media!!.filename).thenReturn("Test file.jpg")
71+
72+
val makeDeletion = deleteHelper!!.makeDeletion(context, media, "Test reason").blockingGet()
73+
assertFalse(makeDeletion)
74+
}
75+
}

0 commit comments

Comments
 (0)