diff --git a/src/api/__mocks__/users.js b/src/api/__mocks__/users.js index b5aca6a1a2efe34f238a3ed0dbe24889582ef122..31657293b8cdc0d0c86748962b92b68129e3e5d9 100644 --- a/src/api/__mocks__/users.js +++ b/src/api/__mocks__/users.js @@ -4,6 +4,10 @@ export let users = [ { active: false, deactivated: true, id: 'abc', nickname: 'john', local: true, external: false, roles: { admin: false, moderator: false }, tags: ['strip_media'] } ] +const userProfile = { avatar: 'avatar.jpg', display_name: 'Allis', nickname: 'allis', id: '2', tags: [], roles: { admin: true, moderator: false }, local: true, external: false } + +const userStatuses = [] + const filterUsers = (str) => { const filters = str.split(',').filter(item => item.length > 0) if (filters.length === 0) { @@ -20,6 +24,10 @@ const filterUsers = (str) => { return applyFilters([], filters, users) } +export async function fetchUser(id, authHost, token) { + return Promise.resolve({ data: userProfile }) +} + export async function fetchUsers(filters, authHost, token, page = 1) { const filteredUsers = filterUsers(filters) return Promise.resolve({ data: { @@ -29,6 +37,10 @@ export async function fetchUsers(filters, authHost, token, page = 1) { }}) } +export async function fetchUserStatuses(id, authHost, godmode, token) { + return Promise.resolve({ data: userStatuses }) +} + export async function getPasswordResetToken(nickname, authHost, token) { return Promise.resolve({ data: { token: 'g05lxnBJQnL', link: 'http://url/api/pleroma/password_reset/g05lxnBJQnL' }}) } diff --git a/src/lang/en.js b/src/lang/en.js index d48934556dd6de016a586ab3b8a737959f20b231..13c309066679f6c39d90543b64a27147626ab44d 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -236,11 +236,17 @@ export default { tags: 'Tags', moderator: 'Moderator', admin: 'Admin', - local: 'Local', + local: 'local', + external: 'external', + localUppercase: 'Local', nickname: 'Nickname', - deactivated: 'Deactivated', recentStatuses: 'Recent Statues', - showPrivateStatuses: 'Show private statuses' + showPrivateStatuses: 'Show private statuses', + roles: 'Roles', + activeUppercase: 'Active', + active: 'active', + deactivated: 'deactivated', + noStatuses: 'No statuses to show' }, usersFilter: { inputPlaceholder: 'Select filter', diff --git a/src/views/status/Status.vue b/src/views/status/Status.vue index b33744b1db2f60e7ae764c45214c796b3bda7b90..60fbb61039e18631fa2cdb2bc82170829b1cef09 100644 --- a/src/views/status/Status.vue +++ b/src/views/status/Status.vue @@ -185,54 +185,56 @@ export default { </script> <style rel='stylesheet/scss' lang='scss'> -.account { - text-decoration: underline; - line-height: 26px; - font-size: 13px; -} -.image { - width: 20%; - img { - width: 100%; - } -} -.show-more-button { - margin-left: 5px; -} -.status-account { - display: flex; - align-items: center; -} -.status-avatar-img { - width: 15px; - height: 15px; - margin-right: 5px; -} -.status-account-name { - margin: 0; - height: 22px; -} -.status-body { - display: flex; - flex-direction: column; -} -.status-content { - font-size: 15px; - line-height: 26px; -} .status-card { - margin-bottom: 15px; -} -.status-deleted { - font-style: italic; - margin-top: 3px; -} -.status-header { - display: flex; - justify-content: space-between; -} -.status-without-content { - font-style: italic; + .account { + text-decoration: underline; + line-height: 26px; + font-size: 13px; + } + .image { + width: 20%; + img { + width: 100%; + } + } + .show-more-button { + margin-left: 5px; + } + .status-account { + display: flex; + align-items: center; + } + .status-avatar-img { + width: 15px; + height: 15px; + margin-right: 5px; + } + .status-account-name { + margin: 0; + height: 22px; + } + .status-body { + display: flex; + flex-direction: column; + } + .status-content { + font-size: 15px; + line-height: 26px; + } + .status-card { + margin-bottom: 15px; + } + .status-deleted { + font-style: italic; + margin-top: 3px; + } + .status-header { + display: flex; + justify-content: space-between; + } + .status-without-content { + font-style: italic; + } } @media only screen and (max-width: 760px), diff --git a/src/views/users/index.vue b/src/views/users/index.vue index 4e67ee70fc5caa681ddd5be45afed256d526e631..f9b5e10fca6dee787fa813b3ff94f126f73d49a5 100644 --- a/src/views/users/index.vue +++ b/src/views/users/index.vue @@ -156,9 +156,6 @@ </p> </div> </el-dialog> - <div v-if="users.length === 0" class="no-users-message"> - <p>There are no users to display</p> - </div> <div v-if="!loading" class="pagination"> <el-pagination :total="usersCount" diff --git a/src/views/users/show.vue b/src/views/users/show.vue index f721a7f5aeab06616d9cea7d0fe6f4cfb1f27325..6f5634725cb7cdb25a7befc402ee19d6dda9c3c8 100644 --- a/src/views/users/show.vue +++ b/src/views/users/show.vue @@ -5,60 +5,60 @@ <h1>{{ user.display_name }}</h1> </header> <el-row> - <el-col :span="6"> - <div class="el-table el-table--fit el-table--enable-row-hover el-table--enable-row-transition el-table--medium"> - <table class="el-table__body"> - <tbody> - <tr class="el-table__row"> - <td class="name-col">ID</td> - <td class="value-col"> - {{ user.id }} - </td> - </tr> - <tr class="el-table__row"> - <td>{{ $t('userProfile.tags') }}</td> - <td> - <el-tag v-for="tag in user.tags" :key="tag">{{ tag }}</el-tag> - <span v-if="user.tags.length === 0">None</span> - </td> - </tr> - <tr class="el-table__row"> - <td>{{ $t('userProfile.moderator') }}</td> - <td> - <el-tag v-if="user.roles.moderator" type="success"><i class="el-icon-check" /></el-tag> - <el-tag v-if="!user.roles.moderator" type="danger"><i class="el-icon-error" /></el-tag> - </td> - </tr> - <tr class="el-table__row"> - <td>{{ $t('userProfile.admin') }}</td> - <td> - <el-tag v-if="user.roles.admin" type="success"><i class="el-icon-check" /></el-tag> - <el-tag v-if="!user.roles.admin" type="danger"><i class="el-icon-error" /></el-tag> - </td> - </tr> - <tr class="el-table__row"> - <td>{{ $t('userProfile.local') }}</td> - <td> - <el-tag v-if="user.local" type="success"><i class="el-icon-check" /></el-tag> - <el-tag v-if="!user.local" type="danger"><i class="el-icon-error" /></el-tag> - </td> - </tr> - <tr class="el-table__row"> - <td>{{ $t('userProfile.deactivated') }}</td> - <td> - <el-tag v-if="user.deactivated" type="success"><i class="el-icon-check" /></el-tag> - <el-tag v-if="!user.deactivated" type="danger"><i class="el-icon-error" /></el-tag> - </td> - </tr> - <tr class="el-table__row"> - <td>{{ $t('userProfile.nickname') }}</td> - <td> - {{ user.nickname }} - </td> - </tr> - </tbody> - </table> - </div> + <el-col :span="8"> + <el-card class="user-profile-card"> + <div class="el-table el-table--fit el-table--enable-row-hover el-table--enable-row-transition el-table--medium"> + <table class="user-profile-table"> + <tbody> + <tr class="el-table__row"> + <td>{{ $t('userProfile.nickname') }}</td> + <td> + {{ user.nickname }} + </td> + </tr> + <tr class="el-table__row"> + <td class="name-col">ID</td> + <td class="value-col"> + {{ user.id }} + </td> + </tr> + <tr class="el-table__row"> + <td>{{ $t('userProfile.tags') }}</td> + <td> + <el-tag v-for="tag in user.tags" :key="tag" class="user-profile-tag">{{ tag }}</el-tag> + <span v-if="user.tags.length === 0">—</span> + </td> + </tr> + <tr class="el-table__row"> + <td>{{ $t('userProfile.roles') }}</td> + <td> + <el-tag v-if="user.roles.admin" class="user-profile-tag"> + {{ $t('users.admin') }} + </el-tag> + <el-tag v-if="user.roles.moderator" class="user-profile-tag"> + {{ $t('users.moderator') }} + </el-tag> + <span v-if="!user.roles.moderator && !user.roles.admin">—</span> + </td> + </tr> + <tr class="el-table__row"> + <td>{{ $t('userProfile.localUppercase') }}</td> + <td> + <el-tag v-if="user.local" type="info">{{ $t('userProfile.local') }}</el-tag> + <el-tag v-if="!user.local" type="info">{{ $t('userProfile.external') }}</el-tag> + </td> + </tr> + <tr class="el-table__row"> + <td>{{ $t('userProfile.activeUppercase') }}</td> + <td> + <el-tag v-if="user.deactivated" type="success">{{ $t('userProfile.active') }}</el-tag> + <el-tag v-if="!user.deactivated" type="danger">{{ $t('userProfile.deactivated') }}</el-tag> + </td> + </tr> + </tbody> + </table> + </div> + </el-card> </el-col> <el-row type="flex" class="row-bg" justify="space-between"> <el-col :span="18"> @@ -70,11 +70,12 @@ </el-checkbox> </el-col> </el-row> - <el-col :span="18"> + <el-col :span="16"> <el-timeline v-if="!statusesLoading" class="statuses"> <el-timeline-item v-for="status in statuses" :key="status.id"> <status :status="status" :user-id="user.id" :godmode="showPrivate"/> </el-timeline-item> + <p v-if="statuses.length === 0" class="no-statuses">{{ $t('userProfile.noStatuses') }}</p> </el-timeline> </el-col> </el-row> @@ -147,8 +148,16 @@ table { width: 100%; } } +.no-statuses { + margin-left: 28px; + color: #606266; + +} +.recent-statuses-header { + margin-top: 10px; +} .statuses { - padding-right: 20px; + padding: 0 20px 0 0; } .show-private { text-align: right; @@ -156,6 +165,16 @@ table { padding-right: 20px; } .recent-statuses { - margin-left: 40px; + margin-left: 28px; +} +.user-profile-card { + margin-left: 15px; + margin-right: 20px; +} +.user-profile-table { + margin: 0; +} +.user-profile-tag { + margin: 0 4px 4px 0; } </style> diff --git a/test/views/users/show.test.js b/test/views/users/show.test.js new file mode 100644 index 0000000000000000000000000000000000000000..b57501c589bc09467c8fb576e936e30674be2316 --- /dev/null +++ b/test/views/users/show.test.js @@ -0,0 +1,48 @@ +import Vuex from 'vuex' +import { mount, createLocalVue, config } from '@vue/test-utils' +import flushPromises from 'flush-promises' +import Element from 'element-ui' +import UsersShow from '@/views/users/show' +import storeConfig from './store.conf' +import { cloneDeep } from 'lodash' + +config.mocks["$t"] = () => {} + +const localVue = createLocalVue() +localVue.use(Vuex) +localVue.use(Element) + +const $route = { + params: { + id: '2' + } +} + +jest.mock('@/api/nodeInfo') +jest.mock('@/api/users') + +describe('Search and filter users', () => { + let store + + beforeEach(() => { + store = new Vuex.Store(cloneDeep(storeConfig)) + }) + + it('fetches user profile', async (done) => { + const wrapper = mount(UsersShow, { + store, + localVue, + sync: false, + stubs: ['router-link'], + mocks: { + $route + } + }) + + await flushPromises() + expect(wrapper.find('.user-profile-card').isVisible()).toBe(true) + expect(store.state.userProfile.user.nickname).toBe('allis') + expect(store.state.userProfile.user.roles.admin).toBe(true) + done() + }) +}) diff --git a/test/views/users/store.conf.js b/test/views/users/store.conf.js index 77e2b7c8b7e2265c486d6c67e0ae07150fac76d9..89a7622a4a5d8d0dcaa04926f2b8c53bd7ec3840 100644 --- a/test/views/users/store.conf.js +++ b/test/views/users/store.conf.js @@ -1,5 +1,6 @@ import app from '@/store/modules/app' import user from '@/store/modules/user' +import userProfile from '@/store/modules/userProfile' import users from '@/store/modules/users' import getters from '@/store/getters' @@ -7,6 +8,7 @@ export default { modules: { app, user, + userProfile, users }, getters