mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Removed butterknife from contributions list fragment (#5396)
* Removed butterknife from contributions list fragment and overhauled its test * Suggested fix from stack overflow to remove duplicate class error during build
This commit is contained in:
parent
8b054926fe
commit
3d525d4eb3
5 changed files with 126 additions and 184 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -43,3 +43,7 @@ app/src/main/jniLibs
|
||||||
#https://docs.opencv.org/3.3.0/
|
#https://docs.opencv.org/3.3.0/
|
||||||
/libraries/opencv/javadoc/
|
/libraries/opencv/javadoc/
|
||||||
captures/*
|
captures/*
|
||||||
|
|
||||||
|
# Test and other output
|
||||||
|
app/jacoco.exec
|
||||||
|
app/CommonsContributions
|
||||||
|
|
@ -75,20 +75,22 @@ dependencies {
|
||||||
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
|
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
|
||||||
annotationProcessor "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
|
annotationProcessor "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$KOTLIN_VERSION"
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$KOTLIN_VERSION"
|
implementation "org.jetbrains.kotlin:kotlin-reflect:$KOTLIN_VERSION"
|
||||||
|
|
||||||
//Mocking
|
//Mocking
|
||||||
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
|
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
|
||||||
testImplementation 'org.mockito:mockito-inline:5.2.0'
|
testImplementation 'org.mockito:mockito-inline:5.2.0'
|
||||||
testImplementation 'org.mockito:mockito-core:5.5.0'
|
testImplementation 'org.mockito:mockito-core:5.6.0'
|
||||||
testImplementation "org.powermock:powermock-module-junit4:2.0.9"
|
testImplementation "org.powermock:powermock-module-junit4:2.0.9"
|
||||||
testImplementation "org.powermock:powermock-api-mockito2:2.0.9"
|
testImplementation "org.powermock:powermock-api-mockito2:2.0.9"
|
||||||
|
|
||||||
// Unit testing
|
// Unit testing
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
testImplementation 'org.robolectric:robolectric:4.10.3'
|
testImplementation 'org.robolectric:robolectric:4.11.1'
|
||||||
testImplementation 'androidx.test:core:1.5.0'
|
testImplementation 'androidx.test:core:1.5.0'
|
||||||
|
testImplementation "androidx.test:runner:1.5.2"
|
||||||
|
testImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
|
testImplementation "androidx.test:rules:1.5.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.2.0"
|
testImplementation "androidx.arch.core:core-testing:2.2.0"
|
||||||
|
|
@ -96,9 +98,9 @@ dependencies {
|
||||||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.10.0"
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.10.0"
|
||||||
testImplementation 'com.facebook.soloader:soloader:0.10.5'
|
testImplementation 'com.facebook.soloader:soloader:0.10.5'
|
||||||
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3"
|
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3"
|
||||||
|
debugImplementation("androidx.fragment:fragment-testing:1.6.2")
|
||||||
|
|
||||||
// Android testing
|
// Android testing
|
||||||
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$KOTLIN_VERSION"
|
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0-alpha04'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0-alpha04'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.0-alpha04'
|
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.0-alpha04'
|
||||||
|
|
@ -158,6 +160,15 @@ dependencies {
|
||||||
kaptAndroidTest "androidx.databinding:databinding-compiler:8.0.2"
|
kaptAndroidTest "androidx.databinding:databinding-compiler:8.0.2"
|
||||||
|
|
||||||
implementation("io.github.coordinates2country:coordinates2country-android:1.3") { exclude group: 'com.google.android', module: 'android' }
|
implementation("io.github.coordinates2country:coordinates2country-android:1.3") { exclude group: 'com.google.android', module: 'android' }
|
||||||
|
|
||||||
|
constraints {
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
|
||||||
|
because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
|
||||||
|
}
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
|
||||||
|
because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task disableAnimations(type: Exec) {
|
task disableAnimations(type: Exec) {
|
||||||
|
|
@ -206,8 +217,10 @@ android {
|
||||||
testOptions {
|
testOptions {
|
||||||
animationsDisabled true
|
animationsDisabled true
|
||||||
|
|
||||||
unitTests.returnDefaultValues = true
|
unitTests {
|
||||||
unitTests.includeAndroidResources = true
|
returnDefaultValues = true
|
||||||
|
includeAndroidResources = true
|
||||||
|
}
|
||||||
|
|
||||||
unitTests.all {
|
unitTests.all {
|
||||||
jvmArgs '-noverify'
|
jvmArgs '-noverify'
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.appcompat.widget.AppCompatTextView;
|
import androidx.appcompat.widget.AppCompatTextView;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
|
@ -32,15 +33,13 @@ import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
|
||||||
import androidx.recyclerview.widget.RecyclerView.ItemAnimator;
|
import androidx.recyclerview.widget.RecyclerView.ItemAnimator;
|
||||||
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
|
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
|
||||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import fr.free.nrw.commons.CommonsApplication;
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
import fr.free.nrw.commons.Media;
|
import fr.free.nrw.commons.Media;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.Utils;
|
import fr.free.nrw.commons.Utils;
|
||||||
import fr.free.nrw.commons.auth.SessionManager;
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
|
import fr.free.nrw.commons.databinding.FragmentContributionsListBinding;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
import fr.free.nrw.commons.media.MediaClient;
|
import fr.free.nrw.commons.media.MediaClient;
|
||||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||||
|
|
@ -66,61 +65,43 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
|
|
||||||
private static final String RV_STATE = "rv_scroll_state";
|
private static final String RV_STATE = "rv_scroll_state";
|
||||||
|
|
||||||
@BindView(R.id.contributionsList)
|
|
||||||
RecyclerView rvContributionsList;
|
|
||||||
@BindView(R.id.loadingContributionsProgressBar)
|
|
||||||
ProgressBar progressBar;
|
|
||||||
@BindView(R.id.fab_plus)
|
|
||||||
FloatingActionButton fabPlus;
|
|
||||||
@BindView(R.id.fab_camera)
|
|
||||||
FloatingActionButton fabCamera;
|
|
||||||
@BindView(R.id.fab_gallery)
|
|
||||||
FloatingActionButton fabGallery;
|
|
||||||
@BindView(R.id.noContributionsYet)
|
|
||||||
TextView noContributionsYet;
|
|
||||||
@BindView(R.id.fab_layout)
|
|
||||||
LinearLayout fab_layout;
|
|
||||||
@BindView(R.id.fab_custom_gallery)
|
|
||||||
FloatingActionButton fabCustomGallery;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SystemThemeUtils systemThemeUtils;
|
SystemThemeUtils systemThemeUtils;
|
||||||
@BindView(R.id.tv_contributions_of_user)
|
|
||||||
AppCompatTextView tvContributionsOfUser;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ContributionController controller;
|
ContributionController controller;
|
||||||
@Inject
|
@Inject
|
||||||
MediaClient mediaClient;
|
MediaClient mediaClient;
|
||||||
|
|
||||||
@Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE)
|
@Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE)
|
||||||
@Inject
|
@Inject
|
||||||
WikiSite languageWikipediaSite;
|
WikiSite languageWikipediaSite;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ContributionsListPresenter contributionsListPresenter;
|
ContributionsListPresenter contributionsListPresenter;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SessionManager sessionManager;
|
SessionManager sessionManager;
|
||||||
|
|
||||||
|
private FragmentContributionsListBinding binding;
|
||||||
private Animation fab_close;
|
private Animation fab_close;
|
||||||
private Animation fab_open;
|
private Animation fab_open;
|
||||||
private Animation rotate_forward;
|
private Animation rotate_forward;
|
||||||
private Animation rotate_backward;
|
private Animation rotate_backward;
|
||||||
|
|
||||||
|
|
||||||
private boolean isFabOpen;
|
private boolean isFabOpen;
|
||||||
|
|
||||||
private ContributionsListAdapter adapter;
|
@VisibleForTesting
|
||||||
|
protected RecyclerView rvContributionsList;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected ContributionsListAdapter adapter;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Callback callback;
|
@VisibleForTesting
|
||||||
|
protected Callback callback;
|
||||||
|
|
||||||
private final int SPAN_COUNT_LANDSCAPE = 3;
|
private final int SPAN_COUNT_LANDSCAPE = 3;
|
||||||
private final int SPAN_COUNT_PORTRAIT = 1;
|
private final int SPAN_COUNT_PORTRAIT = 1;
|
||||||
|
|
||||||
private int contributionsSize;
|
private int contributionsSize;
|
||||||
String userName;
|
private String userName;
|
||||||
|
|
||||||
private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
|
private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(Map<String, Boolean> result) {
|
public void onActivityResult(Map<String, Boolean> result) {
|
||||||
|
|
@ -162,21 +143,32 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
public View onCreateView(
|
public View onCreateView(
|
||||||
final LayoutInflater inflater, @Nullable final ViewGroup container,
|
final LayoutInflater inflater, @Nullable final ViewGroup container,
|
||||||
@Nullable final Bundle savedInstanceState) {
|
@Nullable final Bundle savedInstanceState) {
|
||||||
final View view = inflater.inflate(R.layout.fragment_contributions_list, container, false);
|
binding = FragmentContributionsListBinding.inflate(
|
||||||
ButterKnife.bind(this, view);
|
inflater, container, false
|
||||||
|
);
|
||||||
|
rvContributionsList = binding.contributionsList;
|
||||||
|
|
||||||
contributionsListPresenter.onAttachView(this);
|
contributionsListPresenter.onAttachView(this);
|
||||||
|
binding.fabCustomGallery.setOnClickListener(v -> launchCustomSelector());
|
||||||
|
|
||||||
if (Objects.equals(sessionManager.getUserName(), userName)) {
|
if (Objects.equals(sessionManager.getUserName(), userName)) {
|
||||||
tvContributionsOfUser.setVisibility(GONE);
|
binding.tvContributionsOfUser.setVisibility(GONE);
|
||||||
fab_layout.setVisibility(VISIBLE);
|
binding.fabLayout.setVisibility(VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
tvContributionsOfUser.setVisibility(VISIBLE);
|
binding.tvContributionsOfUser.setVisibility(VISIBLE);
|
||||||
tvContributionsOfUser.setText(getString(R.string.contributions_of_user, userName));
|
binding.tvContributionsOfUser.setText(getString(R.string.contributions_of_user, userName));
|
||||||
fab_layout.setVisibility(GONE);
|
binding.fabLayout.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
initAdapter();
|
initAdapter();
|
||||||
return view;
|
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
binding = null;
|
||||||
|
super.onDestroyView();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -309,7 +301,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
public void onConfigurationChanged(final Configuration newConfig) {
|
public void onConfigurationChanged(final Configuration newConfig) {
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
// check orientation
|
// check orientation
|
||||||
fab_layout.setOrientation(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ?
|
binding.fabLayout.setOrientation(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ?
|
||||||
LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
|
LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
|
||||||
rvContributionsList
|
rvContributionsList
|
||||||
.setLayoutManager(
|
.setLayoutManager(
|
||||||
|
|
@ -324,12 +316,12 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setListeners() {
|
private void setListeners() {
|
||||||
fabPlus.setOnClickListener(view -> animateFAB(isFabOpen));
|
binding.fabPlus.setOnClickListener(view -> animateFAB(isFabOpen));
|
||||||
fabCamera.setOnClickListener(view -> {
|
binding.fabCamera.setOnClickListener(view -> {
|
||||||
controller.initiateCameraPick(getActivity(), inAppCameraLocationPermissionLauncher);
|
controller.initiateCameraPick(getActivity(), inAppCameraLocationPermissionLauncher);
|
||||||
animateFAB(isFabOpen);
|
animateFAB(isFabOpen);
|
||||||
});
|
});
|
||||||
fabGallery.setOnClickListener(view -> {
|
binding.fabGallery.setOnClickListener(view -> {
|
||||||
controller.initiateGalleryPick(getActivity(), true);
|
controller.initiateGalleryPick(getActivity(), true);
|
||||||
animateFAB(isFabOpen);
|
animateFAB(isFabOpen);
|
||||||
});
|
});
|
||||||
|
|
@ -338,8 +330,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
/**
|
/**
|
||||||
* Launch Custom Selector.
|
* Launch Custom Selector.
|
||||||
*/
|
*/
|
||||||
@OnClick(R.id.fab_custom_gallery)
|
protected void launchCustomSelector() {
|
||||||
void launchCustomSelector() {
|
|
||||||
controller.initiateCustomGalleryPickWithPermission(getActivity());
|
controller.initiateCustomGalleryPickWithPermission(getActivity());
|
||||||
animateFAB(isFabOpen);
|
animateFAB(isFabOpen);
|
||||||
}
|
}
|
||||||
|
|
@ -350,23 +341,23 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
|
|
||||||
private void animateFAB(final boolean isFabOpen) {
|
private void animateFAB(final boolean isFabOpen) {
|
||||||
this.isFabOpen = !isFabOpen;
|
this.isFabOpen = !isFabOpen;
|
||||||
if (fabPlus.isShown()) {
|
if (binding.fabPlus.isShown()) {
|
||||||
if (isFabOpen) {
|
if (isFabOpen) {
|
||||||
fabPlus.startAnimation(rotate_backward);
|
binding.fabPlus.startAnimation(rotate_backward);
|
||||||
fabCamera.startAnimation(fab_close);
|
binding.fabCamera.startAnimation(fab_close);
|
||||||
fabGallery.startAnimation(fab_close);
|
binding.fabGallery.startAnimation(fab_close);
|
||||||
fabCustomGallery.startAnimation(fab_close);
|
binding.fabCustomGallery.startAnimation(fab_close);
|
||||||
fabCamera.hide();
|
binding.fabCamera.hide();
|
||||||
fabGallery.hide();
|
binding.fabGallery.hide();
|
||||||
fabCustomGallery.hide();
|
binding.fabCustomGallery.hide();
|
||||||
} else {
|
} else {
|
||||||
fabPlus.startAnimation(rotate_forward);
|
binding.fabPlus.startAnimation(rotate_forward);
|
||||||
fabCamera.startAnimation(fab_open);
|
binding.fabCamera.startAnimation(fab_open);
|
||||||
fabGallery.startAnimation(fab_open);
|
binding.fabGallery.startAnimation(fab_open);
|
||||||
fabCustomGallery.startAnimation(fab_open);
|
binding.fabCustomGallery.startAnimation(fab_open);
|
||||||
fabCamera.show();
|
binding.fabCamera.show();
|
||||||
fabGallery.show();
|
binding.fabGallery.show();
|
||||||
fabCustomGallery.show();
|
binding.fabCustomGallery.show();
|
||||||
}
|
}
|
||||||
this.isFabOpen = !isFabOpen;
|
this.isFabOpen = !isFabOpen;
|
||||||
}
|
}
|
||||||
|
|
@ -377,7 +368,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void showWelcomeTip(final boolean shouldShow) {
|
public void showWelcomeTip(final boolean shouldShow) {
|
||||||
noContributionsYet.setVisibility(shouldShow ? VISIBLE : GONE);
|
binding.noContributionsYet.setVisibility(shouldShow ? VISIBLE : GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -387,12 +378,12 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void showProgress(final boolean shouldShow) {
|
public void showProgress(final boolean shouldShow) {
|
||||||
progressBar.setVisibility(shouldShow ? VISIBLE : GONE);
|
binding.loadingContributionsProgressBar.setVisibility(shouldShow ? VISIBLE : GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showNoContributionsUI(final boolean shouldShow) {
|
public void showNoContributionsUI(final boolean shouldShow) {
|
||||||
noContributionsYet.setVisibility(shouldShow ? VISIBLE : GONE);
|
binding.noContributionsYet.setVisibility(shouldShow ? VISIBLE : GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,11 @@
|
||||||
package fr.free.nrw.commons.contributions
|
package fr.free.nrw.commons.contributions
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.view.LayoutInflater
|
import androidx.fragment.app.testing.FragmentScenario
|
||||||
import android.widget.LinearLayout
|
import androidx.fragment.app.testing.launchFragmentInContainer
|
||||||
import android.widget.ProgressBar
|
import androidx.lifecycle.Lifecycle
|
||||||
import android.widget.TextView
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.fragment.app.FragmentManager
|
|
||||||
import androidx.fragment.app.FragmentTransaction
|
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import androidx.test.core.app.ApplicationProvider
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.TestAppAdapter
|
import fr.free.nrw.commons.TestAppAdapter
|
||||||
|
|
@ -23,113 +16,48 @@ import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.ArgumentMatchers.anyInt
|
import org.mockito.ArgumentMatchers.anyInt
|
||||||
import org.mockito.Mock
|
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
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
|
||||||
import org.robolectric.annotation.Config
|
import org.robolectric.annotation.Config
|
||||||
import org.robolectric.annotation.LooperMode
|
import org.robolectric.annotation.LooperMode
|
||||||
import org.wikipedia.AppAdapter
|
import org.wikipedia.AppAdapter
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import org.mockito.Mockito.mock
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@Config(sdk = [21], application = TestCommonsApplication::class)
|
@Config(sdk = [21], application = TestCommonsApplication::class)
|
||||||
@LooperMode(LooperMode.Mode.PAUSED)
|
@LooperMode(LooperMode.Mode.PAUSED)
|
||||||
class ContributionsListFragmentUnitTests {
|
class ContributionsListFragmentUnitTests {
|
||||||
|
|
||||||
private lateinit var activity: MainActivity
|
private lateinit var scenario: FragmentScenario<ContributionsListFragment>
|
||||||
private lateinit var fragment: ContributionsListFragment
|
private lateinit var fragment: ContributionsListFragment
|
||||||
private lateinit var context: Context
|
|
||||||
private lateinit var layoutInflater: LayoutInflater
|
|
||||||
|
|
||||||
@Mock
|
private val adapter: ContributionsListAdapter = mock()
|
||||||
private lateinit var savedInstanceState: Bundle
|
private val contribution: Contribution = mock()
|
||||||
|
private val media: Media = mock()
|
||||||
@Mock
|
private val wikidataPlace: WikidataPlace = mock()
|
||||||
private lateinit var rvContributionsList: RecyclerView
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var adapter: ContributionsListAdapter
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var contribution: Contribution
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var media: Media
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var wikidataPlace: WikidataPlace
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var callback: ContributionsListFragment.Callback
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var layoutManager: RecyclerView.LayoutManager
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var gridLayoutManager: GridLayoutManager
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var noContributionsYet: TextView
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var progressBar: ProgressBar
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var fabPlus: FloatingActionButton
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var fabCamera: FloatingActionButton
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var fabGallery: FloatingActionButton
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var fabCustomGallery: FloatingActionButton
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var newConfig: Configuration
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var fabLayout: LinearLayout
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var contributionsListPresenter: ContributionsListPresenter
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
|
||||||
AppAdapter.set(TestAppAdapter())
|
AppAdapter.set(TestAppAdapter())
|
||||||
|
|
||||||
context = ApplicationProvider.getApplicationContext()
|
scenario = launchFragmentInContainer(
|
||||||
activity = Robolectric.buildActivity(MainActivity::class.java).create().get()
|
initialState = Lifecycle.State.RESUMED,
|
||||||
layoutInflater = LayoutInflater.from(activity)
|
themeResId = R.style.LightAppTheme
|
||||||
|
) {
|
||||||
|
ContributionsListFragment().apply {
|
||||||
|
contributionsListPresenter = mock()
|
||||||
|
callback = mock()
|
||||||
|
}.also {
|
||||||
|
fragment = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fragment = ContributionsListFragment()
|
scenario.onFragment {
|
||||||
val fragmentManager: FragmentManager = activity.supportFragmentManager
|
it.adapter = adapter
|
||||||
val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction()
|
}
|
||||||
fragmentTransaction.add(fragment, null)
|
|
||||||
fragmentTransaction.commit()
|
|
||||||
|
|
||||||
Whitebox.setInternalState(fragment, "rvContributionsList", rvContributionsList)
|
|
||||||
Whitebox.setInternalState(fragment, "adapter", adapter)
|
|
||||||
Whitebox.setInternalState(fragment, "callback", callback)
|
|
||||||
Whitebox.setInternalState(fragment, "noContributionsYet", noContributionsYet)
|
|
||||||
Whitebox.setInternalState(fragment, "progressBar", progressBar)
|
|
||||||
Whitebox.setInternalState(fragment, "fabPlus", fabPlus)
|
|
||||||
Whitebox.setInternalState(fragment, "fabCamera", fabCamera)
|
|
||||||
Whitebox.setInternalState(fragment, "fabGallery", fabGallery)
|
|
||||||
Whitebox.setInternalState(fragment, "fabCustomGallery", fabCustomGallery)
|
|
||||||
Whitebox.setInternalState(fragment, "fab_layout", fabLayout)
|
|
||||||
Whitebox.setInternalState(
|
|
||||||
fragment,
|
|
||||||
"contributionsListPresenter",
|
|
||||||
contributionsListPresenter
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -139,13 +67,6 @@ class ContributionsListFragmentUnitTests {
|
||||||
Assert.assertNotNull(fragment)
|
Assert.assertNotNull(fragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@Throws(Exception::class)
|
|
||||||
fun testOnCreateView() {
|
|
||||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
|
||||||
fragment.onCreateView(layoutInflater, null, savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testOnDetach() {
|
fun testOnDetach() {
|
||||||
|
|
@ -165,8 +86,9 @@ class ContributionsListFragmentUnitTests {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testOnScrollToTop() {
|
fun testOnScrollToTop() {
|
||||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||||
|
fragment.rvContributionsList = mock()
|
||||||
fragment.scrollToTop()
|
fragment.scrollToTop()
|
||||||
verify(rvContributionsList).smoothScrollToPosition(0)
|
verify(fragment.rvContributionsList).smoothScrollToPosition(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -261,16 +183,14 @@ class ContributionsListFragmentUnitTests {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testOnViewStateRestored() {
|
fun testOnViewStateRestored() {
|
||||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||||
`when`(rvContributionsList.layoutManager).thenReturn(layoutManager)
|
fragment.onViewStateRestored(mock())
|
||||||
fragment.onViewStateRestored(savedInstanceState)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testOnSaveInstanceState() {
|
fun testOnSaveInstanceState() {
|
||||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||||
`when`(rvContributionsList.layoutManager).thenReturn(gridLayoutManager)
|
fragment.onSaveInstanceState(mock())
|
||||||
fragment.onSaveInstanceState(savedInstanceState)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -298,7 +218,9 @@ class ContributionsListFragmentUnitTests {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testAnimateFAB() {
|
fun testAnimateFAB() {
|
||||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||||
`when`(fabPlus.isShown).thenReturn(false)
|
scenario.onFragment {
|
||||||
|
it.requireView().findViewById<FloatingActionButton>(R.id.fab_plus).hide()
|
||||||
|
}
|
||||||
val method: Method = ContributionsListFragment::class.java.getDeclaredMethod(
|
val method: Method = ContributionsListFragment::class.java.getDeclaredMethod(
|
||||||
"animateFAB",
|
"animateFAB",
|
||||||
Boolean::class.java
|
Boolean::class.java
|
||||||
|
|
@ -311,7 +233,9 @@ class ContributionsListFragmentUnitTests {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testAnimateFABCaseShownAndOpen() {
|
fun testAnimateFABCaseShownAndOpen() {
|
||||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||||
`when`(fabPlus.isShown).thenReturn(true)
|
scenario.onFragment {
|
||||||
|
it.requireView().findViewById<FloatingActionButton>(R.id.fab_plus).show()
|
||||||
|
}
|
||||||
val method: Method = ContributionsListFragment::class.java.getDeclaredMethod(
|
val method: Method = ContributionsListFragment::class.java.getDeclaredMethod(
|
||||||
"animateFAB",
|
"animateFAB",
|
||||||
Boolean::class.java
|
Boolean::class.java
|
||||||
|
|
@ -324,7 +248,9 @@ class ContributionsListFragmentUnitTests {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testAnimateFABCaseShownAndClose() {
|
fun testAnimateFABCaseShownAndClose() {
|
||||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||||
`when`(fabPlus.isShown).thenReturn(true)
|
scenario.onFragment {
|
||||||
|
it.requireView().findViewById<FloatingActionButton>(R.id.fab_plus).show()
|
||||||
|
}
|
||||||
val method: Method = ContributionsListFragment::class.java.getDeclaredMethod(
|
val method: Method = ContributionsListFragment::class.java.getDeclaredMethod(
|
||||||
"animateFAB",
|
"animateFAB",
|
||||||
Boolean::class.java
|
Boolean::class.java
|
||||||
|
|
@ -359,8 +285,8 @@ class ContributionsListFragmentUnitTests {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testOnConfigurationChanged() {
|
fun testOnConfigurationChanged() {
|
||||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||||
|
val newConfig: Configuration = mock()
|
||||||
newConfig.orientation = Configuration.ORIENTATION_LANDSCAPE
|
newConfig.orientation = Configuration.ORIENTATION_LANDSCAPE
|
||||||
fragment.onConfigurationChanged(newConfig)
|
fragment.onConfigurationChanged(newConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +78,6 @@ dependencies {
|
||||||
implementation "io.reactivex.rxjava2:rxjava:2.2.3"
|
implementation "io.reactivex.rxjava2:rxjava:2.2.3"
|
||||||
implementation "io.reactivex.rxjava2:rxandroid:2.1.0"
|
implementation "io.reactivex.rxjava2:rxandroid:2.1.0"
|
||||||
implementation 'org.apache.commons:commons-lang3:3.8.1'
|
implementation 'org.apache.commons:commons-lang3:3.8.1'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
|
||||||
|
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||||
|
|
||||||
|
|
@ -88,6 +87,15 @@ dependencies {
|
||||||
testImplementation 'org.hamcrest:hamcrest-junit:2.0.0.0'
|
testImplementation 'org.hamcrest:hamcrest-junit:2.0.0.0'
|
||||||
testImplementation "com.squareup.okhttp3:mockwebserver:4.10.0"
|
testImplementation "com.squareup.okhttp3:mockwebserver:4.10.0"
|
||||||
testImplementation "commons-io:commons-io:2.6"
|
testImplementation "commons-io:commons-io:2.6"
|
||||||
|
|
||||||
|
constraints {
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
|
||||||
|
because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
|
||||||
|
}
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
|
||||||
|
because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue