Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions cypress/e2e/mixins/audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
*/

import { randHash } from '../../utils'
import { randHash } from '../../utils/index.js'
const randUser = randHash()

/**
Expand All @@ -29,7 +29,7 @@ const randUser = randHash()
* @param {string} fileName the audio to upload and test against
* @param {string} mimeType the audio mime type
*/
export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') {
export default function(fileName = 'audio.ogg', mimeType = 'audio/ogg') {
before(function() {
// Init user
cy.nextcloudCreateUser(randUser)
Expand All @@ -49,12 +49,16 @@ export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') {
.should('contain', fileName)
})

it('Open the viewer on file click', function() {
it('Open the viewer on file click and wait for loading to end', function() {
// Match audio request
cy.intercept('GET', `/remote.php/dav/files/${randUser}/${fileName}`).as('source')

// Open the file and check Viewer existence
cy.openFile(fileName)
cy.get('body > .viewer').should('be.visible')
})

it('Does not see a loading animation', function() {
// Make sure loading is finished
cy.wait('@source').its('response.statusCode').should('eq', 206)
cy.get('body > .viewer', { timeout: 10000 })
.should('be.visible')
.and('have.class', 'modal-mask')
Expand Down
19 changes: 15 additions & 4 deletions cypress/e2e/mixins/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const randUser = randHash()
* @param {string} source the optional custom source to check against
*/
export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg', source = null) {
let fileId
before(function() {
// Init user
cy.nextcloudCreateUser(randUser)
Expand All @@ -48,14 +49,24 @@ export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg', source

cy.get(`.files-fileList tr[data-file="${fileName}"]`, { timeout: 10000 })
.should('contain', fileName)
.then(row => {
fileId = row[0].dataset.id
})
})

it('Open the viewer on file click', function() {
it('Open the viewer on file click and wait for loading to end', function() {
// Match image request
const matchRoute = source
? `/remote.php/dav/files/*/${fileName}`
: `/index.php/core/preview*fileId=${fileId}*`
cy.intercept('GET', matchRoute).as('image')

// Open the file and check Viewer existence
cy.openFile(fileName)
cy.get('body > .viewer').should('be.visible')
})

it('Does not see a loading animation', function() {
// Make sure loading is finished
cy.wait('@image').its('response.statusCode').should('eq', 200)
cy.get('body > .viewer', { timeout: 10000 })
.should('be.visible')
.and('have.class', 'modal-mask')
Expand All @@ -73,7 +84,7 @@ export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg', source
cy.get('body > .viewer button.next').should('not.be.visible')
})

it('The image source is the preview url', function() {
it(`The image source is the ${source ? 'remote' : 'preview'} url`, function() {
cy.get('body > .viewer .modal-container img.viewer__file.viewer__file--active')
.should('have.attr', 'src')
.and('contain', source ?? '/index.php/core/preview')
Expand Down
28 changes: 23 additions & 5 deletions cypress/e2e/mixins/oddname.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ import { randHash } from '../../utils/'
/**
* Make a name aimed to break the viewer in case of escaping errors
*
* @param {String} realName
* @returns {String} a name for the file to be uploaded as
* @param {string} realName the file original name
* @return {string} a name for the file to be uploaded as
*/
function naughtyFileName(realName) {
const ext = realName.split('.').pop()
return (
'~⛰️ shot of a ${big} mountain`, '
'~⛰️ shot of a $[big} mountain`, '
+ "realy #1's "
+ '" #_+="%2520%27%22%60%25%21%23 was this called '
+ realName
Expand All @@ -50,7 +50,7 @@ Cypress.on('fail', (error, runnable) => {
throw error // throw error to have test still fail
})

export default function(file, type) {
export default function(file, type, sidebar = false) {
const placedName = naughtyFileName(file)

// We'll escape all the characters in the name to match it with css
Expand All @@ -62,7 +62,7 @@ export default function(file, type) {
const folderName
= 'Nextcloud "%27%22%60%25%21%23" >`⛰️<' + file + "><` e*'rocks!#?#%~"

describe(`Open ${file} in viewer with a naughty name`, function() {
describe(`Open ${file} in viewer with a naughty name ${sidebar ? 'with sidebar' : ''}`, function() {
before(function() {
// fail fast
if (failsLeft < 0) {
Expand Down Expand Up @@ -119,6 +119,24 @@ export default function(file, type) {
it('See the menu icon and title on the viewer header', menuOk)
it('Does not see navigation arrows', arrowsOK)

if (sidebar) {
it('Open the sidebar', function() {
// open the menu
cy.get('body > .viewer .modal-header button.action-item__menutoggle').click()
// open the sidebar
cy.get('.action-button__icon.icon-menu-sidebar').click()
cy.get('aside.app-sidebar').should('be.visible')
// we hide the sidebar button if opened
cy.get('.action-button__icon.icon-menu-sidebar').should('not.exist')
// check the sidebar is opened for the correct file
cy.get('aside.app-sidebar .app-sidebar-header .app-sidebar-header__maintitle').should('contain', placedName)
// check we do not have a preview
cy.get('aside.app-sidebar .app-sidebar-header').should('have.class', 'app-sidebar-header--with-figure')
cy.get('aside.app-sidebar .app-sidebar-header').should('have.class', 'app-sidebar-header--compact')
cy.get('aside.app-sidebar .app-sidebar-header .app-sidebar-header__figure').should('have.attr', 'style').should('contain', 'core/filetypes')
})
}

it('Share the folder with a share link and access the share link', function() {
cy.createLinkShare(folderName).then((token) => {
cy.logout()
Expand Down
14 changes: 9 additions & 5 deletions cypress/e2e/mixins/video.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
*/

import { randHash } from '../../utils'
import { randHash } from '../../utils/index.js'
const randUser = randHash()

/**
Expand All @@ -29,7 +29,7 @@ const randUser = randHash()
* @param {string} fileName the video to upload and test against
* @param {string} mimeType the video mime type
*/
export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') {
export default function(fileName = 'video1.mp4', mimeType = 'video/mp4') {
before(function() {
// Init user
cy.nextcloudCreateUser(randUser)
Expand All @@ -49,12 +49,16 @@ export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') {
.should('contain', fileName)
})

it('Open the viewer on file click', function() {
it('Open the viewer on file click and wait for loading to end', function() {
// Match audio request
cy.intercept('GET', `/remote.php/dav/files/${randUser}/${fileName}`).as('source')

// Open the file and check Viewer existence
cy.openFile(fileName)
cy.get('body > .viewer').should('be.visible')
})

it('Does not see a loading animation', function() {
// Make sure loading is finished
cy.wait('@source').its('response.statusCode').should('eq', 206)
cy.get('body > .viewer', { timeout: 10000 })
.should('be.visible')
.and('have.class', 'modal-mask')
Expand Down
3 changes: 3 additions & 0 deletions cypress/e2e/oddname/oddname-sidebar.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import runTest from '../mixins/oddname.js'

runTest('image.png', 'image/png', true)
4 changes: 2 additions & 2 deletions js/viewer-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/viewer-main.js.map

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"@types/dockerode": "^3.3.12",
"@vue/tsconfig": "^0.1.3",
"babel-loader-exclude-node-modules-except": "^1.2.1",
"cypress": "^10.10.0",
"cypress": "^10.11.0",
"cypress-visual-regression": "^1.7.0",
"dockerode": "^3.3.4",
"eslint-plugin-cypress": "^2.12.1",
Expand Down
5 changes: 3 additions & 2 deletions src/mixins/PreviewUrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { encodePath } from '@nextcloud/paths'
import { generateUrl } from '@nextcloud/router'
import { getToken, isPublic } from '../utils/davUtils.js'
import { encodeFilePath, getDavPath } from '../utils/fileUtils.js'
import { getDavPath } from '../utils/fileUtils.js'

export default {
computed: {
Expand Down Expand Up @@ -73,7 +74,7 @@ export default {
if (hasPreview) {
// TODO: find a nicer standard way of doing this?
if (isPublic()) {
return generateUrl(`/apps/files_sharing/publicpreview/${getToken()}?file=${encodeFilePath(filename)}&${searchParams}`)
return generateUrl(`/apps/files_sharing/publicpreview/${getToken()}?file=${encodePath(filename)}&${searchParams}`)
}
return generateUrl(`/core/preview?${searchParams}`)
}
Expand Down
23 changes: 3 additions & 20 deletions src/utils/fileUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { dirname } from '@nextcloud/paths'
import { dirname, encodePath } from '@nextcloud/paths'
import { generateUrl } from '@nextcloud/router'
import camelcase from 'camelcase'

import { getRootPath, getToken, getUserRoot, isPublic } from './davUtils.js'
import { isNumber } from './numberUtil.js'

/**
* Get an url encoded path
*
* @param {string} path the full path
* @return {string} url encoded file path
*/
const encodeFilePath = function(path) {
const pathSections = (path.startsWith('/') ? path : `/${path}`).split('/')
let relativePath = ''
pathSections.forEach((section) => {
if (section !== '') {
relativePath += '/' + encodeURIComponent(section)
}
})
return relativePath
}

/**
* Extract dir and name from file path
*
Expand Down Expand Up @@ -151,7 +134,7 @@ const getDavPath = function({ filename, basename, source = '' }) {
if (filename.startsWith(prefixUser)) {
filename = filename.slice(prefixUser.length)
}
return getRootPath() + encodeFilePath(filename)
return getRootPath() + encodePath(filename)
}

export { encodeFilePath, extractFilePaths, sortCompare, genFileInfo, getDavPath }
export { extractFilePaths, sortCompare, genFileInfo, getDavPath }
3 changes: 2 additions & 1 deletion src/views/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ export default {
return this.Sidebar && this.Sidebar.file
},
sidebarOpenFilePath() {
return this.currentFile?.davPath?.split(getUserRoot())[1]
const relativePath = this.currentFile?.davPath?.split(getUserRoot())[1]
return relativePath?.split('/')?.map(decodeURIComponent)?.join('/')
},

/**
Expand Down