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(FileAction): add file action support #608

Merged
merged 1 commit into from Apr 4, 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
212 changes: 212 additions & 0 deletions __tests__/fileAction.spec.ts
@@ -0,0 +1,212 @@
import { getFileActions, registerFileAction, FileAction } from '../lib/fileAction'
import logger from '../lib/utils/logger';

declare global {
interface Window {
OC: any;
_nc_fileactions: FileAction[] | undefined;
}
}

describe('FileActions init', () => {

beforeEach(() => {
delete window._nc_fileactions
})

test('Getting empty uninitialized FileActions', () => {
logger.debug = jest.fn()
const fileActions = getFileActions()
expect(window._nc_fileactions).toBeUndefined()
expect(fileActions).toHaveLength(0)
expect(logger.debug).toHaveBeenCalledTimes(0)
})

test('Initializing FileActions', () => {
logger.debug = jest.fn()
const action = new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
})

expect(action.id).toBe('test')
expect(action.displayName([], {})).toBe('Test')
expect(action.iconSvgInline([], {})).toBe('<svg></svg>')

registerFileAction(action)

expect(window._nc_fileactions).toHaveLength(1)
expect(getFileActions()).toHaveLength(1)
expect(getFileActions()[0]).toStrictEqual(action)
expect(logger.debug).toHaveBeenCalled()
})

test('Duplicate FileAction gets rejected', () => {
logger.error = jest.fn()
const action = new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
})

registerFileAction(action)
expect(getFileActions()).toHaveLength(1)
expect(getFileActions()[0]).toStrictEqual(action)

const action2 = new FileAction({
id: 'test',
displayName: () => 'Test 2',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
})

registerFileAction(action2)
expect(getFileActions()).toHaveLength(1)
expect(getFileActions()[0]).toStrictEqual(action)
expect(logger.error).toHaveBeenCalledWith('FileAction test already registered', { action: action2 })
})
})

describe('Invalid FileAction creation', () => {
test('Invalid id', () => {
expect(() => {
new FileAction({
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
} as any as FileAction)
}).toThrowError('Invalid id')
})
test('Invalid displayName', () => {
expect(() => {
new FileAction({
id: 'test',
displayName: 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
} as any as FileAction)
}).toThrowError('Invalid displayName function')
})
test('Invalid iconSvgInline', () => {
expect(() => {
new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: '<svg></svg>',
exec: async () => true,
} as any as FileAction)
}).toThrowError('Invalid iconSvgInline function')
})
test('Invalid exec', () => {
expect(() => {
new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: false,
} as any as FileAction)
}).toThrowError('Invalid exec function')
})
test('Invalid enabled', () => {
expect(() => {
new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
enabled: false,
} as any as FileAction)
}).toThrowError('Invalid enabled function')
})
test('Invalid execBatch', () => {
expect(() => {
new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
execBatch: false,
} as any as FileAction)
}).toThrowError('Invalid execBatch function')
})
test('Invalid order', () => {
expect(() => {
new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
order: 'invalid',
} as any as FileAction)
}).toThrowError('Invalid order')
})
test('Invalid default', () => {
expect(() => {
new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
default: 'invalid',
} as any as FileAction)
}).toThrowError('Invalid default')
})
test('Invalid inline', () => {
expect(() => {
new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
inline: true,
} as any as FileAction)
}).toThrowError('Invalid inline function')

expect(() => {
new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
inline: () => true,
renderInline: false
} as any as FileAction)
}).toThrowError('Invalid renderInline function')
})
})

describe('FileActions creation', () => {
test('create valid FileAction', async () => {
logger.debug = jest.fn()
const action = new FileAction({
id: 'test',
displayName: () => 'Test',
iconSvgInline: () => '<svg></svg>',
exec: async () => true,
execBatch: async () => [true],
enabled: () => true,
order: 100,
default: true,
inline: () => true,
renderInline() {
const span = document.createElement('span')
span.textContent = 'test'
return span
},
})

expect(action.id).toBe('test')
expect(action.displayName([], {})).toBe('Test')
expect(action.iconSvgInline([], {})).toBe('<svg></svg>')
await expect(action.exec({} as any, {})).resolves.toBe(true)
await expect(action.execBatch?.([], {})).resolves.toStrictEqual([true])
expect(action.enabled?.({} as any, {})).toBe(true)
expect(action.order).toBe(100)
expect(action.default).toBe(true)
expect(action.inline?.({} as any, {})).toBe(true)
expect(action.renderInline?.({} as any, {}).outerHTML).toBe('<span>test</span>')
})
})
23 changes: 23 additions & 0 deletions __tests__/files/node.spec.ts
Expand Up @@ -29,6 +29,29 @@ describe('Node testing', () => {
})
})

describe('FileId attribute', () => {
test('FileId null fallback', () => {
const file = new File({
source: 'https://cloud.domain.com/remote.php/dav/picture.jpg',
mime: 'image/jpeg',
owner: 'emma'
})
expect(file.fileid).toBeUndefined()
})

test('FileId source ending slash', () => {
const file = new Folder({
source: 'https://cloud.domain.com/remote.php/dav/files/emma/Photos/',
mime: 'image/jpeg',
owner: 'emma',
attributes: {
fileid: 1234
}
})
expect(file.fileid).toBe(1234)
})
})

describe('Sanity checks', () => {
test('Invalid id', () => {
expect(() => new File({
Expand Down
19 changes: 17 additions & 2 deletions __tests__/index.spec.ts
Expand Up @@ -15,13 +15,13 @@ import { File as FileSource } from '../lib/files/file'
import { Folder as FolderSource } from '../lib/files/folder'
import { Permission as PermissionSource } from '../lib/permissions'
import { FileType as FileTypeSource } from '../lib/files/fileType'

import { Entry, NewFileMenu } from '../lib/newFileMenu';
import { FileAction, registerFileAction, getFileActions } from '../lib/fileAction'

declare global {
interface Window {
OC: any;
_nc_newfilemenu: NewFileMenu;
_nc_newfilemenu: NewFileMenu | undefined;
}
}

Expand Down Expand Up @@ -75,6 +75,21 @@ describe('Exports checks', () => {
expect(Node).toBeTruthy()
expect(typeof Node).toBe('function')
})

test('FileAction', () => {
expect(FileAction).toBeTruthy()
expect(typeof FileAction).toBe('function')
})

test('registerFileAction', () => {
expect(registerFileAction).toBeTruthy()
expect(typeof Node).toBe('function')
})

test('getFileActions', () => {
expect(getFileActions).toBeTruthy()
expect(typeof Node).toBe('function')
})
})


Expand Down
2 changes: 1 addition & 1 deletion __tests__/newFileMenu.spec.ts
Expand Up @@ -4,7 +4,7 @@ import logger from '../lib/utils/logger';
declare global {
interface Window {
OC: any;
_nc_newfilemenu: NewFileMenu;
_nc_newfilemenu: NewFileMenu | undefined;
}
}

Expand Down