#3408 Refactoring the FileProcessor and GPSExtractor classes (#3543)

* #3408 Refactoring the FileProcessor and GPSExtractor classes - refactor FileProcessor

* #3408 Refactoring the FileProcessor and GPSExtractor classes - refactor and rename GpsExtractor

* #3408 Refactoring the FileProcessor and GPSExtractor classes - convert ImageCoordinates to kotlin

* #3408 Refactoring the FileProcessor and GPSExtractor classes - convert FileProcessor to kotlin

* #3408 Refactoring the FileProcessor and GPSExtractor classes - minor reformatting

* #3408 Refactoring the FileProcessor and GPSExtractor classes - fix compilation and naming issues

* #3408 Refactoring the FileProcessor and GPSExtractor classes - remove empty test

* #3408 Refactoring the FileProcessor and GPSExtractor classes - set coordinates for upload item if user chooses it
This commit is contained in:
Seán Mac Gillicuddy 2020-03-20 14:18:14 +00:00 committed by GitHub
parent efc6fa6211
commit fb51fc618a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 450 additions and 834 deletions

View file

@ -1,89 +0,0 @@
package fr.free.nrw.commons.upload
import android.content.SharedPreferences
import androidx.exifinterface.media.ExifInterface
import fr.free.nrw.commons.caching.CacheController
import fr.free.nrw.commons.mwapi.CategoryApi
import org.junit.Before
import org.junit.Test
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import javax.inject.Inject
import javax.inject.Named
import java.io.FileInputStream
import java.io.FileOutputStream
class FileProcessorTest {
@Mock
internal var cacheController: CacheController? = null
@Mock
internal var gpsCategoryModel: GpsCategoryModel? = null
@Mock
internal var apiCall: CategoryApi? = null
@Mock
@field:[Inject Named("default_preferences")]
internal var prefs: SharedPreferences? = null
@InjectMocks
var fileProcessor: FileProcessor? = null
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
}
@Test
fun processFileCoordinates() {
}
/**
* Test method to verify redaction Exif metadata
*/
@Test
fun redactExifTags() {
/*
val filePathRef: String? = "src/test/data/exif_redact_sample.jpg"
val filePathTmp: String? = "" + System.getProperty("java.io.tmpdir") + "exif_redact_sample_tmp.jpg"
val inStream = FileInputStream(filePathRef)
val outStream = FileOutputStream(filePathTmp)
val inChannel = inStream.getChannel()
val outChannel = outStream.getChannel()
inChannel.transferTo(0, inChannel.size(), outChannel)
inStream.close()
outStream.close()
val redactTags = mutableSetOf("Author", "Copyright", "Location", "Camera Model",
"Lens Model", "Serial Numbers", "Software")
val exifInterface : ExifInterface? = ExifInterface(filePathTmp.toString())
var nonEmptyTag = false
for (redactTag in redactTags) {
for (tag in FileMetadataUtils.getTagsFromPref(redactTag)) {
val tagValue = exifInterface?.getAttribute(tag)
if(tagValue != null) {
nonEmptyTag = true
break
}
}
if (nonEmptyTag) break
}
// all tags are empty, can't test redaction
assert(nonEmptyTag)
FileProcessor.redactExifTags(exifInterface, redactTags)
for (redactTag in redactTags) {
for (tag in FileMetadataUtils.getTagsFromPref(redactTag)) {
val oldValue = exifInterface?.getAttribute(tag)
assert(oldValue == null)
}
}
*/
}
}

View file

@ -1,5 +1,7 @@
package fr.free.nrw.commons.upload
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.filepicker.UploadableFile
import fr.free.nrw.commons.nearby.Place
import fr.free.nrw.commons.repository.UploadRepository
@ -14,7 +16,6 @@ import org.junit.Test
import org.mockito.ArgumentMatchers
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@ -24,31 +25,32 @@ import org.mockito.MockitoAnnotations
*/
class UploadMediaPresenterTest {
@Mock
internal var repository: UploadRepository? = null
@Mock
internal var view: UploadMediaDetailsContract.View? = null
private var uploadMediaPresenter: UploadMediaPresenter? = null
internal lateinit var repository: UploadRepository
@Mock
private var uploadableFile: UploadableFile? = null
internal lateinit var view: UploadMediaDetailsContract.View
private lateinit var uploadMediaPresenter: UploadMediaPresenter
@Mock
private var place: Place? = null
private lateinit var uploadableFile: UploadableFile
@Mock
private var uploadItem: UploadModel.UploadItem? = null
private lateinit var place: Place
@Mock
private var title: Title? = null
private lateinit var uploadItem: UploadModel.UploadItem
@Mock
private var descriptions: List<Description>? = null
private lateinit var title: Title
private var testObservableUploadItem: Observable<UploadModel.UploadItem>? = null
private var testSingleImageResult: Single<Int>? = null
@Mock
private lateinit var descriptions: List<Description>
private var testScheduler: TestScheduler? = null
private lateinit var testObservableUploadItem: Observable<UploadModel.UploadItem>
private lateinit var testSingleImageResult: Single<Int>
private lateinit var testScheduler: TestScheduler
/**
* initial setup unit test environment
@ -61,7 +63,7 @@ class UploadMediaPresenterTest {
testSingleImageResult = Single.just(1)
testScheduler = TestScheduler()
uploadMediaPresenter = UploadMediaPresenter(repository, testScheduler, testScheduler)
uploadMediaPresenter?.onAttachView(view)
uploadMediaPresenter.onAttachView(view)
}
/**
@ -69,12 +71,22 @@ class UploadMediaPresenterTest {
*/
@Test
fun receiveImageTest() {
Mockito.`when`(repository?.preProcessImage(ArgumentMatchers.any(UploadableFile::class.java), ArgumentMatchers.any(Place::class.java), ArgumentMatchers.anyString(), ArgumentMatchers.any(UploadMediaPresenter::class.java))).thenReturn(testObservableUploadItem)
uploadMediaPresenter?.receiveImage(uploadableFile, ArgumentMatchers.anyString(), place)
verify(view)?.showProgress(true)
testScheduler?.triggerActions()
verify(view)?.onImageProcessed(ArgumentMatchers.any(UploadModel.UploadItem::class.java), ArgumentMatchers.any(Place::class.java))
verify(view)?.showProgress(false)
whenever(
repository.preProcessImage(
ArgumentMatchers.any(UploadableFile::class.java),
ArgumentMatchers.any(Place::class.java),
ArgumentMatchers.anyString(),
ArgumentMatchers.any(UploadMediaPresenter::class.java)
)
).thenReturn(testObservableUploadItem)
uploadMediaPresenter.receiveImage(uploadableFile, ArgumentMatchers.anyString(), place)
verify(view).showProgress(true)
testScheduler.triggerActions()
verify(view).onImageProcessed(
ArgumentMatchers.any(UploadModel.UploadItem::class.java),
ArgumentMatchers.any(Place::class.java)
)
verify(view).showProgress(false)
}
/**
@ -82,12 +94,13 @@ class UploadMediaPresenterTest {
*/
@Test
fun verifyImageQualityTest() {
Mockito.`when`(repository?.getImageQuality(ArgumentMatchers.any(UploadModel.UploadItem::class.java))).thenReturn(testSingleImageResult)
Mockito.`when`(uploadItem?.imageQuality).thenReturn(ArgumentMatchers.anyInt())
uploadMediaPresenter?.verifyImageQuality(uploadItem)
verify(view)?.showProgress(true)
testScheduler?.triggerActions()
verify(view)?.showProgress(false)
whenever(repository.getImageQuality(ArgumentMatchers.any(UploadModel.UploadItem::class.java)))
.thenReturn(testSingleImageResult)
whenever(uploadItem.imageQuality).thenReturn(ArgumentMatchers.anyInt())
uploadMediaPresenter.verifyImageQuality(uploadItem)
verify(view).showProgress(true)
testScheduler.triggerActions()
verify(view).showProgress(false)
}
/**
@ -96,21 +109,21 @@ class UploadMediaPresenterTest {
@Test
fun handleImageResult() {
//Positive case test
uploadMediaPresenter?.handleImageResult(IMAGE_KEEP)
verify(view)?.onImageValidationSuccess()
uploadMediaPresenter.handleImageResult(IMAGE_KEEP)
verify(view).onImageValidationSuccess()
//Duplicate file name
uploadMediaPresenter?.handleImageResult(FILE_NAME_EXISTS)
verify(view)?.showDuplicatePicturePopup()
uploadMediaPresenter.handleImageResult(FILE_NAME_EXISTS)
verify(view).showDuplicatePicturePopup()
//Empty Title test
uploadMediaPresenter?.handleImageResult(EMPTY_TITLE)
verify(view)?.showMessage(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())
uploadMediaPresenter.handleImageResult(EMPTY_TITLE)
verify(view).showMessage(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())
//Bad Picture test
//Empty Title test
uploadMediaPresenter?.handleImageResult(-7)
verify(view)?.showBadImagePopup(ArgumentMatchers.anyInt())
uploadMediaPresenter.handleImageResult(-7)
verify(view).showBadImagePopup(ArgumentMatchers.anyInt())
}
@ -118,52 +131,54 @@ class UploadMediaPresenterTest {
* Test fetch previous image title when there was one
*/
@Test
fun fetchPreviousImageAndTitleTestPositive(){
Mockito.`when`(repository?.getPreviousUploadItem(ArgumentMatchers.anyInt())).thenReturn(uploadItem)
Mockito.`when`(uploadItem?.descriptions).thenReturn(descriptions)
Mockito.`when`(uploadItem?.title).thenReturn(title)
Mockito.`when`(title?.getTitleText()).thenReturn(ArgumentMatchers.anyString())
fun fetchPreviousImageAndTitleTestPositive() {
whenever(repository.getPreviousUploadItem(ArgumentMatchers.anyInt()))
.thenReturn(uploadItem)
whenever(uploadItem.descriptions).thenReturn(descriptions)
whenever(uploadItem.title).thenReturn(title)
whenever(title.getTitleText()).thenReturn(ArgumentMatchers.anyString())
uploadMediaPresenter?.fetchPreviousTitleAndDescription(0)
verify(view)?.setTitleAndDescription(ArgumentMatchers.anyString(),ArgumentMatchers.any())
uploadMediaPresenter.fetchPreviousTitleAndDescription(0)
verify(view).setTitleAndDescription(ArgumentMatchers.anyString(), ArgumentMatchers.any())
}
/**
* Test fetch previous image title when there was none
*/
@Test
fun fetchPreviousImageAndTitleTestNegative(){
Mockito.`when`(repository?.getPreviousUploadItem(ArgumentMatchers.anyInt())).thenReturn(null)
uploadMediaPresenter?.fetchPreviousTitleAndDescription(0)
verify(view)?.showMessage(ArgumentMatchers.anyInt(),ArgumentMatchers.anyInt())
fun fetchPreviousImageAndTitleTestNegative() {
whenever(repository.getPreviousUploadItem(ArgumentMatchers.anyInt()))
.thenReturn(null)
uploadMediaPresenter.fetchPreviousTitleAndDescription(0)
verify(view).showMessage(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())
}
/**
* Test bad image invalid location
*/
@Test
fun handleBadImageBaseTestInvalidLocation(){
uploadMediaPresenter?.handleBadImage(8)
verify(repository)?.saveValue(ArgumentMatchers.anyString(),eq(false))
verify(view)?.showBadImagePopup(8)
fun handleBadImageBaseTestInvalidLocation() {
uploadMediaPresenter.handleBadImage(8)
verify(repository).saveValue(ArgumentMatchers.anyString(), eq(false))
verify(view).showBadImagePopup(8)
}
/**
* Test bad image empty title
*/
@Test
fun handleBadImageBaseTestEmptyTitle(){
uploadMediaPresenter?.handleBadImage(-3)
verify(view)?.showMessage(ArgumentMatchers.anyInt(),ArgumentMatchers.anyInt())
fun handleBadImageBaseTestEmptyTitle() {
uploadMediaPresenter.handleBadImage(-3)
verify(view).showMessage(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())
}
/**
* Teste show file already exists
*/
@Test
fun handleBadImageBaseTestFileNameExists(){
uploadMediaPresenter?.handleBadImage(-4)
verify(view)?.showDuplicatePicturePopup()
fun handleBadImageBaseTestFileNameExists() {
uploadMediaPresenter.handleBadImage(-4)
verify(view).showDuplicatePicturePopup()
}
@ -171,18 +186,19 @@ class UploadMediaPresenterTest {
* Test show SimilarImageFragment
*/
@Test
fun showSimilarImageFragmentTest(){
uploadMediaPresenter?.showSimilarImageFragment(ArgumentMatchers.anyString(),ArgumentMatchers.anyString())
verify(view)?.showSimilarImageFragment(ArgumentMatchers.anyString(),ArgumentMatchers.anyString())
fun showSimilarImageFragmentTest() {
val similar: ImageCoordinates = mock()
uploadMediaPresenter.showSimilarImageFragment("original", "possible", similar)
verify(view).showSimilarImageFragment("original", "possible", similar)
}
/**
* Test set upload item
*/
@Test
fun setUploadItemTest(){
uploadMediaPresenter?.setUploadItem(0,uploadItem)
verify(repository)?.updateUploadItem(0,uploadItem)
fun setUploadItemTest() {
uploadMediaPresenter.setUploadItem(0, uploadItem)
verify(repository).updateUploadItem(0, uploadItem)
}
}

View file

@ -1,132 +0,0 @@
package fr.free.nrw.commons.upload
import android.app.Application
import android.content.Context
import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.filepicker.UploadableFile
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.nearby.Place
import fr.free.nrw.commons.utils.ImageUtils.IMAGE_OK
import io.reactivex.Single
import org.junit.After
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.`when`
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
import java.io.FileInputStream
import java.io.InputStream
import java.util.*
import javax.inject.Inject
import javax.inject.Named
class UploadModelTest {
@Mock
@field:[Inject Named("licenses")]
internal var licenses: List<String>? = null
@Mock
@field:[Inject Named("default_preferences")]
internal var prefs: JsonKvStore? = null
@Mock
@field:[Inject Named("licenses_by_name")]
internal var licensesByName: Map<String, String>? = null
@Mock
internal var context: Context? = null
@Mock
internal var sessionManage: SessionManager? = null
@Mock
internal var fileUtilsWrapper: FileUtilsWrapper? = null
@Mock
internal var fileProcessor: FileProcessor? = null
@Mock
internal var imageProcessingService: ImageProcessingService? = null
@InjectMocks
var uploadModel: UploadModel? = null
@Before
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.initMocks(this)
`when`(context!!.applicationContext)
.thenReturn(mock(Application::class.java))
`when`(fileUtilsWrapper!!.getFileExt(anyString()))
.thenReturn("jpg")
`when`(fileUtilsWrapper!!.getSHA1(any(InputStream::class.java)))
.thenReturn("sha")
`when`(fileUtilsWrapper!!.getFileInputStream(anyString()))
.thenReturn(mock(FileInputStream::class.java))
`when`(fileUtilsWrapper!!.getGeolocationOfFile(anyString()))
.thenReturn("")
`when`(imageProcessingService!!.validateImage(any(UploadModel.UploadItem::class.java)))
.thenReturn(Single.just(IMAGE_OK))
}
@After
@Throws(Exception::class)
fun tearDown() {
}
@Test
fun receive() {
val preProcessImages = uploadModel!!.preProcessImages(getMediaList(), mock(Place::class.java), "external") { _, _ -> }
preProcessImages.doOnComplete {
assertTrue(uploadModel!!.items.size == 2)
}
}
@Test
fun getCurrentStep() {
uploadModel!!.preProcessImages(getMediaList(), mock(Place::class.java), "external") { _, _ -> }
assertTrue(uploadModel!!.currentStep == 1)
}
@Test
fun getStepCount() {
val preProcessImages = uploadModel!!.preProcessImages(getMediaList(), mock(Place::class.java), "external") { _, _ -> }
preProcessImages.doOnComplete {
assertTrue(uploadModel!!.stepCount == 4)
}
}
@Test
fun getCount() {
val preProcessImages = uploadModel!!.preProcessImages(getMediaList(), mock(Place::class.java), "external") { _, _ -> }
preProcessImages.doOnComplete {
assertTrue(uploadModel!!.count == 2)
}
}
@Test
fun getUploads() {
val preProcessImages = uploadModel!!.preProcessImages(getMediaList(), mock(Place::class.java), "external") { _, _ -> }
preProcessImages.doOnComplete {
assertTrue(uploadModel!!.uploads.size == 2)
}
}
private fun getMediaList(): List<UploadableFile> {
val element = getElement()
val element2 = getElement()
var uriList: List<UploadableFile> = mutableListOf(element, element2)
return uriList
}
private fun getElement(): UploadableFile {
val mock = mock(UploadableFile::class.java)
`when`(mock.filePath).thenReturn(UUID.randomUUID().toString() + "/filePath.jpg")
return mock
}
@Test
fun buildContributions() {
}
}