The original owner could not be resolved because the original file was
already deleted, so no versions were retained.
This fix passes the owner and path to retainVersions() since it was
already resolved before the file deletion. This reactivates the versions
logic and creates a copy of the versions in each trashbin.
This makes sure that folders are moved to trash when deleted with
rmdir() instead of unlink().
This happens for example when deleting a folder over WebDAV.
The web UI uses unlink() so it wasn't affected.
The purpose of $originalStorage in unit tests was to remount the old
root.
However that storage itself is already wrapped by storage wrapper, so
remounting it would rewrap the storage several times.
This fix makes use of "loginAsUser()" and "logout()" from the TestCase
class to properly initialize and cleanup the FS as expected.
In the case of cross-storage delete, the files are copied to the trash,
then deleted. The final delete on the source storage would still reach
the trash wrapper.
This fix makes forwards that second call to the wrapped storage to make
the final delete work.
It fixes the issue with remote shares, local shares and external
storage.
Also, it uses a new function "renameRecursive" that renames the files
and preserves the mtimes (like "copy_recursive" did in the past))