From ec7db058a104c8ea0043bb1a7c15d5605af22fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=9D=E5=8D=9C?= Date: Sat, 14 Mar 2026 21:04:53 +0000 Subject: [PATCH] test(backurl): cover query edge cases and back-first behavior --- tests/Unit/BackUrlAppendBackTest.php | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/Unit/BackUrlAppendBackTest.php diff --git a/tests/Unit/BackUrlAppendBackTest.php b/tests/Unit/BackUrlAppendBackTest.php new file mode 100644 index 0000000..e587189 --- /dev/null +++ b/tests/Unit/BackUrlAppendBackTest.php @@ -0,0 +1,63 @@ + $back]); + + return [ + 'no query' => ['/admin/site-subscriptions/2', $back, '/admin/site-subscriptions/2?' . $backQuery], + 'question mark only' => ['/admin/site-subscriptions/2?', $back, '/admin/site-subscriptions/2?' . $backQuery], + 'question mark with ampersand' => ['/admin/site-subscriptions/2?&', $back, '/admin/site-subscriptions/2?' . $backQuery], + 'has query' => ['/admin/site-subscriptions/2?order_sync_status=syncable', $back, '/admin/site-subscriptions/2?order_sync_status=syncable&' . $backQuery], + 'has query with trailing &' => ['/admin/site-subscriptions/2?order_sync_status=syncable&', $back, '/admin/site-subscriptions/2?order_sync_status=syncable&' . $backQuery], + ]; + } + + #[DataProvider('withBackCases')] + public function test_with_back_should_not_generate_question_ampersand(string $path, string $back, string $expected): void + { + $url = BackUrl::withBack($path, $back); + + $this->assertSame($expected, $url); + $this->assertStringNotContainsString('?&', $url); + } + + public function test_with_back_should_ignore_non_relative_path(): void + { + $url = BackUrl::withBack('https://example.com/a?x=1', '/admin/x'); + $this->assertSame('https://example.com/a?x=1', $url); + } + + public function test_with_back_first_should_put_back_in_front(): void + { + $back = '/admin/platform-orders/2'; + $backQuery = Arr::query(['back' => $back]); + + $url = BackUrl::withBackFirst('/admin/site-subscriptions/2?order_sync_status=syncable', $back); + + $this->assertSame('/admin/site-subscriptions/2?' . $backQuery . '&order_sync_status=syncable', $url); + } + + public function test_with_back_first_and_fragment_should_keep_fragment_whitelist(): void + { + $back = '/admin/platform-orders/2'; + $backQuery = Arr::query(['back' => $back]); + + $url = BackUrl::withBackFirstAndFragment('/admin/site-subscriptions/2?order_sync_status=syncable', $back, 'syncable-batch'); + + $this->assertSame('/admin/site-subscriptions/2?' . $backQuery . '&order_sync_status=syncable#syncable-batch', $url); + + $url2 = BackUrl::withBackFirstAndFragment('/admin/site-subscriptions/2?order_sync_status=syncable', $back, 'bad#frag'); + $this->assertSame('/admin/site-subscriptions/2?' . $backQuery . '&order_sync_status=syncable', $url2); + } +}