includes/tests/qcubed-unit/BasicOrmTest.php
<?php
/**
*
* @package Tests
*/
if(!class_exists('Person')){
require_once __INCLUDES__ .'/model/Person.class.php';
}
if(!class_exists('Project')){
require_once __INCLUDES__ .'/model/Project.class.php';
}
if(!class_exists('Login')){
require_once __INCLUDES__ .'/model/Login.class.php';
}
if(!class_exists('Milestone')){
require_once __INCLUDES__ .'/model/Milestone.class.php';
}
if(!class_exists('Address')){
require_once __INCLUDES__ .'/model/Address.class.php';
}
if(!class_exists('TwoKey')){
require_once __INCLUDES__ .'/model/TwoKey.class.php';
}
class BasicOrmTests extends QUnitTestCaseBase {
public function testSaveAndDelete() {
$objPerson1 = new Person();
$objPerson1->FirstName = "Test1";
$objPerson1->LastName = "Last1";
$objPerson1->Save();
$items = Person::QueryArray(
QQ::AndCondition(
QQ::Equal(QQN::Person()->FirstName, "Test1"),
QQ::Equal(QQN::Person()->LastName, "Last1")
)
);
$this->assertEquals(1, sizeof($items), "Saved the Person object");
$objPerson2 = $items[0];
$this->assertEquals("Test1", $objPerson2->FirstName, "The first name is correct");
$this->assertEquals("Last1", $objPerson2->LastName, "The last name is correct");
$objPerson2->Delete();
$items = Person::QueryArray(
QQ::AndCondition(
QQ::Equal(QQN::Person()->FirstName, "Test1"),
QQ::Equal(QQN::Person()->LastName, "Last1")
)
);
$this->assertEquals(0, sizeof($items), "Deleting the Person object");
}
public function testQueryArray() {
$someDate = new QDateTime();
$someDate->setDate(2006, 1, 1);
$objItems = Milestone::QueryArray(
QQ::GreaterThan(QQN::Milestone()->Project->StartDate, $someDate),
QQ::OrderBy(QQN::Milestone()->Project->Name)
);
$this->assertEquals(3, sizeof($objItems));
$this->assertEquals("Milestone F", $objItems[0]->Name);
$this->assertEquals("Blueman Industrial Site Architecture", $objItems[0]->Project->Name);
$this->assertEquals("Milestone D", $objItems[1]->Name);
$this->assertEquals("State College HR System", $objItems[1]->Project->Name);
$this->assertEquals("Milestone E", $objItems[2]->Name);
$this->assertEquals("State College HR System", $objItems[2]->Project->Name);
}
public function testQueryCount() {
$someDate = new QDateTime();
$someDate->setDate(2006, 1, 1);
$intItemCount = Milestone::QueryCount(
QQ::GreaterThan(QQN::Milestone()->Project->StartDate, $someDate),
// test for single QQClause object
// the subject of the https://github.com/qcubed/qcubed/issues/100 issue #100
QQ::Distinct()
);
$this->assertEquals(3, $intItemCount);
$intItemCount2 = Milestone::QueryCount(
QQ::GreaterThan(QQN::Milestone()->Project->StartDate, $someDate),
// test for an array of QQClause objects
QQ::Clause(
// The QQ::Distinct is used because of the https://github.com/qcubed/qcubed/issues/231 issue #231
QQ::Distinct()
, QQ::Distinct()
)
);
$this->assertEquals(3, $intItemCount2);
}
public function testOrderByCondition() {
$objItems = Person::QueryArray(
QQ::All(),
QQ::Clause(
QQ::OrderBy(
QQ::NotEqual(QQN::Person()->LastName, 'Smith'),
QQN::Person()->FirstName)
)
);
$this->assertEquals("Alex Smith", $objItems[0]->FirstName . " " . $objItems[0]->LastName);
$this->assertEquals("Jennifer Smith", $objItems[1]->FirstName . " " . $objItems[1]->LastName);
$this->assertEquals("Wendy Smith", $objItems[2]->FirstName . " " . $objItems[2]->LastName);
$this->assertEquals("Ben Robinson", $objItems[3]->FirstName . " " . $objItems[3]->LastName);
}
public function testGroupBy() {
$objItems = Project::QueryArray(
QQ::All(),
QQ::Clause(
QQ::GroupBy(QQN::Project()->Id),
QQ::Count(QQN::Project()->PersonAsTeamMember->PersonId, 'team_member_count'),
QQ::OrderBy(QQN::Project()->Id)
)
);
$this->assertEquals(4, sizeof($objItems), "4 projects found");
$this->assertEquals(5, $objItems[0]->GetVirtualAttribute('team_member_count'), "5 team members found for the first project");
$this->assertEquals(6, $objItems[1]->GetVirtualAttribute('team_member_count'), "6 team members found for the second project");
$this->assertEquals(5, $objItems[2]->GetVirtualAttribute('team_member_count'), "5 team members found for the third project");
$this->assertEquals(7, $objItems[3]->GetVirtualAttribute('team_member_count'), "7 team members found for the forth project");
}
public function testAssociationTables() {
// All People Who Are on a Project Managed by Karen Wolfe (Person ID #7)
$objPersonArray = Person::QueryArray(
QQ::Equal(QQN::Person()->ProjectAsTeamMember->Project->ManagerPersonId, 7),
QQ::Clause(
QQ::Distinct(),
QQ::OrderBy(QQN::Person()->LastName, QQN::Person()->FirstName)
)
);
$arrNamesOnly = array();
foreach ($objPersonArray as $item) {
$arrNamesOnly[] = $item->FirstName . " " . $item->LastName;
}
$this->assertEquals(array(
"Brett Carlisle",
"John Doe",
"Samantha Jones",
"Jacob Pratt",
"Kendall Public",
"Ben Robinson",
"Alex Smith",
"Wendy Smith",
"Karen Wolfe"),
$arrNamesOnly,
"List managed persons is correct");
$objPersonArray = Person::QueryArray(
QQ::Equal(QQN::Person()->PersonType->PersonTypeId, PersonType::Inactive),
QQ::Clause(
QQ::OrderBy(QQN::Person()->LastName, QQN::Person()->FirstName)
)
);
$arrNamesOnly = array();
foreach ($objPersonArray as $item) {
$arrNamesOnly[] = $item->FirstName . " " . $item->LastName;
}
$this->assertEquals(array(
"Linda Brady",
"John Doe",
"Ben Robinson")
, $arrNamesOnly
, "Person-PersonType assn is correct");
}
public function testQuerySingleEmpty() {
$targetPerson = Person::QuerySingle(
QQ::Equal(QQN::Person()->Id, 1241243));
$this->assertEquals(null, $targetPerson, "QuerySingle should return null for a not-found record");
}
public function testQuerySelectSubset() {
$objPersonArray = Person::LoadAll(QQ::Select(QQN::Person()->FirstName));
foreach ($objPersonArray as $objPerson) {
$this->setExpectedExceptionRegExp('QCallerException', '/LastName .* is not valid./');
$objPerson->LastName;
$this->setExpectedException(null);
// If we now set the last name, we should be able to get it
$objPerson->LastName = "Test";
$this->assertEquals("Test", $objPerson->LastName); // use the getter
$this->assertNotNull($objPerson->Id, "Id should not be null since it's always added to the select list");
}
}
public function testLoadAll() {
$objPersonArray = Person::LoadAll ();
$this->assertEquals(12, count($objPersonArray), "12 people found.");
$objTwoKeyArray = TwoKey::LoadAll();
$this->assertEquals(6, count($objTwoKeyArray), "6 TwoKey items found.");
}
public function testQuerySelectSubsetSkipPK() {
$objSelect = QQ::Select(QQN::Person()->FirstName);
$objSelect->SetSkipPrimaryKey(true);
$objPersonArray = Person::LoadAll($objSelect);
foreach ($objPersonArray as $objPerson) {
$this->setExpectedExceptionRegExp('QCallerException', '/LastName .* is not valid./');
$objPerson->LastName;
$this->setExpectedException(null);
$this->assertNull($objPerson->Id, "Id should be null since SkipPrimaryKey is set on the Select object");
}
}
public function testExpand() {
// Test intermediate nodes on expansion
$clauses = QQ::Clause(
QQ::Expand(QQN::Milestone()->Project->ManagerPerson)
);
$objMilestone =
Milestone::QuerySingle(
QQ::Equal (QQN::Milestone()->Id, 1),
$clauses
);
$this->assertTrue(!is_null($objMilestone->Name), "Milestone 1 has a name");
$this->assertEquals("Milestone A", $objMilestone->Name, "Milestone 1 has name of Milestone A");
$this->assertTrue(!is_null($objMilestone->Project->Name), "Project 1 has a name");
$this->assertEquals("ACME Website Redesign", $objMilestone->Project->Name, "Project 1 has name of ACME Website Redesign");
$this->assertTrue(!is_null($objMilestone->Project->ManagerPerson->FirstName), "Person 7 has a name");
$this->assertEquals("Karen", $objMilestone->Project->ManagerPerson->FirstName, "Person 7 has first name of Karen");
$clauses = QQ::Clause(
QQ::ExpandAsArray (QQN::Project()->PersonAsTeamMember),
QQ::OrderBy (QQN::Project()->PersonAsTeamMember->Person->LastName, QQN::Project()->PersonAsTeamMember->Person->FirstName)
);
// short reach
$objProject =
Project::QuerySingle(
QQ::Equal (QQN::Project()->Id, 1),
$clauses
);
$objPersonArray = $objProject->_PersonAsTeamMemberArray;
$arrNamesOnly = array();
foreach ($objPersonArray as $item) {
$arrNamesOnly[] = $item->FirstName . " " . $item->LastName;
}
$this->assertEquals(array(
"Samantha Jones",
"Kendall Public",
"Alex Smith",
"Wendy Smith",
"Karen Wolfe")
, $arrNamesOnly
, "Project Team Member expansion is correct");
// long reach
$clauses = QQ::Clause(
QQ::ExpandAsArray (QQN::Milestone()->Project->PersonAsTeamMember),
QQ::OrderBy (QQN::Milestone()->Project->PersonAsTeamMember->Person->LastName, QQN::Milestone()->Project->PersonAsTeamMember->Person->FirstName)
);
$objMilestone =
Milestone::QuerySingle(
QQ::Equal (QQN::Milestone()->Id, 1),
$clauses
);
$objPersonArray = $objMilestone->Project->_PersonAsTeamMemberArray;
$arrNamesOnly = array();
foreach ($objPersonArray as $item) {
$arrNamesOnly[] = $item->FirstName . " " . $item->LastName;
}
$this->assertEquals(array(
"Samantha Jones",
"Kendall Public",
"Alex Smith",
"Wendy Smith",
"Karen Wolfe"
)
, $arrNamesOnly
, "Long reach Milestone to Project Team Member expansion is correct");
}
/**
* Make sure that expansions looking backwards are pointing to the same object looking forwards
*/
public function testExpandReverseReferences() {
// Test virtual binding of reverse relationships
$clauses = [QQ::Expand(QQN::Person()->ProjectAsManager)];
$objPerson = Person::QuerySingle(QQ::All(), $clauses);
$objPerson->FirstName = 'test';
$objProject = $objPerson->ProjectAsManager;
$objPerson2 = $objProject->ManagerPerson;
$this->assertEquals('test', $objPerson2->FirstName);
// Test forward reference looking back
$clauses = [QQ::Expand(QQN::Project()->ManagerPerson)];
$objProject = Project::QuerySingle(QQ::All(), $clauses);
$objProject->Name = 'test';
$objPerson = $objProject->ManagerPerson;
$objProject2 = $objPerson->ProjectAsManager;
$this->assertEquals('test', $objProject2->Name);
// test unique reverse reference
$clauses = [QQ::Expand(QQN::Person()->Login)];
$objPerson = Person::QuerySingle(QQ::All(), $clauses);
$objPerson->FirstName = 'test';
$objLogin = $objPerson->Login;
$objPerson2 = $objLogin->Person;
$this->assertEquals('test', $objPerson2->FirstName);
// test many-to-many expansion
$clauses = [QQ::ExpandAsArray(QQN::Project()->PersonAsTeamMember)];
$objProject = Project::QuerySingle(QQ::All(), $clauses);
$objProject->Name = 'test';
$objPersonArray = $objProject->_PersonAsTeamMemberArray;
$objProject2 = $objPersonArray[0]->_ProjectAsTeamMember;
$this->assertEquals('test', $objProject2->Name);
}
public function testHaving() {
$objItems = Project::QueryArray(
QQ::All(),
QQ::Clause(
QQ::Select(QQN::Project()->Id, QQN::Project()->Name), // Some databases require selecting specific fields when aggregating
QQ::GroupBy(QQN::Project()->Id),
QQ::Count(QQN::Project()->PersonAsTeamMember->PersonId, 'team_member_count'),
QQ::Having(QQ::SubSql('COUNT({1}) > 5', QQN::Project()->PersonAsTeamMember->PersonId)),
QQ::OrderBy(QQN::Project()->Id)
)
);
$this->assertEquals(2, sizeof($objItems), "2 projects found");
$this->assertEquals("State College HR System", $objItems[0]->Name, "Project " . $objItems[0]->Name . " found");
$this->assertEquals(6, $objItems[0]->GetVirtualAttribute('team_member_count'), "6 team members found for project " . $objItems[0]->Name);
}
public function testEmptyColumns() {
$objItem = Login::QuerySingle(
QQ::Equal(QQN::Login()->Id, 1)
);
$var = $objItem->IsEnabled;
$this->assertNotNull($var, "Zero column does not return null. ");
$this->assertTrue($var == 0, "Zero boolean column is false or zero. ");
$objItem = Project::QuerySingle(
QQ::Equal(QQN::Project()->Id, 2)
);
$this->assertTrue($objItem->EndDate === null, "Null date column returns a null.");
// Testing unique reverse reference on null
$objPerson = new Person();
$objLogin = $objPerson->Login;
$this->assertNull($objLogin, "New record should not be associated with null PK.");
}
public function testOrderByReverseReference() {
// orders by the private key of the reverse reference node.
$objPerson = Person::QuerySingle(
QQ::IsNotNull(QQN::Person()->ProjectAsManager->Id),
[QQ::OrderBy(QQN::Person()->ProjectAsManager)]
);
$this->assertEquals(7, $objPerson->Id, "Manager of first project found.");
}
public function testOrderByExpansion() {
$objPersonArray = Person::QueryArray(
QQ::All(),
QQ::OrderBy(
QQ::IsNotNull(QQN::Person()->ProjectAsManager->Description), false, QQN::Person()->ProjectAsManager->Id
)
);
$this->assertEquals(7, $objPersonArray[0]->Id, "Found first project with manager");
}
public function testVirtualAttributeAliases() {
$clauses = [
QQ::GroupBy(QQN::Project()->ProjectStatusTypeId),
QQ::Sum(QQN::Project()->Budget, 'Budget Amount'),
QQ::Expand(QQ::Virtual('Balance', QQ::Func('SUM', QQ::Sub(QQN::Project()->Budget, QQN::Project()->Spent))))
];
$cond = QQ::Equal(QQN::Project()->ProjectStatusTypeId, ProjectStatusType::Open);
$objProject = Project::QuerySingle($cond, $clauses);
$amount1 = $objProject->GetVirtualAttribute('Budget Amount');
$this->assertEquals(83000, $amount1);
$amount2 = $objProject->GetVirtualAttribute('Balance');
$this->assertEquals(5599.50, $amount2);
}
public function testSubSql() {
$objProject = Project::QuerySingle(
QQ::All(),
QQ::Clause(
QQ::Count(QQ::SubSql('DISTINCT {1}', QQN::Project()->ManagerPersonId), "manager_count")
)
);
$this->assertEquals(3, $objProject->GetVirtualAttribute("manager_count"), "Project manager count is 3");
}
public function testGettersSetters() {
$objProject = Project::QuerySingle(QQ::Equal(QQN::Project()->Id, 1));
$this->assertEquals(1, $objProject->getId());
$this->assertEquals(7, $objProject->getManagerPersonId());
$objProject2 = new Project();
try {
$objProject2->setId(2); // can't set a pk that is an identity
$blnPassed = true;
}
catch(QCallerException $e) {
$blnPassed = false;
}
$this->assertEquals(false, $blnPassed, 'Exception sould be called when trying to set a pk on an identity column');
$objProject2->setName('Test');
$strName = $objProject2->getName();
$this->assertEquals('Test', $strName);
}
public function testReload() {
$objProject = Project::QuerySingle(QQ::Equal(QQN::Project()->Id, 1));
$objProject->Reload();
$this->assertEquals(1, $objProject->getId());
$this->assertEquals(7, $objProject->getManagerPersonId());
$this->assertEquals("ACME Website Redesign", $objProject->Name);
// Test non-identity set and reload
$objMilestone = Milestone::Load(1);
$objMilestone->Id = 5; // Should be legal for non-identity PKs
$objMilestone->Reload();
$this->assertEquals(1, $objMilestone->Id, "Identity should reset to original value after a reload");
}
public function testSetReference() {
$milestone1 = Milestone::Load(1);
$intProjectId = $milestone1->ProjectId;
$project4 = Project::Load(4);
$milestone1->Project = $project4;
$milestone1->Save();
$milestone1 = Milestone::Load(1);
$this->assertEquals(4, $milestone1->Project->Id);
// Restore state of database
$milestone1->ProjectId = $intProjectId;
$milestone1->Save();
$this->assertEquals($intProjectId, $milestone1->Project->Id);
}
public function testTypes() {
$objProject =
Project::QuerySingle(
QQ::Equal (QQN::Project()->Id, 1)
);
$this->assertEquals(3, $objProject->getProjectStatusTypeId());
$this->assertEquals("Completed", $objProject->getProjectStatusType());
}
}