Files
namaste/tests/unit/writeBrokerPDOTest.php
gramps 373ebc8c93 Archive: Namaste PHP AMQP framework v1.0 (2017-2020)
952 days continuous production uptime, 40k+ tp/s single node.
Original corpo Bitbucket history not included — clean archive commit.
2026-04-05 09:49:30 -07:00

1447 lines
76 KiB
PHP

<?php
/**
* Created by PhpStorm.
* User: mshallop
* Date: 10/23/17
* Time: 3:04 PM
*/
$_REDIRECT = false;
require(dirname(__DIR__) . '/../config/sneakerstrap.inc'); // and load the namaste environment
use PHPUnit\Framework\TestCase;
/**
* validateMigrationDate() -- file method
*
* This method validates a date string in the default format similar to: "2018-08-12 19:06:44"
*
* The method returns a boolean indicating if the date is valid.
*
* @author mike@givingassistant.org
* @version 1.0
*
* @param string $date - string containing the date string returned by the date-picker widget
* @return bool
*
*
* HISTORY:
* ========
* 10-02-18 mks DB-43: original coding
* 03-29-19 mks DB-116: updated for broker-services-level cache-mapping
* 01-23-20 mks DB-150: updated for PHP7.4 class member type casting
*
*/
function validateMigrationDate(string $date): bool
{
$dateFormat = 'Y-m-d H:i:s';
$d = DateTime::createFromFormat($dateFormat, $date);
return $d && $d->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));
}
}