diff --git a/src/api/public.js b/src/api/public.js
index 740a55ca2..ef799566d 100644
--- a/src/api/public.js
+++ b/src/api/public.js
@@ -26,15 +26,17 @@ export const MASTODON_FOLLOWERS_URL = (
export const MASTODON_STATUS_URL = (id) => `/api/v1/statuses/${id}`
const MASTODON_STATUS_CONTEXT_URL = (id) => `/api/v1/statuses/${id}/context`
-const MASTODON_STATUS_SOURCE_URL = (id) => `/api/v1/statuses/${id}/source`
-const MASTODON_STATUS_HISTORY_URL = (id) => `/api/v1/statuses/${id}/history`
+export const MASTODON_STATUS_SOURCE_URL = (id) =>
+ `/api/v1/statuses/${id}/source`
+export const MASTODON_STATUS_HISTORY_URL = (id) =>
+ `/api/v1/statuses/${id}/history`
const MASTODON_USER_URL = '/api/v1/accounts'
const MASTODON_USER_LOOKUP_URL = ({ acct }) =>
`/api/v1/accounts/lookup${paramsString({ acct })}`
const MASTODON_POLL_URL = (id = '') => `/api/v1/polls/${id}`
-const MASTODON_STATUS_FAVORITEDBY_URL = (id) =>
+export const MASTODON_STATUS_FAVORITEDBY_URL = (id) =>
`/api/v1/statuses/${id}/favourited_by`
-const MASTODON_STATUS_REBLOGGEDBY_URL = (id) =>
+export const MASTODON_STATUS_REBLOGGEDBY_URL = (id) =>
`/api/v1/statuses/${id}/reblogged_by`
const MASTODON_SEARCH_2 = ({
q,
@@ -51,7 +53,7 @@ const MASTODON_SEARCH_2 = ({
const MASTODON_USER_SEARCH_URL = ({ q, resolve }) =>
`/api/v1/accounts/search${paramsString({ q, resolve })}`
const MASTODON_KNOWN_DOMAIN_LIST_URL = '/api/v1/instance/peers'
-const PLEROMA_EMOJI_REACTIONS_URL = (id) =>
+export const PLEROMA_EMOJI_REACTIONS_URL = (id) =>
`/api/v1/pleroma/statuses/${id}/reactions`
const PLEROMA_SCROBBLES_URL = (id, { maxId, sinceId, minId, limit, offset }) =>
`/api/v1/pleroma/accounts/${id}/scrobbles${paramsString({ maxId, sinceId, minId, limit, offset })}`
@@ -174,15 +176,18 @@ export const fetchStatusSource = ({ id, credentials }) =>
credentials,
}).then(({ data, ...rest }) => ({ ...rest, data: parseSource(data) }))
-export const fetchStatusHistory = ({ status, credentials }) =>
+export const fetchStatusHistory = ({ id, credentials }) =>
promisedRequest({
- url: MASTODON_STATUS_HISTORY_URL(status.id),
+ url: MASTODON_STATUS_HISTORY_URL(id),
credentials,
}).then(({ data, ...rest }) => {
- return [...data].reverse().map((item) => {
- item.originalStatus = status
- return { ...rest, data: parseStatus(item) }
- })
+ return {
+ ...rest,
+ data: [...data].reverse().map((item) => {
+ item.originalStatus = status
+ return parseStatus(item)
+ }),
+ }
})
export const listEmojiPacks = ({ page, pageSize, credentials }) =>
diff --git a/src/api/user.js b/src/api/user.js
index 0802d8c8b..cb7195f49 100644
--- a/src/api/user.js
+++ b/src/api/user.js
@@ -29,11 +29,12 @@ const MFA_DISABLE_OTP_URL = '/api/pleroma/accounts/mfa/totp'
const MASTODON_DISMISS_NOTIFICATION_URL = (id) =>
`/api/v1/notifications/${id}/dismiss`
-const MASTODON_FAVORITE_URL = (id) => `/api/v1/statuses/${id}/favourite`
-const MASTODON_UNFAVORITE_URL = (id) => `/api/v1/statuses/${id}/unfavourite`
-const MASTODON_RETWEET_URL = (id) => `/api/v1/statuses/${id}/reblog`
-const MASTODON_UNRETWEET_URL = (id) => `/api/v1/statuses/${id}/unreblog`
-const MASTODON_DELETE_URL = (id) => `/api/v1/statuses/${id}`
+export const MASTODON_FAVORITE_URL = (id) => `/api/v1/statuses/${id}/favourite`
+export const MASTODON_UNFAVORITE_URL = (id) =>
+ `/api/v1/statuses/${id}/unfavourite`
+export const MASTODON_RETWEET_URL = (id) => `/api/v1/statuses/${id}/reblog`
+export const MASTODON_UNRETWEET_URL = (id) => `/api/v1/statuses/${id}/unreblog`
+export const MASTODON_DELETE_URL = (id) => `/api/v1/statuses/${id}`
export const MASTODON_FOLLOW_URL = (id) => `/api/v1/accounts/${id}/follow`
export const MASTODON_UNFOLLOW_URL = (id) => `/api/v1/accounts/${id}/unfollow`
@@ -68,25 +69,29 @@ export const MASTODON_UNMUTE_USER_URL = (id) => `/api/v1/accounts/${id}/unmute`
export const MASTODON_REMOVE_USER_FROM_FOLLOWERS_URL = (id) =>
`/api/v1/accounts/${id}/remove_from_followers`
export const MASTODON_USER_NOTE_URL = (id) => `/api/v1/accounts/${id}/note`
-const MASTODON_BOOKMARK_STATUS_URL = (id) => `/api/v1/statuses/${id}/bookmark`
-const MASTODON_UNBOOKMARK_STATUS_URL = (id) =>
+export const MASTODON_BOOKMARK_STATUS_URL = (id) =>
+ `/api/v1/statuses/${id}/bookmark`
+export const MASTODON_UNBOOKMARK_STATUS_URL = (id) =>
`/api/v1/statuses/${id}/unbookmark`
const MASTODON_POST_STATUS_URL = '/api/v1/statuses'
const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media'
const MASTODON_VOTE_URL = (id) => `/api/v1/polls/${id}/votes`
const MASTODON_PROFILE_UPDATE_URL = '/api/v1/accounts/update_credentials'
const MASTODON_REPORT_USER_URL = '/api/v1/reports'
-const MASTODON_PIN_OWN_STATUS = (id) => `/api/v1/statuses/${id}/pin`
-const MASTODON_UNPIN_OWN_STATUS = (id) => `/api/v1/statuses/${id}/unpin`
-const MASTODON_MUTE_CONVERSATION = (id) => `/api/v1/statuses/${id}/mute`
-const MASTODON_UNMUTE_CONVERSATION = (id) => `/api/v1/statuses/${id}/unmute`
+export const MASTODON_PIN_OWN_STATUS_URL = (id) => `/api/v1/statuses/${id}/pin`
+export const MASTODON_UNPIN_OWN_STATUS_URL = (id) =>
+ `/api/v1/statuses/${id}/unpin`
+export const MASTODON_MUTE_CONVERSATION_URL = (id) =>
+ `/api/v1/statuses/${id}/mute`
+export const MASTODON_UNMUTE_CONVERSATION_URL = (id) =>
+ `/api/v1/statuses/${id}/unmute`
export const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks'
const MASTODON_ANNOUNCEMENTS_URL = '/api/v1/announcements'
const MASTODON_ANNOUNCEMENTS_DISMISS_URL = (id) =>
`/api/v1/announcements/${id}/dismiss`
-const PLEROMA_EMOJI_REACT_URL = (id, emoji) =>
+export const PLEROMA_EMOJI_REACT_URL = (id, emoji) =>
`/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
-const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) =>
+export const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) =>
`/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
const PLEROMA_BOOKMARK_FOLDERS_URL = '/api/v1/pleroma/bookmark_folders'
@@ -155,28 +160,28 @@ export const unbookmarkStatus = ({ id, credentials }) =>
export const pinOwnStatus = ({ id, credentials }) =>
promisedRequest({
- url: MASTODON_PIN_OWN_STATUS(id),
+ url: MASTODON_PIN_OWN_STATUS_URL(id),
credentials,
method: 'POST',
}).then(({ data, ...rest }) => ({ ...rest, data: parseStatus(data) }))
export const unpinOwnStatus = ({ id, credentials }) =>
promisedRequest({
- url: MASTODON_UNPIN_OWN_STATUS(id),
+ url: MASTODON_UNPIN_OWN_STATUS_URL(id),
credentials,
method: 'POST',
}).then(({ data, ...rest }) => ({ ...rest, data: parseStatus(data) }))
export const muteConversation = ({ id, credentials }) =>
promisedRequest({
- url: MASTODON_MUTE_CONVERSATION(id),
+ url: MASTODON_MUTE_CONVERSATION_URL(id),
credentials,
method: 'POST',
}).then(({ data, ...rest }) => ({ ...rest, data: parseStatus(data) }))
export const unmuteConversation = ({ id, credentials }) =>
promisedRequest({
- url: MASTODON_UNMUTE_CONVERSATION(id),
+ url: MASTODON_UNMUTE_CONVERSATION_URL(id),
credentials,
method: 'POST',
}).then(({ data, ...rest }) => ({ ...rest, data: parseStatus(data) }))
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index 63657017c..f5a441d54 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -109,6 +109,11 @@ const conversation = {
}
},
computed: {
+ status() {
+ console.log(this.statusId)
+ console.log(useStatusesStore().allStatuses.get(this.statusId))
+ return useStatusesStore().allStatuses.get(this.statusId)
+ },
maxDepthToShowByDefault() {
// maxDepthInThread = max number of depths that is *visible*
// since our depth starts with 0 and "showing" means "showing children"
@@ -152,9 +157,6 @@ const conversation = {
hideStatus() {
return this.virtualHidden && this.suspendable
},
- status() {
- return useStatusesStore().allStatuses.get(this.statusId)
- },
originalStatusId() {
if (this.status.retweeted_status) {
return this.status.retweeted_status.id
@@ -178,7 +180,9 @@ const conversation = {
this.conversationId,
)
- return [...conversation.values()].toSorted(sortById)
+ return [...conversation.keys()]
+ .map((k) => useStatusesStore().allStatuses.get(k))
+ .toSorted(sortById)
},
statusMap() {
return this.conversation.reduce((res, s) => {
@@ -472,7 +476,7 @@ const conversation = {
}
useStatusesStore().fetchFavsAndRepeats(id)
- useStatusesStore().fetchEmojiReactionsBy(id)
+ useStatusesStore().fetchEmojiReactions(id)
},
toggleExpanded() {
this.expanded = !this.expanded
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index 0833c4f89..ae6e3a0ce 100644
--- a/src/components/conversation/conversation.vue
+++ b/src/components/conversation/conversation.vue
@@ -99,7 +99,7 @@
ref="statusComponent"
class="conversation-status status-fadein panel-body"
- :statusoid="status"
+ :status-id="status.id"
:replies="getReplies(status.id)"
:expandable="!isExpanded"
@@ -152,7 +152,7 @@
ref="statusComponent"
:depth="0"
- :status="status"
+ :status-id="status.id"
:in-profile="inProfile"
:conversation="conversation"
:collapsable="collapsable"
@@ -186,7 +186,7 @@
:key="status.id"
ref="statusComponent"
class="conversation-status status-fadein panel-body"
- :statusoid="status"
+ :status-id="status.id"
:replies="getReplies(status.id)"
:expandable="!isExpanded"
diff --git a/src/components/emoji_reactions/emoji_reactions.js b/src/components/emoji_reactions/emoji_reactions.js
index f881036df..3077ed212 100644
--- a/src/components/emoji_reactions/emoji_reactions.js
+++ b/src/components/emoji_reactions/emoji_reactions.js
@@ -60,10 +60,10 @@ const EmojiReactions = {
reactedWith(emoji) {
return this.status.emoji_reactions.find((r) => r.name === emoji).me
},
- async fetchEmojiReactionsByIfMissing() {
+ async fetchEmojiReactionsIfMissing() {
const hasNoAccounts = this.status.emoji_reactions.find((r) => !r.accounts)
- if (hasNoAccounts) {
- return await useStatusesStore().fetchEmojiReactionsBy(this.status.id)
+ if (!hasNoAccounts) {
+ return await useStatusesStore().fetchEmojiReactions(this.status.id)
}
},
reactWith(emoji) {
@@ -75,7 +75,7 @@ const EmojiReactions = {
async emojiOnClick(emoji) {
if (!this.loggedIn) return
- await this.fetchEmojiReactionsByIfMissing()
+ await this.fetchEmojiReactionsIfMissing()
if (this.reactedWith(emoji)) {
this.unreact(emoji)
} else {
diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue
index 16c69fa40..a8100c0d4 100644
--- a/src/components/emoji_reactions/emoji_reactions.vue
+++ b/src/components/emoji_reactions/emoji_reactions.vue
@@ -56,7 +56,7 @@
class="emoji-reaction-popover"
:normal-button="true"
:trigger-attrs="counterTriggerAttrs(reaction)"
- @show="fetchEmojiReactionsByIfMissing()"
+ @show="fetchEmojiReactionsIfMissing()"
>
{{ reaction.count }}
diff --git a/src/components/follow_button/follow_button.js b/src/components/follow_button/follow_button.js
index 7ad91f236..e4d243ff9 100644
--- a/src/components/follow_button/follow_button.js
+++ b/src/components/follow_button/follow_button.js
@@ -75,7 +75,6 @@ export default {
}
},
doUnfollow() {
- const store = this.$store
this.inProgress = true
useUsersStore()
.unfollowUser(this.relationship.id)
diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index 44c07383d..1004f50c9 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -184,6 +184,7 @@ const Notification = {
},
computed: {
status() {
+ // Used for StatusContent
if (this.notification.status) {
return useStatusesStore().allStatuses.get(this.notification.status.id)
}
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 3fc486127..d2f370928 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -6,7 +6,7 @@
diff --git a/src/components/status/status.js b/src/components/status/status.js
index c88d120db..8fc7db75a 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -94,6 +94,7 @@ const Status = {
StatusActionButtons,
},
props: {
+ statusId: String,
statusoid: Object,
replies: Array,
@@ -128,9 +129,13 @@ const Status = {
}
},
computed: {
+ status() {
+ return this.statusoid ?? useStatusesStore().allStatuses.get(this.statusId)
+ },
showReasonMutedThread() {
return (
- (this.status.thread_muted || this.status.reblog?.thread_muted) &&
+ (this.mainStatus.thread_muted ||
+ this.smainSatus.reblog?.thread_muted) &&
!this.inConversation
)
},
@@ -144,27 +149,27 @@ const Status = {
return this.mergedConfig.scaleMfm
},
repeaterClass() {
- const user = this.statusoid.user
+ const user = this.status.user
return highlightClass(user)
},
userClass() {
const user = this.retweet
- ? this.statusoid.retweeted_status.user
- : this.statusoid.user
+ ? this.status.retweeted_status.user
+ : this.status.user
return highlightClass(user)
},
deleted() {
- return this.statusoid.deleted
+ return this.status.deleted
},
repeaterStyle() {
- const user = this.statusoid.user
+ const user = this.status.user
return highlightStyle(useUserHighlightStore().get(user.screen_name))
},
userStyle() {
if (this.noHeading) return
const user = this.retweet
- ? this.statusoid.retweeted_status.user
- : this.statusoid.user
+ ? this.status.retweeted_status.user
+ : this.status.user
return highlightStyle(useUserHighlightStore().get(user.screen_name))
},
userProfileLink() {
@@ -181,28 +186,28 @@ const Status = {
}
},
retweet() {
- return !!this.statusoid.retweeted_status
+ return !!this.status.retweeted_status
},
retweeterUser() {
- return this.statusoid.user
+ return this.status.user
},
retweeter() {
- return this.statusoid.user.name || this.statusoid.user.screen_name_ui
+ return this.status.user.name || this.status.user.screen_name_ui
},
retweeterHtml() {
- return this.statusoid.user.name
+ return this.status.user.name
},
retweeterProfileLink() {
return this.generateUserProfileLink(
- this.statusoid.user.id,
- this.statusoid.user.screen_name,
+ this.status.user.id,
+ this.status.user.screen_name,
)
},
- status() {
+ mainStatus() {
if (this.retweet) {
- return this.statusoid.retweeted_status
+ return this.status.retweeted_status
} else {
- return this.statusoid
+ return this.status
}
},
statusFromGlobalRepository() {
@@ -231,14 +236,14 @@ const Status = {
const writtenSet = new Set(
this.headTailLinks.writtenMentions.map((_) => _.url),
)
- return this.status.attentions
+ return this.mainStatus.attentions
.filter((attn) => {
// no reply user
return (
- attn.id !== this.status.in_reply_to_user_id &&
+ attn.id !== this.mainStatus.in_reply_to_user_id &&
// no self-replies
attn.statusnet_profile_url !==
- this.status.user.statusnet_profile_url &&
+ this.mainStatus.user.statusnet_profile_url &&
// don't include if mentions is written
!writtenSet.has(attn.statusnet_profile_url)
)
@@ -255,7 +260,7 @@ const Status = {
muteReasons() {
return [
this.userIsMuted ? 'user' : null,
- this.status.thread_muted ? 'thread' : null,
+ this.mainStatus.thread_muted ? 'thread' : null,
this.muteFilterHits.length > 0 ? 'filtered' : null,
this.muteBotStatuses && this.botStatus ? 'bot' : null,
this.muteSensitiveStatuses && this.sensitiveStatus ? 'nsfw' : null,
@@ -299,14 +304,13 @@ const Status = {
},
muted() {
if (this.ignoreMute) return false
- if (this.statusoid.user.id === this.currentUser?.id) return false
+ if (this.status.user.id === this.currentUser?.id) return false
return !this.unmuted && !this.shouldNotMute && this.muteReasons.length > 0
},
userIsMuted() {
- if (this.statusoid.user.id === this.currentUser?.id) return false
- const { status } = this
- const { reblog } = status
- const relationship = useUsersStore().relationship(status.user.id)
+ if (this.status.user.id === this.currentUser?.id) return false
+ const { reblog } = this.status
+ const relationship = useUsersStore().relationship(this.status.user.id)
const relationshipReblog =
reblog && useUsersStore().relationship(reblog.user.id)
return (
@@ -322,8 +326,7 @@ const Status = {
shouldNotMute() {
if (this.ignoreMute) return true
if (this.focused) return true
- const { status } = this
- const { reblog } = status
+ const { reblog } = this.status
return (
((this.inProfile &&
// Don't mute user's posts on user timeline (except reblogs)
@@ -576,7 +579,7 @@ const Status = {
}
},
isSuspendable: function (suspend) {
- this.$emit('suspendableStateChange', { id: this.statusoid.id, suspend })
+ this.$emit('suspendableStateChange', { id: this.status.id, suspend })
},
},
}
diff --git a/src/components/status_action_buttons/buttons_definitions.js b/src/components/status_action_buttons/buttons_definitions.js
index 47b1baaf2..399fad395 100644
--- a/src/components/status_action_buttons/buttons_definitions.js
+++ b/src/components/status_action_buttons/buttons_definitions.js
@@ -187,7 +187,7 @@ export const BUTTONS = [
'summary_raw_html',
]
stripFieldsList.forEach((p) => delete originalStatus[p])
- useStatusHistoryStore().openStatusHistoryModal(originalStatus)
+ useStatusHistoryStore().openModal(originalStatus.id)
return Promise.resolve()
},
},
diff --git a/src/components/status_history_modal/status_history_modal.js b/src/components/status_history_modal/status_history_modal.js
index b27c19b73..5a3fc2a41 100644
--- a/src/components/status_history_modal/status_history_modal.js
+++ b/src/components/status_history_modal/status_history_modal.js
@@ -1,13 +1,14 @@
-import { get } from 'lodash'
+import { mapState } from 'pinia'
import Modal from 'src/components/modal/modal.vue'
+import StatusContent from 'src/components/status_content/status_content.vue'
-import { useStatusesStore } from 'src/stores/statuses.js'
import { useStatusHistoryStore } from 'src/stores/statusHistory.js'
const StatusHistoryModal = {
components: {
Modal,
+ StatusContent,
},
data() {
return {
@@ -15,50 +16,14 @@ const StatusHistoryModal = {
}
},
computed: {
- modalActivated() {
- return useStatusHistoryStore().modalActivated
- },
- params() {
- return useStatusHistoryStore().params
- },
- statusId() {
- return this.params.id
- },
historyCount() {
- return this.statuses.length
- },
- history() {
- return this.statuses
- },
- },
- watch: {
- params(newVal, oldVal) {
- const newStatusId = get(newVal, 'id') !== get(oldVal, 'id')
- if (newStatusId) {
- this.resetHistory()
- }
-
- if (
- newStatusId ||
- get(newVal, 'edited_at') !== get(oldVal, 'edited_at')
- ) {
- this.fetchStatusHistory()
- }
+ return this.history.length
},
+ ...mapState(useStatusHistoryStore, ['modalActivated', 'history']),
},
methods: {
- resetHistory() {
- this.statuses = []
- },
- fetchStatusHistory() {
- useStatusesStore()
- .fetchStatusHistory(this.params)
- .then((data) => {
- this.statuses = data
- })
- },
closeModal() {
- useStatusHistoryStore().closeStatusHistoryModal()
+ useStatusHistoryStore().closeModal()
},
},
}
diff --git a/src/components/status_history_modal/status_history_modal.vue b/src/components/status_history_modal/status_history_modal.vue
index 282878b52..a78e04c96 100644
--- a/src/components/status_history_modal/status_history_modal.vue
+++ b/src/components/status_history_modal/status_history_modal.vue
@@ -15,10 +15,10 @@
v-if="historyCount > 0"
class="history-body"
>
-
diff --git a/src/components/status_popover/status_popover.js b/src/components/status_popover/status_popover.js
index e9fc2398d..30b43be2c 100644
--- a/src/components/status_popover/status_popover.js
+++ b/src/components/status_popover/status_popover.js
@@ -15,11 +15,6 @@ const StatusPopover = {
error: false,
}
},
- computed: {
- status() {
- return useStatusesStore().allStatuses.get(this.statusId)
- },
- },
components: {
Popover,
},
diff --git a/src/components/status_popover/status_popover.vue b/src/components/status_popover/status_popover.vue
index ccfb06c02..a17b41675 100644
--- a/src/components/status_popover/status_popover.vue
+++ b/src/components/status_popover/status_popover.vue
@@ -14,7 +14,7 @@
diff --git a/src/components/thread_tree/thread_tree.js b/src/components/thread_tree/thread_tree.js
index 75232a259..e5352fba1 100644
--- a/src/components/thread_tree/thread_tree.js
+++ b/src/components/thread_tree/thread_tree.js
@@ -11,7 +11,7 @@ const ThreadTree = {
name: 'ThreadTree',
props: {
depth: Number,
- status: Object,
+ statusId: String,
inProfile: Boolean,
conversation: Array,
collapsable: Boolean,
@@ -34,8 +34,8 @@ const ThreadTree = {
computed: {
reverseLookupTable() {
return this.conversation.reduce(
- (table, status, index) => {
- table[status.id] = index
+ (table, statusId, index) => {
+ table[statusId] = index
return table
},
{
@@ -44,12 +44,10 @@ const ThreadTree = {
)
},
currentReplies() {
- return this.getReplies(this.status.id).map(({ id }) =>
- this.statusById(id),
- )
+ return this.getReplies(this.statusId).map(({ id }) => this.statusById(id))
},
threadShowing() {
- return this.threadDisplayStatus[this.status.id] === 'showing'
+ return this.threadDisplayStatus[this.statusId] === 'showing'
},
},
methods: {
diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue
index 556858ad7..113119fa6 100644
--- a/src/components/thread_tree/thread_tree.vue
+++ b/src/components/thread_tree/thread_tree.vue
@@ -1,25 +1,25 @@
$emit('suspendableStateChange', e)"
/>
@@ -29,10 +29,10 @@
>
- {{ $t('status.thread_follow', { numStatus: totalReplyCount[status.id] }, totalReplyCount[status.id]) }}
+ {{ $t('status.thread_follow', { numStatus: totalReplyCount[statusId] }, totalReplyCount[statusId]) }}
@@ -86,7 +86,7 @@
tag="button"
keypath="status.thread_show_full_with_icon"
class="button-unstyled -link thread-tree-show-replies-button"
- @click.prevent="showThreadRecursively(status.id)"
+ @click.prevent="showThreadRecursively(statusId)"
>
- {{ $t('status.thread_show_full', { numStatus: totalReplyCount[status.id], depth: totalReplyDepth[status.id] }, totalReplyCount[status.id]) }}
+ {{ $t('status.thread_show_full', { numStatus: totalReplyCount[statusId], depth: totalReplyDepth[statusId] }, totalReplyCount[statusId]) }}
diff --git a/src/stores/notifications.js b/src/stores/notifications.js
index 078b66b89..bc516d3bd 100644
--- a/src/stores/notifications.js
+++ b/src/stores/notifications.js
@@ -173,7 +173,7 @@ export const useNotificationsStore = defineStore('notifications', {
}
if (notification.type === 'pleroma:emoji_reaction') {
- useStatusesStore().fetchEmojiReactionsBy(notification.status.id)
+ useStatusesStore().fetchEmojiReactions(notification.status.id)
}
// Only add a new notification if we don't have one for the same action
diff --git a/src/stores/statusHistory.js b/src/stores/statusHistory.js
index 9868b22c5..e2a69c36d 100644
--- a/src/stores/statusHistory.js
+++ b/src/stores/statusHistory.js
@@ -1,17 +1,34 @@
import { defineStore } from 'pinia'
+import { useOAuthStore } from 'src/stores/oauth.js'
+
+import { fetchStatusHistory } from 'src/api/public.js'
+
export const useStatusHistoryStore = defineStore('statusHistory', {
state: () => ({
- params: {},
+ id: null,
modalActivated: false,
+ history: null,
}),
actions: {
- openStatusHistoryModal(params) {
- this.params = params
- this.modalActivated = true
+ openModal(id) {
+ this.fetchStatusHistory(id).then(() => {
+ this.id = id
+ this.modalActivated = true
+ })
},
- closeStatusHistoryModal() {
+ closeModal() {
+ this.id = null
this.modalActivated = false
+ this.history = null
+ },
+ fetchStatusHistory(id) {
+ return fetchStatusHistory({
+ id,
+ credentials: useOAuthStore().token,
+ }).then(({ data }) => {
+ this.history = data
+ })
},
},
})
diff --git a/src/stores/statuses.js b/src/stores/statuses.js
index 9605556f1..878515687 100644
--- a/src/stores/statuses.js
+++ b/src/stores/statuses.js
@@ -12,7 +12,6 @@ import {
fetchRebloggedByUsers,
fetchScrobbles,
fetchStatus,
- fetchStatusHistory,
fetchStatusSource,
search2,
} from 'src/api/public.js'
@@ -128,16 +127,16 @@ export const useStatusesStore = defineStore('statuses', {
const addStatus = (data) => {
getLatestScrobble(data.user)
- const [status] = this.mergeOrAdd(this.allStatuses, data)
+ const [status] = this.mergeOrAdd(this.allStatuses, data, timestamp)
// Add to conversation
const conversations = this.conversations
const conversationId = status.statusnet_conversation_id
if (conversations.has(conversationId)) {
- conversations.get(conversationId).set(status.id, status)
+ conversations.get(conversationId).add(status.id)
} else {
- conversations.set(conversationId, new Map([[status.id, status]]))
+ conversations.set(conversationId, new Set([status.id]))
}
// Work on quote
@@ -160,30 +159,6 @@ export const useStatusesStore = defineStore('statuses', {
if (status.retweeted_status) addStatus(status.retweeted_status)
return addStatus(status)
},
- favorite: (favorite) => {
- // Only update if this is a new favorite.
- // Ignore our own favorites because we get info about likes as response to like request
- if (!this.favorites.has(favorite.id)) {
- this.favorites.add(favorite.id)
-
- const status = this.allStatuses.get(favorite.in_reply_to_status_id)
-
- if (status) {
- // This is our favorite, so the relevant bit.
- if (favorite.user.id === useUsersStore().currentUser?.id) {
- status.favorited = true
- } else {
- status.fave_num += 1
- }
- }
- return status
- }
- return null
- },
- follow: () => {
- // NOOP, it is known status but we don't do anything about it for now
- return null
- },
default: (unknown) => {
console.warn('unknown status type', unknown)
return null
@@ -228,7 +203,10 @@ export const useStatusesStore = defineStore('statuses', {
// Fetches
fetchStatus(id) {
- return fetchStatus({ id }).then(({ data: status, timestamp }) =>
+ return fetchStatus({
+ id,
+ credentials: useOAuthStore().token,
+ }).then(({ data: status, timestamp }) =>
this.addNewStatuses({ statuses: [status], timestamp }),
)
},
@@ -238,10 +216,7 @@ export const useStatusesStore = defineStore('statuses', {
credentials: useOAuthStore().token,
}).then(({ data }) => data)
},
- fetchStatusHistory(status) {
- return fetchStatusHistory({ status }).then(({ data }) => data)
- },
- fetchEmojiReactionsBy(id) {
+ fetchEmojiReactions(id) {
return fetchEmojiReactions({
id,
credentials: useOAuthStore().token,
@@ -452,7 +427,7 @@ export const useStatusesStore = defineStore('statuses', {
const accounts = value
? [...reaction.accounts, currentUser]
- : accounts.filter((acc) => acc.id !== currentUser.id)
+ : reaction.accounts.filter((acc) => acc.id !== currentUser.id)
const newReaction = {
...reaction,
@@ -480,7 +455,7 @@ export const useStatusesStore = defineStore('statuses', {
apiCall: bookmarkStatus,
optimisticCall: this.setBookmarked,
argument: bookmark_folder_id,
- value: false,
+ value: true,
})
},
unbookmark(id) {
@@ -511,7 +486,7 @@ export const useStatusesStore = defineStore('statuses', {
id,
apiCall: muteConversation,
optimisticCall: this.setMutedStatus,
- value: false,
+ value: true,
})
},
unmuteConversation(id) {
@@ -532,8 +507,8 @@ export const useStatusesStore = defineStore('statuses', {
if (newStatus.thread_muted !== undefined) {
this.conversations
.get(newStatus.statusnet_conversation_id)
- .forEach((status) => {
- status.thread_muted = value
+ .forEach((statusId) => {
+ this.allStatuses.get(statusId).thread_muted = value
})
}
},
@@ -564,7 +539,7 @@ export const useStatusesStore = defineStore('statuses', {
/// Delete
deleteStatus(id) {
- deleteStatus({
+ return deleteStatus({
id,
credentials: useOAuthStore().token,
})
@@ -584,17 +559,10 @@ export const useStatusesStore = defineStore('statuses', {
const newStatus = this.allStatuses.get(id)
if (newStatus) newStatus.deleted = true
},
- setManyDeleted(condition) {
- this.allStatuses.values().forEach((status) => {
- if (condition(status)) {
- status.deleted = true
- }
- })
- },
// For when blocking a user
wipeUserStatuses(userId) {
- this.allStatuses.values().forEach((status) => {
+ this.allStatuses.forEach((status) => {
if (status.user.id === userId) {
this.allStatuses.delete(status.id)
}
diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js
deleted file mode 100644
index 04bd07ffe..000000000
--- a/test/unit/specs/modules/statuses.spec.js
+++ /dev/null
@@ -1,447 +0,0 @@
-import { createTestingPinia } from '@pinia/testing'
-
-import {
- defaultState,
- mutations,
- prepareStatus,
-} from '../../../../src/modules/statuses.js'
-
-createTestingPinia()
-
-const makeMockStatus = ({ id, text, type = 'status' }) => {
- return {
- id,
- user: { id: '0' },
- name: 'status',
- text: text || `Text number ${id}`,
- fave_num: 0,
- uri: '',
- type,
- attentions: [],
- }
-}
-
-describe('Statuses module', () => {
- describe('prepareStatus', () => {
- it('sets deleted flag to false', () => {
- const aStatus = makeMockStatus({ id: '1', text: 'Hello oniichan' })
- expect(prepareStatus(aStatus).deleted).to.eq(false)
- })
- })
-
- describe('addNewStatuses', () => {
- it('adds the status to allStatuses and to the given timeline', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- timeline: 'public',
- })
-
- expect(state.allStatuses).to.eql([status])
- expect(state.timelines.public.statuses).to.eql([status])
- expect(state.timelines.public.visibleStatuses).to.eql([])
- expect(state.timelines.public.newStatusCount).to.equal(1)
- })
-
- it('counts the status as new if it has not been seen on this timeline', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- timeline: 'public',
- })
- mutations.addNewStatuses(state, {
- statuses: [status],
- timeline: 'friends',
- })
-
- expect(state.allStatuses).to.eql([status])
- expect(state.timelines.public.statuses).to.eql([status])
- expect(state.timelines.public.visibleStatuses).to.eql([])
- expect(state.timelines.public.newStatusCount).to.equal(1)
-
- expect(state.allStatuses).to.eql([status])
- expect(state.timelines.friends.statuses).to.eql([status])
- expect(state.timelines.friends.visibleStatuses).to.eql([])
- expect(state.timelines.friends.newStatusCount).to.equal(1)
- })
-
- it('add the statuses to allStatuses if no timeline is given', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
-
- mutations.addNewStatuses(state, { statuses: [status] })
-
- expect(state.allStatuses).to.eql([status])
- expect(state.timelines.public.statuses).to.eql([])
- expect(state.timelines.public.visibleStatuses).to.eql([])
- expect(state.timelines.public.newStatusCount).to.equal(0)
- })
-
- it('adds the status to allStatuses and to the given timeline, directly visible', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
-
- expect(state.allStatuses).to.eql([status])
- expect(state.timelines.public.statuses).to.eql([status])
- expect(state.timelines.public.visibleStatuses).to.eql([status])
- expect(state.timelines.public.newStatusCount).to.equal(0)
- })
-
- it('does not update the maxId when the noIdUpdate flag is set', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
- const secondStatus = makeMockStatus({ id: '2' })
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- expect(state.timelines.public.maxId).to.equal('1')
-
- mutations.addNewStatuses(state, {
- statuses: [secondStatus],
- showImmediately: true,
- timeline: 'public',
- noIdUpdate: true,
- })
- expect(state.timelines.public.statuses).to.eql([secondStatus, status])
- expect(state.timelines.public.visibleStatuses).to.eql([
- secondStatus,
- status,
- ])
- expect(state.timelines.public.maxId).to.equal('1')
- })
-
- it('keeps a descending by id order in timeline.visibleStatuses and timeline.statuses', () => {
- const state = defaultState()
- const nonVisibleStatus = makeMockStatus({ id: '1' })
- const status = makeMockStatus({ id: '3' })
- const statusTwo = makeMockStatus({ id: '2' })
- const statusThree = makeMockStatus({ id: '4' })
-
- mutations.addNewStatuses(state, {
- statuses: [nonVisibleStatus],
- showImmediately: false,
- timeline: 'public',
- })
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- mutations.addNewStatuses(state, {
- statuses: [statusTwo],
- showImmediately: true,
- timeline: 'public',
- })
-
- expect(state.timelines.public.minVisibleId).to.equal('2')
-
- mutations.addNewStatuses(state, {
- statuses: [statusThree],
- showImmediately: true,
- timeline: 'public',
- })
-
- expect(state.timelines.public.statuses).to.eql([
- statusThree,
- status,
- statusTwo,
- nonVisibleStatus,
- ])
- expect(state.timelines.public.visibleStatuses).to.eql([
- statusThree,
- status,
- statusTwo,
- ])
- })
-
- it('splits retweets from their status and links them', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
- const retweet = makeMockStatus({ id: '2', type: 'retweet' })
- const modStatus = makeMockStatus({ id: '1', text: 'something else' })
-
- retweet.retweeted_status = status
-
- // It adds both statuses, but only the retweet to visible.
- mutations.addNewStatuses(state, {
- statuses: [retweet],
- timeline: 'public',
- showImmediately: true,
- })
- expect(state.timelines.public.visibleStatuses).to.have.length(1)
- expect(state.timelines.public.statuses).to.have.length(1)
- expect(state.allStatuses).to.have.length(2)
- expect(state.allStatuses[0].id).to.equal('1')
- expect(state.allStatuses[1].id).to.equal('2')
-
- // It refers to the modified status.
- mutations.addNewStatuses(state, {
- statuses: [modStatus],
- timeline: 'public',
- })
- expect(state.allStatuses).to.have.length(2)
- expect(state.allStatuses[0].id).to.equal('1')
- expect(state.allStatuses[0].text).to.equal(modStatus.text)
- expect(state.allStatuses[1].id).to.equal('2')
- expect(retweet.retweeted_status.text).to.eql(modStatus.text)
- })
-
- it('replaces existing statuses with the same id', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
- const modStatus = makeMockStatus({ id: '1', text: 'something else' })
-
- // Add original status
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- expect(state.timelines.public.visibleStatuses).to.have.length(1)
- expect(state.allStatuses).to.have.length(1)
-
- // Add new version of status
- mutations.addNewStatuses(state, {
- statuses: [modStatus],
- showImmediately: true,
- timeline: 'public',
- })
- expect(state.timelines.public.visibleStatuses).to.have.length(1)
- expect(state.allStatuses).to.have.length(1)
- expect(state.allStatuses[0].text).to.eql(modStatus.text)
- })
-
- it('replaces existing statuses with the same id, coming from a retweet', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
- const modStatus = makeMockStatus({ id: '1', text: 'something else' })
- const retweet = makeMockStatus({ id: '2', type: 'retweet' })
- retweet.retweeted_status = modStatus
-
- // Add original status
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- expect(state.timelines.public.visibleStatuses).to.have.length(1)
- expect(state.allStatuses).to.have.length(1)
-
- // Add new version of status
- mutations.addNewStatuses(state, {
- statuses: [retweet],
- showImmediately: false,
- timeline: 'public',
- })
- expect(state.timelines.public.visibleStatuses).to.have.length(1)
- // Don't add the retweet itself if the tweet is visible
- expect(state.timelines.public.statuses).to.have.length(1)
- expect(state.allStatuses).to.have.length(2)
- expect(state.allStatuses[0].text).to.eql(modStatus.text)
- })
-
- it('handles favorite actions', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
-
- const favorite = {
- id: '2',
- type: 'favorite',
- in_reply_to_status_id: '1', // The API uses strings here...
- uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
- text: 'a favorited something by b',
- user: { id: '99' },
- }
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- mutations.addNewStatuses(state, {
- statuses: [favorite],
- showImmediately: true,
- timeline: 'public',
- })
-
- expect(state.timelines.public.visibleStatuses).to.have.length(1)
- expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(1)
- expect(state.timelines.public.maxId).to.eq(favorite.id)
-
- // Adding it again does nothing
- mutations.addNewStatuses(state, {
- statuses: [favorite],
- showImmediately: true,
- timeline: 'public',
- })
-
- expect(state.timelines.public.visibleStatuses).to.have.length(1)
- expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(1)
- expect(state.timelines.public.maxId).to.eq(favorite.id)
-
- // If something is favorited by the current user, it also sets the 'favorited' property but does not increment counter to avoid over-counting. Counter is incremented (updated, really) via response to the favorite request.
- const user = {
- id: '1',
- }
-
- const ownFavorite = {
- id: '3',
- type: 'favorite',
- in_reply_to_status_id: '1', // The API uses strings here...
- uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
- text: 'a favorited something by b',
- user,
- }
-
- mutations.addNewStatuses(state, {
- statuses: [ownFavorite],
- showImmediately: true,
- timeline: 'public',
- user,
- })
-
- expect(state.timelines.public.visibleStatuses).to.have.length(1)
- expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(1)
- expect(state.timelines.public.visibleStatuses[0].favorited).to.eql(true)
- })
- })
-
- describe('emojiReactions', () => {
- it('increments count in existing reaction', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
- status.emoji_reactions = [{ name: '😂', count: 1, accounts: [] }]
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- mutations.addOwnReaction(state, {
- id: '1',
- emoji: '😂',
- currentUser: { id: 'me' },
- })
- expect(state.allStatusesObject['1'].emoji_reactions[0].count).to.eql(2)
- expect(state.allStatusesObject['1'].emoji_reactions[0].me).to.eql(true)
- expect(
- state.allStatusesObject['1'].emoji_reactions[0].accounts[0].id,
- ).to.equal('me')
- })
-
- it('adds a new reaction', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
- status.emoji_reactions = []
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- mutations.addOwnReaction(state, {
- id: '1',
- emoji: '😂',
- currentUser: { id: 'me' },
- })
- expect(state.allStatusesObject['1'].emoji_reactions[0].count).to.eql(1)
- expect(state.allStatusesObject['1'].emoji_reactions[0].me).to.eql(true)
- expect(
- state.allStatusesObject['1'].emoji_reactions[0].accounts[0].id,
- ).to.equal('me')
- })
-
- it('decreases count in existing reaction', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
- status.emoji_reactions = [
- { name: '😂', count: 2, accounts: [{ id: 'me' }] },
- ]
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- mutations.removeOwnReaction(state, {
- id: '1',
- emoji: '😂',
- currentUser: { id: 'me' },
- })
- expect(state.allStatusesObject['1'].emoji_reactions[0].count).to.eql(1)
- expect(state.allStatusesObject['1'].emoji_reactions[0].me).to.eql(false)
- expect(state.allStatusesObject['1'].emoji_reactions[0].accounts).to.eql(
- [],
- )
- })
-
- it('removes a reaction', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '1' })
- status.emoji_reactions = [
- { name: '😂', count: 1, accounts: [{ id: 'me' }] },
- ]
-
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- mutations.removeOwnReaction(state, {
- id: '1',
- emoji: '😂',
- currentUser: { id: 'me' },
- })
- expect(state.allStatusesObject['1'].emoji_reactions).to.have.length(0)
- })
- })
-
- describe('showNewStatuses', () => {
- it('resets the minId to the min of the visible statuses when adding new to visible statuses', () => {
- const state = defaultState()
- const status = makeMockStatus({ id: '10' })
- mutations.addNewStatuses(state, {
- statuses: [status],
- showImmediately: true,
- timeline: 'public',
- })
- const newStatus = makeMockStatus({ id: '20' })
- mutations.addNewStatuses(state, {
- statuses: [newStatus],
- showImmediately: false,
- timeline: 'public',
- })
- state.timelines.public.minId = '5'
- mutations.showNewStatuses(state, { timeline: 'public' })
-
- expect(state.timelines.public.visibleStatuses).to.have.length(2)
- expect(state.timelines.public.minVisibleId).to.equal('10')
- expect(state.timelines.public.minId).to.equal('10')
- })
- })
-
- describe('clearTimeline', () => {
- it('keeps userId when clearing user timeline when excludeUserId param is true', () => {
- const state = defaultState()
- state.timelines.user.userId = 123
-
- mutations.clearTimeline(state, { timeline: 'user', excludeUserId: true })
-
- expect(state.timelines.user.userId).to.eql(123)
- })
- })
-})
diff --git a/test/unit/specs/stores/statuses.spec.js b/test/unit/specs/stores/statuses.spec.js
new file mode 100644
index 000000000..01795b25d
--- /dev/null
+++ b/test/unit/specs/stores/statuses.spec.js
@@ -0,0 +1,603 @@
+import { createTestingPinia } from '@pinia/testing'
+import { snakeCase } from 'lodash'
+import { setActivePinia } from 'pinia'
+
+import { useStatusesStore } from 'src/stores/statuses.js'
+import { useUsersStore } from 'src/stores/users.js'
+
+import * as PUBLIC_API from 'src/api/public.js'
+import * as USER_API from 'src/api/user.js'
+
+const userId = '1'
+const userScreenName = 'user'
+const userName = 'Guy'
+const userUrl = 'http://localhost/user'
+
+const mockMastoAPIUser = ({
+ screen_name = userScreenName,
+ name = userName,
+ url = userUrl,
+ id = userId,
+} = {}) => ({
+ id,
+ acct: screen_name,
+ display_name: name,
+ fields: [],
+ avatar: '',
+ url,
+ pleroma: {
+ emoji_reactions: [],
+ },
+})
+
+const mockUser = ({
+ screen_name = userScreenName,
+ id = userId,
+ name = userName,
+ url = userUrl,
+} = {}) => ({
+ _original: mockMastoAPIUser({
+ screen_name,
+ id,
+ name,
+ url,
+ }),
+ id,
+ name,
+ screen_name,
+ url,
+ relationship: undefined,
+})
+
+const mockStatus = ({
+ id = '1',
+ text,
+ type = 'status',
+ statusUser = mockUser(),
+} = {}) => ({
+ id,
+ user: statusUser,
+ name: 'status',
+ text: text ?? `Text number ${id}`,
+ uri: '',
+ type,
+ attentions: [],
+ statusnet_conversation_id: 'c1',
+ emoji_reactions: [],
+})
+
+const mockMastoAPIStatus = ({
+ id = '1',
+ text,
+ type = 'status',
+ statusUser = mockMastoAPIUser(),
+} = {}) => ({
+ id,
+ account: statusUser,
+ name: 'status',
+ content: text ?? `Text number ${id}`,
+ uri: '',
+ type,
+ attentions: [],
+ statusnet_conversation_id: 'c1',
+})
+
+const DEFAULT_OPTIONS = (method = 'GET') => ({
+ method,
+ credentials: 'same-origin',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+})
+
+describe('Statuses store', () => {
+ beforeEach(() => {
+ setActivePinia(createTestingPinia({ stubActions: false }))
+ })
+
+ describe('addNewStatuses', () => {
+ beforeEach(() => {
+ const usersStore = useUsersStore()
+ usersStore.addNewUsers = vi.fn().mockReturnValue([mockUser()])
+ })
+
+ it('adds the status to allStatuses', () => {
+ const store = useStatusesStore()
+ const usersStore = useUsersStore()
+ const status = mockStatus({ id: '1' })
+
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 1,
+ })
+
+ expect(store.allStatuses).to.eql(new Map([['1', status]]))
+ expect(store.conversations).to.eql(new Map([['c1', new Set(['1'])]]))
+ expect(usersStore.addNewUsers).to.have.callCount(1)
+ })
+
+ it('splits retweets from their status and links them', () => {
+ const store = useStatusesStore()
+ const usersStore = useUsersStore()
+ const status = mockStatus({ id: '1' })
+ const retweet = mockStatus({
+ id: '2',
+ type: 'retweet',
+ user: mockUser({ id: '2' }),
+ })
+ retweet.type = 'retweet'
+ retweet.retweeted_status = status
+
+ store.addNewStatuses({
+ statuses: [retweet],
+ timestamp: 1,
+ })
+
+ expect(store.allStatuses).to.eql(
+ new Map([
+ ['1', status],
+ ['2', retweet],
+ ]),
+ )
+ expect(usersStore.addNewUsers).to.have.callCount(2)
+ })
+
+ it('splits quotes from their status and links them', () => {
+ const store = useStatusesStore()
+ const usersStore = useUsersStore()
+ const status = mockStatus({ id: '1' })
+ const quote = mockStatus({ id: '2' })
+ quote.quote = status
+
+ store.addNewStatuses({
+ statuses: [quote],
+ timestamp: 1,
+ })
+
+ expect(store.allStatuses).to.eql(
+ new Map([
+ ['1', status],
+ ['2', quote],
+ ]),
+ )
+ expect(usersStore.addNewUsers).to.have.callCount(2)
+ })
+
+ it('replaces existing statuses with the same id', () => {
+ const store = useStatusesStore()
+ const usersStore = useUsersStore()
+ const status = mockStatus({ id: '1' })
+ const modStatus = mockStatus({ id: '1', text: 'something else' })
+
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 1991,
+ })
+ expect(store.allStatuses).to.eql(new Map([['1', status]]))
+
+ store.addNewStatuses({
+ statuses: [modStatus],
+ timestamp: 2000,
+ })
+ expect(store.allStatuses).to.eql(new Map([['1', modStatus]]))
+ expect(usersStore.addNewUsers).to.have.callCount(2)
+ })
+
+ it('handles edits', () => {
+ const store = useStatusesStore()
+ const usersStore = useUsersStore()
+ const status = mockStatus({ id: '1' })
+ const modStatus = mockStatus({
+ id: '1',
+ text: 'something else',
+ type: 'edit',
+ })
+
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 1991,
+ })
+ expect(store.allStatuses).to.eql(new Map([['1', status]]))
+
+ store.addNewStatuses({
+ statuses: [modStatus],
+ timestamp: 2000,
+ })
+ expect(store.allStatuses).to.eql(new Map([['1', modStatus]]))
+ expect(usersStore.addNewUsers).to.have.callCount(2)
+ })
+
+ it('ignores updates with older timestamp', () => {
+ const store = useStatusesStore()
+ const usersStore = useUsersStore()
+ const status = mockStatus({ id: '1' })
+ const modStatus = mockStatus({ id: '1', text: 'something else' })
+
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 2000,
+ })
+ expect(store.allStatuses).to.eql(new Map([['1', status]]))
+
+ store.addNewStatuses({
+ statuses: [modStatus],
+ timestamp: 1991,
+ })
+ expect(store.allStatuses).to.eql(new Map([['1', status]]))
+ expect(usersStore.addNewUsers).to.have.callCount(2)
+ })
+
+ it('calls useUsersStore().addNewUsers() even on older timestamp', () => {
+ const store = useStatusesStore()
+ const usersStore = useUsersStore()
+ const status = mockStatus({ id: '1' })
+ const modStatus = mockStatus({ id: '1', text: 'something else' })
+
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 2000,
+ })
+ store.addNewStatuses({
+ statuses: [modStatus],
+ timestamp: 1991,
+ })
+ expect(usersStore.addNewUsers).to.have.callCount(2)
+ })
+ })
+
+ describe('fetchers', () => {
+ it.each([
+ [
+ 'StatusSource',
+ {
+ content_type: 'text/plain',
+ text: 'Text',
+ spoiler_text: 'Text',
+ },
+ ],
+ [
+ 'EmojiReactions',
+ [
+ {
+ accounts: [mockMastoAPIUser()],
+ count: 1,
+ me: false,
+ name: 'cofe',
+ url: '',
+ },
+ ],
+ ],
+ ['Favs', [mockMastoAPIUser()]],
+ ['Repeats', [mockMastoAPIUser()]],
+ ])('fetch%s', async (group, mockedResponse) => {
+ const mockFetch = vi.fn()
+ mockFetch.mockResolvedValueOnce(
+ new Response(JSON.stringify(mockedResponse), {
+ headers: { 'Content-Type': 'application/json' },
+ }),
+ )
+
+ vi.stubGlobal('fetch', mockFetch)
+
+ let urlKey
+ let prefix = 'MASTODON'
+ if (group === 'Favs') {
+ urlKey = 'STATUS_FAVORITEDBY'
+ } else if (group === 'Repeats') {
+ urlKey = 'STATUS_REBLOGGEDBY'
+ } else {
+ urlKey = snakeCase(group).toUpperCase()
+ }
+ if (group === 'EmojiReactions') {
+ prefix = 'PLEROMA'
+ }
+
+ const url = PUBLIC_API[`${prefix}_${urlKey}_URL`]('id')
+
+ const store = useStatusesStore()
+ const status = mockStatus({ id: 'id' })
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 2000,
+ })
+
+ const result = await store[`fetch${group}`]('id')
+ const updated = store.allStatuses.get('id')
+
+ expect(mockFetch).to.have.been.calledWith(url, DEFAULT_OPTIONS())
+ if (group === 'Favs') {
+ expect(updated.favoritedBy).to.have.length(1)
+ expect(updated.fave_num).to.eql(1)
+ } else if (group === 'Repeats') {
+ expect(updated.rebloggedBy).to.have.length(1)
+ expect(updated.repeat_num).to.eql(1)
+ } else if (group === 'EmojiReactions') {
+ expect(updated.emoji_reactions).to.have.length(mockedResponse.length)
+ expect(updated.emoji_reactions[0].name).to.eql(mockedResponse[0].name)
+ } else {
+ expect(result).to.eql(mockedResponse)
+ }
+ })
+
+ it('fetchFavsAndRepeats', async () => {
+ const store = useStatusesStore()
+ store.fetchFavs = vi.fn().mockResolvedValue(async () => {
+ /* no-op */
+ })
+ store.fetchRepeats = vi.fn().mockResolvedValue(async () => {
+ /* no-op */
+ })
+
+ await store.fetchFavsAndRepeats('id')
+ expect(store.fetchFavs).to.have.been.calledWith('id')
+ expect(store.fetchRepeats).to.have.been.calledWith('id')
+ })
+
+ it('fetchStatus', async () => {
+ const mockFetch = vi.fn()
+ mockFetch.mockResolvedValueOnce(
+ new Response(JSON.stringify(mockMastoAPIStatus()), {
+ headers: { 'Content-Type': 'application/json' },
+ }),
+ )
+
+ vi.stubGlobal('fetch', mockFetch)
+
+ const store = useStatusesStore()
+ await store.fetchStatus('id')
+
+ expect(mockFetch).to.have.been.calledWith(
+ PUBLIC_API.MASTODON_STATUS_URL('id'),
+ DEFAULT_OPTIONS(),
+ )
+ expect(store.allStatuses).to.have.length(1)
+ })
+ })
+
+ describe('interactions', () => {
+ it.each([
+ ['favorite', 'MASTODON_FAVORITE_URL'],
+ ['unfavorite', 'MASTODON_UNFAVORITE_URL'],
+ ['retweet', 'MASTODON_RETWEET_URL'],
+ ['unretweet', 'MASTODON_UNRETWEET_URL'],
+ ['reactWithEmoji', 'PLEROMA_EMOJI_REACT_URL', 'PUT'],
+ ['unreactWithEmoji', 'PLEROMA_EMOJI_UNREACT_URL', 'DELETE'],
+ [
+ 'bookmark',
+ 'MASTODON_BOOKMARK_STATUS_URL',
+ undefined,
+ { folder_id: 'argument' },
+ ],
+ ['unbookmark', 'MASTODON_UNBOOKMARK_STATUS_URL'],
+ ['pinStatus', 'MASTODON_PIN_OWN_STATUS_URL'],
+ ['unpinStatus', 'MASTODON_UNPIN_OWN_STATUS_URL'],
+ ['muteConversation', 'MASTODON_MUTE_CONVERSATION_URL'],
+ ['unmuteConversation', 'MASTODON_UNMUTE_CONVERSATION_URL'],
+ ['deleteStatus', 'MASTODON_DELETE_URL', 'DELETE'],
+ ])('%s - api call', async (interaction, urlKey, method = 'POST', body) => {
+ const url = USER_API[urlKey]('1', 'argument')
+
+ const status = mockStatus()
+ const store = useStatusesStore()
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 1,
+ })
+
+ const mockFetch = vi.fn()
+ mockFetch.mockResolvedValueOnce(
+ new Response(JSON.stringify(mockMastoAPIStatus({ text: 'Updated' })), {
+ headers: { 'Content-Type': 'application/json' },
+ }),
+ )
+
+ vi.stubGlobal('fetch', mockFetch)
+ await store[interaction]('1', 'argument')
+ const expectedArg = DEFAULT_OPTIONS(method)
+
+ if (body) {
+ expectedArg.body = JSON.stringify(body)
+ }
+
+ expect(mockFetch).to.have.been.calledWith(url, expectedArg)
+ if (interaction === 'deleteStatus') {
+ expect(store.allStatuses.get('1').deleted).to.be.true
+ } else {
+ expect(store.allStatuses.get('1').text).to.eql('Updated')
+ }
+ })
+
+ const optimismInteractions = [
+ ['favorite', 'favorited', 'fave_num'],
+ ['retweet', 'repeated', 'repeat_num'],
+ ['bookmark', 'bookmarked'],
+ ['muteConversation', 'thread_muted'],
+ ]
+ .map(([method, property, count]) => [
+ [method, property, count],
+ ['un' + method, property, count],
+ ])
+ .flat()
+
+ it.each(
+ optimismInteractions,
+ )('%s - optimism call', async (method, property, count) => {
+ // Prepare our status
+ const status = mockStatus()
+ const negate = method.startsWith('un')
+ const oldCount = 9
+ const newCount = negate ? 8 : 10
+ status[property] = negate
+ if (count) {
+ status[count] = oldCount
+ }
+ if (method === 'unbookmark') {
+ status.bookmark_folder_id = 'argument'
+ }
+
+ // Insert it
+ const store = useStatusesStore()
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 1,
+ })
+
+ const mockFetch = vi.fn()
+ mockFetch.mockResolvedValueOnce(
+ new Response(JSON.stringify(mockMastoAPIStatus({ text: 'Updated' })), {
+ headers: { 'Content-Type': 'application/json' },
+ }),
+ )
+
+ expect(store.allStatuses.get('1')).to.have.property(property, negate)
+ if (count) {
+ expect(store.allStatuses.get('1')).to.have.property(count, oldCount)
+ }
+ vi.stubGlobal('fetch', mockFetch)
+
+ store[method]('1', 'argument')
+ expect(store.allStatuses.get('1')).to.have.property(property, !negate)
+ if (count) {
+ expect(store.allStatuses.get('1')).to.have.property(count, newCount)
+ }
+ if (property === 'bookmarked') {
+ expect(store.allStatuses.get('1')).to.have.property(
+ 'bookmark_folder_id',
+ 'argument',
+ )
+ }
+ })
+
+ it.each(
+ optimismInteractions,
+ )('%s - optimism fail', async (method, property, count) => {
+ // Prepare our status
+ const status = mockStatus()
+ const negate = method.startsWith('un')
+ const oldCount = 9
+ status[property] = negate
+ if (count) {
+ status[count] = oldCount
+ }
+ if (method === 'unbookmark') {
+ status.bookmark_folder_id = 'argument'
+ }
+
+ // Insert it
+ const store = useStatusesStore()
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 1,
+ })
+
+ const mockFetch = vi.fn()
+ mockFetch.mockRejectedValueOnce(new Error('Failure!'))
+
+ expect(store.allStatuses.get('1')).to.have.property(property, negate)
+ if (count) {
+ expect(store.allStatuses.get('1')).to.have.property(count, oldCount)
+ }
+ vi.stubGlobal('fetch', mockFetch)
+
+ await store[method]('1', 'argument')
+ expect(store.allStatuses.get('1')).to.have.property(property, negate)
+ if (count) {
+ expect(store.allStatuses.get('1')).to.have.property(count, oldCount)
+ }
+
+ // Failing 'bookmark' method SHOULD clear folder id
+ if (method === 'unbookmark') {
+ expect(store.allStatuses.get('1')).to.have.property(
+ 'bookmark_folder_id',
+ 'argument',
+ )
+ }
+ })
+
+ it.each([
+ ['reactWithEmoji', 0],
+ ['unreactWithEmoji', 1],
+ ['reactWithEmoji', 1],
+ ['unreactWithEmoji', 2],
+ ])('%s count: %s - optimism call', async (method, oldCount) => {
+ // Prepare our status
+ const status = mockStatus()
+ const negate = method.startsWith('un')
+ const newCount = negate ? oldCount - 1 : oldCount + 1
+
+ useUsersStore().currentUser = mockUser()
+
+ if (oldCount > 0) {
+ const reactors = [...new Array(oldCount)].map((empty, index) =>
+ mockUser({ id: 'o' + index }),
+ )
+ if (negate) {
+ // Replace one of reactors with ourselves
+ reactors[0] = useUsersStore().currentUser
+ }
+ status.emoji_reactions = [
+ {
+ name: 'hyperlol',
+ count: oldCount,
+ accounts: reactors,
+ },
+ ]
+ } else {
+ status.emoji_reactions = []
+ }
+
+ // Insert it
+ const store = useStatusesStore()
+ store.addNewStatuses({
+ statuses: [status],
+ timestamp: 1,
+ })
+
+ const mockFetch = vi.fn()
+ mockFetch.mockResolvedValueOnce(
+ new Response(JSON.stringify(mockMastoAPIStatus({ text: 'Updated' })), {
+ headers: { 'Content-Type': 'application/json' },
+ }),
+ )
+
+ vi.stubGlobal('fetch', mockFetch)
+ const expected = store.allStatuses.get('1')
+
+ expect(expected.emoji_reactions).to.have.length(oldCount === 0 ? 0 : 1)
+ if (oldCount !== 0) {
+ expect(expected.emoji_reactions[0].name).to.eql('hyperlol')
+ expect(expected.emoji_reactions[0].count).to.eql(oldCount)
+ expect(expected.emoji_reactions[0].accounts).to.have.length(oldCount)
+ }
+
+ store[method]('1', 'hyperlol')
+
+ expect(expected.emoji_reactions).to.have.length(newCount === 0 ? 0 : 1)
+ if (newCount !== 0) {
+ expect(expected.emoji_reactions[0].name).to.eql('hyperlol')
+ expect(expected.emoji_reactions[0].count).to.eql(newCount)
+ expect(expected.emoji_reactions[0].accounts).to.have.length(newCount)
+ }
+ })
+ })
+
+ it('wipeUserStatuses', () => {
+ const store = useStatusesStore()
+ const statuses = [...new Array(20)].map((empty, index) =>
+ mockStatus({
+ id: 's' + index,
+ statusUser: mockUser({ id: 'u' + index }),
+ }),
+ )
+
+ store.addNewStatuses({
+ statuses,
+ timestamp: 1,
+ })
+
+ store.wipeUserStatuses('u19')
+
+ expect(store.allStatuses).to.have.length(19)
+ })
+})
diff --git a/test/unit/specs/stores/users.spec.js b/test/unit/specs/stores/users.spec.js
index 879d2b0a9..b234a0ffe 100644
--- a/test/unit/specs/stores/users.spec.js
+++ b/test/unit/specs/stores/users.spec.js
@@ -43,47 +43,47 @@ const actionKeys = (action) => {
return result
}
-describe('The users store', () => {
- beforeEach(() => {
- setActivePinia(createTestingPinia({ stubActions: false }))
- })
+const userId = '1'
+const userScreenName = 'user'
+const userName = 'Guy'
+const userUrl = 'http://localhost/user'
- const userId = '1'
- const userScreenName = 'user'
- const userName = 'Guy'
- const userUrl = 'http://localhost/user'
+const mockMastoAPIUser = ({
+ screen_name = userScreenName,
+ name = userName,
+ url = userUrl,
+ id = userId,
+} = {}) => ({
+ id,
+ acct: screen_name,
+ display_name: name,
+ fields: [],
+ avatar: '',
+ url,
+})
- const mastoApiUser = ({
- screen_name = userScreenName,
- name = userName,
- url = userUrl,
- id = userId,
- } = {}) => ({
- id,
- acct: screen_name,
- display_name: name,
- fields: [],
- avatar: '',
- url,
- })
-
- const user = ({
- screen_name = userScreenName,
- id = userId,
- name = userName,
- url = userUrl,
- } = {}) => ({
- _original: mastoApiUser({
- screen_name,
- id,
- name,
- url,
- }),
+const mockUser = ({
+ screen_name = userScreenName,
+ id = userId,
+ name = userName,
+ url = userUrl,
+} = {}) => ({
+ _original: mockMastoAPIUser({
+ screen_name,
id,
name,
- screen_name,
url,
- relationship: undefined,
+ }),
+ id,
+ name,
+ screen_name,
+ url,
+ relationship: undefined,
+})
+
+describe('Users store', () => {
+ beforeEach(() => {
+ setActivePinia(createTestingPinia({ stubActions: false }))
})
describe('addNewUsers', () => {
@@ -91,9 +91,9 @@ describe('The users store', () => {
it('adds new users to the set, merging in new information for old users', () => {
const store = useUsersStore()
- const modUser = user({ name: 'Dude' })
+ const modUser = mockUser({ name: 'Dude' })
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
expect(store.users).to.have.length(1)
expect(store.users).to.have.all.keys(userId)
@@ -106,9 +106,9 @@ describe('The users store', () => {
it('ignores new users if timestamp is older', () => {
const store = useUsersStore()
- const modUser = user({ name: 'Old guy' })
+ const modUser = mockUser({ name: 'Old guy' })
- store.addNewUsers({ data: [user()], timestamp: 2000 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 2000 })
expect(store.users).to.have.length(1)
expect(store.users).to.have.all.keys(userId)
expect(store.users.get(userId).name).to.eql('Guy')
@@ -123,18 +123,18 @@ describe('The users store', () => {
const store = useUsersStore()
const userFields = {
- ...user(),
+ ...mockUser(),
fields: [{ name: 'Label 1', value: 'Content 1' }],
}
const firstModUser = {
- ...user(),
+ ...mockUser(),
fields: [
{ name: 'Label 2', value: 'Content 2' },
{ name: 'Label 3', value: 'Content 3' },
],
}
const secondModUser = {
- ...user(),
+ ...mockUser(),
fields: [{ name: 'Label 4', value: 'Content 4' }],
}
@@ -159,14 +159,14 @@ describe('The users store', () => {
const store = useUsersStore()
const modUser = {
- ...user(),
+ ...mockUser(),
relationship: {
id: userId,
following: true,
},
}
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
store.addNewUsers({ data: [modUser], timestamp: 2 })
expect(store.relationships).to.have.length(1)
@@ -179,14 +179,14 @@ describe('The users store', () => {
const store = useUsersStore()
const modUser = {
- ...user({ name: 'Old Dude' }),
+ ...mockUser({ name: 'Old Dude' }),
relationship: {
id: userId,
following: true,
},
}
- store.addNewUsers({ data: [user()], timestamp: 2000 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 2000 })
store.addNewUsers({ data: [modUser], timestamp: 1991 })
expect(store.relationships).to.have.length(1)
@@ -198,10 +198,12 @@ describe('The users store', () => {
it("doesn't erase relationship information if new data has it missing", () => {
const store = useUsersStore()
- const modUser = user({ name: 'Dude' })
+ const modUser = mockUser({ name: 'Dude' })
store.addNewUsers({
- data: [{ ...user(), relationship: { id: userId, following: true } }],
+ data: [
+ { ...mockUser(), relationship: { id: userId, following: true } },
+ ],
timestamp: 1,
})
store.addNewUsers({ data: [modUser], timestamp: 2 })
@@ -219,7 +221,7 @@ describe('The users store', () => {
const store = useUsersStore()
const relationship = { id: userId, following: true }
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
store.updateUserRelationships({ data: relationship, timestamp: 2 })
expect(store.relationship(userId)).to.eql({ id: userId, following: true })
@@ -240,7 +242,7 @@ describe('The users store', () => {
const relationship = { id: userId, following: true }
store.updateUserRelationships({ data: relationship, timestamp: 1 })
- store.addNewUsers({ data: [user()], timestamp: 2 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 2 })
expect(store.relationship(userId)).to.eql({ id: userId, following: true })
expect(store.findUser(userId).relationship).to.eql({
@@ -255,7 +257,7 @@ describe('The users store', () => {
const newRelationship = { id: userId, following: false }
store.addNewUsers({
- data: [{ ...user(), relationship: newRelationship }],
+ data: [{ ...mockUser(), relationship: newRelationship }],
timestamp: 2000,
})
store.updateUserRelationships({ data: oldRelationship, timestamp: 1991 })
@@ -274,13 +276,13 @@ describe('The users store', () => {
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValueOnce(
- new Response(JSON.stringify(mastoApiUser()), {
+ new Response(JSON.stringify(mockMastoAPIUser()), {
headers: { 'Content-Type': 'application/json' },
}),
),
)
- const expected = user()
+ const expected = mockUser()
const store = useUsersStore()
const resultUser = await store.fetchUserIfMissing({ id: '1' })
@@ -300,14 +302,14 @@ describe('The users store', () => {
)
// fetch by name yields user id which we request next
.mockResolvedValueOnce(
- new Response(JSON.stringify(mastoApiUser()), {
+ new Response(JSON.stringify(mockMastoAPIUser()), {
headers: { 'Content-Type': 'application/json' },
}),
)
.mockThrowOnce(new Error("Shouldn't be called more than once")),
)
- const expected = user()
+ const expected = mockUser()
const store = useUsersStore()
const resultUser1 = await store.fetchUserIfMissing({ name: 'user' })
const resultUser2 = await store.fetchUserIfMissing({ id: '1' })
@@ -323,11 +325,11 @@ describe('The users store', () => {
vi.fn().mockThrowOnce(new Error("Shouldn't be called at all")),
)
const store = useUsersStore()
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
const resultUser1 = await store.fetchUserIfMissing({ id: '1' })
const resultUser2 = await store.fetchUserIfMissing({ name: 'user' })
- const expected = user()
+ const expected = mockUser()
expect(resultUser1).to.deep.include(expected)
expect(resultUser2).to.deep.include(expected)
@@ -338,7 +340,7 @@ describe('The users store', () => {
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValueOnce(
- new Response(JSON.stringify(mastoApiUser()), {
+ new Response(JSON.stringify(mockMastoAPIUser()), {
status: 404,
statusText: 'Not Found',
headers: { 'Content-Type': 'application/json' },
@@ -371,8 +373,12 @@ describe('The users store', () => {
.mockResolvedValueOnce(
new Response(
JSON.stringify([
- mastoApiUser({ screen_name: 'snake', name: 'John', id: '2' }),
- mastoApiUser({
+ mockMastoAPIUser({
+ screen_name: 'snake',
+ name: 'John',
+ id: '2',
+ }),
+ mockMastoAPIUser({
screen_name: 'zero',
name: 'David Oh',
id: '3',
@@ -386,12 +392,12 @@ describe('The users store', () => {
.mockResolvedValueOnce(
new Response(
JSON.stringify([
- mastoApiUser({
+ mockMastoAPIUser({
screen_name: 'sigint',
name: 'Mr.Anderson',
id: '4',
}),
- mastoApiUser({
+ mockMastoAPIUser({
screen_name: 'paramedic',
name: 'Dr.Clark',
id: '5',
@@ -406,7 +412,7 @@ describe('The users store', () => {
vi.stubGlobal('fetch', mockFetch)
const store = useUsersStore()
- store.addNewUsers({ timestamp: 1, data: user() })
+ store.addNewUsers({ timestamp: 1, data: mockUser() })
const urlGroup = group === 'Friends' ? 'Following' : group
const us = store.users.get(userId)
@@ -443,8 +449,12 @@ describe('The users store', () => {
.mockResolvedValueOnce(
new Response(
JSON.stringify([
- mastoApiUser({ screen_name: 'snake', name: 'John', id: '2' }),
- mastoApiUser({
+ mockMastoAPIUser({
+ screen_name: 'snake',
+ name: 'John',
+ id: '2',
+ }),
+ mockMastoAPIUser({
screen_name: 'zero',
name: 'David Oh',
id: '3',
@@ -458,12 +468,12 @@ describe('The users store', () => {
.mockResolvedValueOnce(
new Response(
JSON.stringify([
- mastoApiUser({
+ mockMastoAPIUser({
screen_name: 'sigint',
name: 'Mr.Anderson',
id: '4',
}),
- mastoApiUser({
+ mockMastoAPIUser({
screen_name: 'paramedic',
name: 'Dr.Clark',
id: '5',
@@ -478,7 +488,7 @@ describe('The users store', () => {
vi.stubGlobal('fetch', mockFetch)
const store = useUsersStore()
- store.addNewUsers({ timestamp: 1, data: user() })
+ store.addNewUsers({ timestamp: 1, data: mockUser() })
const us = store.users.get(userId)
@@ -514,7 +524,7 @@ describe('The users store', () => {
vi.stubGlobal('fetch', mockFetch)
const store = useUsersStore()
- store.addNewUsers({ timestamp: 1, data: user() })
+ store.addNewUsers({ timestamp: 1, data: mockUser() })
const us = store.users.get(userId)
store.currentUser = us
@@ -548,9 +558,9 @@ describe('The users store', () => {
store.addNewUsers({
timestamp: 1,
data: [
- user(),
- { ...user({ name: 'John', screen_name: 'snake', id: '2' }) },
- { ...user({ name: 'David Oh', screen_name: 'zero', id: '3' }) },
+ mockUser(),
+ { ...mockUser({ name: 'John', screen_name: 'snake', id: '2' }) },
+ { ...mockUser({ name: 'David Oh', screen_name: 'zero', id: '3' }) },
],
})
@@ -572,7 +582,7 @@ describe('The users store', () => {
describe('misc updates', () => {
it('updateUserAdminData', () => {
const store = useUsersStore()
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
const adminData = { is_active: true, tags: ['one', 'two'] }
store.updateUserAdminData(userId, adminData)
@@ -583,7 +593,7 @@ describe('The users store', () => {
it('updateRight', () => {
const store = useUsersStore()
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
store.updateRight(userId, 'right1', true)
store.updateRight(userId, 'right2', false)
@@ -594,7 +604,7 @@ describe('The users store', () => {
it('clearFollowLists', () => {
const store = useUsersStore()
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
const userData = store.users.get(userId)
store.relationshipsLists.friends.get(userData).add('2')
store.relationshipsLists.friends.get(userData).add('3')
@@ -613,7 +623,7 @@ describe('The users store', () => {
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValueOnce(
- new Response(JSON.stringify(mastoApiUser()), {
+ new Response(JSON.stringify(mockMastoAPIUser()), {
headers: { 'Content-Type': 'application/json' },
}),
),
@@ -653,9 +663,9 @@ describe('The users store', () => {
// Adding some users to verify they are getting cleaned afterwards
store.addNewUsers({
data: [
- user(),
- { ...user({ name: 'John', screen_name: 'snake' }) },
- { ...user({ name: 'David Oh', screen_name: 'zero' }) },
+ mockUser(),
+ { ...mockUser({ name: 'John', screen_name: 'snake' }) },
+ { ...mockUser({ name: 'David Oh', screen_name: 'zero' }) },
],
timestamp: 2000,
})
@@ -679,7 +689,7 @@ describe('The users store', () => {
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValueOnce(
- new Response(JSON.stringify(mastoApiUser()), {
+ new Response(JSON.stringify(mockMastoAPIUser()), {
status: 403,
statusText: 'Forbidden',
headers: { 'Content-Type': 'application/json' },
@@ -756,17 +766,17 @@ describe('The users store', () => {
useMergedConfigStore().mergedConfig = { useStreamingApi: true }
const store = useUsersStore()
- store.currentUser = user()
+ store.currentUser = mockUser()
// Adding some users to verify they are getting cleaned afterwards
store.addNewUsers({
data: [
- user(),
+ mockUser(),
{
- ...user({ name: 'John', screen_name: 'snake' }),
+ ...mockUser({ name: 'John', screen_name: 'snake' }),
relationship: { id: userId, following: true },
},
- { ...user({ name: 'David Oh', screen_name: 'zero' }) },
+ { ...mockUser({ name: 'David Oh', screen_name: 'zero' }) },
],
timestamp: 2000,
})
@@ -1168,7 +1178,7 @@ describe('The users store', () => {
vi.stubGlobal('fetch', mockFetch)
const store = useUsersStore()
- store.currentUser = user()
+ store.currentUser = mockUser()
store.currentUser.domainMutes = new Set()
if (action === 'unmute') {
store.currentUser.domainMutes.add('example.com')
@@ -1198,14 +1208,6 @@ describe('The users store', () => {
'blockUser',
'unblockUser',
])('%ss', async (action) => {
- const mockFetch = vi.fn().mockResolvedValueOnce(
- new Response(JSON.stringify({ id: userId }), {
- headers: { 'Content-Type': 'application/json' },
- }),
- )
-
- vi.stubGlobal('fetch', mockFetch)
-
const store = useUsersStore()
store[action] = vi.fn().mockResolvedValue(async () => {
/* no-op */
@@ -1226,30 +1228,30 @@ describe('The users store', () => {
it('relationship returns a placeholder if relationship info is missing while user is present', () => {
const store = useUsersStore()
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
expect(store.relationship(userId)).to.eql({ id: userId, loading: true })
})
it('findUser returns user with matching id', () => {
const store = useUsersStore()
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
expect(store.findUser(userId).id).to.eql(userId)
})
it('findUserByName returns user with matching screen_name', () => {
const store = useUsersStore()
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
- expect(store.findUserByName(user().screen_name).id).to.eql(userId)
+ expect(store.findUserByName(mockUser().screen_name).id).to.eql(userId)
})
it('findUserByName returns user with matching url', () => {
const store = useUsersStore()
- store.addNewUsers({ data: [user()], timestamp: 1 })
+ store.addNewUsers({ data: [mockUser()], timestamp: 1 })
- expect(store.findUserByUrl(user().url).id).to.eql(userId)
+ expect(store.findUserByUrl(mockUser().url).id).to.eql(userId)
})
})
})