mirror of
https://github.com/nextcloud/server.git
synced 2026-04-23 15:21:00 -04:00
Merge pull request #38806 from nextcloud/feat/f2v/actions-1
This commit is contained in:
commit
32bbe3db81
25 changed files with 1118 additions and 291 deletions
15
.codecov.yml
15
.codecov.yml
|
|
@ -1,15 +0,0 @@
|
|||
codecov:
|
||||
branch: master
|
||||
ci:
|
||||
- drone.nextcloud.com
|
||||
- !scrutinizer-ci.com
|
||||
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: "70...100"
|
||||
status:
|
||||
project: off
|
||||
patch: off
|
||||
|
||||
comment: off
|
||||
13
.github/workflows/node-tests.yml
vendored
13
.github/workflows/node-tests.yml
vendored
|
|
@ -25,8 +25,8 @@ jobs:
|
|||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^12'
|
||||
fallbackNpm: '^6'
|
||||
fallbackNode: '^16'
|
||||
fallbackNpm: '^7'
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -47,8 +47,13 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Test
|
||||
run: npm run test
|
||||
- name: Test and process coverage
|
||||
run: npm run test:coverage
|
||||
|
||||
- name: Collect coverage
|
||||
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4
|
||||
with:
|
||||
files: ./coverage/lcov.info
|
||||
|
||||
jsunit:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -154,6 +154,7 @@ Vagrantfile
|
|||
/config/config-autotest-backup.php
|
||||
/config/autoconfig.php
|
||||
clover.xml
|
||||
/coverage
|
||||
|
||||
# Tests - dependencies
|
||||
tests/acceptance/vendor/
|
||||
|
|
|
|||
34
__mocks__/@nextcloud/auth.ts
Normal file
34
__mocks__/@nextcloud/auth.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
export const getCurrentUser = function() {
|
||||
return {
|
||||
uid: 'test',
|
||||
displayName: 'Test',
|
||||
isAdmin: false,
|
||||
}
|
||||
}
|
||||
|
||||
export const getRequestToken = function() {
|
||||
return 'test-token-1234'
|
||||
}
|
||||
|
||||
export const onRequestTokenUpdate = function() {}
|
||||
24
__mocks__/@nextcloud/axios.ts
Normal file
24
__mocks__/@nextcloud/axios.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
delete: async () => ({ status: 200, data: {} }),
|
||||
}
|
||||
22
__mocks__/svg.js
Normal file
22
__mocks__/svg.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
export default 'SvgMock'
|
||||
184
apps/files/src/actions/deleteAction.spec.ts
Normal file
184
apps/files/src/actions/deleteAction.spec.ts
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { action } from './deleteAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import * as eventBus from '@nextcloud/event-bus'
|
||||
import axios from '@nextcloud/axios'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import logger from '../logger'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
|
||||
const trashbinView = {
|
||||
id: 'trashbin',
|
||||
name: 'Trashbin',
|
||||
} as Navigation
|
||||
|
||||
describe('Delete action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
expect(action).toBeInstanceOf(FileAction)
|
||||
expect(action.id).toBe('delete')
|
||||
expect(action.displayName([], view)).toBe('Delete')
|
||||
expect(action.iconSvgInline([], view)).toBe('SvgMock')
|
||||
expect(action.order).toBe(100)
|
||||
})
|
||||
|
||||
test('Default trashbin view values', () => {
|
||||
expect(action.displayName([], trashbinView)).toBe('Delete permanently')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Delete action enabled tests', () => {
|
||||
test('Enabled with DELETE permissions', () => {
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.ALL,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(true)
|
||||
})
|
||||
|
||||
test('Disabled without DELETE permissions', () => {
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled without nodes', () => {
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled if not all nodes can be deleted', () => {
|
||||
const folder1 = new Folder({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.DELETE,
|
||||
})
|
||||
const folder2 = new Folder({
|
||||
id: 2,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Bar/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([folder1], view)).toBe(true)
|
||||
expect(action.enabled!([folder2], view)).toBe(false)
|
||||
expect(action.enabled!([folder1, folder2], view)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Delete action execute tests', () => {
|
||||
test('Delete action', async () => {
|
||||
jest.spyOn(axios, 'delete')
|
||||
jest.spyOn(eventBus, 'emit')
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ | Permission.UPDATE | Permission.DELETE,
|
||||
})
|
||||
|
||||
const exec = await action.exec(file, view, '/')
|
||||
|
||||
expect(exec).toBe(true)
|
||||
expect(axios.delete).toBeCalledTimes(1)
|
||||
expect(axios.delete).toBeCalledWith('https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt')
|
||||
|
||||
expect(eventBus.emit).toBeCalledTimes(1)
|
||||
expect(eventBus.emit).toBeCalledWith('files:node:deleted', file)
|
||||
})
|
||||
|
||||
test('Delete action batch', async () => {
|
||||
jest.spyOn(axios, 'delete')
|
||||
jest.spyOn(eventBus, 'emit')
|
||||
|
||||
const file1 = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foo.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ | Permission.UPDATE | Permission.DELETE,
|
||||
})
|
||||
|
||||
const file2 = new File({
|
||||
id: 2,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/bar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ | Permission.UPDATE | Permission.DELETE,
|
||||
})
|
||||
|
||||
const exec = await action.execBatch!([file1, file2], view, '/')
|
||||
|
||||
expect(exec).toStrictEqual([true, true])
|
||||
expect(axios.delete).toBeCalledTimes(2)
|
||||
expect(axios.delete).toHaveBeenNthCalledWith(1, 'https://cloud.domain.com/remote.php/dav/files/admin/foo.txt')
|
||||
expect(axios.delete).toHaveBeenNthCalledWith(2, 'https://cloud.domain.com/remote.php/dav/files/admin/bar.txt')
|
||||
|
||||
expect(eventBus.emit).toBeCalledTimes(2)
|
||||
expect(eventBus.emit).toHaveBeenNthCalledWith(1, 'files:node:deleted', file1)
|
||||
expect(eventBus.emit).toHaveBeenNthCalledWith(2, 'files:node:deleted', file2)
|
||||
})
|
||||
|
||||
test('Delete fails', async () => {
|
||||
jest.spyOn(axios, 'delete').mockImplementation(() => { throw new Error('Mock error') })
|
||||
jest.spyOn(logger, 'error').mockImplementation(() => jest.fn())
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ | Permission.UPDATE | Permission.DELETE,
|
||||
})
|
||||
|
||||
const exec = await action.exec(file, view, '/')
|
||||
|
||||
expect(exec).toBe(false)
|
||||
expect(axios.delete).toBeCalledTimes(1)
|
||||
expect(axios.delete).toBeCalledWith('https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt')
|
||||
|
||||
expect(eventBus.emit).toBeCalledTimes(0)
|
||||
expect(logger.error).toBeCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
|
@ -25,11 +25,11 @@ import { translate as t } from '@nextcloud/l10n'
|
|||
import axios from '@nextcloud/axios'
|
||||
import TrashCan from '@mdi/svg/svg/trash-can.svg?raw'
|
||||
|
||||
import { registerFileAction, FileAction } from '../services/FileAction.ts'
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
import logger from '../logger.js'
|
||||
import type { Navigation } from '../services/Navigation.ts'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
registerFileAction(new FileAction({
|
||||
export const action = new FileAction({
|
||||
id: 'delete',
|
||||
displayName(nodes: Node[], view: Navigation) {
|
||||
return view.id === 'trashbin'
|
||||
|
|
@ -63,4 +63,6 @@ registerFileAction(new FileAction({
|
|||
},
|
||||
|
||||
order: 100,
|
||||
}))
|
||||
})
|
||||
|
||||
registerFileAction(action)
|
||||
|
|
|
|||
185
apps/files/src/actions/downloadAction.spec.ts
Normal file
185
apps/files/src/actions/downloadAction.spec.ts
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { action } from './downloadAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import * as eventBus from '@nextcloud/event-bus'
|
||||
import axios from '@nextcloud/axios'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import logger from '../logger'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
|
||||
describe('Download action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
expect(action).toBeInstanceOf(FileAction)
|
||||
expect(action.id).toBe('download')
|
||||
expect(action.displayName([], view)).toBe('Download')
|
||||
expect(action.iconSvgInline([], view)).toBe('SvgMock')
|
||||
expect(action.order).toBe(30)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Download action enabled tests', () => {
|
||||
test('Enabled with READ permissions', () => {
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.ALL,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(true)
|
||||
})
|
||||
|
||||
test('Disabled without READ permissions', () => {
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.NONE,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled if not all nodes have READ permissions', () => {
|
||||
const folder1 = new Folder({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
const folder2 = new Folder({
|
||||
id: 2,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Bar/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.NONE,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([folder1], view)).toBe(true)
|
||||
expect(action.enabled!([folder2], view)).toBe(false)
|
||||
expect(action.enabled!([folder1, folder2], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled without nodes', () => {
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([], view)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Download action execute tests', () => {
|
||||
const link = {
|
||||
click: jest.fn(),
|
||||
} as unknown as HTMLAnchorElement
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(document, 'createElement').mockImplementation(() => link)
|
||||
})
|
||||
|
||||
test('Download single file', async () => {
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
const exec = await action.exec(file, view, '/')
|
||||
|
||||
// Silent action
|
||||
expect(exec).toBe(null)
|
||||
expect(link.download).toEqual('')
|
||||
expect(link.href).toEqual('https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt')
|
||||
expect(link.click).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
test('Download single file with batch', async () => {
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
const exec = await action.execBatch!([file], view, '/')
|
||||
|
||||
// Silent action
|
||||
expect(exec).toStrictEqual([null])
|
||||
expect(link.download).toEqual('')
|
||||
expect(link.href).toEqual('https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt')
|
||||
expect(link.click).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
test('Download single folder', async () => {
|
||||
const folder = new Folder({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/FooBar/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
const exec = await action.exec(folder, view, '/')
|
||||
|
||||
// Silent action
|
||||
expect(exec).toBe(null)
|
||||
expect(link.download).toEqual('')
|
||||
expect(link.href.startsWith('/index.php/apps/files/ajax/download.php?dir=%2F&files=%5B%22FooBar%22%5D&downloadStartSecret=')).toBe(true)
|
||||
expect(link.click).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
test('Download multiple nodes', async () => {
|
||||
const file1 = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Dir/foo.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
const file2 = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Dir/bar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
const exec = await action.execBatch!([file1, file2], view, '/Dir')
|
||||
|
||||
// Silent action
|
||||
expect(exec).toStrictEqual([null, null])
|
||||
expect(link.download).toEqual('')
|
||||
expect(link.href.startsWith('/index.php/apps/files/ajax/download.php?dir=%2FDir&files=%5B%22foo.txt%22%2C%22bar.txt%22%5D&downloadStartSecret=')).toBe(true)
|
||||
expect(link.click).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
82
apps/files/src/actions/downloadAction.ts
Normal file
82
apps/files/src/actions/downloadAction.ts
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { Permission, Node, FileType } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import ArrowDown from '@mdi/svg/svg/arrow-down.svg?raw'
|
||||
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
const triggerDownload = function(url: string) {
|
||||
const hiddenElement = document.createElement('a')
|
||||
hiddenElement.download = ''
|
||||
hiddenElement.href = url
|
||||
hiddenElement.click()
|
||||
}
|
||||
|
||||
const downloadNodes = function(dir: string, nodes: Node[]) {
|
||||
const secret = Math.random().toString(36).substring(2)
|
||||
const url = generateUrl('/apps/files/ajax/download.php?dir={dir}&files={files}&downloadStartSecret={secret}', {
|
||||
dir,
|
||||
secret,
|
||||
files: JSON.stringify(nodes.map(node => node.basename)),
|
||||
})
|
||||
triggerDownload(url)
|
||||
}
|
||||
|
||||
export const action = new FileAction({
|
||||
id: 'download',
|
||||
displayName: () => t('files', 'Download'),
|
||||
iconSvgInline: () => ArrowDown,
|
||||
|
||||
enabled(nodes: Node[]) {
|
||||
return nodes.length > 0 && nodes
|
||||
.map(node => node.permissions)
|
||||
.every(permission => (permission & Permission.READ) !== 0)
|
||||
},
|
||||
|
||||
async exec(node: Node, view: Navigation, dir: string) {
|
||||
if (node.type === FileType.Folder) {
|
||||
downloadNodes(dir, [node])
|
||||
return null
|
||||
}
|
||||
|
||||
triggerDownload(node.source)
|
||||
return null
|
||||
},
|
||||
|
||||
async execBatch(nodes: Node[], view: Navigation, dir: string) {
|
||||
if (nodes.length === 1) {
|
||||
this.exec(nodes[0], view, dir)
|
||||
return [null]
|
||||
}
|
||||
|
||||
downloadNodes(dir, nodes)
|
||||
return new Array(nodes.length).fill(null)
|
||||
},
|
||||
|
||||
order: 30,
|
||||
})
|
||||
|
||||
registerFileAction(action)
|
||||
163
apps/files/src/actions/openFolderAction.spec.ts
Normal file
163
apps/files/src/actions/openFolderAction.spec.ts
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { action } from './openFolderAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
|
||||
describe('Open folder action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
const folder = new Folder({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/FooBar/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
expect(action).toBeInstanceOf(FileAction)
|
||||
expect(action.id).toBe('open-folder')
|
||||
expect(action.displayName([folder], view)).toBe('Open folder FooBar')
|
||||
expect(action.iconSvgInline([], view)).toBe('SvgMock')
|
||||
expect(action.default).toBe(true)
|
||||
expect(action.order).toBe(-100)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Open folder action enabled tests', () => {
|
||||
test('Enabled for folders', () => {
|
||||
const folder = new Folder({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/FooBar/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([folder], view)).toBe(true)
|
||||
})
|
||||
|
||||
test('Disabled for non-dav ressources', () => {
|
||||
const folder = new Folder({
|
||||
id: 1,
|
||||
source: 'https://domain.com/data/FooBar/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.NONE,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([folder], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled if more than one node', () => {
|
||||
const folder1 = new Folder({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
const folder2 = new Folder({
|
||||
id: 2,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Bar/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([folder1, folder2], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled for files', () => {
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled without READ permissions', () => {
|
||||
const folder = new Folder({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.NONE,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([folder], view)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Open folder action execute tests', () => {
|
||||
test('Open folder', async () => {
|
||||
const goToRouteMock = jest.fn()
|
||||
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }
|
||||
|
||||
const folder = new Folder({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/FooBar/',
|
||||
owner: 'admin',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
const exec = await action.exec(folder, view, '/')
|
||||
// Silent action
|
||||
expect(exec).toBe(null)
|
||||
expect(goToRouteMock).toBeCalledTimes(1)
|
||||
expect(goToRouteMock).toBeCalledWith(null, null, { dir: '/FooBar' })
|
||||
})
|
||||
|
||||
test('Open folder fails without node', async () => {
|
||||
const goToRouteMock = jest.fn()
|
||||
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }
|
||||
|
||||
// @ts-ignore null as Node
|
||||
const exec = await action.exec(null, view, '/')
|
||||
expect(exec).toBe(false)
|
||||
expect(goToRouteMock).toBeCalledTimes(0)
|
||||
})
|
||||
|
||||
test('Open folder fails without Folder', async () => {
|
||||
const goToRouteMock = jest.fn()
|
||||
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/Foo/',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
|
||||
const exec = await action.exec(file, view, '/')
|
||||
expect(exec).toBe(false)
|
||||
expect(goToRouteMock).toBeCalledTimes(0)
|
||||
})
|
||||
})
|
||||
|
|
@ -27,7 +27,7 @@ import type { Navigation } from '../services/Navigation'
|
|||
import { join } from 'path'
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
|
||||
registerFileAction(new FileAction({
|
||||
export const action = new FileAction({
|
||||
id: 'open-folder',
|
||||
displayName(files: Node[]) {
|
||||
// Only works on single node
|
||||
|
|
@ -43,6 +43,11 @@ registerFileAction(new FileAction({
|
|||
}
|
||||
|
||||
const node = nodes[0]
|
||||
|
||||
if (!node.isDavRessource) {
|
||||
return false
|
||||
}
|
||||
|
||||
return node.type === FileType.Folder
|
||||
&& (node.permissions & Permission.READ) !== 0
|
||||
},
|
||||
|
|
@ -59,11 +64,10 @@ registerFileAction(new FileAction({
|
|||
)
|
||||
return null
|
||||
},
|
||||
async execBatch(nodes: Node[], view: Navigation, dir: string) {
|
||||
return Promise.all(nodes.map(node => this.exec(node, view, dir)))
|
||||
},
|
||||
|
||||
// Main action if enabled, meaning folders only
|
||||
order: -100,
|
||||
default: true,
|
||||
}))
|
||||
order: -100,
|
||||
})
|
||||
|
||||
registerFileAction(action)
|
||||
|
|
|
|||
144
apps/files/src/actions/sidebarAction.spec.ts
Normal file
144
apps/files/src/actions/sidebarAction.spec.ts
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { action } from './sidebarAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import logger from '../logger'
|
||||
|
||||
const view = {
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
} as Navigation
|
||||
|
||||
describe('Open sidebar action conditions tests', () => {
|
||||
test('Default values', () => {
|
||||
expect(action).toBeInstanceOf(FileAction)
|
||||
expect(action.id).toBe('details')
|
||||
expect(action.displayName([], view)).toBe('Details')
|
||||
expect(action.iconSvgInline([], view)).toBe('SvgMock')
|
||||
expect(action.default).toBe(true)
|
||||
expect(action.order).toBe(-50)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Open folder action enabled tests', () => {
|
||||
test('Enabled for ressources within user root folder', () => {
|
||||
window.OCA = { Files: { Sidebar: {} } }
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(true)
|
||||
})
|
||||
|
||||
test('Disabled if more than one node', () => {
|
||||
window.OCA = { Files: { Sidebar: {} } }
|
||||
|
||||
const file1 = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foo.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
const file2 = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/bar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file1, file2], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled if no Sidebar', () => {
|
||||
window.OCA = {}
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(false)
|
||||
})
|
||||
|
||||
test('Disabled for non-dav ressources', () => {
|
||||
window.OCA = { Files: { Sidebar: {} } }
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://domain.com/documents/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Open sidebar action exec tests', () => {
|
||||
test('Open sidebar', async () => {
|
||||
const openMock = jest.fn()
|
||||
window.OCA = { Files: { Sidebar: { open: openMock } } }
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
|
||||
const exec = await action.exec(file, view, '/')
|
||||
// Silent action
|
||||
expect(exec).toBe(null)
|
||||
expect(openMock).toBeCalledWith('/foobar.txt')
|
||||
})
|
||||
|
||||
test('Open sidebar fails', async () => {
|
||||
const openMock = jest.fn(() => { throw new Error('Mock error') })
|
||||
window.OCA = { Files: { Sidebar: { open: openMock } } }
|
||||
jest.spyOn(logger, 'error').mockImplementation(() => jest.fn())
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
})
|
||||
|
||||
const exec = await action.exec(file, view, '/')
|
||||
expect(exec).toBe(false)
|
||||
expect(openMock).toBeCalledTimes(1)
|
||||
expect(logger.error).toBeCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
|
@ -23,19 +23,30 @@ import { translate as t } from '@nextcloud/l10n'
|
|||
import InformationSvg from '@mdi/svg/svg/information-variant.svg?raw'
|
||||
import type { Node } from '@nextcloud/files'
|
||||
|
||||
import { registerFileAction, FileAction } from '../services/FileAction.ts'
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
import logger from '../logger.js'
|
||||
|
||||
export const ACTION_DETAILS = 'details'
|
||||
|
||||
registerFileAction(new FileAction({
|
||||
export const action = new FileAction({
|
||||
id: ACTION_DETAILS,
|
||||
displayName: () => t('files', 'Details'),
|
||||
iconSvgInline: () => InformationSvg,
|
||||
|
||||
// Sidebar currently supports user folder only, /files/USER
|
||||
enabled: (files: Node[]) => !!window?.OCA?.Files?.Sidebar
|
||||
&& files.some(node => node.root?.startsWith('/files/')),
|
||||
enabled: (nodes: Node[]) => {
|
||||
// Only works on single node
|
||||
if (nodes.length !== 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Only work if the sidebar is available
|
||||
if (!window?.OCA?.Files?.Sidebar) {
|
||||
return false
|
||||
}
|
||||
|
||||
return nodes[0].root?.startsWith('/files/') ?? false
|
||||
},
|
||||
|
||||
async exec(node: Node) {
|
||||
try {
|
||||
|
|
@ -51,4 +62,7 @@ registerFileAction(new FileAction({
|
|||
|
||||
default: true,
|
||||
order: -50,
|
||||
}))
|
||||
})
|
||||
|
||||
registerFileAction(action)
|
||||
|
||||
|
|
|
|||
|
|
@ -39,11 +39,11 @@ interface FileActionData {
|
|||
/** Unique ID */
|
||||
id: string
|
||||
/** Translatable string displayed in the menu */
|
||||
displayName: (files: Node[], view) => string
|
||||
displayName: (files: Node[], view: Navigation) => string
|
||||
/** Svg as inline string. <svg><path fill="..." /></svg> */
|
||||
iconSvgInline: (files: Node[], view) => string
|
||||
iconSvgInline: (files: Node[], view: Navigation) => string
|
||||
/** Condition wether this action is shown or not */
|
||||
enabled?: (files: Node[], view) => boolean
|
||||
enabled?: (files: Node[], view: Navigation) => boolean
|
||||
/**
|
||||
* Function executed on single file action
|
||||
* @returns true if the action was executed, false otherwise
|
||||
|
|
@ -64,12 +64,12 @@ interface FileActionData {
|
|||
/**
|
||||
* If true, the renderInline function will be called
|
||||
*/
|
||||
inline?: (file: Node, view) => boolean,
|
||||
inline?: (file: Node, view: Navigation) => boolean,
|
||||
/**
|
||||
* If defined, the returned html element will be
|
||||
* appended before the actions menu.
|
||||
*/
|
||||
renderInline?: (file: Node, view) => HTMLElement,
|
||||
renderInline?: (file: Node, view: Navigation) => HTMLElement,
|
||||
}
|
||||
|
||||
export class FileAction {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
$expectedFiles = [
|
||||
'.',
|
||||
'..',
|
||||
'.codecov.yml',
|
||||
'.devcontainer',
|
||||
'.drone.yml',
|
||||
'.editorconfig',
|
||||
|
|
@ -44,6 +43,8 @@ $expectedFiles = [
|
|||
'.tag',
|
||||
'.tx',
|
||||
'.user.ini',
|
||||
'__mocks__',
|
||||
'__tests__',
|
||||
'3rdparty',
|
||||
'AUTHORS',
|
||||
'CHANGELOG.md',
|
||||
|
|
@ -60,6 +61,7 @@ $expectedFiles = [
|
|||
'autotest.sh',
|
||||
'babel.config.js',
|
||||
'build',
|
||||
'codecov.yml',
|
||||
'composer.json',
|
||||
'composer.lock',
|
||||
'config',
|
||||
|
|
@ -74,7 +76,7 @@ $expectedFiles = [
|
|||
'dist',
|
||||
'index.html',
|
||||
'index.php',
|
||||
'jest.config.js',
|
||||
'jest.config.ts',
|
||||
'lib',
|
||||
'occ',
|
||||
'ocm-provider',
|
||||
|
|
|
|||
7
codecov.yml
Normal file
7
codecov.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
codecov:
|
||||
branch: master
|
||||
ci:
|
||||
- drone.nextcloud.com
|
||||
- '!scrutinizer-ci.com'
|
||||
|
||||
comment: false
|
||||
5
custom.d.ts
vendored
5
custom.d.ts
vendored
|
|
@ -24,6 +24,11 @@ declare module '*.svg?raw' {
|
|||
export default content
|
||||
}
|
||||
|
||||
declare module '*.svg' {
|
||||
const content: any
|
||||
export default content
|
||||
}
|
||||
|
||||
declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
export default Vue
|
||||
|
|
|
|||
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/**
|
||||
* @copyright Copyright (c) 2020 Marco Ambrosini <marcoambrosini@pm.me>
|
||||
*
|
||||
* @author Marco Ambrosini <marcoambrosini@pm.me>
|
||||
|
|
@ -19,42 +19,55 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { Config } from 'jest'
|
||||
|
||||
// TODO: find a way to consolidate this in one place, with webpack.common.js
|
||||
const ignorePatterns = [
|
||||
'vue-material-design-icons',
|
||||
'@juliushaertl',
|
||||
'tributejs',
|
||||
'@mdi/svg',
|
||||
'@nextcloud/vue',
|
||||
'ansi-regex',
|
||||
'char-regex',
|
||||
'splitpanes',
|
||||
'string-length',
|
||||
'strip-ansi',
|
||||
'ansi-regex',
|
||||
'char-regex',
|
||||
'tributejs',
|
||||
'vue-material-design-icons',
|
||||
]
|
||||
|
||||
module.exports = {
|
||||
testMatch: ['<rootDir>/apps/*/src/**/*.(spec|test).(ts|js)'],
|
||||
modulePathIgnorePatterns: ["<rootDir>/apps-extra/"],
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!(' + ignorePatterns.join('|') + ')/)',
|
||||
],
|
||||
setupFilesAfterEnv: ['<rootDir>/tests/jestSetup.js'],
|
||||
resetMocks: false,
|
||||
collectCoverageFrom: [
|
||||
'<rootDir>/apps/*/src/**/*.{js,vue}',
|
||||
],
|
||||
const config: Config = {
|
||||
testMatch: ['<rootDir>/**/*.(spec|test).(ts|js)'],
|
||||
|
||||
clearMocks: true,
|
||||
setupFilesAfterEnv: ['<rootDir>/__tests__/jest-setup.ts'],
|
||||
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
preset: 'ts-jest/presets/js-with-ts',
|
||||
|
||||
moduleFileExtensions: [
|
||||
'js',
|
||||
'vue',
|
||||
roots: [
|
||||
'<rootDir>/__mocks__',
|
||||
'<rootDir>/__tests__',
|
||||
'<rootDir>/apps',
|
||||
'<rootDir>/core',
|
||||
],
|
||||
|
||||
transform: {
|
||||
// process `*.js` files with `babel-jest`
|
||||
'.*\\.(js)$': 'babel-jest',
|
||||
'^.+\\.js$': 'babel-jest',
|
||||
'^.+\\.vue$': '@vue/vue2-jest',
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!(' + ignorePatterns.join('|') + ')/)',
|
||||
],
|
||||
|
||||
// Allow mocking svg files
|
||||
moduleNameMapper: {
|
||||
'^.+\\.svg(\\?raw)?$': '<rootDir>/__mocks__/svg.js',
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/apps2/',
|
||||
'<rootDir>/apps-extra/',
|
||||
],
|
||||
}
|
||||
|
||||
export default config
|
||||
399
package-lock.json
generated
399
package-lock.json
generated
|
|
@ -105,6 +105,7 @@
|
|||
"@testing-library/user-event": "^14.4.3",
|
||||
"@testing-library/vue": "^5.8.3",
|
||||
"@types/dockerode": "^3.3.17",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.5",
|
||||
"@vue/test-utils": "^1.3.5",
|
||||
|
|
@ -128,7 +129,6 @@
|
|||
"jest": "^29.0.3",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"jsdoc": "^4.0.2",
|
||||
"jsdom": "^22.0.0",
|
||||
"karma": "^6.4.2",
|
||||
"karma-chrome-launcher": "^3.1.1",
|
||||
"karma-coverage": "2.2.0",
|
||||
|
|
@ -144,6 +144,7 @@
|
|||
"sinon": "<= 5.0.7",
|
||||
"style-loader": "^3.3.1",
|
||||
"tar": "^6.1.15",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-loader": "^9.4.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"tslib": "^2.5.3",
|
||||
|
|
@ -4638,9 +4639,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/jest": {
|
||||
"version": "29.5.1",
|
||||
"version": "29.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz",
|
||||
"integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"expect": "^29.0.0",
|
||||
"pretty-format": "^29.0.0"
|
||||
|
|
@ -7039,6 +7041,18 @@
|
|||
"version": "1.0.0",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/bs-logger": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
|
||||
"integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fast-json-stable-stringify": "2.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/bser": {
|
||||
"version": "2.1.1",
|
||||
"dev": true,
|
||||
|
|
@ -8201,17 +8215,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cssstyle": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"rrweb-cssom": "^0.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.2",
|
||||
"license": "MIT"
|
||||
|
|
@ -8452,19 +8455,6 @@
|
|||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/data-urls": {
|
||||
"version": "4.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"abab": "^2.0.6",
|
||||
"whatwg-mimetype": "^3.0.0",
|
||||
"whatwg-url": "^12.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/date-format": {
|
||||
"version": "4.0.14",
|
||||
"dev": true,
|
||||
|
|
@ -15301,77 +15291,6 @@
|
|||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom": {
|
||||
"version": "22.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"abab": "^2.0.6",
|
||||
"cssstyle": "^3.0.0",
|
||||
"data-urls": "^4.0.0",
|
||||
"decimal.js": "^10.4.3",
|
||||
"domexception": "^4.0.0",
|
||||
"form-data": "^4.0.0",
|
||||
"html-encoding-sniffer": "^3.0.0",
|
||||
"http-proxy-agent": "^5.0.0",
|
||||
"https-proxy-agent": "^5.0.1",
|
||||
"is-potential-custom-element-name": "^1.0.1",
|
||||
"nwsapi": "^2.2.4",
|
||||
"parse5": "^7.1.2",
|
||||
"rrweb-cssom": "^0.6.0",
|
||||
"saxes": "^6.0.0",
|
||||
"symbol-tree": "^3.2.4",
|
||||
"tough-cookie": "^4.1.2",
|
||||
"w3c-xmlserializer": "^4.0.0",
|
||||
"webidl-conversions": "^7.0.0",
|
||||
"whatwg-encoding": "^2.0.0",
|
||||
"whatwg-mimetype": "^3.0.0",
|
||||
"whatwg-url": "^12.0.1",
|
||||
"ws": "^8.13.0",
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"canvas": "^2.5.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"canvas": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom/node_modules/punycode": {
|
||||
"version": "2.3.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom/node_modules/tough-cookie": {
|
||||
"version": "4.1.2",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.33",
|
||||
"punycode": "^2.1.1",
|
||||
"universalify": "^0.2.0",
|
||||
"url-parse": "^1.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom/node_modules/universalify": {
|
||||
"version": "0.2.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsesc": {
|
||||
"version": "2.5.2",
|
||||
"dev": true,
|
||||
|
|
@ -19863,11 +19782,6 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/rrweb-cssom": {
|
||||
"version": "0.6.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"dev": true,
|
||||
|
|
@ -21993,25 +21907,6 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "4.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"punycode": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46/node_modules/punycode": {
|
||||
"version": "2.3.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tributejs": {
|
||||
"version": "5.1.3",
|
||||
"license": "MIT"
|
||||
|
|
@ -22041,6 +21936,97 @@
|
|||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest": {
|
||||
"version": "29.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz",
|
||||
"integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bs-logger": "0.x",
|
||||
"fast-json-stable-stringify": "2.x",
|
||||
"jest-util": "^29.0.0",
|
||||
"json5": "^2.2.3",
|
||||
"lodash.memoize": "4.x",
|
||||
"make-error": "1.x",
|
||||
"semver": "7.x",
|
||||
"yargs-parser": "^21.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-jest": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": ">=7.0.0-beta.0 <8",
|
||||
"@jest/types": "^29.0.0",
|
||||
"babel-jest": "^29.0.0",
|
||||
"jest": "^29.0.0",
|
||||
"typescript": ">=4.3 <6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@babel/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@jest/types": {
|
||||
"optional": true
|
||||
},
|
||||
"babel-jest": {
|
||||
"optional": true
|
||||
},
|
||||
"esbuild": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest/node_modules/lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||
"integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ts-jest/node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest/node_modules/semver": {
|
||||
"version": "7.5.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
|
||||
"integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ts-jest/node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader": {
|
||||
"version": "9.4.2",
|
||||
"dev": true,
|
||||
|
|
@ -23914,18 +23900,6 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "12.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tr46": "^4.1.1",
|
||||
"webidl-conversions": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"dev": true,
|
||||
|
|
@ -27456,7 +27430,9 @@
|
|||
}
|
||||
},
|
||||
"@types/jest": {
|
||||
"version": "29.5.1",
|
||||
"version": "29.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz",
|
||||
"integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"expect": "^29.0.0",
|
||||
|
|
@ -29016,6 +28992,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"bs-logger": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
|
||||
"integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-json-stable-stringify": "2.x"
|
||||
}
|
||||
},
|
||||
"bser": {
|
||||
"version": "2.1.1",
|
||||
"dev": true,
|
||||
|
|
@ -29766,13 +29751,6 @@
|
|||
"version": "0.5.0",
|
||||
"dev": true
|
||||
},
|
||||
"cssstyle": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"rrweb-cssom": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.1.2"
|
||||
},
|
||||
|
|
@ -29933,15 +29911,6 @@
|
|||
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||
"optional": true
|
||||
},
|
||||
"data-urls": {
|
||||
"version": "4.0.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abab": "^2.0.6",
|
||||
"whatwg-mimetype": "^3.0.0",
|
||||
"whatwg-url": "^12.0.0"
|
||||
}
|
||||
},
|
||||
"date-format": {
|
||||
"version": "4.0.14",
|
||||
"dev": true
|
||||
|
|
@ -34346,55 +34315,6 @@
|
|||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"jsdom": {
|
||||
"version": "22.0.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abab": "^2.0.6",
|
||||
"cssstyle": "^3.0.0",
|
||||
"data-urls": "^4.0.0",
|
||||
"decimal.js": "^10.4.3",
|
||||
"domexception": "^4.0.0",
|
||||
"form-data": "^4.0.0",
|
||||
"html-encoding-sniffer": "^3.0.0",
|
||||
"http-proxy-agent": "^5.0.0",
|
||||
"https-proxy-agent": "^5.0.1",
|
||||
"is-potential-custom-element-name": "^1.0.1",
|
||||
"nwsapi": "^2.2.4",
|
||||
"parse5": "^7.1.2",
|
||||
"rrweb-cssom": "^0.6.0",
|
||||
"saxes": "^6.0.0",
|
||||
"symbol-tree": "^3.2.4",
|
||||
"tough-cookie": "^4.1.2",
|
||||
"w3c-xmlserializer": "^4.0.0",
|
||||
"webidl-conversions": "^7.0.0",
|
||||
"whatwg-encoding": "^2.0.0",
|
||||
"whatwg-mimetype": "^3.0.0",
|
||||
"whatwg-url": "^12.0.1",
|
||||
"ws": "^8.13.0",
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "2.3.0",
|
||||
"dev": true
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "4.1.2",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.33",
|
||||
"punycode": "^2.1.1",
|
||||
"universalify": "^0.2.0",
|
||||
"url-parse": "^1.5.3"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.2.0",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsesc": {
|
||||
"version": "2.5.2",
|
||||
"dev": true
|
||||
|
|
@ -37253,10 +37173,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"rrweb-cssom": {
|
||||
"version": "0.6.0",
|
||||
"dev": true
|
||||
},
|
||||
"run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"dev": true,
|
||||
|
|
@ -38647,19 +38563,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"version": "4.1.1",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "2.3.0",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tributejs": {
|
||||
"version": "5.1.3"
|
||||
},
|
||||
|
|
@ -38674,6 +38577,60 @@
|
|||
"trough": {
|
||||
"version": "2.1.0"
|
||||
},
|
||||
"ts-jest": {
|
||||
"version": "29.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz",
|
||||
"integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bs-logger": "0.x",
|
||||
"fast-json-stable-stringify": "2.x",
|
||||
"jest-util": "^29.0.0",
|
||||
"json5": "^2.2.3",
|
||||
"lodash.memoize": "4.x",
|
||||
"make-error": "1.x",
|
||||
"semver": "7.x",
|
||||
"yargs-parser": "^21.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||
"integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
|
||||
"dev": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.5.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
|
||||
"integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "9.4.2",
|
||||
"dev": true,
|
||||
|
|
@ -39873,14 +39830,6 @@
|
|||
"version": "3.0.0",
|
||||
"dev": true
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "12.0.1",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tr46": "^4.1.1",
|
||||
"webidl-conversions": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"dev": true,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"lint:fix": "eslint 'apps/*/src/**/*.{vue,js}' 'core/src/**/*.{vue,js}' --fix",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"test:coverage": "jest --coverage",
|
||||
"test:jsunit": "karma start tests/karma.config.js --single-run",
|
||||
"sass": "sass --style compressed --load-path core/css core/css/ $(for cssdir in $(find apps -mindepth 2 -maxdepth 2 -name \"css\"); do if ! $(git check-ignore -q $cssdir); then echo -n \"$cssdir \"; fi; done)",
|
||||
"sass:watch": "sass --watch --load-path core/css core/css/ $(for cssdir in $(find apps -mindepth 2 -maxdepth 2 -name \"css\"); do if ! $(git check-ignore -q $cssdir); then echo -n \"$cssdir \"; fi; done)",
|
||||
|
|
@ -130,6 +131,7 @@
|
|||
"@testing-library/user-event": "^14.4.3",
|
||||
"@testing-library/vue": "^5.8.3",
|
||||
"@types/dockerode": "^3.3.17",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.5",
|
||||
"@vue/test-utils": "^1.3.5",
|
||||
|
|
@ -153,7 +155,6 @@
|
|||
"jest": "^29.0.3",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"jsdoc": "^4.0.2",
|
||||
"jsdom": "^22.0.0",
|
||||
"karma": "^6.4.2",
|
||||
"karma-chrome-launcher": "^3.1.1",
|
||||
"karma-coverage": "2.2.0",
|
||||
|
|
@ -169,6 +170,7 @@
|
|||
"sinon": "<= 5.0.7",
|
||||
"style-loader": "^3.3.1",
|
||||
"tar": "^6.1.15",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-loader": "^9.4.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"tslib": "^2.5.3",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"extends": "@vue/tsconfig/tsconfig.json",
|
||||
"include": ["./apps/**/*.ts", "./core/**/*.ts", "./*.d.ts"],
|
||||
"compilerOptions": {
|
||||
"types": ["cypress", "node", "vue"],
|
||||
"types": ["cypress", "jest", "node", "vue"],
|
||||
"outDir": "./dist/",
|
||||
"target": "ESNext",
|
||||
"module": "esnext",
|
||||
|
|
|
|||
Loading…
Reference in a new issue