feat: complete dockerization (optional)
This commit is contained in:
1 parent
3e01c29657
commit
d275ba3c14
38 files changed
+1244
-20
No files matched your search
@@ -0,0 +1,150 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { mount, flushPromises, type VueWrapper } from '@vue/test-utils'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import uiPlugin from '@nuxt/ui/vue-plugin'
|
||||
import router from '@/router'
|
||||
import { useApi, type UserRole } from '@/composables/useApi'
|
||||
import type { UpdateStatus } from '@/composables/useUpdate'
|
||||
import { useSessionStore } from '@/stores/session'
|
||||
import SettingsView from '../SettingsView.vue'
|
||||
import {
|
||||
RUNNING_VERSION,
|
||||
STATUS_PATH,
|
||||
findButton,
|
||||
newerAvailable,
|
||||
stubClipboard,
|
||||
upToDate,
|
||||
visibleButtonLabels,
|
||||
} from './updateTestKit'
|
||||
|
||||
vi.mock('@/composables/useApi', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@/composables/useApi')>()
|
||||
return {
|
||||
...actual,
|
||||
useApi: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
const CONTAINER_COMMAND = 'docker compose pull && docker compose up -d'
|
||||
|
||||
let wrapper: VueWrapper | null = null
|
||||
|
||||
async function mountSettings(role: UserRole, status: UpdateStatus) {
|
||||
setActivePinia(createPinia())
|
||||
const session = useSessionStore()
|
||||
session.session = { verified: true, username: 'marta', id: 1, role }
|
||||
session.status = 'ready'
|
||||
const request = vi.fn((path: string) => {
|
||||
if (path === '/v1/settings/') {
|
||||
return Promise.resolve({ version: RUNNING_VERSION })
|
||||
}
|
||||
if (path === STATUS_PATH) {
|
||||
return Promise.resolve(status)
|
||||
}
|
||||
throw new Error(`Unexpected request: ${path}`)
|
||||
})
|
||||
vi.mocked(useApi).mockReturnValue({
|
||||
getMe: vi.fn().mockResolvedValue({
|
||||
verified: true,
|
||||
username: 'marta',
|
||||
id: 1,
|
||||
displayName: '',
|
||||
role,
|
||||
}),
|
||||
request,
|
||||
})
|
||||
await router.push('/settings')
|
||||
wrapper = mount(SettingsView, {
|
||||
attachTo: document.body,
|
||||
global: { plugins: [router, uiPlugin] },
|
||||
})
|
||||
await flushPromises()
|
||||
}
|
||||
|
||||
function updatesCard() {
|
||||
return document.body.querySelector('[data-testid="updates-card"]')!
|
||||
}
|
||||
|
||||
function cardText() {
|
||||
return updatesCard().textContent ?? ''
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
wrapper?.unmount()
|
||||
wrapper = null
|
||||
vi.useRealTimers()
|
||||
await router.push('/login')
|
||||
document.body.innerHTML = ''
|
||||
})
|
||||
|
||||
describe('Settings, owner, container, update available', () => {
|
||||
it('shows the pull-image guidance, the command, Copy and the docs link, with no other button', async () => {
|
||||
await mountSettings('owner', newerAvailable({ container: true }))
|
||||
|
||||
expect(cardText()).toContain('Version 2.3.0-beta is available')
|
||||
expect(cardText()).toContain(
|
||||
'You have v2.2.0-beta. This site runs in Docker, so it updates by pulling a new image. Run the commands below on the server.',
|
||||
)
|
||||
expect(updatesCard().querySelector('code')?.textContent).toBe(CONTAINER_COMMAND)
|
||||
const link = Array.from(updatesCard().querySelectorAll('a')).find(
|
||||
(anchor) => anchor.textContent?.trim() === 'How to update',
|
||||
)!
|
||||
expect(link.getAttribute('href')).toBe(
|
||||
'https://git.example/fsylvain/RenewCMS/src/branch/main/docs/docker.md',
|
||||
)
|
||||
expect(visibleButtonLabels(updatesCard())).toEqual(["What's new in 2.3.0-beta", 'Copy'])
|
||||
expect(cardText()).not.toContain('renewcms enable-browser-updates')
|
||||
expect(cardText()).not.toContain('They run this once on the server')
|
||||
expect(cardText()).not.toContain("can't update itself from the browser")
|
||||
})
|
||||
|
||||
it('copies the container command and reads Copied for 2 s', async () => {
|
||||
const writeText = stubClipboard()
|
||||
vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout'] })
|
||||
await mountSettings('owner', newerAvailable({ container: true }))
|
||||
|
||||
findButton('Copy')!.click()
|
||||
await flushPromises()
|
||||
|
||||
expect(writeText).toHaveBeenCalledWith(CONTAINER_COMMAND)
|
||||
expect(findButton('Copied')!.getAttribute('aria-live')).toBe('polite')
|
||||
|
||||
await vi.advanceTimersByTimeAsync(2000)
|
||||
expect(findButton('Copy')?.textContent?.trim()).toBe('Copy')
|
||||
expect(findButton('Copied')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Settings, owner, container, up to date', () => {
|
||||
it("shows You're up to date with only Check for updates and no container hint", async () => {
|
||||
await mountSettings('owner', upToDate({ container: true }))
|
||||
|
||||
expect(cardText()).toContain("You're up to date")
|
||||
expect(visibleButtonLabels(updatesCard())).toEqual(['Check for updates'])
|
||||
expect(cardText()).not.toContain('Docker')
|
||||
expect(updatesCard().querySelector('code')).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Settings, admin, container', () => {
|
||||
it('keeps the admin view with no command block', async () => {
|
||||
await mountSettings('admin', newerAvailable({ container: true }))
|
||||
|
||||
expect(cardText()).toContain('Only the owner can update RenewCMS.')
|
||||
expect(cardText()).not.toContain('Docker')
|
||||
expect(updatesCard().querySelector('code')).toBeNull()
|
||||
expect(visibleButtonLabels(updatesCard())).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('Settings, owner, not container, not prepared', () => {
|
||||
it('still shows the enable-browser-updates command', async () => {
|
||||
await mountSettings('owner', newerAvailable({ container: false }))
|
||||
|
||||
expect(updatesCard().querySelector('code')?.textContent).toBe(
|
||||
'renewcms enable-browser-updates',
|
||||
)
|
||||
expect(cardText()).toContain("This site can't update itself from the browser yet.")
|
||||
expect(cardText()).not.toContain('Docker')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user