#3749 Improve MediaClient UnitTests - test rewrite

This commit is contained in:
Sean Mac Gillicuddy 2020-06-25 08:57:03 +01:00
parent 454d7adaa8
commit 501e5f7f23
2 changed files with 192 additions and 229 deletions

View file

@ -107,21 +107,6 @@ class MediaClient @Inject constructor(
)
}
private fun mediaFromPageAndEntity(pages: List<MwQueryPage>): Single<List<Media>> {
return if (pages.isEmpty())
Single.just(emptyList())
else
getEntities(pages.map { "$PAGE_ID_PREFIX${it.pageId()}" })
.map {
pages.zip(it.entities().values)
.mapNotNull { (page, entity) ->
page.imageInfo()?.let {
mediaConverter.convert(page, entity, it)
}
}
}
}
/**
* Fetches Media object from the imageInfo API
*
@ -141,7 +126,6 @@ class MediaClient @Inject constructor(
fun getPictureOfTheDay(): Single<Media> {
val date = CommonsDateUtil.getIso8601DateFormatShort().format(Date())
return responseMapper(mediaInterface.getMediaWithGenerator("Template:Potd/$date")).map { it.first() }
}
fun getPageHtml(title: String?): Single<String> {
@ -156,7 +140,6 @@ class MediaClient @Inject constructor(
mediaDetailInterface.getEntity(entityIds.joinToString("|"))
}
fun doesPageContainMedia(title: String?): Single<Boolean> {
return pageMediaInterface.getMediaList(title)
.map { it.items.isNotEmpty() }
@ -175,4 +158,19 @@ class MediaClient @Inject constructor(
it.query()?.pages() ?: emptyList()
}.flatMap(::mediaFromPageAndEntity)
}
private fun mediaFromPageAndEntity(pages: List<MwQueryPage>): Single<List<Media>> {
return if (pages.isEmpty())
Single.just(emptyList())
else
getEntities(pages.map { "$PAGE_ID_PREFIX${it.pageId()}" })
.map {
pages.zip(it.entities().values)
.mapNotNull { (page, entity) ->
page.imageInfo()?.let {
mediaConverter.convert(page, entity, it)
}
}
}
}
}

View file

@ -4,266 +4,231 @@ import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.explore.media.MediaConverter
import fr.free.nrw.commons.media.model.PageMediaListItem
import fr.free.nrw.commons.media.model.PageMediaListResponse
import fr.free.nrw.commons.utils.CommonsDateUtil
import io.reactivex.Single
import junit.framework.Assert.*
import media
import org.junit.Before
import org.junit.Test
import org.mockito.*
import org.mockito.Mockito.*
import org.wikipedia.dataclient.mwapi.ImageDetails
import org.mockito.ArgumentMatchers
import org.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
import org.wikipedia.wikidata.Entities
import java.util.*
class MediaClientTest {
@Mock
internal var mediaInterface: MediaInterface? = null
@Mock
internal var mediaConverter: MediaConverter? = null
@Mock
internal var mediaDetailInterface: MediaDetailInterface? = null
internal lateinit var mediaInterface: MediaInterface
@Mock
internal var pageMediaInterface: PageMediaInterface? = null
internal lateinit var mediaConverter: MediaConverter
@Mock
internal lateinit var mediaDetailInterface: MediaDetailInterface
@InjectMocks
var mediaClient: MediaClient? = null
@Mock
internal lateinit var pageMediaInterface: PageMediaInterface
val continuationMap = mapOf("continuation" to "continuation")
private lateinit var mediaClient: MediaClient
@Before
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.initMocks(this)
mediaClient =
MediaClient(mediaInterface, pageMediaInterface, mediaDetailInterface, mediaConverter)
}
@Test
fun checkPageExistsUsingTitle() {
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.pageId()).thenReturn(10)
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(Single.just(mockResponse))
val checkPageExistsUsingTitle =
mediaClient!!.checkPageExistsUsingTitle("File:Test.jpg").blockingGet()
assertTrue(checkPageExistsUsingTitle)
fun `getMediaById maps response of interface`() {
val (mwQueryResponse, media) = expectSuccessfulMapping()
whenever(mediaInterface.getMediaById("id")).thenReturn(Single.just(mwQueryResponse))
mediaClient.getMediaById("id").test().assertValue(media)
}
@Test
fun checkPageNotExistsUsingTitle() {
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.pageId()).thenReturn(0)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
`when`(mwQueryResult.pages()).thenReturn(listOf())
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mockResponse))
val checkPageExistsUsingTitle =
mediaClient!!.checkPageExistsUsingTitle("File:Test.jpg").blockingGet()
assertFalse(checkPageExistsUsingTitle)
fun `checkPageExistsUsingTitle returns true for greater than 0 id`() {
val mwQueryResponse = expectResponseWithPageId(1)
whenever(mediaInterface.checkPageExistsUsingTitle(""))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.checkPageExistsUsingTitle("").test().assertValue(true)
}
@Test
fun checkFileExistsUsingSha() {
val mwQueryPage = mock(MwQueryPage::class.java)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.allImages()).thenReturn(listOf(mock(ImageDetails::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(Single.just(mockResponse))
val checkFileExistsUsingSha = mediaClient!!.checkFileExistsUsingSha("abcde").blockingGet()
assertTrue(checkFileExistsUsingSha)
fun `checkPageExistsUsingTitle returns false for 0 id`() {
val mwQueryResponse = expectResponseWithPageId(0)
whenever(mediaInterface.checkPageExistsUsingTitle(""))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.checkPageExistsUsingTitle("").test().assertValue(false)
}
@Test
fun checkFileNotExistsUsingSha() {
val mwQueryPage = mock(MwQueryPage::class.java)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.allImages()).thenReturn(listOf())
`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(Single.just(mockResponse))
val checkFileExistsUsingSha = mediaClient!!.checkFileExistsUsingSha("abcde").blockingGet()
assertFalse(checkFileExistsUsingSha)
fun `checkFileExistsUsingSha returns false with no Images`() {
val mwQueryResponse = mockQuery {
whenever(allImages()).thenReturn(listOf())
}
whenever(mediaInterface.checkFileExistsUsingSha(""))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.checkFileExistsUsingSha("").test().assertValue(false)
}
@Test
fun getMedia() {
val (mockResponse, media: Media) = expectGetEntitiesAndMediaConversion()
`when`(mediaInterface!!.getMedia(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mockResponse))
mediaClient!!.getMedia("abcde").test().assertValue(media)
fun `checkFileExistsUsingSha returns true with Images`() {
val mwQueryResponse = mockQuery {
whenever(allImages()).thenReturn(listOf(mock()))
}
whenever(mediaInterface.checkFileExistsUsingSha(""))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.checkFileExistsUsingSha("").test().assertValue(true)
}
@Test
fun getMediaNull() {
val imageInfo = ImageInfo()
fun `getMediaListFromCategory is continuable and returns mapped response`() {
val (mwQueryResponse, media) = expectSuccessfulMapping(continuationMap)
whenever(mediaInterface.getMediaListFromCategory("", 10, emptyMap()))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.getMediaListFromCategory("").test().assertValues(listOf(media))
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.title()).thenReturn("Test")
`when`(mwQueryPage.imageInfo()).thenReturn(imageInfo)
whenever(mediaInterface.getMediaListFromCategory("", 10, continuationMap))
.thenReturn(Single.error(Exception()))
mediaClient.getMediaListFromCategory("").test().assertError { true }
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(null)
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.getMedia(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mockResponse))
mediaClient!!.getMedia("abcde").test().assertErrorMessage("List is empty.")
mediaClient.resetCategoryContinuation("")
val (resetMwQueryResponse, resetMedia)=expectSuccessfulMapping()
whenever(mediaInterface.getMediaListFromCategory("", 10, emptyMap()))
.thenReturn(Single.just(resetMwQueryResponse))
mediaClient.getMediaListFromCategory("").test().assertValues(listOf(resetMedia))
}
@Test
fun getPictureOfTheDay() {
val template = "Template:Potd/" + CommonsDateUtil.getIso8601DateFormatShort().format(Date())
val (mockResponse, media: Media) = expectGetEntitiesAndMediaConversion()
`when`(mediaInterface!!.getMediaWithGenerator(template))
.thenReturn(Single.just(mockResponse))
mediaClient!!.getPictureOfTheDay().test().assertValue(media)
fun `getMediaListForUser is continuable and returns mapped response`() {
val (mwQueryResponse, media) = expectSuccessfulMapping(null)
whenever(mediaInterface.getMediaListForUser("", 10, emptyMap()))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.getMediaListForUser("").test().assertValues(listOf(media))
mediaClient.getMediaListForUser("").test().assertValue(emptyList())
}
private fun expectGetEntitiesAndMediaConversion(): Pair<MwQueryResponse, Media> {
val mockResponse = mock(MwQueryResponse::class.java)
val queryResult: MwQueryResult = mock()
whenever(mockResponse.query()).thenReturn(queryResult)
val queryPage: MwQueryPage = mock()
whenever(queryResult.pages()).thenReturn(listOf(queryPage))
whenever(queryPage.pageId()).thenReturn(0)
val entities: Entities = mock()
whenever(mediaDetailInterface!!.getEntity("M0")).thenReturn(Single.just(entities))
val entity: Entities.Entity = mock()
whenever(entities.entities()).thenReturn(mapOf("id" to entity))
val media: Media = mock()
@Test
fun `getMediaListFromSearch returns mapped response`() {
val (mwQueryResponse, media) = expectSuccessfulMapping()
whenever(mediaInterface.getMediaListFromSearch("", 0, 1))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.getMediaListFromSearch("", 0, 1)
.test()
.assertValues(listOf(media))
}
@Test
fun `fetchImagesForDepictedItem returns mapped response`() {
val (mwQueryResponse, media) = expectSuccessfulMapping()
whenever(mediaInterface.fetchImagesForDepictedItem("haswbstatement:P180=", "0", "1"))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.fetchImagesForDepictedItem("", 0, 1)
.test()
.assertValues(listOf(media))
}
@Test
fun `getMedia returns mapped response`() {
val (mwQueryResponse, media) = expectSuccessfulMapping()
whenever(mediaInterface.getMedia("")).thenReturn(Single.just(mwQueryResponse))
mediaClient.getMedia("").test().assertValues(media)
}
@Test
fun `getPictureOfTheDay returns mapped response`() {
val (mwQueryResponse, media) = expectSuccessfulMapping()
whenever(mediaInterface.getMediaWithGenerator(ArgumentMatchers.startsWith("Template:Potd/")))
.thenReturn(Single.just(mwQueryResponse))
mediaClient.getPictureOfTheDay().test().assertValues(media)
}
@Test
fun `getPageHtml with null parse result returns empty`() {
val mwParseResponse = mock<MwParseResponse>()
whenever(mediaInterface.getPageHtml("")).thenReturn(Single.just(mwParseResponse))
whenever(mwParseResponse.parse()).thenReturn(null)
mediaClient.getPageHtml("").test().assertValues("")
}
@Test
fun `getPageHtml with parse result returns text`() {
val mwParseResponse = mock<MwParseResponse>()
whenever(mediaInterface.getPageHtml("")).thenReturn(Single.just(mwParseResponse))
val mwParseResult = mock<MwParseResult>()
whenever(mwParseResponse.parse()).thenReturn(mwParseResult)
whenever(mwParseResult.text()).thenReturn("text")
mediaClient.getPageHtml("").test().assertValues("text")
}
@Test
fun `getEntities throws exception for empty ids`() {
mediaClient.getEntities(emptyList()).test().assertErrorMessage("empty list passed for ids")
}
@Test
fun `getEntities invokes interface with non empty ids`() {
val entities = mock<Entities>()
whenever(mediaDetailInterface.getEntity("1|2")).thenReturn(Single.just(entities))
mediaClient.getEntities(listOf("1","2")).test().assertValue(entities)
}
@Test
fun `doesPageContainMedia returns false for empty items`() {
val pageMediaListResponse = mock<PageMediaListResponse>()
whenever(pageMediaInterface.getMediaList(""))
.thenReturn(Single.just(pageMediaListResponse))
whenever(pageMediaListResponse.items).thenReturn(emptyList())
mediaClient.doesPageContainMedia("").test().assertValue(false)
}
@Test
fun `doesPageContainMedia returns true for non empty items`() {
val pageMediaListResponse = mock<PageMediaListResponse>()
whenever(pageMediaInterface.getMediaList(""))
.thenReturn(Single.just(pageMediaListResponse))
whenever(pageMediaListResponse.items).thenReturn(listOf(mock()))
mediaClient.doesPageContainMedia("").test().assertValue(true)
}
private fun mockQuery(queryReceiver: MwQueryResult.() -> Unit): MwQueryResponse {
val mwQueryResponse = mock<MwQueryResponse>()
val mwQueryResult = mock<MwQueryResult>()
whenever(mwQueryResponse.query()).thenReturn(mwQueryResult)
mwQueryResult.queryReceiver()
return mwQueryResponse
}
private fun expectResponseWithPageId(expectedId: Int): MwQueryResponse {
return mockQuery {
val mwQueryPage = mock<MwQueryPage>()
whenever(firstPage()).thenReturn(mwQueryPage)
whenever(mwQueryPage.pageId()).thenReturn(expectedId)
}
}
private fun expectSuccessfulMapping(continuationMap: Map<String, String>? = emptyMap()): Pair<MwQueryResponse, Media> {
val media = media()
val mwQueryPage = mock<MwQueryPage>()
val mwQueryResponse = mockQuery {
whenever(pages()).thenReturn(listOf(mwQueryPage, mwQueryPage))
whenever(mwQueryPage.pageId()).thenReturn(1, 2)
}
whenever(mwQueryResponse.continuation()).thenReturn(continuationMap)
val entities = mock<Entities>()
whenever(mediaDetailInterface.getEntity("M1|M2")).thenReturn(Single.just(entities))
val entity = mock<Entities.Entity>()
whenever(entities.entities()).thenReturn(mapOf("a" to entity, "b" to entity))
val imageInfo = mock<ImageInfo>()
whenever(queryPage.imageInfo()).thenReturn(imageInfo)
whenever(mediaConverter!!.convert(queryPage, entity, imageInfo)).thenReturn(media)
return Pair(mockResponse, media)
}
@Captor
private val continuationCaptor: ArgumentCaptor<Map<String, String>>? = null
@Test
fun getMediaListFromCategoryTwice() {
val mockContinuation = mapOf(Pair("gcmcontinue", "test"))
val (mockResponse, media: Media) = expectGetEntitiesAndMediaConversion()
`when`(mockResponse.continuation()).thenReturn(mockContinuation)
`when`(
mediaInterface!!.getMediaListFromCategory(
ArgumentMatchers.anyString(), ArgumentMatchers.anyInt(),
continuationCaptor!!.capture()
)
)
.thenReturn(Single.just(mockResponse))
val media1 = mediaClient!!.getMediaListFromCategory("abcde").blockingGet().get(0)
val media2 = mediaClient!!.getMediaListFromCategory("abcde").blockingGet().get(0)
assertEquals(continuationCaptor.allValues[0], emptyMap<String, String>())
assertEquals(continuationCaptor.allValues[1], mockContinuation)
assertEquals(media1, media)
assertEquals(media2, media)
}
@Test
fun getMediaListForUser() {
val mockContinuation = mapOf("gcmcontinue" to "test")
val (mockResponse, media: Media) = expectGetEntitiesAndMediaConversion()
whenever(mockResponse.continuation()).thenReturn(mockContinuation)
whenever(
mediaInterface!!.getMediaListForUser(
ArgumentMatchers.anyString(), ArgumentMatchers.anyInt(),
continuationCaptor!!.capture()
)
)
.thenReturn(Single.just(mockResponse))
val media1 = mediaClient!!.getMediaListForUser("Test").blockingGet().get(0)
val media2 = mediaClient!!.getMediaListForUser("Test").blockingGet().get(0)
verify(mediaInterface, times(2))?.getMediaListForUser(
ArgumentMatchers.anyString(),
ArgumentMatchers.anyInt(), ArgumentMatchers.anyMap<String, String>()
)
}
@Test
fun getPageHtmlTest() {
val mwParseResult = mock(MwParseResult::class.java)
`when`(mwParseResult.text()).thenReturn("Test")
val mockResponse = MwParseResponse()
mockResponse.setParse(mwParseResult)
`when`(mediaInterface!!.getPageHtml(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mockResponse))
assertEquals("Test", mediaClient!!.getPageHtml("abcde").blockingGet())
}
@Test
fun doesPageContainMedia() {
val mock = mock(PageMediaListResponse::class.java)
whenever(mock.items).thenReturn(listOf<PageMediaListItem>(mock(PageMediaListItem::class.java)))
`when`(pageMediaInterface!!.getMediaList(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mock))
mediaClient!!.doesPageContainMedia("Test").test().assertValue(true)
}
@Test
fun doesPageContainMediaWithNoMedia() {
val mock = mock(PageMediaListResponse::class.java)
whenever(mock.items).thenReturn(listOf<PageMediaListItem>())
`when`(pageMediaInterface!!.getMediaList(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mock))
mediaClient!!.doesPageContainMedia("Test").test().assertValue(false)
}
@Test
fun getPageHtmlTestNull() {
val mockResponse = MwParseResponse()
mockResponse.setParse(null)
`when`(mediaInterface!!.getPageHtml(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mockResponse))
assertEquals("", mediaClient!!.getPageHtml("abcde").blockingGet())
whenever(mwQueryPage.imageInfo()).thenReturn(imageInfo, null)
whenever(mediaConverter.convert(mwQueryPage, entity, imageInfo)).thenReturn(media)
return Pair(mwQueryResponse, media)
}
}