diff --git a/.drone.star b/.drone.star
index 5dedfc6b1a1..fada65f5ef5 100644
--- a/.drone.star
+++ b/.drone.star
@@ -216,21 +216,6 @@ config = {
"screenShots": True,
"retry": False,
},
- "webUINotification": {
- "type": NOTIFICATIONS,
- "suites": {
- "oC10Notification": [
- "webUINotifications",
- "webUISharingNotifications",
- "webUISharingNotificationsToRoot",
- ],
- },
- "extraEnvironment": {
- "EXPECTED_FAILURES_FILE": "%s/tests/acceptance/expected-failures-with-oc10-server-oauth2-login.md" % dir["web"],
- },
- "screenShots": True,
- "notificationsAppNeeded": True,
- },
"webUIFederation": {
"type": FEDERATED,
"suites": {
@@ -245,22 +230,6 @@ config = {
"federatedServerNeeded": True,
"federatedServerVersion": OC10_VERSION,
},
- "webUI-XGA-Notifications": {
- "type": NOTIFICATIONS,
- "suites": {
- "oC10XGAPortraitNotifications": [
- "webUINotifications",
- "webUISharingNotifications",
- "webUISharingNotificationsToRoot",
- ],
- },
- "extraEnvironment": {
- "EXPECTED_FAILURES_FILE": "%s/tests/acceptance/expected-failures-XGA-with-oc10-server-oauth2-login.md" % dir["web"],
- "SCREEN_RESOLUTION": "768x1024",
- },
- "notificationsAppNeeded": True,
- "filterTags": "@smokeTest and not @skipOnXGAPortraitResolution and not @skip and not @skipOnOC10 and not @notToImplementOnOC10",
- },
"webUI-XGA": {
"type": FULL,
"suites": {
@@ -337,22 +306,6 @@ config = {
},
"filterTags": "@smokeTest and not @skipOnXGAPortraitResolution and not @skip and not @skipOnOC10 and not @notToImplementOnOC10",
},
- "webUI-Notifications-iPhone": {
- "type": NOTIFICATIONS,
- "suites": {
- "oC10iPhoneNotifications": [
- "webUINotifications",
- "webUISharingNotifications",
- "webUISharingNotificationsToRoot",
- ],
- },
- "extraEnvironment": {
- "EXPECTED_FAILURES_FILE": "%s/tests/acceptance/expected-failures-Iphone-oc10-server-oauth2-login.md" % dir["web"],
- "SCREEN_RESOLUTION": "375x812",
- },
- "notificationsAppNeeded": True,
- "filterTags": "@smokeTest and not @skipOnIphoneResolution and not @skip and not @skipOnOC10 and not @notToImplementOnOC10",
- },
"webUI-iPhone": {
"type": FULL,
"suites": {
@@ -436,7 +389,6 @@ config = {
],
"suites": {
"oCISBasic": [
- "webUINotifications",
"webUIPrivateLinks",
"webUIPreview",
"webUIAccount",
@@ -446,7 +398,6 @@ config = {
"oCISSharingBasic": [
"webUISharingAcceptShares",
"webUIRestrictSharing",
- "webUISharingNotifications",
],
"webUIFavorites": "oCISFavorites",
"oCISFiles1": [
@@ -537,25 +488,6 @@ config = {
"filterTags": "not @skip and not @skipOnOCIS and not @notToImplementOnOCIS",
"screenShots": True,
},
- "webUI-notifications-oc10-integration": {
- "type": NOTIFICATIONS,
- "suites": {
- "oC10IntegrationNotifications": [
- "webUINotifications",
- "webUISharingNotifications",
- "webUISharingNotificationsToRoot",
- ],
- },
- "extraEnvironment": {
- "WEB_UI_CONFIG": "%s" % dir["oc10IntegrationAppOauthConfig"],
- "SERVER_HOST": "http://owncloud/index.php/apps/web/index.html",
- "EXPECTED_FAILURES_FILE": "%s/tests/acceptance/expected-failures-with-oc10-server-oauth2-login-and-web-integration-app.md" % dir["web"],
- },
- "filterTags": "not @skip and not @skipOnOC10 and not @notToImplementOnOC10 and not @openIdLogin and @smokeTest",
- "oc10IntegrationAppIncluded": True,
- "notificationsAppNeeded": True,
- "screenShots": True,
- },
"webUI-oc10-integration": {
"type": FULL,
"suites": {
@@ -663,15 +595,6 @@ rootSharingTestSuites = [
"webUISharingPermissionToRoot",
]
-notificationsTestSuites = [
- "webUINotifications",
- "webUISharingNotifications",
-]
-
-notificationsRootTestSuites = [
- "webUISharingNotificationsToRoot",
-]
-
basicTestSuites = [
"webUIAccount",
"webUICreateFilesFolders",
@@ -776,15 +699,11 @@ def checkTestSuites():
expected += basicTestSuites
if ("runningOnOCIS" not in test or test["runningOnOCIS"] != True):
expected += rootSharingTestSuites
- elif (test["type"] == NOTIFICATIONS):
- expected += notificationsTestSuites
- if ("runningOnOCIS" not in test or test["runningOnOCIS"] != True):
- expected += notificationsRootTestSuites
elif (test["type"] == FEDERATED):
expected += federatedTestSuites + federatedRootTestSuites
if ("runningOnOCIS" in test and test["runningOnOCIS"] == True):
- expected += notificationsTestSuites + ocisSpecificTestSuites
+ expected += ocisSpecificTestSuites
if (sorted(suites) != sorted(expected)):
print("Error: Suites dont match " + testGroupName)
diff --git a/changelog/unreleased/enhancement-notifications-ocis b/changelog/unreleased/enhancement-notifications-ocis
new file mode 100644
index 00000000000..38c466f36d0
--- /dev/null
+++ b/changelog/unreleased/enhancement-notifications-ocis
@@ -0,0 +1,7 @@
+Enhancement: Make notifications work with oCIS
+
+Notifications now work when running oCIS as backend.
+
+https://github.com/owncloud/web/pull/8518
+https://github.com/owncloud/web/issues/8519
+https://github.com/owncloud/web/issues/8520
diff --git a/packages/web-app-files/src/views/shares/SharedWithMe.vue b/packages/web-app-files/src/views/shares/SharedWithMe.vue
index 364984d9a5a..698f5d881bb 100644
--- a/packages/web-app-files/src/views/shares/SharedWithMe.vue
+++ b/packages/web-app-files/src/views/shares/SharedWithMe.vue
@@ -228,7 +228,11 @@ export default defineComponent({
async created() {
await this.loadResourcesTask.perform()
- this.scrollToResourceFromRoute(this.acceptedItems)
+ this.scrollToResourceFromRoute([
+ ...this.acceptedItems,
+ ...this.pendingItems,
+ ...this.declinedItems
+ ])
}
})
diff --git a/packages/web-runtime/src/App.vue b/packages/web-runtime/src/App.vue
index 03bc15b531e..51295953aca 100644
--- a/packages/web-runtime/src/App.vue
+++ b/packages/web-runtime/src/App.vue
@@ -42,7 +42,7 @@
diff --git a/packages/web-runtime/src/components/Topbar/TopBar.vue b/packages/web-runtime/src/components/Topbar/TopBar.vue
index 750667994b8..09988514ef5 100644
--- a/packages/web-runtime/src/components/Topbar/TopBar.vue
+++ b/packages/web-runtime/src/components/Topbar/TopBar.vue
@@ -53,11 +53,6 @@ export default {
type: Array,
required: false,
default: () => []
- },
- activeNotifications: {
- type: [Array, Boolean],
- required: false,
- default: () => []
}
},
setup() {
diff --git a/packages/web-runtime/src/helpers/notifications.ts b/packages/web-runtime/src/helpers/notifications.ts
new file mode 100644
index 00000000000..580b5869de8
--- /dev/null
+++ b/packages/web-runtime/src/helpers/notifications.ts
@@ -0,0 +1,25 @@
+import { RouteLocationNamedRaw } from 'vue-router'
+
+export interface NotificationAction {
+ label: string
+ link: string
+ type: string
+ primary: boolean
+}
+
+export interface Notification {
+ notification_id: string
+ app: string
+ user: string
+ datetime: string
+ subject: string
+ message?: string
+ messageRich?: string
+ messageRichParameters?: any
+ object_type?: string
+ object_id?: string
+ link?: string
+ actions?: NotificationAction[]
+ computedMessage?: string
+ computedLink?: RouteLocationNamedRaw
+}
diff --git a/packages/web-runtime/src/layouts/Application.vue b/packages/web-runtime/src/layouts/Application.vue
index 5a8a80989f9..91305eb10b2 100644
--- a/packages/web-runtime/src/layouts/Application.vue
+++ b/packages/web-runtime/src/layouts/Application.vue
@@ -4,7 +4,7 @@
-
+
@@ -98,7 +98,6 @@ export default defineComponent({
...mapGetters([
'apps',
'activeMessages',
- 'activeNotifications',
'capabilities',
'configuration',
'getExtensionsWithNavItems',
diff --git a/packages/web-runtime/src/store/app.ts b/packages/web-runtime/src/store/app.ts
index d7d4568940b..de507e4434f 100644
--- a/packages/web-runtime/src/store/app.ts
+++ b/packages/web-runtime/src/store/app.ts
@@ -1,10 +1,5 @@
const state = {
messages: [],
- notifications: {
- loading: true,
- failed: false,
- data: []
- },
quickActions: {}
}
@@ -14,50 +9,6 @@ const actions = {
},
deleteMessage(context, mId) {
context.commit('REMOVE_MESSAGE', mId)
- },
- fetchNotifications(context, client) {
- context.commit('LOADING_NOTIFICATIONS', true)
-
- return client.requests
- .ocs({
- service: 'apps/notifications',
- action: 'api/v1/notifications'
- })
- .then((response) => {
- if (response.headers.get('Content-Length') === '0') {
- return
- }
- response.json().then((json) => {
- if (response.ok) {
- context.commit('UPDATE_NOTIFICATIONS', json.ocs.data)
- } else {
- context.commit('ERROR_NOTIFICATIONS', json.ocs.meta.message)
- }
- context.commit('LOADING_NOTIFICATIONS', false)
- })
- })
- .catch((error) => {
- context.commit('ERROR_NOTIFICATIONS', error)
- context.commit('LOADING_NOTIFICATIONS', false)
- })
- },
- deleteNotification(context, { client, notification }) {
- client.requests
- .ocs({
- service: 'apps/notifications',
- action: 'api/v1/notifications/' + notification,
- method: 'DELETE'
- })
- .then((response) => {
- if (response.ok) {
- context.commit('DELETE_NOTIFICATION', notification)
- } else {
- context.commit('ERROR_NOTIFICATIONS', response.ocs.meta.status)
- }
- })
- .catch((error) => {
- context.commit('ERROR_NOTIFICATIONS', error)
- })
}
}
@@ -73,22 +24,6 @@ const mutations = {
REMOVE_MESSAGE(state, item) {
state.messages.splice(state.messages.indexOf(item), 1)
},
- LOADING_NOTIFICATIONS(state, loading) {
- state.notifications.loading = loading
- },
- ERROR_NOTIFICATIONS(state, failed) {
- state.notifications.failed = failed
- },
- UPDATE_NOTIFICATIONS(state, notifications) {
- state.notifications.data = notifications
- },
- DELETE_NOTIFICATION(state, notification) {
- const data = state.notifications.data.filter((n) => {
- return n.notification_id !== notification
- })
- state.notifications.data = data
- },
-
ADD_QUICK_ACTIONS(state, quickActions) {
state.quickActions = Object.assign(state.quickActions, quickActions)
}
@@ -97,11 +32,6 @@ const mutations = {
const getters = {
activeMessages: (state) => {
return state.messages
- },
- activeNotifications: (state) => {
- return state.notifications.data.length && !state.notifications.failed
- ? state.notifications.data
- : false
}
}
diff --git a/packages/web-runtime/tests/unit/components/Topbar/Notification.spec.ts b/packages/web-runtime/tests/unit/components/Topbar/Notification.spec.ts
deleted file mode 100644
index f46d48d70f3..00000000000
--- a/packages/web-runtime/tests/unit/components/Topbar/Notification.spec.ts
+++ /dev/null
@@ -1,212 +0,0 @@
-import Notifications from 'web-runtime/src/components/Topbar/Notifications.vue'
-import { mockDeep } from 'jest-mock-extended'
-import { OwnCloudSdk } from 'web-client/src/types'
-import {
- createStore,
- defaultComponentMocks,
- defaultPlugins,
- mount,
- shallowMount,
- defaultStoreMockOptions
-} from 'web-test-helpers'
-
-const testData = {
- selectors: {
- notificationBell: '#oc-notification-bell',
- ocIconStub: 'oc-icon-stub',
- actionButton: '.oc-ml-s',
- resolveNotificationButton: '#resolve-notification-button',
- link: '.oc-width-1-1 > p > a',
- subject: 'h4',
- message: '.oc-text-small'
- },
- notifications: {
- emptyActions: [
- {
- notification_id: 1,
- subject: 'Test',
- message: 'This is a test message',
- actions: []
- }
- ],
- get singleAction() {
- return [
- {
- ...this.emptyActions[0],
- actions: [
- {
- label: 'Test Action',
- link: 'http://some.link'
- }
- ]
- }
- ]
- },
- twoActiveNotifications: [
- {
- subject: 'First Notification',
- message: 'This is first test message',
- actions: []
- },
- {
- subject: 'Second Notification',
- message: 'This is second test message',
- actions: []
- }
- ],
- linkActions: [
- {
- link: 'http://test.link',
- actions: []
- }
- ]
- }
-}
-
-describe('Notification component', () => {
- const { selectors } = testData
-
- describe('when active notification contains a message', () => {
- it('displays the notification message', () => {
- const { wrapper } = getWrapper({
- mountType: shallowMount,
- activeNotifications: testData.notifications.emptyActions
- })
- const messageElement = wrapper.find(selectors.message)
-
- expect(messageElement.exists()).toBeTruthy()
- expect(messageElement.text()).toBe('This is a test message')
- })
-
- it('displays the notification subject', () => {
- const { wrapper } = getWrapper({
- mountType: shallowMount,
- activeNotifications: testData.notifications.emptyActions
- })
- const subjectElement = wrapper.find(selectors.subject)
-
- expect(subjectElement.exists()).toBeTruthy()
- expect(subjectElement.text()).toBe('Test')
- })
- })
-
- describe('active notifications actions', () => {
- describe('when active notification action is empty', () => {
- const client = mockDeep
({})
- const { wrapper } = getWrapper({
- activeNotifications: testData.notifications.emptyActions,
- mocks: { $client: client }
- })
-
- it('does not display the action button', () => {
- expect(wrapper.find(selectors.actionButton).exists()).toBeFalsy()
- })
-
- it('displays the resolve notification button', () => {
- expect(wrapper.find(selectors.resolveNotificationButton).exists()).toBeTruthy()
- })
-
- it('dispatches deleteNotification when resolve notification is clicked', () => {
- const notificationSpy = jest.spyOn(wrapper.vm, 'deleteNotification')
- client.requests.ocs.mockImplementation(() => Promise.resolve(new Response()))
-
- const resolveNotificationButton = wrapper.find(selectors.resolveNotificationButton)
-
- expect(resolveNotificationButton.exists()).toBeTruthy()
- resolveNotificationButton.trigger('click')
- expect(notificationSpy).toHaveBeenCalledTimes(1)
- expect(notificationSpy).toHaveBeenCalledWith({ client, notification: 1 })
- })
- })
-
- describe('when active notification action has an action', () => {
- const { wrapper, mocks } = getWrapper({
- activeNotifications: testData.notifications.singleAction
- })
-
- it('displays the action button with action label', () => {
- const actionButton = wrapper.find(selectors.actionButton)
-
- expect(actionButton.exists()).toBeTruthy()
- expect(actionButton.text()).toBe('Test Action')
- })
-
- it("doesn't display the resolve notification button", () => {
- expect(wrapper.find(selectors.resolveNotificationButton).exists()).toBeFalsy()
- })
-
- it('calls executeRequest when action button is clicked', async () => {
- const actionButton = wrapper.find(selectors.actionButton)
-
- await actionButton.trigger('click')
- expect(mocks.$client.requests.ocs).toHaveBeenCalledTimes(1)
- })
- })
- })
-
- describe('active notifications links', () => {
- it('does not display link if no link is given', () => {
- const { wrapper } = getWrapper({
- mountType: shallowMount,
- activeNotifications: testData.notifications.emptyActions
- })
- const linkButton = wrapper.find(selectors.link)
-
- expect(linkButton.exists()).toBeFalsy()
- })
-
- it('displays link if a link is given', () => {
- const { wrapper } = getWrapper({
- mountType: shallowMount,
- activeNotifications: testData.notifications.linkActions
- })
- const linkButton = wrapper.find(selectors.link)
-
- expect(linkButton.exists()).toBeTruthy()
- expect(linkButton.text()).toBe('http://test.link')
- })
- })
-
- describe('when active notification has multiple notifications', () => {
- it('displays all notifications from active notifications', () => {
- const { wrapper } = getWrapper({
- mountType: shallowMount,
- activeNotifications: testData.notifications.twoActiveNotifications
- })
- const subject = wrapper.findAll(selectors.subject)
- const message = wrapper.findAll(selectors.message)
-
- expect(subject).toHaveLength(2)
- expect(message).toHaveLength(2)
- expect(subject.at(0).text()).toBe('First Notification')
- expect(subject.at(1).text()).toBe('Second Notification')
- expect(message.at(0).text()).toBe('This is first test message')
- expect(message.at(1).text()).toBe('This is second test message')
- })
- })
-})
-
-function getWrapper({ mountType = mount, mocks = {}, activeNotifications = [] } = {}) {
- const localMocks = { ...defaultComponentMocks(), ...mocks }
- const jsonResponse = {
- json: jest.fn().mockImplementation(() => Promise.resolve({ ocs: { data: [] } }))
- }
- localMocks.$client.requests.ocs.mockImplementation(() =>
- Promise.resolve(mockDeep(jsonResponse))
- )
- const storeOptions = { ...defaultStoreMockOptions }
- storeOptions.getters.activeNotifications.mockImplementation(() => activeNotifications)
- const store = createStore(storeOptions)
- return {
- mocks: localMocks,
- storeOptions,
- wrapper: mountType(Notifications, {
- global: {
- renderStubDefaultSlot: true,
- plugins: [...defaultPlugins(), store],
- mocks: localMocks,
- stubs: { 'oc-icon': true }
- }
- })
- }
-}
diff --git a/packages/web-runtime/tests/unit/components/Topbar/NotificationBell.spec.ts b/packages/web-runtime/tests/unit/components/Topbar/NotificationBell.spec.ts
index 0953e9eb2f2..f545e3d9e28 100644
--- a/packages/web-runtime/tests/unit/components/Topbar/NotificationBell.spec.ts
+++ b/packages/web-runtime/tests/unit/components/Topbar/NotificationBell.spec.ts
@@ -34,7 +34,7 @@ describe('NotificationBell', () => {
notificationCount: 0
}
})
- expect(wrapper.find('#oc-notification-bell').attributes('aria-label')).toEqual('Notifications')
+ expect(wrapper.find('#oc-notifications-bell').attributes('aria-label')).toEqual('Notifications')
})
it('animates when notification count changes', async () => {
const { wrapper } = getWrapper({
diff --git a/packages/web-runtime/tests/unit/components/Topbar/Notifications.spec.ts b/packages/web-runtime/tests/unit/components/Topbar/Notifications.spec.ts
new file mode 100644
index 00000000000..90d37a7d4ca
--- /dev/null
+++ b/packages/web-runtime/tests/unit/components/Topbar/Notifications.spec.ts
@@ -0,0 +1,240 @@
+import Notifications from 'web-runtime/src/components/Topbar/Notifications.vue'
+import { Notification, NotificationAction } from 'web-runtime/src/helpers/notifications'
+import { mock, mockDeep } from 'jest-mock-extended'
+import {
+ createStore,
+ defaultComponentMocks,
+ defaultPlugins,
+ shallowMount,
+ defaultStoreMockOptions
+} from 'web-test-helpers'
+import { OwnCloudSdk } from 'web-client/src/types'
+import { SpaceResource } from 'web-client'
+
+const selectors = {
+ notificationBellStub: 'notification-bell-stub',
+ avatarImageStub: 'avatar-image-stub',
+ noNewNotifications: '.oc-notifications-no-new',
+ markAll: '.oc-notifications-mark-all',
+ notificationsLoading: '.oc-notifications-loading',
+ notificationItem: '.oc-notifications-item',
+ notificationSubject: '.oc-notifications-subject',
+ notificationMessage: '.oc-notifications-message',
+ notificationLink: '.oc-notifications-link',
+ notificationActions: '.oc-notifications-actions'
+}
+
+describe('Notification component', () => {
+ it('renders the notification bell and no notifications if there are none', () => {
+ const { wrapper } = getWrapper()
+ expect(wrapper.find(selectors.notificationBellStub).exists()).toBeTruthy()
+ expect(wrapper.find(selectors.noNewNotifications).exists()).toBeTruthy()
+ expect(wrapper.find(selectors.markAll).exists()).toBeFalsy()
+ })
+ it('renders a set of notifications', async () => {
+ const notifications = [mock({ messageRich: undefined })]
+ const { wrapper } = getWrapper({ notifications })
+ await wrapper.vm.fetchNotificationsTask.last
+ expect(wrapper.find(selectors.noNewNotifications).exists()).toBeFalsy()
+ expect(wrapper.findAll(selectors.notificationItem).length).toBe(notifications.length)
+ })
+ it('renders the loading state', async () => {
+ const notifications = [mock({ messageRich: undefined })]
+ const { wrapper } = getWrapper({ notifications })
+ await wrapper.vm.fetchNotificationsTask.last
+ wrapper.vm.loading = true
+ await wrapper.vm.$nextTick()
+ expect(wrapper.find(selectors.notificationsLoading).exists()).toBeTruthy()
+ })
+ it('marks all notifications as read', async () => {
+ const notifications = [mock({ messageRich: undefined })]
+ const { wrapper, mocks } = getWrapper({ notifications })
+ await wrapper.vm.fetchNotificationsTask.last
+ await wrapper.find(selectors.markAll).trigger('click')
+ expect(wrapper.find(selectors.notificationItem).exists()).toBeFalsy()
+ expect(mocks.$clientService.owncloudSdk.requests.ocs).toHaveBeenCalledTimes(2)
+ })
+ describe('avatar', () => {
+ it('loads based on the username', async () => {
+ const notification = mock({
+ messageRich: undefined,
+ user: 'einstein'
+ })
+ const { wrapper } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ const avatarImageStub = wrapper.findComponent(selectors.avatarImageStub)
+ expect(avatarImageStub.attributes('userid')).toEqual(notification.user)
+ expect(avatarImageStub.attributes('user-name')).toEqual(notification.user)
+ })
+ it('loads based on the rich parameters', async () => {
+ const displayname = 'Albert Einstein'
+ const name = 'einstein'
+ const notification = mock({
+ messageRich: undefined,
+ messageRichParameters: { user: { displayname, name } }
+ })
+ const { wrapper } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ const avatarImageStub = wrapper.findComponent(selectors.avatarImageStub)
+ expect(avatarImageStub.attributes('userid')).toEqual(name)
+ expect(avatarImageStub.attributes('user-name')).toEqual(displayname)
+ })
+ })
+ describe('subject', () => {
+ it('displays if no message given', async () => {
+ const notification = mock({
+ messageRich: undefined,
+ message: undefined
+ })
+ const { wrapper } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ expect(wrapper.find(selectors.notificationSubject).exists()).toBeTruthy()
+ })
+ })
+ describe('message', () => {
+ it('displays simple message if messageRich not given', async () => {
+ const notification = mock({
+ messageRich: undefined,
+ message: 'some message'
+ })
+ const { wrapper } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ wrapper.vm.showDrop()
+ await wrapper.vm.$nextTick()
+ expect(wrapper.find(selectors.notificationMessage).text()).toEqual(notification.message)
+ })
+ it('displays rich message and interpolates the text', async () => {
+ const notification = mock({
+ messageRich: '{user} shared {resource} with you',
+ messageRichParameters: {
+ user: { displayname: 'Albert Einstein' },
+ resource: { name: 'someFile.txt' }
+ }
+ })
+ const { wrapper } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ wrapper.vm.showDrop()
+ await wrapper.vm.$nextTick()
+ expect(wrapper.find(selectors.notificationMessage).text()).toEqual(
+ 'Albert Einstein shared someFile.txt with you'
+ )
+ })
+ })
+ describe('link', () => {
+ it('displays if given directly', async () => {
+ const notification = mock({
+ messageRich: undefined,
+ link: 'http://some-link.com'
+ })
+ const { wrapper } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ expect(wrapper.find(selectors.notificationLink).exists()).toBeTruthy()
+ })
+ describe('if given via messageRichParameters', () => {
+ it('renders notification as link for shares', async () => {
+ const notification = mock({
+ messageRich: '{user} shared {resource} with you',
+ object_type: 'share',
+ messageRichParameters: {
+ user: { displayname: 'Albert Einstein' },
+ resource: { name: 'someFile.txt' },
+ share: { id: '1' }
+ }
+ })
+ const { wrapper } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ wrapper.vm.showDrop()
+ await wrapper.vm.$nextTick()
+ const routerLink = wrapper.findComponent(
+ `${selectors.notificationItem} router-link-stub`
+ )
+ expect(routerLink.props('to').name).toEqual('files-shares-with-me')
+ expect(routerLink.props('to').query).toEqual({
+ scrollTo: notification.messageRichParameters.share.id
+ })
+ })
+ it('renders notification as link for spaces', async () => {
+ const spaceMock = mock({
+ fileId: '1',
+ getDriveAliasAndItem: () => 'driveAlias',
+ disabled: false
+ })
+ const notification = mock({
+ messageRich: '{user} added you to space {space}',
+ object_type: 'storagespace',
+ messageRichParameters: {
+ user: { displayname: 'Albert Einstein' },
+ space: { name: 'someFile.txt', id: `${spaceMock.fileId}!2` }
+ }
+ })
+ const { wrapper } = getWrapper({ notifications: [notification], spaces: [spaceMock] })
+ await wrapper.vm.fetchNotificationsTask.last
+ wrapper.vm.showDrop()
+ await wrapper.vm.$nextTick()
+ const routerLink = wrapper.findComponent(
+ `${selectors.notificationItem} router-link-stub`
+ )
+ expect(routerLink.props('to').params).toEqual({
+ driveAliasAndItem: 'driveAlias'
+ })
+ })
+ })
+ })
+ describe('actions', () => {
+ it('display if given', async () => {
+ const notification = mock({
+ messageRich: undefined,
+ actions: [mock()]
+ })
+ const { wrapper } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ expect(wrapper.find(selectors.notificationActions).exists()).toBeTruthy()
+ })
+ it('remove the notification when triggered', async () => {
+ const notification = mock({
+ notification_id: '1',
+ messageRich: undefined,
+ actions: [mock({ link: 'http://some-link.com' })]
+ })
+ const { wrapper, mocks } = getWrapper({ notifications: [notification] })
+ await wrapper.vm.fetchNotificationsTask.last
+ expect(wrapper.find(selectors.notificationItem).exists()).toBeTruthy()
+ const jsonResponse = {
+ json: jest.fn().mockResolvedValue({ ocs: { data: {} } })
+ }
+ mocks.$clientService.owncloudSdk.requests.ocs.mockResolvedValue(
+ mockDeep(jsonResponse)
+ )
+ await wrapper.find(`${selectors.notificationActions} button`).trigger('click')
+ await wrapper.vm.$nextTick()
+ expect(wrapper.find(selectors.notificationItem).exists()).toBeFalsy()
+ })
+ })
+})
+
+function getWrapper({ mocks = {}, notifications = [], spaces = [] } = {}) {
+ const localMocks = { ...defaultComponentMocks(), ...mocks }
+ const clientMock = mockDeep()
+ const jsonResponse = {
+ json: jest.fn().mockResolvedValue({ ocs: { data: notifications } }),
+ headers: {}
+ }
+ clientMock.requests.ocs.mockResolvedValue(mockDeep(jsonResponse))
+ localMocks.$clientService.owncloudSdk = clientMock
+
+ const storeOptions = { ...defaultStoreMockOptions }
+ storeOptions.modules.runtime.modules.spaces.getters.spaces.mockReturnValue(spaces)
+ const store = createStore(storeOptions)
+ return {
+ mocks: localMocks,
+ storeOptions,
+ wrapper: shallowMount(Notifications, {
+ global: {
+ renderStubDefaultSlot: true,
+ plugins: [...defaultPlugins(), store],
+ mocks: localMocks,
+ stubs: { 'avatar-image': true, OcButton: false }
+ }
+ })
+ }
+}
diff --git a/packages/web-runtime/tests/unit/components/Topbar/TopBar.spec.ts b/packages/web-runtime/tests/unit/components/Topbar/TopBar.spec.ts
index af1e63423db..bfb0dd0093b 100644
--- a/packages/web-runtime/tests/unit/components/Topbar/TopBar.spec.ts
+++ b/packages/web-runtime/tests/unit/components/Topbar/TopBar.spec.ts
@@ -33,7 +33,6 @@ describe('Top Bar component', () => {
it('Displays applications menu', () => {
const { wrapper } = getWrapper()
expect(wrapper.find('applications-menu-stub').exists()).toBeTruthy()
- expect(wrapper.html()).toMatchSnapshot()
})
it('should display notifications bell', () => {
const { wrapper } = getWrapper({
diff --git a/packages/web-runtime/tests/unit/components/Topbar/__snapshots__/NotificationBell.spec.ts.snap b/packages/web-runtime/tests/unit/components/Topbar/__snapshots__/NotificationBell.spec.ts.snap
index 96eb92024b1..22f03052fdc 100644
--- a/packages/web-runtime/tests/unit/components/Topbar/__snapshots__/NotificationBell.spec.ts.snap
+++ b/packages/web-runtime/tests/unit/components/Topbar/__snapshots__/NotificationBell.spec.ts.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NotificationBell should match snapshot 1`] = `
-