This document outlines a comprehensive testing strategy for the QDR Temporary Shared Storage plugin to ensure all components function correctly after the latest updates and refactoring.
fileid field).htaccess protection[qdr_tss_download] shortcodefileid format)Test the complete chunked upload process:
POST /upload/init):
POST /upload/chunk):
POST /upload/finalize):
fileid formatfileid, permalink, and shortcodeTest with various file types and sizes:
GET /media/{fileid}):
PUT /media/{fileid}):
DELETE /media/{fileid}):
GET /media):
/shared-file-download//shared-file-download/{fileid}[qdr_tss_download] - generic form[qdr_tss_download id="fileid"] - specific file form/shared-file-download/{fileid}.htaccess rules are workingInstall PHPUnit and Dependencies:
composer require --dev phpunit/phpunit
composer require --dev brain/monkey
composer require --dev mockery/mockery
WordPress Test Library Setup:
bash bin/install-wp-tests.sh wordpress_test root '' localhost latest
PHPUnit Configuration (phpunit.xml):
<phpunit
bootstrap="tests/bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite name="QDR Temporary Shared Storage Test Suite">
<directory prefix="test-" suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./includes/</directory>
<directory suffix=".php">./admin/</directory>
<directory suffix=".php">./public/</directory>
<directory suffix=".php">./rest-api/</directory>
</whitelist>
</filter>
</phpunit>
tests/test-db-manager.php)<?php
class TestDbManager extends WP_UnitTestCase {
private $db_manager;
public function setUp(): void {
parent::setUp();
$this->db_manager = QDR_TSS_DB_Manager::instance();
}
public function test_create_table() {
global $wpdb;
$table_name = $wpdb->prefix . QDR_TSS_PLUGIN_TABLE;
$wpdb->query("DROP TABLE IF EXISTS $table_name");
$result = $this->db_manager->create_table();
$table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name;
$this->assertTrue($table_exists);
// Test table structure
$columns = $wpdb->get_results("DESCRIBE $table_name");
$column_names = wp_list_pluck($columns, 'Field');
$this->assertContains('fileid', $column_names);
$this->assertContains('original_file_name', $column_names);
$this->assertContains('active_from', $column_names);
$this->assertContains('active_to', $column_names);
}
public function test_insert_and_get_item() {
$data = array(
'fileid' => 'test123456789',
'original_file_name' => 'test.pdf',
'description' => 'Test description',
'message' => 'Test message',
'active_from' => current_time('mysql'),
'active_to' => date('Y-m-d H:i:s', strtotime('+30 days')),
'password' => wp_hash_password('test_password'),
'reference' => 'TEST123',
'file_path' => 'test/path/test.pdf',
'file_size' => 1024
);
$item_id = $this->db_manager->insert_item($data);
$this->assertNotFalse($item_id);
$this->assertGreaterThan(0, $item_id);
// Test get by ID
$item = $this->db_manager->get_item($item_id);
$this->assertEquals($data['fileid'], $item->fileid);
$this->assertEquals($data['original_file_name'], $item->original_file_name);
// Test get by fileid
$item_by_fileid = $this->db_manager->get_item_by_fileid($data['fileid']);
$this->assertEquals($item_id, $item_by_fileid->id);
}
public function test_get_items_with_pagination() {
// Insert test data
for ($i = 1; $i <= 15; $i++) {
$this->db_manager->insert_item([
'fileid' => 'test' . $i,
'original_file_name' => "test{$i}.pdf",
'description' => "Test file {$i}",
'active_from' => current_time('mysql'),
'active_to' => date('Y-m-d H:i:s', strtotime('+30 days')),
'password' => wp_hash_password('test'),
'file_path' => "test/test{$i}.pdf",
'file_size' => 1024 * $i
]);
}
// Test pagination
$result = $this->db_manager->get_items(['per_page' => 10, 'page' => 1]);
$this->assertEquals(10, count($result['items']));
$this->assertEquals(15, $result['total']);
$this->assertEquals(2, $result['total_pages']);
// Test second page
$result = $this->db_manager->get_items(['per_page' => 10, 'page' => 2]);
$this->assertEquals(5, count($result['items']));
}
}
tests/test-file-manager.php)<?php
class TestFileManager extends WP_UnitTestCase {
private $file_manager;
public function setUp(): void {
parent::setUp();
$this->file_manager = QDR_TSS_File_Manager::instance();
}
public function test_init_file_system() {
$result = $this->file_manager->init_file_system();
$this->assertTrue($result);
$this->assertTrue(file_exists(QDR_TSS_UPLOADS_DIR));
$this->assertTrue(file_exists(QDR_TSS_UPLOADS_DIR . 'tmp/'));
$this->assertTrue(file_exists(QDR_TSS_UPLOADS_DIR . '.htaccess'));
}
public function test_generate_fileid() {
$fileid1 = $this->file_manager->generate_fileid();
$fileid2 = $this->file_manager->generate_fileid();
$this->assertNotEquals($fileid1, $fileid2);
$this->assertTrue(strlen($fileid1) > 40);
$this->assertMatchesRegularExpression('/^[a-zA-Z0-9]+$/', $fileid1);
}
public function test_chunked_upload_process() {
// Initialize upload
$upload_id = $this->file_manager->init_chunked_upload();
$this->assertNotFalse($upload_id);
// Create test chunk data
$chunk_data = 'This is test chunk data';
$temp_file = tempnam(sys_get_temp_dir(), 'test_chunk');
file_put_contents($temp_file, $chunk_data);
$file_array = [
'tmp_name' => $temp_file,
'name' => 'test_chunk',
'size' => strlen($chunk_data)
];
// Store chunk
$result = $this->file_manager->store_chunk($upload_id, 0, $file_array);
$this->assertTrue($result);
// Check all chunks (should return true for single chunk)
$all_chunks = $this->file_manager->check_all_chunks($upload_id, 1);
$this->assertTrue($all_chunks);
// Finalize upload
$final_result = $this->file_manager->finalize_chunked_upload($upload_id, 1, 'test.txt');
$this->assertIsArray($final_result);
$this->assertArrayHasKey('file_path', $final_result);
$this->assertArrayHasKey('file_size', $final_result);
// Cleanup
unlink($temp_file);
}
}
tests/test-rest-api.php)<?php
class TestRestApi extends WP_UnitTestCase {
private $server;
private $api_key;
public function setUp(): void {
parent::setUp();
global $wp_rest_server;
$this->server = $wp_rest_server = new WP_REST_Server;
do_action('rest_api_init');
// Set up API key
$settings = QDR_TSS_Settings::instance();
$this->api_key = $settings->generate_api_key();
$settings->update_setting('api_key', $this->api_key);
}
public function test_unauthorized_access() {
$request = new WP_REST_Request('GET', '/qdr-tss/v1/media');
$response = $this->server->dispatch($request);
$this->assertEquals(403, $response->get_status());
}
public function test_authorized_access() {
$request = new WP_REST_Request('GET', '/qdr-tss/v1/media');
$request->add_header('X-Api-Key', $this->api_key);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
}
public function test_upload_init() {
$request = new WP_REST_Request('POST', '/qdr-tss/v1/upload/init');
$request->add_header('X-Api-Key', $this->api_key);
$request->set_param('original_file_name', 'test.pdf');
$request->set_param('file_size', 1024);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertArrayHasKey('upload_id', $data);
$this->assertArrayHasKey('status', $data);
$this->assertEquals('initialized', $data['status']);
}
}
tests/integration/api-client-test.php)<?php
/**
* Integration test script for API client functionality
*/
class QDR_TSS_Integration_Test {
private $api_url;
private $api_key;
public function __construct($api_url, $api_key) {
$this->api_url = rtrim($api_url, '/');
$this->api_key = $api_key;
}
public function run_all_tests() {
echo "Starting QDR TSS API Integration Tests\n";
echo "=====================================\n\n";
try {
$this->test_complete_upload_workflow();
$this->test_file_management();
$this->test_error_handling();
echo "\n✅ All tests passed!\n";
} catch (Exception $e) {
echo "\n❌ Test failed: " . $e->getMessage() . "\n";
}
}
private function test_complete_upload_workflow() {
echo "Testing complete upload workflow...\n";
// Create test file
$test_content = "This is a test file for QDR TSS integration testing.";
$temp_file = tempnam(sys_get_temp_dir(), 'qdr_test');
file_put_contents($temp_file, $test_content);
try {
$result = $this->upload_file($temp_file, 'Integration Test File', 'test_password', 'INT_TEST_001');
echo " ✓ File uploaded successfully\n";
echo " ✓ File ID: {$result['fileid']}\n";
echo " ✓ Permalink: {$result['permalink']}\n";
// Store fileid for later tests
$this->test_fileid = $result['fileid'];
} finally {
unlink($temp_file);
}
}
private function test_file_management() {
echo "Testing file management operations...\n";
if (!isset($this->test_fileid)) {
throw new Exception("No test file ID available");
}
// Test get file details
$details = $this->get_file_details($this->test_fileid);
echo " ✓ Retrieved file details\n";
// Test update file
$updated = $this->update_file($this->test_fileid, [
'message' => 'Updated via integration test'
]);
echo " ✓ Updated file properties\n";
// Test delete file
$this->delete_file($this->test_fileid);
echo " ✓ Deleted file\n";
}
private function test_error_handling() {
echo "Testing error handling...\n";
// Test with invalid API key
$old_key = $this->api_key;
$this->api_key = 'invalid_key';
try {
$this->get_file_list();
throw new Exception("Should have failed with invalid API key");
} catch (Exception $e) {
if (strpos($e->getMessage(), '403') !== false) {
echo " ✓ Invalid API key properly rejected\n";
} else {
throw $e;
}
}
$this->api_key = $old_key;
// Test with non-existent file
try {
$this->get_file_details('nonexistent123');
throw new Exception("Should have failed with non-existent file");
} catch (Exception $e) {
if (strpos($e->getMessage(), '404') !== false) {
echo " ✓ Non-existent file properly handled\n";
} else {
throw $e;
}
}
}
// API helper methods...
private function upload_file($file_path, $description, $password, $reference) {
// Implementation similar to previous examples
// ... (chunked upload implementation)
}
private function get_file_details($fileid) {
// ... (implementation)
}
private function update_file($fileid, $data) {
// ... (implementation)
}
private function delete_file($fileid) {
// ... (implementation)
}
private function get_file_list() {
// ... (implementation)
}
}
// Run tests
$tester = new QDR_TSS_Integration_Test(
'https://your-test-site.com/wp-json/qdr-tss/v1',
'your-test-api-key'
);
$tester->run_all_tests();
#!/bin/bash
# Simple load test for file uploads
API_URL="https://your-test-site.com/wp-json/qdr-tss/v1"
API_KEY="your-test-api-key"
CONCURRENT_UPLOADS=5
TEST_FILE_SIZE=1048576 # 1MB
echo "Starting load test with $CONCURRENT_UPLOADS concurrent uploads"
for i in $(seq 1 $CONCURRENT_UPLOADS); do
(
# Create test file
dd if=/dev/zero of="test_file_$i.bin" bs=$TEST_FILE_SIZE count=1 2>/dev/null
# Upload file
echo "Starting upload $i"
start_time=$(date +%s)
# Your upload implementation here
# ...
end_time=$(date +%s)
duration=$((end_time - start_time))
echo "Upload $i completed in ${duration}s"
# Cleanup
rm "test_file_$i.bin"
) &
done
wait
echo "All uploads completed"
Test the admin interface across different browsers:
For each browser, test:
Before deploying to production:
./vendor/bin/phpunit)This comprehensive testing approach ensures the plugin works reliably across all components and integrates properly with WordPress and client applications.