WP-10: contract and failing tests for OS and package inventory
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / ui (push) Has been cancelled

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-09-02 22:19:25 +02:00
parent b6c3ddf040
commit 7b6d242988
21 changed files with 698 additions and 0 deletions

View File

@ -0,0 +1,18 @@
import { test, expect } from '@playwright/test'
test('updates page shows OS info and packages after a refresh', async ({ page }) => {
await page.goto('/login')
await page.getByLabel('Email').fill('admin@example.com')
await page.getByLabel('Password').fill('admin-password-123')
await page.getByRole('button', { name: 'Sign in' }).click()
await page.getByRole('link', { name: 'Updates' }).click()
await page.getByRole('button', { name: 'Refresh inventory' }).click()
await expect(page.getByTestId('os-name')).toContainText('Debian', { timeout: 15_000 })
await expect(page.getByText('Reboot required')).toBeVisible()
await expect(page.getByTestId('summary-upgradable')).toContainText('3')
await page.getByLabel('Upgradable only').check()
await expect(page.getByRole('row', { name: /openssl/ })).toBeVisible()
await expect(page.getByRole('row', { name: /bash/ })).toHaveCount(0)
})

View File

@ -67,3 +67,27 @@ export interface JobRun {
log: string
triggered_by: string
}
export interface OsInfo {
hostname: string
name: string
version: string
kernel: string
uptime_secs: number
reboot_required: boolean
}
export interface Package {
name: string
source: 'apt' | 'snap'
installed: string
candidate: string | null
is_security: boolean
}
export interface InventoryResponse {
refreshed_at: string | null
os: OsInfo | null
packages: Package[]
summary: { total: number; upgradable: number; security: number }
}

View File

@ -0,0 +1,37 @@
import { mount } from '@vue/test-utils'
import PackageTable from './PackageTable.vue'
import type { Package } from '../api/types'
const pkgs: Package[] = [
{ name: 'bash', source: 'apt', installed: '5.2', candidate: null, is_security: false },
{ name: 'openssl', source: 'apt', installed: '3.0.1', candidate: '3.0.2', is_security: true },
{ name: 'curl', source: 'apt', installed: '7.88', candidate: '7.89', is_security: false },
{ name: 'microk8s', source: 'snap', installed: 'v1.32', candidate: null, is_security: false },
]
const rows = (w: ReturnType<typeof mount>) => w.findAll('tbody tr').map((r) => r.text())
describe('PackageTable', () => {
it('lists all packages and marks upgradable ones', () => {
const w = mount(PackageTable, { props: { packages: pkgs } })
expect(rows(w)).toHaveLength(4)
expect(rows(w)[1]).toContain('3.0.2')
expect(rows(w)[1]).toContain('security')
})
it('filters by search text and upgradable flag', async () => {
const w = mount(PackageTable, { props: { packages: pkgs } })
await w.find('input[name=search]').setValue('ssl')
expect(rows(w)).toHaveLength(1)
await w.find('input[name=search]').setValue('')
await w.find('input[name=upgradable]').setValue(true)
expect(rows(w).map((r) => r.split(' ')[0])).toEqual(['openssl', 'curl'])
})
it('filters by source', async () => {
const w = mount(PackageTable, { props: { packages: pkgs } })
await w.find('select[name=source]').setValue('snap')
expect(rows(w)).toHaveLength(1)
expect(rows(w)[0]).toContain('microk8s')
})
})