qrcode: don't refetch metadata & tally status if scanning the same certificate twice (#86854)
gitea/passerelle/pipeline/head This commit looks good Details

This commit is contained in:
Corentin Sechet 2024-02-14 13:21:54 +01:00
parent 9ed59bc94d
commit 0fa387d6d0
2 changed files with 107 additions and 2 deletions

View File

@ -152,6 +152,7 @@ class QRCodeReader extends window.HTMLElement {
#popup
#popupContent
#popupTitle
#currentCertificate
constructor () {
super()
@ -169,6 +170,8 @@ class QRCodeReader extends window.HTMLElement {
const closePopupButton = this.querySelector('.qrcode-reader--close-popup-button')
closePopupButton.addEventListener('click', () => {
this.#popupContent.innerHTML = ''
this.#currentCertificate = undefined
this.#popup.classList.add('closed')
})
@ -227,13 +230,18 @@ class QRCodeReader extends window.HTMLElement {
return
}
this.#popupContent.innerHTML = ''
const decoder = new TextDecoder('utf-8')
const decoded = decoder.decode(opened)
const data = decodeMimeLike(decoded)
const certificateUUID = data.uuid
if(certificateUUID && certificateUUID === this.#currentCertificate) {
return
}
this.#currentCertificate = certificateUUID
this.#popupContent.innerHTML = ''
delete data.uuid

View File

@ -142,11 +142,14 @@ qrcodeReaderTest('qrcode reader shows error on not yet valid or expired qrcodes'
const popup = reader.querySelector('.qrcode-reader--popup')
const title = popup.querySelector('.qrcode-reader--popup-title')
const closeButton = reader.querySelector('.qrcode-reader--close-popup-button')
expect(popup.classList.contains('closed')).toBe(false)
expect(popup.classList.contains('error')).toBe(true)
expect(title.innerText).toBe('not_yet_valid')
closeButton.dispatchEvent(new Event('click'))
vi.setSystemTime(new Date(2023, 11, 2)) // monthes start at 0 index, wtf javascript
await scan(okCodeData)
@ -257,6 +260,7 @@ const qrcodeReaderMetadataTest = qrcodeReaderTest.extend({
// Wait for scan promises to finish
await new Promise((resolve) => setTimeout(resolve))
fetch.mockReset()
}
await use(loadMetadata)
@ -293,6 +297,7 @@ qrcodeReaderMetadataTest('qrcode reader fetches metadata', async ({mock, loadMet
expect(values[1].innerText).toMatch('Non')
})
qrcodeReaderMetadataTest('qrcode reader show feedback on metadata network error', async ({mock, loadMetadata}) => {
const { reader, scan } = mock
await loadMetadata(okCodeData, async (url) => {
@ -344,6 +349,50 @@ qrcodeReaderMetadataTest('qrcode reader show feedback on api error', async ({moc
expect(items.innerText.trim()).toBe('metadata_api_error')
})
qrcodeReaderMetadataTest("qrcode reader doesn't refetch metadata for the same certificate if popup is opened", async ({mock, loadMetadata}) => {
const { reader, scan } = mock
await loadMetadata(okCodeData, async (url) => {
return {
ok: true,
json: async () => ({'err': 0, 'data': {'Classe': 'Oui', 'Ravioles': 'Non'}})
}
})
let items = reader.querySelector('.qrcode-reader--metadata-items')
// loading the same certificate doesn't refeches metadata
await loadMetadata(okCodeData, async (url) => {
expect.unreachable()
})
expect(reader.querySelector('.qrcode-reader--metadata-items')).toBe(items)
// loading another certificate refetches metadata
await loadMetadata(certificateWithoutValidity, async (url) => {
return {
ok: true,
json: async () => ({'err': 0, 'data': {'Classe': 'Oui', 'Ravioles': 'Non'}})
}
})
expect(reader.querySelector('.qrcode-reader--metadata-items')).not.toBe(items)
items = reader.querySelector('.qrcode-reader--metadata-items')
const closeButton = reader.querySelector('.qrcode-reader--close-popup-button')
closeButton.dispatchEvent(new Event('click'))
// metadata is refetched for the same certificate after closing the popup
await loadMetadata(certificateWithoutValidity, async (url) => {
return {
ok: true,
json: async () => ({'err': 0, 'data': {'Classe': 'Oui', 'Ravioles': 'Non'}})
}
})
expect(reader.querySelector('.qrcode-reader--metadata-items')).not.toBe(items)
})
const qrcodeReaderTallyTest = qrcodeReaderTest.extend({
loadTally: async ({ task, mock }, use) => {
const loadTally = async (qrCodeData, mockFetch) => {
@ -357,6 +406,7 @@ const qrcodeReaderTallyTest = qrcodeReaderTest.extend({
await scan(qrCodeData)
await new Promise((resolve) => setTimeout(resolve))
fetch.mockReset()
}
await use(loadTally)
@ -422,6 +472,9 @@ qrcodeReaderTallyTest('qrcode reader show tally when request fails ', async ({mo
expect(items.classList.contains('error')).toBe(true)
expect(items.innerText.trim()).toBe('tally_network_error')
const closeButton = reader.querySelector('.qrcode-reader--close-popup-button')
closeButton.dispatchEvent(new Event('click'))
await loadTally(okCodeData, async (url, body) => {
return {
ok: false,
@ -433,3 +486,47 @@ qrcodeReaderTallyTest('qrcode reader show tally when request fails ', async ({mo
expect(items.innerText.trim()).toBe('tally_api_error')
})
qrcodeReaderTallyTest("qrcode reader doesn't refetch tally for the same certificate if popup is opened", async ({mock, loadTally}) => {
const { reader, scan } = mock
await loadTally(okCodeData, async (url, body) => {
return {
ok: true,
json: async () => ({'err': 0, 'data': {'stamps': {[body.events[0].certificate]: 'duplicate'}}})
}
})
let tallyStatus = reader.querySelector('.qrcode-reader--tally-status')
// loading the same certificate doesn't refeches metadata
await loadTally(okCodeData, async () => {
expect.unreachable()
})
expect(reader.querySelector('.qrcode-reader--tally-status')).toBe(tallyStatus)
// loading another certificate refetches tally status
await loadTally(certificateWithoutValidity, async (url, body) => {
return {
ok: true,
json: async () => ({'err': 0, 'data': {'stamps': {[body.events[0].certificate]: 'ok'}}})
}
})
expect(reader.querySelector('.qrcode-reader--tally-status')).not.toBe(tallyStatus)
tallyStatus = reader.querySelector('.qrcode-reader--tally-status')
const closeButton = reader.querySelector('.qrcode-reader--close-popup-button')
closeButton.dispatchEvent(new Event('click'))
// tally status is refetched for the same certificate after closing the popup
await loadTally(certificateWithoutValidity, async (url, body) => {
return {
ok: true,
json: async () => ({'err': 0, 'data': {'stamps': {[body.events[0].certificate]: 'ok'}}})
}
})
expect(reader.querySelector('.qrcode-reader--tally-status')).not.toBe(tallyStatus)
tallyStatus = reader.querySelector('.qrcode-reader--tally-status')
})