Skip to content

Commit c18ac34

Browse files
Added more WebPushManager tests
1 parent 8ddd4ac commit c18ac34

File tree

1 file changed

+175
-9
lines changed

1 file changed

+175
-9
lines changed

Tests/WebPushTests/WebPushManagerTests.swift

Lines changed: 175 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,16 @@ struct WebPushManagerTests {
161161
func decrypt(
162162
request: HTTPClientRequest,
163163
userAgentPrivateKey: P256.KeyAgreement.PrivateKey,
164-
userAgentKeyMaterial: UserAgentKeyMaterial
164+
userAgentKeyMaterial: UserAgentKeyMaterial,
165+
expectedReadableBytes: Int = 4096,
166+
expectedRecordSize: Int = 4010
165167
) async throws -> [UInt8] {
166168
var body = try #require(try await request.body?.collect(upTo: 16*1024))
167-
#expect(body.readableBytes == 4096)
169+
#expect(body.readableBytes == expectedReadableBytes)
168170

169171
let salt = body.readBytes(length: 16)
170172
let recordSize = body.readInteger(as: UInt32.self)
171-
#expect(try #require(recordSize) == 4010)
173+
#expect(try #require(recordSize) == expectedRecordSize)
172174
let keyIDSize = body.readInteger(as: UInt8.self)
173175
let keyID = body.readBytes(length: Int(keyIDSize ?? 0))
174176

@@ -342,8 +344,74 @@ struct WebPushManagerTests {
342344
}
343345
}
344346

345-
@Test func sendMessageToNotFoundPushServerError() async throws {
346-
await confirmation { requestWasMade in
347+
@Test func sendMessageToSubscriberWithInvalidVAPIDKey() async throws {
348+
await confirmation(expectedCount: 0) { requestWasMade in
349+
let vapidConfiguration = VAPID.Configuration.mockedConfiguration
350+
351+
let subscriberPrivateKey = P256.KeyAgreement.PrivateKey(compactRepresentable: false)
352+
var authenticationSecret: [UInt8] = Array(repeating: 0, count: 16)
353+
for index in authenticationSecret.indices { authenticationSecret[index] = .random(in: .min ... .max) }
354+
355+
let subscriber = Subscriber(
356+
endpoint: URL(string: "https://example.com/subscriber")!,
357+
userAgentKeyMaterial: UserAgentKeyMaterial(publicKey: subscriberPrivateKey.publicKey, authenticationSecret: Data(authenticationSecret)),
358+
vapidKeyID: .mockedKeyID2
359+
)
360+
361+
let manager = WebPushManager(
362+
vapidConfiguration: vapidConfiguration,
363+
backgroundActivityLogger: Logger(label: "WebPushManagerTests", factory: { PrintLogHandler(label: $0, metadataProvider: $1) }),
364+
executor: .httpClient(MockHTTPClient({ request in
365+
requestWasMade()
366+
return HTTPClientResponse(status: .created)
367+
}))
368+
)
369+
370+
await #expect(throws: VAPID.ConfigurationError.matchingKeyNotFound) {
371+
try await manager.send(string: "hello", to: subscriber)
372+
}
373+
}
374+
}
375+
376+
@Test(.disabled("Fails because we need a public/private key pair that fails to make a shared secret"))
377+
func sendMessageToSubscriberWithInvalidUserAgentKey() async throws {
378+
try await confirmation(expectedCount: 0) { requestWasMade in
379+
let vapidConfiguration = VAPID.Configuration.mockedConfiguration
380+
381+
let privateKey = try P256.KeyAgreement.PrivateKey(rawRepresentation: Data(base64Encoded: "fkqlT3FL8B34XFAmm+o6hnIfhK/nT3tB6lirzzR06I0=")!)
382+
let publicKey = try P256.KeyAgreement.PublicKey(compressedRepresentation: Data(base64Encoded: "Ahj5uud0fNhE6YUlt8zQ2vbh0gqBiyF1qakeTq5TQ7yY")!)
383+
var authenticationSecret: [UInt8] = Array(repeating: 0, count: 16)
384+
for index in authenticationSecret.indices { authenticationSecret[index] = .random(in: .min ... .max) }
385+
386+
let subscriber = Subscriber(
387+
endpoint: URL(string: "https://example.com/subscriber")!,
388+
userAgentKeyMaterial: UserAgentKeyMaterial(
389+
publicKey: publicKey,
390+
authenticationSecret: Data(authenticationSecret)
391+
),
392+
vapidKeyID: .mockedKeyID1
393+
)
394+
395+
let manager = WebPushManager(
396+
vapidConfiguration: vapidConfiguration,
397+
backgroundActivityLogger: Logger(label: "WebPushManagerTests", factory: { PrintLogHandler(label: $0, metadataProvider: $1) }),
398+
executor: .httpClient(
399+
MockHTTPClient({ request in
400+
requestWasMade()
401+
return HTTPClientResponse(status: .created)
402+
}),
403+
privateKey
404+
)
405+
)
406+
407+
await #expect(throws: BadSubscriberError()) {
408+
try await manager.send(string: "hello", to: subscriber)
409+
}
410+
}
411+
}
412+
413+
@Test func sendSizeLimitMessageSucceeds() async throws {
414+
try await confirmation { requestWasMade in
347415
let vapidConfiguration = VAPID.Configuration.makeTesting()
348416

349417
let subscriberPrivateKey = P256.KeyAgreement.PrivateKey(compactRepresentable: false)
@@ -356,6 +424,104 @@ struct WebPushManagerTests {
356424
vapidKeyID: vapidConfiguration.primaryKey!.id
357425
)
358426

427+
let manager = WebPushManager(
428+
vapidConfiguration: vapidConfiguration,
429+
backgroundActivityLogger: Logger(label: "WebPushManagerTests", factory: { PrintLogHandler(label: $0, metadataProvider: $1) }),
430+
executor: .httpClient(MockHTTPClient({ request in
431+
try validateAuthotizationHeader(
432+
request: request,
433+
vapidConfiguration: vapidConfiguration,
434+
origin: "https://example.com"
435+
)
436+
#expect(request.method == .POST)
437+
#expect(request.headers["Content-Encoding"] == ["aes128gcm"])
438+
#expect(request.headers["Content-Type"] == ["application/octet-stream"])
439+
#expect(request.headers["TTL"] == ["2592000"])
440+
#expect(request.headers["Urgency"] == ["high"])
441+
#expect(request.headers["Topic"] == []) // TODO: Update when topic is added
442+
443+
let message = try await decrypt(
444+
request: request,
445+
userAgentPrivateKey: subscriberPrivateKey,
446+
userAgentKeyMaterial: subscriber.userAgentKeyMaterial,
447+
expectedReadableBytes: 4096,
448+
expectedRecordSize: 4010
449+
)
450+
451+
#expect(message == Array(repeating: 0, count: 3993))
452+
453+
requestWasMade()
454+
return HTTPClientResponse(status: .created)
455+
}))
456+
)
457+
458+
try await manager.send(data: Array(repeating: 0, count: 3993), to: subscriber)
459+
}
460+
}
461+
462+
@Test func sendExtraLargeMessageCouldSucceed() async throws {
463+
try await confirmation { requestWasMade in
464+
let vapidConfiguration = VAPID.Configuration.makeTesting()
465+
466+
let subscriberPrivateKey = P256.KeyAgreement.PrivateKey(compactRepresentable: false)
467+
var authenticationSecret: [UInt8] = Array(repeating: 0, count: 16)
468+
for index in authenticationSecret.indices { authenticationSecret[index] = .random(in: .min ... .max) }
469+
470+
let subscriber = Subscriber(
471+
endpoint: URL(string: "https://example.com/subscriber")!,
472+
userAgentKeyMaterial: UserAgentKeyMaterial(publicKey: subscriberPrivateKey.publicKey, authenticationSecret: Data(authenticationSecret)),
473+
vapidKeyID: vapidConfiguration.primaryKey!.id
474+
)
475+
476+
let manager = WebPushManager(
477+
vapidConfiguration: vapidConfiguration,
478+
backgroundActivityLogger: Logger(label: "WebPushManagerTests", factory: { PrintLogHandler(label: $0, metadataProvider: $1) }),
479+
executor: .httpClient(MockHTTPClient({ request in
480+
try validateAuthotizationHeader(
481+
request: request,
482+
vapidConfiguration: vapidConfiguration,
483+
origin: "https://example.com"
484+
)
485+
#expect(request.method == .POST)
486+
#expect(request.headers["Content-Encoding"] == ["aes128gcm"])
487+
#expect(request.headers["Content-Type"] == ["application/octet-stream"])
488+
#expect(request.headers["TTL"] == ["2592000"])
489+
#expect(request.headers["Urgency"] == ["high"])
490+
#expect(request.headers["Topic"] == []) // TODO: Update when topic is added
491+
492+
let message = try await decrypt(
493+
request: request,
494+
userAgentPrivateKey: subscriberPrivateKey,
495+
userAgentKeyMaterial: subscriber.userAgentKeyMaterial,
496+
expectedReadableBytes: 4097,
497+
expectedRecordSize: 4011
498+
)
499+
500+
#expect(message == Array(repeating: 0, count: 3994))
501+
502+
requestWasMade()
503+
return HTTPClientResponse(status: .created)
504+
}))
505+
)
506+
507+
try await manager.send(data: Array(repeating: 0, count: 3994), to: subscriber)
508+
}
509+
}
510+
511+
@Test func sendMessageToNotFoundPushServerError() async throws {
512+
await confirmation { requestWasMade in
513+
let vapidConfiguration = VAPID.Configuration.mockedConfiguration
514+
515+
let subscriberPrivateKey = P256.KeyAgreement.PrivateKey(compactRepresentable: false)
516+
var authenticationSecret: [UInt8] = Array(repeating: 0, count: 16)
517+
for index in authenticationSecret.indices { authenticationSecret[index] = .random(in: .min ... .max) }
518+
519+
let subscriber = Subscriber(
520+
endpoint: URL(string: "https://example.com/subscriber")!,
521+
userAgentKeyMaterial: UserAgentKeyMaterial(publicKey: subscriberPrivateKey.publicKey, authenticationSecret: Data(authenticationSecret)),
522+
vapidKeyID: .mockedKeyID1
523+
)
524+
359525
let manager = WebPushManager(
360526
vapidConfiguration: vapidConfiguration,
361527
backgroundActivityLogger: Logger(label: "WebPushManagerTests", factory: { PrintLogHandler(label: $0, metadataProvider: $1) }),
@@ -373,7 +539,7 @@ struct WebPushManagerTests {
373539

374540
@Test func sendMessageToGonePushServerError() async throws {
375541
await confirmation { requestWasMade in
376-
let vapidConfiguration = VAPID.Configuration.makeTesting()
542+
let vapidConfiguration = VAPID.Configuration.mockedConfiguration
377543

378544
let subscriberPrivateKey = P256.KeyAgreement.PrivateKey(compactRepresentable: false)
379545
var authenticationSecret: [UInt8] = Array(repeating: 0, count: 16)
@@ -382,7 +548,7 @@ struct WebPushManagerTests {
382548
let subscriber = Subscriber(
383549
endpoint: URL(string: "https://example.com/subscriber")!,
384550
userAgentKeyMaterial: UserAgentKeyMaterial(publicKey: subscriberPrivateKey.publicKey, authenticationSecret: Data(authenticationSecret)),
385-
vapidKeyID: vapidConfiguration.primaryKey!.id
551+
vapidKeyID: .mockedKeyID1
386552
)
387553

388554
let manager = WebPushManager(
@@ -402,7 +568,7 @@ struct WebPushManagerTests {
402568

403569
@Test func sendMessageToUnknownPushServerError() async throws {
404570
await confirmation { requestWasMade in
405-
let vapidConfiguration = VAPID.Configuration.makeTesting()
571+
let vapidConfiguration = VAPID.Configuration.mockedConfiguration
406572

407573
let subscriberPrivateKey = P256.KeyAgreement.PrivateKey(compactRepresentable: false)
408574
var authenticationSecret: [UInt8] = Array(repeating: 0, count: 16)
@@ -411,7 +577,7 @@ struct WebPushManagerTests {
411577
let subscriber = Subscriber(
412578
endpoint: URL(string: "https://example.com/subscriber")!,
413579
userAgentKeyMaterial: UserAgentKeyMaterial(publicKey: subscriberPrivateKey.publicKey, authenticationSecret: Data(authenticationSecret)),
414-
vapidKeyID: vapidConfiguration.primaryKey!.id
580+
vapidKeyID: .mockedKeyID1
415581
)
416582

417583
let manager = WebPushManager(

0 commit comments

Comments
 (0)