format($dateFormat) === $date; } class writeBrokerPDOTest extends TestCase { protected gacBrokerClient $readBrokerClient; protected gacBrokerClient $writeBrokerClient; protected gacBrokerClient $adminOutClient; protected static ?array $meta; protected static ?array $adminMeta; protected static ?object $widget; protected static string $cKey; protected static string $dataKey; protected static ?array $dataRecord; protected static string $auditKey; protected static ?array $auditRecord; protected static string $journalKey; protected static ?array $journalRecord; protected static string $eventGUID; protected static string $extTst = '_tst'; protected static string $extAud = '_aud'; protected static string $extJnl = '_jnl'; /** * setUpBeforeClass() -- public static unit test method * * this method is called first, and once, on execution. It sets up a list of brokers we're going to test. * * @author mike@givingassistant.org * @version 1.0 * * * HISTORY: * ======== * 10-23-17 mks CORE-585: original coding * 01-14-19 mks DB-103: support for audit/journaling unit testing * */ public static function setUpBeforeClass() { parent::setUpBeforeClass(); // meta data static::$meta = [ META_CLIENT => CLIENT_UNIT, META_CLIENT_IP => STRING_SESSION_HOME, META_SYSTEM_NOTES => STRING_ORIGIN_UT, META_TEMPLATE => TEMPLATE_CLASS_TEST_PDO ]; // meta data for admin requests static::$adminMeta = [ META_CLIENT => CLIENT_UNIT, META_CLIENT_IP => STRING_SESSION_HOME, META_SYSTEM_NOTES => STRING_ORIGIN_UT ]; } /** * setUp() -- unit test reserved method * * the setUp method is executed prior to each test, executing the following tasks: * * 1. validate that the meta data persisted across tests * 2. validate that we successfully created a write-broker client * 3. validate that we successfully created a read-broker client * 4. validate the successful instantiation of a factory-class and assign to the widget static * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 10-23-17 mks CORE-585: original coding * 01-14-19 mks DB-103: support for audit/journaling unit testing * */ protected function setUp() { $errors = array(); // validate the meta data for the pending query $this->assertTrue(!empty(static::$meta), __FILE__ . COLON . __LINE__ . COLON . ERROR_DATA_META_404); $this->assertTrue(is_array(static::$meta), __FILE__ . COLON . __LINE__ . COLON . ERROR_META_INVALID_FORMAT_ARRAY); $this->assertTrue(array_key_exists(META_TEMPLATE, static::$meta), __FILE__ . COLON . __LINE__ . COLON . ERROR_DATA_META_KEY_404 . META_TEMPLATE); // create the write broker client $this->writeBrokerClient = new gacBrokerClient(BROKER_QUEUE_W, basename(__FILE__) . COLON . __METHOD__ . COLON . __LINE__); $this->assertTrue($this->writeBrokerClient->status, __METHOD__ . __LINE__ . ERROR_BROKER_QUEUE_DECLARE . BROKER_QUEUE_W); // create the read broker client $this->readBrokerClient = new gacBrokerClient(BROKER_QUEUE_R, basename(__FILE__) . COLON . __METHOD__ . COLON . __LINE__); $this->assertTrue($this->readBrokerClient->status, __METHOD__ . __LINE__ . ERROR_BROKER_QUEUE_DECLARE . BROKER_QUEUE_R); // create the admin broker client $this->adminOutClient = new gacBrokerClient(BROKER_QUEUE_AO, basename(__FILE__) . COLON . __METHOD__ . COLON . __LINE__); $this->assertTrue($this->adminOutClient->status, __FILE__ . COLON . __LINE__ . COLON . ERROR_BROKER_QUEUE_DECLARE . BROKER_QUEUE_AO); // instantiate a new widget $objFactory = new gacFactory(static::$meta, FACTORY_EVENT_NEW_CLASS, '', $errors); $this->assertTrue($objFactory->status, __FILE__ . COLON . __LINE__ . COLON . ERROR_FAILED_TO_INSTANTIATE . static::$meta[META_TEMPLATE]); // extract and assign the factory widget and deallocate the factory static::$widget = $objFactory->widget; if (is_object($objFactory)) $objFactory->__destruct(); unset($objFactory); } /** * tearDown() -- unit test method * * this is the (reserved) tearDown method which is executed at the end of every test. * the method deletes the current broker client. * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 10-23-17 mks CORE-585: original coding * */ protected function tearDown() { if (is_object($this->readBrokerClient)) $this->readBrokerClient->__destruct(); unset($this->readBrokerClient); if (is_object($this->writeBrokerClient)) $this->writeBrokerClient->__destruct(); unset($this->writeBrokerClient); if (is_object(static::$widget)) { static::$widget->__destruct(); } static::$widget = null; } /** * testInsert() -- unit test method * * this unit test method is a simple test consisting of the following: * * 1. validate that we have a valid widget object * 2. validate that we were able to create a test record of 1 record * -- submit the create-event to the broker * 3. validate that the create-event was successful and returned 1 cache-key * -- fetch the cached record * 4. validate that the integer, float, bool and string values are the same * 5. validate that the guid, status and cData values were inserted * 6. validate the guid * 7. validate the status (active) * 8. validate the date as an integer * 9. validate that we're able to fetch the new record from the db * * * Assumptions: * ------------ * That we know the test class being used supports caching. * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 10-23-17 mks CORE-585: original coding * 01-14-19 mks DB-103: support for audit/journaling unit testing * */ public function testOneInsert() { $testRecord = null; $this->assertTrue(is_object(static::$widget), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_WIDGET_404); // create one record $testRecord = static::$widget->template->buildTestData(1); $this->assertTrue(is_array($testRecord), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_TRUE . 'is_array($testRecord)'); $this->assertEquals(1, count($testRecord), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, 1, count($testRecord))); // create the query/broker-event payload $request = [ BROKER_REQUEST => BROKER_REQUEST_CREATE, BROKER_DATA => $testRecord, BROKER_META_DATA => static::$meta ]; // build the request payload and submit the request to the write broker $payload = gzcompress(json_encode($request)); $response = $this->writeBrokerClient->call($payload); $response = json_decode(gzuncompress($response), true); // validate the response payload $this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_CREATE, $response[PAYLOAD_STATE])); $this->assertEquals(STATE_SUCCESS, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_STRING_MISMATCH, STATE_SUCCESS, $response[PAYLOAD_STATE])); $this->assertEquals(1, count($response[PAYLOAD_RESULTS]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, 1, count($response[PAYLOAD_RESULTS]))); // get the cache-key from the response payload $cKey = $response[PAYLOAD_RESULTS][0]; $cacheRecord = gasCache::get($cKey); $cacheRecord = json_decode(gzuncompress($cacheRecord), true); $cacheRecord = $cacheRecord[0]; // test the four primary values (int, float, bool, string) of the pre-saved record and // the post-saved cached record $this->assertEquals($testRecord[0][CM_TST_FIELD_TEST_INT], $cacheRecord[CM_TST_FIELD_TEST_INT], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_INT)); $this->assertEquals($testRecord[0][CM_TST_FIELD_TEST_STRING], $cacheRecord[CM_TST_FIELD_TEST_STRING], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_STRING)); $this->assertEquals($testRecord[0][CM_TST_FIELD_TEST_DOUBLE], $cacheRecord[CM_TST_FIELD_TEST_DOUBLE], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_DOUBLE)); $this->assertEquals($testRecord[0][CM_TST_FIELD_TEST_BOOL], $cacheRecord[CM_TST_FIELD_TEST_BOOL], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_BOOL)); // validate that we have dateCreated, key and status fields which were inserted by the framework $this->assertTrue(array_key_exists(CM_TST_FIELD_TEST_CDATE, $cacheRecord), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, CM_TST_FIELD_TEST_CDATE, RESOURCE_CACHE)); $this->assertTrue(array_key_exists(CM_TST_TOKEN, $cacheRecord), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, CM_TST_TOKEN, RESOURCE_CACHE)); $this->assertTrue(array_key_exists(CM_TST_FIELD_TEST_STATUS, $cacheRecord), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, CM_TST_FIELD_TEST_STATUS, RESOURCE_CACHE)); // validate that these fields have content of the correct type or that the literals match // validate the token guid $this->assertTrue(validateGUID($cacheRecord[CM_TST_TOKEN]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_TOKEN)); // validate the status value $this->assertEquals(STATUS_ACTIVE, $cacheRecord[CM_TST_FIELD_TEST_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_FIELD_TEST_STATUS)); // validate the createdDate $this->assertTrue(validateMigrationDate($cacheRecord[CM_TST_FIELD_TEST_CDATE]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_FIELD_TEST_CDATE)); // save the cKey value as we're going to use this record in subsequent tests static::$cKey = $cKey; // copy the guid for the audit test next static::$dataKey = $cacheRecord[CM_TST_TOKEN]; // grab a copy of the new record for later test comparison $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_TEST_PDO; $meta[META_DONUT_FILTER] = 1; $query = [ CM_TST_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey ]]]]; $payload = [ BROKER_REQUEST => BROKER_REQUEST_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->readBrokerClient->call(gzcompress(json_encode($payload)))), true); $this->assertTrue($response[PAYLOAD_STATUS], (basename(__FILE__) . COLON . __LINE__) . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE])); $this->assertTrue(is_array($response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]), (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_FIELD_VALUE, STRING_QUERY_RESULTS)); static::$dataRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; } /** * testInsertAudit() -- unit test method * * This unit test should execute immediately after the testOneInsert() unit test. This unit test test for the * presence of an audit record that was inserted after the previous create-new-record event. We'll ensure that * the audit record was created by searching for the audit record using a combination of the newly-created record * token and the eventGUID for the create event. * * This method makes the following assertions: * * 1-4: static members required for this method are available and correctly populated * 5: We fetched the cached record and that record contains the event GUID * 6: The cached record eventGUID is a valid GUID * 7: We successfully identified and fetched the audit record generated by the create event * 8-11: The audit record contains the correct field data and types * * Programmer Note's: * ------------------ * A normal fetch, even with filtering disabled, does not return the eventGUID - we have to attain this value * by fetching the cached version of the record. A bug report (DB-108) was created to resolve this dependency. * * * @author mike@givingassistant.org * @version 1.0 * * * HISTORY: * ======== * 01-15-19 mks DB-104: original coding * */ public function testInsertAudit() { sleep(1); $errors = ''; // test that we have saved the new record insert data from the previous method $this->assertNotEmpty(static::$dataKey, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'dataKey')); $this->assertTrue(validateGUID(static::$dataKey), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$dataKey); $this->assertNotEmpty(static::$dataRecord, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'dataRecord')); $this->assertNotEmpty(static::$cKey, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'cacheKey')); // fetch the cache record to get the eventGUID $cacheRecord = json_decode(gzuncompress(gasCache::get(static::$cKey)), true); if (!validateCacheChecksum($cacheRecord,$errors)) $this->assertTrue(false, $errors); $cacheRecord = $cacheRecord[0]; $this->assertArrayHasKey(CM_TST_EVENT_GUID, $cacheRecord, basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL); $eventToken = $cacheRecord[CM_TST_EVENT_GUID]; $this->assertTrue(validateGUID($eventToken), basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . $eventToken); // from the just-created record we saved, build a query for the audit record off the record and event guids $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT; $query = [ AUDIT_RECORD_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey ]]], DB_EVENT_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ $eventToken ]]], OPERAND_AND => null ]; $payload = [ BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($payload)))), true); // validate that we created an audit record and fetch/store the audit-record data $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE])); static::$auditRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertTrue(is_array(static::$auditRecord), basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, 'auditRecord')); $this->assertArrayHasKey(DB_TOKEN . static::$extAud, static::$auditRecord, basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . DB_TOKEN); static::$auditKey = static::$auditRecord[DB_TOKEN . static::$extAud]; $this->assertTrue(validateGUID(static::$auditKey), basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$auditKey); $this->assertEquals(EVENT_NAME_AUDIT_CREATE, static::$auditRecord[AUDIT_OPERATION . static::$extAud], basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_STRING_MISMATCH, EVENT_NAME_AUDIT_CREATE, static::$auditRecord[AUDIT_OPERATION . static::$extAud])); static::$eventGUID = $eventToken; } /** * testInsertJournaling() -- unit test method * * This unit test validates that we created a journal record from the create-new-record event for our test class * data. We ensure that the journal record exists by querying against the data-record guid, the event guid, and * the audit-record token guid. Assertions made in this method: * * 1-6: Previously stored variables are still valid and available * 7: we successfully retrieved the journal record * 8: we successfully retrieved the journal record data as an array * 9: that the journal data has a valid record token * * We store copies of the journal record for the next unit test. * * * @author mike@givingassistant.org * @version 1.0 * * * HISTORY: * ======== * 01-15-19 DB-103: original coding * */ public function testInsertJournaling() { // allow the system to write data to disk sleep(1); // ensure we maintained our statics $this->assertNotEmpty(static::$dataKey, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'dataKey')); $this->assertTrue(validateGUID(static::$dataKey), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$dataKey); $this->assertNotEmpty(static::$dataRecord, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'dataRecord')); $this->assertNotEmpty(static::$cKey, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'cacheKey')); $this->assertNotEmpty(static::$eventGUID, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, CM_TST_EVENT_GUID)); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$eventGUID); // test that we created a journaling record by fetching the journal record based off the audit record GUID, // data record GUID, and the eventGUID... $query = [ JOURNAL_AUD_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$auditKey ]]], JOURNAL_SYSEV_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventGUID]]], JOURNAL_RECORD_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey]]], OPERAND_AND => null ]; $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_JOURNAL; $meta[META_DONUT_FILTER] = 1; $payload = [ BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($payload)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE])); $this->assertTrue(is_array($response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]), basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_QUERY_RESULTS); static::$journalRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertArrayHasKey(DB_TOKEN . static::$extJnl, static::$journalRecord, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, DB_TOKEN)); static::$journalKey = static::$journalRecord[(DB_TOKEN . static::$extJnl)]; } /** * testInsertJournalRecovery() -- unit test method * * This unit test will ensure that we're able to recover the newly-created record by deleting it via the audit * recovery event which loads the journal record and executes the query stored therein and associated, via the * audit record, back to the create event. The following assertions are made: * * 1-8: stored variables are still available and correct * 9: the restore record event successfully completed * 10: fetching the record directly (without caching) results in a not-found result * 11: the record no longer exists in cache * * * @author mike@givingassistant.org * @version 1.0 * * * HISTORY: * ======== * 01-16-19 mks DB-103: original coding * */ public function testInsertJournalRecovery() { // ensure we maintained our statics $this->assertNotEmpty(static::$dataKey, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'dataKey')); $this->assertTrue(validateGUID(static::$dataKey), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$dataKey); $this->assertNotEmpty(static::$auditKey, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'auditKey')); $this->assertTrue(validateGUID(static::$auditKey), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$auditKey); $this->assertNotEmpty(static::$dataRecord, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'dataRecord')); $this->assertNotEmpty(static::$cKey, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'cacheKey')); $this->assertNotEmpty(static::$eventGUID, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, CM_TST_EVENT_GUID)); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$eventGUID); $this->assertNotEmpty(static::$journalRecord, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, 'journalRecord')); $this->assertNotEmpty(static::$journalKey, basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$journalKey); // in order to roll-back the record to it's previous state, we invoke the restore event with the audit record GUID $query = [ STRING_KEY => static::$auditKey ]; $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT; $meta[META_DONUT_FILTER] = 1; $payload = [ BROKER_REQUEST => BROKER_REQUEST_AUDIT_RESTORE, BROKER_DATA => $query, BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($payload)))), true); // test that the restore command exec'd successfully $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_AUDIT_RESTORE, $response[PAYLOAD_STATE])); // fetch the "deleted" record $query = [ DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey ]]]]; $meta = static::$meta; $meta[META_DONUT_FILTER] = 1; // b/c PDO: set the don't-filter override $payload = [ BROKER_REQUEST => BROKER_REQUEST_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->readBrokerClient->call(gzcompress(json_encode($payload)))), true); $this->assertEquals(STATE_NOT_FOUND, $response[PAYLOAD_STATE], basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, STATE_NOT_FOUND, $response[PAYLOAD_STATE])); // finally, test that the record has been deleted/removed from cache $record = gasCache::get(static::$cKey); $this->assertNull($record, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_STRING_MISMATCH, OPERAND_NULL, DATA_TYPE_ARRAY)); } /** * testMultipleInserts() -- unit test method * * This method functions almost identically to the previous test method except, in this method, we're testing * batch-inserts of between 50 and 100 records. * * 1. validate that the widget object is still viable * -- generate a random value between 50 and 100 * -- generate that number of random test records * 2. validate that we were able to generate the correct number of random records * -- build, submit and evaluate the broker-event request return data * 3. validate that the event returned the same number of records processed (count) * -- generate a random number between 0 and the number of records generated * -- fetch that record from cache and unpack the cache record * 4. validate that the base values are the same (request -> insert -> cache -> test) * 5. validate that we added createdData, guid, and status to the record * 6. validate the type of the added data elements * * * @author mike@givingassistant.org * @version 1.0 * * @param int $_startVal -- defaults to 10 -- minimum # of random records to create * @param int $_endVal -- defaults to 50 -- maximum # of random records to create * * * HISTORY: * ======== * 10-23-17 mks CORE-585: original coding * 12-05-18 mks DB-55: parameter-ized function to control number of records generated * */ public function testMultipleInserts(int $_startVal = 10, int $_endVal = 50) { $testRecords = null; $errors = ''; $this->assertTrue(is_object(static::$widget), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_WIDGET_404); // create random (default: 10-50) records $recCount = mt_rand($_startVal, $_endVal); $testRecords = static::$widget->template->buildTestData($recCount, true); $this->assertTrue(is_array($testRecords), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_TRUE . 'is_array($testRecords)'); $this->assertEquals($recCount, count($testRecords), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, 1, count($testRecords))); // create the query/broker-event payload $request = [ BROKER_REQUEST => BROKER_REQUEST_CREATE, BROKER_DATA => $testRecords, BROKER_META_DATA => static::$meta ]; // build the request payload and submit the request to the write broker $payload = gzcompress(json_encode($request)); $response = $this->writeBrokerClient->call($payload); $response = json_decode(gzuncompress($response), true); // validate that the return payload is an array $this->assertTrue(is_array($response), (__FILE__ . COLON . __LINE__) . COLON . ERROR_DATA_MISSING_ARRAY . 'broker response'); // validate that the payload returned was successful $this->assertTrue($response[PAYLOAD_STATUS], (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS); $cacheGUID = $response[PAYLOAD_RESULTS][0]; // fetch records from cache and validate checksum $newRecords = json_decode(gzuncompress(gasCache::get($cacheGUID)), true); if (!validateCacheChecksum($newRecords,$errors)) $this->assertTrue(false, $errors); unset($newRecords[STRING_CHECKSUM]); // compare query to cache results by testing a random record $this->assertEquals($recCount, count($newRecords), (__FILE__ . COLON) . __LINE__ . sprintf(ERROR_DATA_ARRAY_COUNT, $recCount, 'newRecords', count($newRecords))); $rn = mt_rand(0, $recCount); $randomRec = $newRecords[$rn]; // validate that we have dateCreated, key and status fields which were inserted by the framework $this->assertTrue(array_key_exists(CM_TST_FIELD_TEST_CDATE, $randomRec), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, CM_TST_FIELD_TEST_CDATE, RESOURCE_CACHE)); $this->assertTrue(array_key_exists(CM_TST_TOKEN, $randomRec), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, CM_TST_TOKEN, RESOURCE_CACHE)); $this->assertTrue(array_key_exists(CM_TST_FIELD_TEST_STATUS, $randomRec), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, CM_TST_FIELD_TEST_STATUS, RESOURCE_CACHE)); // validate that these fields have content of the correct type or that the literals match // validate the token guid $this->assertTrue(validateGUID($randomRec[CM_TST_TOKEN]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_TOKEN)); // validate the status value $this->assertEquals(STATUS_ACTIVE, $randomRec[CM_TST_FIELD_TEST_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_FIELD_TEST_STATUS)); // validate the createdData type $this->assertTrue(validateMigrationDate($randomRec[CM_TST_FIELD_TEST_CDATE]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_FIELD_TEST_CDATE)); } /** * testUpdateOne() -- unit test method * * This unit test will fetch one record randomly with the requirement is that the string field not be equal * to the string to which we'll update to. * * Create a new string value to replace the string value in the target record and use this value in the update * query. * * Build the event-request payload and submit it, and evaluate the return. * * The following assertions are made: * * 1. that we can fetch a random record from the test suite * 2. that we fetched the record as an array * 3. that the array contains the record token * 4. the record token is a valid token * 5. we generate an eventGUID and validate that it's a valid GUID * 6. Validate that the response to the update event reported a successful completion * 5. Validate that the cached record now has the updated string stored * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 10-30-17 mks CORE-586: original coding * 01-18-19 mks DB-106: refactor for audit/journaling testing * */ public function testUpdateOne() { $testRecord = null; $errors = ''; // the update string $jayne = "Ten percent of nothin' is ... let me do the math here ... nothin' into nothin' ... carry the nothin' ... "; // fetch any record $query = [ TEST_FIELD_TEST_STRING => [ OPERAND_NULL => [ OPERATOR_DNE => [$jayne]]]]; $meta = static::$meta; $meta[META_DONUT_FILTER] = 1; $meta[META_LIMIT] = 1; $request = [ BROKER_REQUEST => BROKER_REQUEST_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->readBrokerClient->call(gzcompress(json_encode($request)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE])); // assign the data record, prior to update, to a static member and store the record token in another static static::$dataRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertTrue(is_array(static::$dataRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_DATA); $this->assertArrayHasKey((DB_TOKEN . static::$extTst), static::$dataRecord, basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, DB_TOKEN, STRING_DATA)); static::$dataKey = static::$dataRecord[(DB_TOKEN . static::$extTst)]; $oldString = static::$dataRecord[(TEST_FIELD_TEST_STRING . static::$extTst)]; $this->assertTrue(is_string($oldString), basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, TEST_FIELD_TEST_STRING)); // build a simple update query $query = [ CM_TST_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [static::$dataKey] ] ] ]; $update = [ CM_TST_FIELD_TEST_STRING => $jayne ]; static::$eventGUID = guid(); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . static::$eventGUID); $meta = static::$meta; // reset the meta payload $meta[META_EVENT_GUID] = static::$eventGUID; // build the update-event request $payload = [ BROKER_REQUEST => BROKER_REQUEST_UPDATE, BROKER_DATA => [ STRING_QUERY_DATA => $query, STRING_UPDATE_DATA => $update ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->writeBrokerClient->call(gzcompress(json_encode($payload)))), true); // verify that the update was successful $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS); // get the (updated) cache record and verify the update was stored in the updated cache record $rc = gasCache::get(($response[PAYLOAD_RESULTS][0])); $this->assertNotNull($rc, basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL); $newRecord = json_decode(gzuncompress($rc), true); if (!validateCacheChecksum($newRecord,$errors)) $this->assertTrue(false, $errors); $newString = $newRecord[0][CM_TST_FIELD_TEST_STRING]; $this->assertEquals($jayne, $newString, basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_STRING_MISMATCH, $jayne, $newString)); } /** * testUpdateAudit() -- unit test method * * This unit test ensures that we created an audit record triggered from the update event in the previous method. * The following assertions are made: * * 1-3: previously stored data in member statics is available and valid * 4: we're able to fetch the audit record using the data-record and event GUIDs as search query filters * 5: that the audit record was successfully fetched and stored * 6: that the audit record guid is successfully stored and validated * 7: that the operation assigned to the record is of type: EVENT_NAME_AUDIT_UPDATE * * Store the audit record and the audit-record token in class member static variables. * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 01-23-19 mks DB-106: original coding * */ public function testUpdateAudit() { // allow system time to write data to disk sleep(1); // validate that carry-over data still exists $this->assertTrue(validateGUID(static::$dataKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_KEY); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . DB_EVENT_GUID); $this->assertTrue(is_array(static::$dataRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . 'dataRecord'); // build a query based on the record and event guids to fetch the audit record $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT; $query = [ AUDIT_RECORD_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey ]]], DB_EVENT_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventGUID ]]], OPERAND_AND => null ]; $request = [ BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($request)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE])); static::$auditRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertTrue(is_array(static::$auditRecord), basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, STRING_AUDIT_DATA)); static::$auditKey = static::$auditRecord[DB_TOKEN . static::$extAud]; $this->assertTrue(validateGUID(static::$auditKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . static::$auditKey); $this->assertEquals(EVENT_NAME_AUDIT_UPDATE, static::$auditRecord[AUDIT_OPERATION . static::$extAud], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, EVENT_NAME_AUDIT_UPDATE, static::$auditRecord[AUDIT_OPERATION . static::$extAud])); } /** * testUpdateJournal() -- unit test method * * This unit test proves that we created a journal record from the update event a couple methods back. We query * the journal collection using a combination of the audit-record and event GUIDs. * The following assertions are made: * * 1-5: that previously-stored static member variables are still accessible and valid * 6: that we successfully fetched the journal record based off the audit-record and event GUIDs * 7: that the journal record is in the correct format and successfully stored as a member static * 8: that the journal token is in the correct format and was successfully stored as a member static * * * @author mike@givingassistant.org * @version 1.0 * * * HISTORY: * ======== * 01-23-19 mks DB-106: original coding * */ public function testUpdateJournal() { // validate that carry-over data still exists $this->assertTrue(validateGUID(static::$dataKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_KEY); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . DB_EVENT_GUID); $this->assertTrue(validateGUID(static::$auditKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . static::$auditKey); $this->assertTrue(is_array(static::$dataRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . 'dataRecord'); $this->assertTrue(is_array(static::$auditRecord), basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, STRING_AUDIT_DATA)); // build a query request to fetch the journal record based off the audit-record and event GUID tokens $query = [ JOURNAL_AUD_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$auditKey ]]], DB_EVENT_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventGUID]]], OPERAND_AND => null ]; $adminMeta = static::$adminMeta; $adminMeta[META_TEMPLATE] = TEMPLATE_CLASS_JOURNAL; $request = [ BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $adminMeta ]; $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($request)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE])); static::$journalRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertTrue(is_array(static::$journalRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . 'journalRecord'); static::$journalKey = static::$journalRecord[(DB_TOKEN . static::$extJnl)]; $this->assertTrue(validateGUID(static::$journalKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . static::$journalKey); } /** * testUpdateJournalRecovery() -- unit test method * * This unit tests takes the recently created journal record, we identified in the last test, and uses the audit * key for the event to call the journal-recovery event on the admin broker side. * * The following assertions are made: * 1-7: that previously stored data in static members are still valid and accessible * 8: that we successfully invoked the audit-restore event and that event completed successfully * 9: that we successfully fetched the restored data record * 10: that the test-string field was successfully restored back to the original value * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 01-23-19 mks DB-106: original coding * */ public function testUpdateJournalRecovery() { // validate that carry-over data still exists $this->assertTrue(validateGUID(static::$dataKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_KEY); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . DB_EVENT_GUID); $this->assertTrue(validateGUID(static::$auditKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . static::$auditKey); $this->assertTrue(validateGUID(static::$journalKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . static::$journalKey); $this->assertTrue(is_array(static::$journalRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . 'journalRecord'); $this->assertTrue(is_array(static::$dataRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . 'dataRecord'); $this->assertTrue(is_array(static::$auditRecord), basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, STRING_AUDIT_DATA)); // build the event request to restore the updated record back to it's previous state $query = [ STRING_KEY => static::$auditKey ]; $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT; $meta[META_DONUT_FILTER] = 1; $request = [ BROKER_REQUEST => BROKER_REQUEST_AUDIT_RESTORE, BROKER_DATA => $query, BROKER_META_DATA => $meta ]; // submit the event and test the payload results $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($request)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_AUDIT_RESTORE, $response[PAYLOAD_STATE])); // fetch the updated record and compare the text/string value to the original record stored in a static member $query = [ DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey ]]]]; $meta = static::$meta; $meta[META_DONUT_FILTER] = 1; $request = [ BROKER_REQUEST => BROKER_REQUEST_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->readBrokerClient->call(gzcompress(json_encode($request)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE])); $restoredRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $key = TEST_FIELD_TEST_STRING . static::$extTst; $this->assertEquals(static::$dataRecord[$key], $restoredRecord[$key], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, static::$dataRecord[$key], $restoredRecord[$key])); } /** * testUpdateMany() -- unit test method * * this unit test is similar to the previous test except for: * * -- we're executing a more-complex query which may not return records to update * -- we had to provide query-options so that namaste would update past the first matching record * * 1. assert that the widget object persisted * -- generate a target value for matching the test-integer field * -- generate the query * -- submit query to the broker and process the return payload * 2. payload return a success status * 3. payload return records (if null, it could mean that the query did not pick up qualifying records) * -- grab random updated record from cache * 4. verify that the string was updated in the refreshed cache record * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 11-01-17 mks CORE-586: original coding/port from mongo unit test * 12-05-18 mks DB-55: set-up a renewing data population for when the pool gets too thinned-out to * execute a query to update three records in a single event request * 02-05-19 mks DB-107: tweaked test to ensure we're testing the cache update for the changed record list * */ public function testUpdateMany() { $testRecord = null; // $query = ''; // $foundData = false; $this->assertTrue(is_object(static::$widget), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_WIDGET_404); // plan here is to use a complex query to return some random guids --- then we're going to submit an // complex update query that will change the string field to our favorite fixed value. // set-up some variables that will not change in the loop below: // first, let's limit the number of records updated/fetched to 3... static::$meta[META_LIMIT] = 3; // and update/fetch the last three records based on their created date $orderBy = [CM_TST_FIELD_TEST_CDATE => STRING_SORT_DESC]; // we're going to update the string field to this: $jayne = "Ten percent of nothin' is ... let me do the math here ... nothin' into nothin' ... carry the nothin' ... "; // build the update query $update = [ CM_TST_FIELD_TEST_STRING => $jayne, CM_TST_FIELD_TEST_INT => 1319 ]; // this is the selection query $query = [ CM_TST_FIELD_TEST_STRING => [ OPERAND_NULL => [ OPERATOR_DNE => [ $jayne ]]]]; // copy the meta static and add a limit $newMeta = static::$meta; $newMeta[META_LIMIT] = 3; // build the broker-event payload $payload = [ STRING_QUERY_DATA => $query, STRING_UPDATE_DATA => $update, STRING_ORDER_BY_DATA => $orderBy ]; // create the query/broker-event payload $request = [ BROKER_REQUEST => BROKER_REQUEST_UPDATE, BROKER_DATA => $payload, BROKER_META_DATA => static::$meta ]; // submit the request and unpack the results $eventPayload = gzcompress(json_encode($request)); $response = $this->writeBrokerClient->call($eventPayload); $response = json_decode(gzuncompress($response), true); $this->assertTrue($response[PAYLOAD_STATUS], (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS); $expectedString = strval($newMeta[META_LIMIT]) . ' records updated'; $this->assertEquals($expectedString, $response[PAYLOAD_DIAGNOSTICS][0], (basename(__METHOD__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, $expectedString, $response[PAYLOAD_DIAGNOSTICS][0]))); $this->assertTrue(validateGUID($response[PAYLOAD_RESULTS][0]), basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID. $response[PAYLOAD_RESULTS][0]); $cachedKeyList = json_decode(gzuncompress(gasCache::get($response[PAYLOAD_RESULTS][0])), true); $this->assertNotNull($cachedKeyList, basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL . COLON . $response[PAYLOAD_RESULTS][0]); // grab one of the records returned and pull that record from cache to validate the string update // there's two keys returned -- the before record list and the after record list. We want the latter. $ur = $cachedKeyList[1]; $this->assertEquals($jayne, $ur[CM_TST_FIELD_TEST_STRING], (__FILE__ . COLON . __LINE__) . COLON . sprintf(ERROR_UT_STRING_MISMATCH, $jayne, $ur[CM_TST_FIELD_TEST_STRING])); } /** * testNegativeUpdateOne() -- unit test method * * This unit test tests the ability to update a record by resetting a field marked as protected. If the framework * processes the request correctly, the event should fail with a validation state error. * * Create a request to update a record -- the field to be updated is protected -- and test the return payload * for a false status and a validation error in the state return. * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 11-01-17 mks CORE-586: original coding/port from mongo unit test * 01-23-19 mks DB-107: refactored to remove cached-record dependency making method independent * */ public function testNegativeUpdateOne() { $testRecord = null; $query = []; $meta = static::$meta; $meta[META_DONUT_FILTER] = 1; $meta[META_LIMIT] = 1; $request = [ BROKER_REQUEST => BROKER_REQUEST_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query], BROKER_META_DATA => $meta ]; // submit a request to fetch any random record $response = json_decode(gzuncompress($this->readBrokerClient->call(gzcompress(json_encode($request)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE])); $record = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertTrue(is_array($record), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_DATA); $recordToken = $record[(DB_TOKEN . static::$extTst)]; $this->assertTrue(validateGUID($recordToken), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . $recordToken); // build a simple update query $query = [ CM_TST_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [$recordToken] ] ] ]; // build the update query using a protected field -- doesn't matter since it should be rejected/dropped $update = [ CM_TST_FIELD_TEST_CDATE => STRING_DATA ]; // build the broker-update-event payload $payload = [ STRING_QUERY_DATA => $query, STRING_UPDATE_DATA => $update ]; $meta[META_EVENT_GUID] = guid(); // create the query/broker-event payload $request = [ BROKER_REQUEST => BROKER_REQUEST_UPDATE, BROKER_DATA => $payload, BROKER_META_DATA => $meta ]; // submit the request and process the result payload $response = json_decode(gzuncompress($this->writeBrokerClient->call(gzcompress(json_encode($request)))), true); $this->assertFalse($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_FALSE . BROKER_REQUEST_UPDATE); $this->assertEquals(STATE_VALIDATION_ERROR, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_STRING_MISMATCH, STATE_VALIDATION_ERROR, $response[PAYLOAD_STATE])); } /** * testDeleteOneRecord() -- unit test method * * this method tests the deletion of a single record, denoted by the cache-key we created earlier and stored * as a member property. * * 1. validate that the widget is still instantiated * 2. validate that the cacheKey still exists * -- Fetch the record from cache and extract the guid. * 3. validate the cache-extracted guid * 4. validate the cached record has status = active * -- build the query, submit, and unpack the return payload * 5. validate the response returned a status of true * -- fetch the record from cache * 6. validate that the record status is not long available in cache * * Since the test class has soft-deletes configured, we can pull the update from cache. * * Notes: * ------ * For this test to successfully work, we need to have the _updateRecord() code already in-play. * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 10-25-17 mks CORE-585: original coding, port from mongo version * 01-24-19 mks DB-107: updated to pull a random record instead of cached record * */ public function testDeleteOneRecord() { $testRecord = null; $query = []; $meta = static::$meta; $meta[META_DONUT_FILTER] = 1; $meta[META_LIMIT] = 1; $request = [ BROKER_REQUEST => BROKER_REQUEST_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query], BROKER_META_DATA => $meta ]; // submit a request to fetch any random record $response = json_decode(gzuncompress($this->readBrokerClient->call(gzcompress(json_encode($request)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE])); static::$dataRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertTrue(is_array(static::$dataRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_DATA); static::$dataKey = static::$dataRecord[(DB_TOKEN . static::$extTst)]; $this->assertTrue(validateGUID(static::$dataKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . static::$dataKey); // validate that the current record has an ACTIVE (e.g.: not-deleted) status $this->assertEquals(STATUS_ACTIVE, static::$dataRecord[(DB_STATUS . static::$extTst)], (__FILE__ . COLON . __LINE__) . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, DB_STATUS)); // delete the record we created a couple methods ago referenced by the static $cKey value $query = [ CM_TST_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey ]]]]; $request = [ STRING_QUERY_DATA => $query]; unset($meta[META_LIMIT]); static::$eventGUID = guid(); $meta[META_EVENT_GUID] = static::$eventGUID; // pre-load the guid for audit testing // create the query/broker-event payload $request = [ BROKER_REQUEST => BROKER_REQUEST_DELETE, BROKER_DATA => $request, BROKER_META_DATA => $meta ]; // submit the request and unpack the results $response = json_decode(gzuncompress($this->writeBrokerClient->call(gzcompress(json_encode($request)))), true); // verify that the update was successful $this->assertTrue($response[PAYLOAD_STATUS], (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS); // fetch record from cache to confirm that it was removed from, or does not exist in, cache $record = gasCache::get(static::$dataKey); $this->assertNull($record, (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_CACHE_FETCH_FAIL . COLON . static::$dataKey); } /** * testDeleteAudit() -- unit test method * * This unit tests ensures that we created an audit record from the previous delete event. We qualify this by * searching the audit collection using the record token (that was deleted in the previous method) coupled with * the eventGUID we generated for the delete event. * * The following assertions are made: * 1-3: previously saved data in member statics are still available and valid * 4: that we successfully fetched (and saved locally) the audit record * 5: that the audit token is valid and stored locally * 6: that the audit event is a delete event * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 01-24-19 mks DB-107: original coding * */ public function testDeleteAudit() { sleep(1); // give time for the system writes to catch-up $this->assertTrue(is_array(static::$dataRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_DATA); $this->assertTrue(validateGUID(static::$dataKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . JOURNAL_RECORD_GUID); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . META_EVENT_GUID); // to validate that an audit record was successfully completed on the previous delete-record event, we'll // query the audit collection using the data record token and the event guids we saved in the previous method $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT; $meta[META_DONUT_FILTER] = 1; $query = [ AUDIT_RECORD_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey ]]], DB_EVENT_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventGUID ]]], OPERAND_AND => null ]; $request = [ BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($request)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE])); static::$auditRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertTrue(is_array(static::$auditRecord), basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, STRING_AUDIT_DATA)); static::$auditKey = static::$auditRecord[(DB_TOKEN . static::$extAud)]; $this->assertTrue(validateGUID(static::$auditKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . static::$auditKey); // audit event can be either auditRecordDeleted (for hard deletes) or auditRecordUpdated (for soft deletes) $ao = static::$auditRecord[(AUDIT_OPERATION . static::$extAud)]; // audit operation $this->assertTrue((($ao == EVENT_NAME_AUDIT_DELETE) || ($ao == EVENT_NAME_AUDIT_UPDATE)), basename(__FILE__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, (EVENT_NAME_AUDIT_UPDATE . COMMA . EVENT_NAME_AUDIT_DELETE), $ao)); } /** * testDeleteJournal() -- unit test method * * This unit test ensures that a journal record was created off the delete-record event. Additionally, we test * that the journal record is correctly linked by executing a query requiring the audit-record token, the event * GUID and the data-record GUID to all be present in the journal record. * * We make the following assertions: * 1-5: assert that previously stored variables still exist and are in their proper format * 6: assert that the fetch of the journal record completed successfully (via the broker event) * 7: assert that we received the actual record * 8: assert that the record token is a valid GUID * * Store the journal record, in it's entirety, along with the record guid, in separate class static members. * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 02-05-19 mks DB-107: original coding * */ public function testDeleteJournal() { // validate that we still have access to previously-saved statics $this->assertTrue(is_array(static::$dataRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_DATA); $this->assertTrue(validateGUID(static::$dataKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . JOURNAL_RECORD_GUID); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . META_EVENT_GUID); $this->assertTrue(is_array(static::$auditRecord), basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_AUDIT_DATA); $this->assertTrue(validateGUID(static::$auditKey), basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . AUDIT_RECORD_TOKEN); // validate that the journal record was successfully completed by querying for the record off the audit // record token, the event GUID, and the original data-record GUID: (implicitly validating that all three // GUIDs (which are all required) exist in the journal record -- we could have just queried off the audit // record token since that GUID is guaranteed to be unique. $query = [ JOURNAL_AUD_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$auditKey ]]], JOURNAL_SYSEV_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventGUID]]], JOURNAL_RECORD_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey]]], OPERAND_AND => null ]; $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_JOURNAL; $meta[META_DONUT_FILTER] = 1; $payload = [ BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($payload)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE])); $this->assertTrue(is_array($response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]), basename(__FILE__) . COLON . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_QUERY_RESULTS); static::$journalRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; $this->assertArrayHasKey(DB_TOKEN . static::$extJnl, static::$journalRecord, basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_LOST_VARIABLE, DB_TOKEN)); static::$journalKey = static::$journalRecord[(DB_TOKEN . static::$extJnl)]; } /** * testDeleteJournalRecovery() -- unit test method * * this unit test invokes the journal-recovery process on the previously-deleted record to restore it. Since the * deleted record was soft-deleted, then we're checking to see that the previous record's status was toggled back * ACTIVE from deleted. * * The following assertions are made in this test: * * 1-8: carryover data is still actively stored and correct * 9: we've submitted a successful audit restore event request to the adminOut broker * 10: that the record was removed from cache * 11: that we're able to fetch the new record off the token only (status qualifier will be injected by namaste) * 12: that the record's status was correctly toggled from DELETED to ACTIVE * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 02-06-19 mks DB-107: original coding completed * */ public function testDeleteJournalRecovery() { // validate that we still have access to previously-saved statics $this->assertTrue(is_array(static::$dataRecord), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_DATA); $this->assertTrue(validateGUID(static::$dataKey), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . JOURNAL_RECORD_GUID); $this->assertTrue(validateGUID(static::$eventGUID), basename(__FILE__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . META_EVENT_GUID); $this->assertTrue(is_array(static::$auditRecord), basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_AUDIT_DATA); $this->assertTrue(validateGUID(static::$auditKey), basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . AUDIT_RECORD_TOKEN); $this->assertTrue(is_array(static::$journalRecord), basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_JOURNAL_DATA); $this->assertTrue(validateGUID(static::$journalKey), basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . JOURNAL_RECORD_GUID); // in order to roll-back the record to it's previous state, we invoke the restore event with the audit record GUID $query = [ STRING_KEY => static::$auditKey ]; $meta = static::$adminMeta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT; $meta[META_DONUT_FILTER] = 1; $meta[META_CLIENT] = CLIENT_AUDIT; // if this client is CLIENT_UNIT the unit test will fail $payload = [ BROKER_REQUEST => BROKER_REQUEST_AUDIT_RESTORE, BROKER_DATA => $query, BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->adminOutClient->call(gzcompress(json_encode($payload)))), true); // test that the restore command exec'd successfully $this->assertTrue($response[PAYLOAD_STATUS], basename(__FILE__) . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_AUDIT_RESTORE, $response[PAYLOAD_STATE])); // the record should still not be in-cache $record = gasCache::get(static::$dataKey); $this->assertNull($record, basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL); // fetch the new record $query = [ DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$dataKey ]]]]; $meta = static::$meta; $meta[META_TEMPLATE] = TEMPLATE_CLASS_TEST_PDO; $meta[META_DONUT_FILTER] = 1; $payload = [ BROKER_REQUEST => BROKER_REQUEST_FETCH, BROKER_DATA => [ STRING_QUERY_DATA => $query ], BROKER_META_DATA => $meta ]; $response = json_decode(gzuncompress($this->readBrokerClient->call(gzcompress(json_encode($payload)))), true); $this->assertTrue($response[PAYLOAD_STATUS], basename(__METHOD__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE])); $newStatus = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0][(DB_STATUS . static::$extTst)]; $this->assertEquals(STATUS_ACTIVE, $newStatus, basename(__METHOD__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, STATUS_ACTIVE, $newStatus)); } /** * testSP0() -- unit test method * * This tests the testPDO class stored procedure: testProc0 -- which tests invoking a stored procedure with * no input parameters. The SP returns an integer value assigned to a columnName (created in the SP) that * reflects the current total record count for the test table. * * We're testing the following: * * -- that the writeBroker can successfully accept and process a valid stored procedure request * -- that the request for this stored procedure was successfully processed * -- that the results sets is not-null (empty) (e.g.: data was returned) * -- that the results set contains the key "recordCount" in the payload * -- that the results set value, referenced by 'recordCount', is a non-zero value (some integer) * * Note: * ----- * The results set returns the record-count value reference as an associative array named "recordCount". This * value is set in the storedProcedure itself. There is a variable initialized in this test method which * sets the variable to this string value. Should you change the name of the value reference in the stored * procedure, you will need to update the $rc assignment to the same value. * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 11-13-17 mks CORE-588: initial coding * */ public function testSP0() { $rc = 'recordCount'; // if you change the test0 stored procedure return field name, update it here! $query = [ STRING_PROCEDURE_NAME => 'testProc0', STRING_PARAM_LIST => null ]; $request = [ BROKER_REQUEST => BROKER_REQUEST_CALL_SP, BROKER_DATA => $query, BROKER_META_DATA => static::$meta ]; $eventPayload = gzcompress(json_encode($request)); $response = $this->writeBrokerClient->call($eventPayload); $response = json_decode(gzuncompress($response), true); $this->assertTrue($response[PAYLOAD_STATUS], (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS); $this->assertNotEmpty($response[PAYLOAD_RESULTS], (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_EMPTY_RESULTS); $this->assertTrue(array_key_exists($rc, $response[PAYLOAD_RESULTS][0]), (__METHOD__ . AT . __LINE__) . COLON . sprintf(ERROR_UT_FIELD_404, $rc, PAYLOAD_RESULTS)); $this->assertGreaterThan(0, $response[PAYLOAD_RESULTS][0][$rc], (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_EXPECTING_NON_ZERO_INT . $response[PAYLOAD_RESULTS][0][$rc]); } /** * testSP1() -- unit test method * * this unit test invokes stored-procedure #1 in the testPDO class and evaluates the results. * * We're also testing the functionality of processing a stored-procedure request for a stored procedure that * requires input parameters. * * The stored procedure sorts the table based on the occurrence/count of the integer values stored in the integer * column and then takes the top-10 (if more than 10 records were returned) and sorts the list by frequency. * * We're going to loop through the return data and ensure that no integer value (key, not value) is duplicated * and that none of the count values are out-of-sequence (not sorted). * * Success Criteria: * * -- that the writeBroker can successfully accept and process a valid stored procedure request * -- that the request for this stored procedure was successfully processed * -- that the results sets is not-null (empty) (e.g.: data was returned) * -- that the result set contains at least one record * -- that the result set contains no more than 10 records * -- that the result set keys do not repeat * -- that the result set values are in sorted order * * * @author mike@givingassistant.org * @version 1.0 * * * HISTORY: * ======== * 11-13-17 mks CORE-688: original coding * */ public function testSP1() { $f1 = 'testInteger_tst'; $f2 = 'rowCount'; $query = [ STRING_PROCEDURE_NAME => 'testProc1', STRING_PARAM_LIST => [ 7 ]]; $request = [ BROKER_REQUEST => BROKER_REQUEST_CALL_SP, BROKER_DATA => $query, BROKER_META_DATA => static::$meta ]; $eventPayload = gzcompress(json_encode($request)); $response = $this->writeBrokerClient->call($eventPayload); $response = json_decode(gzuncompress($response), true); $this->assertTrue($response[PAYLOAD_STATUS], (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS); $this->assertNotEmpty($response[PAYLOAD_RESULTS], (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_EMPTY_RESULTS); $retData = $response[PAYLOAD_RESULTS]; $this->assertGreaterThan(0, count($retData), (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_EMPTY_RESULTS); $this->assertLessThanOrEqual(10, count($retData), (__METHOD__ . AT . __LINE__) . COLON . sprintf(ERROR_UT_EXCESSIVE_COUNT, 10, count($retData))); $numList = []; $numViolation = false; $maxVal = 0; $maxViolation = false; foreach ($retData as $record) { if (in_array($record[$f1], $numList)) { $numViolation = true; } $numList[] = $record[$f1]; if ($record[$f2] > $maxVal) { if ($maxVal != 0) { $maxViolation = true; } else { $maxVal = $record[$f2]; } } } $this->assertFalse($numViolation, (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_GENERIC_FAIL . 'repeat integer value in data set'); $this->assertFalse($maxViolation, (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_GENERIC_FAIL . 'sorted value sequence violation in data set'); } /** * testSP2() -- unit test method * * This method tests the third, and final, stored-procedure in our PDO test class. The purpose of this test is to * validate stored-procedure processing for a stored-procedure that requires both IN and OUT parameters and, in this * specific case, multiple OUT params. * * The stored-procedure has one IN param and two OUT params. It's function is to pass in an integer value and, * for all records that have that integer value in the integer column, calculates the average and standard * deviation of the float-values stored in the same record, returning two output parameters in the results set. * * NOTE: * ----- * The return "column" names in the results payload are determined in the stored procedure. They're defined as * lvars($f1, $f2) -- so if you change these values in the stored-procedure, you will also need to update the * lvar assignment(s) in this method. * * Criteria for success: * -- that the writeBroker can successfully accept and process a valid stored procedure request * -- that the request for this stored procedure was successfully processed * -- that the results sets is not-null (empty) (e.g.: data was returned) * -- that the result set contains at only one record * -- the $f1 (avgDouble) column exists as a key in the results set * -- the $f2 (stdDevDouble) column exists as a key in the results set * * * @author mike@givingassistant.org * @version 1.0 * * HISTORY: * ======== * 11-13-17 mks CORE-588:original coding * */ public function testSP2() { $f1 = 'avgDouble'; $f2 = 'stdDevDouble'; $query = [ STRING_PROCEDURE_NAME => 'testProc2', STRING_PARAM_LIST => [12]]; $request = [ BROKER_REQUEST => BROKER_REQUEST_CALL_SP, BROKER_DATA => $query, BROKER_META_DATA => static::$meta ]; $eventPayload = gzcompress(json_encode($request)); $response = $this->writeBrokerClient->call($eventPayload); $response = json_decode(gzuncompress($response), true); $this->assertTrue($response[PAYLOAD_STATUS], (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS); $this->assertNotEmpty($response[PAYLOAD_RESULTS], (__METHOD__ . AT . __LINE__) . COLON . ERROR_UT_EMPTY_RESULTS); $this->assertEquals(1, count($response[PAYLOAD_RESULTS]), (__METHOD__ . AT . __LINE__) . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, 1, count($response[PAYLOAD_RESULTS]))); $this->assertTrue(array_key_exists($f1, $response[PAYLOAD_RESULTS][0]), (__METHOD__ . AT . __LINE__) . COLON . sprintf(ERROR_UT_FIELD_404, $f1, PAYLOAD_RESULTS)); $this->assertTrue(array_key_exists($f2, $response[PAYLOAD_RESULTS][0]), (__METHOD__ . AT . __LINE__) . COLON . sprintf(ERROR_UT_FIELD_404, $f2, PAYLOAD_RESULTS)); } }