Skip to content

Commit b6acc02

Browse files
Merge pull request #239 from JLG-WOCFR-DEV/codex/add-tests-for-linkscancontroller-and-others
Add Brain Monkey scanner tests
2 parents f1b67bb + 8ac05b8 commit b6acc02

File tree

4 files changed

+576
-0
lines changed

4 files changed

+576
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
namespace Tests\Scanner;
4+
5+
use Brain\Monkey\Functions;
6+
7+
final class LinkScanControllerTest extends ScannerTestCase
8+
{
9+
public function test_acquire_lock_generates_token_when_unlocked(): void
10+
{
11+
Functions\when('blc_generate_lock_token')->alias(fn() => 'lock-token');
12+
13+
$token = blc_acquire_link_scan_lock(300);
14+
15+
$this->assertSame('lock-token', $token);
16+
$this->assertSame(
17+
[
18+
'token' => 'lock-token',
19+
'locked_at' => $this->currentTime,
20+
],
21+
$this->options['blc_link_scan_lock'] ?? null,
22+
'Lock state should be stored with the generated token.'
23+
);
24+
$this->assertSame(
25+
'lock-token',
26+
$this->options['blc_link_scan_lock_token'] ?? null,
27+
'Token mirror option should be updated for watchdog checks.'
28+
);
29+
}
30+
31+
public function test_acquire_lock_returns_empty_string_when_lock_is_active(): void
32+
{
33+
$this->options['blc_link_scan_lock'] = [
34+
'token' => 'existing-token',
35+
'locked_at' => $this->currentTime,
36+
];
37+
38+
$token = blc_acquire_link_scan_lock(120);
39+
40+
$this->assertSame('', $token);
41+
$this->assertSame(
42+
'existing-token',
43+
$this->options['blc_link_scan_lock']['token'] ?? null,
44+
'Existing lock token should remain untouched when lock is active.'
45+
);
46+
$this->assertArrayNotHasKey(
47+
'blc_link_scan_lock_token',
48+
$this->options,
49+
'Mirror token option should not be overwritten when acquisition fails.'
50+
);
51+
}
52+
53+
public function test_release_lock_clears_stored_options(): void
54+
{
55+
$this->options['blc_link_scan_lock'] = [
56+
'token' => 'release-me',
57+
'locked_at' => $this->currentTime,
58+
];
59+
$this->options['blc_link_scan_lock_token'] = 'release-me';
60+
61+
blc_release_link_scan_lock('release-me');
62+
63+
$this->assertArrayNotHasKey('blc_link_scan_lock', $this->options);
64+
$this->assertArrayNotHasKey('blc_link_scan_lock_token', $this->options);
65+
}
66+
67+
public function test_perform_check_reschedules_batch_inside_rest_window(): void
68+
{
69+
$this->options['blc_rest_start_hour'] = '08';
70+
$this->options['blc_rest_end_hour'] = '20';
71+
$this->options['blc_batch_delay'] = 300;
72+
$this->options['blc_debug_mode'] = false;
73+
74+
$this->setCurrentTime(strtotime('2023-01-01 12:34:00 UTC'));
75+
76+
Functions\when('blc_acquire_link_scan_lock')->alias(fn() => 'token-123');
77+
Functions\expect('blc_release_link_scan_lock')->once()->with('token-123');
78+
Functions\when('current_filter')->alias(fn() => 'blc_check_links');
79+
80+
blc_perform_check(0, true);
81+
82+
$this->assertCount(1, $this->scheduledEvents, 'A follow-up batch should be scheduled during the rest window.');
83+
$scheduled = $this->scheduledEvents[0];
84+
$this->assertSame('blc_check_batch', $scheduled['hook']);
85+
$this->assertSame([0, true, false], $scheduled['args']);
86+
$this->assertSame(
87+
strtotime('2023-01-01 20:00:00 UTC'),
88+
$scheduled['timestamp'],
89+
'Next run should align with the configured rest window exit.'
90+
);
91+
}
92+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Tests\Scanner;
4+
5+
use Brain\Monkey\Functions;
6+
7+
final class RemoteRequestClientTest extends ScannerTestCase
8+
{
9+
public function test_get_request_timeout_constraints_merges_filter_values(): void
10+
{
11+
Functions\when('apply_filters')->alias(function ($hook, $value, ...$args) {
12+
if ($hook === 'blc_request_timeout_constraints') {
13+
return [
14+
'head' => ['default' => 8, 'min' => 2, 'max' => 12],
15+
'get' => ['default' => 15, 'min' => 5, 'max' => 45],
16+
];
17+
}
18+
19+
return $value;
20+
});
21+
22+
$constraints = blc_get_request_timeout_constraints();
23+
24+
$this->assertSame(
25+
['default' => 8.0, 'min' => 2.0, 'max' => 12.0],
26+
$constraints['head']
27+
);
28+
$this->assertSame(
29+
['default' => 15.0, 'min' => 5.0, 'max' => 45.0],
30+
$constraints['get']
31+
);
32+
}
33+
34+
public function test_normalize_timeout_option_clamps_and_parses_values(): void
35+
{
36+
$this->assertSame(4.5, blc_normalize_timeout_option('4,5', 5.0, 1.0, 10.0));
37+
$this->assertSame(1.0, blc_normalize_timeout_option('0', 5.0, 1.0, 10.0));
38+
$this->assertSame(10.0, blc_normalize_timeout_option('50', 5.0, 1.0, 10.0));
39+
$this->assertSame(5.0, blc_normalize_timeout_option('n/a', 5.0, 1.0, 10.0));
40+
}
41+
42+
public function test_is_public_ip_address_rejects_private_and_loopback_ranges(): void
43+
{
44+
$this->assertFalse(blc_is_public_ip_address('192.168.1.20'));
45+
$this->assertFalse(blc_is_public_ip_address('127.0.0.1'));
46+
$this->assertFalse(blc_is_public_ip_address('::1'));
47+
$this->assertFalse(blc_is_public_ip_address('fe80::1'));
48+
}
49+
50+
public function test_is_public_ip_address_accepts_public_addresses(): void
51+
{
52+
$this->assertTrue(blc_is_public_ip_address('93.184.216.34'));
53+
$this->assertTrue(blc_is_public_ip_address('2001:4860:4860::8888'));
54+
}
55+
56+
public function test_normalize_remote_host_lowercases_and_trims(): void
57+
{
58+
$this->assertSame('example.com', blc_normalize_remote_host(' Example.COM '));
59+
$this->assertSame('2001:db8::1', blc_normalize_remote_host('2001:DB8::1'));
60+
$this->assertSame('203.0.113.5', blc_normalize_remote_host('203.0.113.5'));
61+
}
62+
}

tests/Scanner/ScanQueueTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace Tests\Scanner;
4+
5+
use Brain\Monkey\Functions;
6+
7+
final class ScanQueueTest extends ScannerTestCase
8+
{
9+
public function test_get_scan_cache_context_reuses_existing_cache(): void
10+
{
11+
$this->options['blc_active_link_scan_key'] = 'existing-key';
12+
$transient = blc_build_scan_cache_transient_name('link', 'existing-key');
13+
$this->transients[$transient] = [
14+
'value' => ['cached' => ['foo' => 'bar']],
15+
'expiration' => 3600,
16+
];
17+
18+
$context = blc_get_scan_cache_context('link', 1);
19+
20+
$this->assertSame('existing-key', $context['key']);
21+
$this->assertSame('blc_active_link_scan_key', $context['option']);
22+
$this->assertSame(
23+
['cached' => ['foo' => 'bar']],
24+
$context['data'],
25+
'Stored scan cache should be loaded when a key is present.'
26+
);
27+
}
28+
29+
public function test_get_scan_cache_context_generates_new_key_for_first_batch(): void
30+
{
31+
$context = blc_get_scan_cache_context('link', 0);
32+
33+
$this->assertArrayHasKey('key', $context);
34+
$this->assertNotSame('', $context['key']);
35+
$this->assertSame('blc_active_link_scan_key', $context['option']);
36+
$this->assertSame(
37+
$context['key'],
38+
$this->options['blc_active_link_scan_key'] ?? '',
39+
'Fresh scan key should be persisted for subsequent batches.'
40+
);
41+
$this->assertSame([], $context['data']);
42+
}
43+
44+
public function test_save_scan_cache_persists_payload_with_filtered_expiration(): void
45+
{
46+
$context = blc_get_scan_cache_context('link', 0);
47+
$transientName = $context['transient'];
48+
49+
Functions\when('apply_filters')->alias(function ($hook, $value, ...$args) use ($context) {
50+
if ($hook === 'blc_scan_cache_expiration') {
51+
return 7200;
52+
}
53+
54+
return $value;
55+
});
56+
57+
$payload = ['items' => [1, 2, 3]];
58+
blc_save_scan_cache($context, $payload);
59+
60+
$this->assertSame($payload, $context['data']);
61+
$this->assertArrayHasKey($transientName, $this->transients);
62+
$this->assertSame($payload, $this->transients[$transientName]['value']);
63+
$this->assertSame(7200, $this->transients[$transientName]['expiration']);
64+
}
65+
66+
public function test_clear_scan_cache_removes_transient_and_active_option(): void
67+
{
68+
$context = blc_get_scan_cache_context('link', 0);
69+
blc_save_scan_cache($context, ['foo' => 'bar']);
70+
71+
blc_clear_scan_cache($context);
72+
73+
$this->assertArrayNotHasKey($context['transient'], $this->transients);
74+
$this->assertArrayNotHasKey('blc_active_link_scan_key', $this->options);
75+
}
76+
}

0 commit comments

Comments
 (0)