Use wrapper for interacting with shared preferences (#2288)

* Use wrapper for accessing shared preferences across the app

* Use Json kv store for storing place object

* Fix tests

* Fix test failure

* Fix UI tests
This commit is contained in:
Vivek Maskara 2019-01-14 00:13:21 +05:30 committed by Ashish Kumar
parent 1b7b909107
commit d4fa9cfa45
61 changed files with 908 additions and 585 deletions

View file

@ -2,7 +2,6 @@ package fr.free.nrw.commons
import android.content.ContentProviderClient
import android.content.Context
import android.content.SharedPreferences
import android.support.v4.util.LruCache
import com.google.gson.Gson
import com.nhaarman.mockito_kotlin.mock
@ -13,6 +12,8 @@ import fr.free.nrw.commons.data.DBOpenHelper
import fr.free.nrw.commons.di.CommonsApplicationComponent
import fr.free.nrw.commons.di.CommonsApplicationModule
import fr.free.nrw.commons.di.DaggerCommonsApplicationComponent
import fr.free.nrw.commons.kvstore.BasicKvStore
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.location.LocationServiceManager
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.nearby.NearbyPlaces
@ -37,9 +38,9 @@ class TestCommonsApplication : CommonsApplication() {
@Suppress("MemberVisibilityCanBePrivate")
class MockCommonsApplicationModule(appContext: Context) : CommonsApplicationModule(appContext) {
val accountUtil: AccountUtil = mock()
val appSharedPreferences: SharedPreferences = mock()
val defaultSharedPreferences: SharedPreferences = mock()
val otherSharedPreferences: SharedPreferences = mock()
val appSharedPreferences: BasicKvStore = mock()
val defaultSharedPreferences: BasicKvStore = mock()
val otherSharedPreferences: BasicKvStore = mock()
val uploadController: UploadController = mock()
val mockSessionManager: SessionManager = mock()
val locationServiceManager: LocationServiceManager = mock()
@ -50,7 +51,7 @@ class MockCommonsApplicationModule(appContext: Context) : CommonsApplicationModu
val categoryClient: ContentProviderClient = mock()
val contributionClient: ContentProviderClient = mock()
val modificationClient: ContentProviderClient = mock()
val uploadPrefs: SharedPreferences = mock()
val uploadPrefs: JsonKvStore = mock()
override fun provideCategoryContentProviderClient(context: Context?): ContentProviderClient = categoryClient
@ -58,19 +59,19 @@ class MockCommonsApplicationModule(appContext: Context) : CommonsApplicationModu
override fun provideModificationContentProviderClient(context: Context?): ContentProviderClient = modificationClient
override fun providesDirectNearbyUploadPreferences(context: Context?): SharedPreferences = uploadPrefs
override fun providesDirectNearbyUploadKvStore(context: Context?): JsonKvStore = uploadPrefs
override fun providesAccountUtil(context: Context): AccountUtil = accountUtil
override fun providesApplicationSharedPreferences(context: Context): SharedPreferences = appSharedPreferences
override fun providesApplicationKvStore(context: Context): BasicKvStore = appSharedPreferences
override fun providesDefaultSharedPreferences(context: Context): SharedPreferences = defaultSharedPreferences
override fun providesDefaultKvStore(context: Context): BasicKvStore = defaultSharedPreferences
override fun providesOtherSharedPreferences(context: Context): SharedPreferences = otherSharedPreferences
override fun providesOtherKvStore(context: Context): BasicKvStore = otherSharedPreferences
override fun providesUploadController(sessionManager: SessionManager, sharedPreferences: SharedPreferences, context: Context): UploadController = uploadController
override fun providesUploadController(sessionManager: SessionManager, sharedPreferences: BasicKvStore, context: Context): UploadController = uploadController
override fun providesSessionManager(context: Context, mediaWikiApi: MediaWikiApi, sharedPreferences: SharedPreferences): SessionManager = mockSessionManager
override fun providesSessionManager(context: Context, mediaWikiApi: MediaWikiApi, sharedPreferences: BasicKvStore): SessionManager = mockSessionManager
override fun provideLocationServiceManager(context: Context): LocationServiceManager = locationServiceManager

View file

@ -13,6 +13,7 @@ import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsContentProvider.BASE_URI
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.*
import fr.free.nrw.commons.location.LatLng
import fr.free.nrw.commons.nearby.Label
import fr.free.nrw.commons.nearby.Place
import fr.free.nrw.commons.nearby.Sitelinks
import junit.framework.Assert.*
@ -42,14 +43,14 @@ class BookMarkLocationDaoTest {
private lateinit var testObject: BookmarkLocationsDao
private lateinit var examplePlaceBookmark: Place
private lateinit var exampleLabel: Place.Label
private lateinit var exampleLabel: Label
private lateinit var exampleUri: Uri
private lateinit var exampleLocation: LatLng
private lateinit var builder: Sitelinks.Builder
@Before
fun setUp() {
exampleLabel = Place.Label.FOREST
exampleLabel = Label.FOREST
exampleUri = Uri.parse("wikimedia/uri")
exampleLocation = LatLng(40.0,51.4, 1f)
@ -85,7 +86,7 @@ class BookMarkLocationDaoTest {
cursor.moveToFirst()
testObject.fromCursor(cursor).let {
assertEquals("placeName", it.name)
assertEquals(Place.Label.FOREST, it.label)
assertEquals(Label.FOREST, it.label)
assertEquals("placeDescription", it.longDescription)
assertEquals(exampleUri, it.secondaryImageUrl)
assertEquals(40.0, it.location.latitude)

View file

@ -1,12 +1,10 @@
package fr.free.nrw.commons.mwapi
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import android.preference.PreferenceManager
import com.google.gson.Gson
import fr.free.nrw.commons.BuildConfig
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.kvstore.BasicKvStore
import okhttp3.OkHttpClient
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
@ -20,8 +18,6 @@ import org.mockito.Mockito.mock
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import timber.log.Timber
import java.io.InputStream
import java.net.URLDecoder
import java.text.SimpleDateFormat
import java.util.*
@ -33,8 +29,8 @@ class ApacheHttpClientMediaWikiApiTest {
private lateinit var testObject: ApacheHttpClientMediaWikiApi
private lateinit var server: MockWebServer
private lateinit var wikidataServer: MockWebServer
private lateinit var sharedPreferences: SharedPreferences
private lateinit var categoryPreferences: SharedPreferences
private lateinit var sharedPreferences: BasicKvStore
private lateinit var categoryPreferences: BasicKvStore
private lateinit var okHttpClient: OkHttpClient
@Before
@ -42,8 +38,8 @@ class ApacheHttpClientMediaWikiApiTest {
server = MockWebServer()
wikidataServer = MockWebServer()
okHttpClient = OkHttpClient()
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application)
categoryPreferences = PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application)
sharedPreferences = mock(BasicKvStore::class.java)
categoryPreferences = mock(BasicKvStore::class.java)
testObject = ApacheHttpClientMediaWikiApi(RuntimeEnvironment.application, "http://" + server.hostName + ":" + server.port + "/", "http://" + wikidataServer.hostName + ":" + wikidataServer.port + "/", sharedPreferences, categoryPreferences, Gson(), okHttpClient)
testObject.setWikiMediaToolforgeUrl("http://" + server.hostName + ":" + server.port + "/")
}

View file

@ -6,6 +6,7 @@ import android.content.SharedPreferences
import fr.free.nrw.commons.HandlerService
import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.contributions.Contribution
import fr.free.nrw.commons.kvstore.BasicKvStore
import org.junit.Before
import org.junit.Test
import org.mockito.InjectMocks
@ -21,7 +22,7 @@ class UploadControllerTest {
@Mock
internal var context: Context? = null
@Mock
internal var prefs: SharedPreferences? = null
internal var prefs: BasicKvStore? = null
@InjectMocks
var uploadController: UploadController? = null

View file

@ -7,7 +7,10 @@ import android.content.SharedPreferences
import android.graphics.BitmapRegionDecoder
import android.net.Uri
import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.kvstore.BasicKvStore
import fr.free.nrw.commons.location.LatLng
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.nearby.Place
import fr.free.nrw.commons.utils.BitmapRegionDecoderWrapper
import fr.free.nrw.commons.utils.ImageUtils.IMAGE_OK
import fr.free.nrw.commons.utils.ImageUtilsWrapper
@ -35,7 +38,7 @@ class UploadModelTest {
internal var licenses: List<String>? = null
@Mock
@field:[Inject Named("default_preferences")]
internal var prefs: SharedPreferences? = null
internal var prefs: BasicKvStore? = null
@Mock
@field:[Inject Named("licenses_by_name")]
internal var licensesByName: Map<String, String>? = null
@ -76,7 +79,7 @@ class UploadModelTest {
.thenReturn("")
`when`(imageUtilsWrapper!!.checkIfImageIsTooDark(any(BitmapRegionDecoder::class.java)))
.thenReturn(IMAGE_OK)
`when`(imageUtilsWrapper!!.checkImageGeolocationIsDifferent(anyString(), anyString()))
`when`(imageUtilsWrapper!!.checkImageGeolocationIsDifferent(anyString(), any(LatLng::class.java)))
.thenReturn(false)
`when`(bitmapRegionDecoderWrapper!!.newInstance(any(FileInputStream::class.java), anyBoolean()))
.thenReturn(mock(BitmapRegionDecoder::class.java))
@ -100,24 +103,21 @@ class UploadModelTest {
@Test
fun receiveDirect() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertTrue(uploadModel!!.items.size == 1)
}
@Test
fun verifyPreviousNotAvailableForDirectUpload() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertFalse(uploadModel!!.isPreviousAvailable)
}
@Test
fun verifyNextAvailableForDirectUpload() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertTrue(uploadModel!!.isNextAvailable)
}
@ -151,16 +151,14 @@ class UploadModelTest {
@Test
fun isSubmitAvailableForDirectUpload() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertTrue(uploadModel!!.isNextAvailable)
}
@Test
fun getCurrentStepForDirectUpload() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertTrue(uploadModel!!.currentStep == 1)
}
@ -185,16 +183,14 @@ class UploadModelTest {
@Test
fun getStepCountForDirectUpload() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertTrue(uploadModel!!.stepCount == 3)
}
@Test
fun getDirectCount() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertTrue(uploadModel!!.count == 1)
}
@ -219,8 +215,7 @@ class UploadModelTest {
@Test
fun getDirectUploads() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertTrue(uploadModel!!.uploads.size == 1)
}
@ -236,8 +231,7 @@ class UploadModelTest {
@Test
fun isTopCardStateForDirectUpload() {
val element = mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", mock(Place::class.java)) { _, _ -> }
assertTrue(uploadModel!!.isTopCardState)
}

View file

@ -2,6 +2,7 @@ package fr.free.nrw.commons.upload
import android.net.Uri
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.nearby.Place
import org.junit.Before
import org.junit.Test
import org.mockito.InjectMocks
@ -44,7 +45,6 @@ class UploadPresenterTest {
@Test
fun receiveDirect() {
val element = Mockito.mock(Uri::class.java)
uploadModel!!.receiveDirect(element, "image/jpeg", "external", "Q1", "Test", "Test", { _, _ -> }
, "")
uploadModel!!.receiveDirect(element, "image/jpeg", "external", Mockito.mock(Place::class.java)) { _, _ -> }
}
}