Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion projects/ios-readplace/Tests/LoginFlowTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final class LoginFlowTests: XCTestCase {
let request = makeService(store: TestSupport.loggedInStore()).makeNativeLoginAuthorizationRequest()

let components = URLComponents(url: request.url, resolvingAgainstBaseURL: false)!
XCTAssertEqual(components.host, "readplace.com")
XCTAssertEqual(components.host, URL(string: AppConfig.serverBaseURL)?.host)
XCTAssertEqual(components.path, "/oauth/authorize")
let items = Dictionary(uniqueKeysWithValues: (components.queryItems ?? []).map { ($0.name, $0.value ?? "") })
XCTAssertEqual(items["client_id"], "ios-app")
Expand Down
13 changes: 8 additions & 5 deletions projects/ios-readplace/Tests/PKCETests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ final class PKCETests: XCTestCase {
XCTAssertNotEqual(PKCE.makeCodeVerifier(), PKCE.makeCodeVerifier())
}

func testChallengeIsURLSafe() {
func testChallengeIsBase64URLAndCorrectLength() {
let challenge = PKCE.challenge(for: PKCE.makeCodeVerifier())
XCTAssertFalse(challenge.contains("+"))
XCTAssertFalse(challenge.contains("/"))
XCTAssertFalse(challenge.contains("="))
XCTAssertFalse(challenge.isEmpty)
XCTAssertEqual(challenge.count, 43, "a SHA-256 digest base64url-encodes to 43 chars")
let allowed = CharacterSet(charactersIn:
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_")
XCTAssertTrue(
challenge.unicodeScalars.allSatisfy(allowed.contains),
"every character is in the base64url alphabet (no +, /, or =)"
)
}
}
4 changes: 2 additions & 2 deletions projects/ios-readplace/Tests/SignupFlowTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ final class SignupFlowTests: XCTestCase {
let request = makeService(store: TestSupport.loggedInStore()).makeSignupAuthorizationRequest()

let components = URLComponents(url: request.url, resolvingAgainstBaseURL: false)!
XCTAssertEqual(components.host, "readplace.com")
XCTAssertEqual(components.host, URL(string: AppConfig.serverBaseURL)?.host)
XCTAssertEqual(components.path, "/oauth/authorize")
let items = Dictionary(uniqueKeysWithValues: (components.queryItems ?? []).map { ($0.name, $0.value ?? "") })
XCTAssertEqual(items["client_id"], "ios-app")
Expand Down Expand Up @@ -83,7 +83,7 @@ final class SignupFlowTests: XCTestCase {
XCTAssertEqual(probed?.scheme, "googlechromes", "Chrome availability is probed with the https scheme variant")
let components = URLComponents(url: chrome, resolvingAgainstBaseURL: false)!
XCTAssertEqual(components.scheme, "googlechromes")
XCTAssertEqual(components.host, "readplace.com")
XCTAssertEqual(components.host, URL(string: AppConfig.serverBaseURL)?.host)
XCTAssertEqual(components.path, "/oauth/authorize")
XCTAssertEqual(components.percentEncodedQuery, "client_id=ios-app&state=abc")
}
Expand Down
22 changes: 18 additions & 4 deletions projects/ios-readplace/Tests/SirenDecodingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ import XCTest
@testable import Readplace

final class SirenDecodingTests: XCTestCase {
/// A fixed UTC instant, for asserting a parsed date equals a known point in
/// time rather than merely being non-nil.
static func utc(_ year: Int, _ month: Int, _ day: Int, _ hour: Int, _ minute: Int, _ second: Int) -> Date {
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(identifier: "UTC")!
return calendar.date(from: DateComponents(
year: year, month: month, day: day, hour: hour, minute: minute, second: second
))!
}

private func decodeCollection(_ json: String) throws -> SirenCollection {
try JSONDecoder().decode(SirenCollection.self, from: Data(json.utf8))
}
Expand All @@ -27,7 +37,8 @@ final class SirenDecodingTests: XCTestCase {
XCTAssertEqual(updateStatus.type, "application/x-www-form-urlencoded")
XCTAssertEqual(updateStatus.fields?.first?.name, "status")
XCTAssertEqual(article.readHref, "/queue/a1/view")
XCTAssertNotNil(article.savedAt)
XCTAssertEqual(article.savedAt, SirenDecodingTests.utc(2026, 5, 30, 10, 0, 0),
"the fixture's savedAt (2026-05-30T10:00:00.000Z) parses to that exact instant")
}

func testArticleAffordancesIterateAdvertisedActionsInWireOrder() throws {
Expand Down Expand Up @@ -315,9 +326,12 @@ final class SirenDecodingTests: XCTestCase {
XCTAssertEqual(page.warning?.message, "Cannot save that link.")
}

func testSirenDateParsesWithAndWithoutFractionalSeconds() {
XCTAssertNotNil(SirenDate.parse("2026-05-30T10:00:00.123Z"))
XCTAssertNotNil(SirenDate.parse("2026-05-30T10:00:00Z"))
func testSirenDateParsesWithAndWithoutFractionalSeconds() throws {
let base = SirenDecodingTests.utc(2026, 5, 30, 10, 0, 0)
XCTAssertEqual(try XCTUnwrap(SirenDate.parse("2026-05-30T10:00:00Z")), base)
let fractional = try XCTUnwrap(SirenDate.parse("2026-05-30T10:00:00.123Z"))
XCTAssertEqual(fractional.timeIntervalSince(base), 0.123, accuracy: 0.0005,
"the fractional variant is 123 ms after the whole-second instant")
XCTAssertNil(SirenDate.parse("not-a-date"))
XCTAssertNil(SirenDate.parse(""))
}
Expand Down