Skip to content

Commit

Permalink
Improve support for base and extended classes
Browse files Browse the repository at this point in the history
  • Loading branch information
chrispenny committed Dec 21, 2021
1 parent e23e781 commit a9274fc
Show file tree
Hide file tree
Showing 11 changed files with 252 additions and 6 deletions.
13 changes: 11 additions & 2 deletions src/RelationshipGraph/Graph.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\ORM\DataObject;
use SilverStripe\View\ViewableData;
use Terraformers\KeysForCache\Models\CacheKey;

class Graph implements Flushable
Expand Down Expand Up @@ -44,10 +45,18 @@ public static function flush() // phpcs:ignore SlevomatCodingStandard.TypeHints

public function getEdgesFrom(string $from): array
{
$ancestry = ClassInfo::ancestry($from);
// Base classes that show up in every ancestry array
$disallowList = [
DataObject::class,
ViewableData::class,
];

return array_filter(
$this->getEdges(),
static function (Edge $e) use ($from) {
return $e->getFromClassName() === $from;
static function (Edge $e) use ($ancestry, $disallowList) {
return in_array($e->getFromClassName(), $ancestry, true)
&& !in_array($e->getFromClassName(), $disallowList, true);
}
);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Services/CacheProcessingService.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use SilverStripe\ORM\Queries\SQLDelete;
use Terraformers\KeysForCache\DataTransferObjects\EdgeUpdateDto;
use Terraformers\KeysForCache\Models\CacheKey;
use Terraformers\KeysForCache\RelationshipGraph\Edge;
use Terraformers\KeysForCache\RelationshipGraph\Graph;

abstract class CacheProcessingService
Expand Down Expand Up @@ -127,7 +128,7 @@ private function createEdges(DataObject $instance): array
}

return array_map(
static function ($e) use ($instance) {
static function (Edge $e) use ($instance) {
return new EdgeUpdateDto($e, $instance);
},
$applicableEdges
Expand Down
26 changes: 26 additions & 0 deletions tests/Mocks/Models/BaseCaredHasManyModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Terraformers\KeysForCache\Tests\Mocks\Models;

use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;
use Terraformers\KeysForCache\Tests\Mocks\Pages\ExtendedCaresPage;

class BaseCaredHasManyModel extends DataObject
{
private static array $db = [
'Title' => 'Varchar',
];

private static array $has_one = [
'ExtendedCaresPage' => ExtendedCaresPage::class,
];

private static array $extensions = [
Versioned::class,
];

private static string $table_name = 'BaseCaredHasManyModel';

private static bool $has_cache_key = false;
}
26 changes: 26 additions & 0 deletions tests/Mocks/Models/BaseCaredHasOneModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Terraformers\KeysForCache\Tests\Mocks\Models;

use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;
use Terraformers\KeysForCache\Tests\Mocks\Pages\ExtendedCaresPage;

class BaseCaredHasOneModel extends DataObject
{
private static array $db = [
'Title' => 'Varchar',
];

private static array $has_many = [
'ExtendedCaresPages' => ExtendedCaresPage::class,
];

private static array $extensions = [
Versioned::class,
];

private static string $table_name = 'BaseCaredHasOneModel';

private static bool $has_cache_key = false;
}
12 changes: 12 additions & 0 deletions tests/Mocks/Models/ExtendedCaredHasManyModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Terraformers\KeysForCache\Tests\Mocks\Models;

class ExtendedCaredHasManyModel extends BaseCaredHasManyModel
{
private static array $db = [
'Description' => 'Varchar',
];

private static string $table_name = 'ExtendedCaredHasManyModel';
}
12 changes: 12 additions & 0 deletions tests/Mocks/Models/ExtendedCaredHasOneModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Terraformers\KeysForCache\Tests\Mocks\Models;

class ExtendedCaredHasOneModel extends BaseCaredHasOneModel
{
private static array $db = [
'Description' => 'Varchar',
];

private static string $table_name = 'ExtendedCaredHasOneModel';
}
19 changes: 19 additions & 0 deletions tests/Mocks/Pages/ExtendedCaresPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

namespace Terraformers\KeysForCache\Tests\Mocks\Pages;

use Terraformers\KeysForCache\Tests\Mocks\Models\BaseCaredHasManyModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\BaseCaredHasOneModel;

class ExtendedCaresPage extends CaresPage
{
private static array $has_one = [
'BaseCaredHasOneModel' => BaseCaredHasOneModel::class,
];

private static array $has_many = [
'BaseCaredHasManyModels' => BaseCaredHasManyModel::class,
];

private static array $cares = [
'BaseCaredHasOneModel',
'BaseCaredHasManyModels',
'ExtendedCaredHasOneModel',
'ExtendedCaredHasManyModels',
];

private static string $table_name = 'ExtendedCaresPage';
}
1 change: 1 addition & 0 deletions tests/Mocks/Pages/ExtendedTouchedPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

class ExtendedTouchedPage extends TouchedPage
{
private static string $table_name = 'ExtendedTouchedPage';
}
1 change: 1 addition & 0 deletions tests/Mocks/Pages/ExtendedTouchesPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

class ExtendedTouchesPage extends TouchesPage
{
private static string $table_name = 'ExtendedTouchesPage';
}
119 changes: 116 additions & 3 deletions tests/Scenarios/ExtendedCaresTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
use SilverStripe\Dev\SapphireTest;
use Terraformers\KeysForCache\RelationshipGraph\Graph;
use Terraformers\KeysForCache\Services\ProcessedUpdatesService;
use Terraformers\KeysForCache\Tests\Mocks\Models\BaseCaredHasManyModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\BaseCaredHasOneModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredBelongsToModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasManyModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredManyManyModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredThroughModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\ExtendedCaredHasManyModel;
use Terraformers\KeysForCache\Tests\Mocks\Models\ExtendedCaredHasOneModel;
use Terraformers\KeysForCache\Tests\Mocks\Pages\CaresPage;
use Terraformers\KeysForCache\Tests\Mocks\Pages\ExtendedCaresPage;
use Terraformers\KeysForCache\Tests\Mocks\Relations\CaresPageCaredThroughModel;
Expand All @@ -24,6 +28,8 @@ class ExtendedCaresTest extends SapphireTest
* @var array
*/
protected static $extra_dataobjects = [
BaseCaredHasOneModel::class,
BaseCaredHasManyModel::class,
CaresPage::class,
CaresPageCaredThroughModel::class,
CaredBelongsToModel::class,
Expand All @@ -32,6 +38,8 @@ class ExtendedCaresTest extends SapphireTest
CaredManyManyModel::class,
CaredThroughModel::class,
ExtendedCaresPage::class,
ExtendedCaredHasOneModel::class,
ExtendedCaredHasManyModel::class,
];

public function testCaresPureHasOne(): void
Expand Down Expand Up @@ -118,9 +126,6 @@ public function testCaresHasOne(): void
$this->assertNotEquals($originalKey, $newKey);
}

/**
* This test is currently failing, and is a scenario we expect to support
*/
public function testCaresHasMany(): void
{
// Updates are processed as part of scaffold, so we need to flush before we kick off
Expand All @@ -144,6 +149,114 @@ public function testCaresHasMany(): void
$this->assertNotEquals($originalKey, $newKey);
}

/**
* Testing that Base relationships work when the explicit class is used in the relationship
*/
public function testBaseCaredHasOne(): void
{
// Updates are processed as part of scaffold, so we need to flush before we kick off
ProcessedUpdatesService::singleton()->flush();

$page = $this->objFromFixture(ExtendedCaresPage::class, 'page2');
$model = $this->objFromFixture(BaseCaredHasOneModel::class, 'model1');

$originalKey = $page->getCacheKey();

$this->assertNotNull($originalKey);
$this->assertNotEmpty($originalKey);

$model->forceChange();
$model->write();

$newKey = $page->getCacheKey();

$this->assertNotNull($newKey);
$this->assertNotEmpty($originalKey);
$this->assertNotEquals($originalKey, $newKey);
}

/**
* Testing that Base relationships work when the explicit class is used in the relationship
*/
public function testBaseCaredHasMany(): void
{
// Updates are processed as part of scaffold, so we need to flush before we kick off
ProcessedUpdatesService::singleton()->flush();

$page = $this->objFromFixture(ExtendedCaresPage::class, 'page2');
$model = $this->objFromFixture(BaseCaredHasManyModel::class, 'model1');

$originalKey = $page->getCacheKey();

$this->assertNotNull($originalKey);
$this->assertNotEmpty($originalKey);

$model->forceChange();
$model->write();

$newKey = $page->getCacheKey();

$this->assertNotNull($newKey);
$this->assertNotEmpty($originalKey);
$this->assertNotEquals($originalKey, $newKey);
}

/**
* Now testing that a relationship to a Base class still works when the related object is an extended class
*/
public function testExtendedCaredHasOne(): void
{
// Updates are processed as part of scaffold, so we need to flush before we kick off
ProcessedUpdatesService::singleton()->flush();

$page = $this->objFromFixture(ExtendedCaresPage::class, 'page3');
// This model is defined on an ExtendedCaresPage relationship that is for BaseCaredHasOneModel. This is a valid
// class extension that should also trigger an update
$model = $this->objFromFixture(ExtendedCaredHasOneModel::class, 'model1');

$originalKey = $page->getCacheKey();

$this->assertNotNull($originalKey);
$this->assertNotEmpty($originalKey);

$model->forceChange();
$model->write();

$newKey = $page->getCacheKey();

$this->assertNotNull($newKey);
$this->assertNotEmpty($originalKey);
$this->assertNotEquals($originalKey, $newKey);
}

/**
* Now testing that a relationship to a Base class still works when the related object is an extended class
*/
public function testExtendedCaredHasMany(): void
{
// Updates are processed as part of scaffold, so we need to flush before we kick off
ProcessedUpdatesService::singleton()->flush();

$page = $this->objFromFixture(ExtendedCaresPage::class, 'page3');
// This model is defined on an ExtendedCaresPage relationship that is for BaseCaredHasManyModel. This is a valid
// class extension that should also trigger an update
$model = $this->objFromFixture(ExtendedCaredHasManyModel::class, 'model1');

$originalKey = $page->getCacheKey();

$this->assertNotNull($originalKey);
$this->assertNotEmpty($originalKey);

$model->forceChange();
$model->write();

$newKey = $page->getCacheKey();

$this->assertNotNull($newKey);
$this->assertNotEmpty($originalKey);
$this->assertNotEquals($originalKey, $newKey);
}

protected function tearDown(): void
{
Injector::inst()->get(Graph::CACHE_KEY)->clear();
Expand Down
26 changes: 26 additions & 0 deletions tests/Scenarios/ExtendedCaresTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,36 @@ Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasManyModel:
model1:
Title: Has Many Model 1

Terraformers\KeysForCache\Tests\Mocks\Models\BaseCaredHasManyModel:
model1:
Title: Base Has Many Model 1

Terraformers\KeysForCache\Tests\Mocks\Models\BaseCaredHasOneModel:
model1:
Title: Base Has One Model 1

Terraformers\KeysForCache\Tests\Mocks\Models\ExtendedCaredHasManyModel:
model1:
Title: Extended Has Many Model 1

Terraformers\KeysForCache\Tests\Mocks\Models\ExtendedCaredHasOneModel:
model1:
Title: Extended Has One Model 1

Terraformers\KeysForCache\Tests\Mocks\Pages\ExtendedCaresPage:
page1:
Title: Page 1
CaredBelongsToModel: =>Terraformers\KeysForCache\Tests\Mocks\Models\CaredBelongsToModel.model1
CaredHasOneModel: =>Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneModel.model1
CaredHasManyModels:
- =>Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasManyModel.model1
page2:
Title: Page 2
BaseCaredHasOneModel: =>Terraformers\KeysForCache\Tests\Mocks\Models\BaseCaredHasOneModel.model1
BaseCaredHasManyModels:
- =>Terraformers\KeysForCache\Tests\Mocks\Models\BaseCaredHasManyModel.model1
page3:
Title: Page 3
BaseCaredHasOneModel: =>Terraformers\KeysForCache\Tests\Mocks\Models\ExtendedCaredHasOneModel.model1
BaseCaredHasManyModels:
- =>Terraformers\KeysForCache\Tests\Mocks\Models\ExtendedCaredHasManyModel.model1

0 comments on commit a9274fc

Please sign in to comment.