Skip to content

Commit

Permalink
[Cypress] PHP Backend Notice com_media/Files (#44976)
Browse files Browse the repository at this point in the history
* [Cypress] PHP Backend Notice com_media/Files.cy.js

Fixing all Joomla backend PHP notices from Cypress test file `api/com_media/Files.cy.js` and doing some refactoring.

Fixed PHP notices are:
```
[Sat Feb 22 18:28:44.019593 2025] [php:notice] [pid 31:tid 31] [client 10.0.0.1:64714] PHP Notice:  exif_imagetype(): Error reading from /var/www/html/files/test-image-1.jpg! in /var/www/html/libraries/src/Helper/MediaHelper.php on line 93
[Sat Feb 22 18:28:44.022074 2025] [php:notice] [pid 31:tid 31] [client 10.0.0.1:64714] PHP Notice:  getimagesize(): Error reading from /var/www/html/files/test-image-1.jpg! in /var/www/html/libraries/src/Image/Image.php on line 177
[Sat Feb 22 18:28:44.258619 2025] [php:notice] [pid 31:tid 31] [client 10.0.0.1:64714] PHP Notice:  exif_imagetype(): Error reading from /var/www/html/files/test-dir/test-image-1-subfolder.jpg! in /var/www/html/libraries/src/Helper/MediaHelper.php on line 93
[Sat Feb 22 18:28:44.259092 2025] [php:notice] [pid 31:tid 31] [client 10.0.0.1:64714] PHP Notice:  getimagesize(): Error reading from /var/www/html/files/test-dir/test-image-1-subfolder.jpg! in /var/www/html/libraries/src/Image/Image.php on line 177
[Sat Feb 22 18:28:47.177357 2025] [php:notice] [pid 31:tid 31] [client 10.0.0.1:64714] PHP Notice:  exif_imagetype(): Error reading from /var/www/html/files/test-dir/todelete.jpg! in /var/www/html/libraries/src/Helper/MediaHelper.php on line 93
[Sat Feb 22 18:28:47.178099 2025] [php:notice] [pid 31:tid 31] [client 10.0.0.1:64714] PHP Notice:  getimagesize(): Error reading from /var/www/html/files/test-dir/todelete.jpg! in /var/www/html/libraries/src/Image/Image.php on line 177
[Sat Feb 22 18:28:47.564807 2025] [php:notice] [pid 31:tid 31] [client 10.0.0.1:64714] PHP Notice:  exif_imagetype(): Error reading from /var/www/html/images/test-dir/todelete.jpg! in /var/www/html/libraries/src/Helper/MediaHelper.php on line 93
[Sat Feb 22 18:28:47.565288 2025] [php:notice] [pid 31:tid 31] [client 10.0.0.1:64714] PHP Notice:  getimagesize(): Error reading from /var/www/html/images/test-dir/todelete.jpg! in /var/www/html/libraries/src/Image/Image.php on line 177
```

All 8 x PHP notices are fixed. Instead of using 1-Byte files real images are used from Cypress fixtures.
Please consider there are still 4 x PHP warning to be fixed (I assume they need to be fixed in PHP API backend code) from `api/com_media/Files.cy.js` and more warnings and notices in the overall Joomla System Tests.

Some refactoring:
* Deleted 3 images in `tests/System/data/com_media`, 2 are not used and Cypress default is to use `fixtures` folder
* The image file names are counted through and the images show name and path in different colors.
* Second `test-dir` was named `test-dir2` to distinguish clearly.
* `afterEach()` is reduced to `after()`, as it is only a clean-up and not needed to execute the tests.
* The last 4 tests can use the prepared files too, as with `beforeEach` the files are restored before each test.

* Corrected Image Description to test-dir2

Used command:
```
convert -size 100x100 -gravity center -pointsize 11 xc:lightgreen -fill red -annotate +0+0 'Joomla\nSystem Tests\n\nimages/test-dir2\ntest-image-3.jpg' tests/System/fixtures/com_media/test-image-3.jpg
```

* Fix for Windows Path and Read-Only Overwrites

- Creating relative fixtures folder path now also works on Windows with backslashes as separators and a drive letter
- All overwrite files are now created with explicit read-write 0o666, as the default 0o444 creates read-only files, leading to PHP Warnings `Failed to open`

---------

Co-authored-by: Allon Moritz <allon.moritz@digital-peak.com>
Co-authored-by: Robert Deutz <rdeutz@googlemail.com>
3 people authored Feb 28, 2025
1 parent 4c6bb85 commit 6af88f5
Showing 7 changed files with 46 additions and 38 deletions.
Binary file removed tests/System/data/com_media/test-image-1.jpg
Binary file not shown.
Binary file removed tests/System/data/com_media/test-image-1.png
Binary file not shown.
Binary file removed tests/System/data/com_media/test-image-2.png
Binary file not shown.
Binary file added tests/System/fixtures/com_media/test-image-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/System/fixtures/com_media/test-image-2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/System/fixtures/com_media/test-image-3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 46 additions & 38 deletions tests/System/integration/api/com_media/Files.cy.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
describe('Test that media files API endpoint', () => {
// Ensure 'test-dir' (relative to cmsPath) is available and has correct permissions
// Create relative path to the fixtures images directory, from Cypress config and platform independent
const fixturesFolder = Cypress.config('fixturesFolder').replace(/\\/g, '/');
// projectRoot is e.g. 'C:\laragon\www\joomla53\tests\System\fixtures'
const projectRoot = Cypress.config('projectRoot').replace(/\\/g, '/');
// Result is e.g. 'tests/System/fixtures/com_media'
const mediaFixturesFolder = `${fixturesFolder
.replace(projectRoot, '')
.replace(/^\//, '')}/com_media`;

// Create directories and test images before running each test
beforeEach(() => {
cy.task('writeRelativeFile', { path: 'images/test-dir/dummy.txt', content: '1' });
cy.task('writeRelativeFile', { path: 'files/test-image-1.jpg', content: '1' });
// Ensure 'files/test-dir' exists (relative to cmsPath) and has the correct permissions
cy.task('writeRelativeFile', { path: 'files/test-dir/dummy.txt', content: '1' });
cy.task('writeRelativeFile', { path: 'files/test-dir/test-image-1-subfolder.jpg', content: '1' });
});
// If it exists, delete the 'test-dir' (relative to cmsPath) and its contents
afterEach(() => {
cy.task('deleteRelativePath', 'images/test-dir');
// Ensure 'images/test-dir2' exists (relative to cmsPath) and has the correct permissions
cy.task('writeRelativeFile', { path: 'images/test-dir2/dummy.txt', content: '1' });
cy.task('copyRelativeFile', { source: `${mediaFixturesFolder}/test-image-1.jpg`, destination: 'files/test-image-1.jpg' });
cy.task('copyRelativeFile', { source: `${mediaFixturesFolder}/test-image-2.jpg`, destination: 'files/test-dir/test-image-2.jpg' });
cy.task('copyRelativeFile', { source: `${mediaFixturesFolder}/test-image-3.jpg`, destination: 'images/test-dir2/test-image-3.jpg' });
});
// Delete all files and directories created during the test, only for clean-up and only if they exist
after(() => {
cy.task('deleteRelativePath', 'files/test-dir');
cy.task('deleteRelativePath', 'images/test-dir2');
cy.task('deleteRelativePath', 'files/test-image-1.jpg');
});

@@ -23,7 +35,7 @@ describe('Test that media files API endpoint', () => {

it('can deliver a list of files in a subfolder', () => {
cy.api_get('/media/files/test-dir/')
.then((response) => cy.api_responseContains(response, 'name', 'test-image-1-subfolder.jpg'));
.then((response) => cy.api_responseContains(response, 'name', 'test-image-2.jpg'));
});

it('can deliver a list of files with an adapter', () => {
@@ -61,7 +73,7 @@ describe('Test that media files API endpoint', () => {
});

it('can create a file without adapter', () => {
cy.readFile('tests/System/data/com_media/test-image-1.jpg', 'binary')
cy.readFile('tests/System/fixtures/com_media/test-image-1.jpg', 'binary')
.then((data) => cy.api_post('/media/files', { path: 'test-dir/test.jpg', content: Buffer.from(data, 'binary').toString('base64') }))
.then((response) => {
cy.wrap(response).its('body').its('data').its('attributes')
@@ -86,33 +98,33 @@ describe('Test that media files API endpoint', () => {
});

it('can create a file with adapter', () => {
cy.readFile('tests/System/data/com_media/test-image-1.jpg', 'binary')
.then((data) => cy.api_post('/media/files', { path: 'local-images:/test-dir/test.jpg', content: Buffer.from(data, 'binary').toString('base64') }))
cy.readFile('tests/System/fixtures/com_media/test-image-2.jpg', 'binary')
.then((data) => cy.api_post('/media/files', { path: 'local-images:/test-dir2/test.jpg', content: Buffer.from(data, 'binary').toString('base64') }))
.then((response) => {
cy.wrap(response).its('body').its('data').its('attributes')
.its('name')
.should('include', 'test.jpg');
cy.wrap(response).its('body').its('data').its('attributes')
.its('path')
.should('include', 'local-images:/test-dir/test.jpg');
.should('include', 'local-images:/test-dir2/test.jpg');
});
});

it('can create a folder with adapter', () => {
cy.api_post('/media/files', { path: 'local-images:/test-dir/test-from-create' })
cy.api_post('/media/files', { path: 'local-images:/test-dir2/test-from-create' })
.then((response) => {
cy.wrap(response).its('body').its('data').its('attributes')
.its('name')
.should('include', 'test-from-create');
cy.wrap(response).its('body').its('data').its('attributes')
.its('path')
.should('include', 'local-images:/test-dir/test-from-create');
.should('include', 'local-images:/test-dir2/test-from-create');
});
});

it('can update a file without adapter', () => {
cy.task('writeRelativeFile', { path: 'files/test-dir/override.jpg', content: '1' })
.then(() => cy.readFile('tests/System/data/com_media/test-image-1.jpg', 'binary'))
cy.task('writeRelativeFile', { path: 'files/test-dir/override.jpg', content: '1', mode: 0o666 })
.then(() => cy.readFile('tests/System/fixtures/com_media/test-image-1.jpg', 'binary'))
.then((data) => cy.api_patch(
'/media/files/test-dir/override.jpg',
{ path: 'test-dir/override.jpg', content: Buffer.from(data, 'binary').toString('base64') },
@@ -127,7 +139,7 @@ describe('Test that media files API endpoint', () => {
});

it('can update a folder without adapter', () => {
cy.task('writeRelativeFile', { path: 'files/test-dir/override/test.jpg', content: '1' })
cy.task('writeRelativeFile', { path: 'files/test-dir/override/test.jpg', content: '1', mode: 0o666 })
.then(() => cy.api_patch('/media/files/test-dir/override', { path: 'test-dir/override-new' }))
.then((response) => {
cy.wrap(response).its('body').its('data').its('attributes')
@@ -140,51 +152,47 @@ describe('Test that media files API endpoint', () => {
});

it('can update a file with adapter', () => {
cy.task('writeRelativeFile', { path: 'images/test-dir/override.jpg', content: '1' })
.then(() => cy.readFile('tests/System/data/com_media/test-image-1.jpg', 'binary'))
cy.task('writeRelativeFile', { path: 'images/test-dir2/override.jpg', content: '1', mode: 0o666 })
.then(() => cy.readFile('tests/System/fixtures/com_media/test-image-2.jpg', 'binary'))
.then((data) => cy.api_patch(
'/media/files/local-images:/test-dir/override.jpg',
{ path: 'local-images:/test-dir/override.jpg', content: Buffer.from(data, 'binary').toString('base64') },
'/media/files/local-images:/test-dir2/override.jpg',
{ path: 'local-images:/test-dir2/override.jpg', content: Buffer.from(data, 'binary').toString('base64') },
)).then((response) => {
cy.wrap(response).its('body').its('data').its('attributes')
.its('name')
.should('include', 'override.jpg');
cy.wrap(response).its('body').its('data').its('attributes')
.its('path')
.should('include', 'local-images:/test-dir/override.jpg');
.should('include', 'local-images:/test-dir2/override.jpg');
});
});

it('can update a folder with adapter', () => {
cy.task('writeRelativeFile', { path: 'images/test-dir/override/test.jpg', content: '1' })
.then(() => cy.api_patch('/media/files/local-images:/test-dir/override', { path: 'local-images:/test-dir/override-new' }))
cy.task('writeRelativeFile', { path: 'images/test-dir2/override/test.jpg', content: '1', mode: 0o666 })
.then(() => cy.api_patch('/media/files/local-images:/test-dir2/override', { path: 'local-images:/test-dir2/override-new' }))
.then((response) => {
cy.wrap(response).its('body').its('data').its('attributes')
.its('name')
.should('include', 'override-new');
cy.wrap(response).its('body').its('data').its('attributes')
.its('path')
.should('include', 'local-images:/test-dir/override-new');
.should('include', 'local-images:/test-dir2/override-new');
});
});

it('can delete a file without adapter', () => {
cy.task('writeRelativeFile', { path: 'files/test-dir/todelete.jpg', content: '1' })
.then(() => cy.api_delete('/media/files/test-dir/todelete.jpg'));
it("can delete an image in 'files' without adapter", () => {
cy.api_delete('/media/files/test-dir/test-image-2.jpg');
});

it('can delete a folder without adapter', () => {
cy.task('writeRelativeFile', { path: 'files/test-dir/todelete/dummy.txt', content: '1' })
.then(() => cy.api_delete('/media/files/test-dir/todelete'));
it("can delete a folder in 'files' without adapter", () => {
cy.api_delete('/media/files/test-dir');
});

it('can delete a file with adapter', () => {
cy.task('writeRelativeFile', { path: 'images/test-dir/todelete.jpg', content: '1' })
.then(() => cy.api_delete('/media/files/local-images:/test-dir/todelete.jpg'));
it("can delete an image in 'images' with adapter", () => {
cy.api_delete('/media/files/local-images:/test-dir2/test-image-3.jpg');
});

it('can delete a folder with adapter', () => {
cy.task('writeRelativeFile', { path: 'images/test-dir/todelete/dummy.txt', content: '1' })
.then(() => cy.api_delete('/media/files/local-images:/test-dir/todelete'));
it("can delete a folder in 'images' with adapter", () => {
cy.api_delete('/media/files/local-images:/test-dir2');
});
});

0 comments on commit 6af88f5

Please sign in to comment.