Merge pull request #1068 from h3poteto/iss-1065

closes #1065 Fix comparison between login user and target account
This commit is contained in:
AkiraFukushima 2019-10-28 23:24:06 +09:00 committed by GitHub
commit 2c8af191a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 222 additions and 8 deletions

View File

@ -0,0 +1,198 @@
import { Account } from 'megalodon'
import { createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'
import AccountProfile, { AccountProfileState } from '~/src/renderer/store/TimelineSpace/Contents/SideBar/AccountProfile'
const state = (account: Account | null): AccountProfileState => {
return {
loading: false,
relationship: null,
account: account
}
}
const timelineSpace = {
namespaced: true,
state: {
account: {
baseURL: 'https://example.com',
domain: 'example.com',
clientId: 'sampleId',
clientSecret: 'sampleSecret',
accessToken: 'sampleAccessToken',
refreshToken: null,
username: 'h3poteto',
accountID: '1',
avatar: null,
order: 1
}
}
}
const initStore = (account: Account | null) => {
return {
namespaced: true,
state: state(account),
actions: AccountProfile.actions,
mutations: AccountProfile.mutations,
getters: AccountProfile.getters
}
}
describe('AccountProfile', () => {
let store
let localVue
beforeEach(() => {
localVue = createLocalVue()
localVue.use(Vuex)
store = new Vuex.Store({
modules: {
AccountProfile: initStore(null),
TimelineSpace: timelineSpace
}
})
})
describe('isOwnProfile', () => {
describe('target is a same Mastodon account', () => {
const account: Account = {
id: '1',
username: 'h3poteto',
acct: 'h3poteto@example.com',
display_name: 'h3poteto',
locked: false,
created_at: '2019-10-28T23:11:54',
followers_count: 100,
following_count: 200,
statuses_count: 500,
note: '',
url: 'https://example.com/@h3poteto',
avatar: '',
avatar_static: '',
header: '',
header_static: '',
emojis: [],
moved: null,
fields: null,
bot: false
}
beforeEach(() => {
store = new Vuex.Store({
modules: {
AccountProfile: initStore(account),
TimelineSpace: timelineSpace
}
})
})
it('should be matched', () => {
expect(store.getters['AccountProfile/isOwnProfile']).toBeTruthy()
})
})
describe('target is another Mastodon account', () => {
const account: Account = {
id: '1',
username: 'h3poteto',
acct: 'h3poteto@another.example.com',
display_name: 'h3poteto',
locked: false,
created_at: '2019-10-28T23:11:54',
followers_count: 100,
following_count: 200,
statuses_count: 500,
note: '',
url: 'https://another.example.com/@h3poteto',
avatar: '',
avatar_static: '',
header: '',
header_static: '',
emojis: [],
moved: null,
fields: null,
bot: false
}
beforeEach(() => {
store = new Vuex.Store({
modules: {
AccountProfile: initStore(account),
TimelineSpace: timelineSpace
}
})
})
it('should be matched', () => {
expect(store.getters['AccountProfile/isOwnProfile']).toBeFalsy()
})
})
describe('target is a same Pleroma account', () => {
const account: Account = {
id: '1',
username: 'h3poteto',
acct: 'h3poteto@example.com',
display_name: 'h3poteto',
locked: false,
created_at: '2019-10-28T23:11:54',
followers_count: 100,
following_count: 200,
statuses_count: 500,
note: '',
url: 'https://example.com/users/h3poteto',
avatar: '',
avatar_static: '',
header: '',
header_static: '',
emojis: [],
moved: null,
fields: null,
bot: false
}
beforeEach(() => {
store = new Vuex.Store({
modules: {
AccountProfile: initStore(account),
TimelineSpace: timelineSpace
}
})
})
it('should be matched', () => {
expect(store.getters['AccountProfile/isOwnProfile']).toBeTruthy()
})
})
describe('target is another Pleroma account', () => {
const account: Account = {
id: '1',
username: 'h3poteto',
acct: 'h3poteto@another.example.com',
display_name: 'h3poteto',
locked: false,
created_at: '2019-10-28T23:11:54',
followers_count: 100,
following_count: 200,
statuses_count: 500,
note: '',
url: 'https://another.example.com/users/h3poteto',
avatar: '',
avatar_static: '',
header: '',
header_static: '',
emojis: [],
moved: null,
fields: null,
bot: false
}
beforeEach(() => {
store = new Vuex.Store({
modules: {
AccountProfile: initStore(account),
TimelineSpace: timelineSpace
}
})
})
it('should be matched', () => {
expect(store.getters['AccountProfile/isOwnProfile']).toBeFalsy()
})
})
})
})

View File

@ -8,14 +8,14 @@
aria-label="account profile">
<div class="header-background" v-bind:style="{ backgroundImage: 'url(' + account.header + ')' }">
<div class="header">
<div class="follow-follower" v-if="relationship !== null && relationship !== '' && account.username!==user.username">
<div class="follow-follower" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
<div class="follower-status">
<el-tag class="status" size="small" v-if="relationship.followed_by">{{ $t('side_bar.account_profile.follows_you') }}</el-tag>
<el-tag class="status" size="medium" v-else>{{ $t('side_bar.account_profile.doesnt_follow_you') }}</el-tag>
</div>
</div>
<div class="user-info">
<div class="more" v-if="relationship !== null && relationship !== '' && account.username!==user.username">
<div class="more" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
<popper trigger="click" :options="{placement: 'bottom'}" ref="popper">
<div class="popper">
<ul class="menu-list">
@ -48,7 +48,7 @@
<div class="icon" role="presentation">
<FailoverImg :src="account.avatar" :alt="`Avatar of ${account.username}`" />
</div>
<div class="follow-status" v-if="relationship !== null && relationship !== '' && account.username!==user.username">
<div class="follow-status" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
<div v-if="relationship.following" class="unfollow" @click="unfollow(account)" :title="$t('side_bar.account_profile.unfollow')">
<icon name="user-times" scale="1.5"></icon>
</div>
@ -107,7 +107,7 @@
</template>
<script>
import { mapState } from 'vuex'
import { mapState, mapGetters } from 'vuex'
import { shell } from 'electron'
import { findLink } from '~/src/renderer/utils/tootParser'
import emojify from '~/src/renderer/utils/emojify'
@ -131,7 +131,6 @@ export default {
},
computed: {
...mapState({
user: state => state.TimelineSpace.account,
theme: (state) => {
return {
'--theme-mask-color': state.App.theme.wrapper_mask_color,
@ -146,7 +145,8 @@ export default {
loading: state => state.loading,
muting: state => state.relationship && state.relationship.muting,
blocking: state => state.relationship && state.relationship.blocking
})
}),
...mapGetters('TimelineSpace/Contents/SideBar/AccountProfile', ['isOwnProfile'])
},
watch: {
account: function () {

View File

@ -2,7 +2,7 @@ import Mastodon, { Account, Relationship, Response } from 'megalodon'
import Timeline, { TimelineState } from './AccountProfile/Timeline'
import Follows, { FollowsState } from './AccountProfile/Follows'
import Followers, { FollowersState } from './AccountProfile/Followers'
import { Module, MutationTree, ActionTree } from 'vuex'
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
import { RootState } from '@/store'
export type AccountProfileState = {
@ -165,6 +165,21 @@ const actions: ActionTree<AccountProfileState, RootState> = {
}
}
const getters: GetterTree<AccountProfileState, RootState> = {
isOwnProfile: (state, _getters, rootState) => {
if (!state.account) {
return false
}
const own = rootState.TimelineSpace.account
// For Mastodon
if (`${own.baseURL}/@${own.username}` === state.account.url) {
return true
}
// For Pleroma
return `${own.baseURL}/users/${own.username}` === state.account.url
}
}
const AccountProfile: Module<AccountProfileState, RootState> = {
namespaced: true,
modules: {
@ -174,7 +189,8 @@ const AccountProfile: Module<AccountProfileState, RootState> = {
},
state: state,
mutations: mutations,
actions: actions
actions: actions,
getters: getters
}
class AccountNotFound extends Error {}