Skip to content

Commit

Permalink
Fixes NCCO parsing to and from arrays (#495)
Browse files Browse the repository at this point in the history
* update stream factory to accept arrays and strings

* Add tests, fix NCCO action factories casting incorrect data types

---------

Co-authored-by: Sam Taylor <[email protected]>
  • Loading branch information
itssamtaylor and itssamtaylor authored Aug 19, 2024
1 parent 700cd53 commit 4d9540e
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 4 deletions.
6 changes: 6 additions & 0 deletions src/Voice/NCCO/Action/Input.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ public static function factory(array $data): Input
if (array_key_exists('dtmf', $data)) {
$dtmf = $data['dtmf'];
$action->setEnableDtmf(true);
if (is_object($dtmf)) {
$dtmf = (array)$dtmf;
}

if (array_key_exists('timeOut', $dtmf)) {
$action->setDtmfTimeout((int)$dtmf['timeOut']);
Expand All @@ -103,6 +106,9 @@ public static function factory(array $data): Input
if (array_key_exists('speech', $data)) {
$speech = $data['speech'];
$action->setEnableSpeech(true);
if (is_object($speech)) {
$speech = (array)$speech;
}

if (array_key_exists('uuid', $speech)) {
$action->setSpeechUUID($speech['uuid'][0]);
Expand Down
3 changes: 3 additions & 0 deletions src/Voice/NCCO/Action/Notify.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public function __construct(protected array $payload, protected ?\Vonage\Voice\W
public static function factory(array $payload, array $data): Notify
{
if (array_key_exists('eventUrl', $data)) {
if (is_array($data['eventUrl'])) {
$data['eventUrl'] = $data['eventUrl'][0];
}
if (array_key_exists('eventMethod', $data)) {
$webhook = new Webhook($data['eventUrl'], $data['eventMethod']);
} else {
Expand Down
11 changes: 9 additions & 2 deletions src/Voice/NCCO/Action/Record.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ public static function factory(array $data): self
}

if (array_key_exists('channels', $data)) {
$action->setChannels($data['channels']);
$action->setChannels(
filter_var($data['channels'], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE)
);
}

if (array_key_exists('endOnSilence', $data)) {
Expand All @@ -85,7 +87,9 @@ public static function factory(array $data): self
}

if (array_key_exists('timeOut', $data)) {
$action->setTimeout($data['timeOut']);
$action->setTimeout(
filter_var($data['timeOut'], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE)
);
}

if (array_key_exists('beepStart', $data)) {
Expand All @@ -95,6 +99,9 @@ public static function factory(array $data): self
}

if (array_key_exists('eventUrl', $data)) {
if (is_array($data['eventUrl'])) {
$data['eventUrl'] = $data['eventUrl'][0];
}
if (array_key_exists('eventMethod', $data)) {
$webhook = new Webhook($data['eventUrl'], $data['eventMethod']);
} else {
Expand Down
7 changes: 5 additions & 2 deletions src/Voice/NCCO/Action/Stream.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ public function __construct(protected string $streamUrl)
}

/**
* @param array{streamUrl: string, bargeIn?: bool, level?: float, loop?: int, voiceName?: string} $data
* @param array{streamUrl: string|array, bargeIn?: bool, level?: float, loop?: int, voiceName?: string} $data
*/
public static function factory(string $streamUrl, array $data): Stream
public static function factory(string|array $streamUrl, array $data): Stream
{
if (is_array($streamUrl)) {
$streamUrl = $streamUrl[0];
}
$stream = new Stream($streamUrl);

if (array_key_exists('bargeIn', $data)) {
Expand Down
16 changes: 16 additions & 0 deletions test/Voice/NCCO/Action/StreamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,20 @@ public function testJsonSerializeLooksCorrect(): void
->setLoop(1)
->jsonSerialize());
}

public function testFactoryWithArray(): void
{
$this->assertSame([
'action' => 'stream',
'streamUrl' => ['https://test.domain/music.mp3']
], Stream::factory(['https://test.domain/music.mp3'], [])->toNCCOArray());
}

public function testFactoryWithString(): void
{
$this->assertSame([
'action' => 'stream',
'streamUrl' => ['https://test.domain/music.mp3']
], Stream::factory('https://test.domain/music.mp3', [])->toNCCOArray());
}
}
267 changes: 267 additions & 0 deletions test/Voice/NCCO/NCCOTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,271 @@ public function testCanCreateNCCOFromArray(): void
$this->assertCount(7, $json);
$this->assertEquals($data[0], $json[0]);
}

public function testCanCreateFromValidNCCOArray(): void
{
$data = [
[
"action" => "talk",
"text" => "Thank you for trying Vonage",
"bargeIn" => "false",
"level" => "0",
"loop" => "1",
"language" => "en-US",
"style" => "0",
"premium" => "false",
],
[
"action" => "record",
"format" => "wav",
"beepStart" => "true",
"endOnSilence" => "4",
"endOnKey" => "#",
"channels" => "12",
"split" => "conversation",
"timeOut" => "7200",
"eventUrl" => [
"http://domain.test/event",
],
"eventMethod" => "POST",
],
[
"action" => "conversation",
"name" => "Sample Conversation",
"startOnEnter" => "true",
"endOnExit" => "false",
"record" => "true",
"canSpeak" => [
"49502bca-da71-44bb-b3a6-5077b58c2690",
],
"canHear" => [
"798146f0-af79-468a-83a4-b6fcda7cd4e6",
],
],
[
"action" => "connect",
"endpoint" => [
[
"type" => "phone",
"number" => "447700900001",
],
],
],
[
"action" => "talk",
"text" => "Thank you for trying Vonage",
"bargeIn" => "false",
"level" => "0",
"loop" => "1",
"language" => "en-US",
"style" => "0",
"premium" => "false",
],
[
"action" => "record",
"format" => "wav",
"beepStart" => "true",
"endOnSilence" => "4",
"endOnKey" => "#",
"channels" => "12",
"split" => "conversation",
"timeOut" => "7200",
"eventUrl" => [
"http://domain.test/event",
],
"eventMethod" => "POST",
],
[
"action" => "conversation",
"name" => "Sample Conversation",
"startOnEnter" => "true",
"endOnExit" => "false",
"record" => "true",
"canSpeak" => [
"49502bca-da71-44bb-b3a6-5077b58c2690",
],
"canHear" => [
"798146f0-af79-468a-83a4-b6fcda7cd4e6",
],
],
[
"action" => "connect",
"endpoint" => [
[
"type" => "phone",
"number" => "447700900001",
],
],
],
[
"action" => "stream",
"streamUrl" => [
"http://domain.test/music.mp3",
],
"bargeIn" => "true",
"level" => "0.1",
"loop" => "0",
],
[
"action" => "input",
"dtmf" => [
"maxDigits" => 1,
],
"speech" => [
"uuid" => [
"49502bca-da71-44bb-b3a6-5077b58c2690",
],
"maxDuration" => 30,
],
],
[
"action" => "notify",
"payload" => [
"foo" => "bar",
],
"eventUrl" => [
"http://domain.test/event",
],
"eventMethod" => "POST",
],
];
$ncco = new NCCO();
$ncco->fromArray($data);
$this->assertEquals(json_encode($data), json_encode($ncco));
}

public function testCanConvertToAndFromArray(): void
{
$data = [
[
"action" => "talk",
"text" => "Thank you for trying Vonage",
"bargeIn" => "false",
"level" => "0",
"loop" => "1",
"language" => "en-US",
"style" => "0",
"premium" => "false",
],
[
"action" => "record",
"format" => "wav",
"beepStart" => "true",
"endOnSilence" => "4",
"endOnKey" => "#",
"channels" => "12",
"split" => "conversation",
"timeOut" => "7200",
"eventUrl" => [
"http://domain.test/event",
],
"eventMethod" => "POST",
],
[
"action" => "conversation",
"name" => "Sample Conversation",
"startOnEnter" => "true",
"endOnExit" => "false",
"record" => "true",
"canSpeak" => [
"49502bca-da71-44bb-b3a6-5077b58c2690",
],
"canHear" => [
"798146f0-af79-468a-83a4-b6fcda7cd4e6",
],
],
[
"action" => "connect",
"endpoint" => [
[
"type" => "phone",
"number" => "447700900001",
],
],
],
[
"action" => "talk",
"text" => "Thank you for trying Vonage",
"bargeIn" => "false",
"level" => "0",
"loop" => "1",
"language" => "en-US",
"style" => "0",
"premium" => "false",
],
[
"action" => "record",
"format" => "wav",
"beepStart" => "true",
"endOnSilence" => "4",
"endOnKey" => "#",
"channels" => "12",
"split" => "conversation",
"timeOut" => "7200",
"eventUrl" => [
"http://domain.test/event",
],
"eventMethod" => "POST",
],
[
"action" => "conversation",
"name" => "Sample Conversation",
"startOnEnter" => "true",
"endOnExit" => "false",
"record" => "true",
"canSpeak" => [
"49502bca-da71-44bb-b3a6-5077b58c2690",
],
"canHear" => [
"798146f0-af79-468a-83a4-b6fcda7cd4e6",
],
],
[
"action" => "connect",
"endpoint" => [
[
"type" => "phone",
"number" => "447700900001",
],
],
],
[
"action" => "stream",
"streamUrl" => [
"http://domain.test/music.mp3",
],
"bargeIn" => "true",
"level" => "0.1",
"loop" => "0",
],
[
"action" => "input",
"dtmf" => [
"maxDigits" => 1,
],
"speech" => [
"uuid" => [
"49502bca-da71-44bb-b3a6-5077b58c2690",
],
"maxDuration" => 30,
],
],
[
"action" => "notify",
"payload" => [
"foo" => "bar",
],
"eventUrl" => [
"http://domain.test/event",
],
"eventMethod" => "POST",
],
];
$ncco1 = new NCCO();
$ncco2 = new NCCO();
$ncco1->fromArray($data);
$ncco2->fromArray($ncco1->toArray());
$this->assertEquals($ncco1->toArray(), $ncco2->toArray());
$this->assertEquals(json_encode($data), json_encode($ncco2));
}
}

0 comments on commit 4d9540e

Please sign in to comment.