Skip to content

Commit

Permalink
Support navigation and globals in the static caching invalidation
Browse files Browse the repository at this point in the history
Clean up tests by using regular mocks, not spies, and do a little tidying.

Closes #2639
Closes #2393

Co-authored-by: Duncan McClean <duncan@mcclean.co.uk>
  • Loading branch information
jasonvarga and duncanmcclean committed Oct 30, 2020
1 parent f11a5d2 commit ca33420
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 55 deletions.
37 changes: 28 additions & 9 deletions src/StaticCaching/DefaultInvalidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Statamic\StaticCaching;

use Statamic\Contracts\Entries\Entry;
use Statamic\Contracts\Globals\GlobalSet;
use Statamic\Contracts\Structures\Nav;
use Statamic\Contracts\Taxonomies\Term;
use Statamic\Support\Arr;

Expand All @@ -23,33 +25,50 @@ public function invalidate($item)
return $this->cacher->flush();
}

// Invalidate the item's own URL.
if ($url = $item->url()) {
$this->cacher->invalidateUrl($url);
}

if ($item instanceof Entry) {
$this->invalidateEntryUrls($item);
} elseif ($item instanceof Term) {
$this->invalidateTermUrls($item);
} elseif ($item instanceof Nav) {
$this->invalidateNavUrls($item);
} elseif ($item instanceof GlobalSet) {
$this->invalidateGlobalUrls($item);
}
}

protected function invalidateEntryUrls($entry)
{
$collection = $entry->collectionHandle();
if ($url = $entry->url()) {
$this->cacher->invalidateUrl($url);
}

$this->cacher->invalidateUrls(
Arr::get($this->rules, "collections.$collection.urls")
Arr::get($this->rules, "collections.{$entry->collectionHandle()}.urls")
);
}

protected function invalidateTermUrls($term)
{
$taxonomy = $term->taxonomyHandle();
if ($url = $term->url()) {
$this->cacher->invalidateUrl($url);
}

$this->cacher->invalidateUrls(
Arr::get($this->rules, "taxonomies.$taxonomy.urls")
Arr::get($this->rules, "taxonomies.{$term->taxonomyHandle()}.urls")
);
}

protected function invalidateNavUrls($nav)
{
$this->cacher->invalidateUrls(
Arr::get($this->rules, "navigation.{$nav->handle()}.urls")
);
}

protected function invalidateGlobalUrls($set)
{
$this->cacher->invalidateUrls(
Arr::get($this->rules, "globals.{$set->handle()}.urls")
);
}
}
18 changes: 18 additions & 0 deletions src/StaticCaching/Invalidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
use Illuminate\Contracts\Queue\ShouldQueue;
use Statamic\Events\EntryDeleted;
use Statamic\Events\EntrySaved;
use Statamic\Events\GlobalSetDeleted;
use Statamic\Events\GlobalSetSaved;
use Statamic\Events\NavDeleted;
use Statamic\Events\NavSaved;
use Statamic\Events\TermDeleted;
use Statamic\Events\TermSaved;

Expand All @@ -17,6 +21,10 @@ class Invalidate implements ShouldQueue
EntryDeleted::class => 'invalidateEntry',
TermSaved::class => 'invalidateTerm',
TermDeleted::class => 'invalidateTerm',
GlobalSetSaved::class => 'invalidateGlobalSet',
GlobalSetDeleted::class => 'invalidateGlobalSet',
NavSaved::class => 'invalidateNav',
NavDeleted::class => 'invalidateNav',
];

public function __construct(Invalidator $invalidator)
Expand All @@ -40,4 +48,14 @@ public function invalidateTerm($event)
{
$this->invalidator->invalidate($event->term);
}

public function invalidateGlobalSet($event)
{
$this->invalidator->invalidate($event->globals);
}

public function invalidateNav($event)
{
$this->invalidator->invalidate($event->nav);
}
}
118 changes: 72 additions & 46 deletions tests/StaticCaching/DefaultInvalidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace Tests\StaticCaching;

use Statamic\Contracts\Data\Content\Content;
use Mockery;
use Statamic\Contracts\Entries\Entry;
use Statamic\Contracts\Globals\GlobalSet;
use Statamic\Contracts\Structures\Nav;
use Statamic\Contracts\Taxonomies\Term;
use Statamic\StaticCaching\Cacher;
use Statamic\StaticCaching\DefaultInvalidator as Invalidator;
Expand All @@ -12,46 +14,33 @@ class DefaultInvalidatorTest extends \PHPUnit\Framework\TestCase
{
public function tearDown(): void
{
if ($container = \Mockery::getContainer()) {
$this->addToAssertionCount($container->mockery_getExpectationCount());
}

parent::tearDown();
Mockery::close();
}

/** @test */
public function specifying_all_as_invalidation_rule_will_just_flush_the_cache()
{
$cacher = \Mockery::spy(Cacher::class);
$invalidator = new Invalidator($cacher, 'all');
$content = \Mockery::mock(Content::class);
$cacher = Mockery::mock(Cacher::class)->shouldReceive('flush')->once()->getMock();
$item = Mockery::mock(Entry::class);

$invalidator->invalidate($content);
$invalidator = new Invalidator($cacher, 'all');

$cacher->shouldHaveReceived('flush');
$this->assertNull($invalidator->invalidate($item));
}

/** @test */
public function the_entrys_url_gets_invalidated()
public function collection_urls_can_be_invalidated()
{
$cacher = \Mockery::spy(Cacher::class);
$invalidator = new Invalidator($cacher);
$cacher = tap(Mockery::mock(Cacher::class), function ($cacher) {
$cacher->shouldReceive('invalidateUrl')->with('/my/test/entry')->once();
$cacher->shouldReceive('invalidateUrls')->once()->with(['/blog/one', '/blog/two']);
});

$entry = tap(\Mockery::mock(Entry::class), function ($m) {
$entry = tap(Mockery::mock(Entry::class), function ($m) {
$m->shouldReceive('url')->andReturn('/my/test/entry');
$m->shouldReceive('collectionHandle')->andReturn('blog');
});

$invalidator->invalidate($entry);

$cacher->shouldNotHaveReceived('flush');
$cacher->shouldHaveReceived('invalidateUrl')->with('/my/test/entry');
}

/** @test */
public function collection_urls_can_be_invalidated()
{
$cacher = \Mockery::spy(Cacher::class);
$invalidator = new Invalidator($cacher, [
'collections' => [
'blog' => [
Expand All @@ -63,24 +52,22 @@ public function collection_urls_can_be_invalidated()
],
]);

$entry = tap(\Mockery::mock(Entry::class), function ($m) {
$m->shouldReceive('url')->andReturn('/my/test/entry');
$m->shouldReceive('collectionHandle')->andReturn('blog');
});

$invalidator->invalidate($entry);

$cacher->shouldNotHaveReceived('flush');
$cacher->shouldHaveReceived('invalidateUrls')->once()->with([
'/blog/one',
'/blog/two',
]);
$this->assertNull($invalidator->invalidate($entry));
}

/** @test */
public function taxonomy_urls_can_be_invalidated()
{
$cacher = \Mockery::spy(Cacher::class);
$cacher = tap(Mockery::mock(Cacher::class), function ($cacher) {
$cacher->shouldReceive('invalidateUrl')->with('/my/test/term')->once();
$cacher->shouldReceive('invalidateUrls')->once()->with(['/tags/one', '/tags/two']);
});

$term = tap(Mockery::mock(Term::class), function ($m) {
$m->shouldReceive('url')->andReturn('/my/test/term');
$m->shouldReceive('taxonomyHandle')->andReturn('tags');
});

$invalidator = new Invalidator($cacher, [
'taxonomies' => [
'tags' => [
Expand All @@ -92,17 +79,56 @@ public function taxonomy_urls_can_be_invalidated()
],
]);

$entry = tap(\Mockery::mock(Term::class), function ($m) {
$m->shouldReceive('url')->andReturn('/my/test/term');
$m->shouldReceive('taxonomyHandle')->andReturn('tags');
$this->assertNull($invalidator->invalidate($term));
}

/** @test */
public function navigation_urls_can_be_invalidated()
{
$cacher = tap(Mockery::mock(Cacher::class), function ($cacher) {
$cacher->shouldReceive('invalidateUrls')->once()->with(['/one', '/two']);
});

$invalidator->invalidate($entry);
$nav = tap(Mockery::mock(Nav::class), function ($m) {
$m->shouldReceive('handle')->andReturn('links');
});

$cacher->shouldNotHaveReceived('flush');
$cacher->shouldHaveReceived('invalidateUrls')->once()->with([
'/tags/one',
'/tags/two',
$invalidator = new Invalidator($cacher, [
'navigation' => [
'links' => [
'urls' => [
'/one',
'/two',
],
],
],
]);

$this->assertNull($invalidator->invalidate($nav));
}

/** @test */
public function globals_urls_can_be_invalidated()
{
$cacher = tap(Mockery::mock(Cacher::class), function ($cacher) {
$cacher->shouldReceive('invalidateUrls')->once()->with(['/one', '/two']);
});

$set = tap(Mockery::mock(GlobalSet::class), function ($m) {
$m->shouldReceive('handle')->andReturn('social');
});

$invalidator = new Invalidator($cacher, [
'globals' => [
'social' => [
'urls' => [
'/one',
'/two',
],
],
],
]);

$this->assertNull($invalidator->invalidate($set));
}
}

0 comments on commit ca33420

Please sign in to comment.