Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/api/Ticker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface TickerFormData {
telegram: TickerTelegram
bluesky: TickerBluesky
signalGroup: TickerSignalGroup
matrix: TickerMatrix
location: TickerLocation
}

Expand All @@ -39,6 +40,7 @@ export interface Ticker {
telegram: TickerTelegram
bluesky: TickerBluesky
signalGroup: TickerSignalGroup
matrix: TickerMatrix
location: TickerLocation
}

Expand Down Expand Up @@ -118,6 +120,17 @@ export interface TickerSignalGroupAdminFormData {
number: string
}

export interface TickerMatrix {
active: boolean
connected: boolean
roomID: string
roomName: string
}

export interface TickerMatrixFormData {
active: boolean
}

export interface TickerLocation {
lat: number
lon: number
Expand Down Expand Up @@ -249,3 +262,15 @@ export async function putTickerSignalGroupAdminApi(token: string, data: TickerSi
body: JSON.stringify(data),
})
}

export async function putTickerMatrixApi(token: string, data: TickerMatrixFormData, ticker: Ticker): Promise<ApiResponse<TickerResponseData>> {
return apiClient<TickerResponseData>(`${ApiUrl}/admin/tickers/${ticker.id}/matrix`, {
headers: apiHeaders(token),
method: 'put',
body: JSON.stringify(data),
})
}

export async function deleteTickerMatrixApi(token: string, ticker: Ticker): Promise<ApiResponse<TickerResponseData>> {
return apiClient<TickerResponseData>(`${ApiUrl}/admin/tickers/${ticker.id}/matrix`, { headers: apiHeaders(token), method: 'delete' })
}
144 changes: 144 additions & 0 deletions src/components/ticker/MatrixCard.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Ticker } from '../../api/Ticker'
import { renderWithProviders, setMockToken, userToken } from '../../tests/utils'
import MatrixCard from './MatrixCard'

describe('MatrixCard', () => {
beforeEach(() => {
setMockToken(userToken)
fetchMock.resetMocks()
})

const ticker = ({ active, connected, roomName = '' }: { active: boolean; connected: boolean; roomName?: string }) => {
return {
id: 1,
matrix: {
active: active,
connected: connected,
roomName: roomName,
},
} as Ticker
}

const component = ({ ticker }: { ticker: Ticker }) => {
return <MatrixCard ticker={ticker} />
}

it('should render the component', () => {
renderWithProviders(component({ ticker: ticker({ active: false, connected: false }) }))

expect(screen.getByText('Matrix')).toBeInTheDocument()
expect(screen.getByText('You are not connected with Matrix.')).toBeInTheDocument()
expect(screen.getByRole('button', { name: 'Add' })).toBeInTheDocument()
})

it('should render the component when connected and active', async () => {
renderWithProviders(component({ ticker: ticker({ active: true, connected: true, roomName: '#room:matrix.org' }) }))

expect(screen.getByText('Matrix')).toBeInTheDocument()
expect(screen.getByText('You are connected with Matrix.')).toBeInTheDocument()
expect(screen.getByText('Your Room:')).toBeInTheDocument()
expect(screen.getByRole('link', { name: '#room:matrix.org' })).toBeInTheDocument()
expect(screen.getByRole('button', { name: 'Delete' })).toBeInTheDocument()
expect(screen.getByRole('button', { name: 'Disable' })).toBeInTheDocument()

fetchMock.mockResponseOnce(JSON.stringify({ status: 'success' }))

await userEvent.click(screen.getByRole('button', { name: 'Disable' }))

expect(fetchMock).toHaveBeenCalledTimes(1)
expect(fetchMock).toHaveBeenCalledWith('http://localhost:8080/v1/admin/tickers/1/matrix', {
body: JSON.stringify({ active: false }),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + userToken,
},
method: 'put',
})
})

it('should handle add button click', async () => {
renderWithProviders(component({ ticker: ticker({ active: false, connected: false }) }))

fetchMock.mockResponseOnce(JSON.stringify({ status: 'success' }))

await userEvent.click(screen.getByRole('button', { name: 'Add' }))

expect(fetchMock).toHaveBeenCalledTimes(1)
expect(fetchMock).toHaveBeenCalledWith('http://localhost:8080/v1/admin/tickers/1/matrix', {
body: JSON.stringify({ active: true }),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + userToken,
},
method: 'put',
})
})

it('should handle delete with dialog', async () => {
renderWithProviders(component({ ticker: ticker({ active: true, connected: true, roomName: '#room:matrix.org' }) }))

await userEvent.click(screen.getByRole('button', { name: 'Delete' }))

expect(screen.getByRole('dialog')).toBeInTheDocument()
expect(screen.getByText('Delete Matrix integration')).toBeInTheDocument()

fetchMock.mockResponseOnce(JSON.stringify({ status: 'success' }))

await userEvent.click(screen.getByTestId('dialog-delete'))

expect(fetchMock).toHaveBeenCalledTimes(1)
expect(fetchMock).toHaveBeenCalledWith('http://localhost:8080/v1/admin/tickers/1/matrix', {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + userToken,
},
method: 'delete',
})
})

it('should handle enable when inactive', async () => {
renderWithProviders(component({ ticker: ticker({ active: false, connected: true, roomName: '#room:matrix.org' }) }))

expect(screen.getByRole('button', { name: 'Enable' })).toBeInTheDocument()

fetchMock.mockResponseOnce(JSON.stringify({ status: 'success' }))

await userEvent.click(screen.getByRole('button', { name: 'Enable' }))

expect(fetchMock).toHaveBeenCalledTimes(1)
expect(fetchMock).toHaveBeenCalledWith('http://localhost:8080/v1/admin/tickers/1/matrix', {
body: JSON.stringify({ active: true }),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + userToken,
},
method: 'put',
})
})

it('should fail when response fails', async () => {
renderWithProviders(component({ ticker: ticker({ active: true, connected: true, roomName: '#room:matrix.org' }) }))

fetchMock.mockResponseOnce(JSON.stringify({ status: 'error' }))

await userEvent.click(screen.getByRole('button', { name: 'Disable' }))

expect(fetchMock).toHaveBeenCalledTimes(1)
})

it('should fail when request fails', async () => {
renderWithProviders(component({ ticker: ticker({ active: true, connected: true, roomName: '#room:matrix.org' }) }))

fetchMock.mockReject()

await userEvent.click(screen.getByRole('button', { name: 'Disable' }))

expect(fetchMock).toHaveBeenCalledTimes(1)
})
})
Loading
Loading