Skip to content

Commit 3bf6a7d

Browse files
authored
Merge pull request #1234 from nextcloud-libraries/feat/edit-mime
2 parents 065a1fc + 72f1909 commit 3bf6a7d

2 files changed

Lines changed: 111 additions & 11 deletions

File tree

__tests__/files/node.spec.ts

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,49 @@ describe('FileId attribute', () => {
8181
})
8282
})
8383

84+
describe('Mime attribute', () => {
85+
test('Mime definition', () => {
86+
const file = new File({
87+
source: 'https://cloud.domain.com/remote.php/dav/picture.jpg',
88+
mime: 'image/jpeg',
89+
owner: 'emma',
90+
})
91+
expect(file.mime).toBe('image/jpeg')
92+
})
93+
94+
test('Default mime', () => {
95+
const file = new File({
96+
source: 'https://cloud.domain.com/remote.php/dav/picture.jpg',
97+
owner: 'emma',
98+
})
99+
expect(file.mime).toBe('application/octet-stream')
100+
})
101+
102+
test('Changing mime', () => {
103+
const file = new File({
104+
source: 'https://cloud.domain.com/remote.php/dav/picture.jpg',
105+
mime: 'image/jpeg',
106+
owner: 'emma',
107+
})
108+
expect(file.mime).toBe('image/jpeg')
109+
110+
file.mime = 'image/png'
111+
expect(file.mime).toBe('image/png')
112+
})
113+
114+
test('Removing mime', () => {
115+
const file = new File({
116+
source: 'https://cloud.domain.com/remote.php/dav/picture.jpg',
117+
mime: 'image/jpeg',
118+
owner: 'emma',
119+
})
120+
expect(file.mime).toBe('image/jpeg')
121+
122+
file.mime = undefined
123+
expect(file.mime).toBe('application/octet-stream')
124+
})
125+
})
126+
84127
describe('Mtime attribute', () => {
85128
test('Mtime definition', () => {
86129
const mtime = new Date()
@@ -271,9 +314,8 @@ describe('Sanity checks', () => {
271314

272315
test('Invalid source', () => {
273316
expect(() => new File({} as unknown as NodeData)).toThrowError('Missing mandatory source')
274-
expect(() => new File({
317+
expect(() => new Folder({
275318
source: 'cloud.domain.com/remote.php/dav/Photos',
276-
mime: 'image/jpeg',
277319
owner: 'emma',
278320
})).toThrowError('Invalid source')
279321
expect(() => new File({
@@ -289,27 +331,40 @@ describe('Sanity checks', () => {
289331
})
290332

291333
test('Invalid displayname', () => {
292-
expect(() => new File({
334+
expect(() => new Folder({
293335
source: 'https://cloud.domain.com/remote.php/dav/Photos',
294-
mime: 'image',
295336
displayname: true as unknown as string,
296337
owner: 'emma',
297338
})).toThrowError('Invalid displayname type')
339+
340+
const file = new Folder({
341+
source: 'https://cloud.domain.com/remote.php/dav/Photos',
342+
displayname: 'test',
343+
owner: 'emma',
344+
})
345+
// @ts-expect-error wrong type error check
346+
expect(() => { file.displayname = true }).toThrowError('Invalid displayname')
298347
})
299348

300349
test('Invalid mtime', () => {
301350
expect(() => new File({
302-
source: 'https://cloud.domain.com/remote.php/dav/Photos',
303-
mime: 'image',
351+
source: 'https://cloud.domain.com/remote.php/dav/Photos/picture.jpg',
304352
owner: 'emma',
305353
mtime: 'invalid' as unknown as Date,
306354
})).toThrowError('Invalid mtime type')
355+
356+
const file = new File({
357+
source: 'https://cloud.domain.com/remote.php/dav/Photos/picture.jpg',
358+
owner: 'emma',
359+
})
360+
// @ts-expect-error wrong type error check
361+
expect(() => { file.mtime = 'invalid' }).toThrowError('Invalid mtime type')
307362
})
308363

309364
test('Invalid crtime', () => {
310365
expect(() => new File({
311-
source: 'https://cloud.domain.com/remote.php/dav/Photos',
312-
mime: 'image',
366+
source: 'https://cloud.domain.com/remote.php/dav/Photos/picture.jpg',
367+
mime: 'image/jpeg',
313368
owner: 'emma',
314369
crtime: 'invalid' as unknown as Date,
315370
})).toThrowError('Invalid crtime type')
@@ -321,6 +376,15 @@ describe('Sanity checks', () => {
321376
mime: 'image',
322377
owner: 'emma',
323378
})).toThrowError('Missing or invalid mandatory mime')
379+
380+
const file = new File({
381+
source: 'https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg',
382+
mime: 'image/jpeg',
383+
owner: 'emma',
384+
})
385+
// @ts-expect-error wrong type error check
386+
expect(() => { file.mime = 1234 }).toThrowError('Missing or invalid mandatory mime')
387+
expect(() => { file.mime = 'image' }).toThrowError('Missing or invalid mandatory mime')
324388
})
325389

326390
test('Invalid attributes', () => {
@@ -348,6 +412,14 @@ describe('Sanity checks', () => {
348412
owner: 'emma',
349413
size: 'test' as unknown as number,
350414
})).toThrowError('Invalid size type')
415+
416+
const file = new File({
417+
source: 'https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg',
418+
mime: 'image/jpeg',
419+
owner: 'emma',
420+
})
421+
// @ts-expect-error wrong type error check
422+
expect(() => { file.size = 'test' }).toThrowError('Invalid size type')
351423
})
352424

353425
test('Invalid owner', () => {
@@ -395,6 +467,15 @@ describe('Sanity checks', () => {
395467
owner: 'emma',
396468
status: 'invalid' as unknown as NodeStatus,
397469
})).toThrowError('Status must be a valid NodeStatus')
470+
471+
const file = new File({
472+
source: 'https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg',
473+
mime: 'image/jpeg',
474+
owner: 'emma',
475+
status: NodeStatus.LOCKED,
476+
})
477+
// @ts-expect-error wrong type error check
478+
expect(() => { file.status = 'invalid' }).toThrowError('Status must be a valid NodeStatus')
398479
})
399480
})
400481

lib/files/node.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ export abstract class Node {
5959
} as ProxyHandler<Attribute>
6060

6161
constructor(data: NodeData, davService?: RegExp) {
62+
if (!data.mime) {
63+
data.mime = 'application/octet-stream'
64+
}
65+
6266
// Validate data
6367
validateData(data, davService || this._knownDavService)
6468

@@ -121,6 +125,7 @@ export abstract class Node {
121125
* Set the displayname
122126
*/
123127
set displayname(displayname: string) {
128+
validateData({ ...this._data, displayname }, this._knownDavService)
124129
this._data.displayname = displayname
125130
}
126131

@@ -167,10 +172,20 @@ export abstract class Node {
167172

168173
/**
169174
* Get the file mime
170-
* There is no setter as the mime is not meant to be changed
171175
*/
172-
get mime(): string|undefined {
173-
return this._data.mime
176+
get mime(): string {
177+
return this._data.mime || 'application/octet-stream'
178+
}
179+
180+
/**
181+
* Set the file mime
182+
* Removing the mime type will set it to `application/octet-stream`
183+
*/
184+
set mime(mime: string|undefined) {
185+
mime ??= 'application/octet-stream'
186+
187+
validateData({ ...this._data, mime }, this._knownDavService)
188+
this._data.mime = mime
174189
}
175190

176191
/**
@@ -184,6 +199,7 @@ export abstract class Node {
184199
* Set the file modification time
185200
*/
186201
set mtime(mtime: Date|undefined) {
202+
validateData({ ...this._data, mtime }, this._knownDavService)
187203
this._data.mtime = mtime
188204
}
189205

@@ -206,6 +222,7 @@ export abstract class Node {
206222
* Set the file size
207223
*/
208224
set size(size: number|undefined) {
225+
validateData({ ...this._data, size }, this._knownDavService)
209226
this.updateMtime()
210227
this._data.size = size
211228
}
@@ -237,6 +254,7 @@ export abstract class Node {
237254
* Set the file permissions
238255
*/
239256
set permissions(permissions: Permission) {
257+
validateData({ ...this._data, permissions }, this._knownDavService)
240258
this.updateMtime()
241259
this._data.permissions = permissions
242260
}
@@ -324,6 +342,7 @@ export abstract class Node {
324342
* Set the node status.
325343
*/
326344
set status(status: NodeStatus|undefined) {
345+
validateData({ ...this._data, status }, this._knownDavService)
327346
this._data.status = status
328347
}
329348

0 commit comments

Comments
 (0)