From 0449d13c7effa07b8bc0f6de10206fee2cf6838b Mon Sep 17 00:00:00 2001
From: Ilja <ilja@ilja.space>
Date: Mon, 12 Sep 2022 11:59:42 +0200
Subject: [PATCH] Statuses "Change scope" dropdown

---
 src/components/Status/index.vue             |  7 +-
 src/views/users/index.vue                   |  1 -
 test/components/Status/index.test.js        | 71 +++++++++++++++++++++
 test/components/Status/store.conf.js        | 47 ++++++++++++++
 test/views/statuses/statusShowStore.conf.js |  8 ++-
 5 files changed, 131 insertions(+), 3 deletions(-)
 create mode 100644 test/components/Status/index.test.js
 create mode 100644 test/components/Status/store.conf.js

diff --git a/src/components/Status/index.vue b/src/components/Status/index.vue
index f2b071c2..a3283a29 100644
--- a/src/components/Status/index.vue
+++ b/src/components/Status/index.vue
@@ -23,7 +23,7 @@
             </router-link>
           </div>
         </div>
-        <div class="status-actions">
+        <div v-if="isPrivileged(['messages_delete'], [])" class="status-actions">
           <div class="status-tags">
             <el-tag v-if="status.sensitive" type="warning" size="large">{{ $t('reports.sensitive') }}</el-tag>
             <el-tag size="large">{{ capitalizeFirstLetter(status.visibility) }}</el-tag>
@@ -184,6 +184,11 @@ export default {
     capitalizeFirstLetter(str) {
       return str.charAt(0).toUpperCase() + str.slice(1)
     },
+    isPrivileged(accepted_privileges, accepted_roles) {
+      const user_privileges = this.$store.getters.privileges
+      const user_roles = this.$store.getters.roles
+      return accepted_privileges.some(privilege => user_privileges.indexOf(privilege) >= 0) || accepted_roles.some(role => user_roles.indexOf(role) >= 0)
+    },
     changeStatus(statusId, isSensitive, visibility) {
       this.$store.dispatch('ChangeStatusScope', {
         statusId,
diff --git a/src/views/users/index.vue b/src/views/users/index.vue
index f053aace..e3f0bfc2 100644
--- a/src/views/users/index.vue
+++ b/src/views/users/index.vue
@@ -213,7 +213,6 @@ export default {
       const user_roles = this.$store.getters.roles
       return accepted_privileges.some(privilege => user_privileges.indexOf(privilege) >= 0) || accepted_roles.some(role => user_roles.indexOf(role) >= 0)
     },
-
     closeResetPasswordDialog() {
       this.resetPasswordDialogOpen = false
       this.$store.dispatch('RemovePasswordToken')
diff --git a/test/components/Status/index.test.js b/test/components/Status/index.test.js
new file mode 100644
index 00000000..2401eec6
--- /dev/null
+++ b/test/components/Status/index.test.js
@@ -0,0 +1,71 @@
+import Vuex from 'vuex'
+import { mount, createLocalVue, config } from '@vue/test-utils'
+import flushPromises from 'flush-promises'
+import Element from 'element-ui'
+import Statuses from '@/views/statuses/index'
+import {
+  storeNoPrivilegesNoRoles,
+  storeWithPrivilegesMessagesDeleteNoRoles
+} from './store.conf'
+import { cloneDeep } from 'lodash'
+
+config.mocks["$t"] = (t) => t
+config.stubs.transition = false
+
+const localVue = createLocalVue()
+localVue.use(Vuex)
+localVue.use(Element)
+
+jest.mock('@/api/app')
+jest.mock('@/api/nodeInfo')
+jest.mock('@/api/peers')
+jest.mock('@/api/settings')
+jest.mock('@/api/status')
+
+describe('Statuses', () => {
+  it('Allows to change scope when privileged', async (done) => {
+    const store = new Vuex.Store(cloneDeep(storeWithPrivilegesMessagesDeleteNoRoles))
+    const wrapper = mount(Statuses, {
+      store: store,
+      localVue
+    })
+    await flushPromises()
+
+    store.dispatch('HandleFilterChange', 'heaven.com')
+    wrapper.vm.handleFilterChange()
+    await flushPromises()
+
+    const menu = wrapper.find('.status-actions')
+    const menu_items = menu.findAll('.el-dropdown-menu__item')
+    const menu_items_text = menu_items.wrappers.map(menu_item => menu_item.text()).sort()
+
+    expect(menu.isVisible()).toEqual(true)
+    expect(menu_items_text).toEqual([
+      'reports.addSensitive',
+      'reports.deleteStatus',
+      'reports.private',
+      'reports.public'
+    ])
+
+    done()
+  })
+
+  it('Allows to change scope when not privileged', async (done) => {
+    const store = new Vuex.Store(cloneDeep(storeNoPrivilegesNoRoles))
+    const wrapper = mount(Statuses, {
+      store: store,
+      localVue
+    })
+    await flushPromises()
+
+    store.dispatch('HandleFilterChange', 'heaven.com')
+    wrapper.vm.handleFilterChange()
+    await flushPromises()
+
+    const menu = wrapper.find('.status-actions')
+
+    expect(menu.exists()).toEqual(false)
+
+    done()
+  })
+})
diff --git a/test/components/Status/store.conf.js b/test/components/Status/store.conf.js
new file mode 100644
index 00000000..18945a74
--- /dev/null
+++ b/test/components/Status/store.conf.js
@@ -0,0 +1,47 @@
+import app from '@/store/modules/app'
+import peers from '@/store/modules/peers'
+import user from '@/store/modules/user'
+import users from '@/store/modules/users'
+import settings from '@/store/modules/settings'
+import status from '@/store/modules/status'
+import getters from '@/store/getters'
+
+export const storeNoPrivilegesNoRoles = {
+  modules: {
+    app,
+    peers,
+    settings,
+    status,
+    user: {
+      ...user,
+      state: {
+        ...user.state,
+        authHost: 'localhost:4000',
+        roles: [],
+        privileges: []
+      }
+    },
+    users
+  },
+  getters
+}
+
+export const storeWithPrivilegesMessagesDeleteNoRoles = {
+  modules: {
+    app,
+    peers,
+    settings,
+    status,
+    user: {
+      ...user,
+      state: {
+        ...user.state,
+        authHost: 'localhost:4000',
+        roles: [],
+        privileges: ['messages_delete']
+      }
+    },
+    users
+  },
+  getters
+}
diff --git a/test/views/statuses/statusShowStore.conf.js b/test/views/statuses/statusShowStore.conf.js
index cc45cd69..38a3ec18 100644
--- a/test/views/statuses/statusShowStore.conf.js
+++ b/test/views/statuses/statusShowStore.conf.js
@@ -18,7 +18,13 @@ export default {
       state: {
         ...user.state,
         roles: ['admin'],
-        privileges: ['users_manage_activation_state', 'users_delete', 'users_manage_tags', 'users_manage_credentials']
+        privileges: [
+          'users_manage_activation_state',
+          'users_delete',
+          'users_manage_tags',
+          'users_manage_credentials',
+          'messages_delete'
+        ]
       }
     },
     userProfile,
-- 
GitLab