Skip to content

Commit 24607df

Browse files
committed
clean: use eslint on oddname + use encodeFilePath
- use generateUrl to automatically encode the basename. - Properly test if the error page is not shown Signed-off-by: Robbert Gurdeep Singh <[email protected]>
1 parent 04a8ab1 commit 24607df

File tree

4 files changed

+113
-113
lines changed

4 files changed

+113
-113
lines changed

cypress/integration/oddname.spec.js

Lines changed: 107 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -21,138 +21,137 @@
2121
*
2222
*/
2323

24-
import { randHash } from "../utils/";
24+
import { randHash } from '../utils/'
2525

2626
/**
2727
* Make a name aimed to break the viewer in case of escaping errors
2828
*
29-
* @param {String} realName
29+
* @param {String} realName original name of the file
3030
* @returns {String} a name for the file to be uploaded as
3131
*/
3232
function naughtyFileName(realName) {
33-
const ext = realName.split(".").pop();
33+
const ext = realName.split('.').pop()
3434
return (
35-
"~⛰️ shot of a ${big} mountain`, " +
36-
"realy #1's " +
37-
'" #_+="%2520%27%22%60%25%21%23 was this called ' +
38-
realName +
39-
"in the" +
40-
"☁️" +
41-
"👩‍💻" +
42-
"? :* ." +
43-
ext.toUpperCase()
44-
);
35+
'~⛰️ shot of a ${big} mountain`, '
36+
+ "realy #1's "
37+
+ '" #_+="%2520%27%22%60%25%21%23 was this called '
38+
+ realName
39+
+ 'in % the'
40+
+ '☁️'
41+
+ '👩‍💻'
42+
+ '? :* .'
43+
+ ext.toUpperCase()
44+
)
4545
}
4646

47-
for (let [file, type] of [
48-
["audio.mp3", "audio/mpeg"],
49-
["audio.ogg", "audio/mpeg"],
50-
["audio.ogg", "audio/ogg"],
51-
["image1.jpg", "image/jpeg"],
52-
["image.gif", "image/gif"],
53-
["image.heic", "image/heic"],
54-
["image.png", "image/png"],
55-
["image-small.png", "image/png"],
56-
["image.svg", "image/svg"],
57-
["image.webp", "image/webp"],
58-
["video1.mp4", "video/mp4"],
59-
["video.mkv", "video/mkv"],
60-
["video.ogv", "video/ogv"],
61-
["video.webm", "video/webm"],
47+
// Make this test fail faster
48+
let failsLeft = 5
49+
Cypress.on('fail', (error, runnable) => {
50+
failsLeft--
51+
throw error // throw error to have test still fail
52+
})
53+
54+
for (const [file, type] of [
55+
['audio.mp3', 'audio/mpeg'],
56+
['audio.ogg', 'audio/mpeg'],
57+
['audio.ogg', 'audio/ogg'],
58+
['image-small.png', 'image/png'],
59+
['image.gif', 'image/gif'],
60+
['image.heic', 'image/heic'],
61+
['image.png', 'image/png'],
62+
['image.svg', 'image/svg'],
63+
['image.webp', 'image/webp'],
64+
['image1.jpg', 'image/jpeg'],
65+
['video.mkv', 'video/mkv'],
66+
['video.ogv', 'video/ogv'],
67+
['video.webm', 'video/webm'],
68+
['video1.mp4', 'video/mp4'],
6269
]) {
63-
const placedName = naughtyFileName(file);
70+
const placedName = naughtyFileName(file)
6471

6572
// We'll escape all the characters in the name to match it with css
66-
const placedNameCss = CSS.escape(placedName);
73+
const placedNameCss = CSS.escape(placedName)
6774

6875
// fresh user for each file
69-
const randUser = randHash() + "@-" + randHash(); // @ is allowed, so use it
76+
const randUser = randHash() + '@-' + randHash() // @ is allowed, so use it
7077

71-
const folderName =
72-
'Nextcloud "%27%22%60%25%21%23" >`⛰️<' + file + "><` e*'rocks!#?#%~";
78+
const folderName
79+
= 'Nextcloud "%27%22%60%25%21%23" >`⛰️<' + file + "><` e*'rocks!#?#%~"
80+
81+
describe(`Open ${file} in viewer with a naughty name`, function() {
82+
before(function() {
83+
// fail fast
84+
if (failsLeft < 0) {
85+
throw new Error('Too many previous tests failed')
86+
}
7387

74-
describe(`Open ${file} in viewer with a naughty name`, function () {
75-
before(function () {
7688
// Init user
77-
cy.nextcloudCreateUser(randUser, "password");
78-
cy.login(randUser, "password");
89+
cy.nextcloudCreateUser(randUser, 'password')
90+
cy.login(randUser, 'password')
7991

8092
// Upload test files
81-
cy.createFolder(folderName);
82-
cy.uploadFile(file, type, "/" + folderName, placedName);
83-
cy.visit("/apps/files");
93+
cy.createFolder(folderName)
94+
cy.uploadFile(file, type, '/' + folderName, placedName)
95+
cy.visit('/apps/files')
8496

8597
// wait a bit for things to be settled
86-
cy.wait(1000);
87-
cy.openFile(folderName);
88-
cy.wait(1000);
89-
});
90-
after(function () {
98+
cy.wait(1000)
99+
cy.openFile(folderName)
100+
cy.wait(1000)
101+
})
102+
after(function() {
91103
// no need to log out we do this in the test to check the public link
92-
});
93-
94-
it(`See ${file} as ${placedName} in the list`, function () {
104+
})
105+
106+
function noLoadingAnimation() {
107+
cy.get('body > .viewer', { timeout: 10000 })
108+
.should('be.visible')
109+
.and('have.class', 'modal-mask')
110+
.and('not.have.class', 'icon-loading')
111+
}
112+
113+
function menuOk() {
114+
cy.get('body > .viewer .icon-error').should('not.exist')
115+
cy.get('body > .viewer .modal-title').should('contain', placedName)
116+
cy.get('body > .viewer .modal-header button.icon-close').should(
117+
'be.visible'
118+
)
119+
}
120+
121+
function arrowsOK() {
122+
cy.get('body > .viewer a.prev').should('not.be.visible')
123+
cy.get('body > .viewer a.next').should('not.be.visible')
124+
}
125+
126+
it(`See ${file} as ${placedName} in the list`, function() {
95127
cy.get(`#fileList tr[data-file="${placedNameCss}"]`, {
96128
timeout: 10000,
97-
}).should("contain", placedName);
98-
});
99-
100-
it("Open the viewer on file click", function () {
101-
cy.openFile(placedName);
102-
cy.get("body > .viewer").should("be.visible");
103-
});
104-
105-
it("Does not see a loading animation", function () {
106-
cy.get("body > .viewer", { timeout: 10000 })
107-
.should("be.visible")
108-
.and("have.class", "modal-mask")
109-
.and("not.have.class", "icon-loading");
110-
});
111-
112-
it("See the menu icon and title on the viewer header", function () {
113-
cy.get("body > .viewer .modal-title").should("contain", placedName);
114-
cy.get(
115-
"body > .viewer .modal-header button.action-item__menutoggle"
116-
).should("be.visible");
117-
cy.get("body > .viewer .modal-header button.icon-close").should(
118-
"be.visible"
119-
);
120-
});
121-
122-
it("Does not see navigation arrows", function () {
123-
cy.get("body > .viewer a.prev").should("not.be.visible");
124-
cy.get("body > .viewer a.next").should("not.be.visible");
125-
});
126-
127-
it("Share the folder with a share link and access the share link", function () {
129+
}).should('contain', placedName)
130+
})
131+
132+
it('Open the viewer on file click', function() {
133+
cy.openFile(placedName)
134+
cy.get('body > .viewer').should('be.visible')
135+
})
136+
137+
it('Does not see a loading animation', noLoadingAnimation)
138+
it('See the menu icon and title on the viewer header', menuOk)
139+
it('Does not see navigation arrows', arrowsOK)
140+
141+
it('Share the folder with a share link and access the share link', function() {
128142
cy.createLinkShare(folderName).then((token) => {
129-
cy.logout();
130-
cy.visit(`/s/${token}`);
131-
});
132-
});
133-
134-
it("Open the viewer on file click (public)", function () {
135-
cy.openFile(placedName);
136-
cy.get("body > .viewer").should("be.visible");
137-
});
138-
139-
it("Does not see a loading animation (public)", function () {
140-
cy.get("body > .viewer", { timeout: 10000 })
141-
.should("be.visible")
142-
.and("have.class", "modal-mask")
143-
.and("not.have.class", "icon-loading");
144-
});
145-
146-
it("See the menu icon and title on the viewer header (public)", function () {
147-
cy.get("body > .viewer .modal-title").should("contain", placedName);
148-
cy.get("body > .viewer .modal-header button.icon-close").should(
149-
"be.visible"
150-
);
151-
});
152-
153-
it("Does not see navigation arrows (public)", function () {
154-
cy.get("body > .viewer a.prev").should("not.be.visible");
155-
cy.get("body > .viewer a.next").should("not.be.visible");
156-
});
157-
});
143+
cy.logout()
144+
cy.visit(`/s/${token}`)
145+
})
146+
})
147+
148+
it('Open the viewer on file click (public)', function() {
149+
cy.openFile(placedName)
150+
cy.get('body > .viewer').should('be.visible')
151+
})
152+
153+
it('Does not see a loading animation (public)', noLoadingAnimation)
154+
it('See the menu icon and title on the viewer header (public)', menuOk)
155+
it('Does not see navigation arrows (public)', arrowsOK)
156+
})
158157
}

js/viewer-main.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/viewer-main.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/utils/fileUtils.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,10 @@ const getDavPath = function({ filename, basename }) {
132132
// TODO: allow proper dav access without the need of basic auth
133133
// https://github.com/nextcloud/server/issues/19700
134134
if (isPublic()) {
135-
return generateUrl(`/s/${getToken()}/download?path=${encodeURIComponent(dirname(filename))}&files=${encodeURIComponent(basename)}`)
135+
return generateUrl(`/s/${getToken()}/download?path={dirname}&files={basename}`,
136+
{ dirname: dirname(filename), basename })
136137
}
137-
return getRootPath() + filename.split('/').map((x) => encodeURIComponent(x)).join('/')
138+
return getRootPath() + encodeFilePath(filename)
138139
}
139140

140141
export { encodeFilePath, extractFilePaths, sortCompare, genFileInfo, getDavPath }

0 commit comments

Comments
 (0)