diff --git a/back/methods/collection/exchangeRateUpdate.js b/back/methods/collection/exchangeRateUpdate.js index b1272d73a8..3ad06b242b 100644 --- a/back/methods/collection/exchangeRateUpdate.js +++ b/back/methods/collection/exchangeRateUpdate.js @@ -17,8 +17,10 @@ module.exports = Self => { const response = await axios.get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml'); const xmlData = response.data; - const doc = new DOMParser().parseFromString(xmlData, 'text/xml'); - const cubes = doc.getElementsByTagName('Cube'); + const doc = new DOMParser({errorHandler: {warning: () => {}}})?.parseFromString(xmlData, 'text/xml'); + const cubes = doc?.getElementsByTagName('Cube'); + if (!cubes || cubes.length === 0) + throw new UserError('No cubes found. Exiting the method.'); const models = Self.app.models; @@ -27,7 +29,7 @@ module.exports = Self => { const maxDate = maxDateRecord?.dated ? new Date(maxDateRecord.dated) : null; for (const cube of Array.from(cubes)) { - if (cube.nodeType === 1 && cube.attributes.getNamedItem('time')) { + if (cube.nodeType === doc.ELEMENT_NODE && cube.attributes.getNamedItem('time')) { const xmlDate = new Date(cube.getAttribute('time')); const xmlDateWithoutTime = new Date(xmlDate.getFullYear(), xmlDate.getMonth(), xmlDate.getDate()); if (!maxDate || maxDate < xmlDateWithoutTime) { diff --git a/back/methods/collection/spec/exchangeRateUpdate.spec.js b/back/methods/collection/spec/exchangeRateUpdate.spec.js new file mode 100644 index 0000000000..7086c37a36 --- /dev/null +++ b/back/methods/collection/spec/exchangeRateUpdate.spec.js @@ -0,0 +1,52 @@ +describe('exchangeRateUpdate functionality', function() { + const axios = require('axios'); + const models = require('vn-loopback/server/server').models; + + beforeEach(function() { + spyOn(axios, 'get').and.returnValue(Promise.resolve({ + data: ` + + + + + ` + })); + }); + + it('should process XML data and update or create rates in the database', async function() { + spyOn(models.ReferenceRate, 'findOne').and.returnValue(Promise.resolve(null)); + spyOn(models.ReferenceRate, 'create').and.returnValue(Promise.resolve()); + + await models.Collection.exchangeRateUpdate(); + + expect(models.ReferenceRate.create).toHaveBeenCalledTimes(2); + }); + + it('should not create or update rates when no XML data is available', async function() { + axios.get.and.returnValue(Promise.resolve({})); + spyOn(models.ReferenceRate, 'create'); + + let thrownError = null; + try { + await models.Collection.exchangeRateUpdate(); + } catch (error) { + thrownError = error; + } + + expect(thrownError.message).toBe('No cubes found. Exiting the method.'); + }); + + it('should handle errors gracefully', async function() { + axios.get.and.returnValue(Promise.reject(new Error('Network error'))); + let error; + + try { + await models.Collection.exchangeRateUpdate(); + } catch (e) { + error = e; + } + + expect(error).toBeDefined(); + expect(error.message).toBe('Network error'); + }); +});