mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-10-26 14:29:36 +00:00
cover SMTP authentication and revert campaign date changes
This commit is contained in:
@@ -102,8 +102,8 @@ const businessHours = ref([])
|
||||
const error = ref('')
|
||||
const pendingDelete = ref(null)
|
||||
const stats = ref([])
|
||||
const from = ref('')
|
||||
const to = ref('')
|
||||
const from = ref(new Date(Date.now() - 30 * 86400000).toISOString().slice(0, 10))
|
||||
const to = ref(new Date().toISOString().slice(0, 10))
|
||||
const brandSenderName = computed(() => props.brandName.trim() || t('widget.brandBot'))
|
||||
const campaignEventExample = computed(
|
||||
() => `window.Libredesk.trackEvent(${JSON.stringify(campaign.value?.event || 'pricing_viewed')})`
|
||||
@@ -285,26 +285,13 @@ const refreshStats = async () => {
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const [hoursResult, settingsResult] = await Promise.allSettled([
|
||||
api.getAllBusinessHours(),
|
||||
api.getSettings('general')
|
||||
])
|
||||
if (hoursResult.status === 'fulfilled') {
|
||||
const data = hoursResult.value.data.data
|
||||
try {
|
||||
const response = await api.getAllBusinessHours()
|
||||
const data = response.data.data
|
||||
businessHours.value = data.results || data
|
||||
} catch (err) {
|
||||
error.value = handleHTTPError(err).message
|
||||
}
|
||||
const failed = [hoursResult, settingsResult].find((result) => result.status === 'rejected')
|
||||
if (failed) error.value = handleHTTPError(failed.reason).message
|
||||
const dateFormat = new Intl.DateTimeFormat('en-CA', {
|
||||
timeZone:
|
||||
(settingsResult.status === 'fulfilled' && settingsResult.value.data.data['app.timezone']) ||
|
||||
'UTC',
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit'
|
||||
})
|
||||
from.value = dateFormat.format(new Date(Date.now() - 30 * 86400000))
|
||||
to.value = dateFormat.format(new Date())
|
||||
await refreshStats()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -140,8 +140,13 @@ describe('Email inbox form', () => {
|
||||
cy.contains('New support inbox').should('be.visible')
|
||||
})
|
||||
|
||||
for (const protocol of ['None', 'Login']) {
|
||||
it(`validates empty SMTP credentials with ${protocol} authentication`, () => {
|
||||
for (const [protocol, value] of [
|
||||
['None', 'none'],
|
||||
['Login', 'login'],
|
||||
['CRAM', 'cram'],
|
||||
['Plain', 'plain']
|
||||
]) {
|
||||
it(`validates and saves SMTP credentials with ${protocol} authentication`, () => {
|
||||
openManualForm()
|
||||
fillRequiredFields()
|
||||
field('smtp.username').clear()
|
||||
@@ -160,6 +165,22 @@ describe('Email inbox form', () => {
|
||||
cy.get('@createInbox.all').should('have.length', 0)
|
||||
field('smtp.username').parent().parent().should('contain.text', 'Required')
|
||||
field('smtp.password').parent().parent().should('contain.text', 'Required')
|
||||
field('smtp.username').type('support@example.com')
|
||||
submit()
|
||||
field('smtp.password').should('have.attr', 'aria-invalid', 'true')
|
||||
cy.get('@createInbox.all').should('have.length', 0)
|
||||
field('smtp.username').clear()
|
||||
field('smtp.password').type('test-password')
|
||||
submit()
|
||||
field('smtp.username').should('have.attr', 'aria-invalid', 'true')
|
||||
cy.get('@createInbox.all').should('have.length', 0)
|
||||
field('smtp.username').type('support@example.com')
|
||||
submit()
|
||||
cy.wait('@createInbox').then(({ request }) => {
|
||||
expect(request.body.config.smtp[0].auth_protocol).to.eq(value)
|
||||
expect(request.body.config.smtp[0].username).to.eq('support@example.com')
|
||||
expect(request.body.config.smtp[0].password).to.eq('test-password')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -300,45 +300,6 @@ describe('Live chat inbox form: branches the other specs skip', () => {
|
||||
})
|
||||
})
|
||||
|
||||
for (const { name, path, message, skipBootCall } of [
|
||||
{ name: 'settings', path: 'settings/general', message: 'Settings unavailable', skipBootCall: true },
|
||||
{ name: 'business hours', path: 'business-hours', message: 'Business hours unavailable', skipBootCall: false }
|
||||
]) {
|
||||
it(`loads proactive message stats when the ${name} request fails`, () => {
|
||||
cy.intercept('GET', `**/api/v1/${path}`, {
|
||||
statusCode: 500,
|
||||
body: { status: 'error', message, error_type: 'GeneralException', data: null }
|
||||
})
|
||||
// The app loads general settings once at boot, before the form mounts. Only later calls fail.
|
||||
if (skipBootCall) {
|
||||
cy.intercept({ method: 'GET', url: `**/api/v1/${path}`, times: 1 }, (req) => req.continue())
|
||||
}
|
||||
cy.intercept('GET', `**/api/v1/inboxes/${inboxId}/campaign-stats*`).as('campaignStats')
|
||||
|
||||
editInbox(inboxId)
|
||||
cy.wait('@campaignStats').then(({ request, response }) => {
|
||||
expect(response.statusCode).to.eq(200)
|
||||
expect(new URL(request.url).searchParams.get('from')).to.match(/^\d{4}-\d{2}-\d{2}$/)
|
||||
})
|
||||
cy.contains('[role="alert"]', message).should('exist')
|
||||
})
|
||||
}
|
||||
|
||||
it('uses workspace dates for campaign statistics across a UTC day boundary', () => {
|
||||
cy.clock(Date.UTC(2026, 0, 1, 23, 30), ['Date'])
|
||||
cy.intercept('GET', '**/api/v1/settings/general', (req) => {
|
||||
req.continue((res) => { res.body.data['app.timezone'] = 'Pacific/Kiritimati' })
|
||||
})
|
||||
cy.intercept('GET', `**/api/v1/inboxes/${inboxId}/campaign-stats*`).as('workspaceStats')
|
||||
editInbox(inboxId)
|
||||
cy.wait('@workspaceStats').then(({ request, response }) => {
|
||||
expect(response.statusCode).to.eq(200)
|
||||
const params = new URL(request.url).searchParams
|
||||
expect(params.get('from')).to.eq('2025-12-03')
|
||||
expect(params.get('to')).to.eq('2026-01-02')
|
||||
})
|
||||
})
|
||||
|
||||
it('saves a proactive message condition and removes it again', () => {
|
||||
cy.intercept('PUT', `**/api/v1/inboxes/${inboxId}`).as('updateInbox')
|
||||
|
||||
|
||||
@@ -148,8 +148,13 @@ describe('Notification settings form', () => {
|
||||
cy.get('@saveNotification.all').should('have.length', 0)
|
||||
})
|
||||
|
||||
for (const protocol of ['None', 'Login']) {
|
||||
it(`validates empty notification SMTP credentials with ${protocol} authentication`, () => {
|
||||
for (const [protocol, value] of [
|
||||
['None', 'none'],
|
||||
['Login', 'login'],
|
||||
['CRAM-MD5', 'cram'],
|
||||
['Plain', 'plain']
|
||||
]) {
|
||||
it(`validates and saves notification SMTP credentials with ${protocol} authentication`, () => {
|
||||
cy.intercept('PUT', '**/api/v1/settings/notifications/email').as('saveNotification')
|
||||
cy.visit(path)
|
||||
cy.get('input[name="host"]').should('not.have.value', '')
|
||||
@@ -169,6 +174,30 @@ describe('Notification settings form', () => {
|
||||
cy.get('@saveNotification.all').should('have.length', 0)
|
||||
cy.get('input[name="username"]').parent().parent().should('contain.text', 'Required')
|
||||
cy.get('input[name="password"]').parent().parent().should('contain.text', 'Required')
|
||||
cy.get('input[name="username"]').type(seedUsername)
|
||||
cy.get('button[type="submit"]').click()
|
||||
cy.get('input[name="password"]').should('have.attr', 'aria-invalid', 'true')
|
||||
cy.get('@saveNotification.all').should('have.length', 0)
|
||||
cy.get('input[name="username"]').clear()
|
||||
cy.get('input[name="password"]').type('test-password')
|
||||
cy.get('button[type="submit"]').click()
|
||||
cy.get('input[name="username"]').should('have.attr', 'aria-invalid', 'true')
|
||||
cy.get('@saveNotification.all').should('have.length', 0)
|
||||
cy.get('input[name="username"]').type(seedUsername)
|
||||
cy.get('button[type="submit"]').click()
|
||||
cy.wait('@saveNotification').then(({ request, response }) => {
|
||||
expect(response.statusCode).to.eq(200)
|
||||
expect(request.body[`${prefix}auth_protocol`]).to.eq(value)
|
||||
expect(request.body[`${prefix}username`]).to.eq(seedUsername)
|
||||
expect(request.body[`${prefix}password`]).to.eq('test-password')
|
||||
})
|
||||
cy.reload()
|
||||
cy.contains('label', 'Authentication Protocol')
|
||||
.parent()
|
||||
.find('[role="combobox"]')
|
||||
.should('contain.text', protocol)
|
||||
cy.get('input[name="username"]').should('have.value', seedUsername)
|
||||
cy.get('input[name="password"]').should('have.value', maskedPassword)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user