Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Add "Clear all" GridFieldAction to log viewer #5

Merged
merged 1 commit into from
Jan 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Admin/LogViewerAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace SilverLeague\LogViewer\Admin;

use SilverLeague\LogViewer\Model\LogEntry;
use SilverLeague\LogViewer\Forms\GridField\GridFieldClearAllButton;
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
use SilverStripe\View\Requirements;
Expand Down Expand Up @@ -63,6 +64,7 @@ public function getEditForm($id = null, $fields = null)
/** @var \SilverStripe\Forms\GridField\GridFieldConfig $gridFieldConfig */
$config = $gridField->getConfig();
$config->removeComponentsByType($config->getComponentByType(GridFieldAddNewButton::class));
$config->addComponent(new GridFieldClearAllButton('buttons-before-left'));

return $form;
}
Expand Down
77 changes: 77 additions & 0 deletions src/Forms/GridField/GridFieldClearAllButton.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace SilverLeague\LogViewer\Forms\GridField;

use SilverStripe\ORM\ValidationException;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_FormAction;
use SilverStripe\Forms\GridField\GridField_HTMLProvider;
use SilverStripe\Forms\GridField\GridField_ActionProvider;

/**
* Adds a "Clear all" button to a GridField
*
* @package silverstripe-logviewer
* @author Robbie Averill <robbie@averill.co.nz>
*/
class GridFieldClearAllButton implements GridField_HTMLProvider, GridField_ActionProvider
{
/**
* Fragment to write the button to
*
* @var string
*/
protected $targetFragment;

/**
* @param string $targetFragment The HTML fragment to write the button into
*/
public function __construct($targetFragment = 'after')
{
$this->targetFragment = $targetFragment;
}

/**
* Add a "clear all" button to a <p> tag and assign it to the target fragment
*
* @param GridField $gridField
* @return array
*/
public function getHTMLFragments($gridField)
{
$button = GridField_FormAction::create($gridField, 'clear', 'Clear all', 'clear', null);
$button->setAttribute('data-icon', 'clear-all-logs');
$button->addExtraClass('font-icon-trash-bin action_clear');
$button->setForm($gridField->getForm());

return [$this->targetFragment => '<p class="grid-clear-all-button">' . $button->Field() . '</p>'];
}

/**
* {@inheritDoc}
*
* @throws ValidationException If the current user does not have permission to delete records
*/
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
{
/** @var \SilverStripe\ORM\DataList $gridField */
$list = $gridField->getList();

$dataClass = $list->dataClass();
if (!$dataClass::singleton()->canDelete()) {
throw new ValidationException(
_t('GridFieldAction_Delete.EditPermissionsFailure', "No permission to unlink record")
);
}

$gridField->getList()->removeAll();
}

/**
* {@inheritDoc}
*/
public function getActions($gridField)
{
return ['clear'];
}
}
38 changes: 26 additions & 12 deletions tests/Admin/LogViewerAdminTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace SilverLeague\LogViewer\Tests\Admin;

use SilverLeague\LogViewer\Admin\LogViewerAdmin;
use SilverLeague\LogViewer\Forms\GridField\GridFieldClearAllButton;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
use SilverStripe\Forms\ReadonlyField;
Expand Down Expand Up @@ -39,8 +40,6 @@ public function setUp()

/**
* Test that the log entries are returned in reverse order of creation date/time
*
* @covers ::getList
*/
public function testLogsShouldBeInReverseOrder()
{
Expand All @@ -51,20 +50,21 @@ public function testLogsShouldBeInReverseOrder()

/**
* Test that the GridField "add new" button has been removed
*
* @covers ::getEditForm
* @covers ::getGridFieldName
*/
public function testNoAddButton()
{
/** @var \SilverStripe\Forms\GridField\GridFieldConfig $gridFieldConfig */
$gridFieldConfig = $this->logViewerAdmin
->getEditForm()
->Fields()
->fieldByName($this->logViewerAdmin->getGridFieldName())
->getConfig();
$this->assertNull($this->getConfig()->getComponentByType(GridFieldAddNewButton::class));
}

$this->assertNull($gridFieldConfig->getComponentByType(GridFieldAddNewButton::class));
/**
* Test that there's a "clear all" button
*/
public function testHasClearAllButton()
{
$this->assertInstanceOf(
GridFieldClearAllButton::class,
$this->getConfig()->getComponentByType(GridFieldClearAllButton::class)
);
}

/**
Expand All @@ -76,4 +76,18 @@ public function testEntryAndLevelShouldBeInSummaryFields()
$this->assertContains('Entry', $summaryFields);
$this->assertContains('Level', $summaryFields);
}

/**
* Get the test GridField's config class
*
* @return \SilverStripe\Forms\GridField\GridFieldConfig
*/
protected function getConfig()
{
return $this->logViewerAdmin
->getEditForm()
->Fields()
->fieldByName($this->logViewerAdmin->getGridFieldName())
->getConfig();
}
}
129 changes: 129 additions & 0 deletions tests/Forms/GridField/GridFieldClearAllButtonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace SilverLeague\LogViewer\Tests\Forms\GridField;

use SilverLeague\LogViewer\Forms\GridField\GridFieldClearAllButton;
use SilverLeague\LogViewer\Model\LogEntry;
use SilverStripe\Control\Controller;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\ORM\DataList;

/**
* Tests for the "clear all" GridField action class
*
* @coversDefaultClass \SilverLeague\LogViewer\Forms\GridField\GridFieldClearAllButton
* @package silverstripe-logviewer
* @author Robbie Averill <robbie@averill.co.nz>
*/
class GridFieldClearAllButtonTest extends SapphireTest
{
/**
* {@inheritDoc}
*/
protected $usesDatabase = true;

protected $gridField;

/**
* {@inheritDoc}
*/
public function setUp()
{
parent::setUp();

$config = GridFieldConfig::create()->addComponent(new GridFieldClearAllButton('before'));
$this->gridField = GridField::create('logs', 'logs', DataList::create(LogEntry::class), $config);
$form = Form::create(
Controller::create(),
'foobar',
FieldList::create([$this->gridField]),
FieldList::create()
);
}

/**
* Return the actual class we're testing
*
* @return GridFieldClearAllButton
*/
protected function getSubject()
{
return $this->gridField->getConfig()->getComponentByType(GridFieldClearAllButton::class);
}

/**
* Ensure that the HTML fragment was pushed correctly and assigned to the specified fragment (in setUp above)
*/
public function testGetHtmlFragments()
{
$fragments = $this->getSubject()->getHTMLFragments($this->gridField);

$this->assertArrayHasKey('before', $fragments);
$this->assertContains('Clear all', $fragments['before']);
$this->assertContains('clear-all-logs', $fragments['before']);
$this->assertContains('font-icon-trash-bin action_clear', $fragments['before']);
$this->assertContains('<p class="grid-clear-all-button">', $fragments['before']);
}

/**
* Test that the GridFieldAction actions are returned correctly
*/
public function testActionsAreDefined()
{
$this->assertSame(['clear'], (new GridFieldClearAllButton)->getActions($this->gridField));
}

/**
* Test that an exception is thrown if the Member doesn't have permission to delete the data class assigned
*
* @expectedException \SilverStripe\ORM\ValidationException
* @expectedExceptionMessage No permission to unlink record
*/
public function testCannotClearAllWithoutPermission()
{
$forbiddenList = DataList::create(Stub\SomeDataObject::class);
$this->gridField->setList($forbiddenList);

$this->getSubject()->handleAction($this->gridField, 'clear', null, []);
}

/**
* Test that with permission the list can be cleared
*/
public function testClearList()
{
$this->logInWithPermission('ADMIN');

$this->createDummyLogs();
$this->assertSame(5, $this->gridField->getList()->count());

$this->getSubject()->handleAction($this->gridField, 'clear', null, []);
$this->assertSame(0, $this->gridField->getList()->count());
}

/**
* Create a set of dummy LogEntry records
*
* @param int $limit
*/
protected function createDummyLogs($limit = 5)
{
$factory = Injector::inst()->create('FixtureFactory');

for ($i = 1; $i <= $limit; $i++) {
$factory->createObject(
LogEntry::class,
'stub_log_' . $i,
[
'Entry' => 'Log #' . $i,
'Level' => 'DEBUG'
]
);
}
}
}
23 changes: 23 additions & 0 deletions tests/Forms/GridField/Stub/SomeDataObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace SilverLeague\LogViewer\Tests\Forms\GridField\Stub;

use SilverStripe\ORM\DataObject;
use SilverStripe\Dev\TestOnly;

/**
* A stubbed DataObject for testing permission checks
*
* @package silverstripe-logviewer
* @author Robbie Averill <robbie@averill.co.nz>
*/
class SomeDataObject extends DataObject implements TestOnly
{
/**
* {@inheritDoc}
*/
public function canDelete($member = null)
{
return false;
}
}