|
14 | 14 | import com.azure.communication.callautomation.models.events.CallConnected; |
15 | 15 | import com.azure.communication.callautomation.models.events.ContinuousDtmfRecognitionStopped; |
16 | 16 | import com.azure.communication.callautomation.models.events.PlayCompleted; |
| 17 | +import com.azure.communication.callautomation.models.events.PlayStarted; |
17 | 18 | import com.azure.communication.callautomation.models.events.SendDtmfTonesCompleted; |
18 | 19 | import com.azure.communication.common.CommunicationIdentifier; |
19 | 20 | import com.azure.communication.common.CommunicationUserIdentifier; |
|
27 | 28 | import com.azure.communication.callautomation.models.MediaStreamingContent; |
28 | 29 | import com.azure.communication.callautomation.models.MediaStreamingOptions; |
29 | 30 | import com.azure.communication.callautomation.models.MediaStreamingTransport; |
| 31 | +import com.azure.communication.callautomation.models.PlayOptions; |
30 | 32 | import com.azure.communication.callautomation.models.TranscriptionOptions; |
31 | 33 | import com.azure.communication.callautomation.models.StartMediaStreamingOptions; |
32 | 34 | import com.azure.communication.callautomation.models.StopMediaStreamingOptions; |
|
61 | 63 | import static org.junit.jupiter.api.Assertions.assertTrue; |
62 | 64 | import static org.junit.jupiter.api.Assertions.fail; |
63 | 65 |
|
| 66 | +import com.azure.communication.callautomation.models.events.HoldAudioResumed; |
| 67 | +import com.azure.communication.callautomation.models.events.HoldAudioCompleted; |
| 68 | +import com.azure.communication.callautomation.models.events.HoldAudioPaused; |
| 69 | +import com.azure.communication.callautomation.models.events.HoldAudioStarted; |
| 70 | + |
64 | 71 | public class CallMediaAsyncAutomatedLiveTests extends CallAutomationAutomatedLiveTestBase { |
65 | 72 |
|
66 | 73 | @ParameterizedTest |
@@ -1316,4 +1323,137 @@ public void interruptAudioAndAnnounceToholdParticipantInACallTest(HttpClient htt |
1316 | 1323 | } |
1317 | 1324 | } |
1318 | 1325 | } |
| 1326 | + |
| 1327 | + @ParameterizedTest |
| 1328 | + @MethodSource("com.azure.core.test.TestBase#getHttpClients") |
| 1329 | + @DisabledIfEnvironmentVariable( |
| 1330 | + named = "SKIP_LIVE_TEST", |
| 1331 | + matches = "(?i)(true)", |
| 1332 | + disabledReason = "Requires environment to be set up") |
| 1333 | + public void playMultipleFileSourcesWhenParticipantOnHoldTest(HttpClient httpClient) { |
| 1334 | + /* Test case: ACS to ACS call |
| 1335 | + * 1. create a CallAutomationClient. |
| 1336 | + * 2. create a call from source to one ACS target. |
| 1337 | + * 3. get updated call properties and check for the connected state. |
| 1338 | + * 4. hold the participant |
| 1339 | + * 5. play a media to target participant with mutiple file prompts |
| 1340 | + * 6. unhold the participant |
| 1341 | + * 7. hang up the call. |
| 1342 | + */ |
| 1343 | + |
| 1344 | + CommunicationIdentityAsyncClient identityAsyncClient |
| 1345 | + = getCommunicationIdentityClientUsingConnectionString(httpClient) |
| 1346 | + .addPolicy((context, next) -> logHeaders("playMultipleFileSourcesWhenParticipantOnHoldTest", next)) |
| 1347 | + .buildAsyncClient(); |
| 1348 | + |
| 1349 | + List<CallConnectionAsync> callDestructors = new ArrayList<>(); |
| 1350 | + |
| 1351 | + try { |
| 1352 | + // create caller and receiver |
| 1353 | + CommunicationUserIdentifier caller = identityAsyncClient.createUser().block(); |
| 1354 | + CommunicationIdentifier receiver = identityAsyncClient.createUser().block(); |
| 1355 | + |
| 1356 | + CallAutomationAsyncClient callerAsyncClient = getCallAutomationClientUsingConnectionString(httpClient) |
| 1357 | + .addPolicy((context, next) -> logHeaders("playMultipleFileSourcesWhenParticipantOnHoldTest", next)) |
| 1358 | + .sourceIdentity(caller) |
| 1359 | + .buildAsyncClient(); |
| 1360 | + |
| 1361 | + // Create call automation client for receivers. |
| 1362 | + CallAutomationAsyncClient receiverAsyncClient = getCallAutomationClientUsingConnectionString(httpClient) |
| 1363 | + .addPolicy((context, next) -> logHeaders("playMultipleFileSourcesWhenParticipantOnHoldTest", next)) |
| 1364 | + .buildAsyncClient(); |
| 1365 | + |
| 1366 | + String uniqueId = serviceBusWithNewCall(caller, receiver); |
| 1367 | + |
| 1368 | + // create a call |
| 1369 | + List<CommunicationIdentifier> targets = Collections.singletonList(receiver); |
| 1370 | + CreateGroupCallOptions createCallOptions |
| 1371 | + = new CreateGroupCallOptions(targets, DISPATCHER_CALLBACK + String.format("?q=%s", uniqueId)); |
| 1372 | + Response<CreateCallResult> createCallResultResponse |
| 1373 | + = callerAsyncClient.createGroupCallWithResponse(createCallOptions).block(); |
| 1374 | + assertNotNull(createCallResultResponse); |
| 1375 | + CreateCallResult createCallResult = createCallResultResponse.getValue(); |
| 1376 | + assertNotNull(createCallResult); |
| 1377 | + assertNotNull(createCallResult.getCallConnectionProperties()); |
| 1378 | + String callerConnectionId = createCallResult.getCallConnectionProperties().getCallConnectionId(); |
| 1379 | + assertNotNull(callerConnectionId); |
| 1380 | + |
| 1381 | + // wait for the incomingCallContext |
| 1382 | + String incomingCallContext = waitForIncomingCallContext(uniqueId, Duration.ofSeconds(10)); |
| 1383 | + assertNotNull(incomingCallContext); |
| 1384 | + |
| 1385 | + // answer the call |
| 1386 | + AnswerCallOptions answerCallOptions |
| 1387 | + = new AnswerCallOptions(incomingCallContext, DISPATCHER_CALLBACK + String.format("?q=%s", uniqueId)); |
| 1388 | + AnswerCallResult answerCallResult |
| 1389 | + = Objects.requireNonNull(receiverAsyncClient.answerCallWithResponse(answerCallOptions).block()) |
| 1390 | + .getValue(); |
| 1391 | + assertNotNull(answerCallResult); |
| 1392 | + assertNotNull(answerCallResult.getCallConnectionAsync()); |
| 1393 | + assertNotNull(answerCallResult.getCallConnectionProperties()); |
| 1394 | + callDestructors.add(answerCallResult.getCallConnectionAsync()); |
| 1395 | + |
| 1396 | + // wait for callConnected |
| 1397 | + CallConnected callConnected = waitForEvent(CallConnected.class, callerConnectionId, Duration.ofSeconds(10)); |
| 1398 | + assertNotNull(callConnected); |
| 1399 | + |
| 1400 | + // hold the participant |
| 1401 | + CallMediaAsync callMediaAsync = createCallResult.getCallConnectionAsync().getCallMediaAsync(); |
| 1402 | + PlaySource holdPlaySource = new FileSource().setUrl(MEDIA_SOURCE); |
| 1403 | + callMediaAsync.hold(receiver, holdPlaySource).block(); |
| 1404 | + sleepIfRunningAgainstService(3000); |
| 1405 | + HoldAudioStarted holdAudioStarted |
| 1406 | + = waitForEvent(HoldAudioStarted.class, callerConnectionId, Duration.ofSeconds(20)); |
| 1407 | + assertNotNull(holdAudioStarted); |
| 1408 | + |
| 1409 | + CallConnectionAsync callConnectionAsync = callerAsyncClient.getCallConnectionAsync(callerConnectionId); |
| 1410 | + CallParticipant participantResult = callConnectionAsync.getParticipant(receiver).block(); |
| 1411 | + assertNotNull(participantResult); |
| 1412 | + assertTrue(participantResult.isOnHold()); |
| 1413 | + |
| 1414 | + // Assert multiple File Sources |
| 1415 | + List<PlaySource> playFileSources = new ArrayList<PlaySource>(); |
| 1416 | + playFileSources.add(new FileSource().setUrl(MEDIA_SOURCE)); |
| 1417 | + playFileSources.add(new FileSource().setUrl(MEDIA_SOURCE)); |
| 1418 | + PlayOptions playOptions = new PlayOptions(playFileSources, targets); |
| 1419 | + playOptions.setInterruptHoldAudio(true); |
| 1420 | + // Play multiple files sources |
| 1421 | + callMediaAsync.playWithResponse(playOptions).block(); |
| 1422 | + HoldAudioPaused holdAudioPaused |
| 1423 | + = waitForEvent(HoldAudioPaused.class, callerConnectionId, Duration.ofSeconds(20)); |
| 1424 | + assertNotNull(holdAudioPaused); |
| 1425 | + |
| 1426 | + PlayStarted playStarted = waitForEvent(PlayStarted.class, callerConnectionId, Duration.ofSeconds(20)); |
| 1427 | + assertNotNull(playStarted); |
| 1428 | + |
| 1429 | + PlayCompleted playCompleted = waitForEvent(PlayCompleted.class, callerConnectionId, Duration.ofSeconds(20)); |
| 1430 | + assertNotNull(playCompleted); |
| 1431 | + |
| 1432 | + HoldAudioResumed holdAudioResumed |
| 1433 | + = waitForEvent(HoldAudioResumed.class, callerConnectionId, Duration.ofSeconds(20)); |
| 1434 | + assertNotNull(holdAudioResumed); |
| 1435 | + |
| 1436 | + // unhold the participant |
| 1437 | + callMediaAsync.unhold(receiver).block(); |
| 1438 | + HoldAudioCompleted holdAudioCompleted |
| 1439 | + = waitForEvent(HoldAudioCompleted.class, callerConnectionId, Duration.ofSeconds(20)); |
| 1440 | + assertNotNull(holdAudioCompleted); |
| 1441 | + |
| 1442 | + sleepIfRunningAgainstService(3000); |
| 1443 | + participantResult = callConnectionAsync.getParticipant(receiver).block(); |
| 1444 | + assertNotNull(participantResult); |
| 1445 | + assertFalse(participantResult.isOnHold()); |
| 1446 | + } catch (Exception ex) { |
| 1447 | + fail("Unexpected exception received", ex); |
| 1448 | + } finally { |
| 1449 | + if (!callDestructors.isEmpty()) { |
| 1450 | + try { |
| 1451 | + callDestructors.forEach(callConnection -> callConnection.hangUpWithResponse(true).block()); |
| 1452 | + } catch (Exception ignored) { |
| 1453 | + // Some call might have been terminated during the test, and it will cause exceptions here. |
| 1454 | + // Do nothing and iterate to next call connection. |
| 1455 | + } |
| 1456 | + } |
| 1457 | + } |
| 1458 | + } |
1319 | 1459 | } |
0 commit comments