Skip to content

Commit 484bd07

Browse files
committed
Add behat scenarios
1 parent 4c96a7b commit 484bd07

7 files changed

Lines changed: 520 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
lint:
15+
name: Lint
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- uses: shivammathur/setup-php@v2
21+
with:
22+
php-version: '8.3'
23+
coverage: none
24+
tools: composer
25+
26+
- uses: ramsey/composer-install@v3
27+
28+
- run: composer lint
29+
30+
phpunit:
31+
name: PHPUnit - PHP ${{ matrix.php }}
32+
runs-on: ubuntu-latest
33+
strategy:
34+
fail-fast: false
35+
matrix:
36+
php: ['8.1', '8.2', '8.3', '8.4']
37+
steps:
38+
- uses: actions/checkout@v4
39+
40+
- uses: shivammathur/setup-php@v2
41+
with:
42+
php-version: ${{ matrix.php }}
43+
coverage: none
44+
tools: composer
45+
46+
- uses: ramsey/composer-install@v3
47+
48+
- run: composer phpunit
49+
50+
behat:
51+
name: Behat - PHP ${{ matrix.php }}, WP ${{ matrix.wp }}
52+
runs-on: ubuntu-latest
53+
strategy:
54+
fail-fast: false
55+
matrix:
56+
php: ['8.1', '8.3']
57+
wp: ['latest']
58+
include:
59+
- php: '8.4'
60+
wp: 'trunk'
61+
env:
62+
WP_CLI_TEST_DBROOTUSER: root
63+
WP_CLI_TEST_DBROOTPASS: root
64+
WP_CLI_TEST_DBNAME: wp_cli_test
65+
WP_CLI_TEST_DBUSER: wp_cli_test
66+
WP_CLI_TEST_DBPASS: password1
67+
WP_CLI_TEST_DBHOST: 127.0.0.1:3306
68+
steps:
69+
- uses: actions/checkout@v4
70+
71+
- uses: shivammathur/setup-php@v2
72+
with:
73+
php-version: ${{ matrix.php }}
74+
extensions: gd, imagick, mysql, zip
75+
coverage: none
76+
tools: composer
77+
78+
- uses: ramsey/composer-install@v3
79+
80+
- uses: shogo82148/actions-setup-mysql@v1
81+
with:
82+
mysql-version: '8.0'
83+
auto-start: true
84+
root-password: root
85+
user: wp_cli_test
86+
password: password1
87+
my-cnf: |
88+
default_authentication_plugin=mysql_native_password
89+
90+
- name: Prepare test database
91+
run: composer prepare-tests
92+
93+
- name: Run Behat
94+
env:
95+
WP_VERSION: ${{ matrix.wp }}
96+
run: composer behat || composer behat-rerun
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
Feature: Standard blog orphan detection
2+
3+
Detects the most common orphan sources: deleted posts leaving media
4+
files behind, and files uploaded via FTP never attached to any post.
5+
6+
Background:
7+
Given a WP install
8+
And I run `wp option update uploads_use_yearmonth_folders 0`
9+
10+
Scenario: Detects orphans from deleted attachments and FTP uploads
11+
# Create attachment records directly in the DB (no network/GD needed).
12+
When I run `wp eval 'foreach (["photo1.jpg", "photo2.jpg"] as $f) { $id = wp_insert_attachment(["post_title" => $f, "post_mime_type" => "image/jpeg", "post_status" => "inherit"], $f); update_post_meta($id, "_wp_attached_file", $f); update_post_meta($id, "_wp_attachment_metadata", ["file" => $f, "sizes" => ["thumbnail" => ["file" => str_replace(".jpg", "-150x150.jpg", $f)]]]); } echo "ok";'`
13+
Then STDOUT should contain:
14+
"""
15+
ok
16+
"""
17+
18+
# Plant files on disk for both attachments.
19+
Given a wp-content/uploads/photo1.jpg file:
20+
"""
21+
img1
22+
"""
23+
And a wp-content/uploads/photo1-150x150.jpg file:
24+
"""
25+
thumb1
26+
"""
27+
And a wp-content/uploads/photo2.jpg file:
28+
"""
29+
img2
30+
"""
31+
And a wp-content/uploads/photo2-150x150.jpg file:
32+
"""
33+
thumb2
34+
"""
35+
36+
# Delete photo2 from DB only — files stay on disk as orphans.
37+
When I run `wp eval 'global $wpdb; $id = $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta WHERE meta_key=\"_wp_attached_file\" AND meta_value=\"photo2.jpg\""); $wpdb->delete($wpdb->posts, ["ID" => $id]); $wpdb->delete($wpdb->postmeta, ["post_id" => $id]); echo "deleted $id";'`
38+
Then STDOUT should contain:
39+
"""
40+
deleted
41+
"""
42+
43+
# Plant FTP-uploaded files (never in media library).
44+
Given a wp-content/uploads/client-logo.png file:
45+
"""
46+
fake logo
47+
"""
48+
And a wp-content/uploads/ftp-upload.jpg file:
49+
"""
50+
ftp image
51+
"""
52+
53+
When I run `wp media find-orphans --format=json`
54+
Then the return code should be 0
55+
And STDOUT should be JSON containing:
56+
"""
57+
{"status":"completed"}
58+
"""
59+
# Deleted attachment files are orphans.
60+
And STDOUT should contain:
61+
"""
62+
photo2.jpg
63+
"""
64+
And STDOUT should contain:
65+
"""
66+
photo2-150x150.jpg
67+
"""
68+
# FTP uploads are orphans.
69+
And STDOUT should contain:
70+
"""
71+
ftp-upload.jpg
72+
"""
73+
And STDOUT should contain:
74+
"""
75+
client-logo.png
76+
"""
77+
# Kept attachment is NOT an orphan.
78+
And STDOUT should not contain:
79+
"""
80+
photo1.jpg
81+
"""
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
Feature: Plugin artifacts in uploads directory
2+
3+
Various plugins write files to wp-content/uploads outside the media
4+
library. Tests detecting them as orphans and excluding with --exclude-dirs.
5+
6+
Background:
7+
Given a WP install
8+
And I run `wp option update uploads_use_yearmonth_folders 0`
9+
10+
Scenario: Detects plugin artifacts as orphans with default excludes
11+
Given a wp-content/uploads/gravity_forms/1-abc/upload.pdf file:
12+
"""
13+
form submission
14+
"""
15+
And a wp-content/uploads/elementor/css/post-42.css file:
16+
"""
17+
.elementor-42 { color: red; }
18+
"""
19+
And a wp-content/uploads/woocommerce_uploads/download.zip file:
20+
"""
21+
protected file
22+
"""
23+
And a wp-content/uploads/wc-logs/fatal-2024-03-15.log file:
24+
"""
25+
error log
26+
"""
27+
And a wp-content/uploads/backwpup-abc-logs/backup.log file:
28+
"""
29+
backup log
30+
"""
31+
And a wp-content/uploads/cache/object.tmp file:
32+
"""
33+
cached data
34+
"""
35+
And a wp-content/uploads/debug.log file:
36+
"""
37+
PHP Warning
38+
"""
39+
And a wp-content/uploads/orphan.jpg file:
40+
"""
41+
real orphan
42+
"""
43+
44+
When I run `wp media find-orphans --format=json`
45+
Then the return code should be 0
46+
# All plugin artifacts are orphans (only cache/ excluded by default).
47+
And STDOUT should contain:
48+
"""
49+
upload.pdf
50+
"""
51+
And STDOUT should contain:
52+
"""
53+
post-42.css
54+
"""
55+
And STDOUT should contain:
56+
"""
57+
download.zip
58+
"""
59+
And STDOUT should contain:
60+
"""
61+
debug.log
62+
"""
63+
And STDOUT should contain:
64+
"""
65+
orphan.jpg
66+
"""
67+
# cache/ is excluded by default.
68+
And STDOUT should not contain:
69+
"""
70+
object.tmp
71+
"""
72+
73+
Scenario: Excludes multiple plugin directories
74+
Given a wp-content/uploads/gravity_forms/1-abc/upload.pdf file:
75+
"""
76+
form submission
77+
"""
78+
And a wp-content/uploads/elementor/css/post-42.css file:
79+
"""
80+
styles
81+
"""
82+
And a wp-content/uploads/woocommerce_uploads/download.zip file:
83+
"""
84+
protected file
85+
"""
86+
And a wp-content/uploads/orphan.jpg file:
87+
"""
88+
real orphan
89+
"""
90+
91+
When I run `wp media find-orphans --exclude-dirs=cache,gravity_forms,elementor,woocommerce_uploads --format=json`
92+
Then the return code should be 0
93+
# Plugin dirs excluded.
94+
And STDOUT should not contain:
95+
"""
96+
upload.pdf
97+
"""
98+
And STDOUT should not contain:
99+
"""
100+
post-42.css
101+
"""
102+
And STDOUT should not contain:
103+
"""
104+
download.zip
105+
"""
106+
# Real orphan still found.
107+
And STDOUT should contain:
108+
"""
109+
orphan.jpg
110+
"""
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
Feature: WP 5.3+ scaled images
2+
3+
WordPress 5.3+ creates -scaled versions of large images and stores
4+
the original filename in original_image metadata. Both the scaled
5+
file and the original must be tracked as known.
6+
7+
Background:
8+
Given a WP install
9+
And I run `wp option update uploads_use_yearmonth_folders 0`
10+
11+
Scenario: Tracks scaled image and original correctly
12+
# Simulate a WP 5.3+ scaled attachment:
13+
# - "big-photo-scaled.jpg" is the _wp_attached_file (what WP uses)
14+
# - "big-photo.jpg" is the original_image (full-res original)
15+
When I run `wp eval '$id = wp_insert_attachment(["post_title" => "Big Photo", "post_mime_type" => "image/jpeg", "post_status" => "inherit"], "big-photo-scaled.jpg"); update_post_meta($id, "_wp_attached_file", "big-photo-scaled.jpg"); update_post_meta($id, "_wp_attachment_metadata", ["file" => "big-photo-scaled.jpg", "original_image" => "big-photo.jpg", "sizes" => ["thumbnail" => ["file" => "big-photo-150x150.jpg"], "medium" => ["file" => "big-photo-300x225.jpg"]]]); echo "id:$id";'`
16+
Then STDOUT should contain:
17+
"""
18+
id:
19+
"""
20+
21+
# Plant all the files on disk.
22+
Given a wp-content/uploads/big-photo-scaled.jpg file:
23+
"""
24+
scaled version
25+
"""
26+
And a wp-content/uploads/big-photo.jpg file:
27+
"""
28+
original full-res
29+
"""
30+
And a wp-content/uploads/big-photo-150x150.jpg file:
31+
"""
32+
thumbnail
33+
"""
34+
And a wp-content/uploads/big-photo-300x225.jpg file:
35+
"""
36+
medium
37+
"""
38+
39+
# Plant orphans that look like a deleted scaled attachment.
40+
And a wp-content/uploads/deleted-photo-scaled.jpg file:
41+
"""
42+
orphan scaled
43+
"""
44+
And a wp-content/uploads/deleted-photo.jpg file:
45+
"""
46+
orphan original
47+
"""
48+
49+
When I run `wp media find-orphans --format=json`
50+
Then the return code should be 0
51+
# Real scaled set should NOT be orphans.
52+
And STDOUT should not contain:
53+
"""
54+
big-photo
55+
"""
56+
# Orphan scaled set should be detected.
57+
And STDOUT should contain:
58+
"""
59+
deleted-photo-scaled.jpg
60+
"""
61+
And STDOUT should contain:
62+
"""
63+
deleted-photo.jpg
64+
"""

0 commit comments

Comments
 (0)