From 15b8ed85a85e443d0d2bf518898b20dfa8ed0533 Mon Sep 17 00:00:00 2001 From: Nick Sellen Date: Tue, 19 Mar 2024 00:09:08 +0000 Subject: [PATCH] Support public activity query params (#2713) * Support public activity query params For: - place - activity type * Linting fix * Delete flakey unused cordova test --- src/activities/queries.js | 6 +- src/authuser/api/auth.spec.js | 60 ------------------- src/base/routes/embed.js | 3 + src/base/services.js | 5 ++ src/group/services.js | 6 +- src/groupInfo/pages/PublicActivitiesEmbed.vue | 9 +++ 6 files changed, 27 insertions(+), 62 deletions(-) delete mode 100644 src/authuser/api/auth.spec.js diff --git a/src/activities/queries.js b/src/activities/queries.js index 74f2951ebd..302c2c9191 100644 --- a/src/activities/queries.js +++ b/src/activities/queries.js @@ -273,13 +273,17 @@ export function useICSTokenQuery (queryOptions) { export function usePublicActivityListQuery ({ groupId, dateMin, + placeId, + activityTypeId, pageSize = 10, }, queryOptions = {}) { const query = useInfiniteQuery( - queryKeyActivityList({ groupId, dateMin }), + queryKeyActivityList({ groupId, dateMin, placeId, activityTypeId }), ({ pageParam }) => api.listPublic({ group: unref(groupId), dateMin: unref(dateMin), + place: unref(placeId), + activityType: unref(activityTypeId), cursor: pageParam, pageSize, }), diff --git a/src/authuser/api/auth.spec.js b/src/authuser/api/auth.spec.js deleted file mode 100644 index c77a0af7dd..0000000000 --- a/src/authuser/api/auth.spec.js +++ /dev/null @@ -1,60 +0,0 @@ -import MockAdapter from 'axios-mock-adapter' -import { describe, beforeEach, it, vi } from 'vitest' - -describe('authuser/api/auth', () => { - describe('in cordova', () => { - let mock, auth, lastRequest, axios - - const token = 'sometoken' - const email = 'foo@foo.com' - const password = 'foo' - - const requestInterceptor = config => { - lastRequest = config - return config - } - - beforeEach(async () => { - vi.resetModules() - axios = (await import('@/base/api/axios')).default - axios.interceptors.request.use(requestInterceptor) - lastRequest = null - mock = new MockAdapter(axios) - global.import.meta.env.MODE = 'cordova' - global.location.reload.mockReset() - auth = (await import('@/authuser/api/auth')).default - mock.onGet('/api/auth/user/').reply(200, { email }) - }) - - it('saves the token after login', async () => { - mock.onPost('/api/auth/token/').reply(200, { token }) - await auth.login({ email, password }) - expect(axios.defaults.headers.common.Authorization).toBe(`TOKEN ${token}`) - expect(auth.getToken()).toBe(token) - }) - - it('uses the token in subsequent requests', async () => { - mock.onPost('/api/auth/token/').reply(200, { token }) - await auth.login({ email, password }) - mock.onGet('/random/path').reply(200, 'yay') - await axios.get('/random/path') - expect(lastRequest.headers.Authorization).toBe(`TOKEN ${token}`) - }) - - it('clears the token and reloads if authentication fails', async () => { - mock.onPost('/api/auth/token/').reply(200, { token }) - await auth.login({ email, password }) - mock.onGet('/random/path').reply(403, { error_code: 'authentication_failed' }) - await axios.get('/random/path') - expect(axios.defaults.headers.common.Authorization).toBeUndefined() - expect(auth.getToken()).toBeFalsy() - expect(global.location.reload).toHaveBeenCalled() - }) - - it('does nothing fancy if authentication fails during explicit auth attempt', async () => { - mock.onPost('/api/auth/token/').reply(403, { error_code: 'authentication_failed' }) - await expect(auth.login({ email, password })).rejects.toHaveProperty('response.data.errorCode', 'authentication_failed') - expect(global.location.reload).not.toHaveBeenCalled() - }) - }) -}) diff --git a/src/base/routes/embed.js b/src/base/routes/embed.js index da72595d9a..0f5d44a432 100644 --- a/src/base/routes/embed.js +++ b/src/base/routes/embed.js @@ -5,5 +5,8 @@ export default [ name: 'publicActivitiesEmbed', path: '/embed/public-activities/:groupId', component: PublicActivitiesEmbed, + meta: { + noRedirect: true, + }, }, ] diff --git a/src/base/services.js b/src/base/services.js index 08aa6011fb..767f402f58 100644 --- a/src/base/services.js +++ b/src/base/services.js @@ -68,6 +68,11 @@ export const useRoutingLogic = defineService(() => { router.beforeEach(async (to, from, nextFn) => { let next + if (to.meta.noRedirect) { + nextFn() + return + } + await waitForUserToLoad() const requiredGroupFeatures = to.matched.map(m => m.meta.requireFeature).filter(Boolean) diff --git a/src/group/services.js b/src/group/services.js index 4a95caebd6..d6bc5b818d 100644 --- a/src/group/services.js +++ b/src/group/services.js @@ -1,6 +1,6 @@ import { extend } from 'quasar' import { computed, watch, ref, readonly, watchEffect } from 'vue' -import { useRouter } from 'vue-router' +import { useRoute, useRouter } from 'vue-router' import { useSaveUserMutation } from '@/authuser/mutations' import { useAuthService } from '@/authuser/services' @@ -37,6 +37,8 @@ export const useCurrentGroupService = defineService(() => { clearGroup, } = useCurrentGroupId() + const route = useRoute() + const { groups } = useGroupInfoService() const { @@ -46,6 +48,8 @@ export const useCurrentGroupService = defineService(() => { } = useGroupDetailQuery({ groupId }, { onError (error) { if (error?.response?.status === 404) { // TODO: could do for other errors too? + if (route.meta.noRedirect) return + // Not found! (only groups we are members of can be found) .. but it might exist for preview const groupPreview = groups.value.find(group => group.id === groupId.value) if (groupPreview) { diff --git a/src/groupInfo/pages/PublicActivitiesEmbed.vue b/src/groupInfo/pages/PublicActivitiesEmbed.vue index 3a08693a15..000cbeeac7 100644 --- a/src/groupInfo/pages/PublicActivitiesEmbed.vue +++ b/src/groupInfo/pages/PublicActivitiesEmbed.vue @@ -71,6 +71,8 @@ import { QItemSection, QItemLabel, } from 'quasar' +import { computed } from 'vue' +import { useRoute } from 'vue-router' import { useActivityTypeHelpers } from '@/activities/helpers' import { usePublicActivityListQuery } from '@/activities/queries' @@ -83,12 +85,19 @@ const { getIconProps, getTranslatedName } = useActivityTypeHelpers() const groupId = useIntegerRouteParam('groupId') +const route = useRoute() + +const placeId = computed(() => route.query.place) +const activityTypeId = computed(() => route.query.type) + const { publicActivities, infiniteScroll, } = usePublicActivityListQuery({ groupId, dateMin: newDateRoundedTo5Minutes(), + placeId, + activityTypeId, }) function getBannerImageUrl (publicActivity) {