ima-claude 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/cli.js +1064 -0
- package/package.json +49 -0
- package/platforms/claude/adapter.ts +115 -0
- package/platforms/junie/adapter.ts +254 -0
- package/platforms/junie/agents-template.md +113 -0
- package/platforms/junie/hook-translations.md +84 -0
- package/platforms/shared/detector.ts +27 -0
- package/platforms/shared/installer.ts +202 -0
- package/platforms/shared/types.ts +78 -0
- package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
- package/plugins/ima-claude/agents/explorer.md +30 -0
- package/plugins/ima-claude/agents/implementer.md +30 -0
- package/plugins/ima-claude/agents/memory.md +42 -0
- package/plugins/ima-claude/agents/reviewer.md +53 -0
- package/plugins/ima-claude/agents/tester.md +33 -0
- package/plugins/ima-claude/agents/wp-developer.md +46 -0
- package/plugins/ima-claude/hooks/README.md +145 -0
- package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
- package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
- package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
- package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
- package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
- package/plugins/ima-claude/hooks/docs_organization.py +104 -0
- package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
- package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
- package/plugins/ima-claude/hooks/hook_logger.py +69 -0
- package/plugins/ima-claude/hooks/hooks.json +239 -0
- package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
- package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
- package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
- package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
- package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
- package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
- package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
- package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
- package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
- package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
- package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
- package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
- package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
- package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
- package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
- package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
- package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
- package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
- package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
- package/plugins/ima-claude/personalities/README.md +45 -0
- package/plugins/ima-claude/personalities/enable-40k.md +69 -0
- package/plugins/ima-claude/personalities/enable-templars.md +69 -0
- package/plugins/ima-claude/skills/.research-summary.md +340 -0
- package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
- package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
- package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
- package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
- package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
- package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
- package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
- package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
- package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
- package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
- package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
- package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
- package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
- package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
- package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
- package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
- package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
- package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
- package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
- package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
- package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
- package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
- package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
- package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
- package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
- package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
- package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
- package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
- package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
- package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
- package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
- package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
- package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
- package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
- package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
- package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
- package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
- package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
- package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
- package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
- package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
- package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
- package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
- package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
- package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
- package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
- package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
- package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
- package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
- package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
- package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
- package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
- package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
- package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
- package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
- package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
- package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
- package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
- package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
- package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
- package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
- package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
- package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
- package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
- package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
- package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
- package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
- package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
- package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
- package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
- package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
- package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
- package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
- package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
- package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
- package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
- package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
- package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
- package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
- package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
- package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
- package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
- package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
- package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
- package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
- package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
- package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
- package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
- package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
- package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
- package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
- package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
- package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
- package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
- package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
- package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
- package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
- package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# WordPress Testing Strategy
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
1. [Testing Philosophy](#testing-philosophy)
|
|
5
|
+
2. [Unit Tests (Pure Functions)](#unit-tests-pure-functions)
|
|
6
|
+
3. [Integration Tests (WordPress)](#integration-tests-wordpress)
|
|
7
|
+
4. [Minimal Mock Strategy](#minimal-mock-strategy)
|
|
8
|
+
5. [Security Testing](#security-testing)
|
|
9
|
+
6. [Test Organization](#test-organization)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Testing Philosophy
|
|
14
|
+
|
|
15
|
+
**Pure functions enable fast, comprehensive testing without WordPress.**
|
|
16
|
+
|
|
17
|
+
| Test Type | Target | Speed | WordPress Needed |
|
|
18
|
+
|-----------|--------|-------|------------------|
|
|
19
|
+
| Unit | Pure functions | <1ms each | No |
|
|
20
|
+
| Integration | WordPress wrappers | ~10ms each | Mocked |
|
|
21
|
+
| End-to-end | Full plugin | ~100ms each | Yes |
|
|
22
|
+
|
|
23
|
+
**Goal**: 95%+ coverage via unit tests, minimal integration tests.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Unit Tests (Pure Functions)
|
|
28
|
+
|
|
29
|
+
**Zero WordPress dependencies = instant execution.**
|
|
30
|
+
|
|
31
|
+
```php
|
|
32
|
+
<?php
|
|
33
|
+
use PHPUnit\Framework\TestCase;
|
|
34
|
+
use MyPlugin\BusinessLogic;
|
|
35
|
+
|
|
36
|
+
class DiscountCalculatorTest extends TestCase {
|
|
37
|
+
/**
|
|
38
|
+
* @dataProvider discountProvider
|
|
39
|
+
*/
|
|
40
|
+
public function test_calculate_discount($price, $tier, $days, $expected) {
|
|
41
|
+
$result = BusinessLogic\calculate_discount($price, $tier, $days);
|
|
42
|
+
$this->assertEquals($expected, $result);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public function discountProvider(): array {
|
|
46
|
+
return [
|
|
47
|
+
'bronze_new_member' => [100.00, 'bronze', 30, 95.00],
|
|
48
|
+
'gold_5year_member' => [100.00, 'gold', 1825, 80.00],
|
|
49
|
+
'invalid_tier' => [100.00, 'invalid', 365, 100.00],
|
|
50
|
+
'platinum_max_discount' => [100.00, 'platinum', 3650, 75.00],
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public function test_validate_tier_upgrade_valid() {
|
|
55
|
+
$result = BusinessLogic\validate_tier_upgrade('bronze', 'gold');
|
|
56
|
+
|
|
57
|
+
$this->assertTrue($result['valid']);
|
|
58
|
+
$this->assertEquals(2, $result['upgrade_levels']);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public function test_validate_tier_upgrade_invalid_downgrade() {
|
|
62
|
+
$result = BusinessLogic\validate_tier_upgrade('gold', 'bronze');
|
|
63
|
+
|
|
64
|
+
$this->assertFalse($result['valid']);
|
|
65
|
+
$this->assertStringContainsString('Cannot downgrade', $result['error']);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Integration Tests (WordPress)
|
|
73
|
+
|
|
74
|
+
**Use Brain\Monkey for minimal WordPress mocking.**
|
|
75
|
+
|
|
76
|
+
```php
|
|
77
|
+
<?php
|
|
78
|
+
use PHPUnit\Framework\TestCase;
|
|
79
|
+
use Brain\Monkey;
|
|
80
|
+
use Brain\Monkey\Functions;
|
|
81
|
+
|
|
82
|
+
class MembershipIntegrationTest extends TestCase {
|
|
83
|
+
protected function setUp(): void {
|
|
84
|
+
parent::setUp();
|
|
85
|
+
Monkey\setUp();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
protected function tearDown(): void {
|
|
89
|
+
Monkey\tearDown();
|
|
90
|
+
parent::tearDown();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public function test_upgrade_membership_with_permission() {
|
|
94
|
+
// Mock WordPress functions
|
|
95
|
+
Functions\when('current_user_can')->justReturn(true);
|
|
96
|
+
Functions\when('check_ajax_referer')->justReturn(true);
|
|
97
|
+
Functions\when('get_user_meta')->justReturn('silver');
|
|
98
|
+
Functions\expect('update_user_meta')->twice();
|
|
99
|
+
Functions\expect('wp_send_json_success')->once();
|
|
100
|
+
|
|
101
|
+
$_POST = [
|
|
102
|
+
'user_id' => '1',
|
|
103
|
+
'new_tier' => 'gold',
|
|
104
|
+
'nonce' => 'valid_nonce'
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
// Call the handler
|
|
108
|
+
do_action('wp_ajax_upgrade_membership');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public function test_upgrade_membership_without_permission() {
|
|
112
|
+
Functions\when('current_user_can')->justReturn(false);
|
|
113
|
+
Functions\expect('wp_send_json_error')->once()->with('Insufficient permissions', 403);
|
|
114
|
+
|
|
115
|
+
do_action('wp_ajax_upgrade_membership');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Minimal Mock Strategy
|
|
123
|
+
|
|
124
|
+
**Bootstrap file with minimal WordPress function definitions.**
|
|
125
|
+
|
|
126
|
+
```php
|
|
127
|
+
<?php
|
|
128
|
+
// tests/bootstrap.php
|
|
129
|
+
|
|
130
|
+
// Autoload pure functions (no WordPress)
|
|
131
|
+
require_once __DIR__ . '/../includes/functions.php';
|
|
132
|
+
|
|
133
|
+
// Minimal WordPress mocks (only when needed)
|
|
134
|
+
if (!function_exists('sanitize_email')) {
|
|
135
|
+
function sanitize_email(string $email): string {
|
|
136
|
+
return strtolower(trim($email));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (!function_exists('sanitize_text_field')) {
|
|
141
|
+
function sanitize_text_field(string $str): string {
|
|
142
|
+
return trim(strip_tags($str));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!function_exists('absint')) {
|
|
147
|
+
function absint($val): int {
|
|
148
|
+
return abs((int) $val);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!function_exists('apply_filters')) {
|
|
153
|
+
function apply_filters(string $hook, $value) {
|
|
154
|
+
return $value; // No filters in tests
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!defined('WP_DEBUG')) {
|
|
159
|
+
define('WP_DEBUG', false);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Security Testing
|
|
166
|
+
|
|
167
|
+
**Dedicated tests for security edge cases.**
|
|
168
|
+
|
|
169
|
+
```php
|
|
170
|
+
<?php
|
|
171
|
+
class SecurityTest extends TestCase {
|
|
172
|
+
/**
|
|
173
|
+
* @dataProvider xss_vectors
|
|
174
|
+
*/
|
|
175
|
+
public function test_xss_safety(string $malicious_input) {
|
|
176
|
+
$result = validate_email_domain(
|
|
177
|
+
$malicious_input,
|
|
178
|
+
['<script>alert(1)</script>.com'],
|
|
179
|
+
[]
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
$this->assertIsArray($result);
|
|
183
|
+
$this->assertFalse($result['valid']);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public function xss_vectors(): array {
|
|
187
|
+
return [
|
|
188
|
+
'script_in_user' => ['<script>alert(1)</script>@example.com'],
|
|
189
|
+
'script_in_domain' => ['user@<script>alert(1)</script>.com'],
|
|
190
|
+
'javascript_protocol' => ['javascript:alert(1)@example.com'],
|
|
191
|
+
'data_protocol' => ['data:text/html,<script>alert(1)</script>@example.com'],
|
|
192
|
+
];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @dataProvider sql_injection_vectors
|
|
197
|
+
*/
|
|
198
|
+
public function test_sql_injection_safety(string $malicious_input) {
|
|
199
|
+
// Pure functions should handle malicious input safely
|
|
200
|
+
$result = format_user_data(['name' => $malicious_input]);
|
|
201
|
+
|
|
202
|
+
// Should not throw, should sanitize
|
|
203
|
+
$this->assertIsArray($result);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
public function sql_injection_vectors(): array {
|
|
207
|
+
return [
|
|
208
|
+
'basic_injection' => ["'; DROP TABLE users; --"],
|
|
209
|
+
'union_select' => ["' UNION SELECT * FROM users --"],
|
|
210
|
+
'boolean_based' => ["' OR '1'='1"],
|
|
211
|
+
];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Test Organization
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
tests/
|
|
222
|
+
├── bootstrap.php # Minimal WordPress mocks
|
|
223
|
+
├── phpunit.xml # Configuration
|
|
224
|
+
├── unit/ # Pure function tests (FAST)
|
|
225
|
+
│ ├── DiscountCalculatorTest.php
|
|
226
|
+
│ ├── TierValidationTest.php
|
|
227
|
+
│ └── FormattingTest.php
|
|
228
|
+
├── integration/ # WordPress wrapper tests
|
|
229
|
+
│ ├── MembershipHandlerTest.php
|
|
230
|
+
│ └── ShortcodeTest.php
|
|
231
|
+
└── security/ # Security-focused tests
|
|
232
|
+
├── XSSTest.php
|
|
233
|
+
└── SQLInjectionTest.php
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### phpunit.xml
|
|
237
|
+
|
|
238
|
+
```xml
|
|
239
|
+
<?xml version="1.0"?>
|
|
240
|
+
<phpunit bootstrap="bootstrap.php">
|
|
241
|
+
<testsuites>
|
|
242
|
+
<testsuite name="unit">
|
|
243
|
+
<directory>unit</directory>
|
|
244
|
+
</testsuite>
|
|
245
|
+
<testsuite name="integration">
|
|
246
|
+
<directory>integration</directory>
|
|
247
|
+
</testsuite>
|
|
248
|
+
<testsuite name="security">
|
|
249
|
+
<directory>security</directory>
|
|
250
|
+
</testsuite>
|
|
251
|
+
</testsuites>
|
|
252
|
+
</phpunit>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Production Results (ima-espo plugin)
|
|
256
|
+
- **130 tests, 236 assertions**
|
|
257
|
+
- **<30ms total execution**
|
|
258
|
+
- **100% pure function coverage**
|
|
259
|
+
- **Zero WordPress test database needed**
|