@@ -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 . 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 . 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 . 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 . 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