Kotlin documented no-read-up and no-write-down and pinned the gap in a test. Swift had only permits, undocumented, so the platform that is the source of truth was the one saying nothing. Swift now has mayRead and mayWrite with the same wording, and ClearanceTests mirrors LabelTest, so enforcing it on one side fails the other and forces both into the same commit. The label picker gains the boundary in the place somebody is choosing a label: it decides who can open a file, not where the file can be put. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
53 lines
2.5 KiB
Swift
53 lines
2.5 KiB
Swift
import FilesEngine
|
|
import XCTest
|
|
|
|
@testable import FilesClient
|
|
|
|
/// The two halves of the model, and which one is enforced.
|
|
///
|
|
/// The mirror of `LabelTest` on the Kotlin side. Both engines must answer the
|
|
/// same way: a rule enforced on one client and not the other is worse than the
|
|
/// gap, because a file that saves on one phone and is refused on the other
|
|
/// reads as a bug and gets worked around.
|
|
final class ClearanceTests: XCTestCase {
|
|
|
|
/// No read up. Nothing above the clearance, and nothing outside its areas.
|
|
func testReadingStopsAtTheClearance() {
|
|
let cleared = Clearance(maximum: Label(classification: 5), minimum: Label(classification: 0))
|
|
XCTAssertTrue(cleared.mayRead(Label(classification: 5)))
|
|
XCTAssertTrue(cleared.mayRead(Label(classification: 1)))
|
|
XCTAssertFalse(cleared.mayRead(Label(classification: 8)))
|
|
}
|
|
|
|
/// Writing uses the same range check as reading, so the second rule of the
|
|
/// model is NOT enforced. Pinned, so the day it changes this fails and the
|
|
/// Kotlin test next to it has to change in the same commit.
|
|
func testWritingUsesTheSameCheckAsReading() {
|
|
let cleared = Clearance(maximum: Label(classification: 5), minimum: Label(classification: 0))
|
|
XCTAssertTrue(cleared.mayWrite(Label(classification: 5)))
|
|
XCTAssertTrue(
|
|
cleared.mayWrite(Label(classification: 1)),
|
|
"no-write-down is now enforced: see ios#65, and change the Kotlin "
|
|
+ "LabelTest and this test together")
|
|
XCTAssertFalse(cleared.mayWrite(Label(classification: 8)))
|
|
}
|
|
|
|
/// A floor bounds writing as well as reading.
|
|
func testAFloorBoundsBothDirections() {
|
|
let cleared = Clearance(maximum: Label(classification: 5), minimum: Label(classification: 2))
|
|
XCTAssertTrue(cleared.mayWrite(Label(classification: 3)))
|
|
XCTAssertFalse(cleared.mayWrite(Label(classification: 1)))
|
|
XCTAssertFalse(cleared.mayRead(Label(classification: 1)))
|
|
}
|
|
|
|
/// Areas, not only levels: a clearance without the area does not reach it.
|
|
func testAreasAreCheckedTooBothWays() {
|
|
let cleared = Clearance(
|
|
maximum: Label(classification: 5, compartments: [1]),
|
|
minimum: Label(classification: 0))
|
|
XCTAssertTrue(cleared.mayRead(Label(classification: 3, compartments: [1])))
|
|
XCTAssertFalse(cleared.mayRead(Label(classification: 3, compartments: [2])))
|
|
XCTAssertFalse(cleared.mayWrite(Label(classification: 3, compartments: [2])))
|
|
}
|
|
}
|