Fix some remaining bugs in set/clear project, add some automatic tests

This commit is contained in:
nathangray 2017-02-02 09:22:54 -07:00
parent a906ebb1c9
commit eae8821b97
2 changed files with 431 additions and 1 deletions

View File

@ -1066,7 +1066,7 @@ class infolog_bo
// if project has been removed, but is still info_contact --> also remove it
if ($app == 'projectmanager' && $id && $id == $values['old_pm_id'] && !$values['pm_id'])
{
unset($values['info_link_id'], $id, $values['info_contact']['id']);
unset($values['info_link_id'], $id, $values['info_contact']);
}
elseif ($app && $id)
{
@ -1085,6 +1085,21 @@ class infolog_bo
unset($values['info_link_id']);
}
}
else if ($values['pm_id'] && $values['info_id'] && !$values['old_pm_id'])
{
// Set for new entry with no contact
$app = 'projectmanager';
$id = $values['pm_id'];
$values['info_link_id'] = (int)($info_link_id = Link::link(
'infolog',
$values['info_id'],
$app,$id
));
}
else
{
unset($values['info_link_id']);
}
if ($old_link_id && $old_link_id != $values['info_link_id'])
{
$link = Link::get_link($old_link_id);

View File

@ -0,0 +1,415 @@
<?php
namespace EGroupware\Infolog;
require_once realpath(__DIR__.'/../../api/src/test/AppTest.php'); // Application test base
use Egroupware\Api;
/**
* Test setting a project manager project on an infolog entry
*
* Tests adding, loading, clearing the project to make sure field is set
* correctly, and checks to make sure the infolog entry is properly added / removed
* from the project.
*
* Since projectmanager is involved, there are frequent calls to Api\Link::run_notifies()
* to keep its elements up to date. Normally this is not needed, as it is run
* at the end of every execution.
*/
class SetProjectManagerTest extends \EGroupware\Api\AppTest
{
protected $ui;
protected $bo;
protected $pm_bo;
// Infolog under test
protected $info_id = null;
// Project used to test
protected $pm_id = null;
public function setUp()
{
$this->ui = new \infolog_ui();
$this->ui->tmpl = $this->getMockBuilder('\\Egroupware\\Api\\Etemplate')
->disableOriginalConstructor()
->setMethods(array('exec', 'read'))
->getMock($this->ui);
$this->bo = $this->ui->bo;
$this->pm_bo = new \projectmanager_bo();
$this->mockTracking($this->bo, 'infolog_tracking');
$this->makeProject();
}
public function tearDown()
{
// Remove infolog under test
if($this->info_id)
{
$this->bo->delete($this->info_id, False, False, True);
}
// Remove the test project
$this->deleteProject();
$this->bo = null;
$this->pm_bo = null;
}
/**
* Create a new infolog entry, with project set
*
* This one goes via the ui, mostly to see how it would work
*/
public function testAddProjectToNew()
{
// Saving the infolog should try to send a notification
$this->bo->tracking->expects($this->atLeastOnce())
->method('track')
->with($this->callback(function($subject) { return $subject['pm_id'] == $this->pm_id;}));
// Mock the etemplate call to check the results
$this->ui->tmpl->expects($this->once())
->method('exec')
->with($this->stringContains('infolog.infolog_ui.edit'),
$this->callback(function($info) {
$this->assertNotNull($info['info_id']);
$this->info_id = $info['info_id'];
return $info['pm_id'] == $this->pm_id;
})
);
$info = $this->getTestInfolog();
// Set up the test - just set pm_id
$info['pm_id'] = $this->pm_id;
// Set button 'apply' to save, but not try to close the window since
// that would fail
$info['button'] = array('apply' => true);
// Make a call to edit, looks like user set pm_id and clicked Apply
$this->ui->edit($info);
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Check project
$this->checkElements();
}
public function testAddProjectToExisting()
{
// Saving the infolog should try to send a notification
$this->bo->tracking->expects($this->exactly(2))
->method('track')
->withConsecutive(
// First call - creation
[$this->callback(function($subject) { return is_null($subject['pm_status']);})],
// Second call - after setting project
[$this->callback(function($subject) { return $subject['pm_id'] == $this->pm_id;})]
);
$info = $this->getTestInfolog();
$this->info_id = $this->bo->write($info);
$this->assertThat($this->info_id,
$this->logicalAnd(
$this->isType('integer'),
$this->greaterThan(0)
)
);
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Now load it again
$info = $this->bo->read($this->info_id);
// Set project by pm_id
$info['pm_id'] = $this->pm_id;
$this->bo->write($info);
// Now load it again
$info = $this->bo->read($this->info_id);
// Check pm_id is there
$this->assertNotNull($info['pm_id'], 'Project was not set');
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Check project
$this->checkElements();
}
/**
* Create a new infolog entry, set project via info_contact
*/
public function testContact()
{
// Saving the infolog should try to send a notification
$this->bo->tracking->expects($this->once())
->method('track')
->with($this->callback(function($subject) { return $subject['pm_id'] == $this->pm_id;}));
$info = $this->getTestInfolog();
// Set up the test - just set info_contact
$info['info_contact'] = 'projectmanager:'.$this->pm_id;
$this->info_id = $this->bo->write($info);
$this->assertArrayHasKey('info_id', $info, 'Could not make test project');
$this->assertThat($this->info_id,
$this->logicalAnd(
$this->isType('integer'),
$this->greaterThan(0)
)
);
// Check infolog has pm_id properly set
$this->assertEquals($this->pm_id, $info['pm_id']);
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Check project
$this->checkElements();
}
public function testLoadWithProject()
{
// Saving the infolog should try to send a notification
$this->bo->tracking->expects($this->once())
->method('track')
->with($this->callback(function($subject) { return $subject['pm_id'] == $this->pm_id;}));
$info = $this->getTestInfolog();
// Set up the test - just set info_contact
$info['info_contact'] = 'projectmanager:'.$this->pm_id;
$this->info_id = $this->bo->write($info);
$this->assertThat($this->info_id,
$this->logicalAnd(
$this->isType('integer'),
$this->greaterThan(0)
)
);
// Check infolog has pm_id properly set
$this->assertEquals($this->pm_id, $info['pm_id']);
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Now load it again
$info = $this->bo->read($this->info_id);
// Check infolog still has pm_id
$this->assertEquals($this->pm_id, $info['pm_id'], 'Project went missing');
// Check project
$this->checkElements();
}
public function testClearProject()
{
// Saving the infolog should try to send a notification
$this->bo->tracking->expects($this->exactly(2))
->method('track')
->withConsecutive(
// First call - set the project
[$this->callback(function($subject) { return $subject['pm_id'] == $this->pm_id;})],
// Second call - clear the project
[$this->callback(function($subject) { return is_null($subject['pm_status']);})]
);
$info = $this->getTestInfolog();
// Set up the test - just set info_contact
$info['info_contact'] = 'projectmanager:'.$this->pm_id;
$this->info_id = $this->bo->write($info);
$this->assertThat($this->info_id,
$this->logicalAnd(
$this->isType('integer'),
$this->greaterThan(0)
)
);
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Now load it again
$info = $this->bo->read($this->info_id);
// Clear it
unset($info['pm_id']);
$this->bo->write($info);
// Now load it again
$info = $this->bo->read($this->info_id);
// Check pm_id is gone
$this->assertNull($info['pm_id'], 'Project was not removed');
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Check project
$this->checkElements(0);
}
/**
* If the contact is set to a project, and the contact is cleared, that
* will also clear the project
*/
public function testClearContact()
{
// Saving the infolog should try to send a notification
$this->bo->tracking->expects($this->exactly(2))
->method('track')
->withConsecutive(
// First call - set the project
[$this->callback(function($subject) { return $subject['pm_id'] == $this->pm_id;})],
// Second call - clear the project
[$this->callback(function($subject) { return is_null($subject['pm_status']);})]
);
$info = $this->getTestInfolog();
// Set up the test - just set info_contact
$info['info_contact'] = 'projectmanager:'.$this->pm_id;
$this->info_id = $this->bo->write($info);
$this->assertThat($this->info_id,
$this->logicalAnd(
$this->isType('integer'),
$this->greaterThan(0)
)
);
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Now load it again
$info = $this->bo->read($this->info_id);
// Clear it
unset($info['info_contact']);
$this->bo->write($info);
// Now load it again
$info = $this->bo->read($this->info_id);
// Check contact was cleared
$this->assertNull($info['info_contact'], 'Contact was not cleared');
// Check pm_id is gone
$this->assertNull($info['pm_id'], 'Project was not removed');
// Force links to run notification now so we get valid testing - it
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Check project
$this->checkElements(0);
}
protected function getTestInfolog()
{
return array(
'info_subject' => 'Test Infolog Entry for ' . $this->getName()
);
}
/**
* Make a project so we can test deleting it
*/
protected function makeProject()
{
$project = array(
'pm_number' => 'TEST',
'pm_title' => 'Auto-test for ' . $this->getName(),
'pm_status' => 'active',
'pm_description' => 'Test project for ' . $this->getName()
);
// Save & set modifier, no notifications
try
{
$result = true;
$result = $this->pm_bo->save($project, true, false);
}
catch (\Exception $e)
{
// Something went wrong, we'll just fail
$this->fail($e);
}
$this->assertFalse((boolean)$result, 'Error making test project');
$this->assertArrayHasKey('pm_id', $this->pm_bo->data, 'Could not make test project');
$this->assertThat($this->pm_bo->data['pm_id'],
$this->logicalAnd(
$this->isType('integer'),
$this->greaterThan(0)
)
);
$this->pm_id = $this->pm_bo->data['pm_id'];
}
/**
* Check that the project element is present
*
*/
protected function checkElements($expected_count = 1)
{
$element_bo = new \projectmanager_elements_bo();
$element_count = 0;
foreach($element_bo->search(array('pm_id' => $this->pm_id), false) as $element)
{
$element_count++;
$this->assertEquals($this->info_id, $element['pe_app_id']);
}
$this->assertEquals($expected_count, $element_count, "Incorrect number of elements");
}
/**
* Fully delete a project and its elements, no matter what state or settings
*/
protected function deleteProject()
{
// Force links to run notification now, or elements might stay
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
// Force to ignore setting
$this->pm_bo->history = '';
$this->pm_bo->delete($this->pm_id, true);
// Force links to run notification now, or elements might stay
// usually waits until Egw::on_shutdown();
Api\Link::run_notifies();
}
}