Skip to content

Commit

Permalink
Merge pull request #46082 from nextcloud/chore/enable-eslint
Browse files Browse the repository at this point in the history
chore: Enable ESLint for apps and fix all errors
  • Loading branch information
susnux authored Jul 9, 2024
2 parents 3a97dbf + b0f6686 commit 6d8a7a1
Show file tree
Hide file tree
Showing 255 changed files with 1,090 additions and 1,278 deletions.
9 changes: 9 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,13 @@ module.exports = {
mode: 'typescript',
},
},
overrides: [
// Allow any in tests
{
files: ['**/*.spec.ts'],
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
},
}
],
}
8 changes: 8 additions & 0 deletions __tests__/mock-window.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

window.OC = { ...window.OC }
window.OCA = { ...window.OCA }
window.OCP = { ...window.OCP }
12 changes: 6 additions & 6 deletions apps/comments/src/services/DavClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ const client = createClient(getRootPath())

// set CSRF token header
const setHeaders = (token) => {
client.setHeaders({
// Add this so the server knows it is an request from the browser
'X-Requested-With': 'XMLHttpRequest',
// Inject user auth
requesttoken: token ?? '',
})
client.setHeaders({
// Add this so the server knows it is an request from the browser
'X-Requested-With': 'XMLHttpRequest',
// Inject user auth
requesttoken: token ?? '',
})
}

// refresh headers when request token changes
Expand Down
2 changes: 1 addition & 1 deletion apps/comments/src/services/GetComments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const getDirectoryFiles = function(
// Map all items to a consistent output structure (results)
return responseItems.map(item => {
// Each item should contain a stat object
const props = item.propstat!.prop!;
const props = item.propstat!.prop!

return prepareFileFromProps(props, props.id!.toString(), isDetailed)
})
Expand Down
2 changes: 1 addition & 1 deletion apps/comments/src/utils/cancelableRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const cancelableRequest = function(request) {
const fetch = async function(url, options) {
const response = await request(
url,
Object.assign({ signal }, options)
Object.assign({ signal }, options),
)
return response
}
Expand Down
35 changes: 17 additions & 18 deletions apps/dav/src/components/AbsenceForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
:clear-search-on-blur="() => false"
:user-select="true"
:options="options"
@search="asyncFind"
>
@search="asyncFind">
<template #no-options="{ search }">
{{ search ?$t('dav', 'No results.') : $t('dav', 'Start typing.') }}
</template>
Expand All @@ -51,21 +50,21 @@
</template>

<script>
import { getCurrentUser } from '@nextcloud/auth'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
import { generateOcsUrl } from '@nextcloud/router'
import { ShareType } from '@nextcloud/sharing'
import { formatDateAsYMD } from '../utils/date.js'
import axios from '@nextcloud/axios'
import debounce from 'debounce'
import logger from '../service/logger.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
import NcTextArea from '@nextcloud/vue/dist/Components/NcTextArea.js'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import NcDateTimePickerNative from '@nextcloud/vue/dist/Components/NcDateTimePickerNative.js'
import { generateOcsUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import debounce from 'debounce'
import axios from '@nextcloud/axios'
import { formatDateAsYMD } from '../utils/date.js'
import { loadState } from '@nextcloud/initial-state'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { Type as ShareTypes } from '@nextcloud/sharing'
import logger from '../service/logger.js'
export default {
name: 'AbsenceForm',
Expand All @@ -74,17 +73,17 @@ export default {
NcTextField,
NcTextArea,
NcDateTimePickerNative,
NcSelect
NcSelect,
},
data() {
const { firstDay, lastDay, status, message ,replacementUserId ,replacementUserDisplayName } = loadState('dav', 'absence', {})
const { firstDay, lastDay, status, message, replacementUserId, replacementUserDisplayName } = loadState('dav', 'absence', {})
return {
loading: false,
status: status ?? '',
message: message ?? '',
firstDay: firstDay ? new Date(firstDay) : new Date(),
lastDay: lastDay ? new Date(lastDay) : null,
replacementUserId: replacementUserId ,
replacementUserId,
replacementUser: replacementUserId ? { user: replacementUserId, displayName: replacementUserDisplayName } : null,
searchLoading: false,
options: [],
Expand Down Expand Up @@ -126,10 +125,10 @@ export default {
return {
user: result.uuid || result.value.shareWith,
displayName: result.name || result.label,
subtitle: result.dsc | ''
subtitle: result.dsc | '',
}
},
async asyncFind(query) {
this.searchLoading = true
await this.debounceGetSuggestions(query.trim())
Expand All @@ -142,7 +141,7 @@ export default {
async getSuggestions(search) {
const shareType = [
ShareTypes.SHARE_TYPE_USER,
ShareType.SHARE_TYPE_USER,
]
let request = null
Expand Down
2 changes: 1 addition & 1 deletion apps/dav/src/dav/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ export const getClient = memoize((service) => {
onRequestTokenUpdate(setHeaders)
setHeaders(getRequestToken())

return client;
return client
})
4 changes: 2 additions & 2 deletions apps/dav/src/service/PreferenceService.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function enableUserStatusAutomation() {
}),
{
configValue: 'yes',
}
},
)
}

Expand All @@ -29,6 +29,6 @@ export async function disableUserStatusAutomation() {
generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {
appId: 'dav',
configKey: 'user_status_automation',
})
}),
)
}
4 changes: 2 additions & 2 deletions apps/dav/src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ const CalDavSettingsView = new View({
sendInvitations: loadState('dav', 'sendInvitations'),
generateBirthdayCalendar: loadState(
'dav',
'generateBirthdayCalendar'
'generateBirthdayCalendar',
),
sendEventReminders: loadState('dav', 'sendEventReminders'),
sendEventRemindersToSharedUsers: loadState(
'dav',
'sendEventRemindersToSharedUsers'
'sendEventRemindersToSharedUsers',
),
sendEventRemindersPush: loadState('dav', 'sendEventRemindersPush'),
}
Expand Down
12 changes: 6 additions & 6 deletions apps/dav/src/views/CalDavSettings.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,27 @@ describe('CalDavSettings', () => {
},
Vue => {
Vue.prototype.$t = jest.fn((app, text) => text)
}
},
)
expect(TLUtils.container).toMatchSnapshot()
const sendInvitations = TLUtils.getByLabelText(
'Send invitations to attendees'
'Send invitations to attendees',
)
expect(sendInvitations).toBeChecked()
const generateBirthdayCalendar = TLUtils.getByLabelText(
'Automatically generate a birthday calendar'
'Automatically generate a birthday calendar',
)
expect(generateBirthdayCalendar).toBeChecked()
const sendEventReminders = TLUtils.getByLabelText(
'Send notifications for events'
'Send notifications for events',
)
expect(sendEventReminders).toBeChecked()
const sendEventRemindersToSharedUsers = TLUtils.getByLabelText(
'Send reminder notifications to calendar sharees as well'
'Send reminder notifications to calendar sharees as well',
)
expect(sendEventRemindersToSharedUsers).toBeChecked()
const sendEventRemindersPush = TLUtils.getByLabelText(
'Enable notifications for events via push'
'Enable notifications for events via push',
)
expect(sendEventRemindersPush).toBeChecked()

Expand Down
4 changes: 2 additions & 2 deletions apps/dav/src/views/CalDavSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export default {
OCP.AppConfig.setValue(
'dav',
'sendInvitations',
value ? 'yes' : 'no'
value ? 'yes' : 'no',
)
},
sendEventReminders(value) {
Expand All @@ -138,7 +138,7 @@ export default {
OCP.AppConfig.setValue(
'dav',
'sendEventRemindersToSharedUsers',
value ? 'yes' : 'no'
value ? 'yes' : 'no',
)
},
sendEventRemindersPush(value) {
Expand Down
7 changes: 4 additions & 3 deletions apps/federatedfilesharing/src/components/AdminSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@
</template>

<script>
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
import { loadState } from '@nextcloud/initial-state'
import { showError } from '@nextcloud/dialogs'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import { confirmPassword } from '@nextcloud/password-confirmation'
import axios from '@nextcloud/axios'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
import '@nextcloud/password-confirmation/dist/style.css'
export default {
Expand Down
4 changes: 2 additions & 2 deletions apps/federatedfilesharing/src/components/PersonalSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M502 197q-96 0-96.5 1.5t-1.5 137-1.5 138-2 2.5T266 432.5 132.5 390t-30 94T74 578l232 77q21 8 21 10t-79.5 117.5T168 899t79.5 56.5T328 1011t81-110 82-110 41 55l83 115q43 60 44 60t79.5-58 79-59-76-112.5-76-113.5T795 632.5t129.5-44-28-94T867 400t-128 42-128.5 43-2.5-7.5-1-38.5l-3-108q-4-133-5-133.5t-97-.5z" /></svg>
</template>
</NcButton>
<NcButton @click="showHtml = !showHtml"
class="social-button__website-button">
<NcButton class="social-button__website-button"
@click="showHtml = !showHtml">
<template #icon>
<Web :size="20" />
</template>
Expand Down
2 changes: 1 addition & 1 deletion apps/federatedfilesharing/src/external.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const processIncomingShareFromUrl = function() {
password,
},
).done(function(data) {
if (data.hasOwnProperty('legacyMount')) {
if (Object.hasOwn(data, 'legacyMount')) {
reloadFilesList()
} else {
window.OC.Notification.showTemporary(data.message)
Expand Down
1 change: 1 addition & 0 deletions apps/files/src/actions/deleteAction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ describe('Delete action execute tests', () => {
jest.spyOn(eventBus, 'emit')

const confirmMock = jest.fn()
// @ts-expect-error We only mock what needed
window.OC = { dialogs: { confirmDestructive: confirmMock } }

const file1 = new File({
Expand Down
2 changes: 1 addition & 1 deletion apps/files/src/actions/deleteAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const action = new FileAction({
.every(permission => (permission & Permission.DELETE) !== 0)
},

async exec(node: Node, view: View, dir: string) {
async exec(node: Node) {
try {
await axios.delete(node.encodedSource)

Expand Down
3 changes: 2 additions & 1 deletion apps/files/src/actions/favoriteAction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const favoriteView = {
name: 'Favorites',
} as View

global.window.OC = {
window.OC = {
...window.OC,
TAG_FAVORITE: '_$!<Favorite>!$_',
}

Expand Down
5 changes: 4 additions & 1 deletion apps/files/src/actions/openFolderAction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ describe('Open folder action enabled tests', () => {
describe('Open folder action execute tests', () => {
test('Open folder', async () => {
const goToRouteMock = jest.fn()
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }

const folder = new Folder({
Expand All @@ -114,11 +115,12 @@ describe('Open folder action execute tests', () => {
// Silent action
expect(exec).toBe(null)
expect(goToRouteMock).toBeCalledTimes(1)
expect(goToRouteMock).toBeCalledWith(null, { fileid: 1, view: 'files' }, { dir: '/FooBar' })
expect(goToRouteMock).toBeCalledWith(null, { fileid: '1', view: 'files' }, { dir: '/FooBar' })
})

test('Open folder fails without node', async () => {
const goToRouteMock = jest.fn()
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }

const exec = await action.exec(null as unknown as Node, view, '/')
Expand All @@ -128,6 +130,7 @@ describe('Open folder action execute tests', () => {

test('Open folder fails without Folder', async () => {
const goToRouteMock = jest.fn()
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }

const file = new File({
Expand Down
2 changes: 1 addition & 1 deletion apps/files/src/actions/openFolderAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const action = new FileAction({

window.OCP.Files.Router.goToRoute(
null,
{ view: view.id, fileid: node.fileid },
{ view: view.id, fileid: String(node.fileid) },
{ dir: node.path },
)
return null
Expand Down
6 changes: 4 additions & 2 deletions apps/files/src/actions/openInFilesAction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('Open in files action enabled tests', () => {
describe('Open in files action execute tests', () => {
test('Open in files', async () => {
const goToRouteMock = jest.fn()
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }

const file = new File({
Expand All @@ -59,11 +60,12 @@ describe('Open in files action execute tests', () => {
// Silent action
expect(exec).toBe(null)
expect(goToRouteMock).toBeCalledTimes(1)
expect(goToRouteMock).toBeCalledWith(null, { fileid: 1, view: 'files' }, { dir: '/Foo', openfile: 'true' })
expect(goToRouteMock).toBeCalledWith(null, { fileid: '1', view: 'files' }, { dir: '/Foo', openfile: 'true' })
})

test('Open in files with folder', async () => {
const goToRouteMock = jest.fn()
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }

const file = new Folder({
Expand All @@ -79,6 +81,6 @@ describe('Open in files action execute tests', () => {
// Silent action
expect(exec).toBe(null)
expect(goToRouteMock).toBeCalledTimes(1)
expect(goToRouteMock).toBeCalledWith(null, { fileid: 1, view: 'files' }, { dir: '/Foo/Bar', openfile: 'true' })
expect(goToRouteMock).toBeCalledWith(null, { fileid: '1', view: 'files' }, { dir: '/Foo/Bar', openfile: 'true' })
})
})
2 changes: 1 addition & 1 deletion apps/files/src/actions/openInFilesAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const action = new FileAction({

window.OCP.Files.Router.goToRoute(
null, // use default route
{ view: 'files', fileid: node.fileid },
{ view: 'files', fileid: String(node.fileid) },
{ dir, openfile: 'true' },
)
return null
Expand Down
3 changes: 2 additions & 1 deletion apps/files/src/actions/sidebarAction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ describe('Open sidebar action exec tests', () => {
const openMock = jest.fn()
window.OCA = { Files: { Sidebar: { open: openMock } } }
const goToRouteMock = jest.fn()
// @ts-expect-error We only mock what needed, we do not need Files.Router.goTo or Files.Navigation
window.OCP = { Files: { Router: { goToRoute: goToRouteMock } } }

const file = new File({
Expand All @@ -125,7 +126,7 @@ describe('Open sidebar action exec tests', () => {
expect(openMock).toBeCalledWith('/foobar.txt')
expect(goToRouteMock).toBeCalledWith(
null,
{ view: view.id, fileid: 1 },
{ view: view.id, fileid: '1' },
{ dir: '/' },
true,
)
Expand Down
Loading

0 comments on commit 6d8a7a1

Please sign in to comment.