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

feat(files): add node status #744

Merged
merged 1 commit into from Aug 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
16 changes: 16 additions & 0 deletions __tests__/files/file.spec.ts
Expand Up @@ -3,6 +3,7 @@ import { describe, expect, test } from 'vitest'
import { File } from '../../lib/files/file'
import { FileType } from '../../lib/files/fileType'
import { Permission } from '../../lib/permissions'
import { NodeStatus } from '../../lib/files/node'

describe('File creation', () => {
test('Valid dav file', () => {
Expand All @@ -12,6 +13,7 @@ describe('File creation', () => {
owner: 'emma',
mtime: new Date(Date.UTC(2023, 0, 1, 0, 0, 0)),
crtime: new Date(Date.UTC(1990, 0, 1, 0, 0, 0)),
status: NodeStatus.NEW,
})

expect(file).toBeInstanceOf(File)
Expand All @@ -35,6 +37,7 @@ describe('File creation', () => {
expect(file.path).toBe('/picture.jpg')
expect(file.isDavRessource).toBe(true)
expect(file.permissions).toBe(Permission.NONE)
expect(file.status).toBe(NodeStatus.NEW)
})

test('Valid dav file with root', () => {
Expand Down Expand Up @@ -170,6 +173,19 @@ describe('File data change', () => {
expect(file.source).toBe('https://cloud.domain.com/remote.php/dav/files/emma/Pictures/Old/picture-old.jpg')
expect(file.root).toBe('/files/emma')
})

test('Changing status', () => {
const file = new File({
source: 'https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg',
mime: 'image/jpeg',
owner: 'emma',
root: '/files/emma',
})

expect(file.status).toBeUndefined()
file.status = NodeStatus.NEW
expect(file.status).toBe(NodeStatus.NEW)
})
})

describe('Altering attributes updates mtime', () => {
Expand Down
10 changes: 10 additions & 0 deletions __tests__/files/node.spec.ts
Expand Up @@ -4,6 +4,7 @@ import { File } from '../../lib/files/file'
import { Folder } from '../../lib/files/folder'
import { Attribute, NodeData } from '../../lib/files/nodeData'
import { Permission } from '../../lib/permissions'
import { NodeStatus } from '../../lib/files/node'

describe('Node testing', () => {
test('Root null fallback', () => {
Expand Down Expand Up @@ -195,6 +196,15 @@ describe('Sanity checks', () => {
root: '/remote.php/dav/files/emma',
})).toThrowError('The root must be relative to the service. e.g /files/emma')
})

test('Invalid status', () => {
expect(() => new File({
source: 'https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg',
mime: 'image/jpeg',
owner: 'emma',
status: 'invalid' as unknown as NodeStatus,
})).toThrowError('Status must be a valid NodeStatus')
})
})

describe('Dav service detection', () => {
Expand Down
25 changes: 25 additions & 0 deletions lib/files/node.ts
Expand Up @@ -24,6 +24,17 @@ import { Permission } from '../permissions'
import { FileType } from './fileType'
import { Attribute, NodeData, isDavRessource, validateData } from './nodeData'

export enum NodeStatus {
/** This is a new node and it doesn't exists on the filesystem yet */
NEW = 'new',
/** This node has failed and is unavailable */
FAILED = 'failed',
/** This node is currently loading or have an operation in progress */
LOADING = 'loading',
/** This node is locked and cannot be modified */
LOCKED = 'locked',
}

export abstract class Node {

private _data: NodeData
Expand Down Expand Up @@ -213,6 +224,20 @@ export abstract class Node {
return this._data?.id || this.attributes?.fileid
}

/**
* Get the node status.
*/
get status(): NodeStatus|undefined {
return this._data?.status
}

/**
* Set the node status.
*/
set status(status: NodeStatus|undefined) {
this._data.status = status
}

/**
* Move the node to a new destination
*
Expand Down
9 changes: 9 additions & 0 deletions lib/files/nodeData.ts
Expand Up @@ -22,8 +22,9 @@

import { join } from 'path'
import { Permission } from '../permissions'
import { NodeStatus } from './node'

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

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

View workflow job for this annotation

GitHub Actions / eslint

Unexpected any. Specify a different type

export interface NodeData {
/** Unique ID */
Expand Down Expand Up @@ -54,6 +55,7 @@
/** The owner UID of this node */
owner: string|null

/** The node attributes */
attributes?: Attribute

/**
Expand All @@ -62,6 +64,9 @@
* e.g. /files/emma
*/
root?: string

/** The node status */
status?: NodeStatus
}

/**
Expand Down Expand Up @@ -151,9 +156,13 @@
}

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

Check warning on line 159 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')
}
}

if (data.status && !Object.values(NodeStatus).includes(data.status)) {
throw new Error('Status must be a valid NodeStatus')
}
}
3 changes: 1 addition & 2 deletions lib/index.ts
Expand Up @@ -23,7 +23,6 @@

import { type Entry, getNewFileMenu } from './newFileMenu'
import { type Folder } from './files/folder'
import { type View } from './navigation/view'

export { formatFileSize } from './humanfilesize'
export { FileAction, getFileActions, registerFileAction, DefaultType } from './fileAction'
Expand All @@ -38,7 +37,7 @@ export * from './dav/dav'
export { FileType } from './files/fileType'
export { File } from './files/file'
export { Folder } from './files/folder'
export { Node } from './files/node'
export { Node, NodeStatus } from './files/node'

export * from './navigation/navigation'
export * from './navigation/column'
Expand Down