Add DepictsFragment Unit Tests and update tests dependencies (#4688)

* Add DepictsFragment Unit Tests and update tests dependencies

* Attempt to fix CI
This commit is contained in:
Madhur Gupta 2021-10-26 02:01:59 +05:30 committed by GitHub
parent 3dcd271980
commit 7ce80aa804
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 229 additions and 20 deletions

View file

@ -84,15 +84,15 @@ dependencies {
// Unit testing // Unit testing
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.5.1' testImplementation 'org.robolectric:robolectric:4.6-alpha-1'
testImplementation 'androidx.test:core:1.3.0' testImplementation 'androidx.test:core:1.4.0'
testImplementation "com.squareup.okhttp3:mockwebserver:$OKHTTP_VERSION" testImplementation "com.squareup.okhttp3:mockwebserver:$OKHTTP_VERSION"
testImplementation "com.jraska.livedata:testing-ktx:1.1.2" testImplementation "com.jraska.livedata:testing-ktx:1.1.2"
testImplementation "androidx.arch.core:core-testing:2.1.0" testImplementation "androidx.arch.core:core-testing:2.1.0"
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.1" testImplementation "org.junit.jupiter:junit-jupiter-api:5.7.0"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.1" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.7.0"
testImplementation 'com.facebook.soloader:soloader:0.9.0' testImplementation 'com.facebook.soloader:soloader:0.10.1'
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2" testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.0"
// Android testing // Android testing
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$KOTLIN_VERSION" androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$KOTLIN_VERSION"
@ -142,6 +142,7 @@ dependencies {
def work_version = "2.4.0" def work_version = "2.4.0"
// Kotlin + coroutines // Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version" implementation "androidx.work:work-runtime-ktx:$work_version"
testImplementation "androidx.work:work-testing:$work_version"
//Glide //Glide
implementation 'com.github.bumptech.glide:glide:4.12.0' implementation 'com.github.bumptech.glide:glide:4.12.0'

View file

@ -4,7 +4,6 @@ import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@ -23,12 +22,10 @@ import com.jakewharton.rxbinding2.widget.RxTextView;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.upload.UploadActivity; import fr.free.nrw.commons.upload.UploadActivity;
import fr.free.nrw.commons.upload.UploadBaseFragment; import fr.free.nrw.commons.upload.UploadBaseFragment;
import fr.free.nrw.commons.upload.UploadModel;
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem; import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
import fr.free.nrw.commons.utils.DialogUtil; import fr.free.nrw.commons.utils.DialogUtil;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
@ -82,12 +79,9 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
depictsTitle.setText(getString(R.string.step_count, callback.getIndexInViewFlipper(this) + 1, depictsTitle.setText(getString(R.string.step_count, callback.getIndexInViewFlipper(this) + 1,
callback.getTotalNumberOfSteps(), getString(R.string.depicts_step_title))); callback.getTotalNumberOfSteps(), getString(R.string.depicts_step_title)));
setDepictsSubTitle(); setDepictsSubTitle();
tooltip.setOnClickListener(new OnClickListener() { tooltip.setOnClickListener(v -> DialogUtil
@Override .showAlertDialog(getActivity(), getString(R.string.depicts_step_title),
public void onClick(View v) { getString(R.string.depicts_tooltip), getString(android.R.string.ok), null, true));
DialogUtil.showAlertDialog(getActivity(), getString(R.string.depicts_step_title), getString(R.string.depicts_tooltip), getString(android.R.string.ok), null, true);
}
});
presenter.onAttachView(this); presenter.onAttachView(this);
initRecyclerView(); initRecyclerView();
addTextChangeListenerToSearchBox(); addTextChangeListenerToSearchBox();

View file

@ -6,7 +6,7 @@ import android.os.Bundle
import android.os.Looper import android.os.Looper
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.work.Configuration import androidx.work.Configuration
import androidx.work.WorkManager import androidx.work.testing.WorkManagerTestInitHelper
import fr.free.nrw.commons.CommonsApplication import fr.free.nrw.commons.CommonsApplication
import fr.free.nrw.commons.R import fr.free.nrw.commons.R
import fr.free.nrw.commons.TestAppAdapter import fr.free.nrw.commons.TestAppAdapter
@ -105,6 +105,9 @@ class MainActivityUnitTests {
MainActivity::class.java.getDeclaredField("contributionsFragment") MainActivity::class.java.getDeclaredField("contributionsFragment")
fieldContributionsFragment.isAccessible = true fieldContributionsFragment.isAccessible = true
fieldContributionsFragment.set(activity, contributionsFragment) fieldContributionsFragment.set(activity, contributionsFragment)
val config: Configuration = Configuration.Builder().build()
WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
} }
@Test @Test
@ -199,8 +202,6 @@ class MainActivityUnitTests {
@Throws(Exception::class) @Throws(Exception::class)
fun testToggleLimitedConnectionMode() { fun testToggleLimitedConnectionMode() {
Shadows.shadowOf(Looper.getMainLooper()).idle() Shadows.shadowOf(Looper.getMainLooper()).idle()
val config: Configuration = Configuration.Builder().build()
WorkManager.initialize(context, config)
`when`( `when`(
defaultKvStore.getBoolean( defaultKvStore.getBoolean(
CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED, false CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED, false

View file

@ -2,6 +2,8 @@ package fr.free.nrw.commons.upload
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.work.Configuration
import androidx.work.testing.WorkManagerTestInitHelper
import fr.free.nrw.commons.CommonsApplication import fr.free.nrw.commons.CommonsApplication
import fr.free.nrw.commons.R import fr.free.nrw.commons.R
import fr.free.nrw.commons.TestAppAdapter import fr.free.nrw.commons.TestAppAdapter
@ -62,6 +64,9 @@ class UploadActivityUnitTests {
Whitebox.setInternalState(activity, "fragments", mutableListOf(uploadBaseFragment)) Whitebox.setInternalState(activity, "fragments", mutableListOf(uploadBaseFragment))
Whitebox.setInternalState(activity, "presenter", presenter) Whitebox.setInternalState(activity, "presenter", presenter)
Whitebox.setInternalState(activity, "contributionController", contributionController) Whitebox.setInternalState(activity, "contributionController", contributionController)
val config: Configuration = Configuration.Builder().build()
WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
} }
@Test @Test
@ -158,7 +163,6 @@ class UploadActivityUnitTests {
} }
@Test @Test
@Ignore()
@Throws(Exception::class) @Throws(Exception::class)
fun testMakeUploadRequest() { fun testMakeUploadRequest() {
activity.makeUploadRequest() activity.makeUploadRequest()

View file

@ -168,7 +168,6 @@ class UploadCategoriesFragmentUnitTests {
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testSetCategoriesCaseNonNull() { fun testSetCategoriesCaseNonNull() {
Shadows.shadowOf(Looper.getMainLooper()).idle()
fragment.setCategories(listOf()) fragment.setCategories(listOf())
} }

View file

@ -0,0 +1,210 @@
package fr.free.nrw.commons.upload.depicts
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import fr.free.nrw.commons.R
import fr.free.nrw.commons.TestAppAdapter
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.upload.UploadActivity
import fr.free.nrw.commons.upload.UploadBaseFragment
import io.reactivex.disposables.Disposable
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.Method
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
@LooperMode(LooperMode.Mode.PAUSED)
class DepictsFragmentUnitTests {
private lateinit var fragment: DepictsFragment
private lateinit var fragmentManager: FragmentManager
private lateinit var layoutInflater: LayoutInflater
private lateinit var view: View
private lateinit var context: Context
@Mock
private lateinit var savedInstanceState: Bundle
@Mock
private lateinit var textView: TextView
@Mock
private lateinit var imageView: ImageView
@Mock
private lateinit var recyclerView: RecyclerView
@Mock
private lateinit var textInputEditText: TextInputEditText
@Mock
private lateinit var progressBar: ProgressBar
@Mock
private lateinit var textInputLayout: TextInputLayout
@Mock
private lateinit var callback: UploadBaseFragment.Callback
@Mock
private lateinit var disposable: Disposable
@Mock
private lateinit var adapter: UploadDepictsAdapter
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
context = RuntimeEnvironment.application.applicationContext
AppAdapter.set(TestAppAdapter())
val activity = Robolectric.buildActivity(UploadActivity::class.java).create().get()
fragment = DepictsFragment()
fragmentManager = activity.supportFragmentManager
val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.add(fragment, null)
fragmentTransaction.commitNowAllowingStateLoss()
layoutInflater = LayoutInflater.from(activity)
view = LayoutInflater.from(activity)
.inflate(R.layout.upload_depicts_fragment, null) as View
Whitebox.setInternalState(fragment, "depictsTitle", textView)
Whitebox.setInternalState(fragment, "callback", callback)
Whitebox.setInternalState(fragment, "tooltip", imageView)
Whitebox.setInternalState(fragment, "depictsSubTitle", textView)
Whitebox.setInternalState(fragment, "depictsRecyclerView", recyclerView)
Whitebox.setInternalState(fragment, "depictsSearch", textInputEditText)
Whitebox.setInternalState(fragment, "depictsSearchContainer", textInputLayout)
Whitebox.setInternalState(fragment, "depictsSearchInProgress", progressBar)
Whitebox.setInternalState(fragment, "subscribe", disposable)
Whitebox.setInternalState(fragment, "adapter", adapter)
}
@Test
@Throws(Exception::class)
fun checkFragmentNotNull() {
Assert.assertNotNull(fragment)
}
@Test
@Throws(Exception::class)
fun testOnCreateView() {
fragment.onCreateView(layoutInflater, null, savedInstanceState)
}
@Test
@Throws(Exception::class)
fun testInit() {
val method: Method = DepictsFragment::class.java.getDeclaredMethod(
"init"
)
method.isAccessible = true
method.invoke(fragment)
}
@Test
@Throws(Exception::class)
fun testOnBecameVisible() {
val method: Method = DepictsFragment::class.java.getDeclaredMethod(
"onBecameVisible"
)
method.isAccessible = true
method.invoke(fragment)
}
@Test
@Throws(Exception::class)
fun testGoToNextScreen() {
fragment.goToNextScreen()
}
@Test
@Throws(Exception::class)
fun testGoToPreviousScreen() {
fragment.goToPreviousScreen()
}
@Test
@Throws(Exception::class)
fun testNoDepictionSelected() {
fragment.noDepictionSelected()
}
@Test
@Throws(Exception::class)
fun testOnDestroyView() {
fragment.onDestroyView()
}
@Test
@Throws(Exception::class)
fun testShowProgress() {
fragment.showProgress(true)
}
@Test
@Throws(Exception::class)
fun testShowErrorCaseTrue() {
fragment.showError(true)
}
@Test
@Throws(Exception::class)
fun testShowErrorCaseFalse() {
fragment.showError(false)
}
@Test
@Throws(Exception::class)
fun testSetDepictsList() {
fragment.setDepictsList(listOf())
}
@Test
@Throws(Exception::class)
fun testOnNextButtonClicked() {
fragment.onNextButtonClicked()
}
@Test
@Throws(Exception::class)
fun testOnPreviousButtonClicked() {
fragment.onPreviousButtonClicked()
}
@Test
@Throws(Exception::class)
fun testSearchForDepictions() {
val method: Method = DepictsFragment::class.java.getDeclaredMethod(
"searchForDepictions",
String::class.java
)
method.isAccessible = true
method.invoke(fragment, "")
}
}