Skip to content

Commit 59e451f

Browse files
committed
Skip placeholder emails from example domains in review checks
Filters out example.com, example.org, example.net, test.com, and localhost when extracting support emails from READMEs to avoid false positives from code snippets and templates.
1 parent 844964d commit 59e451f

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

app/Jobs/ReviewPluginRepository.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,16 @@ protected function checkDirectoryHasFiles(array $tree, string $prefix): bool
202202

203203
protected function extractEmail(string $content): ?string
204204
{
205-
if (preg_match('/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/', $content, $matches)) {
206-
return $matches[0];
205+
$excludedDomains = ['example.com', 'example.org', 'example.net', 'test.com', 'localhost'];
206+
207+
if (preg_match_all('/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/', $content, $matches)) {
208+
foreach ($matches[0] as $email) {
209+
$domain = strtolower(substr($email, strpos($email, '@') + 1));
210+
211+
if (! in_array($domain, $excludedDomains, true)) {
212+
return $email;
213+
}
214+
}
207215
}
208216

209217
return null;

tests/Feature/Jobs/ReviewPluginRepositoryTest.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ public function it_extracts_email_from_readme(): void
9797
'repository_url' => 'https://github.com/acme/email-plugin',
9898
]);
9999

100-
Http::fake($this->fakeGitHub('acme/email-plugin', readme: "# Plugin\n\nFor support contact help@example.com"));
100+
Http::fake($this->fakeGitHub('acme/email-plugin', readme: "# Plugin\n\nFor support contact help@acmeplugins.com"));
101101

102102
$checks = (new ReviewPluginRepository($plugin))->handle();
103103

104104
$this->assertTrue($checks['has_support_email']);
105-
$this->assertEquals('help@example.com', $checks['support_email']);
105+
$this->assertEquals('help@acmeplugins.com', $checks['support_email']);
106106
}
107107

108108
/** @test */
@@ -120,6 +120,21 @@ public function it_reports_missing_email_when_readme_has_none(): void
120120
$this->assertNull($checks['support_email']);
121121
}
122122

123+
/** @test */
124+
public function it_skips_placeholder_emails_from_example_domains(): void
125+
{
126+
$plugin = Plugin::factory()->create([
127+
'repository_url' => 'https://github.com/acme/placeholder-plugin',
128+
]);
129+
130+
Http::fake($this->fakeGitHub('acme/placeholder-plugin', readme: "# Plugin\n\nEmail: john@example.com\nReal support: support@realdomain.io"));
131+
132+
$checks = (new ReviewPluginRepository($plugin))->handle();
133+
134+
$this->assertTrue($checks['has_support_email']);
135+
$this->assertEquals('support@realdomain.io', $checks['support_email']);
136+
}
137+
123138
/** @test */
124139
public function it_detects_nativephp_mobile_dependency(): void
125140
{
@@ -162,7 +177,7 @@ public function it_stores_results_in_review_checks_and_stamps_reviewed_at(): voi
162177

163178
Http::fake($this->fakeGitHub('acme/store-plugin',
164179
tree: [['path' => 'resources/ios/Bridge.swift', 'type' => 'blob']],
165-
readme: 'Support: dev@example.com',
180+
readme: 'Support: dev@storeplugin.io',
166181
composerRequire: ['nativephp/mobile' => '^3.0.0'],
167182
));
168183

@@ -178,7 +193,7 @@ public function it_stores_results_in_review_checks_and_stamps_reviewed_at(): voi
178193
$this->assertTrue($plugin->review_checks['supports_ios']);
179194
$this->assertFalse($plugin->review_checks['supports_android']);
180195
$this->assertTrue($plugin->review_checks['has_support_email']);
181-
$this->assertEquals('dev@example.com', $plugin->review_checks['support_email']);
196+
$this->assertEquals('dev@storeplugin.io', $plugin->review_checks['support_email']);
182197
$this->assertTrue($plugin->review_checks['requires_mobile_sdk']);
183198
}
184199

0 commit comments

Comments
 (0)