fix(core): File Provider write probe — OneDriveLocator.probeWritable(at:)

isWritableDirectory (permissions bits) is not enough: a OneDrive
Files-On-Demand directory whose provider domain is signed out can report as
existing and POSIX-writable while an actual write fails. probeWritable
writes a small ".redline-probe-<uuid>" file into the folder via
AtomicFile.write (open+write+fsync+rename+directory-fsync), then removes it;
any failure at write, fsync, or removal means false.

Three unit tests: an ordinary writable directory (true, and no probe file
left behind), a chmod 500 directory (false; permissions restored in
teardown), and a plain file path (false).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012ZiTXPbPCSjzPVsfoweAbp
This commit is contained in:
2026-09-05 09:54:58 +04:00
co-authored by Claude Fable 5.1
parent 70231574c9
commit 723cd7dcea
2 changed files with 63 additions and 0 deletions
@@ -122,6 +122,44 @@ func isWritableDirectoryFalseForAPlainFileAndForANonexistentPath() throws {
#expect(!OneDriveLocator.isWritableDirectory(at: dir.appendingPathComponent("does-not-exist")))
}
@Test
func probeWritableTrueForAnOrdinaryWritableDirectoryAndLeavesNoProbeFileBehind() throws {
let dir = try makeTransportTemporaryDirectory(prefix: "shotdeck-probe-writable")
defer { try? FileManager.default.removeItem(at: dir) }
#expect(OneDriveLocator.probeWritable(at: dir))
let leftovers = try FileManager.default.contentsOfDirectory(atPath: dir.path)
#expect(leftovers.isEmpty)
}
@Test
func probeWritableFalseForAChmod500Directory() throws {
// The File Provider edge case this probe exists for: isWritableDirectory can be
// true (as verified by the isWritableDirectory tests above) while an actual write
// still fails. A chmod 500 directory reproduces that "looks writable, isn't"
// shape closely enough to prove the probe itself does a real write, not just
// another permissions-bit check.
let dir = try makeTransportTemporaryDirectory(prefix: "shotdeck-probe-unwritable")
defer {
try? FileManager.default.setAttributes([.posixPermissions: 0o755], ofItemAtPath: dir.path)
try? FileManager.default.removeItem(at: dir)
}
try FileManager.default.setAttributes([.posixPermissions: 0o500], ofItemAtPath: dir.path)
#expect(!OneDriveLocator.probeWritable(at: dir))
}
@Test
func probeWritableFalseForAPlainFilePath() throws {
let dir = try makeTransportTemporaryDirectory(prefix: "shotdeck-probe-file-parent")
defer { try? FileManager.default.removeItem(at: dir) }
let filePath = dir.appendingPathComponent("plain-file.txt")
FileManager.default.createFile(atPath: filePath.path, contents: Data("x".utf8))
#expect(!OneDriveLocator.probeWritable(at: filePath))
}
struct TransportDefaultsSuite {
let name: String
let defaults: UserDefaults