summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Twilio/TaskRouter/WorkflowConfiguration.php50
-rw-r--r--Twilio/TaskRouter/WorkflowRule.php32
-rw-r--r--Twilio/TaskRouter/WorkflowRuleTarget.php39
-rw-r--r--Twilio/Tests/Unit/WorkflowTest.php414
-rw-r--r--Twilio/Tests/phpunit.xml1
5 files changed, 536 insertions, 0 deletions
diff --git a/Twilio/TaskRouter/WorkflowConfiguration.php b/Twilio/TaskRouter/WorkflowConfiguration.php
new file mode 100644
index 0000000..4b8b88e
--- /dev/null
+++ b/Twilio/TaskRouter/WorkflowConfiguration.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Twilio\TaskRouter;
+
+/**
+ * Twilio TaskRouter Workflow Builder
+ *
+ * @author Justin Witz <jwitz@twilio.com>
+ * @license http://creativecommons.org/licenses/MIT/ MIT
+ */
+class WorkflowConfiguration implements JsonSerializable {
+ public $filters;
+ public $default_filter;
+
+ public function __construct($filters, $default_filter = null)
+ {
+ $this->filters = $filters;
+ $this->default_filter = $default_filter;
+ }
+
+ public function toJSON() {
+ return json_encode($this);
+ }
+
+ public static function parse($json) {
+ return json_decode($json);
+ }
+
+ public static function fromJson($json) {
+ $configJSON = self::parse($json);
+ $default_filter = $configJSON->task_routing->default_filter;
+ $filters = array();
+ foreach($configJSON->task_routing->filters as $filter) {
+ // friendly_name and filter_friendly_name should map to same variable
+ $friendly_name = isset($filter->filter_friendly_name) ? $filter->filter_friendly_name : $filter->friendly_name;
+ $filter = new WorkflowRule($filter->expression, $filter->targets, $friendly_name);
+ $filters[] = $filter;
+ }
+ return new WorkflowConfiguration($filters, $default_filter);
+ }
+
+ public function jsonSerialize() {
+ $json = array();
+ $task_routing = array();
+ $task_routing["filters"] = $this->filters;
+ $task_routing["default_filter"] = $this->default_filter;
+ $json["task_routing"] = $task_routing;
+ return $json;
+ }
+} \ No newline at end of file
diff --git a/Twilio/TaskRouter/WorkflowRule.php b/Twilio/TaskRouter/WorkflowRule.php
new file mode 100644
index 0000000..bb3ed6b
--- /dev/null
+++ b/Twilio/TaskRouter/WorkflowRule.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Twilio\TaskRouter;
+
+/**
+ * Twilio TaskRouter Workflow Rule
+ *
+ * @author Justin Witz <jwitz@twilio.com>
+ * @license http://creativecommons.org/licenses/MIT/ MIT
+ */
+class WorkflowRule implements JsonSerializable {
+ public $expression;
+ public $friendly_name;
+ public $targets;
+
+ public function __construct($expression, $targets, $friendly_name = null)
+ {
+ $this->expression = $expression;
+ $this->targets = $targets;
+ $this->friendly_name = $friendly_name;
+ }
+
+ public function jsonSerialize() {
+ $json = array();
+ $json["expression"] = $this->expression;
+ $json["targets"] = $this->targets;
+ if($this->friendly_name != null) {
+ $json["friendly_name"] = $this->friendly_name;
+ }
+ return $json;
+ }
+} \ No newline at end of file
diff --git a/Twilio/TaskRouter/WorkflowRuleTarget.php b/Twilio/TaskRouter/WorkflowRuleTarget.php
new file mode 100644
index 0000000..43926a6
--- /dev/null
+++ b/Twilio/TaskRouter/WorkflowRuleTarget.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Twilio\TaskRouter;
+
+/**
+ * Twilio TaskRouter Workflow Rule Target
+ *
+ * @author Justin Witz <jwitz@twilio.com>
+ * @license http://creativecommons.org/licenses/MIT/ MIT
+ */
+class WorkflowRuleTarget implements JsonSerializable {
+ public $queue;
+ public $expression;
+ public $priority;
+ public $timeout;
+
+ public function __construct($queue, $priority = null, $timeout = null, $expression = null)
+ {
+ $this->queue = $queue;
+ $this->priority = $priority;
+ $this->timeout = $timeout;
+ $this->expression = $expression;
+ }
+
+ public function jsonSerialize() {
+ $json = array();
+ $json["queue"] = $this->queue;
+ if($this->priority != null) {
+ $json["priority"] = $this->priority;
+ }
+ if($this->timeout != null) {
+ $json["timeout"] = $this->timeout;
+ }
+ if($this->expression != null) {
+ $json["expression"] = $this->expression;
+ }
+ return $json;
+ }
+} \ No newline at end of file
diff --git a/Twilio/Tests/Unit/WorkflowTest.php b/Twilio/Tests/Unit/WorkflowTest.php
new file mode 100644
index 0000000..8f4cbd0
--- /dev/null
+++ b/Twilio/Tests/Unit/WorkflowTest.php
@@ -0,0 +1,414 @@
+<?php
+
+namespace Twilio\Tests\Unit;
+
+use Twilio\TaskRouter\WorkflowConfiguration;
+use Twilio\TaskRouter\WorkflowRule;
+use Twilio\TaskRouter\WorkflowRuleTarget;
+use Twilio\Tests\Unit\UnitTest;
+
+class WorkflowTest extends UnitTest {
+
+ public function testDefaultRuleTarget() {
+ $everyoneQueue = "WQf6724bd5005b30eeb6ea990c3e59e536";
+ $defaultTarget = new WorkflowRuleTarget($everyoneQueue);
+ $this->assertEquals($defaultTarget->queue, "WQf6724bd5005b30eeb6ea990c3e59e536");
+ $this->assertEquals($defaultTarget->priority, null);
+ $this->assertEquals($defaultTarget->timeout, null);
+ $this->assertEquals($defaultTarget->expression, null);
+ }
+
+ public function testSimpleRuleTarget() {
+ $everyoneQueue = "WQf6724bd5005b30eeb6ea990c3e59e536";
+ $priority = 10;
+ $timeout = 60;
+ $filterWorkerExpression = null;
+ $ruleTarget = new WorkflowRuleTarget($everyoneQueue, $priority, $timeout, $filterWorkerExpression);
+ $this->assertEquals($ruleTarget->queue, "WQf6724bd5005b30eeb6ea990c3e59e536");
+ $this->assertEquals($ruleTarget->priority, $priority);
+ $this->assertEquals($ruleTarget->timeout, $timeout);
+ $this->assertEquals($ruleTarget->expression, $filterWorkerExpression);
+ }
+
+ public function testFilterWorkerRuleTarget() {
+ $everyoneQueue = "WQf6724bd5005b30eeb6ea990c3e59e536";
+ $priority = 10;
+ $timeout = 60;
+ $filterWorkerExpression = "task.language IN worker.languages";
+ $ruleTarget = new WorkflowRuleTarget($everyoneQueue, $priority, $timeout, $filterWorkerExpression);
+ $this->assertEquals($ruleTarget->queue, "WQf6724bd5005b30eeb6ea990c3e59e536");
+ $this->assertEquals($ruleTarget->priority, $priority);
+ $this->assertEquals($ruleTarget->timeout, $timeout);
+ $this->assertEquals($ruleTarget->expression, $filterWorkerExpression);
+ }
+
+ public function testSimpleRule() {
+ $salesQueue = "WQf6724bd5005b30eeb6ea990c3e59e536";
+ $salesTarget = new WorkflowRuleTarget($salesQueue);
+ $expression = "type=='sales'";
+ $friendlyName = "Sales";
+ $salesTargets[] = $salesTarget;
+ $salesRule = new WorkflowRule($expression, $salesTargets, $friendlyName);
+ $this->assertEquals($salesRule->expression, $expression);
+ $this->assertEquals($salesRule->friendly_name, $friendlyName);
+ $this->assertEquals($salesRule->targets[0], $salesTarget);
+ }
+
+ public function testFullWorkflow() {
+ $salesQueue = "WQf6724bd5005b30eeb6ea990c3e59e536";
+ $marketingQueue = "WQ8c62f84b61ccfa6a333757cd508f0aae";
+ $supportQueue = "WQ5940dc0da87eaf6e3321d62041d4403b";
+ $everyoneQueue = "WQ6d29383312b24bd898a8df32779fc043";
+
+ $defaultTarget = new WorkflowRuleTarget($everyoneQueue);
+
+ $salesTargets = array();
+ $salesTarget = new WorkflowRuleTarget($salesQueue);
+ $salesTargets[] = $salesTarget;
+ $salesRule = new WorkflowRule("type=='sales'", $salesTargets, 'Sales');
+
+ $marketingTargets = array();
+ $marketingTarget = new WorkflowRuleTarget($marketingQueue);
+ $marketingTargets[] = $marketingTarget;
+ $marketingRule = new WorkflowRule("type=='marketing'", $marketingTargets, 'Marketing');
+
+ $supportTargets = array();
+ $supportTarget = new WorkflowRuleTarget($supportQueue);
+ $supportTargets[] = $supportTarget;
+ $supportRule = new WorkflowRule("type=='support'", $supportTargets, 'Support');
+
+ $rules[] = $salesRule;
+ $rules[] = $marketingRule;
+ $rules[] = $supportRule;
+
+ $configuration = new WorkflowConfiguration($rules, $defaultTarget);
+ $json = $configuration->toJSON();
+
+ $expectedJsonString = "{
+ \"task_routing\":{
+ \"filters\":[
+ {
+ \"expression\":\"type=='sales'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\"
+ }
+ ],
+ \"friendly_name\":\"Sales\"
+ },
+ {
+ \"expression\":\"type=='marketing'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\"
+ }
+ ],
+ \"friendly_name\":\"Marketing\"
+ },
+ {
+ \"expression\":\"type=='support'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\"
+ }
+ ],
+ \"friendly_name\":\"Support\"
+ }
+ ],
+ \"default_filter\":{
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
+ }
+ }
+ }";
+
+ // getting a trimmed, simple string
+ $jsonObject = json_decode($expectedJsonString);
+ $expectedJson = json_encode($jsonObject);
+
+ $this->assertEquals($json, $expectedJson);
+ }
+
+ public function testFullWorkflowWithTimeouts() {
+ $salesQueue = "WQf6724bd5005b30eeb6ea990c3e59e536";
+ $marketingQueue = "WQ8c62f84b61ccfa6a333757cd508f0aae";
+ $supportQueue = "WQ5940dc0da87eaf6e3321d62041d4403b";
+ $everyoneQueue = "WQ6d29383312b24bd898a8df32779fc043";
+
+ $defaultTarget = new WorkflowRuleTarget($everyoneQueue);
+
+ $salesTargets = array();
+ $salesTarget1 = new WorkflowRuleTarget($salesQueue, 5, 30);
+ $salesTarget2 = new WorkflowRuleTarget($salesQueue, 10);
+ $salesTargets[] = $salesTarget1;
+ $salesTargets[] = $salesTarget2;
+ $salesRule = new WorkflowRule("type=='sales'", $salesTargets, 'Sales');
+
+ $marketingTargets = array();
+ $marketingTarget1 = new WorkflowRuleTarget($marketingQueue, 1, 120);
+ $marketingTarget2 = new WorkflowRuleTarget($marketingQueue, 3);
+ $marketingTargets[] = $marketingTarget1;
+ $marketingTargets[] = $marketingTarget2;
+ $marketingRule = new WorkflowRule("type=='marketing'", $marketingTargets, 'Marketing');
+
+ $supportTargets = array();
+ $supportTarget1 = new WorkflowRuleTarget($supportQueue, 10, 30);
+ $supportTarget2 = new WorkflowRuleTarget($supportQueue, 15);
+ $supportTargets[] = $supportTarget1;
+ $supportTargets[] = $supportTarget2;
+ $supportRule = new WorkflowRule("type=='support'", $supportTargets, 'Support');
+
+ $rules[] = $salesRule;
+ $rules[] = $marketingRule;
+ $rules[] = $supportRule;
+
+ $configuration = new WorkflowConfiguration($rules, $defaultTarget);
+ $json = $configuration->toJSON();
+
+ $expectedJsonString = "{
+ \"task_routing\":{
+ \"filters\":[
+ {
+ \"expression\":\"type=='sales'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
+ \"priority\": 5,
+ \"timeout\": 30
+ },
+ {
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
+ \"priority\": 10
+ }
+ ],
+ \"friendly_name\":\"Sales\"
+ },
+ {
+ \"expression\":\"type=='marketing'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
+ \"priority\": 1,
+ \"timeout\": 120
+ },
+ {
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
+ \"priority\": 3
+ }
+ ],
+ \"friendly_name\":\"Marketing\"
+ },
+ {
+ \"expression\":\"type=='support'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
+ \"priority\": 10,
+ \"timeout\": 30
+ },
+ {
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
+ \"priority\": 15
+ }
+ ],
+ \"friendly_name\":\"Support\"
+ }
+ ],
+ \"default_filter\":{
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
+ }
+ }
+ }";
+
+ // getting a trimmed, simple string
+ $jsonObject = json_decode($expectedJsonString);
+ $expectedJson = json_encode($jsonObject);
+
+ $this->assertEquals($json, $expectedJson);
+ }
+
+ public function testParseWorkflow() {
+ $json = "{
+ \"task_routing\":{
+ \"filters\":[
+ {
+ \"expression\":\"type=='sales'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
+ \"priority\": 5,
+ \"timeout\": 30
+ },
+ {
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
+ \"priority\": 10
+ }
+ ],
+ \"friendly_name\":\"Sales\"
+ },
+ {
+ \"expression\":\"type=='marketing'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
+ \"priority\": 1,
+ \"timeout\": 120
+ },
+ {
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
+ \"priority\": 3
+ }
+ ],
+ \"friendly_name\":\"Marketing\"
+ },
+ {
+ \"expression\":\"type=='support'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
+ \"priority\": 10,
+ \"timeout\": 30
+ },
+ {
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
+ \"priority\": 15
+ }
+ ],
+ \"friendly_name\":\"Support\"
+ }
+ ],
+ \"default_filter\":{
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
+ }
+ }
+ }";
+
+ $config = WorkflowConfiguration::fromJson($json);
+ $taskRoutingConfig = WorkflowConfiguration::parse($json)->task_routing;
+
+ $this->assertEquals(3, count($taskRoutingConfig->filters));
+ $this->assertEquals(3, count($config->filters));
+ $this->assertEquals(1, count($config->default_filter));
+ // sales assertions
+ $this->assertEquals("type=='sales'", $config->filters[0]->expression);
+ $this->assertEquals("Sales", $config->filters[0]->friendly_name);
+ $this->assertEquals(2, count($config->filters[0]->targets));
+ $this->assertEquals("WQf6724bd5005b30eeb6ea990c3e59e536", $config->filters[0]->targets[0]->queue);
+ $this->assertEquals(5, $config->filters[0]->targets[0]->priority);
+ $this->assertEquals(30, $config->filters[0]->targets[0]->timeout);
+ $this->assertEquals("WQf6724bd5005b30eeb6ea990c3e59e536", $config->filters[0]->targets[1]->queue);
+ $this->assertEquals(10, $config->filters[0]->targets[1]->priority);
+ // marketing assertions
+ $this->assertEquals("type=='marketing'", $config->filters[1]->expression);
+ $this->assertEquals("Marketing", $config->filters[1]->friendly_name);
+ $this->assertEquals(2, count($config->filters[1]->targets));
+ $this->assertEquals("WQ8c62f84b61ccfa6a333757cd508f0aae", $config->filters[1]->targets[0]->queue);
+ $this->assertEquals(1, $config->filters[1]->targets[0]->priority);
+ $this->assertEquals(120, $config->filters[1]->targets[0]->timeout);
+ $this->assertEquals("WQ8c62f84b61ccfa6a333757cd508f0aae", $config->filters[1]->targets[1]->queue);
+ $this->assertEquals(3, $config->filters[1]->targets[1]->priority);
+ // support assertions
+ $this->assertEquals("type=='support'", $config->filters[2]->expression);
+ $this->assertEquals("Support", $config->filters[2]->friendly_name);
+ $this->assertEquals(2, count($config->filters[2]->targets));
+ $this->assertEquals("WQ5940dc0da87eaf6e3321d62041d4403b", $config->filters[2]->targets[0]->queue);
+ $this->assertEquals(10, $config->filters[2]->targets[0]->priority);
+ $this->assertEquals(30, $config->filters[2]->targets[0]->timeout);
+ $this->assertEquals("WQ5940dc0da87eaf6e3321d62041d4403b", $config->filters[2]->targets[1]->queue);
+ $this->assertEquals(15, $config->filters[2]->targets[1]->priority);
+ // default filter
+ $this->assertEquals("WQ6d29383312b24bd898a8df32779fc043", $config->default_filter->queue);
+ }
+
+ public function testParseWorkflowFilterFriendlyName() {
+ $json = "{
+ \"task_routing\":{
+ \"filters\":[
+ {
+ \"expression\":\"type=='sales'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
+ \"priority\": 5,
+ \"timeout\": 30
+ },
+ {
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
+ \"priority\": 10
+ }
+ ],
+ \"filter_friendly_name\":\"Sales\"
+ },
+ {
+ \"expression\":\"type=='marketing'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
+ \"priority\": 1,
+ \"timeout\": 120
+ },
+ {
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
+ \"priority\": 3
+ }
+ ],
+ \"filter_friendly_name\":\"Marketing\"
+ },
+ {
+ \"expression\":\"type=='support'\",
+ \"targets\":[
+ {
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
+ \"priority\": 10,
+ \"timeout\": 30
+ },
+ {
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
+ \"priority\": 15
+ }
+ ],
+ \"filter_friendly_name\":\"Support\"
+ }
+ ],
+ \"default_filter\":{
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
+ }
+ }
+ }";
+
+ $config = WorkflowConfiguration::fromJson($json);
+ $taskRoutingConfig = WorkflowConfiguration::parse($json)->task_routing;
+
+ $this->assertEquals(3, count($taskRoutingConfig->filters));
+ $this->assertEquals(3, count($config->filters));
+ $this->assertEquals(1, count($config->default_filter));
+ // sales assertions
+ $this->assertEquals("type=='sales'", $config->filters[0]->expression);
+ $this->assertEquals("Sales", $config->filters[0]->friendly_name);
+ $this->assertEquals(2, count($config->filters[0]->targets));
+ $this->assertEquals("WQf6724bd5005b30eeb6ea990c3e59e536", $config->filters[0]->targets[0]->queue);
+ $this->assertEquals(5, $config->filters[0]->targets[0]->priority);
+ $this->assertEquals(30, $config->filters[0]->targets[0]->timeout);
+ $this->assertEquals("WQf6724bd5005b30eeb6ea990c3e59e536", $config->filters[0]->targets[1]->queue);
+ $this->assertEquals(10, $config->filters[0]->targets[1]->priority);
+ // marketing assertions
+ $this->assertEquals("type=='marketing'", $config->filters[1]->expression);
+ $this->assertEquals("Marketing", $config->filters[1]->friendly_name);
+ $this->assertEquals(2, count($config->filters[1]->targets));
+ $this->assertEquals("WQ8c62f84b61ccfa6a333757cd508f0aae", $config->filters[1]->targets[0]->queue);
+ $this->assertEquals(1, $config->filters[1]->targets[0]->priority);
+ $this->assertEquals(120, $config->filters[1]->targets[0]->timeout);
+ $this->assertEquals("WQ8c62f84b61ccfa6a333757cd508f0aae", $config->filters[1]->targets[1]->queue);
+ $this->assertEquals(3, $config->filters[1]->targets[1]->priority);
+ // support assertions
+ $this->assertEquals("type=='support'", $config->filters[2]->expression);
+ $this->assertEquals("Support", $config->filters[2]->friendly_name);
+ $this->assertEquals(2, count($config->filters[2]->targets));
+ $this->assertEquals("WQ5940dc0da87eaf6e3321d62041d4403b", $config->filters[2]->targets[0]->queue);
+ $this->assertEquals(10, $config->filters[2]->targets[0]->priority);
+ $this->assertEquals(30, $config->filters[2]->targets[0]->timeout);
+ $this->assertEquals("WQ5940dc0da87eaf6e3321d62041d4403b", $config->filters[2]->targets[1]->queue);
+ $this->assertEquals(15, $config->filters[2]->targets[1]->priority);
+ // default filter
+ $this->assertEquals("WQ6d29383312b24bd898a8df32779fc043", $config->default_filter->queue);
+ }
+}
diff --git a/Twilio/Tests/phpunit.xml b/Twilio/Tests/phpunit.xml
index ba55d7e..40050b3 100644
--- a/Twilio/Tests/phpunit.xml
+++ b/Twilio/Tests/phpunit.xml
@@ -3,6 +3,7 @@
<testsuites>
<testsuite name="Twilio Test Suite">
<directory>./</directory>
+ <exclude>Unit/WorkflowTest.php</exclude>
</testsuite>
</testsuites>
</phpunit>