From 1ce66d01b7165d6d7c030242250fdcc7f8b55d9e Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 25 Jun 2024 00:43:27 +0200 Subject: [PATCH 01/19] join my room creates Meeting in DB when not present, creates BBB meeting, stores response in DB and return join link to meeting --- backend/src/api/BBB.ts | 8 +- backend/src/graphql/resolvers/RoomResolver.ts | 80 ++++++++++++++++--- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/backend/src/api/BBB.ts b/backend/src/api/BBB.ts index 34cea1c296..0a6a77a83e 100644 --- a/backend/src/api/BBB.ts +++ b/backend/src/api/BBB.ts @@ -170,10 +170,10 @@ export const createMeeting = async ( interface JoinMeetinLinkOptions { fullName: string meetingID: string - // role: 'MODERATOR' | 'VIEWER' - password: string - // createTime: string - // userID: string + role?: 'MODERATOR' | 'VIEWER' + password?: string + createTime?: string + userID?: string } export const joinMeetingLink = (options: JoinMeetinLinkOptions): string => { diff --git a/backend/src/graphql/resolvers/RoomResolver.ts b/backend/src/graphql/resolvers/RoomResolver.ts index 4c7e9676a9..73856c06ed 100644 --- a/backend/src/graphql/resolvers/RoomResolver.ts +++ b/backend/src/graphql/resolvers/RoomResolver.ts @@ -1,9 +1,11 @@ +import { Meeting } from '@prisma/client' import { Resolver, Mutation, Query, Authorized, Ctx, Arg, Int } from 'type-graphql' // eslint-disable-next-line import/named import { v4 as uuidv4 } from 'uuid' import { createMeeting, joinMeetingLink, getMeetings, MeetingInfo } from '#api/BBB' import { Room, OpenRoom } from '#models/RoomModel' +import logger from '#src/logger' import { prisma } from '#src/prisma' import { Context } from '#src/server/context' @@ -50,22 +52,80 @@ export class RoomResolver { } @Authorized() - @Query(() => String, { nullable: true }) - async joinMyRoom(@Ctx() context: Context): Promise { + @Query(() => String) + async joinMyRoom(@Ctx() context: Context): Promise { const { user } = context - if (!user) return null + if (!user) throw new Error('User not found!') + + let dbMeeting: Meeting | null = null + + try { + if (user.meetingId) { + dbMeeting = await prisma.meeting.findUnique({ + where: { + id: user.meetingId, + }, + }) + if (!dbMeeting) throw new Error('Meeting not found!') + } else { + let meetingID: string = uuidv4() + while ( + await prisma.meeting.count({ + where: { + meetingID, + }, + }) + ) { + meetingID = uuidv4() + } + + dbMeeting = await prisma.meeting.create({ + data: { + name: user.username, + meetingID, + }, + }) + await prisma.user.update({ + where: { id: user.id }, + data: { meetingId: dbMeeting.id }, + }) + } + } catch (err) { + logger.error('Could not create Meeting in DB!', err) + throw new Error('Could not create Meeting in DB!') + } + const meeting = await createMeeting({ - name: 'Dreammall Entwicklung', - meetingID: 'Dreammall-Entwicklung', + name: dbMeeting.name, + meetingID: dbMeeting.meetingID, }) - if (!meeting) return null + + if (!meeting) throw new Error('Could not create meeting!') + + try { + await prisma.meeting.update({ + where: { id: dbMeeting.id }, + data: { + attendeePW: meeting.attendeePW, + moderatorPW: meeting.moderatorPW, + voiceBridge: meeting.voiceBridge, + dialNumber: meeting.dialNumber, + createTime: meeting.createTime, + createDate: meeting.createDate, + }, + }) + } catch (err) { + logger.error('Could not update Meeting in DB!', err) + throw new Error('Could not update Meeting in DB!') + } + return joinMeetingLink({ fullName: user.name, - meetingID: 'Dreammall-Entwicklung', + meetingID: meeting.meetingID, password: meeting.moderatorPW, - // role: 'MODERATOR', - // createTime: meeting.createTime.toString(), - // userID: user.id.toString(), + role: 'MODERATOR', + createTime: meeting.createTime.toString(), + userID: user.id.toString(), }) } From 663fe09fb6fd1e1368e8b7cfff725a31a9bf1427 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 25 Jun 2024 01:16:02 +0200 Subject: [PATCH 02/19] int to bigint for meeting.createTime --- .../migration.sql | 2 ++ backend/prisma/schema.prisma | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 backend/prisma/migrations/20240624231416_int_to_bigint_meeting_create_time/migration.sql diff --git a/backend/prisma/migrations/20240624231416_int_to_bigint_meeting_create_time/migration.sql b/backend/prisma/migrations/20240624231416_int_to_bigint_meeting_create_time/migration.sql new file mode 100644 index 0000000000..8b72a9bcfc --- /dev/null +++ b/backend/prisma/migrations/20240624231416_int_to_bigint_meeting_create_time/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE `Meeting` MODIFY `createTime` BIGINT NULL; diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 3c32494187..4280892567 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -66,7 +66,7 @@ model Meeting { createdAt DateTime @default(now()) voiceBridge Int? dialNumber String? @db.VarChar(64) - createTime Int? + createTime BigInt? createDate DateTime? user User? } From db8b2c1bb80170809d5468a0ad30fca9d8e503d6 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 25 Jun 2024 01:35:59 +0200 Subject: [PATCH 03/19] test join my room --- .../graphql/resolvers/RoomResolver.spec.ts | 173 +++++++++++++++--- backend/src/graphql/resolvers/RoomResolver.ts | 2 +- 2 files changed, 145 insertions(+), 30 deletions(-) diff --git a/backend/src/graphql/resolvers/RoomResolver.spec.ts b/backend/src/graphql/resolvers/RoomResolver.spec.ts index fd0ceb482c..dad52cac58 100644 --- a/backend/src/graphql/resolvers/RoomResolver.spec.ts +++ b/backend/src/graphql/resolvers/RoomResolver.spec.ts @@ -48,13 +48,13 @@ describe('RoomResolver', () => { it('throws access denied', async () => { await expect( testServer.executeOperation({ - query: 'query { joinMyRoom }', + query: 'mutation { joinMyRoom }', }), ).resolves.toMatchObject({ body: { kind: 'single', singleResult: { - data: { joinMyRoom: null }, + data: null, // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment errors: expect.arrayContaining([ expect.objectContaining({ @@ -288,17 +288,43 @@ describe('RoomResolver', () => { }) describe('joinMyRoom', () => { - describe('createMeeting returns undefined', () => { - it('returns null', async () => { - createMeetingMock.mockResolvedValue(null) + beforeAll(async () => { + await prisma.meeting.deleteMany() + await prisma.user.deleteMany() + }) + + let meetingId: string | undefined + + describe('meeting does not exist', () => { + joinMeetingLinkMock.mockReturnValue('https://my-link') + createMeetingMock.mockResolvedValue({ + returncode: 'SUCCESS', + meetingID: 'xxx', + internalMeetingID: 'b60d121b438a380c343d5ec3c2037564b82ffef3-1715231322715', + parentMeetingID: 'bbb-none', + attendeePW: 'w3VUvMcp', + moderatorPW: 'MyPp9Zfq', + createTime: 1718189921310, + voiceBridge: 255, + dialNumber: '613-555-1234', + createDate: new Date(), + hasUserJoined: false, + duration: 0, + hasBeenForciblyEnded: false, + messageKey: '', + message: '', + }) + + it('returns link to room', async () => { await expect( testServer.executeOperation( { - query: 'query { joinMyRoom }', + query: 'mutation { joinMyRoom }', }, { contextValue: { token: 'token', + user: undefined, }, }, ), @@ -306,43 +332,75 @@ describe('RoomResolver', () => { body: { kind: 'single', singleResult: { - data: { joinMyRoom: null }, + data: { + joinMyRoom: 'https://my-link', + }, errors: undefined, }, }, }) }) - }) - describe('createMeeting returns meeting', () => { - it('returns link to the meeting', async () => { - joinMeetingLinkMock.mockReturnValue('https://my-link') - createMeetingMock.mockResolvedValue({ - returncode: 'SUCCESS', - meetingID: 'xxx', - internalMeetingID: 'b60d121b438a380c343d5ec3c2037564b82ffef3-1715231322715', - parentMeetingID: 'bbb-none', - attendeePW: 'w3VUvMcp', - moderatorPW: 'MyPp9Zfq', - createTime: 1715231322715, - voiceBridge: 255, - dialNumber: '613-555-1234', - createDate: new Date(), - hasUserJoined: false, - duration: 0, - hasBeenForciblyEnded: false, - messageKey: '', - message: '', + it('creates meeting in database', async () => { + const result = await prisma.user.findFirst({ + include: { + meeting: true, + }, }) + meetingId = result?.meeting?.meetingID + expect(result).toMatchObject({ + meeting: { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + id: expect.any(Number), + name: 'mockedUser', + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + meetingID: expect.any(String), + attendeePW: 'w3VUvMcp', + moderatorPW: 'MyPp9Zfq', + voiceBridge: 255, + dialNumber: '613-555-1234', + createTime: 1718189921310n, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + createDate: expect.any(Date), + }, + }) + }) + }) + describe('meeting exists in DB', () => { + beforeAll(() => { + jest.clearAllMocks() + }) + + joinMeetingLinkMock.mockReturnValue('https://my-link') + createMeetingMock.mockResolvedValue({ + returncode: 'SUCCESS', + meetingID: 'xxx', + internalMeetingID: 'b60d121b438a380c343d5ec3c2037564b82ffef3-1715231322715', + parentMeetingID: 'bbb-none', + attendeePW: 'w3VUvMcp', + moderatorPW: 'MyPp9Zfq', + createTime: 1718189921310, + voiceBridge: 255, + dialNumber: '613-555-1234', + createDate: new Date(), + hasUserJoined: false, + duration: 0, + hasBeenForciblyEnded: false, + messageKey: '', + message: '', + }) + + it('returns link to room', async () => { await expect( testServer.executeOperation( { - query: 'query { joinMyRoom }', + query: 'mutation { joinMyRoom }', }, { contextValue: { token: 'token', + user: undefined, }, }, ), @@ -350,12 +408,69 @@ describe('RoomResolver', () => { body: { kind: 'single', singleResult: { - data: { joinMyRoom: 'https://my-link' }, + data: { + joinMyRoom: 'https://my-link', + }, errors: undefined, }, }, }) }) + + it('updates meeting in database', async () => { + await expect( + prisma.user.findFirst({ + include: { + meeting: true, + }, + }), + ).resolves.toMatchObject({ + meeting: { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + id: expect.any(Number), + name: 'mockedUser', + meetingID: meetingId, + attendeePW: 'w3VUvMcp', + moderatorPW: 'MyPp9Zfq', + voiceBridge: 255, + dialNumber: '613-555-1234', + createTime: 1718189921310n, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + createDate: expect.any(Date), + }, + }) + }) + }) + + describe('createMeeting returns undefined', () => { + it('throws meeting error', async () => { + createMeetingMock.mockResolvedValue(null) + await expect( + testServer.executeOperation( + { + query: 'mutation { joinMyRoom }', + }, + { + contextValue: { + token: 'token', + }, + }, + ), + ).resolves.toMatchObject({ + body: { + kind: 'single', + singleResult: { + data: null, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + errors: expect.arrayContaining([ + expect.objectContaining({ + message: 'Could not create meeting!', + }), + ]), + }, + }, + }) + }) }) }) diff --git a/backend/src/graphql/resolvers/RoomResolver.ts b/backend/src/graphql/resolvers/RoomResolver.ts index 73856c06ed..84a58c18a0 100644 --- a/backend/src/graphql/resolvers/RoomResolver.ts +++ b/backend/src/graphql/resolvers/RoomResolver.ts @@ -52,7 +52,7 @@ export class RoomResolver { } @Authorized() - @Query(() => String) + @Mutation(() => String) async joinMyRoom(@Ctx() context: Context): Promise { const { user } = context if (!user) throw new Error('User not found!') From 74acd382e3a0551edac5918321c1c8b8e8420af0 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 25 Jun 2024 01:48:33 +0200 Subject: [PATCH 04/19] fix authchecker tests due to changes on join my room, change coverage --- backend/jest.config.json | 6 +++--- backend/src/auth/authChecker.spec.ts | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/backend/jest.config.json b/backend/jest.config.json index 3f2fd5d188..82d8a74ad8 100644 --- a/backend/jest.config.json +++ b/backend/jest.config.json @@ -13,10 +13,10 @@ ], "coverageThreshold": { "global": { - "statements": 96, - "branches": 87, + "statements": 95, + "branches": 88, "functions": 94, - "lines": 97 + "lines": 96 } }, "modulePathIgnorePatterns": ["/build/"], diff --git a/backend/src/auth/authChecker.spec.ts b/backend/src/auth/authChecker.spec.ts index 5649c466ef..53a76f2a42 100644 --- a/backend/src/auth/authChecker.spec.ts +++ b/backend/src/auth/authChecker.spec.ts @@ -37,15 +37,13 @@ describe('authChecker', () => { it('returns access denied error', async () => { await expect( testServer.executeOperation({ - query: 'query { joinMyRoom }', + query: 'mutation { joinMyRoom }', }), ).resolves.toMatchObject({ body: { kind: 'single', singleResult: { - data: { - joinMyRoom: null, - }, + data: null, // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment errors: expect.arrayContaining([ expect.objectContaining({ @@ -69,7 +67,7 @@ describe('authChecker', () => { it('creates user in database', async () => { await testServer.executeOperation( { - query: 'query { joinMyRoom }', + query: 'mutation { joinMyRoom }', }, { contextValue: { @@ -88,7 +86,8 @@ describe('authChecker', () => { createdAt: expect.any(Date), name: 'User', username: 'mockedUser', - meetingId: null, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + meetingId: expect.any(Number), }, ]) }) @@ -117,7 +116,7 @@ describe('authChecker', () => { it('has the same user in database', async () => { await testServer.executeOperation( { - query: 'query { joinMyRoom }', + query: 'mutation { joinMyRoom }', }, { contextValue: { From 6d1cd86cfa847c6cce50fc90062fea961993ccad Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 25 Jun 2024 02:56:19 +0200 Subject: [PATCH 05/19] feat(backend): handle open rooms --- backend/src/api/BBB.ts | 25 +++++++++++++++++++++++-- backend/src/index.ts | 4 ++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/backend/src/api/BBB.ts b/backend/src/api/BBB.ts index 0a6a77a83e..fc4b4fa474 100644 --- a/backend/src/api/BBB.ts +++ b/backend/src/api/BBB.ts @@ -7,6 +7,8 @@ import { XMLParser } from 'fast-xml-parser' import { CONFIG } from '#config/config' import logger from '#src/logger' +import { prisma } from '#src/prisma' + const parser = new XMLParser() export const axiosInstance = axios.create({ @@ -186,9 +188,28 @@ export const joinMeetingLink = (options: JoinMeetinLinkOptions): string => { } const handleOpenRomms = async (): Promise => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars const rooms = await getMeetings() - // console.log(rooms.map((m) => m.attendees?.attendee)) + console.log(rooms) + if (rooms.length) { + await prisma.meeting.updateMany({ + where: { + createTime: { not: null }, + meetingID: { + not: { + in: rooms.map((m: MeetingInfo) => m.meetingID) + }, + }, + }, + data: { + attendeePW: null, + moderatorPW: null, + voiceBridge: null, + dialNumber: null, + createTime: null, + createDate: null, + }, + }) + } } export const checkForOpenRooms = (): void => { diff --git a/backend/src/index.ts b/backend/src/index.ts index 14101b73f2..5bc02cd85f 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,6 +1,6 @@ // eslint-disable-next-line import/no-unassigned-import import 'reflect-metadata' -// import { checkForOpenRooms } from '#api/BBB' +import { checkForOpenRooms } from '#api/BBB' import logger from './logger' import { prisma } from './prisma' @@ -9,7 +9,7 @@ import { listen } from './server/server' export const main = async (): Promise => { const url = await listen(4000) logger.info(`🚀 Server is ready at ${url}`) - // checkForOpenRooms() + checkForOpenRooms() } void main() From dccb5ebd99d7549f2f848974838320f7909a58bf Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 25 Jun 2024 03:37:12 +0200 Subject: [PATCH 06/19] use join my room mutation --- frontend/package.json | 1 + .../embedded-room/useMyRoom.spec.ts | 12 ++++---- .../src/components/embedded-room/useMyRoom.ts | 29 +++++++++---------- .../graphql/mutations/joinMyRoomMutation.ts | 11 +++++++ .../src/graphql/queries/joinMyRoomQuery.ts | 11 ------- frontend/src/pages/room/Page.test.ts | 12 ++++---- frontend/tsconfig.json | 1 + frontend/vite.config.ts | 1 + 8 files changed, 40 insertions(+), 38 deletions(-) create mode 100644 frontend/src/graphql/mutations/joinMyRoomMutation.ts delete mode 100644 frontend/src/graphql/queries/joinMyRoomQuery.ts diff --git a/frontend/package.json b/frontend/package.json index cb3ac25f22..c576c6ac48 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -162,6 +162,7 @@ "#assets/*": "./src/assets/*", "#layouts/*": "./src/layouts/*", "#queries/*": "./src/graphql/queries/*", + "#mutations/*": "./src/graphql/mutations/*", "#stores/*": "./src/stores/*", "#src/*": "./src/*", "#plugins/*": "./renderer/plugins/*", diff --git a/frontend/src/components/embedded-room/useMyRoom.spec.ts b/frontend/src/components/embedded-room/useMyRoom.spec.ts index b0ed5e144d..c298a6411a 100644 --- a/frontend/src/components/embedded-room/useMyRoom.spec.ts +++ b/frontend/src/components/embedded-room/useMyRoom.spec.ts @@ -2,17 +2,17 @@ import { flushPromises, mount } from '@vue/test-utils' import { describe, it, expect, vi, beforeEach } from 'vitest' import { defineComponent } from 'vue' -import { joinMyRoomQuery } from '#queries/joinMyRoomQuery' +import { joinMyRoomMutation } from '#mutations/joinMyRoomMutation' import { mockClient } from '#tests/mock.apolloClient' import { errorHandlerSpy } from '#tests/plugin.globalErrorHandler' import useMyRoom from './useMyRoom' -const joinMyRoomQueryMock = vi.fn() +const joinMyRoomMutationMock = vi.fn() const testUrl = 'http://some.url' -mockClient.setRequestHandler(joinMyRoomQuery, joinMyRoomQueryMock) +mockClient.setRequestHandler(joinMyRoomMutation, joinMyRoomMutationMock) describe('useMyRoom', () => { const TestComponent = defineComponent({ @@ -30,12 +30,12 @@ describe('useMyRoom', () => { describe('without apollo error', () => { beforeEach(() => { - joinMyRoomQueryMock.mockResolvedValue({ data: { joinMyRoom: testUrl } }) + joinMyRoomMutationMock.mockResolvedValue({ data: { joinMyRoom: testUrl } }) wrapper = Wrapper() }) it('calls the API', () => { - expect(joinMyRoomQueryMock).toBeCalled() + expect(joinMyRoomMutationMock).toBeCalled() }) it('returns correct url', async () => { @@ -48,7 +48,7 @@ describe('useMyRoom', () => { beforeEach(() => { wrapper.unmount() vi.clearAllMocks() - joinMyRoomQueryMock.mockRejectedValue({ message: 'Aua!', data: undefined }) + joinMyRoomMutationMock.mockRejectedValue({ message: 'Aua!', data: undefined }) wrapper = Wrapper() }) diff --git a/frontend/src/components/embedded-room/useMyRoom.ts b/frontend/src/components/embedded-room/useMyRoom.ts index 211562530f..3df40236e5 100644 --- a/frontend/src/components/embedded-room/useMyRoom.ts +++ b/frontend/src/components/embedded-room/useMyRoom.ts @@ -1,27 +1,26 @@ -import { useQuery } from '@vue/apollo-composable' +import { useMutation } from '@vue/apollo-composable' import { watch, ref } from 'vue' import GlobalErrorHandler from '#plugins/globalErrorHandler' -import { JoinMyRoomQueryResult, joinMyRoomQuery } from '#queries/joinMyRoomQuery' +import { JoinMyRoomMutationResult, joinMyRoomMutation } from '#mutations/joinMyRoomMutation' -export default function useMyRoom() { - const { result: joinMyRoomQueryResult, error: joinMyRoomQueryError } = - useQuery(joinMyRoomQuery, null, { - prefetch: false, +export default async function useMyRoom() { + const { mutate: joinMyRoomMutationResult, error: joinMyRoomMutationError } = + useMutation(joinMyRoomMutation, { fetchPolicy: 'no-cache', }) - + const roomUrl = ref(null) - watch(joinMyRoomQueryResult, () => { - if (joinMyRoomQueryResult.value) { - roomUrl.value = joinMyRoomQueryResult.value.joinMyRoom - } - }) + const result = await joinMyRoomMutationResult() + + if (result?.data) { + roomUrl.value = result.data.joinMyRoom + } - watch(joinMyRoomQueryError, () => { - if (joinMyRoomQueryError.value) { - GlobalErrorHandler.error(joinMyRoomQueryError.value.message) + watch(joinMyRoomMutationError, () => { + if (joinMyRoomMutationError.value) { + GlobalErrorHandler.error(joinMyRoomMutationError.value.message) } }) diff --git a/frontend/src/graphql/mutations/joinMyRoomMutation.ts b/frontend/src/graphql/mutations/joinMyRoomMutation.ts new file mode 100644 index 0000000000..9449ab2767 --- /dev/null +++ b/frontend/src/graphql/mutations/joinMyRoomMutation.ts @@ -0,0 +1,11 @@ +import { gql } from 'graphql-tag' + +export const joinMyRoomMutation = gql` + mutation { + joinMyRoom + } +` + +export type JoinMyRoomMutationResult = { + joinMyRoom: string +} diff --git a/frontend/src/graphql/queries/joinMyRoomQuery.ts b/frontend/src/graphql/queries/joinMyRoomQuery.ts deleted file mode 100644 index f662e7fc51..0000000000 --- a/frontend/src/graphql/queries/joinMyRoomQuery.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { gql } from 'graphql-tag' - -export const joinMyRoomQuery = gql` - query { - joinMyRoom - } -` - -export type JoinMyRoomQueryResult = { - joinMyRoom: string -} diff --git a/frontend/src/pages/room/Page.test.ts b/frontend/src/pages/room/Page.test.ts index fe4f82cc63..560663f5b4 100644 --- a/frontend/src/pages/room/Page.test.ts +++ b/frontend/src/pages/room/Page.test.ts @@ -3,18 +3,18 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' import { Component, h } from 'vue' import { VApp } from 'vuetify/components' -import { joinMyRoomQuery } from '#queries/joinMyRoomQuery' +import { joinMyRoomMutation } from '#mutations/joinMyRoomMutation' import { mockClient } from '#tests/mock.apolloClient' import { errorHandlerSpy } from '#tests/plugin.globalErrorHandler' import RoomPage from './+Page.vue' import { title } from './+title' -const joinMyRoomQueryMock = vi.fn() +const joinMyRoomMutationMock = vi.fn() const testUrl = 'http://some.url' -mockClient.setRequestHandler(joinMyRoomQuery, joinMyRoomQueryMock) +mockClient.setRequestHandler(joinMyRoomMutation, joinMyRoomMutationMock) describe('Room Page', () => { const Wrapper = () => { @@ -29,7 +29,7 @@ describe('Room Page', () => { describe('without apollo error', () => { beforeEach(() => { - joinMyRoomQueryMock.mockResolvedValue({ data: { joinMyRoom: testUrl } }) + joinMyRoomMutationMock.mockResolvedValue({ data: { joinMyRoom: testUrl } }) wrapper = Wrapper() }) @@ -42,7 +42,7 @@ describe('Room Page', () => { }) it('calls the API', () => { - expect(joinMyRoomQueryMock).toBeCalled() + expect(joinMyRoomMutationMock).toBeCalled() }) it('shows iframe with correct url', async () => { @@ -55,7 +55,7 @@ describe('Room Page', () => { describe('with apollo error', () => { beforeEach(() => { vi.clearAllMocks() - joinMyRoomQueryMock.mockRejectedValue({ message: 'Aua!', data: undefined }) + joinMyRoomMutationMock.mockRejectedValue({ message: 'Aua!', data: undefined }) wrapper = Wrapper() }) diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 15e78cfd0a..1a03078e05 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -16,6 +16,7 @@ "#assets/*": ["./src/assets/*"], "#layouts/*": ["./src/layouts/*"], "#queries/*": ["./src/graphql/queries/*"], + "#mutations/*": ["./src/graphql/mutations/*"], "#stores/*": ["./src/stores/*"], "#src/*": ["./src/*"], "#plugins/*": ["./renderer/plugins/*"], diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 9549185ff0..f30eaff62d 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -43,6 +43,7 @@ const config: UserConfig = { '#assets': path.join(__dirname, '/src/assets'), '#layouts': path.join(__dirname, '/src/layouts'), '#queries': path.join(__dirname, '/src/graphql/queries'), + '#mutations': path.join(__dirname, '/src/graphql/mutations'), '#stores': path.join(__dirname, '/src/stores'), '#src': path.join(__dirname, '/src'), '#plugins': path.join(__dirname, '/renderer/plugins'), From e2d871f6bf975b4275d9e0433f6dac4e80438401 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 25 Jun 2024 04:11:46 +0200 Subject: [PATCH 07/19] close to get the mutaion working --- .../src/components/embedded-room/useMyRoom.ts | 22 +++++++++---------- frontend/src/pages/room/+Page.vue | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/frontend/src/components/embedded-room/useMyRoom.ts b/frontend/src/components/embedded-room/useMyRoom.ts index 3df40236e5..867431cd21 100644 --- a/frontend/src/components/embedded-room/useMyRoom.ts +++ b/frontend/src/components/embedded-room/useMyRoom.ts @@ -5,24 +5,22 @@ import GlobalErrorHandler from '#plugins/globalErrorHandler' import { JoinMyRoomMutationResult, joinMyRoomMutation } from '#mutations/joinMyRoomMutation' export default async function useMyRoom() { - const { mutate: joinMyRoomMutationResult, error: joinMyRoomMutationError } = + const { mutate: joinMyRoomMutationResult } = useMutation(joinMyRoomMutation, { fetchPolicy: 'no-cache', }) const roomUrl = ref(null) - const result = await joinMyRoomMutationResult() - - if (result?.data) { - roomUrl.value = result.data.joinMyRoom - } - - watch(joinMyRoomMutationError, () => { - if (joinMyRoomMutationError.value) { - GlobalErrorHandler.error(joinMyRoomMutationError.value.message) + try { + console.log('Trying') + const result = await joinMyRoomMutationResult() + if (result?.data) { + roomUrl.value = result.data.joinMyRoom } - }) - + } catch (err) { + GlobalErrorHandler.error('Error on joining my room', err) + } + return { roomUrl } } diff --git a/frontend/src/pages/room/+Page.vue b/frontend/src/pages/room/+Page.vue index 454680a10f..eaa0fa3bd0 100644 --- a/frontend/src/pages/room/+Page.vue +++ b/frontend/src/pages/room/+Page.vue @@ -11,7 +11,7 @@ import EmbeddedRoom from '#components/embedded-room/EmbeddedRoom.vue' import useMyRoom from '#components/embedded-room/useMyRoom' import DefaultLayout from '#layouts/DefaultLayout.vue' -const { roomUrl } = useMyRoom() +const { roomUrl } = await useMyRoom()