diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_empty.png b/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_empty.png new file mode 100644 index 0000000000..a6cc83d798 Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_empty.png differ diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_error.png b/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_error.png new file mode 100644 index 0000000000..c7b4040e3e Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_error.png differ diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_files.png b/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_files.png new file mode 100644 index 0000000000..3c55eebfc2 Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_files.png differ diff --git a/src/androidTest/java/com/owncloud/android/ui/trashbin/TrashbinActivityIT.kt b/src/androidTest/java/com/owncloud/android/ui/trashbin/TrashbinActivityIT.kt new file mode 100644 index 0000000000..fe96b68ded --- /dev/null +++ b/src/androidTest/java/com/owncloud/android/ui/trashbin/TrashbinActivityIT.kt @@ -0,0 +1,86 @@ +/* + * + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2020 Tobias Kaminsky + * Copyright (C) 2020 Nextcloud GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.owncloud.android.ui.trashbin + +import androidx.test.espresso.intent.rule.IntentsTestRule +import com.facebook.testing.screenshot.Screenshot +import com.owncloud.android.AbstractIT +import com.owncloud.android.utils.ScreenshotTest +import org.junit.Rule +import org.junit.Test + +class TrashbinActivityIT : AbstractIT() { + enum class TestCase { + ERROR, EMPTY, FILES + } + + @get:Rule + var activityRule = IntentsTestRule(TrashbinActivity::class.java, true, false) + + @Test + @ScreenshotTest + fun error() { + val sut: TrashbinActivity = activityRule.launchActivity(null) + + val trashbinRepository = TrashbinLocalRepository(TestCase.ERROR) + + sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut) + + sut.runOnUiThread { sut.loadFolder() } + + shortSleep() + + Screenshot.snapActivity(sut).record() + } + + @Test + @ScreenshotTest + fun files() { + val sut: TrashbinActivity = activityRule.launchActivity(null) + + val trashbinRepository = TrashbinLocalRepository(TestCase.FILES) + + sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut) + + sut.runOnUiThread { sut.loadFolder() } + + shortSleep() + + Screenshot.snapActivity(sut).record() + } + + @Test + @ScreenshotTest + fun empty() { + val sut: TrashbinActivity = activityRule.launchActivity(null) + + val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY) + + sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut) + + sut.runOnUiThread { sut.loadFolder() } + + shortSleep() + + Screenshot.snapActivity(sut).record() + } +} diff --git a/src/androidTest/java/com/owncloud/android/ui/trashbin/TrashbinLocalRepository.kt b/src/androidTest/java/com/owncloud/android/ui/trashbin/TrashbinLocalRepository.kt new file mode 100644 index 0000000000..c0c42c0aff --- /dev/null +++ b/src/androidTest/java/com/owncloud/android/ui/trashbin/TrashbinLocalRepository.kt @@ -0,0 +1,84 @@ +/* + * + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2020 Tobias Kaminsky + * Copyright (C) 2020 Nextcloud GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.ui.trashbin + +import com.owncloud.android.R +import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile +import com.owncloud.android.ui.trashbin.TrashbinRepository.LoadFolderCallback + +class TrashbinLocalRepository(val testCase: TrashbinActivityIT.TestCase) : TrashbinRepository { + override fun emptyTrashbin(callback: TrashbinRepository.OperationCallback?) { + TODO("Not yet implemented") + } + + override fun restoreFile(file: TrashbinFile?, callback: TrashbinRepository.OperationCallback?) { + TODO("Not yet implemented") + } + + override fun removeTrashbinFile(file: TrashbinFile?, callback: TrashbinRepository.OperationCallback?) { + TODO("Not yet implemented") + } + + @Suppress("MagicNumber") + override fun getFolder(remotePath: String?, callback: LoadFolderCallback?) { + when (testCase) { + TrashbinActivityIT.TestCase.ERROR -> callback?.onError(R.string.trashbin_loading_failed) + TrashbinActivityIT.TestCase.FILES -> { + val files = ArrayList() + files.add( + TrashbinFile( + "test.md", + "text/markdown", + "/trashbin/test.md", + "subFolder/test.md", + 1395847838, // random date + 1395847908 // random date + ) + ) + files.add( + TrashbinFile( + "image.jpg", + "image/jpeg", + "/trashbin/image.jpg", + "image.jpg", + 1395841858, // random date + 1395837858 // random date + ) + ) + files.add( + TrashbinFile( + "folder", + "DIR", + "/trashbin/folder/", + "folder", + 1395347858, // random date + 1395849858 // random date + ) + ) + + callback?.onSuccess(files) + } + TrashbinActivityIT.TestCase.EMPTY -> callback?.onSuccess(ArrayList()) + } + } +} diff --git a/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java b/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java index b48d3d33f6..c4ff7b9749 100644 --- a/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java +++ b/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java @@ -28,11 +28,9 @@ import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.ImageView; import android.widget.PopupMenu; import android.widget.TextView; -import com.google.android.material.button.MaterialButton; import com.google.android.material.snackbar.Snackbar; import com.nextcloud.client.account.CurrentAccountProvider; import com.nextcloud.client.account.User; @@ -40,6 +38,7 @@ import com.nextcloud.client.di.Injectable; import com.nextcloud.client.network.ClientFactory; import com.nextcloud.client.preferences.AppPreferences; import com.owncloud.android.R; +import com.owncloud.android.databinding.TrashbinActivityBinding; import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile; import com.owncloud.android.ui.EmptyRecyclerView; import com.owncloud.android.ui.activity.FileActivity; @@ -55,13 +54,9 @@ import java.util.List; import javax.inject.Inject; +import androidx.annotation.VisibleForTesting; import androidx.core.content.res.ResourcesCompat; import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import butterknife.BindString; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.Unbinder; import static com.owncloud.android.utils.DisplayUtils.openSortingOrderDialogFragment; @@ -74,44 +69,16 @@ public class TrashbinActivity extends FileActivity implements TrashbinContract.View, Injectable { - @BindView(R.id.empty_list_progress) - public View emptyListProgress; - - @BindView(R.id.empty_list_view) - public View emptyListView; - - @BindView(R.id.empty_list_view_text) - public TextView emptyContentMessage; - - @BindView(R.id.empty_list_view_headline) - public TextView emptyContentHeadline; - - @BindView(R.id.empty_list_icon) - public ImageView emptyContentIcon; - - @BindView(android.R.id.list) - public EmptyRecyclerView recyclerView; - - @BindView(R.id.swipe_containing_list) - public SwipeRefreshLayout swipeListRefreshLayout; - - @BindView(R.id.sort_button) - public MaterialButton sortButton; - - @BindString(R.string.trashbin_empty_headline) - public String noResultsHeadline; - - @BindString(R.string.trashbin_empty_message) - public String noResultsMessage; - @Inject AppPreferences preferences; @Inject CurrentAccountProvider accountProvider; @Inject ClientFactory clientFactory; - private Unbinder unbinder; private TrashbinListAdapter trashbinListAdapter; - private TrashbinPresenter trashbinPresenter; + + @VisibleForTesting + TrashbinPresenter trashbinPresenter; private boolean active; + private TrashbinActivityBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { @@ -119,8 +86,10 @@ public class TrashbinActivity extends FileActivity implements final User user = accountProvider.getUser(); final RemoteTrashbinRepository trashRepository = new RemoteTrashbinRepository(user, clientFactory); trashbinPresenter = new TrashbinPresenter(trashRepository, this); - setContentView(R.layout.trashbin_activity); - unbinder = ButterKnife.bind(this); + + binding = TrashbinActivityBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + setupToolbar(); findViewById(R.id.sort_list_button_group).setVisibility(View.VISIBLE); findViewById(R.id.switch_grid_view_button).setVisibility(View.GONE); @@ -136,14 +105,14 @@ public class TrashbinActivity extends FileActivity implements } private void setupContent() { - recyclerView = findViewById(android.R.id.list); - recyclerView.setEmptyView(emptyListView); - emptyListView.setVisibility(View.GONE); - emptyContentIcon.setImageResource(R.drawable.ic_delete); - emptyContentIcon.setVisibility(View.VISIBLE); - emptyContentHeadline.setText(noResultsHeadline); - emptyContentMessage.setText(noResultsMessage); - emptyContentMessage.setVisibility(View.VISIBLE); + EmptyRecyclerView recyclerView = binding.list; + recyclerView.setEmptyView(binding.emptyList.emptyListView); + binding.emptyList.emptyListView.setVisibility(View.GONE); + binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_delete); + binding.emptyList.emptyListIcon.setVisibility(View.VISIBLE); + binding.emptyList.emptyListViewHeadline.setText(getString(R.string.trashbin_empty_headline)); + binding.emptyList.emptyListViewText.setText(getString(R.string.trashbin_empty_message)); + binding.emptyList.emptyListViewText.setVisibility(View.VISIBLE); trashbinListAdapter = new TrashbinListAdapter( this, @@ -157,21 +126,21 @@ public class TrashbinActivity extends FileActivity implements recyclerView.setHasFooter(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); - ThemeUtils.colorSwipeRefreshLayout(this, swipeListRefreshLayout); - swipeListRefreshLayout.setOnRefreshListener(this::loadFolder); + ThemeUtils.colorSwipeRefreshLayout(this, binding.swipeContainingList); + binding.swipeContainingList.setOnRefreshListener(this::loadFolder); - sortButton.setOnClickListener(l -> - openSortingOrderDialogFragment(getSupportFragmentManager(), - preferences.getSortOrderByType( - FileSortOrder.Type.trashBinView, - FileSortOrder.sort_new_to_old)) - ); + findViewById(R.id.sort_button).setOnClickListener(l -> + openSortingOrderDialogFragment(getSupportFragmentManager(), + preferences.getSortOrderByType( + FileSortOrder.Type.trashBinView, + FileSortOrder.sort_new_to_old)) + ); loadFolder(); } - private void loadFolder() { - swipeListRefreshLayout.setRefreshing(true); + protected void loadFolder() { + binding.swipeContainingList.setRefreshing(true); trashbinPresenter.loadFolder(); } @@ -209,12 +178,6 @@ public class TrashbinActivity extends FileActivity implements return retval; } - @Override - public void onDestroy() { - super.onDestroy(); - unbinder.unbind(); - } - @Override public void onOverflowIconClicked(TrashbinFile file, View view) { PopupMenu popup = new PopupMenu(this, view); @@ -273,6 +236,7 @@ public class TrashbinActivity extends FileActivity implements @Override public void onSortingOrderChosen(FileSortOrder sortOrder) { + TextView sortButton = findViewById(R.id.sort_button); sortButton.setText(DisplayUtils.getSortOrderStringId(sortOrder)); trashbinListAdapter.setSortOrder(sortOrder); } @@ -281,8 +245,8 @@ public class TrashbinActivity extends FileActivity implements public void showTrashbinFolder(List trashbinFiles) { if (active) { trashbinListAdapter.setTrashbinFiles(trashbinFiles, true); - swipeListRefreshLayout.setRefreshing(false); - emptyListProgress.setVisibility(View.GONE); + binding.swipeContainingList.setRefreshing(false); + binding.emptyList.emptyListProgress.setVisibility(View.GONE); } } @@ -301,8 +265,9 @@ public class TrashbinActivity extends FileActivity implements @Override public void showSnackbarError(int message, TrashbinFile file) { if (active) { - swipeListRefreshLayout.setRefreshing(false); - Snackbar.make(recyclerView, String.format(getString(message), file.getFileName()), Snackbar.LENGTH_LONG) + binding.swipeContainingList.setRefreshing(false); + Snackbar.make(binding.list, + String.format(getString(message), file.getFileName()), Snackbar.LENGTH_LONG) .show(); } } @@ -310,20 +275,17 @@ public class TrashbinActivity extends FileActivity implements @Override public void showError(int message) { if (active) { - swipeListRefreshLayout.setRefreshing(false); + binding.swipeContainingList.setRefreshing(false); - if (emptyContentMessage != null) { - emptyContentHeadline.setText(R.string.common_error); - emptyContentIcon.setImageDrawable(ResourcesCompat.getDrawable(getResources(), - R.drawable.ic_list_empty_error, - null)); - emptyContentMessage.setText(message); - - emptyContentMessage.setVisibility(View.VISIBLE); - emptyContentIcon.setVisibility(View.VISIBLE); - emptyListView.setVisibility(View.VISIBLE); - emptyListProgress.setVisibility(View.GONE); - } + binding.emptyList.emptyListViewHeadline.setText(R.string.common_error); + binding.emptyList.emptyListIcon.setImageDrawable(ResourcesCompat.getDrawable(getResources(), + R.drawable.ic_list_empty_error, + null)); + binding.emptyList.emptyListViewText.setText(message); + binding.emptyList.emptyListViewText.setVisibility(View.VISIBLE); + binding.emptyList.emptyListIcon.setVisibility(View.VISIBLE); + binding.emptyList.emptyListView.setVisibility(View.VISIBLE); + binding.emptyList.emptyListProgress.setVisibility(View.GONE); } } } diff --git a/src/main/res/layout/trashbin_activity.xml b/src/main/res/layout/trashbin_activity.xml index 91661aa89a..f974e52ca0 100644 --- a/src/main/res/layout/trashbin_activity.xml +++ b/src/main/res/layout/trashbin_activity.xml @@ -33,13 +33,15 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + + android:layout_below="@id/toolbar_standard_include"> + android:layout_height="match_parent" /> - +