1414import java .util .List ;
1515
1616import org .junit .jupiter .api .BeforeEach ;
17- import org .junit .jupiter .api .Disabled ;
1817import org .junit .jupiter .api .Test ;
1918import org .mockito .Mock ;
2019import org .mockito .MockitoAnnotations ;
2120
2221import io .a2a .client .http .A2AHttpClient ;
2322import io .a2a .client .http .A2AHttpResponse ;
23+ import io .a2a .common .A2AHeaders ;
2424import io .a2a .spec .PushNotificationConfig ;
2525import io .a2a .spec .Task ;
2626import io .a2a .spec .TaskState ;
@@ -47,6 +47,29 @@ public void setUp() {
4747 notificationSender = new BasePushNotificationSender (configStore , mockHttpClient );
4848 }
4949
50+ private void setupBasicMockHttpResponse () throws Exception {
51+ when (mockHttpClient .createPost ()).thenReturn (mockPostBuilder );
52+ when (mockPostBuilder .url (any (String .class ))).thenReturn (mockPostBuilder );
53+ when (mockPostBuilder .body (any (String .class ))).thenReturn (mockPostBuilder );
54+ when (mockPostBuilder .post ()).thenReturn (mockHttpResponse );
55+ when (mockHttpResponse .success ()).thenReturn (true );
56+ }
57+
58+ private void verifyHttpCallWithoutToken (PushNotificationConfig config , Task task , String expectedToken ) throws Exception {
59+ ArgumentCaptor <String > bodyCaptor = ArgumentCaptor .forClass (String .class );
60+ verify (mockHttpClient ).createPost ();
61+ verify (mockPostBuilder ).url (config .url ());
62+ verify (mockPostBuilder ).body (bodyCaptor .capture ());
63+ verify (mockPostBuilder ).post ();
64+ // Verify that addHeader was never called for authentication token
65+ verify (mockPostBuilder , never ()).addHeader (A2AHeaders .X_A2A_NOTIFICATION_TOKEN , expectedToken );
66+
67+ // Verify the request body contains the task data
68+ String sentBody = bodyCaptor .getValue ();
69+ assertTrue (sentBody .contains (task .getId ()));
70+ assertTrue (sentBody .contains (task .getStatus ().state ().asString ()));
71+ }
72+
5073 private Task createSampleTask (String taskId , TaskState state ) {
5174 return new Task .Builder ()
5275 .id (taskId )
@@ -229,7 +252,6 @@ public void testSendNotificationSuccess() throws Exception {
229252 }
230253
231254 @ Test
232- @ Disabled ("Token authentication is not yet implemented in BasePushNotificationSender (TODO auth)" )
233255 public void testSendNotificationWithToken () throws Exception {
234256 String taskId = "task_send_with_token" ;
235257 Task task = createSampleTask (taskId , TaskState .COMPLETED );
@@ -240,21 +262,19 @@ public void testSendNotificationWithToken() throws Exception {
240262 when (mockHttpClient .createPost ()).thenReturn (mockPostBuilder );
241263 when (mockPostBuilder .url (any (String .class ))).thenReturn (mockPostBuilder );
242264 when (mockPostBuilder .body (any (String .class ))).thenReturn (mockPostBuilder );
265+ when (mockPostBuilder .addHeader (any (String .class ), any (String .class ))).thenReturn (mockPostBuilder );
243266 when (mockPostBuilder .post ()).thenReturn (mockHttpResponse );
244267 when (mockHttpResponse .success ()).thenReturn (true );
245268
246269 notificationSender .sendNotification (task );
247270
248- // TODO: Once token authentication is implemented, verify that:
249- // 1. The token is included in request headers (e.g., X-A2A-Notification-Token)
250- // 2. The HTTP client is called with proper authentication
251- // 3. The token from the config is actually used
252-
253- // For now, just verify basic HTTP client interaction
271+ // Verify HTTP client was called with proper authentication
254272 ArgumentCaptor <String > bodyCaptor = ArgumentCaptor .forClass (String .class );
255273 verify (mockHttpClient ).createPost ();
256274 verify (mockPostBuilder ).url (config .url ());
257275 verify (mockPostBuilder ).body (bodyCaptor .capture ());
276+ // Verify that the token is included in request headers as X-A2A-Notification-Token
277+ verify (mockPostBuilder ).addHeader (A2AHeaders .X_A2A_NOTIFICATION_TOKEN , config .token ());
258278 verify (mockPostBuilder ).post ();
259279
260280 // Verify the request body contains the task data
@@ -274,6 +294,30 @@ public void testSendNotificationNoConfig() throws Exception {
274294 verify (mockHttpClient , never ()).createPost ();
275295 }
276296
297+ @ Test
298+ public void testSendNotificationWithEmptyToken () throws Exception {
299+ String taskId = "task_send_empty_token" ;
300+ Task task = createSampleTask (taskId , TaskState .COMPLETED );
301+ PushNotificationConfig config = createSamplePushConfig ("http://notify.me/here" , "cfg1" , "" );
302+ configStore .setInfo (taskId , config );
303+
304+ setupBasicMockHttpResponse ();
305+ notificationSender .sendNotification (task );
306+ verifyHttpCallWithoutToken (config , task , "" );
307+ }
308+
309+ @ Test
310+ public void testSendNotificationWithBlankToken () throws Exception {
311+ String taskId = "task_send_blank_token" ;
312+ Task task = createSampleTask (taskId , TaskState .COMPLETED );
313+ PushNotificationConfig config = createSamplePushConfig ("http://notify.me/here" , "cfg1" , " " );
314+ configStore .setInfo (taskId , config );
315+
316+ setupBasicMockHttpResponse ();
317+ notificationSender .sendNotification (task );
318+ verifyHttpCallWithoutToken (config , task , " " );
319+ }
320+
277321 @ Test
278322 public void testMultipleConfigsForSameTask () {
279323 String taskId = "task_multiple" ;
0 commit comments