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

Show UI conditionally #82

Merged
merged 2 commits into from
Jul 11, 2024
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: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ parameters:

-
message: "#^Cannot access property \\$categories on array\\|bool\\|stdClass\\.$#"
count: 1
count: 2
path: src/Adapters/DatabaseApproverRepository.php

-
Expand Down
5 changes: 4 additions & 1 deletion psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.24.0@462c80e31c34e58cc4f750c656be3927e80e550e">
<files psalm-version="5.25.0@01a8eb06b9e9cc6cfb6a320bf9fb14331919d505">
<file src="src/Adapters/AuthorityBasedApprovalAuthorizer.php">
<MixedArgumentTypeCoercion>
<code><![CDATA[$page->getCategories()]]></code>
Expand All @@ -26,11 +26,14 @@
<code><![CDATA[$approvers]]></code>
<code><![CDATA[$this->deserializeCategories( $row->ac_categories )]]></code>
<code><![CDATA[array<array{userId: int, categories: string[]}>]]></code>
<code><![CDATA[array_unique( $allCategories )]]></code>
<code><![CDATA[string[]]]></code>
<code><![CDATA[string[]]]></code>
</MixedReturnTypeCoercion>
<PossiblyInvalidPropertyFetch>
<code><![CDATA[$row->ac_categories]]></code>
<code><![CDATA[$row->categories]]></code>
<code><![CDATA[$row->categories]]></code>
<code><![CDATA[$row->userId]]></code>
</PossiblyInvalidPropertyFetch>
</file>
Expand Down
19 changes: 19 additions & 0 deletions src/Adapters/DatabaseApproverRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,25 @@ public function setApproverCategories( int $userId, array $categoryNames ): void
);
}

/**
* @return string[]
*/
public function getAllCategories(): array {
$result = $this->database->select(
'approver_config',
[ 'ac_categories AS categories' ],
[],
__METHOD__
);

$allCategories = [];
foreach ( $result as $row ) {
$allCategories = array_merge( $allCategories, $this->deserializeCategories( (string)$row->categories ) );
}

return array_unique( $allCategories );
}

private function serializeCategories( array $categories ): string {
return implode( '|', array_unique( array_map(
fn ( string $category ) => $this->normalizeCategoryTitle( $category ),
Expand Down
11 changes: 11 additions & 0 deletions src/Adapters/InMemoryApproverRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ public function getApproversWithCategories(): array {
return $this->approversCategories;
}

/**
* @return string[]
*/
public function getAllCategories(): array {
$allCategories = [];
foreach ( $this->approversCategories as $categories ) {
$allCategories = array_merge( $allCategories, $categories );
}
return array_values( array_unique( $allCategories ) );
}

/**
* @param string[] $categoryNames
*/
Expand Down
5 changes: 5 additions & 0 deletions src/Application/ApproverRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public function getApproverCategories( int $userId ): array;
*/
public function getApproversWithCategories(): array;

/**
* @return string[]
*/
public function getAllCategories(): array;

/**
* @param string[] $categoryNames
*/
Expand Down
17 changes: 14 additions & 3 deletions src/Application/UseCases/ApprovalUiQuery/ApprovalUiQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
use ProfessionalWiki\PageApprovals\Application\ApprovalAuthorizer;
use ProfessionalWiki\PageApprovals\Application\ApprovalLog;
use ProfessionalWiki\PageApprovals\Application\ApprovalState;
use ProfessionalWiki\PageApprovals\Application\ApproverRepository;

class ApprovalUiQuery {

public function __construct(
private readonly ApprovalLog $approvalLog,
private readonly ApprovalAuthorizer $approvalAuthorizer
private readonly ApprovalAuthorizer $approvalAuthorizer,
private readonly ApproverRepository $approverRepository
) {
}

Expand All @@ -35,14 +37,23 @@ private function getApprovalState( OutputPage $out, bool $showUi ): ?ApprovalSta
if ( $showUi ) {
return $this->approvalLog->getApprovalState( pageId: $out->getWikiPage()->getId() ); // TODO: test
}

return null;
}

private function isApprovablePage( OutputPage $out ): bool {
return $out->isArticle() // TODO: test
return $this->pageHasApprovers( $out )
&& $out->isArticle() // TODO: test
&& $out->getRevisionId() !== null // Exclude non-existing pages // TODO: test
&& $out->isRevisionCurrent(); // TODO: test
}

private function pageHasApprovers( OutputPage $out ): bool {
return !empty(
array_intersect(
$out->getCategories(),
$this->approverRepository->getAllCategories()
)
);
}

}
3 changes: 2 additions & 1 deletion src/PageApprovals.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ public function getApproverRepository(): ApproverRepository {
public function newApprovalUiQuery(): ApprovalUiQuery {
return new ApprovalUiQuery(
approvalLog: $this->getApprovalLog(),
approvalAuthorizer: $this->newPageApprovalAuthorizer()
approvalAuthorizer: $this->newPageApprovalAuthorizer(),
approverRepository: $this->getApproverRepository()
);
}

Expand Down
12 changes: 12 additions & 0 deletions tests/Adapters/DatabaseApproverRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ public function testGetApproverCategoriesReturnsEmptyArrayForNonexistentUser():
$this->assertSame( [], $repository->getApproverCategories( 404 ) );
}

public function testGetAllCategories(): void {
$repository = $this->newRepository();

$repository->setApproverCategories( 1, [ 'Category1', 'Category2' ] );

$this->assertSame(
[ 'Category1', 'Category2' ],
$repository->getAllCategories(),
'getAllCategories should return all unique categories across all approvers'
);
}

public function testSetAndGetApproverCategories(): void {
$repository = $this->newRepository();
$userId = 1;
Expand Down
4 changes: 3 additions & 1 deletion tests/Application/UseCases/ApprovalUiQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace ProfessionalWiki\PageApprovals\Tests\Application\UseCases;

use ProfessionalWiki\PageApprovals\Adapters\InMemoryApprovalLog;
use ProfessionalWiki\PageApprovals\Adapters\InMemoryApproverRepository;
use ProfessionalWiki\PageApprovals\Application\UseCases\ApprovalUiQuery\ApprovalUiQuery;
use ProfessionalWiki\PageApprovals\Tests\PageApprovalsIntegrationTest;
use ProfessionalWiki\PageApprovals\Tests\TestDoubles\SucceedingApprovalAuthorizer;
Expand Down Expand Up @@ -39,7 +40,8 @@ public function testPageWithNoApprovals(): void {
private function newApprovalUiQuery(): ApprovalUiQuery {
return new ApprovalUiQuery(
new InMemoryApprovalLog(),
new SucceedingApprovalAuthorizer()
new SucceedingApprovalAuthorizer(),
new InMemoryApproverRepository()
);
}

Expand Down
49 changes: 35 additions & 14 deletions tests/EntryPoints/PageApprovalsHooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,54 @@
use ProfessionalWiki\PageApprovals\EntryPoints\PageApprovalsHooks;
use ProfessionalWiki\PageApprovals\Tests\PageApprovalsIntegrationTest;
use RequestContext;
use Title;
use ProfessionalWiki\PageApprovals\PageApprovals;
use ParserOutput;
use WikiPage;

/**
* @group Database
* @covers \ProfessionalWiki\PageApprovals\EntryPoints\PageApprovalsHooks
*/
class PageApprovalsHooksTest extends PageApprovalsIntegrationTest {

public function testOnOutputPageBeforeHTML() {
$title = Title::newFromText( 'PageApprovalsIntegrationTest' );
$this->insertPage( $title );
private OutputPage $out;

$context = new RequestContext();
$context->setTitle( $title );
$context->setUser( $this->getTestUser()->getUser() );
protected function setUp(): void {
parent::setUp();
$this->tablesUsed[] = 'approver_config';

$out = new OutputPage( $context );
$out->setTitle( $title );
$out->setArticleFlag( true );
$out->setRevisionId( $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )->getLatest() );
$page = $this->createPageWithText( 'Test page content' );

PageApprovalsHooks::onOutputPageBeforeHTML( $out );
$this->out = new OutputPage( new RequestContext() );
$this->out->setTitle( $page->getTitle() );
$this->out->setArticleFlag( true );
$this->out->setRevisionId( $page->getLatest() );
}

public function testOnOutputPageBeforeHTMLUiIsNotShown() {
PageApprovalsHooks::onOutputPageBeforeHTML( $this->out );

$this->assertStringNotContainsString(
'page-approval-container',
$this->out->getHTML(),
'The page approval status should not be displayed without a matching category.'
);
}

public function testOnOutputPageBeforeHTMLUiIsShown() {
$parserOutput = new ParserOutput( 'Test page content' );
$parserOutput->addCategory( 'ApprovalCategory', 'ApprovalCategory' );
$this->out->addParserOutput( $parserOutput );

$approverRepository = PageApprovals::getInstance()->getApproverRepository();
$approverRepository->setApproverCategories( 1, [ 'ApprovalCategory' ] );

PageApprovalsHooks::onOutputPageBeforeHTML( $this->out );

$this->assertStringContainsString(
'page-approval-container',
$out->getHTML(),
'The page approval status should be displayed.'
$this->out->getHTML(),
'The page approval status should be displayed with a matching category.'
);
}

Expand Down
Loading