refactor and unify how query strings are formed
This commit is contained in:
parent
c062ae66e3
commit
bd06c8801a
7 changed files with 263 additions and 146 deletions
|
|
@ -798,8 +798,8 @@ const users = {
|
|||
}
|
||||
|
||||
if (useMergedConfigStore().mergedConfig.useStreamingApi) {
|
||||
dispatch('fetchTimeline', { timeline: 'friends', since: null })
|
||||
dispatch('fetchNotifications', { since: null })
|
||||
dispatch('fetchTimeline', { timeline: 'friends', sinceId: null })
|
||||
dispatch('fetchNotifications', { sinceId: null })
|
||||
dispatch('enableMastoSockets', true)
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
parseStatus,
|
||||
parseUser,
|
||||
} from '../entity_normalizer/entity_normalizer.service.js'
|
||||
import { promisedRequest } from './helpers.js'
|
||||
import { paramsString, promisedRequest } from './helpers.js'
|
||||
|
||||
import { RegistrationError, StatusCodeError } from 'src/services/errors/errors'
|
||||
|
||||
|
|
@ -46,8 +46,16 @@ const MASTODON_UNRETWEET_URL = (id) => `/api/v1/statuses/${id}/unreblog`
|
|||
const MASTODON_DELETE_URL = (id) => `/api/v1/statuses/${id}`
|
||||
const MASTODON_FOLLOW_URL = (id) => `/api/v1/accounts/${id}/follow`
|
||||
const MASTODON_UNFOLLOW_URL = (id) => `/api/v1/accounts/${id}/unfollow`
|
||||
const MASTODON_FOLLOWING_URL = (id) => `/api/v1/accounts/${id}/following`
|
||||
const MASTODON_FOLLOWERS_URL = (id) => `/api/v1/accounts/${id}/followers`
|
||||
const MASTODON_FOLLOWING_URL = (
|
||||
id,
|
||||
{ minId, maxId, sinceId, limit, withRelationships },
|
||||
) =>
|
||||
`/api/v1/accounts/${id}/following${paramsString({ minId, maxId, sinceId, limit, withRelationships })}`
|
||||
const MASTODON_FOLLOWERS_URL = (
|
||||
id,
|
||||
{ minId, maxId, sinceId, limit, withRelationships },
|
||||
) =>
|
||||
`/api/v1/accounts/${id}/followers${paramsString({ minId, maxId, sinceId, limit, withRelationships })}`
|
||||
const MASTODON_FOLLOW_REQUESTS_URL = '/api/v1/follow_requests'
|
||||
const MASTODON_APPROVE_USER_URL = (id) =>
|
||||
`/api/v1/follow_requests/${id}/authorize`
|
||||
|
|
@ -61,7 +69,8 @@ const MASTODON_STATUS_SOURCE_URL = (id) => `/api/v1/statuses/${id}/source`
|
|||
const MASTODON_STATUS_HISTORY_URL = (id) => `/api/v1/statuses/${id}/history`
|
||||
const MASTODON_USER_URL = '/api/v1/accounts'
|
||||
const MASTODON_USER_LOOKUP_URL = '/api/v1/accounts/lookup'
|
||||
const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships'
|
||||
const MASTODON_USER_RELATIONSHIPS_URL = ({ id, withSuspended }) =>
|
||||
`/api/v1/accounts/relationships/${paramsString({ id, withSuspended })}`
|
||||
const MASTODON_USER_TIMELINE_URL = (id) => `/api/v1/accounts/${id}/statuses`
|
||||
const MASTODON_USER_IN_LISTS = (id) => `/api/v1/accounts/${id}/lists`
|
||||
const MASTODON_LIST_URL = (id) => `/api/v1/lists/${id}`
|
||||
|
|
@ -70,8 +79,20 @@ const MASTODON_LIST_ACCOUNTS_URL = (id) => `/api/v1/lists/${id}/accounts`
|
|||
const MASTODON_TAG_TIMELINE_URL = (tag) => `/api/v1/timelines/tag/${tag}`
|
||||
const MASTODON_BOOKMARK_TIMELINE_URL = '/api/v1/bookmarks'
|
||||
const AKKOMA_BUBBLE_TIMELINE_URL = '/api/v1/timelines/bubble'
|
||||
const MASTODON_USER_BLOCKS_URL = '/api/v1/blocks/'
|
||||
const MASTODON_USER_MUTES_URL = '/api/v1/mutes/'
|
||||
const MASTODON_USER_BLOCKS_URL = ({
|
||||
maxId,
|
||||
sinceId,
|
||||
limit,
|
||||
withRelationships,
|
||||
}) =>
|
||||
`/api/v1/blocks/${paramsString({ maxId, sinceId, limit, withRelationships })}`
|
||||
const MASTODON_USER_MUTES_URL = ({
|
||||
maxId,
|
||||
sinceId,
|
||||
limit,
|
||||
withRelationships,
|
||||
}) =>
|
||||
`/api/v1/mutes/${paramsString({ maxId, sinceId, limit, withRelationships })}`
|
||||
const MASTODON_BLOCK_USER_URL = (id) => `/api/v1/accounts/${id}/block`
|
||||
const MASTODON_UNBLOCK_USER_URL = (id) => `/api/v1/accounts/${id}/unblock`
|
||||
const MASTODON_MUTE_USER_URL = (id) => `/api/v1/accounts/${id}/mute`
|
||||
|
|
@ -113,12 +134,14 @@ const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) =>
|
|||
`/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
|
||||
const PLEROMA_CHATS_URL = '/api/v1/pleroma/chats'
|
||||
const PLEROMA_CHAT_URL = (id) => `/api/v1/pleroma/chats/by-account-id/${id}`
|
||||
const PLEROMA_CHAT_MESSAGES_URL = (id) => `/api/v1/pleroma/chats/${id}/messages`
|
||||
const PLEROMA_CHAT_MESSAGES_URL = (id, { maxId, sinceId, limit }) =>
|
||||
`/api/v1/pleroma/chats/${id}/messages${paramsString({ maxId, sinceId, limit })}`
|
||||
const PLEROMA_CHAT_READ_URL = (id) => `/api/v1/pleroma/chats/${id}/read`
|
||||
const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) =>
|
||||
`/api/v1/pleroma/chats/${chatId}/messages/${messageId}`
|
||||
const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
|
||||
const PLEROMA_SCROBBLES_URL = (id) => `/api/v1/pleroma/accounts/${id}/scrobbles`
|
||||
const PLEROMA_SCROBBLES_URL = (id, { maxId, sinceId, minId, limit, offset }) =>
|
||||
`/api/v1/pleroma/accounts/${id}/scrobbles${paramsString({ maxId, sinceId, minId, limit, offset })}`
|
||||
const PLEROMA_STATUS_QUOTES_URL = (id) =>
|
||||
`/api/v1/pleroma/statuses/${id}/quotes`
|
||||
const PLEROMA_USER_FAVORITES_TIMELINE_URL = (id) =>
|
||||
|
|
@ -128,20 +151,14 @@ const PLEROMA_BOOKMARK_FOLDER_URL = (id) =>
|
|||
`/api/v1/pleroma/bookmark_folders/${id}`
|
||||
|
||||
const EMOJI_PACKS_URL = (page, pageSize) =>
|
||||
`/api/v1/pleroma/emoji/packs?page=${page}&page_size=${pageSize}`
|
||||
`/api/v1/pleroma/emoji/packs${paramsString({ page, pageSize })}`
|
||||
|
||||
export const updateNotificationSettings = ({ credentials, settings }) => {
|
||||
const form = new FormData()
|
||||
|
||||
each(settings, (value, key) => {
|
||||
form.append(key, value)
|
||||
})
|
||||
|
||||
return promisedRequest({
|
||||
url: `${NOTIFICATION_SETTINGS_URL}?${new URLSearchParams(settings)}`,
|
||||
url: NOTIFICATION_SETTINGS_URL,
|
||||
credentials,
|
||||
method: 'PUT',
|
||||
formData: form,
|
||||
payload: settings,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -380,35 +397,17 @@ export const fetchUserByName = ({ name, credentials }) =>
|
|||
})
|
||||
.then((id) => fetchUser({ id, credentials }))
|
||||
|
||||
export const fetchUserRelationship = ({ id, credentials }) =>
|
||||
export const fetchUserRelationship = ({ id, withSuspended, credentials }) =>
|
||||
promisedRequest({
|
||||
url: `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}`,
|
||||
url: MASTODON_USER_RELATIONSHIPS_URL({ id, withSuspended }),
|
||||
credentials,
|
||||
})
|
||||
|
||||
export const fetchFriends = ({
|
||||
id,
|
||||
maxId,
|
||||
sinceId,
|
||||
limit = 20,
|
||||
credentials,
|
||||
}) => {
|
||||
let url = MASTODON_FOLLOWING_URL(id)
|
||||
const args = [
|
||||
maxId && `max_id=${maxId}`,
|
||||
sinceId && `since_id=${sinceId}`,
|
||||
limit && `limit=${limit}`,
|
||||
'with_relationships=true',
|
||||
]
|
||||
.filter((_) => _)
|
||||
.join('&')
|
||||
|
||||
url = url + (args ? '?' + args : '')
|
||||
return promisedRequest({
|
||||
url,
|
||||
export const fetchFriends = ({ id, maxId, sinceId, limit = 20, credentials }) =>
|
||||
promisedRequest({
|
||||
url: MASTODON_FOLLOWING_URL(id, { maxId, sinceId, limit }),
|
||||
credentials,
|
||||
}).then((data) => data.map(parseUser))
|
||||
}
|
||||
|
||||
export const exportFriends = ({ id, credentials }) => {
|
||||
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: TODO refactor this
|
||||
|
|
@ -418,7 +417,12 @@ export const exportFriends = ({ id, credentials }) => {
|
|||
let more = true
|
||||
while (more) {
|
||||
const maxId = friends.length > 0 ? last(friends).id : undefined
|
||||
const users = await fetchFriends({ id, maxId, credentials })
|
||||
const users = await fetchFriends({
|
||||
id,
|
||||
maxId,
|
||||
credentials,
|
||||
withRelationships: true,
|
||||
})
|
||||
friends = concat(friends, users)
|
||||
if (users.length === 0) {
|
||||
more = false
|
||||
|
|
@ -437,23 +441,16 @@ export const fetchFollowers = ({
|
|||
sinceId,
|
||||
limit = 20,
|
||||
credentials,
|
||||
}) => {
|
||||
let url = MASTODON_FOLLOWERS_URL(id)
|
||||
const args = [
|
||||
maxId && `max_id=${maxId}`,
|
||||
sinceId && `since_id=${sinceId}`,
|
||||
limit && `limit=${limit}`,
|
||||
'with_relationships=true',
|
||||
]
|
||||
.filter((_) => _)
|
||||
.join('&')
|
||||
|
||||
url += args ? '?' + args : ''
|
||||
return promisedRequest({
|
||||
url,
|
||||
}) =>
|
||||
promisedRequest({
|
||||
url: MASTODON_FOLLOWERS_URL(id, {
|
||||
maxId,
|
||||
sinceId,
|
||||
limit,
|
||||
withRelationships: true,
|
||||
}),
|
||||
credentials,
|
||||
}).then((data) => data.map(parseUser))
|
||||
}
|
||||
|
||||
export const fetchFollowRequests = ({ credentials }) =>
|
||||
promisedRequest({
|
||||
|
|
@ -567,17 +564,17 @@ export const fetchStatusHistory = ({ status, credentials }) =>
|
|||
export const fetchTimeline = ({
|
||||
timeline,
|
||||
credentials,
|
||||
since = false,
|
||||
minId = false,
|
||||
until = false,
|
||||
userId = false,
|
||||
listId = false,
|
||||
statusId = false,
|
||||
tag = false,
|
||||
withMuted = false,
|
||||
sinceId,
|
||||
minId,
|
||||
maxId,
|
||||
userId,
|
||||
listId,
|
||||
statusId,
|
||||
tag,
|
||||
withMuted,
|
||||
replyVisibility = 'all',
|
||||
includeTypes = [],
|
||||
bookmarkFolderId = false,
|
||||
bookmarkFolderId,
|
||||
}) => {
|
||||
const timelineUrls = {
|
||||
public: MASTODON_PUBLIC_TIMELINE,
|
||||
|
|
@ -595,8 +592,14 @@ export const fetchTimeline = ({
|
|||
quotes: PLEROMA_STATUS_QUOTES_URL,
|
||||
bubble: AKKOMA_BUBBLE_TIMELINE_URL,
|
||||
}
|
||||
|
||||
const isNotifications = timeline === 'notifications'
|
||||
const params = []
|
||||
const params = {
|
||||
minId,
|
||||
sinceId,
|
||||
maxId,
|
||||
limit: 20,
|
||||
}
|
||||
|
||||
let url = timelineUrls[timeline]
|
||||
|
||||
|
|
@ -616,51 +619,34 @@ export const fetchTimeline = ({
|
|||
url = url(statusId)
|
||||
}
|
||||
|
||||
if (minId) {
|
||||
params.push(['min_id', minId])
|
||||
}
|
||||
if (since) {
|
||||
params.push(['since_id', since])
|
||||
}
|
||||
if (until) {
|
||||
params.push(['max_id', until])
|
||||
}
|
||||
if (tag) {
|
||||
url = url(tag)
|
||||
}
|
||||
|
||||
if (timeline === 'media') {
|
||||
params.push(['only_media', 1])
|
||||
params.onlyMedia = 1
|
||||
}
|
||||
if (timeline === 'public') {
|
||||
params.push(['local', true])
|
||||
params.local = true
|
||||
}
|
||||
if (timeline === 'public' || timeline === 'publicAndExternal') {
|
||||
params.push(['only_media', false])
|
||||
params.onlyMedia = false
|
||||
}
|
||||
if (timeline !== 'favorites' && timeline !== 'bookmarks') {
|
||||
params.push(['with_muted', withMuted])
|
||||
params.withMuted = withMuted
|
||||
}
|
||||
if (replyVisibility !== 'all') {
|
||||
params.push(['reply_visibility', replyVisibility])
|
||||
params.replyVisibility = replyVisibility
|
||||
}
|
||||
if (includeTypes.size > 0) {
|
||||
includeTypes.forEach((type) => {
|
||||
params.push(['include_types[]', type])
|
||||
})
|
||||
params.includeTypes = includeTypes
|
||||
}
|
||||
if (timeline === 'bookmarks' && bookmarkFolderId) {
|
||||
params.push(['folder_id', bookmarkFolderId])
|
||||
params.folderId = bookmarkFolderId
|
||||
}
|
||||
|
||||
params.push(['limit', 20])
|
||||
|
||||
const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join(
|
||||
'&',
|
||||
)
|
||||
url += `?${queryString}`
|
||||
|
||||
return promisedRequest({
|
||||
url,
|
||||
url: url + paramsString(params),
|
||||
credentials,
|
||||
}).then(async (data) => {
|
||||
const pagination = parseLinkHeaderPagination(
|
||||
|
|
@ -1036,16 +1022,11 @@ export const generateMfaBackupCodes = ({ credentials }) =>
|
|||
method: 'GET',
|
||||
})
|
||||
|
||||
export const fetchMutes = ({ maxId, credentials }) => {
|
||||
const query = new URLSearchParams({ with_relationships: true })
|
||||
if (maxId) {
|
||||
query.append('max_id', maxId)
|
||||
}
|
||||
return promisedRequest({
|
||||
url: `${MASTODON_USER_MUTES_URL}?${query.toString()}`,
|
||||
export const fetchMutes = ({ maxId, credentials }) =>
|
||||
promisedRequest({
|
||||
url: MASTODON_USER_MUTES_URL({ maxId, withRelationships: true }),
|
||||
credentials,
|
||||
}).then((users) => users.map(parseUser))
|
||||
}
|
||||
|
||||
export const muteUser = ({ id, expiresIn, credentials }) => {
|
||||
const payload = {}
|
||||
|
|
@ -1068,16 +1049,11 @@ export const unmuteUser = ({ id, credentials }) =>
|
|||
method: 'POST',
|
||||
})
|
||||
|
||||
export const fetchBlocks = ({ maxId, credentials }) => {
|
||||
const query = new URLSearchParams({ with_relationships: true })
|
||||
if (maxId) {
|
||||
query.append('max_id', maxId)
|
||||
}
|
||||
return promisedRequest({
|
||||
url: `${MASTODON_USER_BLOCKS_URL}?${query.toString()}`,
|
||||
export const fetchBlocks = ({ maxId, credentials }) =>
|
||||
promisedRequest({
|
||||
url: MASTODON_USER_BLOCKS_URL({ maxId, withRelationships: true }),
|
||||
credentials,
|
||||
}).then((users) => users.map(parseUser))
|
||||
}
|
||||
|
||||
export const addBackup = ({ credentials }) =>
|
||||
promisedRequest({
|
||||
|
|
@ -1519,19 +1495,8 @@ export const chatMessages = ({
|
|||
sinceId,
|
||||
limit = 20,
|
||||
}) => {
|
||||
let url = PLEROMA_CHAT_MESSAGES_URL(id)
|
||||
const args = [
|
||||
maxId && `max_id=${maxId}`,
|
||||
sinceId && `since_id=${sinceId}`,
|
||||
limit && `limit=${limit}`,
|
||||
]
|
||||
.filter((_) => _)
|
||||
.join('&')
|
||||
|
||||
url = url + (args ? '?' + args : '')
|
||||
|
||||
return promisedRequest({
|
||||
url,
|
||||
url: PLEROMA_CHAT_MESSAGES_URL(id, { maxId, sinceId, limit }),
|
||||
method: 'GET',
|
||||
credentials,
|
||||
})
|
||||
|
|
@ -1584,15 +1549,10 @@ export const deleteChatMessage = ({ chatId, messageId, credentials }) =>
|
|||
credentials,
|
||||
})
|
||||
|
||||
export const fetchScrobbles = ({ accountId, limit = 1 }) => {
|
||||
let url = PLEROMA_SCROBBLES_URL(accountId)
|
||||
const params = [['limit', limit]]
|
||||
const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join(
|
||||
'&',
|
||||
)
|
||||
url += `?${queryString}`
|
||||
return promisedRequest({ url })
|
||||
}
|
||||
export const fetchScrobbles = ({ accountId, limit = 1 }) =>
|
||||
promisedRequest({
|
||||
url: PLEROMA_SCROBBLES_URL(accountId, { limit }),
|
||||
})
|
||||
|
||||
export const fetchBookmarkFolders = ({ credentials }) =>
|
||||
promisedRequest({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,71 @@
|
|||
import { snakeCase } from 'lodash'
|
||||
|
||||
import { RegistrationError, StatusCodeError } from 'src/services/errors/errors'
|
||||
|
||||
export const paramsString = (params = {}) => {
|
||||
if (params == null || params === undefined) return ''
|
||||
|
||||
if (typeof params !== 'object' || Array.isArray(params)) {
|
||||
throw new Error('Params are not an object!')
|
||||
}
|
||||
|
||||
const entries = (() => {
|
||||
if (params instanceof Map) {
|
||||
return params.entries()
|
||||
} else {
|
||||
return Object.entries(params)
|
||||
}
|
||||
})()
|
||||
|
||||
if (entries.length === 0) return ''
|
||||
|
||||
const arrays = []
|
||||
const nonArrays = []
|
||||
|
||||
entries.forEach(([k, v]) => {
|
||||
if (v == null) return // Drop nulls
|
||||
if (
|
||||
(typeof v === 'object' && !Array.isArray(v)) ||
|
||||
typeof v === 'function'
|
||||
) {
|
||||
throw new Error('Param cannot be non-primitive!')
|
||||
}
|
||||
if (Array.isArray(v)) {
|
||||
arrays.push([k, v])
|
||||
} else {
|
||||
nonArrays.push([k, v])
|
||||
}
|
||||
})
|
||||
|
||||
arrays.forEach(([k, array]) => {
|
||||
array.forEach((v) => {
|
||||
if (
|
||||
typeof v === 'object' ||
|
||||
typeof v === 'function' ||
|
||||
typeof v === 'undefined'
|
||||
)
|
||||
throw new Error('Array param cannot contain non-primitives!')
|
||||
})
|
||||
})
|
||||
|
||||
return (
|
||||
'?' +
|
||||
[
|
||||
...nonArrays.map(([k, v]) => [snakeCase(k), v]),
|
||||
// turning [a,[1,2,3]] into [[a[],1],[a[],2],[a[],3]]
|
||||
...arrays.reduce(
|
||||
(acc, [k, arrayValue]) => [
|
||||
...acc,
|
||||
...arrayValue.map((v) => [snakeCase(k) + '[]', v]),
|
||||
],
|
||||
[],
|
||||
),
|
||||
]
|
||||
.map(([k, v]) => `${k}=${window.encodeURIComponent(v)}`)
|
||||
.join('&')
|
||||
)
|
||||
}
|
||||
|
||||
export const promisedRequest = ({
|
||||
method,
|
||||
url,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const mastoApiNotificationTypes = new Set([
|
|||
'pleroma:report',
|
||||
])
|
||||
|
||||
const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
|
||||
const fetchAndUpdate = ({ store, credentials, older = false, sinceId }) => {
|
||||
const args = { credentials }
|
||||
const rootState = store.rootState || store.state
|
||||
const timelineData = rootState.notifications
|
||||
|
|
@ -35,24 +35,24 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
|
|||
mastoApiNotificationTypes.add('pleroma:chat_mention')
|
||||
}
|
||||
|
||||
args.includeTypes = mastoApiNotificationTypes
|
||||
args.includeTypes = [...mastoApiNotificationTypes]
|
||||
args.withMuted = !hideMutedPosts
|
||||
|
||||
args.timeline = 'notifications'
|
||||
if (older) {
|
||||
if (timelineData.minId !== Number.POSITIVE_INFINITY) {
|
||||
args.until = timelineData.minId
|
||||
args.maxId = timelineData.minId
|
||||
}
|
||||
return fetchNotifications({ store, args, older })
|
||||
} else {
|
||||
// fetch new notifications
|
||||
if (
|
||||
since === undefined &&
|
||||
sinceId === undefined &&
|
||||
timelineData.maxId !== Number.POSITIVE_INFINITY
|
||||
) {
|
||||
args.since = timelineData.maxId
|
||||
} else if (since !== null) {
|
||||
args.since = since
|
||||
args.sinceId = timelineData.maxId
|
||||
} else if (sinceId !== null) {
|
||||
args.sinceId = sinceId
|
||||
}
|
||||
const result = fetchNotifications({ store, args, older })
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
|
|||
if (readNotifsIds.length > 0 && readNotifsIds.length > 0) {
|
||||
const minId = Math.min(...unreadNotifsIds) // Oldest known unread notification
|
||||
if (minId !== Infinity) {
|
||||
args.since = false // Don't use since_id since it sorta conflicts with min_id
|
||||
args.sinceId = null // Don't use since_id since it sorta conflicts with min_id
|
||||
args.minId = minId - 1 // go beyond
|
||||
fetchNotifications({ store, args, older })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ const fetchAndUpdate = ({
|
|||
bookmarkFolderId = false,
|
||||
tag = false,
|
||||
until,
|
||||
since,
|
||||
sinceId,
|
||||
}) => {
|
||||
const args = { timeline, credentials }
|
||||
const rootState = store.rootState || store.state
|
||||
|
|
@ -53,10 +53,10 @@ const fetchAndUpdate = ({
|
|||
if (older) {
|
||||
args.until = until || timelineData.minId
|
||||
} else {
|
||||
if (since === undefined) {
|
||||
args.since = timelineData.maxId
|
||||
} else if (since !== null) {
|
||||
args.since = since
|
||||
if (sinceId === undefined) {
|
||||
args.sinceId = timelineData.maxId
|
||||
} else if (sinceId !== null) {
|
||||
args.sinceId = sinceId
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
90
test/unit/specs/services/api/helpers.spec.js
Normal file
90
test/unit/specs/services/api/helpers.spec.js
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import { paramsString } from 'src/services/api/helpers.js'
|
||||
|
||||
describe('API Helpers', () => {
|
||||
describe.only('paramsString', () => {
|
||||
it('should return empty string when given empty object', () => {
|
||||
const string = paramsString({})
|
||||
|
||||
expect(string).to.eq('')
|
||||
})
|
||||
|
||||
it('should return empty string when given null', () => {
|
||||
const string = paramsString(null)
|
||||
|
||||
expect(string).to.eq('')
|
||||
})
|
||||
|
||||
it('should return empty string when given undefined', () => {
|
||||
const string = paramsString(undefined)
|
||||
|
||||
expect(string).to.eq('')
|
||||
})
|
||||
|
||||
it('should return URI param string for normal object', () => {
|
||||
const string = paramsString({ a: 1, b: '3' })
|
||||
|
||||
expect(string).to.eq('?a=1&b=3')
|
||||
})
|
||||
|
||||
it('should encode objects correctly', () => {
|
||||
const string = paramsString({ foo: true, bar: [1, 2, 3] })
|
||||
|
||||
expect(string).to.eq('?foo=true&bar[]=1&bar[]=2&bar[]=3')
|
||||
})
|
||||
|
||||
it('should drop nullish params', () => {
|
||||
const string = paramsString({ present: 'yes', missing: null })
|
||||
|
||||
expect(string).to.eq('?present=yes')
|
||||
})
|
||||
|
||||
it('should convert camelCase keys to snake_keys objects correctly', () => {
|
||||
const string = paramsString({ isActive: true, MaybeNot: false })
|
||||
|
||||
expect(string).to.eq('?is_active=true&maybe_not=false')
|
||||
})
|
||||
|
||||
it('should work with maps', () => {
|
||||
const string = paramsString(
|
||||
new Map([
|
||||
['key', 'yes'],
|
||||
['key2', 'also yes'],
|
||||
]),
|
||||
)
|
||||
|
||||
expect(string).to.eq('?key=yes&key_2=also%20yes')
|
||||
})
|
||||
|
||||
it('should escape components correctly', () => {
|
||||
const string = paramsString({ gachi: '♂', muchi: 'Билли Геррингтон' })
|
||||
|
||||
expect(string).to.eq(
|
||||
'?gachi=%E2%99%82&muchi=%D0%91%D0%B8%D0%BB%D0%BB%D0%B8%20%D0%93%D0%B5%D1%80%D1%80%D0%B8%D0%BD%D0%B3%D1%82%D0%BE%D0%BD',
|
||||
)
|
||||
})
|
||||
|
||||
it('should throw when passed a non-object', () => {
|
||||
expect(() => {
|
||||
paramsString('Totally an object')
|
||||
}).to.throw()
|
||||
})
|
||||
|
||||
it('should throw when passed an array', () => {
|
||||
expect(() => {
|
||||
paramsString(['Totally an object'])
|
||||
}).to.throw()
|
||||
})
|
||||
|
||||
it('should throw when array param is non-primitive', () => {
|
||||
expect(() => {
|
||||
paramsString({ a: [() => ''] })
|
||||
}).to.throw()
|
||||
})
|
||||
|
||||
it('should throw when array param is nullish', () => {
|
||||
expect(() => {
|
||||
paramsString({ a: [1, null, 3] })
|
||||
}).to.throw()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import mastoapidata from '../../../../fixtures/mastoapi.json'
|
||||
|
||||
import {
|
||||
parseLinkHeaderPagination,
|
||||
parseNotification,
|
||||
parseStatus,
|
||||
parseUser,
|
||||
} from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js'
|
||||
import mastoapidata from '../../../../fixtures/mastoapi.json'
|
||||
} from 'src/services/entity_normalizer/entity_normalizer.service.js'
|
||||
|
||||
const makeMockUserMasto = (overrides = {}) => {
|
||||
return Object.assign(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue