952 days continuous production uptime, 40k+ tp/s single node. Original corpo Bitbucket history not included — clean archive commit.
1678 lines
88 KiB
PHP
1678 lines
88 KiB
PHP
<?php
|
|
|
|
$_REDIRECT = false;
|
|
require(dirname(__DIR__) . '/../config/sneakerstrap.inc'); // and load the namaste environment
|
|
|
|
use /** @noinspection PhpUndefinedClassInspection */ PHPUnit\Framework\TestCase;
|
|
|
|
/** @noinspection PhpUndefinedClassInspection */
|
|
class writeBrokerMongoTest extends TestCase
|
|
{
|
|
protected gacBrokerClient $readBrokerClient;
|
|
protected gacBrokerClient $writeBrokerClient;
|
|
protected gacBrokerClient $adminOutClient;
|
|
protected static ?array $meta = null;
|
|
protected static ?array $adminMeta = null;
|
|
protected static ?object $widget;
|
|
protected static string $cKey = '';
|
|
protected static ?array $testRecord;
|
|
protected static ?array $journalRecord;
|
|
protected static string $checksum = '';
|
|
protected static string $testRecordToken;
|
|
protected static string $auditRecordToken;
|
|
protected static string $eventRecordToken;
|
|
protected static ?array $originalTestRecord;
|
|
protected static ?array $auditRecord;
|
|
protected static string $jayne = "Ten percent of nothin' is ... let me do the math here ... nothin' into nothin' ... carry the nothin' ... ";
|
|
|
|
|
|
/**
|
|
* 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:
|
|
* ========
|
|
* 07-31-17 mks original coding
|
|
*
|
|
*/
|
|
public static function setUpBeforeClass()
|
|
{
|
|
/** @noinspection PhpUndefinedClassInspection */
|
|
parent::setUpBeforeClass();
|
|
|
|
// meta data (for namaste)
|
|
static::$meta = [
|
|
META_CLIENT => CLIENT_UNIT,
|
|
META_CLIENT_IP => STRING_SESSION_HOME,
|
|
META_SYSTEM_NOTES => STRING_ORIGIN_UT,
|
|
META_TEMPLATE => TEMPLATE_CLASS_TEST_MONGO
|
|
];
|
|
|
|
// 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:
|
|
* ========
|
|
* 07-31-17 mks original coding
|
|
* 12-10-18 mks DB-71: support for audit/journal 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);
|
|
|
|
// ensure that caching, auditing, and journaling are enabled for the class and that deletes are set to false
|
|
$this->assertTrue(static::$widget->useCache, __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_TRUE . STRING_CACHE);
|
|
$this->assertGreaterThan(0, static::$widget->useAuditing, __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_NON_ZERO_INT . static::$widget->useAuditing);
|
|
$this->assertTrue(static::$widget->useJournaling, __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_TRUE . STRING_JOURNAL);
|
|
$this->assertFalse(static::$widget->useDeletes, __FILE__ . COLON . __LINE__ . ERROR_UT_EXPECTING_FALSE . STRING_DELETE);
|
|
}
|
|
|
|
|
|
/**
|
|
* 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:
|
|
* ========
|
|
* 07-27-17 mks original coding
|
|
*
|
|
*/
|
|
protected function tearDown()
|
|
{
|
|
/** @noinspection PhpUndefinedMethodInspection */
|
|
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)) {
|
|
/** @noinspection PhpUndefinedMethodInspection */
|
|
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
|
|
*
|
|
* Assumptions:
|
|
* ------------
|
|
* That we know the test class being used supports caching.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 07-31-17 mks CORE-486: original coding
|
|
* 12-11-18 mks DB-71: additional queries for testing audit/journaling
|
|
* 03-14-19 mks DB-116: updated for the new cacheMapping
|
|
*
|
|
*/
|
|
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);
|
|
|
|
// 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[0][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[0][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[0][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[0][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[0]), __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[0]), __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[0]), __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[0][CM_TST_TOKEN]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_TOKEN));
|
|
// validate the status value
|
|
$this->assertEquals(STATUS_ACTIVE, $cacheRecord[0][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(is_int($cacheRecord[0][CM_TST_FIELD_TEST_CDATE]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_FIELD_TEST_CDATE));
|
|
|
|
// to prepare for the next unit test, let's store some data about the newly-created record for compare/contrast
|
|
// start by fetching an unfiltered version of the new record
|
|
$query = [ DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [$cacheRecord[0][CM_TST_TOKEN]]]]];
|
|
$tmpMeta = static::$meta;
|
|
$tmpMeta[META_DONUT_FILTER] = 1;
|
|
$payload = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [
|
|
STRING_QUERY_DATA => $query
|
|
],
|
|
BROKER_META_DATA => $tmpMeta
|
|
];
|
|
$payload = gzcompress(json_encode($payload));
|
|
$response = $this->readBrokerClient->call($payload);
|
|
$results = json_decode(gzuncompress($response), true);
|
|
static::$testRecord = $results[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0]; // store a copy of the new record
|
|
static::$checksum = md5(base64_encode(json_encode(static::$testRecord))); // calculate & store the checksum
|
|
|
|
// save the cKey value as we're going to use this record in subsequent tests
|
|
static::$cKey = $cKey;
|
|
}
|
|
|
|
|
|
/**
|
|
* testInsertAudit() -- unit test method
|
|
*
|
|
* This unit test will validate that the previous test, for creating/inserting a new record, will proc an audit
|
|
* event. We've saved a copy, in the stored format, of the record just created as static member and we've
|
|
* calculated the checksum of the encoded record snapshot, also in a member variable, prior to calling this method.
|
|
*
|
|
* The first assertions in this test confirm that the requisite saved data exists and is in the correct format.
|
|
*
|
|
* Next, we fetch the cached record so that we can extract both the GUID of newly-created record, and the record's
|
|
* event GUID. Validate both as GUIDs.
|
|
*
|
|
* Then we build a query to fetch the audit record from admin. We test that we were able to fetch the record and
|
|
* then we calculate the checksum of the record snapshot and compare it to the stored checksum.
|
|
*
|
|
* If all assertion complete successfully, then we store the token GUID for the audit record as a member static
|
|
* to use in the next test.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 12-11-18 mks DB-77: original coding
|
|
*
|
|
*/
|
|
public function testInsertAudit()
|
|
{
|
|
// pause to allow disk writes to catch up
|
|
sleep(1);
|
|
$this->assertNotEmpty(static::$cKey, __FILE__ . COLON . __LINE__ . COLON . 'lost the cache key');
|
|
$this->assertNotEmpty(static::$testRecord, __FILE__ . COLON . __LINE__ . COLON . 'lost the record');
|
|
$this->assertTrue(is_array(static::$testRecord), __FILE__ . COLON . __LINE__ . COLON . 'munged the record');
|
|
$this->assertNotEmpty(static::$checksum, __FILE__ . COLON . __LINE__ . COLON . 'lost the cksum');
|
|
// fetch the cached record
|
|
$cacheRecord = gasCache::get(static::$cKey);
|
|
$this->assertNotNull($cacheRecord, (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
$cacheRecord = json_decode(gzuncompress($cacheRecord), true);
|
|
$cacheRecord = $cacheRecord[0];
|
|
// extract the token for the cached record, and the eventGUID to fetch the audit record that should
|
|
// have been created in the last test...
|
|
$recordToken = $cacheRecord[CM_TST_TOKEN];
|
|
$eventToken = $cacheRecord[CM_TST_EVENT_GUID];
|
|
$this->assertTrue(validateGUID($recordToken), __FILE__ . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . $recordToken);
|
|
$this->assertTrue(validateGUID($eventToken), __FILE__ . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . $eventToken);
|
|
// save these two tokens for the next test
|
|
static::$eventRecordToken = $eventToken;
|
|
static::$testRecordToken = $recordToken;
|
|
|
|
// build the query to fetch the audit record from the admin service
|
|
$query = [
|
|
AUDIT_RECORD_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ $recordToken ]]],
|
|
DB_EVENT_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ $eventToken ]]],
|
|
OPERAND_AND => null
|
|
];
|
|
static::$adminMeta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT;
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH,
|
|
BROKER_DATA => [ STRING_QUERY_DATA => $query ],
|
|
BROKER_META_DATA => static::$adminMeta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->adminOutClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE]));
|
|
$auditData = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0];
|
|
// we've validated that we created an audit record -- test that it's the correct record
|
|
// because the order of the fields may have changed, we validate by looking at the record GUID values
|
|
$ext = COLLECTION_MONGO_TEST_EXT;
|
|
$t1 = static::$testRecord[(DB_TOKEN . $ext)];
|
|
$t2 = $auditData[(AUDIT_RECORD_TOKEN . COLLECTION_MONGO_AUDIT_EXT)];
|
|
$this->assertEquals($t1, $t2, __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, 'new record checksum', 'audit record checksum'));
|
|
$this->assertTrue(validateGUID($auditData[DB_TOKEN . COLLECTION_MONGO_AUDIT_EXT]), __FILE__ . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . $auditData[DB_TOKEN . COLLECTION_MONGO_AUDIT_EXT]);
|
|
// save the audit record token
|
|
static::$auditRecordToken = $auditData[DB_TOKEN . COLLECTION_MONGO_AUDIT_EXT];
|
|
}
|
|
|
|
|
|
/**
|
|
* testInsertJournal() -- unit test method
|
|
*
|
|
* This test takes information saved in the previous method (hence the assertions at the start of the method),
|
|
* and uses this data to fetch the journal record from the database.
|
|
*
|
|
* We're going to query the db on three elements:
|
|
*
|
|
* 1. The namaste-record token
|
|
* 2. The event GUID generated during the unit-test insert (one record) test
|
|
* 3. The audit-record guid generated from the insert operation
|
|
*
|
|
* Even if there is more than one journal record associated with the namaste record, using the audit record key
|
|
* (as well as the event guid) and the record GUID, forces the query to return, at most, a single record.
|
|
* And it validates that we've successfully saved the correct journal record to the database using that query
|
|
* instead of multiple assertions.
|
|
*
|
|
* We assert that the fetch request was successful and that we returned only one record in the query. The method
|
|
* then extracts the data from the return payload and assigns it to a member variable for the next unit test.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 12-11-18 mks DB-77: original coding
|
|
*
|
|
*/
|
|
public function testInsertJournal()
|
|
{
|
|
// pause to let disk-writes catch-up
|
|
sleep(1);
|
|
$this->assertTrue(validateGUID(static::$auditRecordToken), __FILE__ . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$auditRecordToken);
|
|
$this->assertTrue(validateGUID(static::$eventRecordToken), __FILE__ . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$eventRecordToken);
|
|
$this->assertTrue(validateGUID(static::$testRecordToken), __FILE__ . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$testRecordToken);
|
|
$this->assertNotEmpty(static::$cKey, __FILE__ . COLON . __LINE__ . COLON . 'lost the cache key');
|
|
$testRecord = gasCache::get(static::$cKey);
|
|
$this->assertNotNull($testRecord, (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
|
|
// implicitly test that we created the journal record off the insert event by querying the database by the
|
|
// data record token, the event guid, and the audit token together. This way, if the record has more than
|
|
// one journal record associated with the record guid, we're still filtering by the event guid.
|
|
|
|
// build the fetch query for the journaling collection
|
|
$query = [
|
|
JOURNAL_AUD_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$auditRecordToken ]]],
|
|
JOURNAL_SYSEV_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventRecordToken]]],
|
|
JOURNAL_RECORD_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$testRecordToken]]],
|
|
OPERAND_AND => null
|
|
];
|
|
$tmpMeta = static::$adminMeta;
|
|
$tmpMeta[META_TEMPLATE] = TEMPLATE_CLASS_JOURNAL;
|
|
$payload = [
|
|
BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH,
|
|
BROKER_DATA => [
|
|
STRING_QUERY_DATA => $query
|
|
],
|
|
BROKER_META_DATA => $tmpMeta
|
|
];
|
|
$request = gzcompress(json_encode($payload));
|
|
$response = $this->adminOutClient->call($request);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE]));
|
|
$this->assertEquals(1, count($response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, 1, count($response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS])));
|
|
// load the journal record into a static member for the next test
|
|
static::$journalRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0];
|
|
}
|
|
|
|
|
|
/**
|
|
* testInsertJournalRecovery() -- unit test method
|
|
*
|
|
* This method tests that we're able to "recover" the previous operation using the audit record that was created
|
|
* when we created the new namaste record. Because the previous operation was a "CREATE", the rollback event
|
|
* stored in journaling should remove the record from existence. Because the test class supports soft-deletes,
|
|
* that means that the record will not actually be deleted but, instead, have it's status set to DELETED.
|
|
*
|
|
* This means that we're also, albeit indirectly, testing the fetch-broker's ability to process a query that
|
|
* executes successfully but returns no records.
|
|
*
|
|
* ASSERTIONS:
|
|
* -----------
|
|
* Validate that we have stored the the necessary data in member statics -- ensure that they're valid and available
|
|
* Restore the audit record (by invoking the recovery event) and test that the event completed successfully
|
|
* Fetch the original record and validate that the record was "restored" (deleted) successfully
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 12-11-18 mks DB-77: original coding
|
|
*
|
|
*/
|
|
public function testInsertJournalRecovery()
|
|
{
|
|
$this->assertTrue(!empty(static::$journalRecord), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, 'journalRecord', 'class member'));
|
|
$this->assertTrue(validateGUID(static::$auditRecordToken), __FILE__ . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$auditRecordToken);
|
|
$this->assertTrue(validateGUID(static::$testRecordToken), __FILE__ . COLON . __LINE__ . COLON . ERROR_INVALID_GUID . static::$testRecordToken);
|
|
$this->assertNotEmpty(static::$cKey, __FILE__ . COLON . __LINE__ . COLON . 'lost the cache key');
|
|
$testRecord = gasCache::get(static::$cKey);
|
|
$this->assertNotNull($testRecord, (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
|
|
// build the recovery query which should flag the targeted record into a deleted state
|
|
$query = [ STRING_KEY => static::$auditRecordToken ];
|
|
$meta = static::$adminMeta;
|
|
$meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT;
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_AUDIT_RESTORE,
|
|
BROKER_DATA => $query,
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->adminOutClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_AUDIT_RESTORE, $response[PAYLOAD_STATE]));
|
|
// if we're still executing, that the record was "restored" --- attempt to pull the record
|
|
$query = [ DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [static::$testRecordToken ]]]];
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [
|
|
STRING_QUERY_DATA => $query
|
|
],
|
|
BROKER_META_DATA => static::$meta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->readBrokerClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertEquals(STATE_NOT_FOUND, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . sprintf(ERROR_UT_VALS_NOT_EQUAL, STATE_NOT_FOUND, $response[PAYLOAD_STATE]));
|
|
}
|
|
|
|
|
|
/**
|
|
* 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
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 08-01-17 mks original coding
|
|
* 11-28-17 mks CORE-635: updated the unit test for the new cache-handling method
|
|
* 03-15-19 mks DB-116: refactored for broker-level cacheMapping
|
|
*
|
|
*/
|
|
public function testMultipleInserts()
|
|
{
|
|
$testRecord = null;
|
|
$this->assertTrue(is_object(static::$widget), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_WIDGET_404);
|
|
|
|
// create a random number of records between 50 and 100
|
|
$recCount = mt_rand(50,100);
|
|
$testRecord = static::$widget->template->buildTestData($recCount);
|
|
$this->assertTrue(is_array($testRecord), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_TRUE . 'is_array($testRecord)');
|
|
$this->assertEquals($recCount, 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);
|
|
|
|
$this->assertTrue($response[PAYLOAD_STATUS], (__FILE__ . COLON) . __LINE__ . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS);
|
|
// validate that the count of inserted records matches the number of records, or cache keys, returned
|
|
// first, fetch the referenced item from cache
|
|
$guidPayload = json_decode(gzuncompress(gasCache::get($response[PAYLOAD_RESULTS][0])), true);
|
|
$this->assertTrue(is_array($guidPayload), basename(__METHOD__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, 'guidPayload'));
|
|
$this->assertEquals(count($guidPayload), $recCount + 1, basename(__METHOD__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, count($guidPayload), ($recCount + 1)));
|
|
|
|
// validate the checksum for the cached-key list
|
|
$checksum = $guidPayload[STRING_CHECKSUM];
|
|
unset($guidPayload[STRING_CHECKSUM]);
|
|
$newCSum = md5(gzcompress(json_encode($guidPayload)));
|
|
$this->assertEquals($checksum, $newCSum, (__FILE__ . COLON . __LINE__ . COLON) . ERROR_UT_CHECKSUM);
|
|
|
|
// fetch a random record from cache
|
|
$rr = mt_rand(0, ($recCount - 1));
|
|
$rec = $guidPayload[$rr];
|
|
$recCacheGUID = $rec[STRING_KEY];
|
|
$this->assertTrue(validateGUID($recCacheGUID), basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_INVALID_GUID . $recCacheGUID);
|
|
|
|
// compare the random record base values to the same record still stored in the array we submitted to the broker
|
|
$this->assertEquals($testRecord[$rr][CM_TST_FIELD_TEST_INT], $rec[CM_TST_FIELD_TEST_INT], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_INT));
|
|
$this->assertEquals($testRecord[$rr][CM_TST_FIELD_TEST_STRING], $rec[CM_TST_FIELD_TEST_STRING], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_STRING));
|
|
$this->assertEquals($testRecord[$rr][CM_TST_FIELD_TEST_DOUBLE], $rec[CM_TST_FIELD_TEST_DOUBLE], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_DOUBLE));
|
|
$this->assertEquals($testRecord[$rr][CM_TST_FIELD_TEST_BOOL], $rec[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, $rec), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, CM_TST_FIELD_TEST_CDATE, RESOURCE_CACHE));
|
|
$this->assertTrue(array_key_exists(CM_TST_TOKEN, $rec), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_404, CM_TST_TOKEN, RESOURCE_CACHE));
|
|
$this->assertTrue(array_key_exists(CM_TST_FIELD_TEST_STATUS, $rec), __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($rec[CM_TST_TOKEN]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_TOKEN));
|
|
// validate the status value
|
|
$this->assertEquals(STATUS_ACTIVE, $rec[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(is_int($rec[CM_TST_FIELD_TEST_CDATE]), __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_FIELD_VALUE, CM_TST_FIELD_TEST_CDATE));
|
|
}
|
|
|
|
|
|
/**
|
|
* testNegativeInsertCountExceedsLimit()
|
|
*
|
|
* this is a negative unit test in that we're intentionally provoking a failure in the form of a request that the
|
|
* number of new records to create exceeds the declared maximum number of allowable records to be processed in a
|
|
* single event request.
|
|
*
|
|
* Pull the current record limit from the configuration and then generate a payload of records that is equal to
|
|
* the record limit, plus one.
|
|
*
|
|
* Create the payload for the event, submit the request, and then test out the return payload results against
|
|
* the expectations.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 09-11-17 mks CORE-501: original coding
|
|
*
|
|
*/
|
|
public function testNegativeInsertCountExceedsLimit()
|
|
{
|
|
$testRecords = null;
|
|
$this->assertTrue(is_object(static::$widget), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_WIDGET_404);
|
|
|
|
// create more records than the current configuration allows
|
|
$qrl = intval(gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_QUERY_RECORD_LIMIT]);
|
|
$recCount = 1 + $qrl;
|
|
$testRecords = static::$widget->template->buildTestData($recCount);
|
|
$this->assertTrue(is_array($testRecords), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_TRUE . 'is_array($testRecord)');
|
|
$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);
|
|
|
|
// test that the event was rejected with the expected state value
|
|
$this->assertFalse($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_FALSE . BROKER_REQUEST_CREATE);
|
|
$this->assertEquals(STATE_DATA_ERROR, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_STRING_MISMATCH, STATE_DATA_ERROR, $response[PAYLOAD_STATE]));
|
|
}
|
|
|
|
|
|
/**
|
|
* testUpdateOne() -- unit test method
|
|
*
|
|
* this unit test will pull the record we saved in testOneInsert() -- because this was a recently saved record,
|
|
* we know the primary key value and can launch a query to cache to fetch the record.
|
|
*
|
|
* We'll pull the token value from the cache record and compare it to the static::$cKey to ensure it's the same and
|
|
* use the value to build the query for the update event.
|
|
*
|
|
* 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.
|
|
*
|
|
* 1. Validate that the widget class is still active
|
|
* 2. Validate that the cache key is available via a local property
|
|
* 3. Validate that we were able to fetch the cached record by the key
|
|
* -- Build the event-query payload
|
|
* -- Submit and unpack the broker response
|
|
* 4. Validate that the response reported a successful completion
|
|
* -- Fetch the cached record which should have been updated on a successful update db event
|
|
* 5. Validate that the cached record now has the updated string stored
|
|
*
|
|
* Note that we're implicitly validating the cache-update process by going to cache for our records instead
|
|
* of submitting queries to the read-broker.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 08-01-17 mks CORE-486: original coding
|
|
* 01-03-19 mks DB-79: audit-testing support -- refactored to grab a random record b/c we "deleted" the
|
|
* record in a previous method testing journal recovery on a create operation
|
|
*
|
|
*/
|
|
public function testUpdateOne()
|
|
{
|
|
$testRecord = null;
|
|
|
|
// build a simple update query by pulling an active record that doesn't have the jayne string
|
|
$query = [TEST_FIELD_TEST_STRING => [ OPERAND_NULL => [ OPERATOR_DNE => [static::$jayne]]]];
|
|
|
|
// we need to fetch the "before" version of the record before it's updated for testing the audit later
|
|
$adminMeta = static::$adminMeta;
|
|
$adminMeta[META_DONUT_FILTER] = 1;
|
|
$adminMeta[META_SKIP_AUDIT] = 1;
|
|
$adminMeta[META_TEMPLATE] = TEMPLATE_CLASS_TEST_MONGO;
|
|
$adminMeta[META_LIMIT] = 1;
|
|
$adminMeta[META_EVENT_GUID] = guid();
|
|
$ext = '_tst';
|
|
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [ STRING_QUERY_DATA => $query ],
|
|
BROKER_META_DATA => $adminMeta
|
|
];
|
|
$eventPayload = gzcompress(json_encode($request));
|
|
$response = $this->readBrokerClient->call($eventPayload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], (basename(__FILE__) . COLON . __LINE__ ) . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE]));
|
|
$recCount = intval($response[PAYLOAD_RESULTS][STRING_QUERY_DATA][STRING_REC_COUNT_RET]);
|
|
$this->assertEquals(1, $recCount, (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, 1, $recCount) . MONGO_STRING_COUNT);
|
|
$testRecord = $response[PAYLOAD_RESULTS][PAYLOAD_QUERY][0];
|
|
$this->assertEquals(STATUS_ACTIVE, $testRecord[(DB_STATUS . $ext)], (basename(__FILE__) . COLON . __FILE__) . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, STATUS_ACTIVE, $testRecord[(DB_STATUS . $ext)]));
|
|
$this->assertArrayHasKey((STRING_TOKEN . $ext), $testRecord, (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_FIELD_404, STRING_TOKEN, 'testRecord'));
|
|
$guid = $testRecord[(STRING_TOKEN . $ext)];
|
|
$this->assertTrue(validateGUID($guid), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . $guid);
|
|
// we have a copy of the record we're going to update - build the update query
|
|
$query = [ DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [$guid]]]];
|
|
|
|
// quick validate that we're working with a new string
|
|
$testString = '';
|
|
if (array_key_exists((TEST_FIELD_TEST_STRING . $ext), $testRecord)) $testString = $testRecord[(TEST_FIELD_TEST_STRING . $ext)];
|
|
elseif (array_key_exists(TEST_FIELD_TEST_STRING, $testRecord)) $testString = $testRecord[TEST_FIELD_TEST_STRING];
|
|
$this->assertNotEquals(static::$jayne, $testString, (__FILE__ . COLON . __LINE__) . COLON . sprintf(ERROR_UT_STRING_MATCH, 'jayne', (TEST_FIELD_TEST_STRING . $ext)));
|
|
|
|
// build the update query
|
|
$update = [ CM_TST_FIELD_TEST_STRING => static::$jayne ];
|
|
|
|
// build the broker-update-event payload
|
|
$payload = [
|
|
STRING_QUERY_DATA => $query,
|
|
STRING_UPDATE_DATA => $update
|
|
];
|
|
|
|
$eventGUID = guid(); // generate a known event guid for audit tracking
|
|
$meta = static::$meta;
|
|
$meta[META_EVENT_GUID] = $eventGUID;
|
|
// 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
|
|
$eventPayload = gzcompress(json_encode($request));
|
|
$response = $this->writeBrokerClient->call($eventPayload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
|
|
// verify that the update was successful
|
|
$this->assertTrue($response[PAYLOAD_STATUS], (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS);
|
|
|
|
// we're no longer testing the cache-record since we disabled caching for this event
|
|
// $newRecord = json_decode(gzuncompress(gasCache::get($guid)), true);
|
|
// $newString = $newRecord[0][CM_TST_FIELD_TEST_STRING];
|
|
// $this->assertEquals(static::$jayne, $newString, (__FILE__ . COLON . __LINE__) . COLON . sprintf(ERROR_UT_STRING_MISMATCH, static::$jayne, $newString));
|
|
// save the guids and a copy of the original record in the class statics
|
|
static::$eventRecordToken = $eventGUID;
|
|
static::$testRecordToken = $guid;
|
|
static::$originalTestRecord = $testRecord;
|
|
}
|
|
|
|
|
|
/**
|
|
* testUpdateAudit() -- unit test method
|
|
*
|
|
* This unit test is predicated on the previous method where we fetched a random, valid record that hasn't had the
|
|
* string value changed and, was updated to change the string value stored.
|
|
*
|
|
* We've previously stored the original record prior to update. In this method, we'll fetch the audit record
|
|
* based on the record and event GUIDs and validate that we created an audit record off the update event.
|
|
*
|
|
* Next, we extract the audit record token and store it as a class static as well as the entire audit record.
|
|
*
|
|
* This sets us up for the next method which tests that a journal record was created, also off the update event,
|
|
* that's linked-back to the audit record.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 01-04-19 mks DB-79: original coding
|
|
*
|
|
*/
|
|
public function testUpdateAudit()
|
|
{
|
|
// verify that we have a eventGUID so we can fetch the audit token, and verify that we have a copy of
|
|
// the original record before it was updated in the previous method
|
|
$this->assertTrue(validateGUID(static::$eventRecordToken), (basename(__FILE__) . COLON . __LINE__) . ERROR_INVALID_GUID . static::$eventRecordToken);
|
|
$this->assertTrue(validateGUID(static::$testRecordToken), (basename(__FILE__) . COLON . __LINE__) . ERROR_INVALID_GUID . static::$testRecordToken);
|
|
$this->assertTrue(is_array(static::$originalTestRecord), (basename(__FILE__) . COLON . __LINE__) . ERROR_UT_LOST_VARIABLE . 'originalTestRecord');
|
|
|
|
// fetch the audit record based on the record and event guids, testing that we successfully created an audit
|
|
// record off the update operation in the previous method
|
|
$adminMeta = static::$adminMeta;
|
|
$adminMeta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT;
|
|
$query = [
|
|
AUDIT_RECORD_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$testRecordToken ]]],
|
|
DB_EVENT_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventRecordToken ]]],
|
|
OPERAND_AND => null
|
|
];
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH,
|
|
BROKER_DATA => [ STRING_QUERY_DATA => $query ],
|
|
BROKER_META_DATA => $adminMeta
|
|
];
|
|
sleep(1);
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->adminOutClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE]));
|
|
static::$auditRecordToken = $response[PAYLOAD_RESULTS][PAYLOAD_QUERY][0][STRING_TOKEN . COLLECTION_MONGO_AUDIT_EXT];
|
|
$this->assertNotEmpty(static::$auditRecordToken, (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_LOST_VARIABLE . 'audit record token');
|
|
$this->assertTrue(validateGUID(static::$auditRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$auditRecordToken);
|
|
static::$auditRecord = $response[PAYLOAD_RESULTS][PAYLOAD_QUERY][0];
|
|
$this->assertTrue(is_array(static::$auditRecord), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_GENERIC_FAIL . 'failed to fetch audit record');
|
|
}
|
|
|
|
|
|
/**
|
|
* testUpdateJournal() -- unit test method
|
|
*
|
|
* This function continues the previous two methods of testing by asserting that the previous update event created
|
|
* a journal record. We're only testing that the journal record exists, and through the query itself, validates
|
|
* the back-linking to the audit record via the eventGUID and the auditGUID.
|
|
*
|
|
* Once we've confirmed that the journal record was successfully created, then we'll store the journal token and
|
|
* the journal record for the final method/test: restoring the record to it's previous state.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 01-04-19 mks DB-78: original coding
|
|
*
|
|
*/
|
|
public function testUpdateJournal()
|
|
{
|
|
// validate that the carry-over data exists
|
|
$this->assertTrue(validateGUID(static::$eventRecordToken), (basename(__FILE__) . COLON . __LINE__) . ERROR_INVALID_GUID . static::$eventRecordToken);
|
|
$this->assertTrue(validateGUID(static::$testRecordToken), (basename(__FILE__) . COLON . __LINE__) . ERROR_INVALID_GUID . static::$testRecordToken);
|
|
$this->assertTrue(is_array(static::$originalTestRecord), (basename(__FILE__) . COLON . __LINE__) . ERROR_UT_LOST_VARIABLE . 'originalTestRecord');
|
|
$this->assertTrue(validateGUID(static::$auditRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$auditRecordToken);
|
|
$this->assertTrue(is_array(static::$auditRecord), (basename(__FILE__) . COLON . __LINE__) . ERROR_UT_LOST_VARIABLE . 'auditRecord');
|
|
|
|
// fetch the journal record based on the event guid and the audit guid
|
|
$query = [
|
|
JOURNAL_AUD_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$auditRecordToken ]]],
|
|
DB_EVENT_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventRecordToken]]],
|
|
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
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->adminOutClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE]));
|
|
static::$journalRecord = $response[PAYLOAD_RESULTS][PAYLOAD_QUERY][0];
|
|
$this->assertTrue(is_array(static::$journalRecord), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_GENERIC_FAIL . 'failed to fetch journal record');
|
|
}
|
|
|
|
|
|
/**
|
|
* testUpdateJournalRecovery() -- unit test method
|
|
*
|
|
* This unit test will invoke the audit/journal-recovery event to restore the previously-updated record back to
|
|
* it's original state. In the previous update, we changed the string to "jayne" - this test will invoke the audit
|
|
* restore event and then validate that the update was reversed.
|
|
*
|
|
* Assertions:
|
|
* 1-6: static data persists
|
|
* 7: Audit-restore event completed successfully (via the broker event request)
|
|
* 8: That we were able to fetch the updated record
|
|
* 9: That the test-string in the original record matches the updated record
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 01-07-19 mks DB-79: original coding
|
|
*
|
|
*/
|
|
public function testUpdateJournalRecovery()
|
|
{
|
|
// validate that the carry-over data exists
|
|
$this->assertTrue(validateGUID(static::$eventRecordToken), (basename(__FILE__) . COLON . __LINE__) . ERROR_INVALID_GUID . static::$eventRecordToken);
|
|
$this->assertTrue(validateGUID(static::$testRecordToken), (basename(__FILE__) . COLON . __LINE__) . ERROR_INVALID_GUID . static::$testRecordToken);
|
|
$this->assertTrue(is_array(static::$originalTestRecord), (basename(__FILE__) . COLON . __LINE__) . ERROR_UT_LOST_VARIABLE . 'originalTestRecord');
|
|
$this->assertTrue(validateGUID(static::$auditRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$auditRecordToken);
|
|
$this->assertTrue(is_array(static::$auditRecord), (basename(__FILE__) . COLON . __LINE__) . ERROR_UT_LOST_VARIABLE . 'auditRecord');
|
|
$this->assertTrue(is_array(static::$journalRecord), (basename(__FILE__) . COLON . __LINE__) . ERROR_UT_LOST_VARIABLE . 'journalRecord');
|
|
|
|
// build the recovery query to restore the original record
|
|
$query = [ STRING_KEY => static::$auditRecordToken ];
|
|
$meta = static::$adminMeta;
|
|
$meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT;
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_AUDIT_RESTORE,
|
|
BROKER_DATA => $query,
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->adminOutClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_AUDIT_RESTORE, $response[PAYLOAD_STATE]));
|
|
// if we're still executing, that the record was "restored" --- attempt to pull the record
|
|
$query = [ DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [static::$testRecordToken ]]]];
|
|
$meta = static::$meta;
|
|
$meta[META_DONUT_FILTER] = 1;
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [
|
|
STRING_QUERY_DATA => $query
|
|
],
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->readBrokerClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertEquals(STATE_SUCCESS, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . sprintf(ERROR_UT_VALS_NOT_EQUAL, STATE_SUCCESS, $response[PAYLOAD_STATE]));
|
|
// compare the string field to the original record - they should be the same, or at least not jayne
|
|
$originalString = static::$originalTestRecord[TEST_FIELD_TEST_STRING . COLLECTION_MONGO_TEST_EXT];
|
|
$updatedString = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0][TEST_FIELD_TEST_STRING . COLLECTION_MONGO_TEST_EXT];
|
|
$this->assertEquals($originalString, $updatedString, (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, $originalString, $updatedString));
|
|
}
|
|
|
|
|
|
/**
|
|
* 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:
|
|
* ========
|
|
* 08-01-17 mks CORE-486: original coding
|
|
* 03-28-19 mks DB-116: refactored selection query to limit the update to affecting a max of 10 records
|
|
* 06-18-19 mks DB-122: support for META_LIMIT and mongoDB update scope
|
|
*
|
|
*/
|
|
public function testUpdateMany()
|
|
{
|
|
$recordCount = 5;
|
|
$testRecord = null;
|
|
$this->assertTrue(is_object(static::$widget), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_WIDGET_404);
|
|
|
|
// plan is to update the records that have an active status
|
|
$query = [ CM_TST_FIELD_TEST_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]]];
|
|
|
|
// 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 ];
|
|
|
|
// build the broker-event payload
|
|
$payload = [
|
|
STRING_QUERY_DATA => $query,
|
|
STRING_UPDATE_DATA => $update
|
|
];
|
|
$meta = static::$meta;
|
|
$meta[META_LIMIT] = $recordCount; // namaste will limit the delete to $recordCount records
|
|
|
|
// create the query/broker-event payload
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_UPDATE,
|
|
BROKER_DATA => $payload,
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
|
|
// submit the request and unpack the results
|
|
$eventPayload = gzcompress(json_encode($request));
|
|
$response = $this->writeBrokerClient->call($eventPayload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
|
|
// verify that the update was successful
|
|
// json_decode(gzuncompress(gasCache::get('')), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_EXPECTING_TRUE . PAYLOAD_STATUS);
|
|
$this->assertNotNull($response[PAYLOAD_RESULTS], (__FILE__ . COLON . __LINE__) . ERROR_UT_EMPTY_RESULTS);
|
|
// grab the cache-key and fetch the data
|
|
$cData = json_decode(gzuncompress(gasCache::get($response[PAYLOAD_RESULTS][0])), true);
|
|
unset($cData[STRING_CHECKSUM]);
|
|
$this->assertEquals(count($cData), $recordCount, basename(__METHOD__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, count($cData), $recordCount));
|
|
$rr = mt_rand(0, $recordCount); // rr = random record
|
|
$this->assertEquals($jayne, $cData[$rr][CM_TST_FIELD_TEST_STRING], basename(__METHOD__) . AT . __LINE__ . COLON . sprintf(ERROR_UT_STRING_MISMATCH, 'jayne', $cData[$rr][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:
|
|
* ========
|
|
* 09-11-17 mks CORE-558: original coding
|
|
*
|
|
*/
|
|
public function testNegativeUpdateOne()
|
|
{
|
|
$testRecord = null;
|
|
$this->assertTrue(is_object(static::$widget), (basename(__METHOD__) . AT . __LINE__ . COLON) . ERROR_UT_WIDGET_404);
|
|
|
|
// we lost the cached record in insertJournalRecovery() - so fetch a new record
|
|
$meta = static::$meta;
|
|
$meta[META_LIMIT] = 1;
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [ STRING_QUERY_DATA => [] ],
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
// submit the request and unpack the results
|
|
$eventPayload = gzcompress(json_encode($request));
|
|
$response = $this->readBrokerClient->call($eventPayload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
static::$cKey = $response[PAYLOAD_RESULTS][PAYLOAD_QUERY][0];
|
|
// get the cached record and extract the guid and the text string (query/replace values)
|
|
$testRecord = gasCache::get(static::$cKey);
|
|
$this->assertNotNull($testRecord, (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
$testRecord = json_decode(gzuncompress($testRecord), true);
|
|
$testRecord = $testRecord[0];
|
|
$guid = $testRecord[CM_TST_TOKEN]; // this is the raw guid
|
|
$this->assertTrue(validateGUID($guid), (basename(__METHOD__) . AT . __LINE__ . COLON) . ERROR_INVALID_GUID . $guid);
|
|
$this->assertNotEmpty($guid, (basename(__METHOD__) . AT . __LINE__ . COLON) . ERROR_UT_FIELD_404 . CM_TST_TOKEN);
|
|
|
|
// build a simple update query
|
|
$query = [
|
|
CM_TST_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [$guid] ] ]
|
|
];
|
|
|
|
|
|
// 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 ];
|
|
|
|
// meta data should reflect a client request as unit-test, as a client, will bypass the protected field check
|
|
$meta = static::$meta;
|
|
$meta[META_CLIENT] = CLIENT_CLIENT;
|
|
|
|
// build the broker-update-event payload
|
|
$payload = [
|
|
STRING_QUERY_DATA => $query,
|
|
STRING_UPDATE_DATA => $update
|
|
];
|
|
|
|
// create the query/broker-event payload
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_UPDATE,
|
|
BROKER_DATA => $payload,
|
|
BROKER_META_DATA => static::$meta
|
|
];
|
|
|
|
// submit the request and process the result payload
|
|
$eventPayload = gzcompress(json_encode($request));
|
|
$response = $this->writeBrokerClient->call($eventPayload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertFalse($response[PAYLOAD_STATUS], (basename(__METHOD__) . AT . __LINE__ . COLON) . ERROR_UT_EXPECTING_FALSE . BROKER_REQUEST_UPDATE);
|
|
$this->assertEquals(STATE_VALIDATION_ERROR, $response[PAYLOAD_STATE], (basename(__METHOD__) . AT . __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:
|
|
* ------
|
|
* Created JIRA case: CORE-497 to delete cached records
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 08-01-17 mks CORE-486: original coding
|
|
* 08-07-17 mks CORE-497: update for the removal of deleted records from cache
|
|
* 01-08-19 mks DB-80: saving original record data, and the delete event guid, to static members
|
|
* for audit/journal testing later
|
|
*
|
|
*/
|
|
public function testDeleteOneRecord()
|
|
{
|
|
$testRecord = null;
|
|
|
|
// we've deleted the test record so, fetch any record with an active status
|
|
static::$meta[META_LIMIT] = 1;
|
|
$query = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [
|
|
STRING_QUERY_DATA => []
|
|
],
|
|
BROKER_META_DATA => static::$meta
|
|
];
|
|
$payload = gzcompress(json_encode($query));
|
|
$response = $this->readBrokerClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE]));
|
|
static::$cKey = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0];
|
|
|
|
// fetch the cached record so we can get the guid
|
|
$record = gasCache::get(static::$cKey);
|
|
$this->assertNotNull($record, (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
$record = json_decode(gzuncompress($record), true);
|
|
$record = $record[0];
|
|
$guid = $record[CM_TST_TOKEN];
|
|
// validate the guid
|
|
$this->assertTrue(validateGUID($guid), (__FILE__ . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . $guid);
|
|
|
|
// save the original record for testing audit/journaling in following test methods
|
|
static::$testRecordToken = $guid;
|
|
static::$originalTestRecord = $record;
|
|
|
|
// validate that the current record has an ACTIVE (e.g.: not-deleted) status
|
|
$this->assertEquals(STATUS_ACTIVE, $record[CM_TST_FIELD_TEST_STATUS], (__FILE__ . COLON . __LINE__) . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_STATUS));
|
|
|
|
// delete the record we created a couple methods ago referenced by the static $cKey value
|
|
$query = [ CM_TST_TOKEN => [ OPERAND_NULL => [OPERATOR_EQ => [$guid]]]];
|
|
$request = [ STRING_QUERY_DATA => $query];
|
|
|
|
// save the event guid for audit/journal record look-ups later
|
|
$eventGUID = guid();
|
|
$this->assertTrue(validateGUID($eventGUID), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . $eventGUID);
|
|
$meta = static::$meta;
|
|
$meta[META_EVENT_GUID] = $eventGUID;
|
|
static::$eventRecordToken = $eventGUID;
|
|
|
|
// create the query/broker-event payload
|
|
$payload = [
|
|
BROKER_REQUEST => BROKER_REQUEST_DELETE,
|
|
BROKER_DATA => $request,
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
|
|
// submit the request and unpack the results
|
|
$eventPayload = gzcompress(json_encode($payload));
|
|
$response = $this->writeBrokerClient->call($eventPayload);
|
|
$response = json_decode(gzuncompress($response), 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
|
|
$record = gasCache::get(static::$cKey);
|
|
$this->assertNull($record, (__FILE__ . COLON . __LINE__) . COLON . ERROR_UT_CACHE_FETCH_FAIL . COLON . $guid);
|
|
}
|
|
|
|
|
|
/**
|
|
* testDeleteAudit() -- unit test method
|
|
*
|
|
* This unit test confirms that the record, deleted in the previous test-method, was successfully deleted and that
|
|
* an audit record was created for that event.
|
|
*
|
|
* Assertions:
|
|
* -----------
|
|
* 1-3: saved variables from the previous method are accessible and valid
|
|
* 4: We successfully fetched the audit record from admin service (implying that the audit token was created)
|
|
* 5: We pull a valid audit-record token from the data payload
|
|
* 6: We pull the audit record and store it (confirming array format)
|
|
* 7: We successfully fetch the original record
|
|
* 8: That the fetch event resulted in a status of SUCCESS (soft delete) or NOT_FOUND (hard delete)
|
|
* 9: If the delete was soft, that the status of the record was changed to DELETED
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 01-09-19 mks DB-80: original coding
|
|
*
|
|
*/
|
|
public function testDeleteAudit()
|
|
{
|
|
sleep(1); // ensure we've completed writing the audit(delete) event record
|
|
$ext = '_aud';
|
|
|
|
// ensure we've got the necessary saved data
|
|
$this->assertTrue(validateGUID(static::$eventRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_LOST_VARIABLE . 'eventGUID');
|
|
$this->assertTrue(validateGUID(static::$testRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_LOST_VARIABLE . 'testRecordToken');
|
|
$this->assertTrue(is_array(static::$originalTestRecord), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_LOST_VARIABLE . 'originalTestRecord');
|
|
|
|
// validate that we have an audit record for the delete operation that just occurred
|
|
$adminMeta = static::$adminMeta;
|
|
$adminMeta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT;
|
|
$adminMeta[META_DONUT_FILTER] = 1;
|
|
$query = [
|
|
AUDIT_RECORD_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$testRecordToken ]]],
|
|
DB_EVENT_GUID => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$eventRecordToken ]]],
|
|
OPERAND_AND => null
|
|
];
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH,
|
|
BROKER_DATA => [ STRING_QUERY_DATA => $query ],
|
|
BROKER_META_DATA => $adminMeta
|
|
];
|
|
$response = $this->adminOutClient->call(gzcompress(json_encode($request)));
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE]));
|
|
// grab and save the audit record token, and the audit record, for the next method...
|
|
static::$auditRecordToken = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0][(DB_TOKEN . $ext)];
|
|
static::$auditRecord = $response[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0];
|
|
$this->assertNotNull(static::$auditRecord, basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_NULL_VALUE . STRING_GUID_KEY);
|
|
$this->assertTrue(validateGUID(static::$auditRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$auditRecordToken);
|
|
$this->assertTrue(is_array(static::$auditRecord), (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_FIELD_VALUE, 'auditRecord'));
|
|
|
|
// pull the original record and let's confirm that it's deleted or in a deleted state
|
|
$meta = static::$meta;
|
|
$meta[META_DONUT_FILTER] = 1;
|
|
$query = [
|
|
DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$testRecordToken]]],
|
|
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_DELETED ]]],
|
|
OPERAND_AND => null
|
|
];
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [ STRING_QUERY_DATA => $query ],
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
$response = $this->readBrokerClient->call(gzcompress(json_encode($request)));
|
|
$results = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($results[PAYLOAD_STATUS], (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $results[PAYLOAD_STATE]));
|
|
$state = $results[PAYLOAD_STATE];
|
|
$vString = STATE_SUCCESS . ' or ' . STATE_NOT_FOUND;
|
|
$this->assertTrue(($state == STATE_SUCCESS or $state == STATE_NOT_FOUND), (basename(__FILE__) . COLON . __LINE__) . sprintf(ERROR_UT_VALS_NOT_EQUAL, $state, $vString));
|
|
if ($state == STATE_SUCCESS) {
|
|
$newStatus = $results[PAYLOAD_RESULTS][STRING_QUERY_RESULTS][0][(DB_STATUS . COLLECTION_MONGO_TEST_EXT)];
|
|
$this->assertEquals(STATUS_DELETED, $newStatus, (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_VALS_NOT_EQUAL, STATUS_DELETED, $newStatus));
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* testDeleteJournalRecovery() -- unit test method
|
|
*
|
|
* This method tests that a journal record was created off the audit event from the delete-record event posted
|
|
* a couple of methods ago. We make the following assertions in this test:
|
|
*
|
|
* 1-5: That all stored variables are in the correct format and available through class statics
|
|
* 6: That we're able to fetch a journal record (implicitly stating that the journal record was created)
|
|
* 7: That we're able to successfully post a audit-recovery event and that the event successfully completes
|
|
* 8: That deleted record has been recovered back to an active state
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 01-09-19 mks DB-80: original coding
|
|
*
|
|
*/
|
|
public function testDeleteJournalRecovery()
|
|
{
|
|
$this->assertTrue(validateGUID(static::$eventRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_LOST_VARIABLE . 'eventGUID');
|
|
$this->assertTrue(validateGUID(static::$testRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_LOST_VARIABLE . 'testRecordToken');
|
|
$this->assertTrue(is_array(static::$originalTestRecord), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_UT_LOST_VARIABLE . 'originalTestRecord');
|
|
$this->assertTrue(validateGUID(static::$auditRecordToken), (basename(__FILE__) . COLON . __LINE__) . COLON . ERROR_INVALID_GUID . static::$auditRecordToken);
|
|
$this->assertTrue(is_array(static::$auditRecord), (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_FIELD_VALUE, 'auditRecord'));
|
|
|
|
// build the request to fetch the journal record for the delete event
|
|
$meta = static::$adminMeta;
|
|
$meta[META_DONUT_FILTER] = 1;
|
|
$meta[META_TEMPLATE] = TEMPLATE_CLASS_JOURNAL;
|
|
$query = [ JOURNAL_AUD_TOK => [ OPERAND_NULL => [ OPERATOR_EQ => [ static::$auditRecordToken ]]]];
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_REMOTE_FETCH,
|
|
BROKER_DATA => [ STRING_QUERY_DATA => $query ],
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
$response = $this->adminOutClient->call(gzcompress(json_encode($request)));
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], (basename(__FILE__) . COLON . __LINE__) . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_REMOTE_FETCH, $response[PAYLOAD_STATE]));
|
|
|
|
// now that we've confirmed that the journal record exists, invoke the recovery event to restore the
|
|
// original record back to it's non-deleted state
|
|
$query = [ STRING_KEY => static::$auditRecordToken ];
|
|
$meta = static::$adminMeta;
|
|
$meta[META_TEMPLATE] = TEMPLATE_CLASS_AUDIT;
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_AUDIT_RESTORE,
|
|
BROKER_DATA => $query,
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->adminOutClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_AUDIT_RESTORE, $response[PAYLOAD_STATE]));
|
|
// if we're still executing, that the record was "restored" --- attempt to pull the record after a
|
|
// slightly-respectful delay to give time for the update to propagate...
|
|
sleep(1);
|
|
|
|
$query = [ DB_TOKEN => [ OPERAND_NULL => [ OPERATOR_EQ => [static::$testRecordToken ]]]];
|
|
$meta = static::$meta;
|
|
$meta[META_DONUT_FILTER] = 1;
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [
|
|
STRING_QUERY_DATA => $query
|
|
],
|
|
BROKER_META_DATA => $meta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->readBrokerClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertEquals(STATE_SUCCESS, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . sprintf(ERROR_UT_VALS_NOT_EQUAL, STATE_SUCCESS, $response[PAYLOAD_STATE]));
|
|
}
|
|
|
|
|
|
/**
|
|
* grabRandomTestRecord() -- private method for code reduction
|
|
*
|
|
* this is a private function that fetches a random record from the test collection. The function is invoked in
|
|
* the two sub-collection methods immediately following this one.
|
|
*
|
|
* There is an optional input parameter to this method:
|
|
*
|
|
* $_limit -- integer value, that defaults to 1, allowing you to specify the number of records to be returned,
|
|
* up to the maximum allowable.
|
|
*
|
|
* the function build a read-broker query, submits it, unpacks the result, and then validates/tests the return
|
|
* status. If the request was successful, we'll return the response payload otherwise execution of the testing
|
|
* will halt.
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* @param int $_limit -- optional parameter allowing user to specify number of records to be returned
|
|
* @return array
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 09-07-17 mks CORE-494: original coding
|
|
* 03-28-19 mks DB-116: added $_limit optional parameter
|
|
*
|
|
*/
|
|
private function grabRandomTestRecord(int $_limit = 1): array
|
|
{
|
|
$this->assertTrue($this->readBrokerClient->status, __METHOD__ . __LINE__ . ERROR_BROKER_QUEUE_DECLARE . BROKER_QUEUE_R);
|
|
$this->assertTrue($this->writeBrokerClient->status, __METHOD__ . __LINE__ . ERROR_BROKER_QUEUE_DECLARE . BROKER_QUEUE_W);
|
|
|
|
// validate the amount passed, if any, via the $_limit parameter
|
|
$_limit = (!is_numeric($_limit)) ? 1 : intval($_limit);
|
|
if ($_limit > gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_QUERY_RECORD_LIMIT])
|
|
$_limit = gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_QUERY_RECORD_LIMIT];
|
|
|
|
// first thing we want to do is pull a random record in active status...
|
|
$query = [
|
|
CM_TST_FIELD_TEST_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
|
CM_TST_FIELD_TEST_INT => [ OPERAND_NULL => [ OPERATOR_EQ => [ intval(mt_rand(0,20))]]],
|
|
OPERAND_AND => null
|
|
];
|
|
|
|
// limit the return data count to 1 record (we'll test for this...)
|
|
static::$meta[META_LIMIT] = $_limit;
|
|
|
|
// set up the broker request
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_FETCH,
|
|
BROKER_DATA => [STRING_QUERY_DATA => $query ],
|
|
BROKER_META_DATA => static::$meta
|
|
];
|
|
|
|
// build the request payload and submit the request to the read broker
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->readBrokerClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
unset(static::$meta[META_LIMIT]);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], (__FILE__ . COLON) . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_FETCH, $response[PAYLOAD_STATE]));
|
|
return($response);
|
|
}
|
|
|
|
|
|
/**
|
|
* testSubCollectionInserts() -- unit test method
|
|
*
|
|
* This method evaluates the wBroker sub-Collection insert event by adding a new subC record to a randomly
|
|
* selected test record.
|
|
*
|
|
* NOTE THAT THIS TEST WILL ONLY WORK ON A CACHE-SUPPORTED CLASS!
|
|
*
|
|
* Criteria for a successful test:
|
|
* -------------------------------
|
|
* 1. The readBroker class object is still available
|
|
* 2. The writeBroker class object is still available
|
|
* 3. We can fetch a random, active, record
|
|
* 4. That we can fetch the same record from cache
|
|
* 5. That we can successfully publish a subC insert event
|
|
* 6. That we can fetch the updated (reflecting the db status) record from cache
|
|
* 7. That the subC count incremented by 1 record
|
|
* 8. That the inserted record exists
|
|
* 9. That all of the inserted record fields were set correctly
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 08-29-17 mks CORE-494: initial coding
|
|
* 09-06-17 mks CORE-556: injecting guids into sub-collection records on create
|
|
* 09-07-17 mks CORE-494: broke fetch-random record out to private method and invoked
|
|
*
|
|
*/
|
|
public function testSubCollectionInserts()
|
|
{
|
|
$response = $this->grabRandomTestRecord();
|
|
sleep(1);
|
|
$ck = $response[PAYLOAD_RESULTS][PAYLOAD_QUERY][0];
|
|
$this->assertNotNull($ck,basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_UT_LOST_VARIABLE . STRING_CACHE_CKEY);
|
|
$this->assertTrue(gasCache::validateCacheKey($ck), (__FILE__ . COLON) . __LINE__ . ERROR_INVALID_GUID . $ck);
|
|
// we have the cache key for the record - fetch the record data
|
|
$data = gasCache::get($ck);
|
|
$data = json_decode(gzuncompress($data), true);
|
|
$data = $data[0];
|
|
$this->assertTrue(is_array($data), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
if (isset($data[CM_TST_FIELD_TEST_SUBC]) and count($data[CM_TST_FIELD_TEST_SUBC])) {
|
|
$numRecsOld = count($data[CM_TST_FIELD_TEST_SUBC]);
|
|
$this->assertGreaterThan(0, $numRecsOld, __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, 0, $numRecsOld, 'number of subC recs'));
|
|
} else {
|
|
$numRecsOld = 0;
|
|
}
|
|
$key = $data[CM_TST_TOKEN];
|
|
$this->assertTrue(validateGUID($key), __FILE__ . COLON . __LINE__ . ERROR_INVALID_GUID . $key);
|
|
|
|
// create and add a new subC record
|
|
$newGUID = guid();
|
|
$intVal = 33;
|
|
$doubleVal = 33.33;
|
|
$boolVal = false;
|
|
$newSubCRecord = [
|
|
[
|
|
CM_TST_FIELD_TEST_INT => $intVal,
|
|
CM_TST_FIELD_TEST_DOUBLE => $doubleVal,
|
|
CM_TST_FIELD_TEST_STRING => $newGUID,
|
|
CM_TST_FIELD_TEST_NIF => STRING_UT_RECORD_INSERT,
|
|
CM_TST_FIELD_TEST_BOOL => $boolVal
|
|
]
|
|
];
|
|
$field = CM_TST_FIELD_TEST_SUBC;
|
|
$brokerData = [
|
|
STRING_GUID_KEY => $key,
|
|
STRING_SUBC_FIELD => $field,
|
|
STRING_DATA => $newSubCRecord
|
|
];
|
|
|
|
// create the query/broker-event payload
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_SUBC_CREATE,
|
|
BROKER_DATA => $brokerData,
|
|
BROKER_META_DATA => static::$meta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->writeBrokerClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
sleep(1); // give up some time for the cache record to be updated
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . AT . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_SUBC_CREATE, $response[PAYLOAD_STATE]));
|
|
$newCk = $response[PAYLOAD_RESULTS][0];
|
|
$this->assertTrue(gasCache::validateCacheKey($newCk), __FILE__ . AT . __LINE__ . COLON . ERROR_INVALID_GUID . $newCk);
|
|
|
|
// using the "new key", fetch the record from cache and check the count of the sub-collection
|
|
$newData = gasCache::get($newCk);
|
|
$newData = json_decode(gzuncompress($newData), true);
|
|
$this->assertTrue(is_array($newData), __FILE__ . AT . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
$newData = $newData[0];
|
|
$numRecsNew = count($newData[CM_TST_FIELD_TEST_SUBC]);
|
|
$this->assertEquals(($numRecsOld + 1), $numRecsNew, __FILE__ . AT . __LINE__ . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, $numRecsNew, ($numRecsOld + 1), CM_TST_FIELD_TEST_SUBC));
|
|
|
|
// get new subC record and validate the added fields and the injected guid
|
|
$subCRecord = $newData[CM_TST_FIELD_TEST_SUBC][$numRecsOld];
|
|
$this->assertEquals($subCRecord[CM_TST_FIELD_TEST_INT], $intVal, __FILE__ . AT . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_INT));
|
|
$this->assertEquals($subCRecord[CM_TST_FIELD_TEST_DOUBLE], $doubleVal, __FILE__ . AT . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_DOUBLE));
|
|
$this->assertEquals($subCRecord[CM_TST_FIELD_TEST_STRING], $newGUID, __FILE__ . AT . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_STRING));
|
|
$this->assertEquals($subCRecord[CM_TST_FIELD_TEST_BOOL], $boolVal, __FILE__ . AT . __LINE__ . COLON . sprintf(ERROR_UT_SAME_FIELD_COMPARE_FAIL, CM_TST_FIELD_TEST_BOOL));
|
|
$this->assertNotEmpty($subCRecord[CM_TST_TOKEN], __FILE__ . COLON . __LINE__ . AT . ERROR_DATA_KEY_404 . CM_TST_TOKEN);
|
|
$this->assertTrue(validateGUID($subCRecord[CM_TST_TOKEN]), __FILE__ . AT . __LINE__ . COLON . ERROR_INVALID_GUID . $subCRecord[CM_TST_TOKEN]);
|
|
}
|
|
|
|
|
|
/**
|
|
* testNegativeSubCollectionInsert() -- unit test method
|
|
*
|
|
* This is a negative unit test in that we're intentionally submitting an event request we expect to fail. For this
|
|
* test, we're looking at exceeding the maximum number of records allowed for a transaction.
|
|
*
|
|
* We'll pull a random record to get the guid values for the request - and then we'll also pull the max number
|
|
* of allowing records-per-transaction value from the XML configuration file.
|
|
*
|
|
* Next, we'll build a data payload which exceeds the count of allowable records and then submit the event request.
|
|
*
|
|
* Our tests will validate that the request was rejected with the appropriate error state and status.
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 09-11-17 mks CORE-501: original coding
|
|
*
|
|
*/
|
|
public function testNegativeSubCollectionInsert()
|
|
{
|
|
$records = null;
|
|
$response = $this->grabRandomTestRecord();
|
|
|
|
$ck = $response[PAYLOAD_RESULTS][PAYLOAD_QUERY][0];
|
|
$this->assertTrue(gasCache::validateCacheKey($ck), (__FILE__ . COLON) . __LINE__ . ERROR_INVALID_GUID . $ck);
|
|
// we have the cache key for the record - fetch the record data
|
|
$data = gasCache::get($ck);
|
|
$data = json_decode(gzuncompress($data), true);
|
|
$data = $data[0];
|
|
$this->assertTrue(is_array($data), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
$key = $data[CM_TST_TOKEN];
|
|
$this->assertTrue(validateGUID($key), __FILE__ . COLON . __LINE__ . ERROR_INVALID_GUID . $key);
|
|
|
|
$qrl = intval(gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_QUERY_RECORD_LIMIT]);
|
|
$recCount = 1 + $qrl;
|
|
|
|
// create and add a new subC record
|
|
$newGUID = guid();
|
|
$intVal = 33;
|
|
$doubleVal = 33.33;
|
|
$boolVal = false;
|
|
$newSubCRecord = [
|
|
[
|
|
CM_TST_FIELD_TEST_INT => $intVal,
|
|
CM_TST_FIELD_TEST_DOUBLE => $doubleVal,
|
|
CM_TST_FIELD_TEST_STRING => $newGUID,
|
|
CM_TST_FIELD_TEST_NIF => STRING_UT_RECORD_INSERT,
|
|
CM_TST_FIELD_TEST_BOOL => $boolVal
|
|
]
|
|
];
|
|
for ($index = 0; $index < $recCount; $index++) $records[] = $newSubCRecord;
|
|
$field = CM_TST_FIELD_TEST_SUBC;
|
|
$brokerData = [
|
|
STRING_GUID_KEY => $key,
|
|
STRING_SUBC_FIELD => $field,
|
|
STRING_DATA => $records
|
|
];
|
|
// create the query/broker-event payload
|
|
$request = [
|
|
BROKER_REQUEST => BROKER_REQUEST_SUBC_CREATE,
|
|
BROKER_DATA => $brokerData,
|
|
BROKER_META_DATA => static::$meta
|
|
];
|
|
$payload = gzcompress(json_encode($request));
|
|
$response = $this->writeBrokerClient->call($payload);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
|
|
// test that the event was rejected with the expected state value
|
|
$this->assertFalse($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_EXPECTING_FALSE . BROKER_REQUEST_CREATE);
|
|
$this->assertEquals(STATE_DATA_ERROR, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_STRING_MISMATCH, STATE_DATA_ERROR, $response[PAYLOAD_STATE]));
|
|
}
|
|
|
|
|
|
/**
|
|
* testSubCollectionDeletes() -- unit test method
|
|
*
|
|
* this unit test evaluates the BROKER_REQUEST_SUBC_DELETE event in the write-broker by fetching a random record
|
|
* from the test collection and selecting a sub-collection record (with a key) for deletion.
|
|
*
|
|
* The payload request is build and submitted to namaste for processing after which we evaluate the success or
|
|
* fail for the event.
|
|
*
|
|
* next, because this is a cached-class, we're going to pull the updated record from cache using the reference to
|
|
* the cache key returned in the broker-payload and we're going to test that the count of sub-collection records
|
|
* was de-incremented by one and then we're going to spin through every sub-collection record with a key and compare
|
|
* the key value.
|
|
*
|
|
* Finally, we're going to re-submit the request again to test that we got a successful event, but we returned a
|
|
* 404 (STATE_NOT_FOUND) message.
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 09-07-17 mks CORE-494: original coding
|
|
*
|
|
*/
|
|
public function testSubCollectionDeletes()
|
|
{
|
|
$subCKey = '';
|
|
$found = false;
|
|
$data = null;
|
|
while (!$found) {
|
|
$response = $this->grabRandomTestRecord();
|
|
$ck = $response[PAYLOAD_RESULTS][PAYLOAD_QUERY][0];
|
|
$this->assertTrue(gasCache::validateCacheKey($ck), (__FILE__ . COLON) . __LINE__ . ERROR_INVALID_GUID . $ck);
|
|
// we have the cache key for the record - fetch the record data
|
|
$data = gasCache::get($ck);
|
|
$data = json_decode(gzuncompress($data), true);
|
|
$data = $data[0];
|
|
$this->assertTrue(is_array($data), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
$found = (isset($data[CM_TST_FIELD_TEST_SUBC]) and !empty($data[CM_TST_FIELD_TEST_SUBC])) ? true : false;
|
|
}
|
|
$numRecsOld = count($data[CM_TST_FIELD_TEST_SUBC]);
|
|
$this->assertGreaterThan(0, $numRecsOld, __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_INTEGER_MISMATCH, 0, $numRecsOld, 'number of subC recs'));
|
|
$key = $data[CM_TST_TOKEN];
|
|
$this->assertTrue(validateGUID($key), __FILE__ . COLON . __LINE__ . ERROR_INVALID_GUID . $key);
|
|
$subCArray = $data[CM_TST_FIELD_TEST_SUBC];
|
|
$found = false;
|
|
$index = 0;
|
|
while (!$found and $index < $numRecsOld) {
|
|
if (array_key_exists(CM_TST_TOKEN, $subCArray[$index])) {
|
|
$found = true;
|
|
$subCKey = $subCArray[$index][CM_TST_TOKEN];
|
|
} else {
|
|
$index++;
|
|
}
|
|
}
|
|
$this->assertTrue($found, __FILE__ . COLON . __LINE__ . COLON . ERROR_SUBC_RECORD_NO_KEY);
|
|
// build and submit the request to delete the selected sub-collection record
|
|
$payload = [
|
|
BROKER_REQUEST => BROKER_REQUEST_SUBC_DELETE,
|
|
BROKER_DATA => [
|
|
STRING_GUID_KEY => $key,
|
|
STRING_SUBC_FIELD => CM_TST_FIELD_TEST_SUBC,
|
|
STRING_SUBC_GUID => $subCKey
|
|
],
|
|
BROKER_META_DATA => static::$meta
|
|
];
|
|
$request = gzcompress(json_encode($payload));
|
|
$response = $this->writeBrokerClient->call($request);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
|
|
// check that we successfully removed the sub-collection record
|
|
|
|
// first, check that the request was successfully processed
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_SUBC_DELETE, $response[PAYLOAD_STATE]));
|
|
$this->assertEquals(STATE_SUCCESS, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_SUBC_DELETE, $response[PAYLOAD_STATE]));
|
|
|
|
// fetch the updated record from cache
|
|
$newData = gasCache::get($response[PAYLOAD_RESULTS][0]);
|
|
$newData = json_decode(gzuncompress($newData), true);
|
|
$newData = $newData[0];
|
|
$this->assertTrue(is_array($newData), __FILE__ . COLON . __LINE__ . COLON . ERROR_UT_CACHE_FETCH_FAIL);
|
|
$numRecsNew = !isset($newData[CM_TST_FIELD_TEST_SUBC]) ? 0 : count($newData[CM_TST_FIELD_TEST_SUBC]);
|
|
if ($numRecsNew != 0) {
|
|
$this->assertEquals(($numRecsOld - 1), $numRecsNew, __FILE__ . COLON . __LINE__ . sprintf(ERROR_UT_INTEGER_MISMATCH, $numRecsNew, ($numRecsOld + 1), CM_TST_FIELD_TEST_SUBC));
|
|
// search every sub-collection record with a key and compare it to the key in the delete request
|
|
foreach ($newData[CM_TST_FIELD_TEST_SUBC] as $subRecord) {
|
|
if (array_key_exists(CM_TST_TOKEN, $subRecord)) {
|
|
$this->assertNotEquals($subRecord[CM_TST_TOKEN], $subCKey, __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_SUBC_RECORD_KEY_FOUND, $subCKey));
|
|
}
|
|
}
|
|
}
|
|
// test the 404 return payload by re-submitting the request
|
|
$request = gzcompress(json_encode($payload));
|
|
$response = $this->writeBrokerClient->call($request);
|
|
$response = json_decode(gzuncompress($response), true);
|
|
$this->assertTrue($response[PAYLOAD_STATUS], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_SUBC_DELETE, $response[PAYLOAD_STATE]));
|
|
$this->assertEquals(STATE_NOT_FOUND, $response[PAYLOAD_STATE], __FILE__ . COLON . __LINE__ . COLON . sprintf(ERROR_UT_BROKER_EVENT_FAIL, BROKER_REQUEST_SUBC_DELETE, $response[PAYLOAD_STATE]));
|
|
}
|
|
}
|