Skip to content

Commit 75c5438

Browse files
committed
Added tests for ViewLogsPage class
1 parent 308217a commit 75c5438

File tree

4 files changed

+237
-17
lines changed

4 files changed

+237
-17
lines changed

plugins/wpgraphql-logging/src/Admin/View/Download/DownloadLogService.php

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use League\Csv\Writer;
88
use WPGraphQL\Logging\Logger\Database\DatabaseEntity;
99
use WPGraphQL\Logging\Logger\Database\LogsRepository;
10-
use WPGraphQL\Logging\Logger\LoggerService;
1110

1211
/**
1312
* Service for handling log downloads.
@@ -62,9 +61,9 @@ public function generate_csv( int $log_id ): void {
6261
/**
6362
* Get default CSV headers.
6463
*
65-
* @param DatabaseEntity $log The log entry.
64+
* @param \WPGraphQL\Logging\Logger\Database\DatabaseEntity $log The log entry.
6665
*
67-
* @return array The default CSV headers.
66+
* @return array<string> The default CSV headers.
6867
*/
6968
public function get_headers(DatabaseEntity $log): array {
7069
$headers = [
@@ -84,19 +83,19 @@ public function get_headers(DatabaseEntity $log): array {
8483
/**
8584
* Get CSV content for a log entry.
8685
*
87-
* @param DatabaseEntity $log The log entry.
86+
* @param \WPGraphQL\Logging\Logger\Database\DatabaseEntity $log The log entry.
8887
*
89-
* @return array The CSV content for the log entry.
88+
* @return array<string> The CSV content for the log entry.
9089
*/
9190
public function get_content(DatabaseEntity $log): array {
9291
$content = [
93-
$log->get_id() ?? '',
94-
$log->get_datetime() ?? '',
95-
$log->get_level() ?? '',
96-
$log->get_level_name() ?? '',
97-
$log->get_message() ?? '',
98-
$log->get_channel() ?? '',
99-
$log->get_query() ?? '',
92+
$log->get_id(),
93+
$log->get_datetime(),
94+
$log->get_level(),
95+
$log->get_level_name(),
96+
$log->get_message(),
97+
$log->get_channel(),
98+
$log->get_query(),
10099
wp_json_encode( $log->get_context() ),
101100
wp_json_encode( $log->get_extra() ),
102101
];

plugins/wpgraphql-logging/src/Admin/ViewLogsPage.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,19 @@ public function process_filters_redirect(): void {
184184
return;
185185
}
186186

187-
$redirect_url = menu_page_url( self::ADMIN_PAGE_SLUG, false );
187+
$redirect_url = $this->get_redirect_url();
188+
189+
wp_safe_redirect( $redirect_url );
190+
exit;
191+
}
192+
193+
/**
194+
* Constructs the redirect URL with filter parameters.
195+
*
196+
* @return string The constructed redirect URL.
197+
*/
198+
public function get_redirect_url(): string {
199+
$redirect_url = menu_page_url( self::ADMIN_PAGE_SLUG, false );
188200

189201
$possible_filters = [
190202
'start_date',
@@ -205,9 +217,7 @@ public function process_filters_redirect(): void {
205217
return '' !== $value;
206218
} ), $redirect_url );
207219
$redirect_url = apply_filters( 'wpgraphql_logging_filter_redirect_url', $redirect_url, $filters );
208-
209-
wp_safe_redirect( $redirect_url );
210-
exit;
220+
return (string) $redirect_url;
211221
}
212222

213223
/**

plugins/wpgraphql-logging/src/Logger/Database/DatabaseEntity.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public function get_datetime(): string {
239239
/**
240240
* Extracts and returns the GraphQL query from the context, if available.
241241
*
242-
* @phpcs:disable SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
242+
* @phpcs:disable SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh, Generic.Metrics.CyclomaticComplexity.TooHigh
243243
*
244244
* @return string|null The GraphQL query string, or null if not available.
245245
*/
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\WPUnit\Admin\View;
6+
7+
8+
use WPGraphQL\Logging\Admin\ViewLogsPage;
9+
use WPGraphQL\Logging\Logger\Database\LogsRepository;
10+
use Codeception\TestCase\WPTestCase;
11+
use Brain\Monkey;
12+
13+
class ViewLogsPageTest extends WPTestCase {
14+
15+
16+
protected function setUp(): void {
17+
parent::setUp();
18+
19+
// Reset the singleton instance before each test
20+
$reflection = new \ReflectionClass(ViewLogsPage::class);
21+
$instance = $reflection->getProperty('instance');
22+
$instance->setAccessible(true);
23+
$instance->setValue(null);
24+
}
25+
26+
protected function tearDown(): void {
27+
parent::tearDown();
28+
29+
// Clean up singleton instance
30+
$reflection = new \ReflectionClass(ViewLogsPage::class);
31+
$instance = $reflection->getProperty('instance');
32+
$instance->setAccessible(true);
33+
$instance->setValue(null);
34+
}
35+
36+
public function set_as_admin(): void {
37+
$admin_user = $this->factory->user->create(['role' => 'administrator']);
38+
wp_set_current_user($admin_user);
39+
set_current_screen('dashboard');
40+
}
41+
42+
43+
public function test_init_returns_null_when_user_cannot_manage_options(): void {
44+
// Mock user without permissions
45+
wp_set_current_user(0);
46+
47+
$result = ViewLogsPage::init();
48+
49+
$this->assertNull($result);
50+
}
51+
52+
public function test_init_returns_same_instance_on_multiple_calls(): void {
53+
$this->set_as_admin();
54+
$instance1 = ViewLogsPage::init();
55+
$instance2 = ViewLogsPage::init();
56+
57+
$this->assertSame($instance1, $instance2);
58+
}
59+
60+
public function test_enqueue_admin_scripts_only_on_correct_page(): void {
61+
$this->set_as_admin();
62+
$instance = ViewLogsPage::init();
63+
64+
// Test with wrong hook suffix
65+
$instance->enqueue_admin_scripts('different-page');
66+
$this->assertFalse(wp_script_is('jquery-ui-datepicker', 'enqueued'));
67+
68+
// Test with correct hook suffix (simulate the page hook)
69+
$reflection = new \ReflectionClass($instance);
70+
$pageHookProperty = $reflection->getProperty('page_hook');
71+
$pageHookProperty->setAccessible(true);
72+
$pageHookProperty->setValue($instance, 'test-page-hook');
73+
74+
$instance->enqueue_admin_scripts('test-page-hook');
75+
$this->assertTrue(wp_script_is('jquery-ui-datepicker', 'enqueued'));
76+
$this->assertTrue(wp_script_is('jquery-ui-slider', 'enqueued'));
77+
}
78+
79+
public function test_get_post_value_returns_null_for_missing_key(): void {
80+
$this->set_as_admin();
81+
$instance = ViewLogsPage::init();
82+
$reflection = new \ReflectionClass($instance);
83+
$method = $reflection->getMethod('get_post_value');
84+
$method->setAccessible(true);
85+
86+
$result = $method->invoke($instance, 'nonexistent_key');
87+
88+
$this->assertNull($result);
89+
}
90+
91+
public function test_register_page() : void {
92+
$this->set_as_admin();
93+
$instance = ViewLogsPage::init();
94+
$instance->register_settings_page();
95+
96+
global $menu;
97+
$found = false;
98+
foreach ($menu as $item) {
99+
if ($item[2] === ViewLogsPage::ADMIN_PAGE_SLUG) {
100+
$found = true;
101+
break;
102+
}
103+
}
104+
105+
$this->assertTrue($found, 'Admin menu should contain the GraphQL Logs page');
106+
}
107+
108+
public function test_register_admin_page() : void {
109+
$this->set_as_admin();
110+
$instance = ViewLogsPage::init();
111+
$instance->register_settings_page();
112+
113+
// View
114+
$_REQUEST['action'] = 'view';
115+
$_GET['log'] = '123';
116+
117+
ob_start();
118+
$instance->render_admin_page();
119+
$output = ob_get_clean();
120+
$this->assertNotFalse($output);
121+
122+
// Download
123+
$_REQUEST['action'] = 'download';
124+
ob_start();
125+
$instance->render_admin_page();
126+
$output = ob_get_clean();
127+
128+
$this->assertEquals('', $output);
129+
130+
// Clean up
131+
unset($_REQUEST['action'], $_GET['log']);
132+
133+
134+
// Default
135+
ob_start();
136+
$instance->render_admin_page();
137+
$output = ob_get_clean();
138+
139+
$this->assertStringContainsString('<h1 class="wp-heading-inline">WPGraphQL Logs</h1>', $output);
140+
}
141+
142+
143+
public function test_process_page_actions_before_rendering_as_download_action() : void {
144+
$this->set_as_admin();
145+
$instance = ViewLogsPage::init();
146+
147+
// Test download action
148+
$_GET['action'] = 'download';
149+
$_GET['log'] = 'nonexistent-log-id';
150+
151+
ob_start();
152+
$this->expectException(\WPDieException::class);
153+
$this->expectExceptionMessage('Invalid log ID.');
154+
$instance->process_page_actions_before_rendering();
155+
$output = ob_get_clean();
156+
157+
}
158+
159+
160+
public function test_process_page_actions_before_rendering_as_filter_action() : void {
161+
$this->set_as_admin();
162+
$instance = ViewLogsPage::init();
163+
// Test process_filters_redirect
164+
$_GET['action'] = 'filter';
165+
$_GET['log'] = 'nonexistent-log-id';
166+
ob_start();
167+
$instance->process_page_actions_before_rendering();
168+
$output = ob_get_clean();
169+
$this->assertEquals('', $output);
170+
171+
// Clean up
172+
unset($_GET['action'], $_GET['log']);
173+
}
174+
175+
public function test_process_filters_redirect_with_invalid_nonce(): void {
176+
$this->set_as_admin();
177+
$instance = ViewLogsPage::init();
178+
179+
// Simulate POST request with invalid nonce
180+
$_POST['wpgraphql_logging_nonce'] = 'invalid_nonce';
181+
182+
ob_start();
183+
$instance->process_filters_redirect();
184+
$output = ob_get_clean();
185+
186+
$this->assertEquals('', $output);
187+
188+
// Clean up
189+
unset($_POST['wpgraphql_logging_nonce']);
190+
}
191+
192+
public function test_get_redirect_url_constructs_correct_url(): void {
193+
$this->set_as_admin();
194+
$instance = ViewLogsPage::init();
195+
196+
// Simulate POST data
197+
$_POST['start_date'] = '2025-01-01 00:00:00';
198+
$_POST['end_date'] = '2025-12-31 23:59:59';
199+
$_POST['level_filter'] = [1]; // Should not be an array
200+
$_POST['orderby'] = 'id';
201+
$_POST['order'] = 'ASC';
202+
203+
$url = $instance->get_redirect_url();
204+
$this->assertStringNotContainsString('level_filter', $url);
205+
$this->assertEquals(
206+
menu_page_url(ViewLogsPage::ADMIN_PAGE_SLUG, false) .
207+
'&start_date=2025-01-01 00:00:00&end_date=2025-12-31 23:59:59&orderby=id&order=ASC',
208+
$url
209+
);
210+
}
211+
}

0 commit comments

Comments
 (0)