Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace App\Subscriber;

use App\Api\Issue\IssueApi;
use App\Event\GitHubEvent;
use App\GitHubEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* @author Ayyoub AFW-ALLAH <ayyoub.afwallah@gmail.com>
*/
class CongratulateFirstTimeMergedContributorSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly IssueApi $issueApi,
) {
}

public function onPullRequest(GitHubEvent $event): void
{
$data = $event->getData();
if ('closed' !== $data['action'] || !($data['merged'] ?? false)) {
return;
}

$association = $data['pull_request']['author_association'] ?? '';
if (!in_array($association, ['NONE', 'FIRST_TIMER', 'FIRST_TIME_CONTRIBUTOR'])) {
return;
}

$repository = $event->getRepository();
$pullRequestNumber = $data['pull_request']['number'];
$goodFirstIssueUrl = sprintf(
'https://github.com/%s/issues?q=is%%3Aissue%%20state%%3Aopen%%20label%%3A%%22Good%%20first%%20issue%%22',
$repository->getFullName()
);

$this->issueApi->commentOnIssue($repository, $pullRequestNumber, <<<TXT
Your first PR just merged. You're officially a Symfony contributor β€” welcome to the club! πŸŽ‰

Whenever you're ready for more, [good first issue]($goodFirstIssueUrl) is a great place to start. Got ideas, found a bug, or just want to help? We're always here.

Carsonbot
TXT
);

$event->setResponseData([
'pull_request' => $pullRequestNumber,
'first_time_merged_contributor' => true,
]);
}

/**
* @return array<string, string>
*/
public static function getSubscribedEvents(): array
{
return [
GitHubEvents::PULL_REQUEST => 'onPullRequest',
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

namespace App\Tests\Subscriber;

use App\Api\Issue\IssueApi;
use App\Event\GitHubEvent;
use App\GitHubEvents;
use App\Model\Repository;
use App\Subscriber\CongratulateFirstTimeMergedContributorSubscriber;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;

class CongratulateFirstTimeMergedContributorSubscriberTest extends TestCase
{
private IssueApi $issueApi;
private Repository $repository;
private EventDispatcher $dispatcher;

protected function setUp(): void
{
$this->issueApi = $this->createMock(IssueApi::class);
$this->repository = new Repository('symfony', 'symfony', null);

$this->dispatcher = new EventDispatcher();
$this->dispatcher->addSubscriber(new CongratulateFirstTimeMergedContributorSubscriber($this->issueApi));
}

public function testPostsCommentOnFirstTimeMergedContributor()
{
$this->issueApi->expects($this->once())
->method('commentOnIssue')
->with(
$this->repository,
1234,
$this->stringContains("You're officially a Symfony contributor β€” welcome to the club!")
);

$this->dispatcher->dispatch(new GitHubEvent([
'action' => 'closed',
'merged' => true,
'pull_request' => [
'number' => 1234,
'author_association' => 'FIRST_TIME_CONTRIBUTOR',
],
], $this->repository), GitHubEvents::PULL_REQUEST);
}

public function testSkipsNonMergedClosedPR()
{
$this->issueApi->expects($this->never())->method('commentOnIssue');

$this->dispatcher->dispatch(new GitHubEvent([
'action' => 'closed',
'merged' => false,
'pull_request' => [
'number' => 1234,
'author_association' => 'FIRST_TIME_CONTRIBUTOR',
],
], $this->repository), GitHubEvents::PULL_REQUEST);
}

public function testSkipsExistingContributor()
{
$this->issueApi->expects($this->never())->method('commentOnIssue');

$this->dispatcher->dispatch(new GitHubEvent([
'action' => 'closed',
'merged' => true,
'pull_request' => [
'number' => 1234,
'author_association' => 'CONTRIBUTOR',
],
], $this->repository), GitHubEvents::PULL_REQUEST);
}

public function testGoodFirstIssueLinkPointsToCorrectRepo()
{
$this->issueApi->expects($this->once())
->method('commentOnIssue')
->with(
$this->repository,
1234,
$this->stringContains('https://github.com/symfony/symfony/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22Good%20first%20issue%22')
);

$this->dispatcher->dispatch(new GitHubEvent([
'action' => 'closed',
'merged' => true,
'pull_request' => [
'number' => 1234,
'author_association' => 'FIRST_TIMER',
],
], $this->repository), GitHubEvents::PULL_REQUEST);
}
}
Loading