diff --git a/tests/acceptance/TestHelpers/TusClient.php b/tests/acceptance/TestHelpers/TusClient.php
new file mode 100644
index 00000000000..c02718ad9b4
--- /dev/null
+++ b/tests/acceptance/TestHelpers/TusClient.php
@@ -0,0 +1,138 @@
+<?php declare(strict_types=1);
+/**
+ * ownCloud
+ *
+ * @author Nabin Magar <nabin@jankaritech.com>
+ * @copyright Copyright (c) 2025 Nabin Magar nabin@jankaritech.com
+ *
+ * This code 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 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace TestHelpers;
+
+use Carbon\Carbon;
+use GuzzleHttp\Exception\ClientException;
+use GuzzleHttp\Exception\GuzzleException;
+use TusPhp\Exception\ConnectionException;
+use TusPhp\Exception\FileException;
+use Psr\Http\Message\ResponseInterface;
+use Symfony\Component\HttpFoundation\Response as HttpResponse;
+use TusPhp\Exception\TusException;
+use TusPhp\Tus\Client;
+
+/**
+ * A TUS client based on TusPhp\Tus\Client
+ */
+
+class TusClient extends Client {
+
+	/**
+	 * creates a resource with a post request and returns response.
+	 *
+	 * @param string $key
+	 * @param int $bytes
+	 *
+	 * @return ResponseInterface
+	 * @throws GuzzleException
+	 */
+	public function createWithUploadRR(string $key, int $bytes = -1): ResponseInterface {
+		$bytes = $bytes < 0 ? $this->fileSize : $bytes;
+		$headers = $this->headers + [
+				'Upload-Length' => $this->fileSize,
+				'Upload-Key' => $key,
+				'Upload-Checksum' => $this->getUploadChecksumHeader(),
+				'Upload-Metadata' => $this->getUploadMetadataHeader(),
+			];
+		$data = '';
+		if ($bytes > 0) {
+			$data = $this->getData(0, $bytes);
+
+			$headers += [
+				'Content-Type' => self::HEADER_CONTENT_TYPE,
+				'Content-Length' => \strlen($data),
+			];
+		}
+		if ($this->isPartial()) {
+			$headers += ['Upload-Concat' => 'partial'];
+		}
+		try {
+			$response = $this->getClient()->post(
+				$this->apiPath,
+				[
+				'body' => $data,
+				'headers' => $headers,
+				]
+			);
+		} catch (ClientException $e) {
+			$response = $e->getResponse();
+		}
+		if ($response->getStatusCode() === HttpResponse::HTTP_CREATED) {
+			$uploadLocation = current($response->getHeader('location'));
+			$this->getCache()->set(
+				$this->getKey(),
+				[
+					'location' => $uploadLocation,
+					'expires_at' => Carbon::now()->addSeconds(
+						$this->getCache()->getTtl()
+					)->format($this->getCache()::RFC_7231),
+				]
+			);
+		}
+		return $response;
+	}
+
+	/**
+	 * upload file and returns response.
+	 *
+	 * @param int $bytes
+	 *
+	 * @return ResponseInterface
+	 * @throws GuzzleException
+	 * @throws TusException | ConnectionException
+	 */
+	public function uploadRR(int $bytes = -1): ResponseInterface {
+		$bytes  = $bytes < 0 ? $this->getFileSize() : $bytes;
+		$offset = $this->partialOffset < 0 ? 0 : $this->partialOffset;
+		try {
+			// Check if this upload exists with HEAD request.
+			$offset = $this->sendHeadRequest();
+		} catch (FileException | ClientException $e) {
+			// Create a new upload.
+			$response = $this->createWithUploadRR($this->getKey(), 0);
+			if ($response->getStatusCode() !== HttpResponse::HTTP_CREATED) {
+				return $response;
+			}
+		}
+		$data = $this->getData($offset, $bytes);
+		$headers = $this->headers + [
+				'Content-Type' => self::HEADER_CONTENT_TYPE,
+				'Content-Length' => \strlen($data),
+				'Upload-Checksum' => $this->getUploadChecksumHeader(),
+			];
+		if ($this->isPartial()) {
+			$headers += ['Upload-Concat' => self::UPLOAD_TYPE_PARTIAL];
+		} else {
+			$headers += ['Upload-Offset' => $offset];
+		}
+		$response = $this->getClient()->patch(
+			$this->getUrl(),
+			[
+			'body' => $data,
+			'headers' => $headers,
+			]
+		);
+		return $response;
+	}
+}
diff --git a/tests/acceptance/bootstrap/SpacesTUSContext.php b/tests/acceptance/bootstrap/SpacesTUSContext.php
index a179244d7ef..b0a22257b5c 100644
--- a/tests/acceptance/bootstrap/SpacesTUSContext.php
+++ b/tests/acceptance/bootstrap/SpacesTUSContext.php
@@ -14,6 +14,7 @@
 use Behat\Gherkin\Node\TableNode;
 use GuzzleHttp\Exception\GuzzleException;
 use PHPUnit\Framework\Assert;
+use Psr\Http\Message\ResponseInterface;
 use TestHelpers\WebDavHelper;
 use TestHelpers\BehatHelper;
 use TestHelpers\GraphHelper;
@@ -68,8 +69,13 @@ public function userHasUploadedFileViaTusInSpace(
 		string $spaceName
 	): void {
 		$spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName);
-		$this->tusContext->uploadFileUsingTus($user, $source, $destination, $spaceId);
+		$response = $this->tusContext->uploadFileUsingTus($user, $source, $destination, $spaceId);
 		$this->featureContext->setLastUploadDeleteTime(\time());
+		$this->featureContext->theHTTPStatusCodeShouldBe(
+			["201", "204"],
+			"HTTP status code was not 201 or 204 while trying to upload file '$destination' for user '$user'",
+			$response
+		);
 	}
 
 	/**
@@ -91,8 +97,29 @@ public function userUploadsAFileViaTusInsideOfTheSpaceUsingTheWebdavApi(
 		string $spaceName
 	): void {
 		$spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName);
-		$this->tusContext->uploadFileUsingTus($user, $source, $destination, $spaceId);
+		$response = $this->tusContext->uploadFileUsingTus($user, $source, $destination, $spaceId);
 		$this->featureContext->setLastUploadDeleteTime(\time());
+		$this->featureContext->setResponse($response);
+	}
+
+	/**
+	 * @When the public uploads file :source to :destination via TUS inside last link shared folder with password :password using the WebDAV API
+	 *
+	 * @param string $source
+	 * @param string $destination
+	 * @param string $password
+	 *
+	 * @return void
+	 * @throws Exception|GuzzleException
+	 */
+	public function thePublicUploadsFileViaTusInsideLastSharedFolderWithPasswordUsingTheWebdavApi(
+		string $source,
+		string $destination,
+		string $password
+	): void {
+		$response = $this->tusContext->publicUploadFileUsingTus($source, $destination, $password);
+		$this->featureContext->setLastUploadDeleteTime(\time());
+		$this->featureContext->setResponse($response);
 	}
 
 	/**
@@ -149,24 +176,26 @@ public function userCreatesANewTusResourceForTheSpaceUsingTheWebdavApiWithTheseH
 	 * @param string $resource
 	 * @param string $spaceName
 	 *
-	 * @return void
+	 * @return ResponseInterface
 	 * @throws Exception|GuzzleException
 	 */
-	private function uploadFileViaTus(string $user, string $content, string $resource, string $spaceName): void {
+	private function uploadFileViaTus(
+		string $user,
+		string $content,
+		string $resource,
+		string $spaceName
+	): ResponseInterface {
 		$spaceId = $this->spacesContext->getSpaceIdByName($user, $spaceName);
 		$tmpFile = $this->tusContext->writeDataToTempFile($content);
-		try {
-			$this->tusContext->uploadFileUsingTus(
-				$user,
-				\basename($tmpFile),
-				$resource,
-				$spaceId
-			);
-			$this->featureContext->setLastUploadDeleteTime(\time());
-		} catch (Exception $e) {
-			Assert::assertStringContainsString('Unable to create resource', (string)$e);
-		}
+		$response = $this->tusContext->uploadFileUsingTus(
+			$user,
+			\basename($tmpFile),
+			$resource,
+			$spaceId
+		);
+		$this->featureContext->setLastUploadDeleteTime(\time());
 		\unlink($tmpFile);
+		return $response;
 	}
 
 	/**
@@ -189,7 +218,7 @@ public function userUploadsAFileWithContentToInsideFederatedShareViaTusUsingTheW
 		$remoteItemId = $this->spacesContext->getSharesRemoteItemId($user, $destination);
 		$remoteItemId = \rawurlencode($remoteItemId);
 		$tmpFile = $this->tusContext->writeDataToTempFile($content);
-		$this->tusContext->uploadFileUsingTus(
+		$response = $this->tusContext->uploadFileUsingTus(
 			$user,
 			\basename($tmpFile),
 			$file,
@@ -197,6 +226,7 @@ public function userUploadsAFileWithContentToInsideFederatedShareViaTusUsingTheW
 		);
 		$this->featureContext->setLastUploadDeleteTime(\time());
 		\unlink($tmpFile);
+		$this->featureContext->setResponse($response);
 	}
 
 	/**
@@ -216,7 +246,7 @@ public function userUploadsAFileWithContentToViaTusInsideOfTheSpaceUsingTheWebda
 		string $resource,
 		string $spaceName
 	): void {
-		$this->uploadFileViaTus($user, $content, $resource, $spaceName);
+		$this->featureContext->setResponse($this->uploadFileViaTus($user, $content, $resource, $spaceName));
 	}
 
 	/**
@@ -236,7 +266,12 @@ public function userHasUploadedAFileWithContentToViaTusInsideOfTheSpace(
 		string $resource,
 		string $spaceName
 	): void {
-		$this->uploadFileViaTus($user, $content, $resource, $spaceName);
+		$response = $this->uploadFileViaTus($user, $content, $resource, $spaceName);
+		$this->featureContext->theHTTPStatusCodeShouldBe(
+			["201", "204"],
+			"HTTP status code was not 201 or 204 while trying to upload file '$resource' for user '$user'",
+			$response
+		);
 	}
 
 	/**
@@ -282,7 +317,7 @@ public function userUploadsAFileToWithMtimeViaTusInsideOfTheSpaceUsingTheWebdavA
 		$mtime = new DateTime($mtime);
 		$mtime = $mtime->format('U');
 		$user = $this->featureContext->getActualUsername($user);
-		$this->tusContext->uploadFileUsingTus(
+		$response = $this->tusContext->uploadFileUsingTus(
 			$user,
 			$source,
 			$destination,
@@ -290,6 +325,7 @@ public function userUploadsAFileToWithMtimeViaTusInsideOfTheSpaceUsingTheWebdavA
 			['mtime' => $mtime]
 		);
 		$this->featureContext->setLastUploadDeleteTime(\time());
+		$this->featureContext->setResponse($response);
 	}
 
 	/**
diff --git a/tests/acceptance/bootstrap/TUSContext.php b/tests/acceptance/bootstrap/TUSContext.php
index 4d023a0e01c..7018220b291 100644
--- a/tests/acceptance/bootstrap/TUSContext.php
+++ b/tests/acceptance/bootstrap/TUSContext.php
@@ -32,6 +32,7 @@
 use TestHelpers\HttpRequestHelper;
 use TestHelpers\WebDavHelper;
 use TestHelpers\BehatHelper;
+use TestHelpers\TusClient;
 
 require_once 'bootstrap.php';
 
@@ -264,8 +265,18 @@ public function userUploadsUsingTusAFileTo(
 		int     $bytes = null,
 		string  $checksum = ''
 	): void {
-		$this->uploadFileUsingTus($user, $source, $destination, null, $uploadMetadata, $noOfChunks, $bytes, $checksum);
+		$response = $this->uploadFileUsingTus(
+			$user,
+			$source,
+			$destination,
+			null,
+			$uploadMetadata,
+			$noOfChunks,
+			$bytes,
+			$checksum
+		);
 		$this->featureContext->setLastUploadDeleteTime(\time());
+		$this->featureContext->setResponse($response);
 	}
 
 	/**
@@ -278,7 +289,7 @@ public function userUploadsUsingTusAFileTo(
 	 * @param integer $bytes
 	 * @param string $checksum
 	 *
-	 * @return void
+	 * @return ResponseInterface
 	 */
 	public function uploadFileUsingTus(
 		?string $user,
@@ -288,8 +299,8 @@ public function uploadFileUsingTus(
 		array   $uploadMetadata = [],
 		int     $noOfChunks = 1,
 		int     $bytes = null,
-		string  $checksum = ''
-	) {
+		string  $checksum = '',
+	): ResponseInterface {
 		$user = $this->featureContext->getActualUsername($user);
 		$password = $this->featureContext->getUserPassword($user);
 		$headers = [
@@ -309,41 +320,112 @@ public function uploadFileUsingTus(
 			$headers = \array_merge($headers, $checksumHeader);
 		}
 
-		$client = new Client(
-			$this->featureContext->getBaseUrl(),
-			[
-				'verify' => false,
-				'headers' => $headers
-			]
-		);
-
 		$davPathVersion = $this->featureContext->getDavPathVersion();
 		$suffixPath = $user;
 		if ($davPathVersion === WebDavHelper::DAV_VERSION_SPACES) {
 			$suffixPath = $spaceId ?: $this->featureContext->getPersonalSpaceIdForUser($user);
 		}
-
-		$client->setChecksumAlgorithm('sha1');
-		$client->setApiPath(WebDavHelper::getDavPath($davPathVersion, $suffixPath));
-		$client->setMetadata($uploadMetadata);
 		$sourceFile = $this->featureContext->acceptanceTestsDirLocation() . $source;
-		$client->setKey((string)rand())->file($sourceFile, $destination);
+
+		$client = $this->createTusClient(
+			$this->featureContext->getBaseUrl(),
+			$headers,
+			$sourceFile,
+			$destination,
+			WebDavHelper::getDavPath($davPathVersion, $suffixPath),
+			$uploadMetadata
+		);
+
 		$this->featureContext->pauseUploadDelete();
+		$response = null;
 
 		if ($bytes !== null) {
-			$client->file($sourceFile, $destination)->createWithUpload($client->getKey(), $bytes);
+			return $client->file($sourceFile, $destination)
+				->createWithUploadRR($client->getKey(), $bytes);
 		} elseif (\filesize($sourceFile) === 0) {
-			$client->file($sourceFile, $destination)->createWithUpload($client->getKey(), 0);
+			return $client->file($sourceFile, $destination)->createWithUploadRR($client->getKey(), 0);
 		} elseif ($noOfChunks === 1) {
-			$client->file($sourceFile, $destination)->upload();
+			return $client->file($sourceFile, $destination)->uploadRR();
 		} else {
 			$bytesPerChunk = (int)\ceil(\filesize($sourceFile) / $noOfChunks);
 			for ($i = 0; $i < $noOfChunks; $i++) {
-				$client->upload($bytesPerChunk);
+				$response = $client->uploadRR($bytesPerChunk);
 			}
+			return $response;
 		}
 	}
 
+	/**
+	 * @param string $source
+	 * @param string $destination
+	 * @param string $password
+	 *
+	 * @return ResponseInterface
+	 * @throws GuzzleException
+	 * @throws ReflectionException
+	 */
+	public function publicUploadFileUsingTus(
+		string $source,
+		string $destination,
+		string $password,
+	): ResponseInterface {
+		$password = $this->featureContext->getActualPassword($password);
+		if ($this->featureContext->isUsingSharingNG()) {
+			$token = $this->featureContext->shareNgGetLastCreatedLinkShareToken();
+		} else {
+			$token = $this->featureContext->getLastCreatedPublicShareToken();
+		}
+		$headers = [
+			'Authorization' => 'Basic ' . \base64_encode("public:$password"),
+		];
+		$sourceFile = $this->featureContext->acceptanceTestsDirLocation() . $source;
+		$url = WebdavHelper::getDavPath(WebDavHelper::DAV_VERSION_SPACES, $token, "public-files");
+		$client = $this->createTusClient(
+			$this->featureContext->getBaseUrl(),
+			$headers,
+			$sourceFile,
+			$destination,
+			$url
+		);
+		$response = $client->createWithUploadRR("", 0);
+		return $response;
+	}
+
+	/**
+	 * Creates the TusClient with API path, headers, metadata, upload key and checksum
+	 *
+	 * @param string $baseUrl
+	 * @param array $headers
+	 * @param string $sourceFile
+	 * @param string $destination
+	 * @param string $path
+	 * @param array $metadata
+	 *
+	 * @return TusClient
+	 * @throws ReflectionException
+	 */
+	private function createTusClient(
+		string $baseUrl,
+		array  $headers,
+		string $sourceFile,
+		string $destination,
+		string $path,
+		array $metadata = []
+	): TusClient {
+		$client = new TusClient(
+			$baseUrl,
+			[
+				'verify' => false,
+				'headers' => $headers,
+			]
+		);
+		$client->setApiPath($path);
+		$client->setMetadata($metadata);
+		$client->setChecksumAlgorithm('sha1');
+		$client->setKey((string)rand())->file($sourceFile, $destination);
+		return $client;
+	}
+
 	/**
 	 * @When user :user uploads file with content :content to :destination using the TUS protocol on the WebDAV API
 	 *
diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
index 167aa7967d1..b39621ca7bf 100644
--- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
@@ -15,9 +15,9 @@ The expected failures in this file are from features in the owncloud/ocis repo.
 
 #### [PATCH request for TUS upload with wrong checksum gives incorrect response](https://github.com/owncloud/ocis/issues/1755)
 
-- [apiSpacesShares/shareUploadTUS.feature:283](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L283)
-- [apiSpacesShares/shareUploadTUS.feature:303](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L303)
-- [apiSpacesShares/shareUploadTUS.feature:384](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L384)
+- [apiSpacesShares/shareUploadTUS.feature:297](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L297)
+- [apiSpacesShares/shareUploadTUS.feature:317](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L317)
+- [apiSpacesShares/shareUploadTUS.feature:398](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L398)
 
 #### [Settings service user can list other peoples assignments](https://github.com/owncloud/ocis/issues/5032)
 
diff --git a/tests/acceptance/expected-failures-without-remotephp.md b/tests/acceptance/expected-failures-without-remotephp.md
index 6aefe6f9dec..0f48f327cbf 100644
--- a/tests/acceptance/expected-failures-without-remotephp.md
+++ b/tests/acceptance/expected-failures-without-remotephp.md
@@ -199,6 +199,9 @@
 - [apiSpaces/uploadSpaces.feature:115](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/uploadSpaces.feature#L115)
 - [apiSpaces/uploadSpaces.feature:132](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/uploadSpaces.feature#L132)
 - [apiSpacesShares/shareSpacesViaLink.feature:61](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareSpacesViaLink.feature#L61)
+- [apiSpacesShares/shareUploadTUS.feature:421](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L421)
+- [apiSpacesShares/shareUploadTUS.feature:438](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L438)
+- [apiSpacesShares/shareUploadTUS.feature:457](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L457)
 - [apiDepthInfinity/propfind.feature:74](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiDepthInfinity/propfind.feature#L74)
 - [apiDepthInfinity/propfind.feature:124](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiDepthInfinity/propfind.feature#L124)
 - [apiLocks/lockFiles.feature:490](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L490)
@@ -320,8 +323,8 @@
 
 #### [Cannot create new TUS upload resource using /webdav without remote.php - returns html instead](https://github.com/owncloud/ocis/issues/10346)
 
-- [apiSpaces/tusUpload.feature:60](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/tusUpload.feature#L60)
-- [apiSpaces/tusUpload.feature:104](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/tusUpload.feature#L104)
+- [apiSpaces/tusUpload.feature:63](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/tusUpload.feature#L63)
+- [apiSpaces/tusUpload.feature:110](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/tusUpload.feature#L110)
 - [coreApiWebdavUploadTUS/creationWithUploadExtension.feature:38](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavUploadTUS/creationWithUploadExtension.feature#L38)
 - [coreApiWebdavUploadTUS/uploadFile.feature:16](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavUploadTUS/uploadFile.feature#L16)
 - [coreApiWebdavUploadTUS/uploadFile.feature:17](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavUploadTUS/uploadFile.feature#L17)
diff --git a/tests/acceptance/features/apiOcm/share.feature b/tests/acceptance/features/apiOcm/share.feature
index 7107339ff8c..f4bc64b0125 100755
--- a/tests/acceptance/features/apiOcm/share.feature
+++ b/tests/acceptance/features/apiOcm/share.feature
@@ -932,6 +932,7 @@ Feature: an user shares resources using ScienceMesh application
       | permissionsRole | Editor   |
     When using server "REMOTE"
     And user "Brian" uploads a file with content "lorem" to "file.txt" inside federated share "FOLDER" via TUS using the WebDAV API
+    And the HTTP status code should be "204"
     Then for user "Brian" the content of file "file.txt" of federated share "FOLDER" should be "lorem"
 
   @issue-10285 @issue-10536
@@ -950,6 +951,7 @@ Feature: an user shares resources using ScienceMesh application
       | permissionsRole | Editor   |
     When using server "LOCAL"
     And user "Alice" uploads a file with content "lorem" to "file.txt" inside federated share "FOLDER" via TUS using the WebDAV API
+    And the HTTP status code should be "204"
     Then for user "Alice" the content of file "file.txt" of federated share "FOLDER" should be "lorem"
 
   @issue-10495
diff --git a/tests/acceptance/features/apiSpaces/tusUpload.feature b/tests/acceptance/features/apiSpaces/tusUpload.feature
index 34f561b841e..047a9cf6e96 100644
--- a/tests/acceptance/features/apiSpaces/tusUpload.feature
+++ b/tests/acceptance/features/apiSpaces/tusUpload.feature
@@ -14,7 +14,8 @@ Feature: upload resources using TUS protocol
   Scenario: upload a file within the set quota to a project space
     Given user "Alice" has created a space "Project Jupiter" of type "project" with quota "10000"
     When user "Alice" uploads a file with content "uploaded content" to "/upload.txt" via TUS inside of the space "Project Jupiter" using the WebDAV API
-    Then for user "Alice" the space "Project Jupiter" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" the space "Project Jupiter" should contain these entries:
       | upload.txt |
 
 
@@ -36,7 +37,8 @@ Feature: upload resources using TUS protocol
     Given user "Alice" has uploaded a file with content "uploaded content" to "/upload.txt" via TUS inside of the space "Alice Hansen"
     And user "Alice" has moved file "upload.txt" to "test.txt" in space "Alice Hansen"
     When user "Alice" uploads a file with content "uploaded content" to "/upload.txt" via TUS inside of the space "Alice Hansen" using the WebDAV API
-    Then for user "Alice" the space "Alice Hansen" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" the space "Alice Hansen" should contain these entries:
       | test.txt   |
       | upload.txt |
 
@@ -53,7 +55,8 @@ Feature: upload resources using TUS protocol
       | permissionsRole | Editor     |
     And user "Brian" has a share "testFolder" synced
     When user "Brian" uploads file "filesForUpload/zerobyte.txt" to "Shares/testFolder/textfile.txt" using the TUS protocol on the WebDAV API
-    Then the content of file "Shares/testFolder/textfile.txt" for user "Brian" should be ""
+    Then the HTTP status code should be "201"
+    And the content of file "Shares/testFolder/textfile.txt" for user "Brian" should be ""
     And the content of file "testFolder/textfile.txt" for user "Alice" should be ""
     Examples:
       | dav-path-version |
@@ -73,7 +76,8 @@ Feature: upload resources using TUS protocol
       | permissionsRole | Editor     |
     And user "Brian" has a share "testFolder" synced
     When user "Brian" uploads a file from "filesForUpload/zerobyte.txt" to "testFolder/textfile.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Brian" the content of the file "testFolder/textfile.txt" of the space "Shares" should be ""
+    Then the HTTP status code should be "201"
+    And for user "Brian" the content of the file "testFolder/textfile.txt" of the space "Shares" should be ""
     And for user "Alice" the content of the file "testFolder/textfile.txt" of the space "Personal" should be ""
 
 
@@ -82,7 +86,8 @@ Feature: upload resources using TUS protocol
     And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API
     And user "Alice" has created a space "new-space" with the default quota using the Graph API
     When user "Alice" uploads a file from "filesForUpload/zerobyte.txt" to "textfile.txt" via TUS inside of the space "new-space" using the WebDAV API
-    Then for user "Alice" the content of the file "textfile.txt" of the space "new-space" should be ""
+    Then the HTTP status code should be "201"
+    And for user "Alice" the content of the file "textfile.txt" of the space "new-space" should be ""
 
   @issue-8003 @issue-10346
   Scenario Outline: replace a shared file with zero-byte file
@@ -97,7 +102,8 @@ Feature: upload resources using TUS protocol
       | permissionsRole | File Editor  |
     And user "Brian" has a share "textfile.txt" synced
     When user "Brian" uploads file "filesForUpload/zerobyte.txt" to "Shares/textfile.txt" using the TUS protocol on the WebDAV API
-    Then the content of file "Shares/textfile.txt" for user "Brian" should be ""
+    Then the HTTP status code should be "201"
+    And the content of file "Shares/textfile.txt" for user "Brian" should be ""
     And the content of file "textfile.txt" for user "Alice" should be ""
     Examples:
       | dav-path-version |
@@ -117,7 +123,8 @@ Feature: upload resources using TUS protocol
       | permissionsRole | File Editor  |
     And user "Brian" has a share "textfile.txt" synced
     When user "Brian" uploads a file from "filesForUpload/zerobyte.txt" to "textfile.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Brian" the content of the file "textfile.txt" of the space "Shares" should be ""
+    Then the HTTP status code should be "201"
+    And for user "Brian" the content of the file "textfile.txt" of the space "Shares" should be ""
     And for user "Alice" the content of the file "textfile.txt" of the space "Personal" should be ""
 
   @issue-8003
@@ -127,7 +134,8 @@ Feature: upload resources using TUS protocol
     And user "Alice" has created a space "new-space" with the default quota using the Graph API
     And user "Alice" has uploaded a file inside space "new-space" with content "This is TUS upload" to "textfile.txt"
     When user "Alice" uploads a file from "filesForUpload/zerobyte.txt" to "textfile.txt" via TUS inside of the space "new-space" using the WebDAV API
-    Then for user "Alice" the content of the file "textfile.txt" of the space "new-space" should be ""
+    Then the HTTP status code should be "201"
+    And for user "Alice" the content of the file "textfile.txt" of the space "new-space" should be ""
 
   @issue-8003
   Scenario: replace a file inside a shared project space with zero-byte file
@@ -142,5 +150,6 @@ Feature: upload resources using TUS protocol
       | shareType       | user         |
       | permissionsRole | Space Editor |
     When user "Brian" uploads a file from "filesForUpload/zerobyte.txt" to "textfile.txt" via TUS inside of the space "new-space" using the WebDAV API
-    Then for user "Brian" the content of the file "textfile.txt" of the space "new-space" should be ""
+    Then the HTTP status code should be "201"
+    And for user "Brian" the content of the file "textfile.txt" of the space "new-space" should be ""
     And for user "Alice" the content of the file "textfile.txt" of the space "new-space" should be ""
diff --git a/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature b/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature
index e17dcc24e83..740c298e8a1 100644
--- a/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature
+++ b/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature
@@ -21,7 +21,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Editor   |
     And user "Brian" has a share "toShare" synced
     When user "Brian" uploads a file "filesForUpload/textfile.txt" to "toShare/file.txt" with mtime "Thu, 08 Aug 2012 04:18:13 GMT" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Brian" folder "toShare" of the space "Shares" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Brian" folder "toShare" of the space "Shares" should contain these entries:
       | file.txt |
     And as "Brian" the mtime of the file "/toShare/file.txt" in space "Shares" should be "Thu, 08 Aug 2012 04:18:13 GMT"
     And as "Alice" the mtime of the file "/toShare/file.txt" in space "Personal" should be "Thu, 08 Aug 2012 04:18:13 GMT"
@@ -37,7 +38,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Editor   |
     And user "Brian" has a share "toShare" synced
     When user "Alice" uploads a file "filesForUpload/textfile.txt" to "toShare/file.txt" with mtime "Thu, 08 Aug 2012 04:18:13 GMT" via TUS inside of the space "Personal" using the WebDAV API
-    Then for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
       | file.txt |
     And as "Alice" the mtime of the file "/toShare/file.txt" in space "Personal" should be "Thu, 08 Aug 2012 04:18:13 GMT"
     And as "Brian" the mtime of the file "/toShare/file.txt" in space "Shares" should be "Thu, 08 Aug 2012 04:18:13 GMT"
@@ -54,7 +56,8 @@ Feature: upload resources on share using TUS protocol
     And user "Brian" has a share "toShare" synced
     And user "Alice" has uploaded file with content "uploaded content" to "/toShare/file.txt"
     When user "Brian" uploads a file "filesForUpload/textfile.txt" to "toShare/file.txt" with mtime "Thu, 08 Aug 2012 04:18:13 GMT" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Brian" folder "toShare" of the space "Shares" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Brian" folder "toShare" of the space "Shares" should contain these entries:
       | file.txt |
     And as "Brian" the mtime of the file "/toShare/file.txt" in space "Shares" should be "Thu, 08 Aug 2012 04:18:13 GMT"
     And as "Alice" the mtime of the file "/toShare/file.txt" in space "Personal" should be "Thu, 08 Aug 2012 04:18:13 GMT"
@@ -71,7 +74,8 @@ Feature: upload resources on share using TUS protocol
     And user "Brian" has a share "toShare" synced
     And user "Brian" has uploaded a file inside space "Shares" with content "uploaded content" to "toShare/file.txt"
     When user "Alice" uploads a file "filesForUpload/textfile.txt" to "toShare/file.txt" with mtime "Thu, 08 Aug 2012 04:18:13 GMT" via TUS inside of the space "Personal" using the WebDAV API
-    Then for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
       | file.txt |
     And as "Alice" the mtime of the file "/toShare/file.txt" in space "Personal" should be "Thu, 08 Aug 2012 04:18:13 GMT"
     And as "Brian" the mtime of the file "/toShare/file.txt" in space "Shares" should be "Thu, 08 Aug 2012 04:18:13 GMT"
@@ -88,7 +92,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Editor   |
     And user "Brian" has a share "toShare" synced
     When user "Brian" uploads a file with content "uploaded content" to "/toShare/nonExistentFolder/file.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Brian" folder "toShare" of the space "Shares" should not contain these entries:
+    Then the HTTP status code should be "412"
+    And for user "Brian" folder "toShare" of the space "Shares" should not contain these entries:
       | nonExistentFolder |
 
 
@@ -103,7 +108,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Viewer   |
     And user "Brian" has a share "toShare" synced
     When user "Brian" uploads a file with content "uploaded content" to "/toShare/nonExistentFolder/file.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Brian" folder "toShare" of the space "Shares" should not contain these entries:
+    Then the HTTP status code should be "403"
+    And for user "Brian" folder "toShare" of the space "Shares" should not contain these entries:
       | nonExistentFolder |
 
 
@@ -117,7 +123,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Editor   |
     And user "Brian" has a share "toShare" synced
     When user "Brian" uploads a file with content "uploaded content" to "/toShare/file.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
       | file.txt |
     And for user "Alice" the content of the file "toShare/file.txt" of the space "Personal" should be "uploaded content"
 
@@ -132,7 +139,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Uploader |
     And user "Brian" has a share "toShare" synced
     When user "Brian" uploads a file with content "uploaded content" to "/toShare/file.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
       | file.txt |
     And for user "Alice" the content of the file "toShare/file.txt" of the space "Personal" should be "uploaded content"
 
@@ -149,7 +157,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Uploader |
     And user "Brian" has a share "toShare" synced
     When user "Brian" uploads a file with content "uploaded content" to "/toShare/file.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
       | file.txt |
     And for user "Alice" the content of the file "toShare/file.txt" of the space "Personal" should be "uploaded content"
 
@@ -165,7 +174,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Editor   |
     And user "Brian" has a share "toShare" synced
     When user "Brian" uploads a file with content "overwritten content" to "/toShare/file.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" folder "toShare" of the space "Personal" should contain these entries:
       | file.txt |
     And for user "Alice" the content of the file "toShare/file.txt" of the space "Personal" should be "overwritten content"
 
@@ -180,7 +190,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | Viewer   |
     And user "Brian" has a share "toShare" synced
     When user "Brian" uploads a file with content "uploaded content" to "/toShare/file.txt" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Brian" folder "toShare" of the space "Shares" should not contain these entries:
+    Then the HTTP status code should be "403"
+    And for user "Brian" folder "toShare" of the space "Shares" should not contain these entries:
       | file.txt |
 
 
@@ -220,7 +231,8 @@ Feature: upload resources on share using TUS protocol
       | Tus-Resumable   | 1.0.0                                 |
     And user "Alice" has uploaded file with checksum "SHA1 8cb2237d0679ca88db6464eac60da96345513964" to the last created TUS Location with offset "0" and content "12345" via TUS inside of the space "Personal" using the WebDAV API
     When user "Brian" downloads the file "/FOLDER/textFile.txt" of the space "Shares" using the WebDAV API
-    Then the header checksum should match "SHA1:8cb2237d0679ca88db6464eac60da96345513964"
+    Then the HTTP status code should be "200"
+    And the header checksum should match "SHA1:8cb2237d0679ca88db6464eac60da96345513964"
 
 
   Scenario: sharer shares a file with correct checksum should return the checksum in the propfind for sharee
@@ -257,7 +269,8 @@ Feature: upload resources on share using TUS protocol
       | permissionsRole | File Editor  |
     And user "Brian" has a share "textFile.txt" synced
     When user "Brian" downloads the file "/textFile.txt" of the space "Shares" using the WebDAV API
-    Then the header checksum should match "SHA1:8cb2237d0679ca88db6464eac60da96345513964"
+    Then the HTTP status code should be "200"
+    And the header checksum should match "SHA1:8cb2237d0679ca88db6464eac60da96345513964"
 
 
   Scenario: sharee uploads a file to a received share folder with correct checksum
@@ -269,13 +282,14 @@ Feature: upload resources on share using TUS protocol
       | shareType       | user     |
       | permissionsRole | Editor   |
     And user "Brian" has a share "FOLDER" synced
-    When user "Brian" creates a new TUS resource for the space "Shares" with content "" using the WebDAV API with these headers:
+    When user "Brian" creates a new TUS resource for the space "Shares" with content " " using the WebDAV API with these headers:
       | Upload-Length   | 5                                     |
       #    L0ZPTERFUi90ZXh0RmlsZS50eHQ= is the base64 encode of /FOLDER/textFile.txt
       | Upload-Metadata | filename L0ZPTERFUi90ZXh0RmlsZS50eHQ= |
       | Tus-Resumable   | 1.0.0                                 |
     And user "Brian" uploads file with checksum "MD5 827ccb0eea8a706c4c34a16891f84e7b" to the last created TUS Location with offset "0" and content "12345" via TUS inside of the space "Shares" using the WebDAV API
-    Then for user "Alice" folder "FOLDER" of the space "Personal" should contain these entries:
+    Then the HTTP status code should be "204"
+    And for user "Alice" folder "FOLDER" of the space "Personal" should contain these entries:
       | textFile.txt |
     And for user "Alice" the content of the file "FOLDER/textFile.txt" of the space "Personal" should be "12345"
 
@@ -402,3 +416,59 @@ Feature: upload resources on share using TUS protocol
       | Tus-Resumable   | 1.0.0                     |
     Then the HTTP status code should be "460"
     And for user "Alice" the content of the file "/textFile.txt" of the space "Personal" should be "original content"
+
+  @issue-10331 @issue-10469
+  Scenario: public uploads a zero byte file to a public share folder
+    Given using SharingNG
+    And user "Alice" has created folder "/uploadFolder"
+    And user "Alice" has created the following resource link share:
+      | resource        | uploadFolder |
+      | space           | Personal     |
+      | permissionsRole | createOnly   |
+      | password        | %public%     |
+    When the public uploads file "filesForUpload/zerobyte.txt" to "textfile.txt" via TUS inside last link shared folder with password "%public%" using the WebDAV API
+    Then the HTTP status code should be "201"
+    And for user "Alice" folder "uploadFolder" of the space "Personal" should contain these files:
+      | textfile.txt |
+    And for user "Alice" folder "uploadFolder" of the space "Personal" should not contain these files:
+      | textfile (1).txt |
+      | textfile (2).txt |
+
+  @issue-10331 @issue-10469
+  Scenario: public uploads a zero-byte file to a shared folder inside project space
+    Given using SharingNG
+    And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API
+    And user "Alice" has created a space "Project" with the default quota using the Graph API
+    And user "Alice" has created a folder "/uploadFolder" in space "Project"
+    And user "Alice" has created the following resource link share:
+      | resource        | uploadFolder |
+      | space           | Project      |
+      | permissionsRole | createOnly   |
+      | password        | %public%     |
+    When the public uploads file "filesForUpload/zerobyte.txt" to "textfile.txt" via TUS inside last link shared folder with password "%public%" using the WebDAV API
+    Then the HTTP status code should be "201"
+    And for user "Alice" folder "uploadFolder" of the space "Project" should contain these files:
+      | textfile.txt |
+    And for user "Alice" folder "uploadFolder" of the space "Project" should not contain these files:
+      | textfile (1).txt |
+      | textfile (2).txt |
+
+  @issue-10331 @issue-10469
+  Scenario: public uploads a zero-byte file to a public share project space
+    Given using SharingNG
+    And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API
+    And user "Alice" has created a space "Project" with the default quota using the Graph API
+    And user "Alice" has created the following space link share:
+      | space           | Project    |
+      | permissionsRole | createOnly |
+      | password        | %public%   |
+    When the public uploads file "filesForUpload/zerobyte.txt" to "textfile.txt" via TUS inside last link shared folder with password "%public%" using the WebDAV API
+    Then the HTTP status code should be "201"
+    And the following headers should be set
+      | header                        | value                                  |
+      | Access-Control-Expose-Headers | Tus-Resumable, Upload-Offset, Location |
+    And for user "Alice" the space "Project" should contain these files:
+      | textfile.txt |
+    And for user "Alice" the space "Project" should not contain these files:
+      | textfile (1).txt |
+      | textfile (2).txt |