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
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ and this project adheres to
### Changed

- Use custom classes for navigation data
- Create interfaces for page navigation
- Create interfaces for page navigation
- [BREAKING] default value for subItems in PageNavigation introduced as part of interface refactor
- Create interface for parent title

## [v2.4.1] - 2026-05-28

Expand Down
17 changes: 0 additions & 17 deletions spec/chapter_navigation_interface.spec.php

This file was deleted.

17 changes: 0 additions & 17 deletions spec/in_page_navigation_interface.spec.php

This file was deleted.

67 changes: 67 additions & 0 deletions spec/multipage_parent_title.spec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

describe(\LongReadPlugin\MultipageParentTitle::class, function () {
Comment thread
RobjS marked this conversation as resolved.
beforeEach(function () {
$this->parentTitle = new \LongReadPlugin\MultipageParentTitle();
});
it('implements the ParentTitleRetrieverInterface', function () {
expect($this->parentTitle)->toBeAnInstanceOf(\LongReadPlugin\ParentTitleRetrieverInterface::class);
});

describe('->get()', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be useful to have some expects on the tests here confirming that we're getting the title of the highest-level ancestor post (which should be the last one in the returned array).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok - have added something in

it('returns null when post has no ancestors', function () {
global $post;
$post = (object) [
'ID' => 123
];

allow('get_post_ancestors')->toBeCalled()->andReturn([]);

$result = $this->parentTitle->get();

expect($result)->toBeNull();
});

it('returns the top-level ancestor title', function () {
global $post;
$post = (object) [
'ID' => 789
];

allow('get_post_ancestors')->toBeCalled()->andReturn([456, 123]);
allow('get_the_title')->toBeCalled()->andReturn('Top Level Post');
expect('get_the_title')->toBeCalled()->with(123);

$result = $this->parentTitle->get();
expect($result)->toEqual('Top Level Post');
});

it('returns null when get_the_title returns false', function () {
global $post;
$post = (object) [
'ID' => 789
];

allow('get_post_ancestors')->toBeCalled()->andReturn([456, 123]);
allow('get_the_title')->toBeCalled()->andReturn(false);

$result = $this->parentTitle->get();

expect($result)->toBeNull();
});

it('handles single-level hierarchy', function () {
global $post;
$post = (object) [
'ID' => 456
];

allow('get_post_ancestors')->toBeCalled()->andReturn([123]);
allow('get_the_title')->toBeCalled()->andReturn('Parent Post');

$result = $this->parentTitle->get();

expect($result)->toEqual('Parent Post');
});
});
});
50 changes: 20 additions & 30 deletions spec/parent_title.spec.php
Original file line number Diff line number Diff line change
@@ -1,39 +1,29 @@
<?php

describe(\LongReadPlugin\ParentTitle::class, function () {
describe('::get', function () {
context('there is no post parent', function () {
it('returns null', function () {
global $post;
$post = new stdClass();
allow('get_post_ancestors')->toBeCalled()->andReturn([]);
$result = \LongReadPlugin\ParentTitle::get();
expect($result)->toEqual(null);
});
});
describe('::get()', function () {
it('calls the getter instance method and returns its result', function () {
$mockGetter = \Kahlan\Plugin\Double::instance([
'implements' => \LongReadPlugin\ParentTitleRetrieverInterface::class
]);
allow($mockGetter)->toReceive('get')->andReturn('Parent Title');

new \LongReadPlugin\ParentTitle($mockGetter);
$result = \LongReadPlugin\ParentTitle::get();

context('there is only one post ancestors', function () {
it('returns the title of that parent', function () {
global $post;
$post = new stdClass();
allow('get_post_ancestors')->toBeCalled()->andReturn([123]);
allow('get_the_title')->toBeCalled()->andReturn('The parent title');
expect('get_the_title')->toBeCalled()->once()->with(123);
$result = \LongReadPlugin\ParentTitle::get();
expect($result)->toEqual('The parent title');
});
expect($result)->toEqual('Parent Title');
});

context('there is only multiple post ancestors', function () {
it('returns the title of the top level post ancestor', function () {
global $post;
$post = new stdClass();
allow('get_post_ancestors')->toBeCalled()->andReturn([123, 456, 789]);
allow('get_the_title')->toBeCalled()->andReturn('The top ancestor title');
expect('get_the_title')->toBeCalled()->once()->with(789);
$result = \LongReadPlugin\ParentTitle::get();
expect($result)->toEqual('The top ancestor title');
});
it('returns null when getter returns null', function () {
$mockGetter = \Kahlan\Plugin\Double::instance([
'implements' => \LongReadPlugin\ParentTitleRetrieverInterface::class
]);
allow($mockGetter)->toReceive('get')->andReturn(null);

new \LongReadPlugin\ParentTitle($mockGetter);
$result = \LongReadPlugin\ParentTitle::get();

expect($result)->toBeNull();
});
});
});
7 changes: 5 additions & 2 deletions src/HierarchicalInPageNavigation.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ class HierarchicalInPageNavigation implements InPageNavigationInterface
private function parseHeading(string $html): InPageNavigationItem
{
$matches = [];
preg_match('/(id=")(.*?)"/', $html, $matches);
$id = null;
if (preg_match('/(id=")(.*?)"/', $html, $matches)) {
$id = $matches[2] ?? null;
}
return new InPageNavigationItem(
trim(strip_tags($html)),
$matches[2]
$id
);
}

Expand Down
14 changes: 14 additions & 0 deletions src/MultipageParentTitle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace LongReadPlugin;

class MultipageParentTitle implements ParentTitleRetrieverInterface
{
public function get(): ?string
{
global $post;
$ancestors = get_post_ancestors($post);
$topLevelAncestor = array_pop($ancestors);
return $topLevelAncestor ? get_the_title($topLevelAncestor) ?: null : null;
}
}
20 changes: 11 additions & 9 deletions src/ParentTitle.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@

class ParentTitle
{
/**
* @return string|null
*/
public static function get()
private static ParentTitleRetrieverInterface $getter;

public function __construct(ParentTitleRetrieverInterface $getter)
{
self::$getter = $getter;
}

public static function get(): ?string
{
global $post;
$ancestors = get_post_ancestors($post);
$topLevelAncestor = array_pop($ancestors);
if ($topLevelAncestor) {
return get_the_title($topLevelAncestor);
if (!isset(self::$getter)) {
return null;
}
return self::$getter->get();
}
}
8 changes: 8 additions & 0 deletions src/ParentTitleRetrieverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace LongReadPlugin;

interface ParentTitleRetrieverInterface
{
public function get(): ?string;
}
7 changes: 5 additions & 2 deletions src/di.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
$registrar->addInstance(new \LongReadPlugin\PostType());
$registrar->addInstance(new \LongReadPlugin\HeadingAnchors());
$registrar->addInstance(new \LongReadPlugin\Navigation(
new LongReadPlugin\HierarchicalChapterNavigation(),
new LongReadPlugin\HierarchicalInPageNavigation()
new \LongReadPlugin\HierarchicalChapterNavigation(),
new \LongReadPlugin\HierarchicalInPageNavigation()
));
$registrar->addInstance(new \LongReadPlugin\Options());
$registrar->addInstance(new \LongReadPlugin\Template());
$registrar->addInstance(new \LongReadPlugin\ParentTitle(
new \LongReadPlugin\MultipageParentTitle()
));
Loading