+
setFocusedLog(null)} log={focusedLog} />
)}
diff --git a/studio/pages/project/[ref]/settings/logs/[type].tsx b/studio/pages/project/[ref]/settings/logs/[type].tsx
index 7ad605a0ca2..b94e3be193f 100644
--- a/studio/pages/project/[ref]/settings/logs/[type].tsx
+++ b/studio/pages/project/[ref]/settings/logs/[type].tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'
-import { SettingsLayout } from 'components/layouts'
+import { SettingsLayout } from 'components/layouts/'
import { useRouter } from 'next/router'
import LogPanel from 'components/ui/Logs/LogPanel'
import { LOG_TYPE_LABEL_MAPPING } from 'lib/constants'
@@ -14,7 +14,7 @@ import { Typography, Input } from '@supabase/ui'
/**
* Acts as a container component for the entire log display
*/
-const LogPage = () => {
+export const LogPage = () => {
const router = useRouter()
const { ref, type } = router.query
const title = LOG_TYPE_LABEL_MAPPING[type as string]
@@ -28,7 +28,6 @@ const LogPage = () => {
} = useSWR<{ data: LogData[], count: number, error: any }>(`${API_URL}/projects/${ref}/logs?type=${type}`, get, {
revalidateOnFocus: false,
})
- console.log(data)
const { data: logData, error } = data || {}
const filteredData = logData && searchQuery ? logData.filter(d => {
diff --git a/studio/tests/pages/projects/LogTable.test.js b/studio/tests/pages/projects/LogTable.test.js
new file mode 100644
index 00000000000..b515acaf67b
--- /dev/null
+++ b/studio/tests/pages/projects/LogTable.test.js
@@ -0,0 +1,18 @@
+import LogTable from 'components/ui/Logs/LogTable'
+import { render, fireEvent, waitFor, screen } from '@testing-library/react'
+test('can display log data', async () => {
+ render(
)
+
+ await waitFor(() => screen.getByText(/happened/))
+ const row = screen.getByText(/happened/)
+ fireEvent.click(row)
+ await waitFor(() => screen.getByText(/my_key/))
+ await waitFor(() => screen.getByText(/something_value/))
+})
diff --git a/studio/tests/pages/projects/logs.test.js b/studio/tests/pages/projects/logs.test.js
new file mode 100644
index 00000000000..f6c9333f1f7
--- /dev/null
+++ b/studio/tests/pages/projects/logs.test.js
@@ -0,0 +1,74 @@
+// mock the fetch function
+jest.mock('lib/common/fetch')
+import { get } from 'lib/common/fetch'
+
+// mock the settings layout
+jest.mock('components/layouts', () => ({
+ SettingsLayout: jest.fn()
+ .mockImplementation(({ children }) =>
{children}
)
+}))
+
+// mock mobx
+jest.mock('mobx-react-lite')
+import { observer } from 'mobx-react-lite'
+observer.mockImplementation(v => v)
+
+// mock the router
+jest.mock('next/router')
+import { useRouter } from 'next/router'
+useRouter.mockReturnValue({ query: { ref: "123", type: "auth" } })
+
+import { LogPage } from 'pages/project/[ref]/settings/logs/[type]'
+import { render, fireEvent, waitFor, screen } from '@testing-library/react'
+import { SWRConfig } from 'swr'
+
+test('can display log data and metadata', async () => {
+ const data = [{
+ id: "seome-uuid",
+ timestamp: 1621323232312,
+ event_message: "some event happened",
+ metadata: {
+ my_key: "something_value"
+ }
+ }]
+ get.mockResolvedValue({ data })
+ render(
)
+
+ await waitFor(() => screen.getByText(/happened/))
+ const row = screen.getByText(/happened/)
+ fireEvent.click(row)
+ await waitFor(() => screen.getByText(/my_key/))
+ await waitFor(() => screen.getByText(/something_value/))
+})
+
+test('Refresh', async () => {
+ const data = [{
+ id: "some-uuid",
+ timestamp: 1621323232312,
+ event_message: "some event happened",
+ metadata: {
+ my_key: "something_value"
+ }
+ }]
+ get.mockResolvedValue({ data })
+ render(
+
+
+
+ )
+
+ const row = screen.getByText(/happened/)
+ fireEvent.click(row)
+ await waitFor(() => screen.getByText(/my_key/))
+ expect(get).toBeCalledTimes(1)
+ get.mockResolvedValue({ data: [] })
+
+ // simulate full refresh, loop because swr dedupe behaves weirdly
+ await waitFor(() => {
+ fireEvent.click(screen.getByText(/Refresh/))
+ expect(get).toBeCalledTimes(2)
+ })
+ // when log line unmounts and it was focused, should close focus panel
+ await waitFor(() => expect(() => screen.getByText(/my_key/)).toThrow())
+ await waitFor(() => expect(() => screen.getByText(/happened/)).toThrow())
+})