From 728b502966a53bb052c1efb532b863ae484ed0e5 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 2 Jun 2014 20:32:21 -0700 Subject: [PATCH] CRM-14476 - CRM_Case_BAO_CaseType - Add test for XML<=>array conversions. Fix corner-cases. --- CRM/Case/BAO/CaseType.php | 51 ++-- tests/phpunit/CRM/Case/BAO/CaseTypeTest.php | 262 ++++++++++++++++++++ 2 files changed, 291 insertions(+), 22 deletions(-) create mode 100644 tests/phpunit/CRM/Case/BAO/CaseTypeTest.php diff --git a/CRM/Case/BAO/CaseType.php b/CRM/Case/BAO/CaseType.php index 21a3f1e987..6fea8d02f4 100644 --- a/CRM/Case/BAO/CaseType.php +++ b/CRM/Case/BAO/CaseType.php @@ -91,7 +91,7 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType { $xmlFile = '' . "\n\n\n"; $xmlFile .= "{$name}\n"; - if (!empty($definition['activityTypes'])) { + if (isset($definition['activityTypes'])) { $xmlFile .= "\n"; foreach ($definition['activityTypes'] as $values) { $xmlFile .= "\n"; @@ -103,7 +103,7 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType { $xmlFile .= "\n"; } - if (!empty($definition['activitySets'])) { + if (isset($definition['activitySets'])) { $xmlFile .= "\n"; foreach ($definition['activitySets'] as $k => $val) { $xmlFile .= "\n"; @@ -132,7 +132,7 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType { $xmlFile .= "\n"; } - if (!empty($definition['caseRoles'])) { + if (isset($definition['caseRoles'])) { $xmlFile .= "\n"; foreach ($definition['caseRoles'] as $values) { $xmlFile .= "\n"; @@ -161,32 +161,39 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType { $definition = array(); // set activity types - $activityTypes = json_decode(json_encode($xml->ActivityTypes), TRUE); - $definition['activityTypes'] = $activityTypes['ActivityType']; - - // set activity sets - $activitySets = json_decode(json_encode($xml->ActivitySets), TRUE); - - // hack to fix the case when we have only one activityset - if (!empty($activitySets['ActivitySet']['name'])) { - $temp = $activitySets['ActivitySet']; - $activitySets['ActivitySet'] = array($temp); + if (isset($xml->ActivityTypes)) { + $definition['activityTypes'] = array(); + foreach ($xml->ActivityTypes->ActivityType as $activityTypeXML) { + $definition['activityTypes'][] = json_decode(json_encode($activityTypeXML), TRUE); + } } - foreach ($activitySets['ActivitySet'] as $key => $value) { - foreach ($value as $k => $val) { - if ( $k == 'ActivityTypes') { - $definition['activitySets'][$key]['activityTypes'] = array_pop(array_values($val)); - } - else { - $definition['activitySets'][$key][$k] = $val; + // set activity sets + if (isset($xml->ActivitySets)) { + $definition['activitySets'] = array(); + foreach ($xml->ActivitySets->ActivitySet as $activitySetXML) { + // parse basic properties + $activitySet = json_decode(json_encode($activitySetXML), TRUE); + unset($activitySet['ActivityTypes']); // not parsed reliably (eg single-tag vs multi-tag) + + // parse activity-types + if (isset($activitySetXML->ActivityTypes)) { + $activitySet['activityTypes'] = array(); + foreach ($activitySetXML->ActivityTypes->ActivityType as $activityTypeXML) { + $activitySet['activityTypes'][] = json_decode(json_encode($activityTypeXML), TRUE); + } } + $definition['activitySets'][] = $activitySet; } } // set case roles - $caseRoles = json_decode(json_encode($xml->CaseRoles), TRUE); - $definition['caseRoles'] = $caseRoles['RelationshipType']; + if (isset($xml->CaseRoles)) { + $definition['caseRoles'] = array(); + foreach ($xml->CaseRoles->RelationshipType as $caseRoleXml) { + $definition['caseRoles'][] = json_decode(json_encode($caseRoleXml), TRUE); + } + } return $definition; } diff --git a/tests/phpunit/CRM/Case/BAO/CaseTypeTest.php b/tests/phpunit/CRM/Case/BAO/CaseTypeTest.php new file mode 100644 index 0000000000..d26c9ddd32 --- /dev/null +++ b/tests/phpunit/CRM/Case/BAO/CaseTypeTest.php @@ -0,0 +1,262 @@ + json_encode(array()), + 'xml' => ' + + Housing Support + + ', + ); + + $fixtures['empty-lists'] = array( + 'json' => json_encode(array( + 'activitySets' => array(), + 'activityTypes' => array(), + 'caseRoles' => array(), + )), + 'xml' => ' + + Housing Support + + + + + ', + ); + + $fixtures['one-item-in-each'] = array( + 'json' => json_encode(array( + 'activityTypes' => array( + array('name' => 'First act'), + ), + 'activitySets' => array( + array( + 'name' => 'set1', + 'label' => 'Label 1', + 'timeline' => 'true', + 'activityTypes' => array( + array('name' => 'Open Case', 'status' => 'Completed'), + ), + ), + ), + 'caseRoles' => array( + array('name' => 'First role', 'creator' => 1, 'manager' => 1), + ), + )), + 'xml' => ' + + Housing Support + + + First act + + + + + set1 + + true + + + Open Case + Completed + + + + + + + First role + 1 + 1 + + + + ', + ); + + $fixtures['two-items-in-each'] = array( + 'json' => json_encode(array( + 'activityTypes' => array( + array('name' => 'First act'), + array('name' => 'Second act'), + ), + 'activitySets' => array( + array( + 'name' => 'set1', + 'label' => 'Label 1', + 'timeline' => 'true', + 'activityTypes' => array( + array('name' => 'Open Case', 'status' => 'Completed'), + array( + 'name' => 'Meeting', + 'reference_activity' => 'Open Case', + 'reference_offset' => 1, + 'reference_select' => 'newest', + ), + ), + ), + array( + 'name' => 'set2', + 'label' => 'Label 2', + 'sequence' => 'true', + 'activityTypes' => array( + array('name' => 'First act'), + array('name' => 'Second act'), + ), + ), + ), + 'caseRoles' => array( + array('name' => 'First role', 'creator' => 1, 'manager' => 1), + array('name' => 'Second role'), + ), + )), + 'xml' => ' + + Housing Support + + + First act + + + Second act + + + + + set1 + + true + + + Open Case + Completed + + + Meeting + Open Case + 1 + newest + + + + + set2 + + true + + + First act + + + Second act + + + + + + + First role + 1 + 1 + + + Second role + + + + ', + ); + + $cases = array(); + foreach (array( + 'empty-defn', + 'empty-lists', + 'one-item-in-each', + 'two-items-in-each', + ) as $key) { + $cases[] = array($key, $fixtures[$key]['json'], $fixtures[$key]['xml']); + } + return $cases; + } + + /** + * @param string $fixtureName + * @param string $expectedJson + * @param string $inputXml + * @dataProvider definitionProvider + */ + function testConvertXmlToDefinition($fixtureName, $expectedJson, $inputXml) { + $xml = simplexml_load_string($inputXml); + $expectedDefinition = json_decode($expectedJson, TRUE); + $actualDefinition = CRM_Case_BAO_CaseType::convertXmlToDefinition($xml); + $this->assertEquals($expectedDefinition, $actualDefinition); + } + + /** + * @param string $fixtureName + * @param string $inputJson + * @param string $expectedXml + * @dataProvider definitionProvider + */ + function testConvertDefinitionToXml($fixtureName, $inputJson, $expectedXml) { + $inputDefinition = json_decode($inputJson, TRUE); + $actualXml = CRM_Case_BAO_CaseType::convertDefinitionToXML('Housing Support', $inputDefinition); + $this->assertEquals($this->normalizeXml($expectedXml), $this->normalizeXml($actualXml)); + } + + /** + * @param string $fixtureName + * @param string $ignore + * @param string $inputXml + * @dataProvider definitionProvider + */ + function testRoundtrip_XmlToJsonToXml($fixtureName, $ignore, $inputXml) { + $tempDefinition = CRM_Case_BAO_CaseType::convertXmlToDefinition(simplexml_load_string($inputXml)); + $actualXml = CRM_Case_BAO_CaseType::convertDefinitionToXML('Housing Support', $tempDefinition); + $this->assertEquals($this->normalizeXml($inputXml), $this->normalizeXml($actualXml)); + } + + /** + * @param string $fixtureName + * @param string $inputJson + * @param string $ignore + * @dataProvider definitionProvider + */ + function testRoundtrip_JsonToXmlToJson($fixtureName, $inputJson, $ignore) { + $tempXml = CRM_Case_BAO_CaseType::convertDefinitionToXML('Housing Support', json_decode($inputJson, TRUE)); + $actualDefinition = CRM_Case_BAO_CaseType::convertXmlToDefinition(simplexml_load_string($tempXml)); + $expectedDefinition = json_decode($inputJson, TRUE); + $this->assertEquals($expectedDefinition, $actualDefinition); + } + + /** + * Normalize the whitespace in an XML document + * + * @param string $xml + * @return string + */ + function normalizeXml($xml) { + return trim( + preg_replace(":\n*<:", "\n<", // tags on new lines + preg_replace("/\n[\n ]+/", "\n", // no leading whitespace + $xml + ) + ) + ); + } +} \ No newline at end of file -- 2.25.1