Skip to content
94 changes: 94 additions & 0 deletions spec/frontend/submit_form.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import * as helpers from './helpers.js'
import { test, expect } from './fixtures.js'

test.describe('submitForm', _ => {
test.describe('exchanges form', _ => {
test.beforeEach(async ({ page, apimap }) => {
const exchangeTypesLoaded = apimap.get('/api/exchanges', [])
const overviewLoaded = apimap.get('/api/overview', { exchange_types: [{ name: 'topic' }, { name: 'direct' }] })
await page.goto('/exchanges')
await overviewLoaded
})

test('resets form on successful submit', async ({ page }) => {
const exchangeName = 'test-exchange'
const putRequest = helpers.waitForPathRequest(page, `/api/exchanges/bar/${exchangeName}`, { method: 'PUT' })

const form = page.locator('#addExchange')
await form.getByLabel('Name', { exact: true }).fill(exchangeName)
await form.getByRole('button', { name: 'Add exchange' }).click()

await expect(putRequest).toBeRequested()
await expect(form.getByLabel('Name', { exact: true })).toHaveValue('')
})

test('does not reset form on error response', async ({ page }) => {
const exchangeName = 'test-exchange'
// Intercept the PUT and return a 403 error
await page.route(url => url.pathname === `/api/exchanges/bar/${exchangeName}`, async route => {
if (route.request().method() === 'PUT') {
await route.fulfill({
status: 403,
contentType: 'application/json',
body: JSON.stringify({ error: 'access_refused', reason: 'No permission' })
})
} else {
await route.fallback()
}
})

// Dismiss the alert that standardErrorHandler will show
page.on('dialog', dialog => dialog.dismiss())

const form = page.locator('#addExchange')
await form.getByLabel('Name', { exact: true }).fill(exchangeName)
await form.getByRole('button', { name: 'Add exchange' }).click()

// Form should still have the value since request failed
await expect(form.getByLabel('Name', { exact: true })).toHaveValue(exchangeName)
})
})

test.describe('queues form', _ => {
test.beforeEach(async ({ page, apimap }) => {
const queuesLoaded = apimap.get('/api/queues', [])
await page.goto('/queues')
await queuesLoaded
})

test('preserves vhost selection after successful submit', async ({ page }) => {
const queueName = 'test-queue'
const putRequest = helpers.waitForPathRequest(page, `/api/queues/bar/${queueName}`, { method: 'PUT' })

const form = page.locator('#declare')
await form.getByLabel('Name', { exact: true }).fill(queueName)
await form.getByRole('button', { name: 'Add queue' }).click()

await expect(putRequest).toBeRequested()
await expect(form.locator('select[name="vhost"]')).toHaveValue('bar')
})

test('does not reset form on error response', async ({ page }) => {
const queueName = 'test-queue'
await page.route(url => url.pathname === `/api/queues/bar/${queueName}`, async route => {
if (route.request().method() === 'PUT') {
await route.fulfill({
status: 403,
contentType: 'application/json',
body: JSON.stringify({ error: 'access_refused', reason: 'No permission' })
})
} else {
await route.fallback()
}
})

page.on('dialog', dialog => dialog.dismiss())

const form = page.locator('#declare')
await form.getByLabel('Name', { exact: true }).fill(queueName)
await form.getByRole('button', { name: 'Add queue' }).click()

await expect(form.getByLabel('Name', { exact: true })).toHaveValue(queueName)
})
})
})
7 changes: 1 addition & 6 deletions static/js/exchange.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,7 @@ document.querySelector('#addBinding').addEventListener('submit', function (evt)
routing_key: data.get('routing_key').trim(),
arguments: args
}
HTTP.request('POST', url, { body })
.then(res => {
if (res && res.is_error) return
bindingsTable.reload()
evt.target.reset()
})
HTTP.submitForm(evt.target, 'POST', url, { body, table: bindingsTable })
.catch(e => {
if (e.status === 404) {
const type = t === 'q' ? 'Queue' : 'Exchange'
Expand Down
12 changes: 6 additions & 6 deletions static/js/exchanges.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ document.querySelector('#addExchange').addEventListener('submit', function (evt)
type: data.get('type'),
arguments: DOM.parseJSON(data.get('arguments'))
}
HTTP.request('PUT', url, { body })
.then(() => {
exchangeTable.reload()
DOM.toast('Exchange ' + exchange + ' created')
evt.target.reset()
})
HTTP.submitForm(evt.target, 'PUT', url, {
body,
table: exchangeTable
}).then(() => {
DOM.toast(`Exhange ${exchange} created`)
})
})

document.querySelector('#dataTags').addEventListener('click', e => {
Expand Down
12 changes: 6 additions & 6 deletions static/js/federation.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ document.querySelector('#createUpstream').addEventListener('submit', function (e
'consumer-tag': data.get('consumer-tag')
}
}
HTTP.request('PUT', url, { body })
.then(() => {
upstreamsTable.reload()
evt.target.reset()
DOM.toast(`Upstream ${name} saved`)
})
HTTP.submitForm(evt.target, 'PUT', url, {
body,
table: upstreamsTable
}).then(() => {
DOM.toast(`Upstream ${name} saved`)
})
})
11 changes: 11 additions & 0 deletions static/js/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,19 @@ function noencode (v) {
return new NoUrlEscapeString(v)
}

async function submitForm (form, method, url, options = {}) {
const { body, table } = options
return request(method, url, { body })
.then(res => {
if (res?.is_error) throw res
if (table) table.reload()
form.reset()
})
}

export {
request,
submitForm,
url,
noencode
}
6 changes: 1 addition & 5 deletions static/js/policies.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@ document.querySelector('#createPolicy').addEventListener('submit', function (evt
'apply-to': data.get('apply-to'),
priority: parseInt(data.get('priority'))
}
HTTP.request('PUT', url, { body })
.then(() => {
policiesTable.reload()
evt.target.reset()
})
HTTP.submitForm(evt.target, 'PUT', url, { body, table: policiesTable })
})
document.querySelector('#dataTags').addEventListener('click', e => {
Helpers.argumentHelperJSON('createPolicy', 'definition', e)
Expand Down
32 changes: 15 additions & 17 deletions static/js/queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,18 +200,16 @@ document.querySelector('#addBinding').addEventListener('submit', function (evt)
routing_key: data.get('routing_key').trim(),
arguments: args
}
HTTP.request('POST', url, { body })
.then(res => {
if (res && res.is_error) return
bindingsTable.reload()
evt.target.reset()
DOM.toast('Exchange ' + e + ' bound to queue')
})
.catch(err => {
if (err.status === 404) {
DOM.toast.error(`Exchange '${e}' does not exist and needs to be created first.`)
}
})
HTTP.submitForm(evt.target, 'POST', url, {
body,
table: bindingsTable
}).then(() => {
DOM.toast(`Exchange ${e} bound to queue`)
}).catch(err => {
if (err.status === 404) {
DOM.toast.error(`Exchange '${e}' does not exist and needs to be created first.`)
}
})
})

document.querySelector('#publishMessage').addEventListener('submit', function (evt) {
Expand Down Expand Up @@ -298,11 +296,11 @@ document.querySelector('#moveMessages').addEventListener('submit', function (evt
'src-delete-after': 'queue-length'
}
}
HTTP.request('PUT', url, { body })
.then(() => {
evt.target.reset()
DOM.toast('Moving messages to ' + dest)
})
HTTP.submitForm(evt.target, 'PUT', url, {
body
}).then(() => {
DOM.toast(`Moving messages to ${dest}`)
})
})

document.querySelector('#purgeQueue').addEventListener('submit', function (evt) {
Expand Down
17 changes: 9 additions & 8 deletions static/js/queues.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,16 @@ document.querySelector('#declare').addEventListener('submit', function (evt) {
auto_delete: data.get('auto_delete') === '1',
arguments: DOM.parseJSON(data.get('arguments'))
}
HTTP.request('PUT', url, { body })
.then((response) => {
if (response?.is_error) { return }
queuesTable.reload()
evt.target.reset()
evt.target.querySelector('select[name="vhost"]').value = decodeURIComponent(vhost) // Keep selected vhost selected
DOM.toast('Queue ' + queue + ' created')
})

HTTP.submitForm(evt.target, 'PUT', url, {
body,
table: queuesTable
}).then(() => {
DOM.toast(`Queue ${queue} created`)
evt.target.querySelector('select[name="vhost"]').value = decodeURIComponent(vhost) // Keep selected vhost selected
})
})

queuesTable.on('updated', _ => {
const checked = document.querySelectorAll('input[data-name]:checked')
document.getElementById('multi-queue-count').textContent = checked.length
Expand Down
12 changes: 6 additions & 6 deletions static/js/shovels.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,12 @@ document.querySelector('#createShovel').addEventListener('submit', function (evt
} else {
body.value['dest-exchange'] = data.get('dest-endpoint')
}
HTTP.request('PUT', url, { body })
.then(() => {
dataSource.reload()
evt.target.reset()
DOM.toast(`Shovel ${name} saved`)
})
HTTP.submitForm(evt.target, 'PUT', url, {
body,
table: dataSource
}).then(() => {
DOM.toast(`Shovel ${name} saved`)
})
})

// function updateAutocomplete (e, id) {
Expand Down
13 changes: 6 additions & 7 deletions static/js/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,12 @@ document.querySelector('#addBinding').addEventListener('submit', function (evt)
routing_key: data.get('routing_key').trim(),
arguments: args
}
HTTP.request('POST', url, { body })
.then(res => {
if (res && res.is_error) return
bindingsTable.reload()
evt.target.reset()
DOM.toast('Exchange ' + e + ' bound to queue')
})
HTTP.submitForm(evt.target, 'POST', url, {
body,
table: bindingsTable
}).then(() => {
DOM.toast(`Exchange ${e} bound to queue`)
})
})

document.querySelector('#publishMessage').addEventListener('submit', function (evt) {
Expand Down
22 changes: 9 additions & 13 deletions static/js/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@ document.querySelector('#setPermission').addEventListener('submit', function (ev
write: data.get('write'),
read: data.get('read')
}
HTTP.request('PUT', url, { body })
.then(() => {
permissionsTable.reload()
evt.target.reset()
})
HTTP.submitForm(evt.target, 'PUT', url, { body, table: permissionsTable })
})

document.querySelector('[name=remove_password]').addEventListener('change', function () {
Expand All @@ -97,14 +93,14 @@ document.querySelector('#updateUser').addEventListener('submit', function (evt)
} else if (data.get('password') !== '') {
body.password = data.get('password')
}
HTTP.request('PUT', url, { body })
.then(() => {
updateUser()
DOM.toast('User updated')
evt.target.reset()
pwd.disabled = false
pwd.required = true
})
HTTP.submitForm(evt.target, 'PUT', url, {
body
}).then(() => {
DOM.toast('User updated')
updateUser()
pwd.disabled = false
pwd.required = true
})
})

document.querySelector('#dataTags').addEventListener('click', e => {
Expand Down
12 changes: 6 additions & 6 deletions static/js/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ document.querySelector('#createUser').addEventListener('submit', function (evt)
if (data.get('password') !== '') {
body.password = data.get('password')
}
HTTP.request('PUT', url, { body })
.then(() => {
usersTable.reload()
DOM.toast(toastText)
evt.target.reset()
})
HTTP.submitForm(evt.target, 'PUT', url, {
body,
table: usersTable
}).then(() => {
DOM.toast(toastText)
})
})

document.querySelector('#dataTags').addEventListener('click', e => {
Expand Down
6 changes: 1 addition & 5 deletions static/js/vhost.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,7 @@ document.querySelector('#setPermission').addEventListener('submit', function (ev
write: data.get('write'),
read: data.get('read')
}
HTTP.request('PUT', url, { body })
.then(() => {
permissionsTable.reload()
evt.target.reset()
})
HTTP.submitForm(evt.target, 'PUT', url, { body, table: permissionsTable })
})

document.forms.setLimits.addEventListener('submit', function (evt) {
Expand Down
6 changes: 1 addition & 5 deletions static/js/vhosts.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,5 @@ document.querySelector('#createVhost').addEventListener('submit', function (evt)
const data = new window.FormData(this)
const name = data.get('name').trim()
const url = HTTP.url`api/vhosts/${name}`
HTTP.request('PUT', url)
.then(() => {
vhostTable.reload()
evt.target.reset()
})
HTTP.submitForm(evt.target, 'PUT', url, { table: vhostTable })
})
Loading