@@ -13,6 +13,7 @@ import Logging
1313import ServiceLifecycle
1414import Testing
1515@testable import WebPush
16+ import WebPushTesting
1617
1718@Suite ( " WebPush Manager " )
1819struct 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("
[email protected] "))
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
( " [email protected] " ) ) 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