Skip to content
Merged
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
78 changes: 14 additions & 64 deletions e2e/account-jobs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,65 +41,16 @@ function insertJob(input: {
)
}

test('account jobs detail URL persists across reload for a seeded job', async ({
test('account jobs list filters and detail URL persist for seeded jobs', async ({
page,
seedE2eUser,
login,
}) => {
const runId = Date.now()
const email = `account-jobs-detail-${runId}@example.com`
const email = `account-jobs-${runId}@example.com`
const user = await seedE2eUser({
email,
username: `account-jobs-detail-${runId}`,
password: 'account-jobs-password',
})
const userId = await createStableUserIdFromEmail(email)
const jobId = crypto.randomUUID()
const jobName = `Seeded job ${runId}`
const now = new Date().toISOString()
const nextRunAt = new Date(Date.now() + 60 * 60 * 1000).toISOString()
insertJob({
userId,
jobId,
jobName,
schedule: { type: 'interval', every: '1h' },
enabled: 1,
nextRunAt,
now,
})

await login({
email: user.email,
password: user.password,
mode: 'login',
})

await page.goto(`/account/jobs/${encodeURIComponent(jobId)}`)
await expect(
page.getByRole('heading', { name: 'Jobs', exact: true }),
).toBeVisible()
await expect(
page.getByRole('heading', { name: jobName, exact: true }),
).toBeVisible()

const detailUrl = page.url()
await page.reload()
await expect(page).toHaveURL(detailUrl)
await expect(
page.getByRole('heading', { name: jobName, exact: true }),
).toBeVisible()
})

test('account jobs defaults to active view and can show history', async ({
page,
seedE2eUser,
login,
}) => {
const runId = Date.now()
const email = `account-jobs-filter-${runId}@example.com`
const user = await seedE2eUser({
email,
username: `account-jobs-filter-${runId}`,
username: `account-jobs-${runId}`,
password: 'account-jobs-password',
})
const userId = await createStableUserIdFromEmail(email)
Expand Down Expand Up @@ -162,21 +113,20 @@ test('account jobs defaults to active view and can show history', async ({
await expect(page.getByText(historyJobName, { exact: true })).toBeVisible()
await expect(page.getByText(activeJobName, { exact: true })).toHaveCount(0)

await page.getByLabel('Jobs view filter').selectOption('all')
await expect(page).toHaveURL(/view=all/)
await expect(page.getByText(activeJobName, { exact: true })).toBeVisible()
await expect(page.getByText(historyJobName, { exact: true })).toBeVisible()
await expect(page.getByText(packageJobName, { exact: true })).toBeVisible()

await page.getByLabel('Jobs ownership filter').selectOption('package')
await page.getByLabel('Jobs view filter').selectOption('all')
await expect(page).toHaveURL(/ownership=package/)
await expect(page.getByText(packageJobName, { exact: true })).toBeVisible()
await expect(page.getByText(activeJobName, { exact: true })).toHaveCount(0)
await expect(page.getByText(historyJobName, { exact: true })).toHaveCount(0)

await page.getByLabel('Jobs ownership filter').selectOption('ad-hoc')
await expect(page).toHaveURL(/ownership=ad-hoc/)
await expect(page.getByText(activeJobName, { exact: true })).toBeVisible()
await expect(page.getByText(historyJobName, { exact: true })).toBeVisible()
await expect(page.getByText(packageJobName, { exact: true })).toHaveCount(0)
await page.goto(`/account/jobs/${encodeURIComponent(activeJobId)}`)
await expect(
page.getByRole('heading', { name: activeJobName, exact: true }),
).toBeVisible()
const detailUrl = page.url()
await page.reload()
await expect(page).toHaveURL(detailUrl)
await expect(
page.getByRole('heading', { name: activeJobName, exact: true }),
).toBeVisible()
})
10 changes: 1 addition & 9 deletions packages/worker/client/routes/account-jobs-filter.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function job(
}
}

test('isActiveAccountJob keeps enabled jobs and future disabled once jobs', () => {
test('account jobs filters cover active/history views and ownership', () => {
expect(
isActiveAccountJob(
job({ id: 'enabled-cron', enabled: true, scheduleType: 'cron' }),
Expand Down Expand Up @@ -67,29 +67,21 @@ test('isActiveAccountJob keeps enabled jobs and future disabled once jobs', () =
nowMs,
),
).toBe(false)
})

test('readJobsViewFilter defaults to active and accepts history/all', () => {
expect(readJobsViewFilter('/account/jobs')).toBe('active')
expect(readJobsViewFilter('/account/jobs?view=active')).toBe('active')
expect(readJobsViewFilter('/account/jobs?view=history')).toBe('history')
expect(readJobsViewFilter('/account/jobs?view=all')).toBe('all')
expect(readJobsViewFilter('/account/jobs?view=nope')).toBe('active')
})

test('readJobsOwnershipFilter defaults to all and accepts package/ad-hoc', () => {
expect(readJobsOwnershipFilter('/account/jobs')).toBe('all')
expect(readJobsOwnershipFilter('/account/jobs?ownership=all')).toBe('all')
expect(readJobsOwnershipFilter('/account/jobs?ownership=package')).toBe(
'package',
)
expect(readJobsOwnershipFilter('/account/jobs?ownership=ad-hoc')).toBe(
'ad-hoc',
)
expect(readJobsOwnershipFilter('/account/jobs?ownership=nope')).toBe('all')
})

test('filterAccountJobs supports view and ownership filters', () => {
const jobs = [
job({
id: 'live-cron',
Expand Down
72 changes: 28 additions & 44 deletions packages/worker/client/routes/integration-filter.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
oauthAppDisplayName,
} from './integration-filter.ts'

test('integration filtering searches names, endpoints, scopes, hosts, and app metadata', () => {
test('integration filter and app grouping cover search and sibling connections', () => {
const integrations = [
{
name: 'github',
Expand All @@ -24,36 +24,6 @@ test('integration filtering searches names, endpoints, scopes, hosts, and app me
scopes: ['repo', 'read:user'],
},
},
{
name: 'spotify',
appSlug: 'spotify',
provider: 'spotify',
appLabel: null,
accountLabel: null,
tokenUrl: 'https://accounts.spotify.com/api/token',
apiBaseUrl: 'https://api.spotify.com',
clientId: 'spotify-client-id-value',
accessTokenSecretName: 'spotify-access-token',
requiredHosts: ['api.spotify.com'],
authorization: {
authorizeUrl: 'https://accounts.spotify.com/authorize',
scopes: ['user-read-playback-state'],
},
},
]

expect(filterIntegrations(integrations, 'GITHUB repo')).toEqual([
integrations[0],
])
expect(filterIntegrations(integrations, 'playback')).toEqual([
integrations[1],
])
expect(filterIntegrations(integrations, 'missing')).toEqual([])
expect(filterIntegrations(integrations, '')).toEqual(integrations)
})

test('groupIntegrationsByApp groups sibling connections under one OAuth app', () => {
const integrations = [
{
name: 'google',
appSlug: 'google',
Expand All @@ -75,29 +45,43 @@ test('groupIntegrationsByApp groups sibling connections under one OAuth app', ()
accessTokenSecretName: 'googleCalendarAccessToken',
},
{
name: 'github',
appSlug: 'github',
provider: 'github',
name: 'spotify',
appSlug: 'spotify',
provider: 'spotify',
appLabel: null,
accountLabel: null,
tokenUrl: 'https://github.com/login/oauth/access_token',
clientId: 'github-client',
accessTokenSecretName: 'githubAccessToken',
tokenUrl: 'https://accounts.spotify.com/api/token',
apiBaseUrl: 'https://api.spotify.com',
clientId: 'spotify-client-id-value',
accessTokenSecretName: 'spotify-access-token',
requiredHosts: ['api.spotify.com'],
authorization: {
authorizeUrl: 'https://accounts.spotify.com/authorize',
scopes: ['user-read-playback-state'],
},
},
]

expect(filterIntegrations(integrations, 'GITHUB repo')).toEqual([
integrations[0],
])
expect(filterIntegrations(integrations, 'playback')).toEqual([
integrations[3],
])
expect(filterIntegrations(integrations, 'missing')).toEqual([])
expect(filterIntegrations(integrations, '')).toEqual(integrations)

const groups = groupIntegrationsByApp(integrations)
expect(groups).toHaveLength(2)
expect(groups[0]).toMatchObject({
appSlug: 'google',
expect(groups).toHaveLength(3)
const googleGroup = groups.find((group) => group.appSlug === 'google')
expect(googleGroup).toMatchObject({
clientId: 'shared-google-client',
connections: [
expect.objectContaining({ name: 'google' }),
expect.objectContaining({ name: 'google-calendar' }),
],
})
expect(groups[1]?.connections).toHaveLength(1)
expect(oauthAppDisplayName(groups[0]!)).toBe('google')
expect(integrationDisplayName(integrations[0]!)).toBe('Personal')
expect(integrationDisplayName(integrations[2]!)).toBe('github')
expect(oauthAppDisplayName(googleGroup!)).toBe('google')
expect(integrationDisplayName(integrations[1]!)).toBe('Personal')
expect(integrationDisplayName(integrations[0]!)).toBe('github')
})
Loading
Loading