describe('exchangeRateUpdate functionality', function() { const axios = require('axios'); const models = require('vn-loopback/server/server').models; let tx; let options; function formatYmd(d) { const mm = (d.getMonth() + 1).toString().padStart(2, '0'); const dd = d.getDate().toString().padStart(2, '0'); return `${d.getFullYear()}-${mm}-${dd}`; } afterEach(async() => { await tx.rollback(); }); beforeEach(async() => { tx = await models.Sale.beginTransaction({}); options = {transaction: tx}; spyOn(axios, 'get').and.returnValue(Promise.resolve({data: ''})); }); it('should process XML data and create rates', async function() { const d1 = Date.vnNew(); const d4 = Date.vnNew(); d4.setDate(d4.getDate() + 1); const xml = ` `; axios.get.and.returnValue(Promise.resolve({data: xml})); spyOn(models.ReferenceRate, 'findOne').and.returnValue(Promise.resolve(null)); spyOn(models.ReferenceRate, 'create').and.returnValue(Promise.resolve()); await models.InvoiceIn.exchangeRateUpdate(options); expect(models.ReferenceRate.create).toHaveBeenCalledTimes(3); }); it('should handle no data', async function() { axios.get.and.returnValue(Promise.resolve({})); spyOn(models.ReferenceRate, 'create'); let e; try { await models.InvoiceIn.exchangeRateUpdate(options); } catch (err) { e = err; } expect(e.message).toBe('No cubes found. Exiting the method.'); expect(models.ReferenceRate.create).not.toHaveBeenCalled(); }); it('should handle errors', async function() { axios.get.and.returnValue(Promise.reject(new Error('Network error'))); let e; try { await models.InvoiceIn.exchangeRateUpdate(options); } catch (err) { e = err; } expect(e).toBeDefined(); expect(e.message).toBe('Network error'); }); it('should update existing rate', async function() { const existingRate = await models.ReferenceRate.findOne({ order: 'id DESC' }, options); if (!existingRate) return fail('No ReferenceRate records in DB'); const currency = await models.Currency.findById(existingRate.currencyFk, null, options); const xml = ` `; axios.get.and.returnValue(Promise.resolve({data: xml})); await models.InvoiceIn.exchangeRateUpdate(options); const updatedRate = await models.ReferenceRate.findById(existingRate.id, null, options); expect(updatedRate.value).toBeCloseTo('2.22'); }); it('should not update if same rate', async function() { const existingRate = await models.ReferenceRate.findOne({order: 'id DESC'}, options); if (!existingRate) return fail('No existing ReferenceRate in DB'); const currency = await models.Currency.findById(existingRate.currencyFk, null, options); const oldValue = existingRate.value; const xml = ` `; axios.get.and.returnValue(Promise.resolve({data: xml})); await models.InvoiceIn.exchangeRateUpdate(options); const updatedRate = await models.ReferenceRate.findById(existingRate.id, null, options); expect(updatedRate.value).toBe(oldValue); }); it('should backfill missing dates', async function() { const lastRate = await models.ReferenceRate.findOne({order: 'dated DESC'}, options); if (!lastRate) return fail('No existing ReferenceRate data in DB'); const currency = await models.Currency.findById(lastRate.currencyFk, null, options); const d1 = new Date(lastRate.dated); d1.setDate(d1.getDate() + 1); const d4 = new Date(lastRate.dated); d4.setDate(d4.getDate() + 4); const xml = ` `; axios.get.and.returnValue(Promise.resolve({data: xml})); const beforeCount = await models.ReferenceRate.count({}, options); await models.InvoiceIn.exchangeRateUpdate(options); const afterCount = await models.ReferenceRate.count({}, options); expect(afterCount - beforeCount).toBe(4); }); });