Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow undefined properties in File and Folder #683

Merged
merged 1 commit into from Jul 25, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 35 additions & 2 deletions __tests__/files/node.spec.ts
Expand Up @@ -131,7 +131,7 @@ describe('Sanity checks', () => {
mime: 'image/jpeg',
owner: 'emma',
attributes: 'test' as unknown as Attribute,
})).toThrowError('Invalid attributes format')
})).toThrowError('Invalid attributes type')
})

test('Invalid permissions', () => {
Expand Down Expand Up @@ -166,7 +166,7 @@ describe('Sanity checks', () => {
mime: 'image/jpeg',
owner: 'emma',
root: true as unknown as string,
})).toThrowError('Invalid root format')
})).toThrowError('Invalid root type')

expect(() => new File({
source: 'https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg',
Expand Down Expand Up @@ -338,3 +338,36 @@ describe('Root and paths detection', () => {
expect(file.path).toBe('/files/images/emma.jpeg')
})
})

describe('Undefined properties are allowed', () => {
test('File', () => {
expect(() => new File({
source: 'https://domain.com/files/images/emma.jpeg',
owner: 'emma',
id: undefined,
mtime: undefined,
crtime: undefined,
// Mime is optional for folders only
mime: 'image/jpeg',
size: undefined,
permissions: undefined,
attributes: undefined,
root: undefined,
})).not.toThrow()
})

test('Folder', () => {
expect(() => new Folder({
source: 'https://domain.com/files/images/',
owner: 'emma',
id: undefined,
mtime: undefined,
crtime: undefined,
mime: undefined,
size: undefined,
permissions: undefined,
attributes: undefined,
root: undefined,
})).not.toThrow()
})
})
29 changes: 16 additions & 13 deletions lib/files/nodeData.ts
Expand Up @@ -23,7 +23,7 @@
import { join } from 'path'
import { Permission } from '../permissions'

export interface Attribute { [key: string]: any }

Check warning on line 26 in lib/files/nodeData.ts

View workflow job for this annotation

GitHub Actions / eslint

Unexpected any. Specify a different type

export default interface NodeData {
/** Unique ID */
Expand All @@ -42,7 +42,7 @@
/** Creation time */
crtime?: Date

/** The mime type */
/** The mime type Optional for folders only */
mime?: string

/** The node size type */
Expand All @@ -68,11 +68,11 @@
return source.match(davService) !== null
}

/**

Check warning on line 71 in lib/files/nodeData.ts

View workflow job for this annotation

GitHub Actions / eslint

Missing JSDoc @param "data" declaration

Check warning on line 71 in lib/files/nodeData.ts

View workflow job for this annotation

GitHub Actions / eslint

Missing JSDoc @param "davService" declaration
* Validate Node construct data
*/
export const validateData = (data: NodeData, davService: RegExp) => {
if ('id' in data && (typeof data.id !== 'number' || data.id < 0)) {
if (data.id && (typeof data.id !== 'number' || data.id < 0)) {
throw new Error('Invalid id type of value')
}

Expand All @@ -91,11 +91,11 @@
throw new Error('Invalid source format, only http(s) is supported')
}

if ('mtime' in data && !(data.mtime instanceof Date)) {
if (data.mtime && !(data.mtime instanceof Date)) {
throw new Error('Invalid mtime type')
}

if ('crtime' in data && !(data.crtime instanceof Date)) {
if (data.crtime && !(data.crtime instanceof Date)) {
throw new Error('Invalid crtime type')
}

Expand All @@ -104,30 +104,33 @@
throw new Error('Missing or invalid mandatory mime')
}

if ('size' in data && typeof data.size !== 'number') {
// Allow size to be 0
if ('size' in data && typeof data.size !== 'number' && data.size !== undefined) {
throw new Error('Invalid size type')
}

if ('permissions' in data && !(
typeof data.permissions === 'number'
// Allow permissions to be 0
if ('permissions' in data
&& data.permissions !== undefined
&& !(typeof data.permissions === 'number'
&& data.permissions >= Permission.NONE
&& data.permissions <= Permission.ALL
)) {
)) {
throw new Error('Invalid permissions')
}

if ('owner' in data
if (data.owner
&& data.owner !== null
&& typeof data.owner !== 'string') {
throw new Error('Invalid owner type')
}

if ('attributes' in data && typeof data.attributes !== 'object') {
throw new Error('Invalid attributes format')
if (data.attributes && typeof data.attributes !== 'object') {
throw new Error('Invalid attributes type')
}

if ('root' in data && typeof data.root !== 'string') {
throw new Error('Invalid root format')
if (data.root && typeof data.root !== 'string') {
throw new Error('Invalid root type')
}

if (data.root && !data.root.startsWith('/')) {
Expand All @@ -139,7 +142,7 @@
}

if (data.root && isDavRessource(data.source, davService)) {
const service = data.source.match(davService)![0]

Check warning on line 145 in lib/files/nodeData.ts

View workflow job for this annotation

GitHub Actions / eslint

Forbidden non-null assertion
if (!data.source.includes(join(service, data.root))) {
throw new Error('The root must be relative to the service. e.g /files/emma')
}
Expand Down