Skip to content

Commit 1506368

Browse files
authored
fix: keep workspace ls sizes schema-safe (#612)
1 parent ee5694e commit 1506368

2 files changed

Lines changed: 111 additions & 4 deletions

File tree

inc/Workspace/WorkspaceReader.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,19 @@ public function list_directory( string $name, ?string $path = null ): array|\WP_
168168

169169
$entry_path = $target_path . '/' . $entry;
170170
$is_dir = is_dir($entry_path);
171+
$size = 0;
172+
173+
if ( ! $is_dir && is_file($entry_path) ) {
174+
$file_size = filesize($entry_path);
175+
$size = false === $file_size ? 0 : (int) $file_size;
176+
}
171177

172178
$item = array(
173179
'name' => $entry,
174180
'type' => $is_dir ? 'directory' : 'file',
181+
'size' => $size,
175182
);
176183

177-
if ( ! $is_dir ) {
178-
$item['size'] = filesize($entry_path);
179-
}
180-
181184
$items[] = $item;
182185
}
183186

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
/**
3+
* Smoke test for local workspace directory listing contract.
4+
*
5+
* Run: php tests/smoke-workspace-list-directory.php
6+
*/
7+
8+
declare( strict_types=1 );
9+
10+
namespace {
11+
$workspace_root = sys_get_temp_dir() . '/dmc-workspace-list-directory';
12+
if (! defined('ABSPATH') ) {
13+
define('ABSPATH', $workspace_root . '/site/');
14+
}
15+
if (! defined('DATAMACHINE_WORKSPACE_PATH') ) {
16+
define('DATAMACHINE_WORKSPACE_PATH', $workspace_root . '/workspace');
17+
}
18+
19+
if (! class_exists('WP_Error') ) {
20+
class WP_Error
21+
{
22+
public function __construct( private string $code, private string $message, private array $data = array() )
23+
{
24+
}
25+
26+
public function get_error_code(): string
27+
{
28+
return $this->code;
29+
}
30+
public function get_error_message(): string
31+
{
32+
return $this->message;
33+
}
34+
public function get_error_data(): array
35+
{
36+
return $this->data;
37+
}
38+
}
39+
}
40+
41+
if (! function_exists('is_wp_error') ) {
42+
function is_wp_error( $value ): bool
43+
{
44+
return $value instanceof WP_Error;
45+
}
46+
}
47+
48+
if (! function_exists('size_format') ) {
49+
function size_format( $bytes ): string
50+
{
51+
return (string) $bytes . ' B';
52+
}
53+
}
54+
55+
include __DIR__ . '/../inc/Support/PathSecurity.php';
56+
include __DIR__ . '/../inc/Workspace/Workspace.php';
57+
include __DIR__ . '/../inc/Workspace/WorkspaceReader.php';
58+
59+
use DataMachineCode\Workspace\Workspace;
60+
use DataMachineCode\Workspace\WorkspaceReader;
61+
62+
$failures = array();
63+
$total = 0;
64+
$assert = function ( string $label, bool $condition ) use ( &$failures, &$total ): void {
65+
++$total;
66+
if ($condition ) {
67+
echo " ok {$label}\n";
68+
return;
69+
}
70+
$failures[] = $label;
71+
echo " fail {$label}\n";
72+
};
73+
74+
echo "Workspace list directory - smoke\n";
75+
76+
@mkdir(DATAMACHINE_WORKSPACE_PATH . '/example/src', 0777, true);
77+
file_put_contents(DATAMACHINE_WORKSPACE_PATH . '/example/README.md', "hello\n");
78+
79+
$reader = new WorkspaceReader(new Workspace());
80+
$list = $reader->list_directory('example');
81+
82+
$entries = array();
83+
if (! is_wp_error($list) ) {
84+
foreach ( $list['entries'] as $entry ) {
85+
$entries[$entry['name']] = $entry;
86+
}
87+
}
88+
89+
$assert('list directory succeeds', ! is_wp_error($list) && true === $list['success']);
90+
$assert('directory entry includes integer size', isset($entries['src']) && 'directory' === $entries['src']['type'] && 0 === $entries['src']['size']);
91+
$assert('file entry includes integer byte size', isset($entries['README.md']) && 'file' === $entries['README.md']['type'] && 6 === $entries['README.md']['size']);
92+
$assert('every entry exposes schema-safe integer size', ! is_wp_error($list) && array_reduce($list['entries'], fn( bool $carry, array $entry ): bool => $carry && array_key_exists('size', $entry) && is_int($entry['size']), true));
93+
94+
if (! empty($failures) ) {
95+
echo "\nFAIL: " . count($failures) . " assertion(s) failed out of {$total}\n";
96+
foreach ( $failures as $failure ) {
97+
echo " - {$failure}\n";
98+
}
99+
exit(1);
100+
}
101+
102+
echo "\nOK ({$total} assertions)\n";
103+
exit(0);
104+
}

0 commit comments

Comments
 (0)