Skip to content

Commit 785a70f

Browse files
committed
Added tests for Data Sanisation.
1 parent 59dbb0f commit 785a70f

File tree

10 files changed

+293
-5
lines changed

10 files changed

+293
-5
lines changed

plugins/wpgraphql-logging/src/Logger/Processors/DataSanitizationProcessor.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function __construct() {
3535
/**
3636
* Check if data sanitization is enabled.
3737
*/
38-
protected function is_enabled(): bool {
38+
public function is_enabled(): bool {
3939
$is_enabled = (bool) ( $this->config[ DataManagementTab::DATA_SANITIZATION_ENABLED ] ?? false );
4040
return apply_filters( 'wpgraphql_logging_data_sanitization_enabled', $is_enabled );
4141
}
@@ -52,7 +52,8 @@ protected function get_rules(): array {
5252
if ( 'recommended' === $method ) {
5353
return apply_filters( 'wpgraphql_logging_data_sanitization_rules', $this->get_recommended_rules() );
5454
}
55-
return apply_filters( 'wpgraphql_logging_data_sanitization_rules', $this->get_custom_rules() );
55+
56+
return apply_filters( 'wpgraphql_logging_data_sanitization_rules', $this->get_custom_rules() );
5657
}
5758

5859
/**
@@ -92,7 +93,7 @@ protected function get_custom_rules(): array {
9293

9394
$field_string = trim( $field_string );
9495
$field_list = array_filter(
95-
explode( ',', $field_string ),
96+
array_map( 'trim', explode( ',', $field_string ) ),
9697
static function ($value) {
9798
return '' !== $value;
9899
}
@@ -102,6 +103,7 @@ static function ($value) {
102103
$rules[ $field ] = $action;
103104
}
104105
}
106+
105107
return $rules;
106108
}
107109

@@ -140,8 +142,7 @@ protected function &navigate_to_parent(array &$data, array $keys): ?array {
140142
$current = &$data;
141143
foreach ( $keys as $segment ) {
142144
if ( ! is_array( $current ) || ! isset( $current[ $segment ] ) ) {
143-
$null = null;
144-
return $null;
145+
return null;
145146
}
146147
$current = &$current[ $segment ];
147148
}
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<?php
2+
3+
namespace WPGraphQL\Logging\Tests\Logger\Processors;
4+
5+
use WPGraphQL\Logging\Logger\Processors\DataSanitizationProcessor;
6+
use WPGraphQL\Logging\Admin\Settings\ConfigurationHelper;
7+
use lucatume\WPBrowser\TestCase\WPTestCase;
8+
use WPGraphQL\Logging\Admin\Settings\Fields\Tab\DataManagementTab;
9+
use Monolog\LogRecord;
10+
use Monolog\Level;
11+
use DateTimeImmutable;
12+
13+
/**
14+
* Test cases for the DataSanitizationProcessor
15+
*
16+
* @package WPGraphQL\Logging
17+
*
18+
* @since 0.0.1
19+
*/
20+
class DataSanitizationProcessorTest extends WPTestCase {
21+
22+
23+
public function create_mock_processor(array $config) : DataSanitizationProcessor {
24+
$processor = new DataSanitizationProcessor();
25+
$reflection = new \ReflectionClass($processor);
26+
$configProperty = $reflection->getProperty('config');
27+
$configProperty->setAccessible(true);
28+
$configProperty->setValue($processor, $config);
29+
return $processor;
30+
}
31+
32+
public function test_process_record_not_enabled(): void
33+
{
34+
$processor = $this->create_mock_processor(
35+
[
36+
DataManagementTab::DATA_SANITIZATION_ENABLED => false,
37+
DataManagementTab::DATA_SANITIZATION_METHOD => 'recommended',
38+
]
39+
);
40+
41+
$record = new LogRecord(
42+
new DateTimeImmutable('now'),
43+
'wpgraphql_logging',
44+
Level::Info,
45+
'Test log message',
46+
['test_field' => 'test_value'],
47+
[]
48+
);
49+
$result = $processor->__invoke($record);
50+
$this->assertSame($record, $result);
51+
}
52+
53+
54+
public function test_process_record_empty_custom_rules_no_processing(): void {
55+
56+
$processor = $this->create_mock_processor(
57+
[
58+
DataManagementTab::DATA_SANITIZATION_ENABLED => true,
59+
DataManagementTab::DATA_SANITIZATION_METHOD => 'custom',
60+
DataManagementTab::DATA_SANITIZATION_CUSTOM_FIELD_ANONYMIZE => '',
61+
DataManagementTab::DATA_SANITIZATION_CUSTOM_FIELD_REMOVE => '',
62+
DataManagementTab::DATA_SANITIZATION_CUSTOM_FIELD_TRUNCATE => ''
63+
]
64+
);
65+
66+
$record = new LogRecord(
67+
new DateTimeImmutable('now'),
68+
'wpgraphql_logging',
69+
Level::Info,
70+
'Test log message',
71+
['test_field' => 'test_value'],
72+
[]
73+
);
74+
$result = $processor->__invoke($record);
75+
$this->assertSame($record, $result);
76+
}
77+
78+
79+
public function test_process_record_process_recommended_rules(): void
80+
{
81+
$processor = $this->create_mock_processor(
82+
[
83+
DataManagementTab::DATA_SANITIZATION_ENABLED => true,
84+
DataManagementTab::DATA_SANITIZATION_METHOD => 'recommended',
85+
]
86+
);
87+
88+
$record = new LogRecord(
89+
new DateTimeImmutable('now'),
90+
'wpgraphql_logging',
91+
Level::Info,
92+
'Test log message',
93+
[
94+
'request' => [
95+
'app_context' => [
96+
'viewer' => [
97+
'data' => [
98+
'user_email' => 'sensitive_data',
99+
],
100+
'allcaps' => 'administrator',
101+
'cap_key' => 'sensitive_data',
102+
'caps' => 'sensitive_data',
103+
'safe_field' => 'safe_data'
104+
]
105+
]
106+
],
107+
'query' => 'query { posts { id } }'
108+
],
109+
[]
110+
);
111+
$result = $processor->__invoke($record);
112+
$this->assertNotSame($record, $result);
113+
114+
$data = $result->toArray();
115+
116+
$this->assertSame($data['context'], [
117+
'request' => [
118+
'app_context' => [
119+
'viewer' => [
120+
'safe_field' => 'safe_data'
121+
]
122+
]
123+
],
124+
'query' => 'query { posts { id } }'
125+
]);
126+
}
127+
128+
129+
public function test_process_record_process_custom_rules(): void
130+
{
131+
$processor = $this->create_mock_processor(
132+
[
133+
DataManagementTab::DATA_SANITIZATION_ENABLED => true,
134+
DataManagementTab::DATA_SANITIZATION_METHOD => 'custom',
135+
DataManagementTab::DATA_SANITIZATION_CUSTOM_FIELD_ANONYMIZE => 'request.app_context.viewer.user_email, request.app_context.viewer.display_name',
136+
DataManagementTab::DATA_SANITIZATION_CUSTOM_FIELD_REMOVE => 'request.app_context.viewer.allcaps, request.app_context.viewer.cap_key',
137+
DataManagementTab::DATA_SANITIZATION_CUSTOM_FIELD_TRUNCATE => 'request.app_context.viewer.caps'
138+
]
139+
);
140+
141+
$record = new LogRecord(
142+
new DateTimeImmutable('now'),
143+
'wpgraphql_logging',
144+
Level::Info,
145+
'Test log message',
146+
[
147+
'request' => [
148+
'app_context' => [
149+
'viewer' => [
150+
'display_name' => 'Sensitive Name',
151+
'user_email' => 'sensitive_data',
152+
'allcaps' => 'administrator',
153+
'cap_key' => 'sensitive_data',
154+
'caps' => 'This is a really long string that should be truncated',
155+
'safe_field' => 'safe_data'
156+
]
157+
]
158+
],
159+
'query' => 'query { posts { id } }'
160+
],
161+
[]
162+
);
163+
$result = $processor->__invoke($record);
164+
$this->assertNotSame($record, $result);
165+
166+
$data = $result->toArray();
167+
168+
$this->assertSame($data['context'], [
169+
'request' => [
170+
'app_context' => [
171+
'viewer' => [
172+
'display_name' => '***',
173+
'user_email' => '***',
174+
'caps' => 'This is a really long string that should be tru...',
175+
'safe_field' => 'safe_data',
176+
]
177+
]
178+
],
179+
'query' => 'query { posts { id } }'
180+
]);
181+
}
182+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WPGraphQL\Logging\Tests\Logging\Rules;
6+
7+
use WPGraphQL\Logging\Logger\Rules\RuleManager;
8+
use WPGraphQL\Logging\Logger\Rules\LoggingRuleInterface;
9+
use lucatume\WPBrowser\TestCase\WPTestCase;
10+
11+
/**
12+
* Test the RuleManager class.
13+
*
14+
* @package WPGraphQL\Logging
15+
*
16+
* @since 0.0.1
17+
*/
18+
class RuleManagerTest extends WPTestCase {
19+
20+
private RuleManager $rule_manager;
21+
22+
public function setUp(): void {
23+
parent::setUp();
24+
$this->rule_manager = new RuleManager();
25+
}
26+
27+
public function test_add_rule(): void {
28+
$rule = $this->createMock(LoggingRuleInterface::class);
29+
$rule->method('get_name')->willReturn('test_rule');
30+
31+
$this->rule_manager->add_rule($rule);
32+
33+
// Test that all_rules_pass works with the added rule
34+
$rule->method('passes')->willReturn(true);
35+
$this->assertTrue($this->rule_manager->all_rules_pass([]));
36+
}
37+
38+
public function test_all_rules_pass_with_no_rules(): void {
39+
$this->assertTrue($this->rule_manager->all_rules_pass([]));
40+
}
41+
42+
public function test_all_rules_pass_with_single_passing_rule(): void {
43+
$rule = $this->createMock(LoggingRuleInterface::class);
44+
$rule->method('get_name')->willReturn('passing_rule');
45+
$rule->method('passes')->willReturn(true);
46+
47+
$this->rule_manager->add_rule($rule);
48+
49+
$this->assertTrue($this->rule_manager->all_rules_pass(['key' => 'value']));
50+
}
51+
52+
public function test_all_rules_pass_with_single_failing_rule(): void {
53+
$rule = $this->createMock(LoggingRuleInterface::class);
54+
$rule->method('get_name')->willReturn('failing_rule');
55+
$rule->method('passes')->willReturn(false);
56+
57+
$this->rule_manager->add_rule($rule);
58+
59+
$this->assertFalse($this->rule_manager->all_rules_pass(['key' => 'value']));
60+
}
61+
62+
public function test_all_rules_pass_with_multiple_passing_rules(): void {
63+
$rule1 = $this->createMock(LoggingRuleInterface::class);
64+
$rule1->method('get_name')->willReturn('rule_1');
65+
$rule1->method('passes')->willReturn(true);
66+
67+
$rule2 = $this->createMock(LoggingRuleInterface::class);
68+
$rule2->method('get_name')->willReturn('rule_2');
69+
$rule2->method('passes')->willReturn(true);
70+
71+
$this->rule_manager->add_rule($rule1);
72+
$this->rule_manager->add_rule($rule2);
73+
74+
$this->assertTrue($this->rule_manager->all_rules_pass(['key' => 'value']));
75+
}
76+
77+
public function test_all_rules_pass_with_mixed_rules(): void {
78+
$passing_rule = $this->createMock(LoggingRuleInterface::class);
79+
$passing_rule->method('get_name')->willReturn('passing_rule');
80+
$passing_rule->method('passes')->willReturn(true);
81+
82+
$failing_rule = $this->createMock(LoggingRuleInterface::class);
83+
$failing_rule->method('get_name')->willReturn('failing_rule');
84+
$failing_rule->method('passes')->willReturn(false);
85+
86+
$this->rule_manager->add_rule($passing_rule);
87+
$this->rule_manager->add_rule($failing_rule);
88+
89+
$this->assertFalse($this->rule_manager->all_rules_pass(['key' => 'value']));
90+
}
91+
92+
public function test_all_rules_pass_with_query_string(): void {
93+
$rule = $this->createMock(LoggingRuleInterface::class);
94+
$rule->method('get_name')->willReturn('query_rule');
95+
$rule->expects($this->once())
96+
->method('passes')
97+
->with(['key' => 'value'], 'query { user { name } }')
98+
->willReturn(true);
99+
100+
$this->rule_manager->add_rule($rule);
101+
102+
$this->assertTrue($this->rule_manager->all_rules_pass(['key' => 'value'], 'query { user { name } }'));
103+
}
104+
105+
}

0 commit comments

Comments
 (0)