| 1 | import XCTest |
| 2 | @testable import LChatCore |
| 3 | |
| 4 | // Drift gate for the BINARY crypto path: attachments (and avatars) travel as |
| 5 | // raw `iv||ct||tag` bytes, opened natively by GroupKey.decryptBytes |
| 6 | // (BlobImageLoader). The fixture blob was produced by the web's encryptBytes |
| 7 | // (regenerate with `node test/blobbytes.test.mjs --emit`); a failure means |
| 8 | // photos decrypt on one platform and not the other. |
| 9 | final class AttachmentBytesVectorTests: XCTestCase { |
| 10 | struct Vector: Decodable { |
| 11 | let keyB64: String |
| 12 | let blobB64url: String |
| 13 | let plaintextB64url: String |
| 14 | } |
| 15 | |
| 16 | func testAttachmentBytesRoundTrip() throws { |
| 17 | let v = try fixture(Vector.self, "attachment-bytes-vector") |
| 18 | let raw = try XCTUnwrap(Data(base64urlEncoded: v.keyB64)) |
| 19 | let blob = try XCTUnwrap(Data(base64urlEncoded: v.blobB64url)) |
| 20 | let expected = try XCTUnwrap(Data(base64urlEncoded: v.plaintextB64url)) |
| 21 | let key = try GroupKey(rawKey: raw) |
| 22 | |
| 23 | XCTAssertEqual(try key.decryptBytes(blob), expected, |
| 24 | "web-encrypted bytes must open natively") |
| 25 | |
| 26 | // And the reverse: natively-encrypted bytes must be self-consistent |
| 27 | // (the same combined layout), so a native upload would open on the web. |
| 28 | let fresh = try key.encryptBytes(expected) |
| 29 | XCTAssertEqual(try key.decryptBytes(fresh), expected, "native encryptBytes round-trips") |
| 30 | } |
| 31 | } |
| 32 | |