mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
fix: protect csv import (#47040)
## TL;DR fixes protected schema empty tables still exposing CSV import actions in table editor... ## ref: - closes https://github.com/supabase/supabase/issues/41358 - supersedes: https://github.com/supabase/supabase/pull/41362 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Updated the table empty state so CSV import actions are shown only when the table is allowed to accept imports, and are hidden for protected cases (including foreign-table scenarios). * **Tests** * Added an end-to-end test confirming that empty tables in protected schemas do not expose the “Import data from CSV” button or the drag-and-drop CSV hint. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
cedc4c8187
commit
84edf0dc94
2 files changed
+36
-5
No files matched your search
@@ -89,11 +89,12 @@ export const Grid = memo(
|
||||
const tableEntityType = snap.originalTable?.entity_type
|
||||
const isForeignTable = tableEntityType === ENTITY_TYPE.FOREIGN_TABLE
|
||||
const isTableEmpty = (rows ?? []).length === 0
|
||||
const canImportData = snap.editable && !isForeignTable
|
||||
|
||||
const track = useTrack()
|
||||
|
||||
const { isDraggedOver, onDragOver, onFileDrop } = useCsvFileDrop({
|
||||
enabled: isTableEmpty && !isForeignTable,
|
||||
enabled: isTableEmpty && canImportData,
|
||||
onFileDropped: (file) => tableEditorSnap.onImportData(valtioRef(file)),
|
||||
onTelemetryEvent: (eventName) => track(eventName),
|
||||
})
|
||||
@@ -322,7 +323,7 @@ export const Grid = memo(
|
||||
started.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
) : canImportData ? (
|
||||
<div className="flex flex-col items-center gap-4 mt-4">
|
||||
<Button
|
||||
variant="default"
|
||||
@@ -338,7 +339,7 @@ export const Grid = memo(
|
||||
or drag and drop a CSV file here
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
) : null}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { expect, Page } from '@playwright/test'
|
||||
|
||||
import { env } from '../env.config.js'
|
||||
import { expectClipboardValue } from '../utils/clipboard.js'
|
||||
import { dropTable, query } from '../utils/db/index.js'
|
||||
@@ -16,6 +14,7 @@ import {
|
||||
waitForGridDataToLoad,
|
||||
waitForTableToLoad,
|
||||
} from '../utils/wait-for-response.js'
|
||||
import { expect, Page } from '@playwright/test'
|
||||
|
||||
const deleteTable = async (page: Page, ref: string, tableName: string) => {
|
||||
const viewLocator = page.getByLabel(`View ${tableName}`)
|
||||
@@ -155,6 +154,37 @@ testRunner('table editor', () => {
|
||||
await expect(page.getByLabel(`View ${authTableMfa}`)).toBeVisible()
|
||||
})
|
||||
|
||||
test('protected schema empty tables do not expose CSV import actions', async ({ page, ref }) => {
|
||||
const emptyAuthTables = await query<{ relname: string }>(`
|
||||
select relname
|
||||
from pg_stat_user_tables
|
||||
where schemaname = 'auth'
|
||||
and n_live_tup = 0
|
||||
and relname <> 'schema_migrations'
|
||||
order by relname
|
||||
limit 1;
|
||||
`)
|
||||
test.skip(emptyAuthTables.length === 0, 'Requires an empty auth table in the test dataset')
|
||||
const [{ relname: tableName }] = emptyAuthTables
|
||||
|
||||
await page.goto(toUrl(`/project/${ref}/editor?schema=public`))
|
||||
|
||||
await page.getByTestId('schema-selector').click()
|
||||
await page.getByPlaceholder('Find schema...').fill('auth')
|
||||
|
||||
const tableLoadPromise = waitForTableToLoad(page, ref, 'auth')
|
||||
await page.getByRole('option', { name: 'auth' }).click()
|
||||
await tableLoadPromise
|
||||
|
||||
await expect(page.getByRole('button', { name: `View ${tableName}`, exact: true })).toBeVisible()
|
||||
await page.getByRole('button', { name: `View ${tableName}`, exact: true }).click()
|
||||
await page.waitForURL(/\/editor\/\d+\?schema=auth$/)
|
||||
|
||||
await expect(page.getByText('This table is empty')).toBeVisible()
|
||||
await expect(page.getByRole('button', { name: 'Import data from CSV' })).not.toBeVisible()
|
||||
await expect(page.getByText('or drag and drop a CSV file here')).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('should show rls accordingly', async ({ page, ref }) => {
|
||||
const tableNameRlsEnabled = 'pw_table_rls_enabled'
|
||||
const tableNameRlsDisabled = 'pw_table_rls_disabled'
|
||||
|
||||
Reference in new issue
Block a user