Skip to content
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/Reporting/Chunk.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ protected function createPage($content)
->withCurrent($content)
->get();

$data['site'] = $content->locale();

return new Page($content->id(), $data, $this->report);
}
}
5 changes: 5 additions & 0 deletions src/Reporting/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public function url()
return $this->get('canonical_url');
}

public function site()
{
return $this->get('site');
}

public function id()
{
return $this->id;
Expand Down
12 changes: 8 additions & 4 deletions src/Reporting/Rules/UniqueMetaDescription.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,14 @@ public function processPage()

protected function groupAllPagesByDescription()
{
return Blink::once('seo-pro-report-'.$this->report->id().'-page-descriptions-grouped', function () {
return $this->page->report()->pages()->mapToGroups(function ($page) {
return [$page->get('description') => $page->id()];
});
$site = $this->page->site();

return Blink::once('seo-pro-report-'.$this->report->id().'-page-descriptions-grouped-'.$site, function () use ($site) {
return $this->page->report()->pages()
->filter(fn ($page) => $page->site() === $site)
->mapToGroups(function ($page) {
return [$page->get('description') => $page->id()];
});
});
}

Expand Down
12 changes: 8 additions & 4 deletions src/Reporting/Rules/UniqueTitleTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,14 @@ public function processPage()

protected function groupAllPagesByTitle()
{
return Blink::once('seo-pro-report-'.$this->report->id().'-page-titles-grouped', function () {
return $this->page->report()->pages()->mapToGroups(function ($page) {
return [$page->get('title') => $page->id()];
});
$site = $this->page->site();

return Blink::once('seo-pro-report-'.$this->report->id().'-page-titles-grouped-'.$site, function () use ($site) {
return $this->page->report()->pages()
->filter(fn ($page) => $page->site() === $site)
->mapToGroups(function ($page) {
return [$page->get('title') => $page->id()];
});
});
}

Expand Down
87 changes: 87 additions & 0 deletions tests/Localized/ReportTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace Tests\Localized;

use Illuminate\Support\Carbon;
use PHPUnit\Framework\Attributes\Test;
use Statamic\Facades\Entry;
use Statamic\Facades\Term;
use Statamic\Facades\YAML;
use Statamic\SeoPro\Reporting\Report;
use Statamic\Support\Str;

class ReportTest extends LocalizedTestCase
{
protected function setUp(): void
{
parent::setUp();

Entry::all()->filter(fn ($entry) => $entry->hasOrigin())->each->delete();
Entry::all()->each->delete();
Term::all()->each->delete();

if ($this->files->exists($path = $this->reportsPath())) {
$this->files->deleteDirectory($path);
}
}

/**
* @see https://github.com/statamic/seo-pro/issues/213
*/
#[Test]
public function it_does_not_flag_duplicate_titles_and_descriptions_across_sites()
{
$this->makeArticle('default', 'one', 'Shared Title', 'Shared Description');
$this->makeArticle('french', 'two', 'Shared Title', 'Shared Description');

$this->assertEqualsIgnoringLineEndings(0, $this->getReportResult('UniqueTitleTag'));
$this->assertEqualsIgnoringLineEndings(0, $this->getReportResult('UniqueMetaDescription'));
}

/**
* @see https://github.com/statamic/seo-pro/issues/213
*/
#[Test]
public function it_still_flags_duplicate_titles_and_descriptions_within_the_same_site()
{
$this->makeArticle('default', 'one', 'Shared Title', 'Shared Description');
$this->makeArticle('default', 'two', 'Shared Title', 'Shared Description');
$this->makeArticle('french', 'three', 'Shared Title', 'Shared Description');

$this->assertEqualsIgnoringLineEndings(2, $this->getReportResult('UniqueTitleTag'));
$this->assertEqualsIgnoringLineEndings(2, $this->getReportResult('UniqueMetaDescription'));
}

private function makeArticle($site, $slug, $title, $description)
{
Entry::make()
->collection('articles')
->blueprint('articles')
->locale($site)
->slug($slug)
->date('2024-01-01')
->set('title', $title)
->set('seo', ['title' => $title, 'description' => $description])
->save();

return $this;
}

private function reportsPath($path = null)
{
if ($path) {
$path = Str::ensureLeft($path, '/');
}

return storage_path('statamic/seopro/reports').$path;
}

private function getReportResult($key)
{
Carbon::setTestNow(now());

Report::create()->save()->generate();

return YAML::file($this->reportsPath('1/report.yaml'))->parse()['results'][$key];
}
}
20 changes: 4 additions & 16 deletions tests/ReportTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ public function it_properly_reports_on_description_length()
], $this->getReportResult('IdealMetaDescriptionLength'));
}

public function reportsPath($path = null)
private function reportsPath($path = null)
{
if ($path) {
$path = Str::ensureLeft($path, '/');
Expand All @@ -475,7 +475,7 @@ public function reportsPath($path = null)
return storage_path('statamic/seopro/reports').$path;
}

protected function generateEntries($count)
private function generateEntries($count)
{
collect(range(1, $count))->each(function ($i) {
Entry::make()
Expand All @@ -489,7 +489,7 @@ protected function generateEntries($count)
return $this;
}

protected function generateTerms($count)
private function generateTerms($count)
{
collect(range(1, $count))->each(function ($i) {
Term::make()
Expand All @@ -502,26 +502,14 @@ protected function generateTerms($count)
return $this;
}

protected function getReportResult($key)
private function getReportResult($key)
{
Carbon::setTestNow($now = now());

Report::create()->save()->generate();

return YAML::file($this->reportsPath('1/report.yaml'))->parse()['results'][$key];
}

/**
* Normalize line endings before performing assertion in windows.
*/
public static function assertEqualsIgnoringLineEndings($needle, $haystack, $message = ''): void
{
parent::assertEquals(
is_string($needle) ? static::normalizeMultilineString($needle) : $needle,
is_string($haystack) ? static::normalizeMultilineString($haystack) : $haystack,
$message
);
}
}

class TestChunk extends Chunk
Expand Down
12 changes: 12 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ public static function assertStringNotContainsStringIgnoringLineEndings($needle,
);
}

/**
* Normalize line endings before performing assertion in windows.
*/
public static function assertEqualsIgnoringLineEndings(mixed $expected, mixed $actual, string $message = ''): void
{
parent::assertEquals(
is_string($expected) ? static::normalizeMultilineString($expected) : $expected,
is_string($actual) ? static::normalizeMultilineString($actual) : $actual,
$message
);
}

protected function assertArrayHasKeys(array $keys, array|\ArrayAccess $array): void
{
foreach ($keys as $key) {
Expand Down