Skip to content

Commit 9c7dac8

Browse files
committed
Add comprehensive test cases for label spacing in PR titles
Added multiple test cases to ensure labels are always concatenated without spaces between brackets. These tests verify the correct behavior in various scenarios including incremental label additions and empty titles.
1 parent 035e724 commit 9c7dac8

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

tests/Subscriber/AutoUpdateTitleWithLabelSubscriberTest.php

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,200 @@ public function testExtraBlankSpace()
129129
$this->assertSame(57753, $responseData['pull_request']);
130130
$this->assertSame('[ErrorHandler] restrict the maximum length of the X-Debug-Exception header', $responseData['new_title']);
131131
}
132+
133+
public function testMultipleLabelsWithoutSpaceBetweenBrackets()
134+
{
135+
$event = new GitHubEvent(['action' => 'labeled', 'number' => 1234, 'pull_request' => []], $this->repository);
136+
$this->pullRequestApi->method('show')->willReturn([
137+
'title' => 'Foo Bar',
138+
'labels' => [
139+
['name' => 'Platform', 'color' => 'dddddd'],
140+
['name' => 'Agent', 'color' => 'dddddd'],
141+
],
142+
]);
143+
144+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
145+
$responseData = $event->getResponseData();
146+
$this->assertCount(2, $responseData);
147+
$this->assertSame(1234, $responseData['pull_request']);
148+
$this->assertSame('[Agent][Platform] Foo Bar', $responseData['new_title']);
149+
}
150+
151+
public function testMultipleLabelsUpdateRemovesSpaceBetweenBrackets()
152+
{
153+
$event = new GitHubEvent(['action' => 'labeled', 'number' => 1234, 'pull_request' => []], $this->repository);
154+
$this->pullRequestApi->method('show')->willReturn([
155+
'title' => '[Platform] [Agent] Foo Bar', // Title already has labels with space
156+
'labels' => [
157+
['name' => 'Platform', 'color' => 'dddddd'],
158+
['name' => 'Agent', 'color' => 'dddddd'],
159+
],
160+
]);
161+
162+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
163+
$responseData = $event->getResponseData();
164+
$this->assertCount(2, $responseData);
165+
$this->assertSame(1234, $responseData['pull_request']);
166+
$this->assertSame('[Agent][Platform] Foo Bar', $responseData['new_title']);
167+
}
168+
169+
public function testAddingLabelToExistingLabeledTitle()
170+
{
171+
// Simulating when we already have [Platform] and are adding Agent label
172+
$event = new GitHubEvent(['action' => 'labeled', 'number' => 1234, 'pull_request' => []], $this->repository);
173+
$this->pullRequestApi->method('show')->willReturn([
174+
'title' => '[Platform] Foo Bar', // Title already has one label
175+
'labels' => [
176+
['name' => 'Platform', 'color' => 'dddddd'],
177+
['name' => 'Agent', 'color' => 'dddddd'], // New label added
178+
],
179+
]);
180+
181+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
182+
$responseData = $event->getResponseData();
183+
$this->assertCount(2, $responseData);
184+
$this->assertSame(1234, $responseData['pull_request']);
185+
$this->assertSame('[Agent][Platform] Foo Bar', $responseData['new_title']);
186+
}
187+
188+
public function testLabelsNotRecognizedAsValidLabels()
189+
{
190+
// This test simulates what happens when [Platform] and [Agent] are in the title
191+
// but they're NOT recognized as valid labels (wrong case or not in label list)
192+
$event = new GitHubEvent(['action' => 'labeled', 'number' => 1234, 'pull_request' => []], $this->repository);
193+
$this->pullRequestApi->method('show')->willReturn([
194+
'title' => '[Platform] [Agent] Foo Bar', // These are in title but not recognized
195+
'labels' => [
196+
['name' => 'Bug', 'color' => 'dddddd'], // Different valid label
197+
],
198+
]);
199+
200+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
201+
$responseData = $event->getResponseData();
202+
$this->assertCount(2, $responseData);
203+
$this->assertSame(1234, $responseData['pull_request']);
204+
// Since Platform and Agent are not recognized labels, they stay in the title with the space
205+
$this->assertSame('[Bug] [Platform] [Agent] Foo Bar', $responseData['new_title']);
206+
}
207+
208+
/**
209+
* This test reproduces the actual bug: when labels are attached to the PR
210+
* but are not in the repository's configured label list, they won't be
211+
* removed from the title, causing spacing issues.
212+
*/
213+
public function testBugWithLabelsNotInRepositoryLabelList()
214+
{
215+
$event = new GitHubEvent(['action' => 'labeled', 'number' => 1234, 'pull_request' => []], $this->repository);
216+
$this->pullRequestApi->method('show')->willReturn([
217+
'title' => 'Foo Bar',
218+
'labels' => [
219+
// These labels are attached to PR but not in the StaticLabelApi list
220+
['name' => 'Platform', 'color' => 'dddddd'],
221+
['name' => 'Agent', 'color' => 'dddddd'],
222+
],
223+
]);
224+
225+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
226+
$responseData = $event->getResponseData();
227+
228+
// The bug would cause this to be '[Platform] [Agent] Foo Bar'
229+
// because the labels are added with concatenation but not recognized
230+
// for removal from the title
231+
$this->assertCount(2, $responseData);
232+
$this->assertSame(1234, $responseData['pull_request']);
233+
234+
// This is what SHOULD happen (labels concatenated without spaces)
235+
$this->assertSame('[Agent][Platform] Foo Bar', $responseData['new_title']);
236+
}
237+
238+
/**
239+
* Test simulating incremental label additions as would happen with multiple webhooks
240+
*/
241+
public function testIncrementalLabelAdditions()
242+
{
243+
// Need to create a new mock for each test to avoid expectations interference
244+
$pullRequestApi1 = $this->getMockBuilder(NullPullRequestApi::class)
245+
->disableOriginalConstructor()
246+
->setMethods(['show'])
247+
->getMock();
248+
249+
$pullRequestApi1->expects($this->once())->method('show')->willReturn([
250+
'title' => 'Foo Bar',
251+
'labels' => [
252+
['name' => 'FrameworkBundle', 'color' => 'dddddd'],
253+
],
254+
]);
255+
256+
$store = $this->getMockBuilder(PersistingStoreInterface::class)->getMock();
257+
$store->method('exists')->willReturn(false);
258+
259+
$labelsApi = new StaticLabelApi();
260+
$subscriber1 = new AutoUpdateTitleWithLabelSubscriber(
261+
new LabelNameExtractor($labelsApi, new NullLogger()),
262+
$pullRequestApi1,
263+
new LockFactory($store)
264+
);
265+
266+
$dispatcher1 = new EventDispatcher();
267+
$dispatcher1->addSubscriber($subscriber1);
268+
269+
// First webhook: FrameworkBundle label added
270+
$event1 = new GitHubEvent(['action' => 'labeled', 'number' => 1234, 'pull_request' => []], $this->repository);
271+
$dispatcher1->dispatch($event1, GitHubEvents::PULL_REQUEST);
272+
$responseData1 = $event1->getResponseData();
273+
$this->assertSame('[FrameworkBundle] Foo Bar', $responseData1['new_title']);
274+
275+
// Second webhook: Console label added (title now has [FrameworkBundle] in it)
276+
$pullRequestApi2 = $this->getMockBuilder(NullPullRequestApi::class)
277+
->disableOriginalConstructor()
278+
->setMethods(['show'])
279+
->getMock();
280+
281+
$pullRequestApi2->expects($this->once())->method('show')->willReturn([
282+
'title' => '[FrameworkBundle] Foo Bar', // Title from first update
283+
'labels' => [
284+
['name' => 'FrameworkBundle', 'color' => 'dddddd'],
285+
['name' => 'Console', 'color' => 'dddddd'],
286+
],
287+
]);
288+
289+
$subscriber2 = new AutoUpdateTitleWithLabelSubscriber(
290+
new LabelNameExtractor($labelsApi, new NullLogger()),
291+
$pullRequestApi2,
292+
new LockFactory($store)
293+
);
294+
295+
$dispatcher2 = new EventDispatcher();
296+
$dispatcher2->addSubscriber($subscriber2);
297+
298+
$event2 = new GitHubEvent(['action' => 'labeled', 'number' => 1234, 'pull_request' => []], $this->repository);
299+
$dispatcher2->dispatch($event2, GitHubEvents::PULL_REQUEST);
300+
$responseData2 = $event2->getResponseData();
301+
// Should produce [Console][FrameworkBundle] without space
302+
$this->assertSame('[Console][FrameworkBundle] Foo Bar', $responseData2['new_title']);
303+
}
304+
305+
/**
306+
* Test that ensures no spaces are ever added between label brackets
307+
*/
308+
public function testNoSpacesBetweenLabelBrackets()
309+
{
310+
// Test with empty title after label removal
311+
$event = new GitHubEvent(['action' => 'labeled', 'number' => 1234, 'pull_request' => []], $this->repository);
312+
$this->pullRequestApi->method('show')->willReturn([
313+
'title' => '[Console] [FrameworkBundle]', // Only labels, no other text
314+
'labels' => [
315+
['name' => 'Console', 'color' => 'dddddd'],
316+
['name' => 'FrameworkBundle', 'color' => 'dddddd'],
317+
],
318+
]);
319+
320+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
321+
$responseData = $event->getResponseData();
322+
323+
// Should produce labels without spaces and no trailing space
324+
$this->assertCount(2, $responseData);
325+
$this->assertSame(1234, $responseData['pull_request']);
326+
$this->assertSame('[Console][FrameworkBundle]', $responseData['new_title']);
327+
}
132328
}

0 commit comments

Comments
 (0)