From 63d9785dfe47ca6d2680c3dad1a393448b5cabd2 Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Wed, 8 Jul 2020 11:06:01 -0400 Subject: [PATCH 01/10] [Test] unittests for NDB_BVL_Instrument libraries --- ...N_Test.php => NDB_BVL_Instrument_Test.php} | 295 +++++++++++++----- 1 file changed, 222 insertions(+), 73 deletions(-) rename test/unittests/{NDB_BVL_Instrument_ToJSON_Test.php => NDB_BVL_Instrument_Test.php} (57%) diff --git a/test/unittests/NDB_BVL_Instrument_ToJSON_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php similarity index 57% rename from test/unittests/NDB_BVL_Instrument_ToJSON_Test.php rename to test/unittests/NDB_BVL_Instrument_Test.php index 157cb634e61..2c9d74e2fc9 100644 --- a/test/unittests/NDB_BVL_Instrument_ToJSON_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -1,4 +1,15 @@ + * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 + * @link https://www.github.com/aces/Loris/ + */ namespace Loris\Tests; set_include_path(get_include_path().":" . __DIR__ . "/../../php/libraries:"); use PHPUnit\Framework\TestCase; @@ -6,25 +17,45 @@ require_once __DIR__ . '/../../php/libraries/NDB_BVL_Instrument.class.inc'; require_once 'Smarty_hook.class.inc'; require_once 'NDB_Config.class.inc'; - -class NDB_BVL_Instrument_ToJSON_Test extends TestCase +/** + * Unit test for NDB_BVL_Instrument class + * + * PHP Version 7 + * + * @category Tests + * @package Main + * @author Dave MacFarlane + * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 + * @link https://www.github.com/aces/Loris/ + */ +class NDB_BVL_Instrument_Test extends TestCase { + private $_instrument; /** * Set up sets a fake $_SESSION object that we can use for * assertions + * + * @return void */ - function setUp() { + function setUp() + { global $_SESSION; - if(!defined("UNIT_TESTING")) { + if (!defined("UNIT_TESTING")) { define("UNIT_TESTING", true); } date_default_timezone_set("UTC"); - $this->Session = $this->getMockBuilder(\stdClass::class)->setMethods(array('getProperty', 'setProperty', 'getUsername', 'isLoggedIn'))->getMock(); - $this->MockSinglePointLogin = $this->getMockBuilder('SinglePointLogin')->getMock(); - $this->Session->method("getProperty")->willReturn($this->MockSinglePointLogin); + $this->session = $this->getMockBuilder(\stdClass::class) + ->setMethods( + array('getProperty', 'setProperty', 'getUsername', 'isLoggedIn') + ) + ->getMock(); + $this->mockSinglePointLogin = $this->getMockBuilder('SinglePointLogin') + ->getMock(); + $this->session->method("getProperty") + ->willReturn($this->mockSinglePointLogin); $_SESSION = array( - 'State' => $this->Session + 'State' => $this->session ); $factory = \NDB_Factory::singleton(); @@ -37,30 +68,41 @@ function setUp() { \NDB_Factory::$testdb = $mockdb; \NDB_Factory::$config = $mockconfig; - $this->QuickForm = new \LorisForm(); //$this->getMock("HTML_Quickform"); - $this->Client = new \NDB_Client; - $this->Client->makeCommandLine(); - $this->Client->initialize(__DIR__ . "/../../project/config.xml"); + $this->quickForm = new \LorisForm(); - $this->i = $this->getMockBuilder(\NDB_BVL_Instrument::class)->disableOriginalConstructor()->setMethods(array("getFullName", "getSubtestList"))->getMock(); - $this->i->method('getFullName')->willReturn("Test Instrument"); - $this->i->method('getSubtestList')->willReturn(array()); - $this->i->form = $this->QuickForm; - $this->i->testName = "Test"; + $this->_instrument = $this->getMockBuilder(\NDB_BVL_Instrument::class) + ->disableOriginalConstructor() + ->setMethods(array("getFullName", "getSubtestList"))->getMock(); + $this->_instrument->method('getFullName')->willReturn("Test Instrument"); + $this->_instrument->method('getSubtestList')->willReturn(array()); + $this->_instrument->form = $this->quickForm; + $this->_instrument->testName = "Test"; } /** * Helper function to use for creating stubs that stub out everything except * the method being tested + * + * @param $methods The method being tested + * + * @return array */ - function _getAllMethodsExcept($methods) { + function _getAllMethodsExcept($methods) + { $AllMethods = get_class_methods('NDB_BVL_Instrument'); return array_diff($AllMethods, $methods); } - function testMetaData() { - $json = $this->i->toJSON(); + /** + * Test that the toJSON method returns the correct metadata + * + * @covers NDB_BVL_Instrument::toJSON + * @return void + */ + function testMetaData() + { + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $ExpectedMeta = [ 'InstrumentVersion' => "1l", @@ -72,14 +114,34 @@ function testMetaData() { $this->assertEquals($ExpectedMeta, $outArray['Meta']); } - function testSelectElement() { + /** + * Test that addSelect and addElement add the correct information + * and that toJSON returns this data + * + * @covers NDB_BVL_Instrument::toJSON + * @return void + */ + function testSelectElement() + { $value = array('value' => "Option"); $not_answered = array('value' => 'Option', 'not_answered' => 'Not Answered'); - $this->i->addSelect("FieldName", "Field Description", $value); - $this->i->addSelect("FieldName2", "Field Description 2", $not_answered); - $this->i->form->addElement('select', "multiselect1", "Test Question", $value, array("multiple" => 'multiple')); - $this->i->form->addElement('select', "multiselect2", "Test Question", $not_answered, array('multiple' => "multiple")); - $json = $this->i->toJSON(); + $this->_instrument->addSelect("FieldName", "Field Description", $value); + $this->_instrument->addSelect( + "FieldName2", "Field Description 2", $not_answered + ); + $this->_instrument->form->addElement( + 'select', + "multiselect1", + "Test Question", + $value, array("multiple" => 'multiple') + ); + $this->_instrument->form->addElement( + 'select', + "multiselect2", + "Test Question", + $not_answered, array('multiple' => "multiple") + ); + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $selectElement = $outArray['Elements'][0]; $selectElement2 = $outArray['Elements'][1]; @@ -87,7 +149,8 @@ function testSelectElement() { $multiselectElement = $outArray['Elements'][2]; $multiselectElement2 = $outArray['Elements'][3]; - $this->assertEquals($selectElement, + $this->assertEquals( + $selectElement, [ 'Type' => "select", "Name" => "FieldName", @@ -101,7 +164,8 @@ function testSelectElement() { ] ); - $this->assertEquals($selectElement2, + $this->assertEquals( + $selectElement2, [ 'Type' => "select", "Name" => "FieldName2", @@ -115,7 +179,8 @@ function testSelectElement() { ] ); - $this->assertEquals($multiselectElement, + $this->assertEquals( + $multiselectElement, [ 'Type' => "select", "Name" => "multiselect1", @@ -130,7 +195,8 @@ function testSelectElement() { ] ); - $this->assertEquals($multiselectElement2, + $this->assertEquals( + $multiselectElement2, [ 'Type' => "select", "Name" => "multiselect2", @@ -147,15 +213,30 @@ function testSelectElement() { } - function testTextElement() { - $this->i->addTextElement("FieldName", "Field Description for Text", array("value" => "Option")); - $this->i->addTextAreaElement("FieldName2", "Field Description2 for Text", array("value" => "Option")); - $json = $this->i->toJSON(); + /** + * Test that addTextElement and addTextAreaElement adds the correct data to + * the instrument + * + * @covers NDB_BVL_Instrument::addTextElement + * @covers NDB_BVL_Instrument::addTextAreaElement + * @covers NDB_BVL_Instrument::toJSON + * @return void + */ + function testTextElement() + { + $this->_instrument->addTextElement( + "FieldName", "Field Description for Text", array("value" => "Option") + ); + $this->_instrument->addTextAreaElement( + "FieldName2", "Field Description2 for Text", array("value" => "Option") + ); + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $textElement = $outArray['Elements'][0]; $textareaElement = $outArray['Elements'][1]; - $this->assertEquals($textElement, + $this->assertEquals( + $textElement, [ 'Type' => "text", "Name" => "FieldName", @@ -167,7 +248,8 @@ function testTextElement() { ] ); - $this->assertEquals($textareaElement, + $this->assertEquals( + $textareaElement, [ 'Type' => "text", "Name" => "FieldName2", @@ -180,8 +262,18 @@ function testTextElement() { ); } - function testDateElement() { - $this->i->addBasicDate( + /** + * Test that addBasicDate (from NDB_Page) and addDateElement + * adds the correct date to the instrument object + * + * @covers NDB_Page::addBasicDate + * @covers NDB_Page::addDateElement + * @covers NDB_Page::toJSON + * @return void + */ + function testDateElement() + { + $this->_instrument->addBasicDate( "FieldName", "Field Description", [ @@ -191,7 +283,7 @@ function testDateElement() { "addEmptyOption" => false, ] ); - $this->i->addBasicDate( + $this->_instrument->addBasicDate( "FieldName2", "Field Description", [ @@ -202,7 +294,7 @@ function testDateElement() { ] ); - $this->i->addDateElement( + $this->_instrument->addDateElement( "FieldName3", "Field Description", [ @@ -212,7 +304,7 @@ function testDateElement() { "addEmptyOption" => false, ] ); - $this->i->addDateElement( + $this->_instrument->addDateElement( "FieldName4", "Field Description", [ @@ -222,7 +314,7 @@ function testDateElement() { "addEmptyOption" => true, ] ); - $json = $this->i->toJSON(); + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $dateElement = $outArray['Elements'][0]; $dateElement2 = $outArray['Elements'][1]; @@ -258,13 +350,22 @@ function testDateElement() { $this->assertEquals($dateElement4, $expectedResult); } - function testNumericElement() { - $this->i->addNumericElement("TestElement", "Test Description"); - $json = $this->i->toJSON(); + /** + * Test that addNumericElement adds the correct data to the instrument + * + * @covers NDB_BVL_Instrument::addNumericElement + * @covers NDB_BVL_Instrument::toJSON + * @return void + */ + function testNumericElement() + { + $this->_instrument->addNumericElement("TestElement", "Test Description"); + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $numericElement = $outArray['Elements'][0]; - $this->assertEquals($numericElement, + $this->assertEquals( + $numericElement, [ "Type" => "numeric", "Name" => "TestElement", @@ -277,29 +378,40 @@ function testNumericElement() { } - function testScoreElement() { - $this->i->addScoreColumn( + /** + * Test that addScoreColumn (from NDB_Page) adds the data to the + * instrument object + * + * @covers NDB_Page::addScoreColumn + * @covers NDB_BVL_Instrument::toJSON + * @return void + */ + function testScoreElement() + { + $this->_instrument->addScoreColumn( "FieldName", "Field Description", "45" ); - $this->i->addScoreColumn( + $this->_instrument->addScoreColumn( "FieldName2", null ); - $json = $this->i->toJSON(); + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $scoreElement = $outArray['Elements'][0]; $scoreElement2 = $outArray['Elements'][1]; - $this->assertEquals($scoreElement, + $this->assertEquals( + $scoreElement, [ 'Type' => "score", "Name" => "FieldName", "Description" => "Field Description", ] ); - $this->assertEquals($scoreElement2, + $this->assertEquals( + $scoreElement2, [ 'Type' => "score", "Name" => "FieldName2", @@ -308,26 +420,39 @@ function testScoreElement() { } - function testHeaderElement() { + /** + * Test that when a header element is added, the toJSON method returns the + * element in the correct format + * + * @covers NDB_BVL_Instrument::toJSON + * @return void + */ + function testHeaderElement() + { // Since QuickForm arbitrarily decides to split things into "sections" // when there's a header, the header test adds 2 headers to ensure that // the JSON serialization was done according to spec, and not according // to QuickForm's whims. // The first "section" has no elements, and the second one, to make sure // that the serialization won't die on a 0 element "section" - $this->i->form->addElement("header", null, "I am your test header"); - $this->i->form->addElement("header", null, "I am another test header"); - $this->i->addScoreColumn( + $this->_instrument->form->addElement( + "header", null, "I am your test header" + ); + $this->_instrument->form->addElement( + "header", null, "I am another test header" + ); + $this->_instrument->addScoreColumn( "FieldName2", "Field Description", "45" ); - $json = $this->i->toJSON(); + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $headerElement = $outArray['Elements'][0]; $headerElement2= $outArray['Elements'][1]; - $this->assertEquals($headerElement, + $this->assertEquals( + $headerElement, [ 'Type' => "header", "Description" => "I am your test header", @@ -336,7 +461,8 @@ function testHeaderElement() { ] ] ); - $this->assertEquals($headerElement2, + $this->assertEquals( + $headerElement2, [ 'Type' => "header", "Description" => "I am another test header", @@ -349,13 +475,23 @@ function testHeaderElement() { $this->assertEquals(count($outArray['Elements']), 3); } - function testLabelElement() { - $this->i->addLabel("I am a label"); - $json = $this->i->toJSON(); + /** + * Test that addLabel (from NDB_Page) adds the label element + * to the instrument object + * + * @covers NDB_Page::addLabel + * @covers NDB_BVL_Instrument::toJSON + * @return void + */ + function testLabelElement() + { + $this->_instrument->addLabel("I am a label"); + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $labelElement = $outArray['Elements'][0]; - $this->assertEquals($labelElement, + $this->assertEquals( + $labelElement, [ 'Type' => "label", "Description" => "I am a label" @@ -364,25 +500,37 @@ function testLabelElement() { $this->assertEquals(count($outArray['Elements']), 1); } - function testPageGroup() { - $this->i = $this->getMockBuilder(\NDB_BVL_Instrument::class)->disableOriginalConstructor()->setMethods(array("getFullName", "getSubtestList", '_setupForm'))->getMock(); - $this->i->method('getFullName')->willReturn("Test Instrument"); - $this->i->method('getSubtestList')->willReturn( + /** + * Test that toJSON gets the subtest list and full name elements of + * the instrument + * + * @covers NDB_BVL_Instrument::toJSON + * @return void + */ + function testPageGroup() + { + $this->_instrument = $this->getMockBuilder(\NDB_BVL_Instrument::class) + ->disableOriginalConstructor() + ->setMethods( + array("getFullName", "getSubtestList", '_setupForm') + )->getMock(); + $this->_instrument->method('getFullName')->willReturn("Test Instrument"); + $this->_instrument->method('getSubtestList')->willReturn( array( array('Name' => 'Page 1', 'Description' => 'The first page'), array('Name' => 'Page 2', 'Description' => 'The second page'), ) ); - $this->i->form = $this->QuickForm; - $this->i->testName = "Test"; - + $this->_instrument->form = $this->quickForm; + $this->_instrument->testName = "Test"; - $json = $this->i->toJSON(); + $json = $this->_instrument->toJSON(); $outArray = json_decode($json, true); $page1 = $outArray['Elements'][0]; $page2 = $outArray['Elements'][1]; - $this->assertEquals($page1, + $this->assertEquals( + $page1, [ 'Type' => 'ElementGroup', 'GroupType' => 'Page', @@ -390,7 +538,8 @@ function testPageGroup() { 'Description' => 'The first page' ] ); - $this->assertEquals($page2, + $this->assertEquals( + $page2, [ 'Type' => 'ElementGroup', 'GroupType' => 'Page', From e992a67a961cd00adda468ed47d20bc523687396 Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Wed, 8 Jul 2020 15:47:26 -0400 Subject: [PATCH 02/10] Added tests --- test/unittests/NDB_BVL_Instrument_Test.php | 152 +++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/test/unittests/NDB_BVL_Instrument_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php index 2c9d74e2fc9..22170a739eb 100644 --- a/test/unittests/NDB_BVL_Instrument_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -260,6 +260,53 @@ function testTextElement() ] ] ); + + $textRules = $this->_instrument->XINRules['FieldName']; + $textAreaRules = $this->_instrument->XINRules['FieldName2']; + $this->assertEquals( + $textRules, + [ + 'message' => 'This field is required.', + 'group' => 'FieldName_group', + 'rules' => ['FieldName_status{@}=={@}', 'Option'] + ] + ); + $this->assertEquals( + $textAreaRules, + [ + 'message' => 'This field is required.', + 'group' => 'FieldName2_group', + 'rules' => ['FieldName2_status{@}=={@}', 'Option'] + ] + ); + } + + /** + * Test that addTextAreaElementRD adds a group element to the instrument + * + * @covers NDB_BVL_Instrument::addTextAreaElementRD + * @return void + */ + function testAddTextAreaElement() + { + $this->_instrument->addTextAreaElementRD( + "FieldName1", "Field Description1", array("value" => "Option") + ); + $json = $this->_instrument->toJSON(); + $outArray = json_decode($json, true); + $this->assertEquals( + $outArray['Elements'][0], + ['Type' => "Group", 'Error' => "Unimplemented"] + ); + $textRules = $this->_instrument->XINRules['FieldName1']; + $this->assertEquals( + $textRules, + [ + 'message' => 'You must specify or select from the drop-down', + 'group' => 'FieldName1_group', + 'rules' => ['FieldName1_status{@}=={@}', 'Option'] + ] + ); } /** @@ -548,5 +595,110 @@ function testPageGroup() ] ); } + + /** + * Test that setup correctly sets the commentID and page values of the + * instrument and that getCommentID returns the commentID value. + * + * @covers NDB_BVL_Instrument::setup + * @covers NDB_BVL_Instrument::getCommentID + * @return void + */ + function testSetup() + { + $this->_instrument->setup("commentID", "page"); + $this->assertEquals("commentID", $this->_instrument->getCommentID()); + $this->assertEquals("page", $this->_instrument->page); + + } + + /** + * Test that calculateAgeMonths returns the correct number of months + * for the given age array. + * + * @covers NDB_BVL_Instrument::calculateAgeMonths + * @return void + */ + function testCalculateAgeMonths() + { + $age = array('year' => 3, 'mon' => 4, 'day' => 23); + $months = $this->_instrument->calculateAgeMonths($age); + $this->assertEquals(40.8, $months); + } + + /** + * Test that calculateAgeDays returns the correct number of days + * for the given age array + * + * @covers NDB_BVL_Instrument::calculateAgeDays + * @return void + */ + function testCalculateAgeDays() + { + $age = array('year' => 3, 'mon' => 4, 'day' => 23); + $days = $this->_instrument->calculateAgeDays($age); + $this->assertEquals(1238, $days); + } + + /** + * Test that addYesNoElement adds an element to the instrument with + * yes/no options + * + * @covers NDB_BVL_Instrument::addYesNoElement + * @return void + */ + function testAddYesNoElement() + { + $this->_instrument->addYesNoElement("field1", "label1"); + $json = $this->_instrument->toJSON(); + $outArray = json_decode($json, true); + $this->assertEquals( + $outArray['Elements'][0], + array('Type' => 'select', + 'Name' => 'field1', + 'Description' => 'label1', + 'Options' => array('Values' => array('' => '', + 'yes' => 'Yes', + 'no' => 'No'), + 'RequireResponse' => true) + ) + ); + } + + /** + * Test that addYesNoElement adds an element and registers a XIN rule + * if specified. + * + * @covers NDB_BVL_Instrument::addYesNoElementWithRules + * @return void + */ + function testAddYesNoElementWithRules() + { + $this->_instrument->addYesNoElement( + "field1", "label1", ["rule1"], "Rule message" + ); + $json = $this->_instrument->toJSON(); + $outArray = json_decode($json, true); + $this->assertEquals( + $outArray['Elements'][0], + array('Type' => 'select', + 'Name' => 'field1', + 'Description' => 'label1', + 'Options' => array('Values' => array('' => '', + 'yes' => 'Yes', + 'no' => 'No'), + 'RequireResponse' => true) + ) + ); + $rules = $this->_instrument->XINRules["field1"]; + $this->assertEquals( + $rules, + array('message' => 'Rule message', + 'group' => '', + 'rules' => ['rule1'] + ) + ); + } + } ?> From 9b4a641e35185ce598a43d0ae4007c91e9b1847b Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Mon, 13 Jul 2020 14:16:48 -0400 Subject: [PATCH 03/10] More tests added --- test/unittests/NDB_BVL_Instrument_Test.php | 258 ++++++++++++++++++++- 1 file changed, 257 insertions(+), 1 deletion(-) diff --git a/test/unittests/NDB_BVL_Instrument_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php index 22170a739eb..0180f870fe5 100644 --- a/test/unittests/NDB_BVL_Instrument_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -287,7 +287,7 @@ function testTextElement() * @covers NDB_BVL_Instrument::addTextAreaElementRD * @return void */ - function testAddTextAreaElement() + function testAddTextAreaElementRD() { $this->_instrument->addTextAreaElementRD( "FieldName1", "Field Description1", array("value" => "Option") @@ -298,6 +298,38 @@ function testAddTextAreaElement() $outArray['Elements'][0], ['Type' => "Group", 'Error' => "Unimplemented"] ); + $groupEl = $this->_instrument->form->form['FieldName1_group']; + $this->assertEquals( + $groupEl, + [ + 'type' => 'group', + 'name' => 'FieldName1_group', + 'elements' => [ + ['label' => null, + 'name' => 'FieldName1', + 'type' => 'textarea', + 'html' => $this->_instrument->form + ->renderElement($groupEl['elements'][0]) + ], + ['label' => '', + 'name' => 'FieldName1_status', + 'class' => 'form-control input-sm', + 'type' => 'select', + 'options' => ['' => '', + '88_refused' => '88 Refused', + '99_do_not_know' => '99 Do not know', + 'not_answered' => 'Not Answered' + ], + 'html' => $this->_instrument->form + ->renderElement($groupEl['elements'][1]) + ], + ], + 'label' => 'Field Description1', + 'delimiter' => ' ', + 'options' => false, + 'html' => $this->_instrument->form->groupHTML($groupEl) + ] + ); $textRules = $this->_instrument->XINRules['FieldName1']; $this->assertEquals( $textRules, @@ -309,6 +341,67 @@ function testAddTextAreaElement() ); } + /** + * Test that addHourMinElement returns a group element with the correct + * data and sets an appropriate XINRule + * + * @covers NDB_BVL_Instrument::addHourMinElement + * @return void + */ + function testAddHourMinElement() + { + $this->_instrument->addHourMinElement( + "hourMinField", "hourMinLabel", ["value" => "Option"], "Rule_message" + ); + $json = $this->_instrument->toJSON(); + $outArray = json_decode($json, true); + $this->assertEquals( + $outArray['Elements'][0], + ['Type' => "Group", 'Error' => "Unimplemented"] + ); + $groupEl = $this->_instrument->form->form['hourMinField_group']; + $this->assertEquals( + $groupEl, + [ + 'type' => 'group', + 'name' => 'hourMinField_group', + 'elements' => [ + ['label' => null, + 'name' => 'hourMinField', + 'type' => 'time', + 'html' => $this->_instrument->form + ->renderElement($groupEl['elements'][0]) + ], + ['label' => '', + 'name' => 'hourMinField_status', + 'class' => 'form-control input-sm', + 'type' => 'select', + 'options' => [null => '', + 'dnk' => 'DNK', + 'refusal' => 'Refusal', + 'not_answered' => 'Not Answered', + ], + 'html' => $this->_instrument->form + ->renderElement($groupEl['elements'][1]) + ] + ], + 'label' => 'hourMinLabel', + 'delimiter' => ' ', + 'options' => false, + 'html' => $this->_instrument->form->groupHTML($groupEl) + ] + ); + $rules = $this->_instrument->XINRules['hourMinField']; + $this->assertEquals( + $rules, + [ + 'message' => 'Rule_message', + 'group' => 'hourMinField_group', + 'rules' => ['Option', 'hourMinField_status{@}=={@}'] + ] + ); + } + /** * Test that addBasicDate (from NDB_Page) and addDateElement * adds the correct date to the instrument object @@ -397,6 +490,103 @@ function testDateElement() $this->assertEquals($dateElement4, $expectedResult); } + /** + * Test that addMonthYear creates a date element with the correct data + * and that it adds the element name to the monthYearFields array. + * + * @covers NDB_BVL_Instrument::addMonthYear + * @return void + */ + function testMonthYearElement() + { + $this->_instrument->addMonthYear("Field1", "Label 1", ['value' => 'Option']); + $this->assertEquals( + $this->_instrument->form->form["Field1"], + [ + 'label' => 'Label 1', + 'name' => 'Field1', + 'type' => 'date', + 'options' => ['value' => 'Option', + 'format' => 'YM'] + ] + ); + $this->assertEquals($this->_instrument->monthYearFields[0], "Field1"); + } + + /** + * Test that addCustomDateElement creates a group element with + * the correct data and sets a XINRule + * + * @covers NDB_BVL_Instrument::addCustomDateElement + * @return void + */ + function testAddCustomDateElement() + { + $this->_instrument->addCustomDateElement( + "CustomName", "Date Label", array("value" => "Option") + ); + $json = $this->_instrument->toJSON(); + $outArray = json_decode($json, true); + $this->assertEquals( + $outArray['Elements'][0], + ['Type' => "Group", 'Error' => "Unimplemented"] + ); + $groupEl = $this->_instrument->form->form['CustomName_date_group']; + $this->assertEquals( + $groupEl, + [ + 'type' => 'group', + 'name' => 'CustomName_date_group', + 'elements' => [ + [ + 'label' => null, + 'name' => 'CustomName_date', + 'class' => 'form-control input-sm', + 'type' => 'date', + 'html' => $this->_instrument->form + ->renderElement($groupEl['elements'][0]), + 'options' => ['value' => 'Option'] + ], + [ + 'label' => null, + 'name' => 'CustomName_date_status', + 'class' => 'form-control input-sm', + 'type' => 'select', + 'options' => [ + null => '', + '88_refused' => "88 Refused", + '99_do_not_know' => "99 Do not know", + 'not_answered' => "Not Answered" + ], + 'html' => $this->_instrument->form + ->renderElement($groupEl['elements'][1]) + ] + ], + 'label' => 'Date Label', + 'delimiter' => "\n", + 'options' => false, + 'html' => $this->_instrument->form->groupHTML($groupEl) + ] + ); + $rule1 = $this->_instrument->XINRules['CustomName_date']; + $this->assertEquals( + $rule1, + [ + 'message' => "You must specify or select from the drop-down", + 'group' => 'CustomName_date_group', + 'rules' => ['CustomName_date_status{@}=={@}'] + ] + ); + $rule2 = $this->_instrument->XINRules['CustomName_date_status']; + $this->assertEquals( + $rule2, + [ + 'message' => "You must specify or select from the drop-down", + 'group' => 'CustomName_date_group', + 'rules' => ['CustomName_date{@}=={@}'] + ] + ); + } /** * Test that addNumericElement adds the correct data to the instrument * @@ -422,7 +612,73 @@ function testNumericElement() ] ] ); + } + /** + * Test that addNumericElementRD correctly creates a group element + * and sets a XINRule with the proper data + * + * @covers NDB_BVL_Instrument::addNumericElementRD + * @return void + */ + function testNumericElementRD() + { + $this->_instrument->addNumericElementRD("TestElement", "Test Description"); + $json = $this->_instrument->toJSON(); + $outArray = json_decode($json, true); + $numericElement = $outArray['Elements'][0]; + $this->assertEquals( + $numericElement, + ['Type' => "Group", 'Error' => "Unimplemented"] + ); + $groupEl = $this->_instrument->form->form['TestElement_group']; + $this->assertEquals( + $groupEl, + [ + 'type' => 'group', + 'name' => 'TestElement_group', + 'elements' => [ + [ + 'type' => 'text', + 'name' => 'TestElement', + 'label' => 'Test Description', + 'class' => 'form-control input-sm', + 'numeric' => true, + 'numericMsg' => 'Numbers only, please', + 'html' => $this->_instrument->form + ->renderElement($groupEl['elements'][0]) + ], + [ + 'type' => 'select', + 'name' => 'TestElement_status', + 'label' => null, + 'class' => 'form-control input-sm not-answered', + 'options' => [ + '' => '', + '88_refused' => '88 Refused', + '99_do_not_know' => '99 Do not know', + 'not_answered' => 'Not Answered' + ], + 'html' => $this->_instrument->form + ->renderElement($groupEl['elements'][1]) + ] + ], + 'label' => 'Test Description', + 'delimiter' => ' ', + 'options' => false, + 'numeric' => [0], + 'html' => $this->_instrument->form->groupHTML($groupEl) + ] + ); + $rule = $this->_instrument->XINRules['TestElement']; + $this->assertEquals( + $rule, + [ + 'message' => 'This field is required', + 'group' => 'TestElement_group', + 'rules' => ['TestElement_status{@}=={@}'] + ] + ); } /** From 52af343b1eaee8a86fc4265f659b461f0a02d2f5 Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Mon, 13 Jul 2020 17:25:28 -0400 Subject: [PATCH 04/10] More tests --- test/unittests/NDB_BVL_Instrument_Test.php | 215 ++++++++++++++++++++- 1 file changed, 208 insertions(+), 7 deletions(-) diff --git a/test/unittests/NDB_BVL_Instrument_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php index 0180f870fe5..70797d0082a 100644 --- a/test/unittests/NDB_BVL_Instrument_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -31,6 +31,13 @@ class NDB_BVL_Instrument_Test extends TestCase { private $_instrument; + private $_factory; + private $_mockConfig; + private $_mockDB; + + private $_factoryForDB; + private $_config; + private $_DB; /** * Set up sets a fake $_SESSION object that we can use for * assertions @@ -58,15 +65,15 @@ function setUp() 'State' => $this->session ); - $factory = \NDB_Factory::singleton(); - $factory->setTesting(true); + $this->_factory = \NDB_Factory::singleton(); + $this->_factory->setTesting(true); - $mockdb = $this->getMockBuilder("\Database")->getMock(); - $mockconfig = $this->getMockBuilder("\NDB_Config")->getMock(); + $this->_mockDB = $this->getMockBuilder("\Database")->getMock(); + $this->_mockConfig = $this->getMockBuilder("\NDB_Config")->getMock(); - \NDB_Factory::$db = $mockdb; - \NDB_Factory::$testdb = $mockdb; - \NDB_Factory::$config = $mockconfig; + \NDB_Factory::$db = $this->_mockDB; + \NDB_Factory::$testdb = $this->_mockDB; + \NDB_Factory::$config = $this->_mockConfig; $this->quickForm = new \LorisForm(); @@ -956,5 +963,199 @@ function testAddYesNoElementWithRules() ); } + /** + * Test that getCommentID returns the correct string + * + * @covers NDB_BVL_Instrument::getCommentID + * @return void + */ + function testGetCommentID() + { + $this->_instrument->commentID = 'commentID1'; + $this->assertEquals("commentID1", $this->_instrument->getCommentID()); + } + + /** + * Test that getSessionID gets the correct data from the database + * + * @covers NDB_BVL_Instrument::getSessionID + * @return void + */ + function testGetSessionID() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->assertEquals("123", $this->_instrument->getSessionID()); + } + + /** + * Test that getSessionID returns -1 if nothing was found in the + * database for the given commentID + * + * @covers NDB_BVL_Instrument::getSessionID + * @return void + */ + function testGetSessionIDReturnsNegative() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID2'; + $this->assertEquals(-1, $this->_instrument->getSessionID()); + } + + /** + * Test that getVisitLabel returns the correct visit label + * for the given session ID + * + * @covers NDB_BVL_Instrument::getVisitLabel + * @return void + */ + function testGetVisitLabel() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->assertEquals("123", $this->_instrument->getSessionID()); + $this->assertEquals("V1", $this->_instrument->getVisitLabel()); + } + + /** + * Test that getVistiLabel returns an empty string + * if nothing was found in the database + * + * @covers NDB_BVL_Instrument::getVisitLabel + * @return void + */ + function testGetVisitLabelReturnsEmpty() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID2'; + $this->assertEquals("", $this->_instrument->getVisitLabel()); + } + + /** + * Test that getSubprojectID returns the correct value + * for the given session ID + * + * @covers NDB_BVL_Instrument::getSubprojectID + * @return void + */ + function testGetSubprojectID() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->assertEquals(2, $this->_instrument->getSubprojectID()); + } + + /** + * Test that getSubprojectID returns null if nothing was found + * + * @covers NDB_BVL_Instrument::getSubprojectID + * @return void + */ + function testGetSubprojectIDReturnsNull() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID2'; + $this->assertEquals(null, $this->_instrument->getSubprojectID()); + } + + /** + * Test that getDoB returns the correct date of birth from the database + * + * @covers NDB_BVL_Instrument::getDoB + * @return void + */ + function testGetDoB() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->assertEquals('1999-01-01', $this->_instrument->getDoB()); + } + + /** + * Test that getDoD returns the correct date of death from the database + * + * @covers NDB_BVL_Instrument::getDoD + * @return void + */ + function testGetDoD() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->assertEquals('2005-01-01', $this->_instrument->getDoD()); + } + + /** + * Test that getPSCID returns the correct data from the database + * + * @covers NDB_BVL_Instrument::getPSCID + * @return void + */ + function testGetPSCID() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->assertEquals('345', $this->_instrument->getPSCID()); + } + + /** + * Private function to set fake table data to be tested + * + * @return void + */ + private function _setTableData() + { + $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS flag"); + $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS session"); + $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS candidate"); + $this->_DB->setFakeTableData( + "flag", + [['SessionID' => '123', 'CommentID' => 'commentID1']] + ); + $this->_DB->setFakeTableData( + "candidate", + [ + [ + 'CandID' => 1, + 'DoB' => '1999-01-01', + 'DoD' => '2005-01-01', + 'PSCID' => '345' + ] + ] + ); + $this->_DB->setFakeTableData( + "session", + [['ID' => '123', 'CandID' => 1]] + ); + } + + /** + * Private function to set up the mock DB used for testing + * + * @return void + */ + private function _setUpMockDB() + { + $this->_factoryForDB = \NDB_Factory::singleton(); + $this->_factoryForDB->reset(); + $this->_factoryForDB->setTesting(false); + $this->_config = $this->_factoryForDB->Config(CONFIG_XML); + $database = $this->_config->getSetting('database'); + $this->_DB = \Database::singleton( + $database['database'], + $database['username'], + $database['password'], + $database['host'], + 1 + ); + } } ?> From a03d5ef9adb85f16475cfe7bde750607b8cfab57 Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Wed, 15 Jul 2020 11:09:56 -0400 Subject: [PATCH 05/10] Changed variable name --- php/libraries/NDB_BVL_Instrument.class.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/libraries/NDB_BVL_Instrument.class.inc b/php/libraries/NDB_BVL_Instrument.class.inc index f9daea429d2..e1d4a45baea 100644 --- a/php/libraries/NDB_BVL_Instrument.class.inc +++ b/php/libraries/NDB_BVL_Instrument.class.inc @@ -1941,7 +1941,7 @@ abstract class NDB_BVL_Instrument extends NDB_Page $group, $name . "_date_group", $label, - $this->_GUIDelimiter, + $this->GUIDelimiter, false ); unset($group); From 0e0edbb3e4c5228d67278d1f193ebd0e1d354c33 Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Thu, 16 Jul 2020 18:14:44 -0400 Subject: [PATCH 06/10] More tests --- test/unittests/NDB_BVL_Instrument_Test.php | 503 ++++++++++++++++++++- 1 file changed, 499 insertions(+), 4 deletions(-) diff --git a/test/unittests/NDB_BVL_Instrument_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php index 70797d0082a..b3eb94f23f2 100644 --- a/test/unittests/NDB_BVL_Instrument_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -1089,7 +1089,7 @@ function testGetDoD() $this->_setUpMockDB(); $this->_setTableData(); $this->_instrument->commentID = 'commentID1'; - $this->assertEquals('2005-01-01', $this->_instrument->getDoD()); + $this->assertEquals('2016-01-01', $this->_instrument->getDoD()); } /** @@ -1106,6 +1106,462 @@ function testGetPSCID() $this->assertEquals('345', $this->_instrument->getPSCID()); } + /** + * Test that loadInstanceData returns data from the correct database + * + * @covers NDB_BVL_Instrument::loadInstanceData + * @return void + */ + function testLoadInstanceData() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'flag'; + $defaults = \NDB_BVL_Instrument::loadInstanceData($this->_instrument); + $defaults['Testdate'] = '2020-01-01 00:00:00'; + $this->assertEquals( + $defaults, + [ + 'ID' => '1000000', + 'SessionID' => '123', + 'Test_name' => 'Test_name1', + 'CommentID' => 'commentID1', + 'Data_entry' => null, + 'Administration' => null, + 'Validity' => null, + 'Exclusion' => null, + 'Flag_status' => null, + 'UserID' => '456', + 'Testdate' => '2020-01-01 00:00:00', + 'Data' => null + ] + ); + } + + /** + * Test that getFieldValue returns the correct data from the table + * + * @covers NDB_BVL_Instrument::getFieldValue + * @return void + */ + function testGetFieldValue() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->assertEquals( + 'Test Examiner', + $this->_instrument->getFieldValue('Examiner') + ); + } + + /** + * Test that getCandidateAge returns the age from DoB to the date the + * instrument was taken if the DoD of the candidate is after the date taken + * + * @covers NDB_BVL_Instrument::getCandidateAge + * @return void + */ + function testGetCandidateAgeDoDAfterDateTaken() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->assertEquals( + ['year' => 11, 'mon' => 4, 'day' => 4], + $this->_instrument->getCandidateAge() + ); + } + + /** + * Test that getCandidateAge returns the age from DoB to the date taken + * if the DoD of the candidate is empty + * + * @covers NDB_BVL_Instrument::getCandidateAge + * @return void + */ + function testGetCandidateAgeNoDoD() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_DB->run("UPDATE candidate SET DoD=null WHERE CandID=1"); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->assertEquals( + ['year' => 11, 'mon' => 4, 'day' => 4], + $this->_instrument->getCandidateAge() + ); + } + + /** + * Test that getCandidateAge returns the age from DoB to DoD if the + * DoD of the candidate is before the date taken of the instrument + * + * @covers NDB_BVL_Instrument::getCandidateAge + * @return void + */ + function testGetCandidateAgeWithDoD() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_DB->run("UPDATE candidate SET DoD='2005-06-02' WHERE CandID=1"); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->assertEquals( + ['year' => 6, 'mon' => 5, 'day' => 1], + $this->_instrument->getCandidateAge() + ); + } + + /** + * Test that getCandidateAge returns the age from DoB to the given date + * + * @covers NDB_BVL_Instrument::getCandidateAge + * @return void + */ + function testGetCandidateAgeWithDateGiven() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->assertEquals( + ['year' => 4, 'mon' => 8, 'day' => 3], + $this->_instrument->getCandidateAge('2003-09-04') + ); + } + + /** + * Test that _setDefaultsArray changes the candidate age and sets + * the instrument's dateTimeFields value + * + * @covers NDB_BVL_Instrument::_setDefaultsArray + * @return void + */ + function testSetDefaultsArray() + { + $defaults = ['Test' => 'Test1', + 'Window_Difference' => 1, + 'Candidate_Age' => '2020-01-01' + ]; + $result = $this->_instrument->_setDefaultsArray($defaults); + $defaults['Candidate_Age'] = '2020-01-01 (Age out of range)'; + $this->assertEquals($defaults, $result); + $this->assertEquals(["Date_taken"], $this->_instrument->dateTimeFields); + } + + /** + * Test that _saveCandidateAge calculates the candidate age and + * window difference values and saves them to the database + * + * @covers NDB_BVL_Instrument::_saveCandidateAge + * @return void + */ + function testSaveCandidateAge() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->_instrument->testName = 'Test Name1'; + $values = ['Date_taken' => '2005-06-06']; + $this->_instrument->_saveCandidateAge($values); + $this->assertEquals( + $values, + [ + 'Date_taken' => '2005-06-06', + 'Candidate_Age' => 77.2, + 'Window_Difference' => 0 + ] + ); + } + + /** + * Test that _nullStatus sets the value of a field to empty if its + * correlated status field has a value set + * + * @covers NDB_BVL_Instrument::_nullStatus + * @return void + */ + function testNullStatus() + { + $values = ['Test1' => 'field1', + 'Test2' => 'field2', + 'Test3' => 'field3', + 'Test1_status' => 'status1', + 'Test2_status' => 'status2', + 'Test3_status' => '' + ]; + $this->_instrument->_nullStatus($values); + $this->assertEquals( + $values, + [ + 'Test1' => '', + 'Test2' => '', + 'Test3' => 'field3', + 'Test1_status' => 'status1', + 'Test2_status' => 'status2', + 'Test3_status' => '' + ] + ); + } + + /** + * Test that _saveValues correctly preprocesses the given array and + * then updates the instrument table in the database accordingly + * + * @covers NDB_BVL_Instrument::_saveValues + * @covers NDB_BVL_Instrument::_save + * @return void + */ + function testSaveValueAndSave() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->_instrument->testName = 'TestName1'; + $this->_instrument->formType = "XIN"; + $values = ['Date_taken' => '2005-06-06', + 'arthritis_age' => 2, + 'arthritis_age_status' => 'status' + ]; + $this->_instrument->_saveValues($values); + $dbData = $this->_DB->pselect("SELECT * FROM medical_history", []); + $this->assertEquals('77.2', $dbData[0]['Candidate_Age']); + $this->assertEquals('0', $dbData[0]['Window_Difference']); + $this->assertEquals(null, $dbData[0]['arthritis_age']); + $this->assertEquals('', $dbData[0]['arthritis_age_status']); + } + + /** + * Test that freeze correctly freezes the form related to the instrument + * + * @covers NDB_BVL_Instrument::freeze + * @return void + */ + function testFreeze() + { + $this->_instrument->freeze(); + $this->assertTrue($this->_instrument->form->frozen); + } + + /** + * Test that getDateOfAdministration gets the Date_taken + * from the instrument table + * + * @covers NDB_BVL_Instrument::getDateOfAdministration + * @return void + */ + function testGetDateOfAdministration() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->assertEquals( + '2010-05-05', + $this->_instrument->getDateOfAdministration() + ); + } + + /** + * Test that setRequired sets the required value of the form + * + * @note This test is being skipped because there is an error in + * the setRequired method. Once this is resolved, this test can + * be implemented. + * + * @covers NDB_BVL_Instrument::setRequired + * @return void + */ + function testSetRequired() + { + $this->markTestSkipped("Error in setRequired method"); + $this->_instrument->setRequired("Required_el"); + $this->assertEquals("Required_el", $this->_instrument->form->_required[]); + } + + /** + * Test that XINValidate returns true if there are no errors + * for the given elements array + * + * @covers NDB_BVL_Instrument::XINValidate + * @return void + */ + function testXINValidatNoErrors() + { + $elements = ['el1' => 'val1', + 'el2' => 'val2' + ]; + $this->assertTrue($this->_instrument->XINValidate($elements)); + } + /** + * Test that XINRegisterRule sets the values in the XINRules + * array for the appropriate element name + * + * @covers NDB_BVL_Instrument::XINRegisterRule + * @return void + */ + function testXINRegisterRule() + { + $this->_instrument->XINRegisterRule( + 'elname1', ['rule1', 'rule2'], 'message1', 'group1' + ); + $this->assertEquals( + $this->_instrument->XINRules['elname1'], + [ + 'message' => 'message1', + 'group' => 'group1', + 'rules' => ['rule1', 'rule2'] + ] + ); + } + + /** + * Test that the progress of data entry completion is 100 and that the status is + * 'Complete' if the _requiredElements array is empty + * + * @covers NDB_BVL_Instrument::determineDataEntryCompletionProgress + * @covers NDB_BVL_Instrument::_determineDataEntryCompletionStatus + * @return void + */ + function testDetermineDataEntryCompletionProgressNoRequiredEl() + { + $this->_instrument->_requiredElements = []; + $this->assertEquals( + 100, + $this->_instrument->determineDataEntryCompletionProgress() + ); + $this->assertEquals( + 'Complete', + $this->_instrument->_determineDataEntryCompletionStatus() + ); + } + + /** + * Test that the progress of data entry completion is 0 and that the status is + * 'Incomplete' if the _requiredElements field and status field are not set + * + * @covers NDB_BVL_Instrument::determineDataEntryCompletionProgress + * @covers NDB_BVL_Instrument::_determineDataEntryCompletionStatus + * @return void + */ + function testDetermineDataEntryCompletionProgressWithUnanswered() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->_DB->run( + "UPDATE medical_history SET arthritis_age=null + WHERE CommentID='commentID1'" + ); + $this->_DB->run( + "UPDATE medical_history SET arthritis_age_status=null + WHERE CommentID='commentID1'" + ); + $this->_instrument->_requiredElements = ['arthritis_age']; + $this->assertEquals( + 0, + $this->_instrument->determineDataEntryCompletionProgress() + ); + $this->assertEquals( + 'Incomplete', + $this->_instrument->_determineDataEntryCompletionStatus() + ); + } + + /** + * Test that the progress of data entry completion is 100 and that the status is + * 'Complete' if the _requiredElements field and status field have set values + * + * @covers NDB_BVL_Instrument::determineDataEntryCompletionProgress + * @covers NDB_BVL_Instrument::_determineDataEntryCompletionStatus + * @return void + */ + function testDetermineDataEntryCompletionProgressWithAnswered() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->_DB->run( + "UPDATE medical_history SET arthritis_age=60 + WHERE CommentID='commentID1'" + ); + $this->_DB->run( + "UPDATE medical_history SET arthritis_age_status='done' + WHERE CommentID='commentID1'" + ); + $this->_instrument->_requiredElements = ['arthritis_age']; + $this->assertEquals( + 100, + $this->_instrument->determineDataEntryCompletionProgress() + ); + $this->assertEquals( + 'Complete', + $this->_instrument->_determineDataEntryCompletionStatus() + ); + } + + /** + * Test that getDataEntryCompletionStatus returns the correct data + * from the database + * + * @covers NDB_BVL_Instrument::getDataEntryCompletionStatus + * @return void + */ + function testGetDataEntryCompletionStatus() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->assertEquals( + 'Incomplete', + $this->_instrument->getDataEntryCompletionStatus() + ); + } + + /** + * Test that _setDataEntryCompletionStatus correctly sets the + * 'Data_entry_completion_status value in the instrument table + * + * @covers NDB_BVL_Instrument::_setDataEntryCompletionStatus + * @return void + */ + function testSetDataEntryCompletionStatus() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->_instrument->_setDataEntryCompletionStatus('Complete'); + $data = \NDB_BVL_Instrument::loadInstanceData($this->_instrument); + $this->assertEquals('Complete', $data['Data_entry_completion_status']); + } + + /** + * Test that _setDataEntryCompletionStatus throws an exception if + * the given status is not 'Complete' or 'Incomplete' + * + * @covers NDB_BVL_Instrument::_setDataEntryCompletionStatus + * @return void + */ + function testSetDataEntryCompletionStatusThrowsException() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->expectException('Exception'); + $this->_instrument->_setDataEntryCompletionStatus('BadString'); + } + /** * Private function to set fake table data to be tested * @@ -1116,9 +1572,18 @@ private function _setTableData() $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS flag"); $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS session"); $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS candidate"); + $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS medical_history"); + $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS test_battery"); $this->_DB->setFakeTableData( "flag", - [['SessionID' => '123', 'CommentID' => 'commentID1']] + [ + [ + 'SessionID' => '123', + 'CommentID' => 'commentID1', + 'Test_name' => 'Test_name1', + 'UserID' => '456' + ] + ] ); $this->_DB->setFakeTableData( "candidate", @@ -1126,14 +1591,44 @@ private function _setTableData() [ 'CandID' => 1, 'DoB' => '1999-01-01', - 'DoD' => '2005-01-01', + 'DoD' => '2016-01-01', 'PSCID' => '345' ] ] ); $this->_DB->setFakeTableData( "session", - [['ID' => '123', 'CandID' => 1]] + [ + [ + 'ID' => '123', + 'CandID' => 1, + 'SubprojectID' => '12' + ] + ] + ); + $this->_DB->setFakeTableData( + "medical_history", + [ + [ + 'CommentID' => 'commentID1', + 'UserID' => '456', + 'Examiner' => 'Test Examiner', + 'Date_taken' => '2010-05-05 00:00:01', + 'Data_entry_completion_status' => 'Incomplete' + ] + ] + ); + $this->_DB->setFakeTableData( + "test_battery", + [ + [ + 'Active' => 'Y', + 'Test_name' => 'TestName1_proband', + 'SubprojectID' => '12', + 'AgeMinDays' => 0, + 'AgeMaxDays' => 100 + ] + ] ); } From 5570e0988a35ca85af2b586758606d0d9f9a5614 Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Thu, 16 Jul 2020 18:19:05 -0400 Subject: [PATCH 07/10] Changes to NDB_BVL_Instrument class --- php/libraries/NDB_BVL_Instrument.class.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/libraries/NDB_BVL_Instrument.class.inc b/php/libraries/NDB_BVL_Instrument.class.inc index e1d4a45baea..f9daea429d2 100644 --- a/php/libraries/NDB_BVL_Instrument.class.inc +++ b/php/libraries/NDB_BVL_Instrument.class.inc @@ -1941,7 +1941,7 @@ abstract class NDB_BVL_Instrument extends NDB_Page $group, $name . "_date_group", $label, - $this->GUIDelimiter, + $this->_GUIDelimiter, false ); unset($group); From 07f80bb2c9d5b12b311a6baaa1584c76f65039c3 Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Thu, 16 Jul 2020 18:58:08 -0400 Subject: [PATCH 08/10] More tests --- test/unittests/NDB_BVL_Instrument_Test.php | 92 ++++++++++++++++++++-- 1 file changed, 85 insertions(+), 7 deletions(-) diff --git a/test/unittests/NDB_BVL_Instrument_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php index b3eb94f23f2..7746fcd3112 100644 --- a/test/unittests/NDB_BVL_Instrument_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -1000,7 +1000,7 @@ function testGetSessionIDReturnsNegative() { $this->_setUpMockDB(); $this->_setTableData(); - $this->_instrument->commentID = 'commentID2'; + $this->_instrument->commentID = 'commentID3'; $this->assertEquals(-1, $this->_instrument->getSessionID()); } @@ -1031,7 +1031,7 @@ function testGetVisitLabelReturnsEmpty() { $this->_setUpMockDB(); $this->_setTableData(); - $this->_instrument->commentID = 'commentID2'; + $this->_instrument->commentID = 'commentID3'; $this->assertEquals("", $this->_instrument->getVisitLabel()); } @@ -1060,7 +1060,7 @@ function testGetSubprojectIDReturnsNull() { $this->_setUpMockDB(); $this->_setTableData(); - $this->_instrument->commentID = 'commentID2'; + $this->_instrument->commentID = 'commentID3'; $this->assertEquals(null, $this->_instrument->getSubprojectID()); } @@ -1152,7 +1152,7 @@ function testGetFieldValue() $this->_instrument->commentID = 'commentID1'; $this->_instrument->table = 'medical_history'; $this->assertEquals( - 'Test Examiner', + 'Test Examiner1', $this->_instrument->getFieldValue('Examiner') ); } @@ -1562,6 +1562,60 @@ function testSetDataEntryCompletionStatusThrowsException() $this->_instrument->_setDataEntryCompletionStatus('BadString'); } + /** + * Test that nullScores sets the value for the given key-value pair + * to null in the instrument table + * + * @covers NDB_BVL_Instrument::_nullScores + * @return void + */ + function testNullScores() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->_instrument->_nullScores(['Examiner' => 'Test Examiner1']); + $data = \NDB_BVL_Instrument::loadInstanceData($this->_instrument); + $this->assertEquals(null, $data['Examiner']); + } + + /** + * Test that diff returns an array highlighting the differences between + * two instruments + * + * @covers NDB_BVL_Instrument::diff + * @return void + */ + function testDiff() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $otherInstrument = $this->getMockBuilder(\NDB_BVL_Instrument::class) + ->disableOriginalConstructor() + ->setMethods(array("getFullName", "getSubtestList"))->getMock(); + $otherInstrument->commentID = 'commentID2'; + $otherInstrument->table = 'medical_history'; + $this->assertEquals( + $this->_instrument->diff($otherInstrument), + [ + [ + 'TableName' => 'medical_history', + 'ExtraKeyColumn' => null, + 'ExtraKey1' => ' ', + 'ExtraKey2' => ' ', + 'FieldName' => 'Examiner', + 'CommentId1' => 'commentID1', + 'Value1' => 'Test Examiner1', + 'CommentId2' => 'commentID2', + 'Value2' => 'Test Examiner2' + ] + ] + ); + } + /** * Private function to set fake table data to be tested * @@ -1582,7 +1636,13 @@ private function _setTableData() 'CommentID' => 'commentID1', 'Test_name' => 'Test_name1', 'UserID' => '456' - ] + ], + [ + 'SessionID' => '234', + 'CommentID' => 'commentID2', + 'Test_name' => 'Test_name2', + 'UserID' => '457' + ], ] ); $this->_DB->setFakeTableData( @@ -1593,6 +1653,12 @@ private function _setTableData() 'DoB' => '1999-01-01', 'DoD' => '2016-01-01', 'PSCID' => '345' + ], + [ + 'CandID' => 2, + 'DoB' => '1999-01-01', + 'DoD' => '2016-01-01', + 'PSCID' => '346' ] ] ); @@ -1603,6 +1669,11 @@ private function _setTableData() 'ID' => '123', 'CandID' => 1, 'SubprojectID' => '12' + ], + [ + 'ID' => '234', + 'CandID' => 2, + 'SubprojectID' => '12' ] ] ); @@ -1612,10 +1683,17 @@ private function _setTableData() [ 'CommentID' => 'commentID1', 'UserID' => '456', - 'Examiner' => 'Test Examiner', + 'Examiner' => 'Test Examiner1', 'Date_taken' => '2010-05-05 00:00:01', 'Data_entry_completion_status' => 'Incomplete' - ] + ], + [ + 'CommentID' => 'commentID2', + 'UserID' => '457', + 'Examiner' => 'Test Examiner2', + 'Date_taken' => '2010-05-05 00:00:01', + 'Data_entry_completion_status' => 'Incomplete' + ], ] ); $this->_DB->setFakeTableData( From 295c77f9f89c65ffe37fc1344f869d2c5f073584 Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Wed, 29 Jul 2020 16:59:10 -0400 Subject: [PATCH 09/10] Fix Travis, more tests --- test/unittests/NDB_BVL_Instrument_Test.php | 118 ++++++++++++++++++++- 1 file changed, 115 insertions(+), 3 deletions(-) diff --git a/test/unittests/NDB_BVL_Instrument_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php index 7746fcd3112..4cd7aebea05 100644 --- a/test/unittests/NDB_BVL_Instrument_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -1123,7 +1123,7 @@ function testLoadInstanceData() $this->assertEquals( $defaults, [ - 'ID' => '1000000', + 'ID' => '1000', 'SessionID' => '123', 'Test_name' => 'Test_name1', 'CommentID' => 'commentID1', @@ -1616,6 +1616,94 @@ function testDiff() ); } + /** + * Test that clearInstrument clears all relevant instrument data and removes + * instrument data from the conflicts_unresolved table + * + * @covers NDB_BVL_Instrument::clearInstrument + * @return void + */ + function testClearInstrument() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $conflicts_data = [ + [ + 'ConflictID' => '123', + 'TableName' => '', + 'ExtraKeyColumn' => null, + 'ExtraKey1' => '', + 'ExtraKey2' => '', + 'FieldName' => '', + 'CommentId1' => 'commentID1', + 'Value1' => null, + 'CommentId2' => '', + 'Value2' => null + ] + ]; + $this->_DB->setFakeTableData( + "conflicts_unresolved", + $conflicts_data + ); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $conflictsBefore = $this->_DB->pselect( + "SELECT * FROM conflicts_unresolved", [] + ); + $this->_instrument->clearInstrument(); + $data = \NDB_BVL_Instrument::loadInstanceData($this->_instrument); + $conflictsAfter = $this->_DB->pselect( + "SELECT * FROM conflicts_unresolved", [] + ); + $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS conflicts_unresolved"); + $this->assertEquals(null, $data['Examiner']); + $this->assertEquals('Incomplete', $data['Data_entry_completion_status']); + $this->assertEquals( + $conflicts_data, + $conflictsBefore + ); + $this->assertEquals([], $conflictsAfter); + } + + /** + * Test that determineDataEntryAllowed returns true if the Data_entry is anything + * but 'Complete' and returns false if Data_entry is 'Complete. Test that + * validate simply calls determineDataEntryAllowed and has the same output. + * + * @covers NDB_BVL_Instrument::determineDataEntryAllowed + * @covers NDB_BVL_Instrument::validate + * @return void + */ + function testDetermineDataEntryAllowed() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->table = 'medical_history'; + $this->assertTrue($this->_instrument->determineDataEntryAllowed()); + $this->assertTrue($this->_instrument->validate(['value1'])); + $this->_instrument->commentID = 'commentID2'; + $this->assertFalse($this->_instrument->determineDataEntryAllowed()); + $this->assertFalse($this->_instrument->validate(['value1'])); + } + + /** + * Test that getFlags returns an \InstrumentFlags object + * + * @covers NDB_BVL_Instrument::getFlags + * @return void + */ + function testGetFlags() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->assertEquals( + new \InstrumentFlags(null, null, null), + $this->_instrument->getFlags() + ); + } + /** * Private function to set fake table data to be tested * @@ -1628,20 +1716,29 @@ private function _setTableData() $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS candidate"); $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS medical_history"); $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS test_battery"); + $this->_DB->run("DROP TEMPORARY TABLE IF EXISTS parameter_type"); $this->_DB->setFakeTableData( "flag", [ [ + 'ID' => '1000', 'SessionID' => '123', 'CommentID' => 'commentID1', 'Test_name' => 'Test_name1', - 'UserID' => '456' + 'UserID' => '456', + 'Data_entry' => 'Incomplete', + 'Administration' => 'admin1', + 'Validity' => 'valid1' ], [ + 'ID' => '2000', 'SessionID' => '234', 'CommentID' => 'commentID2', 'Test_name' => 'Test_name2', - 'UserID' => '457' + 'UserID' => '457', + 'Data_entry' => 'Complete', + 'Administration' => 'admin2', + 'Validity' => 'valid2' ], ] ); @@ -1708,6 +1805,21 @@ private function _setTableData() ] ] ); + $this->_DB->setFakeTableData( + "parameter_type", + [ + [ + 'Description' => 'description 1', + 'SourceField' => 'Not validity', + 'SourceFrom' => 'Testname1' + ], + [ + 'Description' => 'description 2', + 'SourceField' => 'Validity', + 'SourceFrom' => 'Testname1' + ] + ] + ); } /** From 928212ce4ba4598bf953b544b1481000bbc4a83a Mon Sep 17 00:00:00 2001 From: AlexandraLivadas Date: Fri, 31 Jul 2020 15:08:21 -0400 Subject: [PATCH 10/10] More tests --- test/unittests/NDB_BVL_Instrument_Test.php | 165 +++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/test/unittests/NDB_BVL_Instrument_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php index 4cd7aebea05..c8db0e618a4 100644 --- a/test/unittests/NDB_BVL_Instrument_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -1704,6 +1704,171 @@ function testGetFlags() ); } + /** + * Test that _toJSONParseSmarty returns an array with the + * correct information for a date type element. + * + * @covers NDB_BVL_Instrument::_toJSONParseSmarty + * @return void + */ + function testToJsonParseSmartyDateType() + { + $el = ['type' => 'date']; + $result = ['type' => 'date', + 'options' => ['mindate' => "1990-01-01", + 'maxdate' => "2000-12-31", + 'RequireResponse' => false], + 'NoResponse' => true + ]; + $this->assertEquals($result, $this->_instrument->_toJSONParseSmarty($el)); + } + + /** + * Test that _toJSONParseSmarty returns an array with the + * correct information for a date type element when the form + * is not a LorisForm. + * + * @covers NDB_BVL_Instrument::_toJSONParseSmarty + * @return void + */ + function testToJsonParseSmartyDateTypeNotLorisForm() + { + $date = ['options' => ['minYear' => '1990', + 'maxYear' => '2000'], + 'type' => 'select' + + ]; + $dateHTML = $this->_instrument->form->renderElement($date); + $el = ['type' => 'date', + 'html' => $dateHTML]; + $result = ['type' => 'date', + 'html' => $dateHTML, + 'options' => ['mindate' => "1990-01-01", + 'maxdate' => "2000-12-31"], + 'NoResponse' => true + ]; + $this->_instrument->form = new \Candidate(); + $this->assertEquals($result, $this->_instrument->_toJSONParseSmarty($el)); + } + + /** + * Test that _toJSONParseSmarty returns an array with the + * correct information + * + * @covers NDB_BVL_Instrument::_toJSONParseSmarty + * @return void + */ + function toJsonParseSmartySelectType() + { + $select = ['type' => 'select', + 'multiple' => 'multiple', + 'option' => ['value' => 'not_answered'] + ]; + $html = $this->_instrument->form->renderElement($select); + $el = ['type' => 'select', 'html' => $html]; + $this->assertEquals($el, $this->_instrument->_toJSONParseSmarty($select)); + } + + /** + * Test that getBreadcrumbs returns a BreadcrumbTrail object with the correct + * Breadcrumb data + * + * @covers NDB_BVL_Instrument::getBreadcrumbs + * @return void + */ + function testGetBreadcrumbs() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID1'; + $this->_instrument->testName = 'testname'; + $breadcrumb = new \LORIS\BreadcrumbTrail( + new \LORIS\Breadcrumb( + 'Access Profile', + '/candidate_list' + ), + new \LORIS\Breadcrumb( + "Candidate Profile 300123 / 345", + "/300123" + ), + new \LORIS\Breadcrumb( + "TimePoint V1 Details", + "/instrument_list/?candID=300123&sessionID=123" + ), + new \LORIS\Breadcrumb( + "Test Instrument", + "/instruments/testname/". + "?commentID=commentID1&sessionID=123&candID=300123" + ) + ); + $this->assertEquals( + $breadcrumb, + $this->_instrument->getBreadcrumbs() + ); + } + + /** + * Test that usesJSONData returns false + * + * @covers NDB_BVL_Instrument::usesJSONData + * @return void + */ + function testUsesJSONData() + { + $this->assertFalse($this->_instrument->usesJSONData()); + } + + /** + * Test that display returns an html with an expected hidden element. The HTML + * value returned is too long to be compared. + * + * @covers NDB_BVL_Instrument::display + * @return void + */ + function testDisplay() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->setup("commentID1", "page"); + $this->_instrument->table = 'medical_history'; + $this->assertContains( + "\n", + $this->_instrument->display() + ); + } + + /** + * Test that save returns false if the instrument cannot be validated + * and saved + * + * @covers NDB_BVL_Instrument::save + * @return void + */ + function testSaveFalse() + { + $this->_setUpMockDB(); + $this->_setTableData(); + $this->_instrument->commentID = 'commentID2'; + $this->_instrument->table = 'medical_history'; + $this->_instrument->form = $this->getMockBuilder("\LorisForm")->getMock(); + $this->_instrument->form + ->method('getSubmitValues')->willReturn(['1', '2']); + $this->assertFalse($this->_instrument->save()); + } + + /** + * Test that XINRunRuleFunction throws a LorisException if the operator + * is unsupported (not == or !=) + * + * @covers NDB_BVL_Instrument::XINRunRuleFunction + * @return void + */ + function testXINRunRuleFunctionThrowsException() + { + $this->expectException('\LorisException'); + $this->_instrument->XINRunRuleFunction("controller", ["1"], "&&"); + } + /** * Private function to set fake table data to be tested *