[GSoC 2022] Improve custom picker (all features) (#5035)

* Project Initiated by creating helper classes for database operations

* Database created

* Rest of the work and documentation

* Requested changes done

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* [GSoC] Insert and Remove Images from not for upload (#4999)

* Inserted and marked images as not for upload

* Documentation added

* Test delete

* Implemented remove from not for upload

* Test fixed

* Requested changes done

* Added tests for new lines in existing classes

* [GSoC] Added Bubble Scroll (#5023)

* Library added

* Bubble scroll implemented

* Left and right swipe

* Requested changes

* [GSoC] Hide/Unhide actioned pictures and change numbering (#5012)

* Changed numbering of marked images

* Hide Unhide implemented

* Test fixed

* Improved speed for database operation

* Improved speed for database operation

* Changed progress dialog

* Improved hiding speed

* Test fixed

* Fixed bug

* Fixed bug and improved performance

* Fixed bug and improved performance

* Test fixed

* Bug fixed

* Bug fixed

* Bug fixed

* Bug fixed

* Bug fixed

* Code clean up

* Test hiding images

* Test hiding images

* Test hiding images

* Code clean up and test fixed

* Fixed layout

* Fixed bug

* Bug fixed

* Renamed method

* Documentation added explaining logic

* Documentation added explaining logic

* [GSoC] Full Screen Mode (#5032)

* Gesture detection implemented

* Left and right swipe

* Selection implemented

* onDown implemented

* onDown implemented

* FS mode implemented

* OnSwipe doc

* Scope cancel

* Added label in Manifest

* Merged two features

* Requested changes

* Image uploaded bug fixed

* Increased DB version

* Made requested changes

* Made requested changes

* Made requested changes

* Made requested changes

* Solved image flashing bug

* Solved image flashing bug

* Requested changes

* Requested changes

* Changed name of a function

* Fixed transaction failure on large number of images

* Tested with isIdentity

* Tested with isIdentity

* Increased the threshold

* Added info dialog

* Minor changes

* ImageAdapter Test

* CustomSelectorActivity Test

* Requested changes

* Test for ZoomableActivity

* Test for ZoomableActivity

* Test for ImageLoader

* Test for OnSwipeTouchListener

* Test for rest

* Reverted some test changes

* Added more tests for ImageAdapter

* Added more tests for ImageAdapter and swipe gesture

Co-authored-by: translatewiki.net <l10n-bot@translatewiki.net>
This commit is contained in:
Ayan Sarkar 2022-09-16 14:44:16 +05:30 committed by GitHub
parent b5ffe7120c
commit 33679eb6b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 2560 additions and 284 deletions

View file

@ -0,0 +1,144 @@
package fr.free.nrw.commons.customselector.helper
import android.content.Context
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.TestAppAdapter
import fr.free.nrw.commons.TestCommonsApplication
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.powermock.reflect.Whitebox
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import org.wikipedia.AppAdapter
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
internal class OnSwipeTouchListenerTest {
private lateinit var context: Context
private lateinit var onSwipeTouchListener: OnSwipeTouchListener
private lateinit var gesListener: OnSwipeTouchListener.GestureListener
@Mock
private lateinit var gestureDetector: GestureDetector
@Mock
private lateinit var view: View
@Mock
private lateinit var motionEvent1: MotionEvent
@Mock
private lateinit var motionEvent2: MotionEvent
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
AppAdapter.set(TestAppAdapter())
context = RuntimeEnvironment.application.applicationContext
onSwipeTouchListener = OnSwipeTouchListener(context)
gesListener = OnSwipeTouchListener(context).GestureListener()
Whitebox.setInternalState(onSwipeTouchListener, "gestureDetector", gestureDetector)
}
/**
* Test onTouch
*/
@Test
fun onTouch() {
val func = onSwipeTouchListener.javaClass.getDeclaredMethod("onTouch", View::class.java, MotionEvent::class.java)
func.isAccessible = true
func.invoke(onSwipeTouchListener, view, motionEvent1)
}
/**
* Test onSwipeRight
*/
@Test
fun onSwipeRight() {
onSwipeTouchListener.onSwipeRight()
}
/**
* Test onSwipeLeft
*/
@Test
fun onSwipeLeft() {
onSwipeTouchListener.onSwipeLeft()
}
/**
* Test onSwipeUp
*/
@Test
fun onSwipeUp() {
onSwipeTouchListener.onSwipeUp()
}
/**
* Test onSwipeDown
*/
@Test
fun onSwipeDown() {
onSwipeTouchListener.onSwipeDown()
}
/**
* Test onDown
*/
@Test
fun onDown() {
gesListener.onDown(motionEvent1)
}
/**
* Test onFling for onSwipeRight
*/
@Test
fun `Test onFling for onSwipeRight`() {
whenever(motionEvent1.x).thenReturn(1f)
whenever(motionEvent2.x).thenReturn(110f)
gesListener.onFling(motionEvent1, motionEvent2, 2000f, 0f)
}
/**
* Test onFling for onSwipeLeft
*/
@Test
fun `Test onFling for onSwipeLeft`() {
whenever(motionEvent1.x).thenReturn(110f)
whenever(motionEvent2.x).thenReturn(1f)
gesListener.onFling(motionEvent1, motionEvent2, 2000f, 0f)
}
/**
* Test onFling for onSwipeDown
*/
@Test
fun `Test onFling for onSwipeDown`() {
whenever(motionEvent1.y).thenReturn(1f)
whenever(motionEvent2.y).thenReturn(110f)
gesListener.onFling(motionEvent1, motionEvent2, 0f, 2000f)
}
/**
* Test onFling for onSwipeUp
*/
@Test
fun `Test onFling for onSwipeUp`() {
whenever(motionEvent1.y).thenReturn(110f)
whenever(motionEvent2.y).thenReturn(1f)
gesListener.onFling(motionEvent1, motionEvent2, 0f, 2000f)
}
}

View file

@ -2,6 +2,7 @@ package fr.free.nrw.commons.customselector.ui.adapter
import android.content.ContentResolver
import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
@ -13,22 +14,34 @@ import fr.free.nrw.commons.customselector.listeners.ImageSelectListener
import fr.free.nrw.commons.customselector.model.Image
import fr.free.nrw.commons.customselector.ui.selector.CustomSelectorActivity
import fr.free.nrw.commons.customselector.ui.selector.ImageLoader
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.jupiter.api.Assertions
import org.junit.runner.RunWith
import org.mockito.*
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.powermock.reflect.Whitebox
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import java.lang.reflect.Field
import java.util.*
import kotlin.collections.ArrayList
/**
* Custom Selector image adapter test.
*/
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
@ExperimentalCoroutinesApi
class ImageAdapterTest {
@Mock
private lateinit var imageLoader: ImageLoader
@ -38,6 +51,8 @@ class ImageAdapterTest {
private lateinit var context: Context
@Mock
private lateinit var mockContentResolver: ContentResolver
@Mock
private lateinit var sharedPreferences: SharedPreferences
private lateinit var activity: CustomSelectorActivity
private lateinit var imageAdapter: ImageAdapter
@ -46,6 +61,7 @@ class ImageAdapterTest {
private lateinit var selectedImageField: Field
private var uri: Uri = Mockito.mock(Uri::class.java)
private lateinit var image: Image
private val testDispatcher = TestCoroutineDispatcher()
/**
@ -55,6 +71,7 @@ class ImageAdapterTest {
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.initMocks(this)
Dispatchers.setMain(testDispatcher)
activity = Robolectric.buildActivity(CustomSelectorActivity::class.java).get()
imageAdapter = ImageAdapter(activity, imageSelectListener, imageLoader)
image = Image(1, "image", uri, "abc/abc", 1, "bucket1")
@ -68,6 +85,12 @@ class ImageAdapterTest {
selectedImageField.isAccessible = true
}
@After
fun tearDown() {
Dispatchers.resetMain()
testDispatcher.cleanupTestCoroutines()
}
/**
* Test on create view holder.
*/
@ -88,20 +111,43 @@ class ImageAdapterTest {
// Parameters.
images.add(image)
imageAdapter.init(images)
imageAdapter.init(images, images, TreeMap())
whenever(context.getSharedPreferences("custom_selector", 0))
.thenReturn(sharedPreferences)
// Test conditions.
imageAdapter.onBindViewHolder(holder, 0)
selectedImageField.set(imageAdapter, images)
imageAdapter.onBindViewHolder(holder, 0)
}
/**
* Test processThumbnailForActionedImage
*/
@Test
fun processThumbnailForActionedImage() = runBlocking {
Whitebox.setInternalState(imageAdapter, "allImages", listOf(image))
whenever(imageLoader.nextActionableImage(listOf(image), Dispatchers.IO, Dispatchers.Default,
0)).thenReturn(0)
imageAdapter.processThumbnailForActionedImage(holder, 0)
}
/**
* Test processThumbnailForActionedImage
*/
@Test
fun `processThumbnailForActionedImage when reached end of the folder`() = runBlocking {
whenever(imageLoader.nextActionableImage(ArrayList(), Dispatchers.IO, Dispatchers.Default,
0)).thenReturn(-1)
imageAdapter.processThumbnailForActionedImage(holder, 0)
}
/**
* Test init.
*/
@Test
fun init() {
imageAdapter.init(images)
imageAdapter.init(images, images, TreeMap())
}
/**
@ -115,17 +161,37 @@ class ImageAdapterTest {
// Parameters
images.addAll(listOf(image, image))
imageAdapter.init(images)
imageAdapter.init(images, images, TreeMap())
// Test conditions
holder.itemUploaded()
func.invoke(imageAdapter, holder, 0)
holder.itemNotUploaded()
holder.itemNotForUpload()
func.invoke(imageAdapter, holder, 0)
holder.itemNotForUpload()
func.invoke(imageAdapter, holder, 0)
selectedImageField.set(imageAdapter, images)
func.invoke(imageAdapter, holder, 1)
}
/**
* Test private function onThumbnailClicked.
*/
@Test
fun onThumbnailClicked() {
images.add(image)
Whitebox.setInternalState(imageAdapter, "images", images)
// Access function
val func = imageAdapter.javaClass.getDeclaredMethod(
"onThumbnailClicked",
Int::class.java,
ImageAdapter.ImageViewHolder::class.java
)
func.isAccessible = true
func.invoke(imageAdapter, 0, holder)
}
/**
* Test get item count.
*/
@ -134,12 +200,47 @@ class ImageAdapterTest {
Assertions.assertEquals(0, imageAdapter.itemCount)
}
/**
* Test setSelectedImages.
*/
@Test
fun setSelectedImages() {
images.add(image)
imageAdapter.setSelectedImages(images)
}
/**
* Test refresh.
*/
@Test
fun refresh() {
imageAdapter.refresh(listOf(image), listOf(image))
}
/**
* Test getSectionName.
*/
@Test
fun getSectionName() {
images.add(image)
Whitebox.setInternalState(imageAdapter, "images", images)
Assertions.assertEquals("", imageAdapter.getSectionName(0))
}
/**
* Test cleanUp.
*/
@Test
fun cleanUp() {
imageAdapter.cleanUp()
}
/**
* Test getImageId
*/
@Test
fun getImageIdAt() {
imageAdapter.init(listOf(image))
imageAdapter.init(listOf(image), listOf(image), TreeMap())
Assertions.assertEquals(1, imageAdapter.getImageIdAt(0))
}
}

View file

@ -1,23 +1,21 @@
package fr.free.nrw.commons.customselector.ui.selector
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Looper
import android.os.Looper.getMainLooper
import fr.free.nrw.commons.TestAppAdapter
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.contributions.MainActivity
import fr.free.nrw.commons.customselector.model.Folder
import fr.free.nrw.commons.customselector.model.Image
import fr.free.nrw.commons.customselector.ui.adapter.ImageAdapter
import org.junit.Before
import org.junit.Test
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.powermock.reflect.Whitebox
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows
import org.robolectric.Shadows.shadowOf
import org.robolectric.annotation.Config
import org.wikipedia.AppAdapter
import java.lang.reflect.Method
@ -31,6 +29,14 @@ class CustomSelectorActivityTest {
private lateinit var activity: CustomSelectorActivity
private lateinit var imageFragment: ImageFragment
private lateinit var images : java.util.ArrayList<Image>
private var uri: Uri = Mockito.mock(Uri::class.java)
private lateinit var image: Image
/**
* Set up the tests.
*/
@ -44,6 +50,12 @@ class CustomSelectorActivityTest {
val onCreate = activity.javaClass.getDeclaredMethod("onCreate", Bundle::class.java)
onCreate.isAccessible = true
onCreate.invoke(activity, null)
imageFragment = ImageFragment.newInstance(1,0)
image = Image(1, "image", uri, "abc/abc", 1, "bucket1")
images = ArrayList()
Whitebox.setInternalState(activity, "imageFragment", imageFragment)
Whitebox.setInternalState(imageFragment, "imageAdapter", Mockito.mock(ImageAdapter::class.java))
}
/**
@ -75,13 +87,61 @@ class CustomSelectorActivityTest {
activity.onFolderClick(1, "test", 0);
}
/**
* Test onActivityResult function.
*/
@Test
@Throws(Exception::class)
fun testOnActivityResult() {
val func = activity.javaClass.getDeclaredMethod(
"onActivityResult",
Int::class.java,
Int::class.java,
Intent::class.java
)
func.isAccessible = true
func.invoke(activity, 512, -1, Mockito.mock(Intent::class.java))
}
/**
* Test showWelcomeDialog function.
*/
@Test
@Throws(Exception::class)
fun testShowWelcomeDialog() {
val func = activity.javaClass.getDeclaredMethod(
"showWelcomeDialog"
)
func.isAccessible = true
func.invoke(activity)
}
/**
* Test onLongPress function.
*/
@Test
@Throws(Exception::class)
fun testOnLongPress() {
val func = activity.javaClass.getDeclaredMethod(
"onLongPress",
Int::class.java,
ArrayList::class.java,
ArrayList::class.java
)
images.add(image)
func.isAccessible = true
func.invoke(activity, 0, images, images)
}
/**
* Test selectedImagesChanged function.
*/
@Test
@Throws(Exception::class)
fun testOnSelectedImagesChanged() {
activity.onSelectedImagesChanged(ArrayList())
activity.onSelectedImagesChanged(ArrayList(), 0)
}
/**
@ -91,10 +151,40 @@ class CustomSelectorActivityTest {
@Throws(Exception::class)
fun testOnDone() {
activity.onDone()
activity.onSelectedImagesChanged(ArrayList(arrayListOf(Image(1, "test", Uri.parse("test"), "test", 1))));
activity.onSelectedImagesChanged(
ArrayList(arrayListOf(Image(1, "test", Uri.parse("test"), "test", 1))),
1
)
activity.onDone()
}
/**
* Test onClickNotForUpload function.
*/
@Test
@Throws(Exception::class)
fun testOnClickNotForUpload() {
val method: Method = CustomSelectorActivity::class.java.getDeclaredMethod(
"onClickNotForUpload"
)
method.isAccessible = true
method.invoke(activity)
activity.onSelectedImagesChanged(
ArrayList(arrayListOf(Image(1, "test", Uri.parse("test"), "test", 1))),
0
)
method.invoke(activity)
}
/**
* Test setOnDataListener Function.
*/
@Test
@Throws(Exception::class)
fun testSetOnDataListener() {
activity.setOnDataListener(imageFragment)
}
/**
* Test onBackPressed Function.
*/

View file

@ -64,7 +64,8 @@ class ImageFileLoaderTest {
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.BUCKET_ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_ADDED
)
Whitebox.setInternalState(imageFileLoader, "coroutineContext", coroutineContext)
@ -103,6 +104,7 @@ class ImageFileLoaderTest {
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull()
)
} doReturn imageCursor;

View file

@ -47,6 +47,7 @@ import java.lang.reflect.Field
class ImageFragmentTest {
private lateinit var fragment: ImageFragment
private lateinit var activity: CustomSelectorActivity
private lateinit var view: View
private lateinit var selectorRV : RecyclerView
private lateinit var loader : ProgressBar
@ -76,7 +77,7 @@ class ImageFragmentTest {
AppAdapter.set(TestAppAdapter())
SoLoader.setInTestMode()
Fresco.initialize(context)
val activity = Robolectric.buildActivity(CustomSelectorActivity::class.java).create().get()
activity = Robolectric.buildActivity(CustomSelectorActivity::class.java).create().get()
fragment = ImageFragment.newInstance(1,0)
val fragmentManager: FragmentManager = activity.supportFragmentManager
@ -92,6 +93,7 @@ class ImageFragmentTest {
Whitebox.setInternalState(fragment, "imageAdapter", adapter)
Whitebox.setInternalState(fragment, "selectorRV", selectorRV )
Whitebox.setInternalState(fragment, "loader", loader)
Whitebox.setInternalState(fragment, "filteredImages", arrayListOf(image,image))
viewModelField = fragment.javaClass.getDeclaredField("viewModel")
viewModelField.isAccessible = true
@ -139,6 +141,21 @@ class ImageFragmentTest {
assertEquals(3, func.invoke(fragment))
}
/**
* Test onAttach function.
*/
@Test
fun testOnAttach() {
fragment.onAttach(activity)
}
/**
* Test refresh function.
*/
@Test
fun testRefresh() {
fragment.refresh()
}
/**
* Test onResume.

View file

@ -2,9 +2,11 @@ package fr.free.nrw.commons.customselector.ui.selector
import android.content.ContentResolver
import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import com.nhaarman.mockitokotlin2.*
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.customselector.database.NotForUploadStatusDao
import fr.free.nrw.commons.customselector.database.UploadedStatus
import fr.free.nrw.commons.customselector.database.UploadedStatusDao
import fr.free.nrw.commons.customselector.model.Image
@ -61,6 +63,9 @@ class ImageLoaderTest {
@Mock
private lateinit var uploadedStatusDao: UploadedStatusDao
@Mock
private lateinit var notForUploadStatusDao: NotForUploadStatusDao
@Mock
private lateinit var holder: ImageAdapter.ImageViewHolder
@ -97,7 +102,8 @@ class ImageLoaderTest {
MockitoAnnotations.initMocks(this)
imageLoader =
ImageLoader(mediaClient, fileProcessor, fileUtilsWrapper, uploadedStatusDao, context)
ImageLoader(mediaClient, fileProcessor, fileUtilsWrapper, uploadedStatusDao,
notForUploadStatusDao, context)
uploadedStatus= UploadedStatus(
"testSha1",
"testSha1",
@ -112,8 +118,6 @@ class ImageLoaderTest {
Whitebox.setInternalState(imageLoader, "mapModifiedImageSHA1", mapModifiedImageSHA1);
Whitebox.setInternalState(imageLoader, "mapResult", mapResult);
Whitebox.setInternalState(imageLoader, "context", context)
Whitebox.setInternalState(imageLoader, "ioDispatcher", testDispacher)
Whitebox.setInternalState(imageLoader, "defaultDispatcher", testDispacher)
whenever(contentResolver.openInputStream(uri)).thenReturn(inputStream)
whenever(context.contentResolver).thenReturn(contentResolver)
@ -136,14 +140,17 @@ class ImageLoaderTest {
@Test
fun testQueryAndSetViewUploadedStatusNull() = testDispacher.runBlockingTest {
whenever(uploadedStatusDao.getUploadedFromImageSHA1(any())).thenReturn(null)
whenever(notForUploadStatusDao.find(any())).thenReturn(0)
mapModifiedImageSHA1[image] = "testSha1"
mapImageSHA1[uri] = "testSha1"
whenever(context.getSharedPreferences("custom_selector", 0))
.thenReturn(Mockito.mock(SharedPreferences::class.java))
mapResult["testSha1"] = ImageLoader.Result.TRUE
imageLoader.queryAndSetView(holder, image)
imageLoader.queryAndSetView(holder, image, testDispacher, testDispacher)
mapResult["testSha1"] = ImageLoader.Result.FALSE
imageLoader.queryAndSetView(holder, image)
imageLoader.queryAndSetView(holder, image, testDispacher, testDispacher)
}
/**
@ -152,20 +159,38 @@ class ImageLoaderTest {
@Test
fun testQueryAndSetViewUploadedStatusNotNull() = testDispacher.runBlockingTest {
whenever(uploadedStatusDao.getUploadedFromImageSHA1(any())).thenReturn(uploadedStatus)
imageLoader.queryAndSetView(holder, image)
whenever(notForUploadStatusDao.find(any())).thenReturn(0)
whenever(context.getSharedPreferences("custom_selector", 0))
.thenReturn(Mockito.mock(SharedPreferences::class.java))
imageLoader.queryAndSetView(holder, image, testDispacher, testDispacher)
}
/**
* Test querySha1
* Test nextActionableImage
*/
@Test
fun testQuerySha1() = testDispacher.runBlockingTest {
fun testNextActionableImage() = testDispacher.runBlockingTest {
whenever(notForUploadStatusDao.find(any())).thenReturn(0)
whenever(uploadedStatusDao.findByImageSHA1(any(), any())).thenReturn(0)
whenever(uploadedStatusDao.findByModifiedImageSHA1(any(), any())).thenReturn(0)
PowerMockito.mockStatic(PickedFiles::class.java)
BDDMockito.given(PickedFiles.pickedExistingPicture(context, image.uri))
.willReturn(UploadableFile(uri, File("ABC")))
whenever(fileUtilsWrapper.getFileInputStream("ABC")).thenReturn(inputStream)
whenever(fileUtilsWrapper.getSHA1(inputStream)).thenReturn("testSha1")
whenever(PickedFiles.pickedExistingPicture(context, Uri.parse("test"))).thenReturn(
uploadableFile
)
imageLoader.nextActionableImage(listOf(image), testDispacher, testDispacher, 0)
whenever(single.blockingGet()).thenReturn(true)
whenever(mediaClient.checkFileExistsUsingSha("testSha1")).thenReturn(single)
whenever(fileUtilsWrapper.getSHA1(any())).thenReturn("testSha1")
whenever(notForUploadStatusDao.find(any())).thenReturn(1)
imageLoader.nextActionableImage(listOf(image), testDispacher, testDispacher, 0)
imageLoader.querySHA1("testSha1")
whenever(uploadedStatusDao.findByImageSHA1(any(), any())).thenReturn(2)
imageLoader.nextActionableImage(listOf(image), testDispacher, testDispacher, 0)
whenever(uploadedStatusDao.findByModifiedImageSHA1(any(), any())).thenReturn(2)
imageLoader.nextActionableImage(listOf(image), testDispacher, testDispacher, 0)
}
/**
@ -183,13 +208,13 @@ class ImageLoaderTest {
whenever(fileUtilsWrapper.getFileInputStream("ABC")).thenReturn(inputStream)
whenever(fileUtilsWrapper.getSHA1(inputStream)).thenReturn("testSha1")
Assert.assertEquals("testSha1", imageLoader.getSHA1(image));
Assert.assertEquals("testSha1", imageLoader.getSHA1(image, testDispacher));
whenever(PickedFiles.pickedExistingPicture(context, Uri.parse("test"))).thenReturn(
uploadableFile
)
mapModifiedImageSHA1[image] = "testSha2"
Assert.assertEquals("testSha2", imageLoader.getSHA1(image));
Assert.assertEquals("testSha2", imageLoader.getSHA1(image, testDispacher));
}
/**
@ -213,8 +238,4 @@ class ImageLoaderTest {
imageLoader.getResultFromUploadedStatus(uploadedStatus))
}
@Test
fun testCleanUP() {
imageLoader.cleanUP()
}
}

View file

@ -5,18 +5,25 @@ import android.content.Intent
import android.net.Uri
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.soloader.SoLoader
import fr.free.nrw.commons.TestAppAdapter
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.customselector.model.CallbackStatus
import fr.free.nrw.commons.customselector.model.Image
import fr.free.nrw.commons.customselector.model.Result
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.powermock.reflect.Whitebox
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import org.wikipedia.AppAdapter
import java.lang.reflect.Field
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
@ -25,18 +32,32 @@ class ZoomableActivityUnitTests {
private lateinit var context: Context
private lateinit var activity: ZoomableActivity
private lateinit var viewModelField: Field
private lateinit var image: Image
@Mock
private lateinit var uri: Uri
@Mock
private lateinit var images: ArrayList<Image>
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
AppAdapter.set(TestAppAdapter())
context = RuntimeEnvironment.application.applicationContext
SoLoader.setInTestMode()
Fresco.initialize(context)
val intent = Intent().setData(uri)
activity = Robolectric.buildActivity(ZoomableActivity::class.java, intent).create().get()
image = Image(1, "image", uri, "abc/abc", 1, "bucket1")
Whitebox.setInternalState(activity, "images", arrayListOf(image))
Whitebox.setInternalState(activity, "selectedImages", arrayListOf(image))
viewModelField = activity.javaClass.getDeclaredField("viewModel")
viewModelField.isAccessible = true
}
@Test
@ -45,4 +66,87 @@ class ZoomableActivityUnitTests {
Assert.assertNotNull(activity)
}
/**
* Test handleResult.
*/
@Test
fun testHandleResult(){
val func = activity.javaClass.getDeclaredMethod("handleResult", Result::class.java)
func.isAccessible = true
func.invoke(activity, Result(CallbackStatus.SUCCESS, arrayListOf()))
func.invoke(activity, Result(CallbackStatus.SUCCESS, arrayListOf(image,image)))
}
/**
* Test onLeftSwiped.
*/
@Test
fun testOnLeftSwiped(){
val func = activity.javaClass.getDeclaredMethod("onLeftSwiped", Boolean::class.java)
func.isAccessible = true
func.invoke(activity, true)
Whitebox.setInternalState(activity, "images", arrayListOf(image, image))
Whitebox.setInternalState(activity, "position", 0)
func.invoke(activity, true)
func.invoke(activity, false)
}
/**
* Test onRightSwiped.
*/
@Test
fun testOnRightSwiped(){
val func = activity.javaClass.getDeclaredMethod("onRightSwiped", Boolean::class.java)
func.isAccessible = true
func.invoke(activity, true)
Whitebox.setInternalState(activity, "images", arrayListOf(image, image))
Whitebox.setInternalState(activity, "position", 1)
func.invoke(activity, true)
func.invoke(activity, false)
}
/**
* Test onUpSwiped.
*/
@Test
fun testOnUpSwiped(){
val func = activity.javaClass.getDeclaredMethod("onUpSwiped")
func.isAccessible = true
func.invoke(activity)
}
/**
* Test onDownSwiped.
*/
@Test
fun testOnDownSwiped(){
val func = activity.javaClass.getDeclaredMethod("onDownSwiped")
func.isAccessible = true
func.invoke(activity)
}
/**
* Test onBackPressed.
*/
@Test
fun testOnBackPressed(){
val func = activity.javaClass.getDeclaredMethod("onBackPressed")
func.isAccessible = true
func.invoke(activity)
}
/**
* Test onDestroy.
*/
@Test
fun testOnDestroy(){
val func = activity.javaClass.getDeclaredMethod("onDestroy")
func.isAccessible = true
func.invoke(activity)
}
}