Convert API clients to kotlin (#5567)

* Convert UserClient to kotlin

* Added tests for WikiBaseClient

* Removed superfluous dao tests in review helper and got the proper ReviewDaoTest running in the unit test suite

* Improved tests for ReviewHelper

* Convert the ReviewHelper to kotlin

* Convert the WikiBaseClient to kotlin

* Convert the WikidataClient to kotlin
This commit is contained in:
Paul Hawke 2024-02-19 18:23:11 -06:00 committed by GitHub
parent c43405267a
commit 728712c4e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 496 additions and 526 deletions

View file

@ -36,7 +36,7 @@ class UserClientTest{
Mockito.`when`(userInterface!!.getUserBlockInfo())
.thenReturn(Observable.just(mockResponse))
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
val isBanned = userClient!!.isUserBlockedFromCommons().blockingGet()
assertTrue(isBanned)
}
@ -54,7 +54,7 @@ class UserClientTest{
Mockito.`when`(userInterface!!.getUserBlockInfo())
.thenReturn(Observable.just(mockResponse))
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
val isBanned = userClient!!.isUserBlockedFromCommons().blockingGet()
assertTrue(isBanned)
}
@ -69,7 +69,7 @@ class UserClientTest{
Mockito.`when`(userInterface!!.getUserBlockInfo())
.thenReturn(Observable.just(mockResponse))
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
val isBanned = userClient!!.isUserBlockedFromCommons().blockingGet()
assertFalse(isBanned)
}

View file

@ -111,10 +111,10 @@ class ReviewActivityTest {
val media = mock(Media::class.java)
doReturn(mapOf<String, Boolean>("test" to false)).`when`(media).categoriesHiddenStatus
doReturn(Single.just(media)).`when`(reviewHelper)?.randomMedia
Assert.assertNotNull(reviewHelper?.randomMedia)
doReturn(Single.just(media)).`when`(reviewHelper)?.getRandomMedia()
Assert.assertNotNull(reviewHelper?.getRandomMedia())
reviewHelper
?.randomMedia
?.getRandomMedia()
?.test()
?.assertValue(media);
activity.swipeToNext()

View file

@ -0,0 +1,73 @@
package fr.free.nrw.commons.review
import androidx.room.Room.inMemoryDatabaseBuilder
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.db.AppDatabase
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
@RunWith(AndroidJUnit4::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
@LooperMode(LooperMode.Mode.PAUSED)
class ReviewDaoTest {
private lateinit var reviewDao: ReviewDao
private lateinit var database: AppDatabase
/**
* Set up the application database
*/
@Before
fun createDb() {
database = inMemoryDatabaseBuilder(
context = ApplicationProvider.getApplicationContext(),
klass = AppDatabase::class.java
).allowMainThreadQueries().build()
reviewDao = database.ReviewDao()
}
/**
* Close the database
*/
@After
fun closeDb() {
database.close()
}
/**
* Test insertion
* Also checks isReviewedAlready():
* Case 1: When image has been reviewed/skipped by the user
*/
@Test
fun insert() {
// Insert data
val imageId = "1234"
val reviewEntity = ReviewEntity(imageId)
reviewDao.insert(reviewEntity)
// Check insertion
// Covers the case where the image exists in the database
// And isReviewedAlready() returns true
val isInserted = reviewDao.isReviewedAlready(imageId)
MatcherAssert.assertThat(isInserted, CoreMatchers.equalTo(true))
}
@Test
fun isReviewedAlready() {
/**
* Test review status of the image
* Case 2: When image has not been reviewed/skipped
*/
val imageId = "5856"
val isInserted = reviewDao.isReviewedAlready(imageId)
MatcherAssert.assertThat(isInserted, CoreMatchers.equalTo(false))
}
}

View file

@ -1,40 +1,32 @@
package fr.free.nrw.commons.review
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.media.MediaClient
import io.reactivex.Completable
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResult
import io.reactivex.Observable
import io.reactivex.Single
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.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.*
import org.mockito.MockitoAnnotations
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResult
import java.util.concurrent.Callable
/**
* Test class for ReviewHelper
*/
class ReviewHelperTest {
@Mock
internal var reviewInterface: ReviewInterface? = null
@Mock
internal var mediaClient: MediaClient? = null
private val reviewInterface = mock<ReviewInterface>()
private val mediaClient = mock<MediaClient>()
private val reviewHelper = ReviewHelper(mediaClient, reviewInterface)
@InjectMocks
var reviewHelper: ReviewHelper? = null
val dao = mock(ReviewDao::class.java)
private val mwQueryResult = mock<MwQueryResult>()
private val mockResponse = mock<MwQueryResponse>()
/**
* Init mocks
@ -42,28 +34,8 @@ class ReviewHelperTest {
@Before
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.openMocks(this)
val mwQueryPage = mock(MwQueryPage::class.java)
val mockRevision = mock(MwQueryPage.Revision::class.java)
`when`(mockRevision.user).thenReturn("TestUser")
`when`(mwQueryPage.revisions()).thenReturn(listOf(mockRevision))
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`(reviewInterface?.getRecentChanges())
.thenReturn(Observable.just(mockResponse))
`when`(reviewInterface?.getFirstRevisionOfFile(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
val media = mock(Media::class.java)
whenever(media.filename).thenReturn("Test file.jpg")
`when`(mediaClient?.getMedia(ArgumentMatchers.anyString()))
.thenReturn(Single.just(media))
whenever(mockResponse.query()).thenReturn(mwQueryResult)
whenever(reviewInterface.getRecentChanges()).thenReturn(Observable.just(mockResponse))
}
/**
@ -71,14 +43,19 @@ class ReviewHelperTest {
*/
@Test
fun getRandomMedia() {
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(false))
whenever(mediaClient.checkPageExistsUsingTitle(any())).thenReturn(Single.just(false))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(false))
val page1 = setupMedia("one.jpg")
val page2 = setupMedia("two.jpeg")
val page3 = setupMedia("three.png")
val ignored = setupMedia("ignored.txt")
whenever(mwQueryResult.pages()).thenReturn(listOf(page1, page2, page3, ignored))
reviewHelper?.randomMedia
verify(reviewInterface, times(1))!!.getRecentChanges()
val random = reviewHelper.getRandomMedia().test()
random.assertNoErrors()
assertEquals(1, random.valueCount())
assertTrue(setOf("one.jpg", "two.jpeg", "three.png").contains(random.values().first().filename))
}
/**
@ -86,9 +63,12 @@ class ReviewHelperTest {
*/
@Test(expected = RuntimeException::class)
fun getRandomMediaWithWithAllMediaNominatedForDeletion() {
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val media = reviewHelper?.randomMedia?.blockingGet()
whenever(mediaClient.checkPageExistsUsingTitle(any())).thenReturn(Single.just(true))
val page1 = setupMedia("one.jpg")
whenever(mwQueryResult.pages()).thenReturn(listOf(page1))
val media = reviewHelper.getRandomMedia().blockingGet()
assertNull(media)
verify(reviewInterface, times(1))!!.getRecentChanges()
}
@ -98,15 +78,14 @@ class ReviewHelperTest {
*/
@Test
fun getRandomMediaWithWithOneMediaNominatedForDeletion() {
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test1.jpeg"))
.thenReturn(Single.just(true))
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test2.png"))
.thenReturn(Single.just(false))
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test3.jpg"))
.thenReturn(Single.just(true))
whenever(mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/one.jpg")).thenReturn(Single.just(true))
reviewHelper?.randomMedia
verify(reviewInterface, times(1))!!.getRecentChanges()
val page1 = setupMedia("one.jpg")
whenever(mwQueryResult.pages()).thenReturn(listOf(page1))
val random = reviewHelper.getRandomMedia().test()
assertEquals("one.jpg is deleted", random.errors().first().message)
}
/**
@ -114,57 +93,55 @@ class ReviewHelperTest {
*/
@Test
fun getFirstRevisionOfFile() {
val firstRevisionOfFile = reviewHelper?.getFirstRevisionOfFile("Test.jpg")?.blockingFirst()
val rev1 = mock<MwQueryPage.Revision>()
whenever(rev1.user).thenReturn("TestUser")
whenever(rev1.revisionId).thenReturn(1L)
val rev2 = mock<MwQueryPage.Revision>()
whenever(rev2.user).thenReturn("TestUser")
whenever(rev2.revisionId).thenReturn(2L)
assertTrue(firstRevisionOfFile is MwQueryPage.Revision)
val page = setupMedia("Test.jpg", rev1, rev2)
whenever(mwQueryResult.firstPage()).thenReturn(page)
whenever(reviewInterface.getFirstRevisionOfFile(any())).thenReturn(Observable.just(mockResponse))
val firstRevisionOfFile = reviewHelper.getFirstRevisionOfFile("Test.jpg").blockingFirst()
assertEquals(1, firstRevisionOfFile.revisionId)
}
/**
* Test the review status of the image
* Case 1: Image identifier exists in the database
*/
@Test
fun getReviewStatusWhenImageHasBeenReviewedAlready() {
val testImageId1 = "123456"
`when`(dao.isReviewedAlready(testImageId1)).thenReturn(true)
fun checkFileUsage() {
whenever(reviewInterface.getGlobalUsageInfo(any())).thenReturn(Observable.just(mockResponse))
val page = setupMedia("Test.jpg")
whenever(mwQueryResult.firstPage()).thenReturn(page)
whenever(page.checkWhetherFileIsUsedInWikis()).thenReturn(true)
val observer = io.reactivex.observers.TestObserver<Boolean>()
Observable.fromCallable(Callable<Boolean> {
dao.isReviewedAlready(testImageId1)
}).subscribeWith(observer)
observer.assertValue(true)
observer.dispose()
val result = reviewHelper.checkFileUsage("Test.jpg").test()
assertTrue(result.values().first())
}
/**
* Test the review status of the image
* Case 2: Image identifier does not exist in the database
*/
@Test
fun getReviewStatusWhenImageHasBeenNotReviewedAlready() {
val testImageId2 = "789101"
`when`(dao.isReviewedAlready(testImageId2)).thenReturn(false)
fun testReviewStatus() {
val reviewDao = mock<ReviewDao>()
whenever(reviewDao.isReviewedAlready("Test.jpg")).thenReturn(true)
val observer = io.reactivex.observers.TestObserver<Boolean>()
Observable.fromCallable(Callable<Boolean> {
dao.isReviewedAlready(testImageId2)
}).subscribeWith(observer)
observer.assertValue(false)
observer.dispose()
reviewHelper.dao = reviewDao
val result = reviewHelper.getReviewStatus("Test.jpg")
assertTrue(result)
}
/**
* Test the successful insertion of the image identifier into the database
*/
@Test
fun addViewedImagesToDB() {
val testImageId = "123456"
private fun setupMedia(file: String, vararg revision: MwQueryPage.Revision): MwQueryPage = mock<MwQueryPage>().apply {
whenever(title()).thenReturn(file)
if (revision.isNotEmpty()) {
whenever(revisions()).thenReturn(*revision.toMutableList())
}
val observer = io.reactivex.observers.TestObserver<Boolean>()
Completable.fromAction {
dao.insert(ReviewEntity(testImageId))
}.subscribeWith(observer)
observer.assertComplete()
observer.dispose()
val media = mock<Media>().apply {
whenever(filename).thenReturn(file)
whenever(pageId).thenReturn(file.split(".").first())
}
whenever(mediaClient.getMedia(file)).thenReturn(Single.just(media))
}
}

View file

@ -1,31 +1,84 @@
package fr.free.nrw.commons.wikidata
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient
import fr.free.nrw.commons.upload.UploadResult
import fr.free.nrw.commons.upload.WikiBaseInterface
import fr.free.nrw.commons.wikidata.mwapi.MwPostResponse
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResult
import io.reactivex.Observable
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertSame
import junit.framework.TestCase.assertTrue
import org.junit.Before
import org.junit.Test
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient
import org.mockito.Mockito.mock
class WikiBaseClientUnitTest {
@Mock
internal var csrfTokenClient: CsrfTokenClient? = null
@InjectMocks
var wikiBaseClient: WikiBaseClient? = null
private val csrfTokenClient: CsrfTokenClient = mock()
private val wikiBaseInterface: WikiBaseInterface = mock()
private val wikiBaseClient = WikiBaseClient(wikiBaseInterface, csrfTokenClient)
@Before
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.openMocks(this)
Mockito.`when`(csrfTokenClient!!.getTokenBlocking())
.thenReturn("test")
whenever(csrfTokenClient.getTokenBlocking()).thenReturn("test")
}
@Test
fun testPostEditEntity() {
val response = mock<MwPostResponse>()
whenever(response.successVal).thenReturn(1)
whenever(wikiBaseInterface.postEditEntity("the-id", "test", "the-data"))
.thenReturn(Observable.just(response))
val result = wikiBaseClient.postEditEntity("the-id", "the-data").blockingFirst()
assertTrue(result)
}
@Test
fun testPostEditEntityByFilename() {
wikiBaseClient?.postEditEntityByFilename("File:Example.jpg", "data")
val response = mock<MwPostResponse>()
whenever(response.successVal).thenReturn(1)
whenever(wikiBaseInterface.postEditEntityByFilename("File:Example.jpg", "test", "the-data"))
.thenReturn(Observable.just(response))
val result = wikiBaseClient.postEditEntityByFilename("File:Example.jpg", "the-data").blockingFirst()
assertTrue(result)
}
@Test
fun getFileEntityId() {
val upload = UploadResult("result", "key", 0, "Example.jpg")
val response = mock<MwQueryResponse>()
val query = mock<MwQueryResult>()
val page = mock<MwQueryPage>()
whenever(response.query()).thenReturn(query)
whenever(query.pages()).thenReturn(mutableListOf(page))
whenever(page.pageId()).thenReturn(123)
whenever(wikiBaseInterface.getFileEntityId("File:Example.jpg"))
.thenReturn(Observable.just(response))
val result = wikiBaseClient.getFileEntityId(upload).blockingFirst()
assertEquals(123L, result)
}
@Test
fun addLabelstoWikidata() {
val mwPostResponse = mock<MwPostResponse>()
whenever(wikiBaseInterface.addLabelstoWikidata(
"M123", "test", "en", "caption"
)).thenReturn(Observable.just(mwPostResponse))
val result = wikiBaseClient.addLabelstoWikidata(123L, "en", "caption").blockingFirst()
assertSame(mwPostResponse, result)
}
}

View file

@ -2,6 +2,7 @@ package fr.free.nrw.commons.wikidata
import android.content.Context
import com.google.gson.Gson
import com.nhaarman.mockitokotlin2.anyOrNull
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.kvstore.JsonKvStore
@ -61,7 +62,7 @@ class WikidataEditServiceTest {
fun createImageClaim() {
whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
.thenReturn(true)
whenever(wikibaseClient.getFileEntityId(any())).thenReturn(Observable.just(1L))
whenever(wikibaseClient.getFileEntityId(anyOrNull())).thenReturn(Observable.just(1L))
whenever(wikidataClient.setClaim(any(), anyString()))
.thenReturn(Observable.just(1L))
val wikidataPlace: WikidataPlace = mock()