Files

146 lines
4.8 KiB
TypeScript

import { expect, test, type Page } from '@playwright/test'
import { signIn } from './session'
interface MockEntry {
key: string
isDir: boolean
size: number
lastModified: number
}
async function mockDriveApi(page: Page, initialEntries: MockEntry[] = []) {
let entries = [...initialEntries]
await page.route('**/v1/s3/buckets', (route) => {
if (route.request().method() === 'GET') {
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
buckets: [{ name: 'test-bucket', createdAt: Date.now() }],
}),
})
}
return route.continue()
})
await page.route('**/v1/s3/buckets/test-bucket/objects**', (route) => {
const url = new URL(route.request().url())
const method = route.request().method()
if (method === 'GET') {
const prefix = url.searchParams.get('prefix') || ''
const filtered = entries.filter((e) => {
if (!prefix) return !e.key.includes('/') || e.key.endsWith('/') && e.key.indexOf('/') === e.key.length - 1
return e.key.startsWith(prefix)
})
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
objects: filtered,
}),
})
}
if (method === 'POST') {
const body = route.request().postDataJSON()
const key = body?.key || 'new-item'
const isDir = key.endsWith('/')
entries.push({
key,
isDir,
size: isDir ? 0 : 128,
lastModified: Date.now(),
})
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ url: 'http://localhost:5173/mock-upload' }),
})
}
if (method === 'DELETE') {
const key = decodeURIComponent(url.pathname.split('/objects/')[1] || '')
entries = entries.filter((e) => e.key !== key && !e.key.startsWith(key))
return route.fulfill({ status: 200, contentType: 'application/json', body: '{}' })
}
return route.continue()
})
await page.route('http://localhost:5173/mock-upload', (route) => {
return route.fulfill({ status: 200 })
})
}
test.describe('Workspace Drive component', () => {
test('signed-out visitor sees sign-in prompt', async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 900 })
await page.goto('/drive')
await expect(page.getByText(/sign in to open your drive/i)).toBeVisible({ timeout: 15_000 })
})
test('signed-in user can view bucket, navigate files, and toggle grid/list', async ({ page }) => {
await signIn(page)
await mockDriveApi(page, [
{ key: 'documents/', isDir: true, size: 0, lastModified: Date.now() - 3600000 },
{ key: 'hello.txt', isDir: false, size: 1024, lastModified: Date.now() },
])
await page.setViewportSize({ width: 1440, height: 900 })
await page.goto('/drive')
// Click bucket if on bucket list
const bucketItem = page.getByText('test-bucket')
await expect(bucketItem).toBeVisible({ timeout: 15_000 })
await bucketItem.click()
// Check breadcrumb and entries
await expect(page.getByText('My drive')).toBeVisible({ timeout: 15_000 })
await expect(page.getByText('documents')).toBeVisible()
await expect(page.getByText('hello.txt')).toBeVisible()
// Test search filter
const searchInput = page.getByPlaceholder('Search in this folder')
await searchInput.fill('doc')
await expect(page.getByText('documents')).toBeVisible()
await expect(page.getByText('hello.txt')).not.toBeVisible()
await searchInput.fill('')
await expect(page.getByText('hello.txt')).toBeVisible()
// Test List view toggle
const listBtn = page.getByRole('button', { name: 'List' })
await listBtn.click()
await expect(page.getByText('Last modified')).toBeVisible()
// Test Grid view toggle
const gridBtn = page.getByRole('button', { name: 'Grid' })
await gridBtn.click()
// Test New folder flow
const newBtn = page.getByRole('button', { name: 'New', exact: true })
await newBtn.click()
const newFolderOption = page.getByRole('button', { name: 'New folder' })
await newFolderOption.click()
const nameInput = page.getByPlaceholder('Name')
await expect(nameInput).toBeVisible()
await nameInput.fill('archive')
await nameInput.press('Enter')
await expect(page.getByText('archive')).toBeVisible()
// Test deleting an item via 3-dot verbs menu
const docCard = page.getByRole('button', { name: 'documents/' })
const moreBtn = docCard.getByRole('button', { name: 'More' })
await moreBtn.click()
const deleteBtn = page.getByRole('button', { name: 'Delete' })
await expect(deleteBtn).toBeVisible()
await deleteBtn.click()
await expect(page.getByRole('button', { name: 'documents/' })).not.toBeVisible()
})
})