11/*
22 * Nextcloud - Android Client
33 *
4+ * SPDX-FileCopyrightText: 2025 Philipp Hasper <vcs@hasper.info>
45 * SPDX-FileCopyrightText: 2025 Alper Ozturk <alper.ozturk@nextcloud.com>
56 * SPDX-FileCopyrightText: 2022 Tobias Kaminsky <tobias@kaminsky.me>
67 * SPDX-FileCopyrightText: 2022 Nextcloud GmbH
78 * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
89 */
910package com.owncloud.android.ui.activity
1011
12+ import android.content.Intent
13+ import android.net.Uri
14+ import android.view.KeyEvent
1115import androidx.test.core.app.launchActivity
1216import androidx.test.espresso.Espresso.onView
17+ import androidx.test.espresso.action.ViewActions
1318import androidx.test.espresso.assertion.ViewAssertions.matches
19+ import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
1420import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
21+ import androidx.test.espresso.matcher.ViewMatchers.isEnabled
1522import androidx.test.espresso.matcher.ViewMatchers.isRoot
23+ import androidx.test.espresso.matcher.ViewMatchers.withId
24+ import androidx.test.espresso.matcher.ViewMatchers.withText
1625import com.facebook.testing.screenshot.internal.TestNameDetector
26+ import com.nextcloud.client.preferences.AppPreferencesImpl
27+ import com.nextcloud.test.GrantStoragePermissionRule
28+ import com.nextcloud.test.withSelectedText
29+ import com.nextcloud.utils.extensions.removeFileExtension
1730import com.owncloud.android.AbstractIT
31+ import com.owncloud.android.R
32+ import com.owncloud.android.datamodel.OCFile
1833import com.owncloud.android.utils.ScreenshotTest
34+ import org.junit.Rule
1935import org.junit.Test
36+ import org.junit.rules.TestRule
37+ import java.io.File
2038
2139class ReceiveExternalFilesActivityIT : AbstractIT () {
2240
41+ @get:Rule
42+ var storagePermissionRule: TestRule = GrantStoragePermissionRule .grant()
43+
2344 @Test
2445 @ScreenshotTest
2546 fun open () {
@@ -41,4 +62,72 @@ class ReceiveExternalFilesActivityIT : AbstractIT() {
4162 open()
4263 removeAccount(secondAccount)
4364 }
65+
66+
67+ fun createSendIntent (file : File ): Intent = Intent (targetContext, ReceiveExternalFilesActivity ::class .java).apply {
68+ action = Intent .ACTION_SEND
69+ addFlags(Intent .FLAG_GRANT_READ_URI_PERMISSION )
70+ putExtra(Intent .EXTRA_STREAM , Uri .fromFile(file))
71+ }
72+
73+ @Test
74+ fun renameSingleFileUpload () {
75+ val imageFile = getDummyFile(" image.jpg" )
76+ val intent = createSendIntent(imageFile)
77+
78+ // Create folders with the necessary permissions
79+ val mainFolder = OCFile (" /folder/" ).apply {
80+ permissions = OCFile .PERMISSION_CAN_CREATE_FILE_AND_FOLDER
81+ setFolder()
82+ fileDataStorageManager.saveNewFile(this )
83+ }
84+ val subFolder = OCFile (" ${mainFolder.remotePath} sub folder/" ).apply {
85+ permissions = OCFile .PERMISSION_CAN_CREATE_FILE_AND_FOLDER
86+ setFolder()
87+ fileDataStorageManager.saveNewFile(this )
88+ }
89+
90+ // Store the folder in preferences, so the activity starts from there.
91+ @Suppress(" DEPRECATION" )
92+ val preferences = AppPreferencesImpl .fromContext(targetContext)
93+ preferences.setLastUploadPath(mainFolder.remotePath)
94+
95+ launchActivity<ReceiveExternalFilesActivity >(intent).use {
96+ val expectedMainFolderTitle = (getCurrentActivity() as ToolbarActivity ).getActionBarTitle(mainFolder, false )
97+ // Verify that the test starts in the expected folder. If this fails, change the setup calls above
98+ onView(withId(R .id.toolbar))
99+ .check(matches(hasDescendant(withText(expectedMainFolderTitle))))
100+
101+ onView(withText(R .string.uploader_btn_upload_text))
102+ .check(matches(isDisplayed()))
103+ .check(matches(isEnabled()))
104+
105+ // Test the pre-selection behavior (filename, but without extension, shall be selected)
106+ onView(withId(R .id.user_input))
107+ .check(matches(withText(imageFile.name)))
108+ .perform(ViewActions .click())
109+ .check(matches(withSelectedText(imageFile.name.removeFileExtension())))
110+
111+ // Set a new file name
112+ val secondFileName = " New filename.jpg"
113+ onView(withId(R .id.user_input))
114+ .perform(ViewActions .typeTextIntoFocusedView(secondFileName.removeFileExtension()))
115+ .check(matches(withText(secondFileName)))
116+ // Leave the field and come back to verify the pre-selection behavior correctly handles the new name
117+ .perform(ViewActions .pressKey(KeyEvent .KEYCODE_TAB ))
118+ .perform(ViewActions .click())
119+ .check(matches(withSelectedText(secondFileName.removeFileExtension())))
120+
121+ // Set a file name without file extension
122+ val thirdFileName = " No extension"
123+ onView(withId(R .id.user_input))
124+ .perform(ViewActions .clearText())
125+ .perform(ViewActions .typeTextIntoFocusedView(thirdFileName))
126+ .check(matches(withText(thirdFileName)))
127+ // Leave the field and come back to verify the pre-selection behavior correctly handles the new name
128+ .perform(ViewActions .pressKey(KeyEvent .KEYCODE_TAB ))
129+ .perform(ViewActions .click())
130+ .check(matches(withSelectedText(thirdFileName)))
131+ }
132+ }
44133}
0 commit comments