Skip to content

Commit 0b4fe1d

Browse files
Added more test coverage to WebPushManager
1 parent 765b986 commit 0b4fe1d

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed

Sources/WebPush/VAPID/VAPIDConfiguration.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ extension VoluntaryApplicationServerIdentification {
142142
deprecatedKeys.subtract(keys)
143143
self.deprecatedKeys = deprecatedKeys.isEmpty ? nil : deprecatedKeys
144144
}
145+
146+
/// Internal method to set invalid state for validation that other components are resiliant to these configurations.
147+
mutating func unsafeUpdateKeys(
148+
primaryKey: Key? = nil,
149+
keys: Set<Key>,
150+
deprecatedKeys: Set<Key>? = nil
151+
) {
152+
self.primaryKey = primaryKey
153+
self.keys = keys
154+
self.deprecatedKeys = deprecatedKeys
155+
}
145156
}
146157
}
147158

Tests/WebPushTests/WebPushManagerTests.swift

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Logging
1313
import ServiceLifecycle
1414
import Testing
1515
@testable import WebPush
16+
import WebPushTesting
1617

1718
@Suite("WebPush Manager")
1819
struct WebPushManagerTests {
@@ -41,6 +42,141 @@ struct WebPushManagerTests {
4142
group.cancelAll()
4243
}
4344
}
45+
46+
@Test func managerCanCreateThreadPool() async throws {
47+
let manager = WebPushManager(vapidConfiguration: .makeTesting(), eventLoopGroupProvider: .createNew)
48+
await withThrowingTaskGroup(of: Void.self) { group in
49+
group.addTask {
50+
try await manager.run()
51+
}
52+
group.cancelAll()
53+
}
54+
}
55+
56+
@Test func managerCanBeMocked() async throws {
57+
let manager = WebPushManager.makeMockedManager { _, _, _, _ in }
58+
await withThrowingTaskGroup(of: Void.self) { group in
59+
group.addTask {
60+
try await manager.run()
61+
}
62+
group.cancelAll()
63+
}
64+
}
65+
66+
/// Enable when https://github.com/swiftlang/swift-testing/blob/jgrynspan/exit-tests-proposal/Documentation/Proposals/NNNN-exit-tests.md gets accepted.
67+
// @Test func managerCatchesIncorrectValidity() async throws {
68+
// await #expect(exitsWith: .failure) {
69+
// var configuration = VAPID.Configuration(key: .init(), contactInformation: .email("test@example.com"))
70+
// configuration.validityDuration = .days(2)
71+
// let _ = WebPushManager(vapidConfiguration: configuration)
72+
// }
73+
// }
74+
75+
@Test func managerConstructsAValidKeyLookup() async throws {
76+
let configuration = try VAPID.Configuration(primaryKey: .mockedKey1, keys: [.mockedKey2], deprecatedKeys: [.mockedKey3], contactInformation: .email("test@example.com"))
77+
let manager = WebPushManager(vapidConfiguration: configuration)
78+
#expect(await manager.vapidKeyLookup == [
79+
.mockedKeyID1 : .mockedKey1,
80+
.mockedKeyID2 : .mockedKey2,
81+
.mockedKeyID3 : .mockedKey3,
82+
])
83+
await withThrowingTaskGroup(of: Void.self) { group in
84+
group.addTask {
85+
try await manager.run()
86+
}
87+
group.cancelAll()
88+
}
89+
}
90+
91+
/// This is needed to cover the `uniquingKeysWith` safety call completely.
92+
@Test func managerConstructsAValidKeyLookupFromQuestionableConfiguration() async throws {
93+
var configuration = VAPID.Configuration.mocked
94+
configuration.unsafeUpdateKeys(primaryKey: .mockedKey1, keys: [.mockedKey1], deprecatedKeys: [.mockedKey1])
95+
let manager = WebPushManager(vapidConfiguration: configuration)
96+
#expect(await manager.vapidKeyLookup == [.mockedKeyID1 : .mockedKey1])
97+
await withThrowingTaskGroup(of: Void.self) { group in
98+
group.addTask {
99+
try await manager.run()
100+
}
101+
group.cancelAll()
102+
}
103+
}
104+
}
105+
106+
@Suite("VAPID Key Retrieval") struct VAPIDKeyRetrieval {
107+
@Test func retrievesPrimaryKey() async {
108+
let manager = WebPushManager(vapidConfiguration: .mocked)
109+
#expect(manager.nextVAPIDKeyID == .mockedKeyID1)
110+
await withThrowingTaskGroup(of: Void.self) { group in
111+
group.addTask {
112+
try await manager.run()
113+
}
114+
group.cancelAll()
115+
}
116+
}
117+
118+
@Test func alwaysRetrievesPrimaryKey() async throws {
119+
var configuration = VAPID.Configuration.mocked
120+
try configuration.updateKeys(primaryKey: .mockedKey1, keys: [.mockedKey2], deprecatedKeys: [.mockedKey3])
121+
let manager = WebPushManager(vapidConfiguration: configuration)
122+
for _ in 0..<100_000 {
123+
#expect(manager.nextVAPIDKeyID == .mockedKeyID1)
124+
}
125+
await withThrowingTaskGroup(of: Void.self) { group in
126+
group.addTask {
127+
try await manager.run()
128+
}
129+
group.cancelAll()
130+
}
131+
}
132+
133+
@Test func retrievesFallbackKeys() async throws {
134+
var configuration = VAPID.Configuration.mocked
135+
try configuration.updateKeys(primaryKey: nil, keys: [.mockedKey1, .mockedKey2])
136+
let manager = WebPushManager(vapidConfiguration: configuration)
137+
var keyCounts: [VAPID.Key.ID : Int] = [:]
138+
for _ in 0..<100_000 {
139+
keyCounts[manager.nextVAPIDKeyID, default: 0] += 1
140+
}
141+
#expect(abs(keyCounts[.mockedKeyID1, default: 0] - keyCounts[.mockedKeyID2, default: 0]) < 1_000) /// If this test fails, increase this number accordingly
142+
await withThrowingTaskGroup(of: Void.self) { group in
143+
group.addTask {
144+
try await manager.run()
145+
}
146+
group.cancelAll()
147+
}
148+
}
149+
150+
@Test func neverRetrievesDeprecatedKeys() async throws {
151+
var configuration = VAPID.Configuration.mocked
152+
try configuration.updateKeys(primaryKey: nil, keys: [.mockedKey1, .mockedKey2], deprecatedKeys: [.mockedKey3])
153+
let manager = WebPushManager(vapidConfiguration: configuration)
154+
for _ in 0..<100_000 {
155+
#expect(manager.nextVAPIDKeyID != .mockedKeyID3)
156+
}
157+
await withThrowingTaskGroup(of: Void.self) { group in
158+
group.addTask {
159+
try await manager.run()
160+
}
161+
group.cancelAll()
162+
}
163+
}
164+
165+
@Test func keyStatus() async throws {
166+
var configuration = VAPID.Configuration.mocked
167+
try configuration.updateKeys(primaryKey: .mockedKey1, keys: [.mockedKey2], deprecatedKeys: [.mockedKey3])
168+
let manager = WebPushManager(vapidConfiguration: configuration)
169+
#expect(manager.keyStatus(for: .mockedKeyID1) == .valid)
170+
#expect(manager.keyStatus(for: .mockedKeyID2) == .valid)
171+
#expect(manager.keyStatus(for: .mockedKeyID3) == .deprecated)
172+
#expect(manager.keyStatus(for: .mockedKeyID4) == .unknown)
173+
await withThrowingTaskGroup(of: Void.self) { group in
174+
group.addTask {
175+
try await manager.run()
176+
}
177+
group.cancelAll()
178+
}
179+
}
44180
}
45181

46182
@Suite("Sending Messages")

0 commit comments

Comments
 (0)