Skip to content

Commit

Permalink
Add test cases and java docs
Browse files Browse the repository at this point in the history
  • Loading branch information
maskaravivek committed Jun 17, 2019
1 parent 2d7eac8 commit dbd1a63
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public MediaDataExtractor(MediaWikiApi mwApi,
*/
public Single<Media> fetchMediaDetails(String filename) {
Single<Media> mediaSingle = getMediaFromFileName(filename);
Single<Boolean> pageExistsSingle = mediaClient.doesPageExist("Commons:Deletion_requests/" + filename);
Single<Boolean> pageExistsSingle = mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/" + filename);
Single<String> discussionSingle = getDiscussion(filename);
return Single.zip(mediaSingle, pageExistsSingle, discussionSingle, (media, deletionStatus, discussion) -> {
media.setDiscussion(discussion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class NetworkingModule {

public static final long OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024;

private static final String NAMED_COMMONS_WIKI_SITE = "commons-wikisite";

@Provides
@Singleton
public OkHttpClient provideOkHttpClient(Context context,
Expand Down Expand Up @@ -121,13 +123,13 @@ public WikiSite provideCommonsWikiSite() {

@Provides
@Singleton
public ReviewInterface provideReviewInterface(@Named("commons-wikisite") WikiSite commonsWikiSite) {
public ReviewInterface provideReviewInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, ReviewInterface.class);
}

@Provides
@Singleton
public MediaInterface provideMediaInterface(@Named("commons-wikisite") WikiSite commonsWikiSite) {
public MediaInterface provideMediaInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, MediaInterface.class);
}
}
28 changes: 22 additions & 6 deletions app/src/main/java/fr/free/nrw/commons/media/MediaClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

import io.reactivex.Single;

/**
* Media Client to handle custom calls to Commons MediaWiki APIs
*/
@Singleton
public class MediaClient {

Expand All @@ -16,15 +19,28 @@ public MediaClient(MediaInterface mediaInterface) {
this.mediaInterface = mediaInterface;
}

public Single<Boolean> doesPageExist(String title) {
return mediaInterface.doesPageExist(title)
.map(mwQueryResponse -> mwQueryResponse.query().firstPage() != null)
/**
* Checks if a page exists on Commons
* The same method can be used to check for file or talk page
*
* @param title File:Test.jpg or Commons:Deletion_requests/File:Test1.jpeg
*/
public Single<Boolean> checkPageExistsUsingTitle(String title) {
return mediaInterface.checkPageExistsUsingTitle(title)
.map(mwQueryResponse -> mwQueryResponse
.query().firstPage() != null)
.singleOrError();
}

public Single<Boolean> doesFileExist(String fileSha) {
return mediaInterface.doesFileExist(fileSha)
.map(mwQueryResponse -> mwQueryResponse.query().firstPage().allImages().size() > 0)
/**
* Take the fileSha and returns whether a file with a matching SHA exists or not
*
* @param fileSha SHA of the file to be checked
*/
public Single<Boolean> checkFileExistsUsingSha(String fileSha) {
return mediaInterface.checkFileExistsUsingSha(fileSha)
.map(mwQueryResponse -> mwQueryResponse
.query().firstPage().allImages().size() > 0)
.singleOrError();
}
}
17 changes: 15 additions & 2 deletions app/src/main/java/fr/free/nrw/commons/media/MediaInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,23 @@
import retrofit2.http.GET;
import retrofit2.http.Query;

/**
* Interface for interacting with Commons media related APIs
*/
public interface MediaInterface {
/**
* Checks if a page exists or not.
* @param title the title of the page to be checked
* @return
*/
@GET("w/api.php?action=query")
Observable<MwQueryResponse> doesPageExist(@Query("titles") String title);
Observable<MwQueryResponse> checkPageExistsUsingTitle(@Query("titles") String title);

/**
* Check if file exists
* @param aisha1 the SHA of the media file to be checked
* @return
*/
@GET("w/api.php?action=query&list=allimages")
Observable<MwQueryResponse> doesFileExist(@Query("aisha1") String aisha1);
Observable<MwQueryResponse> checkFileExistsUsingSha(@Query("aisha1") String aisha1);
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public Single<Media> getRandomMedia() {
*/
private Single<Media> getRandomMediaFromRecentChange(RecentChange recentChange) {
return Single.just(recentChange)
.flatMap(change -> mediaClient.doesPageExist("Commons:Deletion_requests/" + change.getTitle()))
.flatMap(change -> mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/" + change.getTitle()))
.flatMap(isDeleted -> {
if (isDeleted) {
return Single.just(new Media(""));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ private Single<Integer> validateItemTitle(UploadModel.UploadItem uploadItem) {
return Single.just(EMPTY_TITLE);
}

return mediaClient.doesPageExist(uploadItem.getFileName())
return mediaClient.checkPageExistsUsingTitle(uploadItem.getFileName())
.map(doesFileExist -> {
Timber.d("Result for valid title is %s", doesFileExist);
return doesFileExist ? FILE_NAME_EXISTS : IMAGE_OK;
Expand All @@ -149,7 +149,7 @@ private Single<Integer> checkDuplicateImage(String filePath) {
return Single.fromCallable(() ->
fileUtilsWrapper.getFileInputStream(filePath))
.map(fileUtilsWrapper::getSHA1)
.flatMap(mediaClient::doesFileExist)
.flatMap(mediaClient::checkFileExistsUsingSha)
.map(b -> {
Timber.d("Result for duplicate image %s", b);
return b ? ImageUtils.IMAGE_DUPLICATE : ImageUtils.IMAGE_OK;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ private String findUniqueFilename(String fileName) throws IOException {
sequenceFileName = regexMatcher.replaceAll("$1 " + sequenceNumber + "$2");
}
}
if (!mediaClient.doesPageExist(sequenceFileName).blockingGet()
if (!mediaClient.checkPageExistsUsingTitle(sequenceFileName).blockingGet()
&& !unfinishedUploads.contains(sequenceFileName)) {
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class MediaDataExtractorTest {
`when`(okHttpJsonApiClient?.getMedia(ArgumentMatchers.anyString(), ArgumentMatchers.anyBoolean()))
.thenReturn(Single.just(mock(Media::class.java)))

`when`(mediaClient?.doesPageExist(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))

val mediaResult = mock(MediaResult::class.java)
Expand Down
97 changes: 97 additions & 0 deletions app/src/test/kotlin/fr/free/nrw/commons/media/MediaClientTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package fr.free.nrw.commons.media

import io.reactivex.Observable
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentMatchers
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
import org.wikipedia.dataclient.mwapi.MwQueryPage
import org.wikipedia.dataclient.mwapi.MwQueryResponse
import org.wikipedia.dataclient.mwapi.MwQueryResult
import org.wikipedia.gallery.ImageInfo

class MediaClientTest {

@Mock
internal var mediaInterface: MediaInterface? = null

@InjectMocks
var mediaClient: MediaClient? = null

@Before
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.initMocks(this)
}

@Test
fun checkPageExistsUsingTitle() {
val mwQueryPage = mock(MwQueryPage::class.java)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)

`when`(mediaInterface!!.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))

val checkPageExistsUsingTitle = mediaClient!!.checkPageExistsUsingTitle("File:Test.jpg").blockingGet()
assertTrue(checkPageExistsUsingTitle)
}

@Test
fun checkPageNotExistsUsingTitle() {
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(null)
`when`(mwQueryResult.pages()).thenReturn(listOf())
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)

`when`(mediaInterface!!.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))

val checkPageExistsUsingTitle = mediaClient!!.checkPageExistsUsingTitle("File:Test.jpg").blockingGet()
assertFalse(checkPageExistsUsingTitle)
}

@Test
fun checkFileExistsUsingSha() {
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.allImages()).thenReturn(listOf(mock(ImageInfo::class.java)))
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)

`when`(mediaInterface!!.checkFileExistsUsingSha(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))

val checkFileExistsUsingSha = mediaClient!!.checkFileExistsUsingSha("abcde").blockingGet()
assertTrue(checkFileExistsUsingSha)
}

@Test
fun checkFileNotExistsUsingSha() {
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.allImages()).thenReturn(listOf())
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)

`when`(mediaInterface!!.checkFileExistsUsingSha(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))

val checkFileExistsUsingSha = mediaClient!!.checkFileExistsUsingSha("abcde").blockingGet()
assertFalse(checkFileExistsUsingSha)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class ReviewHelperTest {
*/
@Test
fun getRandomMedia() {
`when`(mediaClient?.doesPageExist(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(false))

val randomMedia = reviewHelper?.randomMedia?.blockingGet()
Expand All @@ -92,7 +92,7 @@ class ReviewHelperTest {
*/
@Test(expected = RuntimeException::class)
fun getRandomMediaWithWithAllMediaNominatedForDeletion() {
`when`(mediaClient?.doesPageExist(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val media = reviewHelper?.randomMedia?.blockingGet()
assertNull(media)
Expand All @@ -104,11 +104,11 @@ class ReviewHelperTest {
*/
@Test
fun getRandomMediaWithWithOneMediaNominatedForDeletion() {
`when`(mediaClient?.doesPageExist("Commons:Deletion_requests/File:Test1.jpeg"))
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test1.jpeg"))
.thenReturn(Single.just(true))
`when`(mediaClient?.doesPageExist("Commons:Deletion_requests/File:Test2.png"))
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test2.png"))
.thenReturn(Single.just(false))
`when`(mediaClient?.doesPageExist("Commons:Deletion_requests/File:Test3.jpg"))
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test3.jpg"))
.thenReturn(Single.just(true))

val media = reviewHelper?.randomMedia?.blockingGet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ class u {
.thenReturn(mock(FileInputStream::class.java))
`when`(fileUtilsWrapper!!.getSHA1(any(FileInputStream::class.java)))
.thenReturn("fileSha")
`when`(mediaClient!!.doesFileExist(ArgumentMatchers.anyString()))
`when`(mediaClient!!.checkFileExistsUsingSha(ArgumentMatchers.anyString()))
.thenReturn(Single.just(false))
`when`(mediaClient?.doesPageExist(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(false))
`when`(readFBMD?.processMetadata(ArgumentMatchers.any(),ArgumentMatchers.any()))
.thenReturn(Single.just(ImageUtils.IMAGE_OK))
Expand All @@ -96,7 +96,7 @@ class u {

@Test
fun validateImageForDuplicateImage() {
`when`(mediaClient!!.doesFileExist(ArgumentMatchers.anyString()))
`when`(mediaClient!!.checkFileExistsUsingSha(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val validateImage = imageProcessingService!!.validateImage(uploadItem, false)
assertEquals(ImageUtils.IMAGE_DUPLICATE, validateImage.blockingGet())
Expand Down Expand Up @@ -126,15 +126,15 @@ class u {

@Test
fun validateImageForFileNameExistsWithCheckTitleOff() {
`when`(mediaClient?.doesPageExist(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val validateImage = imageProcessingService!!.validateImage(uploadItem, false)
assertEquals(ImageUtils.IMAGE_OK, validateImage.blockingGet())
}

@Test
fun validateImageForFileNameExistsWithCheckTitleOn() {
`when`(mediaClient?.doesPageExist(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val validateImage = imageProcessingService!!.validateImage(uploadItem, true)
assertEquals(ImageUtils.FILE_NAME_EXISTS, validateImage.blockingGet())
Expand Down

0 comments on commit dbd1a63

Please sign in to comment.