Update master with backend overhaul branch (#2829)

* Beginnings of integration with Wikipedia client library. (#2642)

* Remove remaining unnecessary API version check.

* Roll up sleeves.

* Add and integrate the beginnings of app adapter.

* Remove vestigial event logging logic.

Event logging is no longer used in this app.

* Beginnings: remove StringUtils and associated redundancies.

* Remove redundant capitalize() method.

* Remove redundant urlEncode() method.

* Remove redundant (and incomplete) language lists.

* Remove redundant usages of SimpleDateFormat.

* Remove redundant json type adapter.

* Remove redundant MW error model classes.

* Rip out redundant MW model classes.

* Pass SessionManager into AppAdapter instead of injecting.

* Wire up more of the AppAdapter.

* Remove redundant Gson initialization and type adapters.

* Rip out PageTitle.

This was being used in some slightly incorrect/unexpected ways.

* Don't need static WikiSite.

* Bump data client library version

* Bump library version and fix build

* Fix tests

* Fix build

* Fix media of the day

* With fixes in recently modified APIs
This commit is contained in:
Vivek Maskara 2019-04-02 08:35:22 +05:30 committed by GitHub
parent 76e5a30fb5
commit dcbf076965
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 424 additions and 2122 deletions

View file

@ -1,96 +0,0 @@
package fr.free.nrw.commons
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import java.net.URLEncoder
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class)
class PageTitleTest {
@Test
fun displayTextShouldNotBeUnderscored() {
assertEquals("Ex 1", PageTitle("Ex_1").displayText)
assertEquals("Ex 1", PageTitle("Ex_1 ").displayText)
assertEquals("Ex 1", PageTitle("Ex 1").displayText)
assertEquals("Ex 1", PageTitle("Ex 1 ").displayText)
assertEquals("File:Ex 1 2", PageTitle("File:Ex_1_2 ").displayText)
}
@Test
fun prefixedTextShouldBeUnderscored() {
assertEquals("Ex_1", PageTitle("Ex_1").prefixedText)
assertEquals("Ex_1", PageTitle("Ex_1 ").prefixedText)
assertEquals("Ex_1", PageTitle("Ex 1").prefixedText)
assertEquals("Ex_1", PageTitle("Ex 1 ").prefixedText)
assertEquals("File:Ex_1_2", PageTitle("File:Ex 1 2 ").prefixedText)
}
@Test
fun fileNameWithOneColon() {
val pageTitle = PageTitle("File:sample:a.jpg")
assertEquals("File:Sample:a.jpg", pageTitle.prefixedText)
assertEquals("File:Sample:a.jpg", pageTitle.displayText)
assertEquals("Sample:a.jpg", pageTitle.text)
}
@Test
fun fileNameWithMoreThanOneColon() {
var pageTitle = PageTitle("File:sample:a:b.jpg")
assertEquals("File:Sample:a:b.jpg", pageTitle.prefixedText)
assertEquals("File:Sample:a:b.jpg", pageTitle.displayText)
assertEquals("Sample:a:b.jpg", pageTitle.text)
pageTitle = PageTitle("File:sample:a:b:c.jpg")
assertEquals("File:Sample:a:b:c.jpg", pageTitle.prefixedText)
assertEquals("File:Sample:a:b:c.jpg", pageTitle.displayText)
assertEquals("Sample:a:b:c.jpg", pageTitle.text)
}
@Test
fun keyShouldNotIncludeNamespace() {
val pageTitle = PageTitle("File:Sample.jpg")
assertEquals("Sample.jpg", pageTitle.text)
}
@Test
fun capitalizeNamespace() {
val pageTitle = PageTitle("file:Sample.jpg")
assertEquals("File:Sample.jpg", pageTitle.prefixedText)
assertEquals("File:Sample.jpg", pageTitle.displayText)
}
@Test
fun capitalizeKey() {
val pageTitle = PageTitle("File:sample.jpg")
assertEquals("File:Sample.jpg", pageTitle.prefixedText)
assertEquals("File:Sample.jpg", pageTitle.displayText)
assertEquals("Sample.jpg", pageTitle.text)
}
@Test
fun getMobileUriForTest() {
val pageTitle = PageTitle("Test")
assertEquals(BuildConfig.MOBILE_HOME_URL + "Test", pageTitle.mobileUri.toString())
}
@Test
fun spaceBecomesUnderscoreInUri() {
val pageTitle = PageTitle("File:Ex 1.jpg")
assertEquals(BuildConfig.HOME_URL + "File:Ex_1.jpg", pageTitle.canonicalUri.toString())
}
@Test
fun leaveSubpageNamesUncapitalizedInUri() {
val pageTitle = PageTitle("User:Ex/subpage")
assertEquals(BuildConfig.HOME_URL + "User:Ex/subpage", pageTitle.canonicalUri.toString())
}
@Test
fun unicodeUri() {
val pageTitle = PageTitle("User:例")
assertEquals(BuildConfig.HOME_URL + "User:" + URLEncoder.encode("", "utf-8"), pageTitle.canonicalUri.toString())
}
}

View file

@ -19,8 +19,8 @@ import org.mockito.Mockito.mock
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import org.wikipedia.util.DateUtil
import java.net.URLDecoder
import java.text.SimpleDateFormat
import java.util.*
@RunWith(RobolectricTestRunner::class)
@ -262,9 +262,7 @@ class ApacheHttpClientMediaWikiApiTest {
fun isUserBlockedFromCommonsForTimeBlockedUser() {
val currentDate = Date()
val expiredDate = Date(currentDate.time + 10000)
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"1000\" name=\"testusername\" blockid=\"3000\" blockedby=\"blockerusername\" blockedbyid=\"1001\" blockreason=\"testing\" blockedtimestamp=\"2018-05-24T15:32:09Z\" blockexpiry=\"" + dateFormat.format(expiredDate) + "\"></userinfo></query></api>"))
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"1000\" name=\"testusername\" blockid=\"3000\" blockedby=\"blockerusername\" blockedbyid=\"1001\" blockreason=\"testing\" blockedtimestamp=\"2018-05-24T15:32:09Z\" blockexpiry=\"" + DateUtil.getIso8601DateFormat().format(expiredDate) + "\"></userinfo></query></api>"))
val result = testObject.isUserBlockedFromCommons()
@ -284,9 +282,7 @@ class ApacheHttpClientMediaWikiApiTest {
fun isUserBlockedFromCommonsForExpiredBlockedUser() {
val currentDate = Date()
val expiredDate = Date(currentDate.time - 10000)
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"1000\" name=\"testusername\" blockid=\"3000\" blockedby=\"blockerusername\" blockedbyid=\"1001\" blockreason=\"testing\" blockedtimestamp=\"2018-05-24T15:32:09Z\" blockexpiry=\"" + dateFormat.format(expiredDate) + "\"></userinfo></query></api>"))
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"1000\" name=\"testusername\" blockid=\"3000\" blockedby=\"blockerusername\" blockedbyid=\"1001\" blockreason=\"testing\" blockedtimestamp=\"2018-05-24T15:32:09Z\" blockexpiry=\"" + DateUtil.getIso8601DateFormat().format(expiredDate) + "\"></userinfo></query></api>"))
val result = testObject.isUserBlockedFromCommons()

View file

@ -1,178 +0,0 @@
package fr.free.nrw.commons.mwapi
import com.google.gson.Gson
import fr.free.nrw.commons.mwapi.model.Page
import fr.free.nrw.commons.mwapi.model.PageCategory
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
class CategoryApiTest {
private lateinit var server: MockWebServer
private lateinit var url: String
private lateinit var categoryApi: CategoryApi
@Before
fun setUp() {
server = MockWebServer()
url = "http://${server.hostName}:${server.port}/"
categoryApi = CategoryApi(OkHttpClient.Builder().build(), Gson(), HttpUrl.parse(url))
}
@After
fun teardown() {
server.shutdown()
}
@Test
fun apiReturnsEmptyListWhenError() {
server.enqueue(MockResponse().setResponseCode(400).setBody(""))
assertTrue(categoryApi.request("foo").blockingGet().isEmpty())
}
@Test
fun apiReturnsEmptyWhenTheresNoQuery() {
server.success(emptyMap())
assertTrue(categoryApi.request("foo").blockingGet().isEmpty())
}
@Test
fun apiReturnsEmptyWhenQueryHasNoPages() {
server.success(mapOf("query" to emptyMap<String, Any>()))
assertTrue(categoryApi.request("foo").blockingGet().isEmpty())
}
@Test
fun apiReturnsEmptyWhenQueryHasPagesButTheyreEmpty() {
server.success(mapOf("query" to
mapOf("pages" to emptyList<String>())))
assertTrue(categoryApi.request("foo").blockingGet().isEmpty())
}
@Test
fun singlePageSingleCategory() {
server.success(mapOf("query" to
mapOf("pages" to listOf(
page(listOf("one"))
))))
val response = categoryApi.request("foo").blockingGet()
assertEquals(1, response.size)
assertEquals("one", response[0])
}
@Test
fun multiplePagesSingleCategory() {
server.success(mapOf("query" to
mapOf("pages" to listOf(
page(listOf("one")),
page(listOf("two"))
))))
val response = categoryApi.request("foo").blockingGet()
assertEquals(2, response.size)
assertEquals("one", response[0])
assertEquals("two", response[1])
}
@Test
fun singlePageMultipleCategories() {
server.success(mapOf("query" to
mapOf("pages" to listOf(
page(listOf("one", "two"))
))))
val response = categoryApi.request("foo").blockingGet()
assertEquals(2, response.size)
assertEquals("one", response[0])
assertEquals("two", response[1])
}
@Test
fun multiplePagesMultipleCategories() {
server.success(mapOf("query" to
mapOf("pages" to listOf(
page(listOf("one", "two")),
page(listOf("three", "four"))
))))
val response = categoryApi.request("foo").blockingGet()
assertEquals(4, response.size)
assertEquals("one", response[0])
assertEquals("two", response[1])
assertEquals("three", response[2])
assertEquals("four", response[3])
}
@Test
fun multiplePagesMultipleCategories_duplicatesRemoved() {
server.success(mapOf("query" to
mapOf("pages" to listOf(
page(listOf("one", "two", "three")),
page(listOf("three", "four", "one"))
))))
val response = categoryApi.request("foo").blockingGet()
assertEquals(4, response.size)
assertEquals("one", response[0])
assertEquals("two", response[1])
assertEquals("three", response[2])
assertEquals("four", response[3])
}
@Test
fun requestSendsWhatWeExpect() {
server.success(mapOf("query" to mapOf("pages" to emptyList<String>())))
val coords = "foo,bar"
categoryApi.request(coords).blockingGet()
server.takeRequest().let { request ->
assertEquals("GET", request.method)
assertEquals("/w/api.php", request.requestUrl.encodedPath())
request.requestUrl.let { url ->
assertEquals("query", url.queryParameter("action"))
assertEquals("categories|coordinates|pageprops", url.queryParameter("prop"))
assertEquals("json", url.queryParameter("format"))
assertEquals("!hidden", url.queryParameter("clshow"))
assertEquals("type|name|dim|country|region|globe", url.queryParameter("coprop"))
assertEquals(coords, url.queryParameter("codistancefrompoint"))
assertEquals("geosearch", url.queryParameter("generator"))
assertEquals(coords, url.queryParameter("ggscoord"))
assertEquals("10000", url.queryParameter("ggsradius"))
assertEquals("10", url.queryParameter("ggslimit"))
assertEquals("6", url.queryParameter("ggsnamespace"))
assertEquals("type|name|dim|country|region|globe", url.queryParameter("ggsprop"))
assertEquals("all", url.queryParameter("ggsprimary"))
assertEquals("2", url.queryParameter("formatversion"))
}
}
}
private fun page(catList: List<String>) = Page().apply {
categories = catList.map {
PageCategory().apply {
title = "Category:$it"
}
}.toTypedArray()
}
}
fun MockWebServer.success(response: Map<String, Any>) {
enqueue(MockResponse().setResponseCode(200).setBody(Gson().toJson(response)))
}

View file

@ -6,7 +6,6 @@ import fr.free.nrw.commons.Media
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient.mapType
import fr.free.nrw.commons.utils.DateUtils
import junit.framework.Assert.assertEquals
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
@ -22,6 +21,8 @@ import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.wikipedia.util.DateUtil
import java.util.*
import kotlin.random.Random
/**
@ -189,7 +190,7 @@ class OkHttpJsonApiClientTest {
*/
@Test
fun getImageWithGenerator() {
val template = "Template:Potd/" + DateUtils.getCurrentDate()
val template = "Template:Potd/" + DateUtil.getIso8601DateFormatShort().format(Date())
server.enqueue(getMediaList("", "", "", 1))
val media = testObject.getMedia(template, true)!!.blockingGet()
@ -215,7 +216,7 @@ class OkHttpJsonApiClientTest {
*/
@Test
fun getPictureOfTheDay() {
val template = "Template:Potd/" + DateUtils.getCurrentDate()
val template = "Template:Potd/" + DateUtil.getIso8601DateFormatShort().format(Date())
server.enqueue(getMediaList("", "", "", 1))
val media = testObject.pictureOfTheDay?.blockingGet()

View file

@ -1,28 +0,0 @@
package fr.free.nrw.commons.mwapi.model
import org.junit.Assert.*
import org.junit.Test
class ApiResponseTest {
@Test
fun hasPages_whenQueryIsNull() {
val response = ApiResponse()
assertFalse(response.hasPages())
}
@Test
fun hasPages_whenPagesIsNull() {
val response = ApiResponse()
response.query = Query()
response.query.pages = null
assertFalse(response.hasPages())
}
@Test
fun hasPages_defaultsToSafeValue() {
val response = ApiResponse()
response.query = Query()
assertNotNull(response.query.pages)
assertTrue(response.hasPages())
}
}

View file

@ -1,20 +0,0 @@
package fr.free.nrw.commons.mwapi.model
import org.junit.Assert.assertEquals
import org.junit.Test
class PageCategoryTest {
@Test
fun stripPrefix_whenPresent() {
val testObject = PageCategory()
testObject.title = "Category:Foo"
assertEquals("Foo", testObject.withoutPrefix())
}
@Test
fun stripPrefix_prefixAbsent() {
val testObject = PageCategory()
testObject.title = "Foo_Bar"
assertEquals("Foo_Bar", testObject.withoutPrefix())
}
}

View file

@ -1,12 +0,0 @@
package fr.free.nrw.commons.mwapi.model
import org.junit.Assert.assertNotNull
import org.junit.Test
class PageTest {
@Test
fun categoriesDefaultToSafeValue() {
val page = Page()
assertNotNull(page.getCategories())
}
}

View file

@ -1,10 +1,8 @@
package fr.free.nrw.commons.review
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.media.model.MwQueryPage
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
import fr.free.nrw.commons.mwapi.model.RecentChange
import io.reactivex.Single
import junit.framework.Assert.assertTrue
import org.junit.Before
@ -15,6 +13,8 @@ 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.RecentChange
/**
* Test class for ReviewHelper
@ -43,10 +43,11 @@ class ReviewHelperTest {
*/
@Test
fun getRandomMedia() {
val recentChange = getMockRecentChange("test", "File:Test1.jpeg", 0)
val recentChange1 = getMockRecentChange("test", "File:Test2.png", 0)
val recentChange2 = getMockRecentChange("test", "File:Test3.jpg", 0)
`when`(okHttpJsonApiClient?.recentFileChanges)
.thenReturn(Single.just(listOf(RecentChange("test", "File:Test1.jpeg", "0"),
RecentChange("test", "File:Test2.png", "0"),
RecentChange("test", "File:Test3.jpg", "0"))))
.thenReturn(Single.just(listOf(recentChange, recentChange1, recentChange2)))
`when`(mediaWikiApi?.pageExists(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
@ -55,6 +56,14 @@ class ReviewHelperTest {
assertTrue(randomMedia is Media)
}
fun getMockRecentChange(type: String, title: String, oldRevisionId: Long): RecentChange {
val recentChange = mock(RecentChange::class.java)
`when`(recentChange!!.type).thenReturn(type)
`when`(recentChange.title).thenReturn(title)
`when`(recentChange.oldRevisionId).thenReturn(oldRevisionId)
return recentChange
}
/**
* Test for getting first revision of file
*/

View file

@ -1,36 +0,0 @@
package fr.free.nrw.commons.utils
import fr.free.nrw.commons.Utils
import org.junit.Assert
import org.junit.Test
import org.hamcrest.CoreMatchers.`is` as _is
class UtilsTest {
@Test fun `strip nothing from non-localized string`() {
Assert.assertThat(Utils.stripLocalizedString("Hello"), _is("Hello"))
}
@Test fun `strip tag from Japanese string`() {
Assert.assertThat(Utils.stripLocalizedString("\"こんにちは\"@ja"), _is("こんにちは"))
}
@Test fun `capitalize first letter`() {
Assert.assertThat(Utils.capitalize("hello"), _is("Hello"))
}
@Test fun `capitalize - pass all-capital string as it is`() {
Assert.assertThat(Utils.capitalize("HELLO"), _is("HELLO"))
}
@Test fun `capitalize - pass numbers`() {
Assert.assertThat(Utils.capitalize("12x"), _is("12x"))
}
@Test fun `capitalize - pass Japanese characters`() {
Assert.assertThat(Utils.capitalize("こんにちは"), _is("こんにちは"))
}
@Test fun `capitalize does not fail on empty string`() {
Assert.assertThat(Utils.capitalize(""), _is(""))
}
}