diff --git a/package.json b/package.json index d97b887c..f661cec8 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,9 @@ "fiori": { "wrap_multiple_errors": false }, + "features": { + "ieee754compatible": true + }, "build": { "[node!]": { "target": "gen", @@ -122,4 +125,4 @@ "app/travel_processor", "app/travel_analytics" ] -} \ No newline at end of file +} diff --git a/test/odata.test.js b/test/odata.test.js index f1c7562c..6a7b1946 100644 --- a/test/odata.test.js +++ b/test/odata.test.js @@ -3,6 +3,7 @@ const { GET, POST, PATCH, axios, expect } = cds.test(__dirname+'/..') const EDIT = (url) => POST (url+'/TravelService.draftEdit',{}) const SAVE = (url) => POST (url+'/TravelService.draftActivate') axios.defaults.headers['content-type'] = 'application/json;IEEE754Compatible=true' // REVISIT: can be removed when @sap/cds 5.1.5 is released? +axios.defaults.headers.accept = 'application/json;IEEE754Compatible=true' //> for cds^7; decimals and int64s as strings with cds^8 to ensure precision axios.defaults.auth = { username: 'alice', password: 'admin' } describe ("Basic Querying", () => { @@ -43,7 +44,7 @@ describe ("Basic Querying", () => { describe('Basic OData', () => { it('serves $metadata documents in v4', async () => { - const { headers, status, data } = await GET `/processor/$metadata` + const { headers, status, data } = await GET(`/processor/$metadata`, { headers: { accept: 'application/xml' } }) expect(status).to.equal(200) expect(headers).to.contain({ // 'content-type': 'application/xml', //> fails with 'application/xml;charset=utf-8', which is set by express @@ -58,7 +59,7 @@ describe('Basic OData', () => { const { data } = await GET(`/processor/Travel?$filter=TravelUUID eq '00667221A8E4645C17002DF03754AB66'`) expect(data.value).to.containSubset([{ BeginDate: '2023-08-02', - BookingFee: 60, + BookingFee: '60.000', createdAt: expectedValue => /2023-07-16T18:42:07\.000(0000)?Z/.test(expectedValue), // timestamp precision increase with cds^7 createdBy: 'Hansmann', CurrencyCode_code: 'SGD', @@ -71,7 +72,7 @@ describe('Basic OData', () => { LastChangedBy: 'Deichgraeber', to_Agency_AgencyID: '070029', to_Customer_CustomerID: '000318', - TotalPrice: 23439, + TotalPrice: '23439.000', TravelID: 175, TravelStatus_code: 'A', TravelUUID: '00667221A8E4645C17002DF03754AB66' @@ -100,7 +101,7 @@ describe('Basic OData', () => { }) it('supports $value requests', async () => { - const { data } = await GET `/processor/Travel(TravelUUID='52657221A8E4645C17002DF03754AB66',IsActiveEntity=true)/to_Customer/LastName/$value` + const { data } = await GET(`/processor/Travel(TravelUUID='52657221A8E4645C17002DF03754AB66',IsActiveEntity=true)/to_Customer/LastName/$value`, { headers: { accept: 'text/plain' } }) expect(data).to.equal('Prinz') }) @@ -134,7 +135,7 @@ describe('Basic OData', () => { }) const { data: newTravel } = await SAVE (`/processor/Travel(TravelUUID='${newDraft.TravelUUID}',IsActiveEntity=false)`) - expect(newTravel).to.contain({ TravelID: 4134, TotalPrice: 11 }) + expect(newTravel).to.contain({ TravelID: 4134, TotalPrice: '11.000' }) }) it ('re-calculates totals after booking fee changed', async ()=>{ @@ -144,10 +145,7 @@ describe('Basic OData', () => { let Supplement = `/processor/BookingSupplement(BookSupplUUID='85D87221A8E4645C17002DF03754AB66',IsActiveEntity=false)` let { data:draft } = await EDIT (Travel4133) - expect(draft).to.containSubset({ - TotalPrice: 7375, - TravelID: 4133, - }) + expect(draft).to.containSubset({ TravelID: 4133, TotalPrice: '7375.000' }) // Ensure it is not in accepted state as that would disallow changing await POST (Draft +`/TravelService.rejectTravel`) @@ -155,19 +153,19 @@ describe('Basic OData', () => { // Change the Travel's Booking Fee await PATCH (Draft, { BookingFee: '120' }) - await expect_totals (7475) + await expect_totals ('7475.000') // Change a Booking's Flight Price await PATCH (Booking, { FlightPrice: '1657' }) - await expect_totals (5475) + await expect_totals ('5475.000') // Change a Supplements's Price await PATCH (Supplement, { Price: '220' }) - await expect_totals (5675) + await expect_totals ('5675.000') // Save Draft await SAVE (Draft) - await expect_totals (5675, 'IsActiveEntity=true') + await expect_totals ('5675.000', 'IsActiveEntity=true') async function expect_totals (expected, _active = 'IsActiveEntity=false') { let { data: { TotalPrice } } = await GET (`/processor/Travel(TravelUUID='76757221A8E4645C17002DF03754AB66',${_active})? @@ -179,26 +177,26 @@ describe('Basic OData', () => { it('deduct discount multiple times does not end up in error', async () => { const { data: res1 } = await GET `/processor/Travel(TravelUUID='52657221A8E4645C17002DF03754AB66',IsActiveEntity=true)` - expect(res1).to.contain({ TotalPrice: 900, BookingFee: 20 }) + expect(res1).to.contain({ TotalPrice: '900.000', BookingFee: '20.000' }) const { data: res2 } = await POST( `/processor/Travel(TravelUUID='52657221A8E4645C17002DF03754AB66',IsActiveEntity=true)/TravelService.deductDiscount`, { percent: 11 } ) - expect(res2).to.contain({ TotalPrice: 897.8, BookingFee: 17.8 }) + expect(res2).to.contain({ TotalPrice: '897.800', BookingFee: '17.800' }) const { data: res3 } = await POST( `/processor/Travel(TravelUUID='52657221A8E4645C17002DF03754AB66',IsActiveEntity=true)/TravelService.deductDiscount`, { percent: 11 } ) - expect(res3).to.contain({ TotalPrice: 895.842, BookingFee: 15.842 }) + expect(res3).to.contain({ TotalPrice: '895.842', BookingFee: '15.842' }) const { data: res4 } = await POST( `/processor/Travel(TravelUUID='52657221A8E4645C17002DF03754AB66',IsActiveEntity=true)/TravelService.deductDiscount`, { percent: 11 } ) // rounded to 3 decimals - expect(res4).to.contain({ TotalPrice: 894.099, BookingFee: 14.099 }) + expect(res4).to.contain({ TotalPrice: '894.099', BookingFee: '14.099' }) }) it('allows deducting discounts on drafts as well', async ()=>{ @@ -206,10 +204,10 @@ describe('Basic OData', () => { const Draft = `/processor/Travel(TravelUUID='93657221A8E4645C17002DF03754AB66',IsActiveEntity=false)` const { data:res0 } = await GET (Active) - expect(res0).to.contain({ TravelID:66, TotalPrice: 729, BookingFee: 10 }) + expect(res0).to.contain({ TravelID: 66, TotalPrice: '729.000', BookingFee: '10.000' }) const { data:res1 } = await EDIT (Active) - expect(res1).to.contain({ TotalPrice: 729, BookingFee: 10 }) + expect(res1).to.contain({ TotalPrice: '729.000', BookingFee: '10.000' }) // Change the Travel's dates to avoid validation errors const today = new Date().toISOString().split('T')[0] @@ -218,15 +216,15 @@ describe('Basic OData', () => { await PATCH (Draft, { EndDate: tomorrow }) const { data:res2 } = await POST (`${Draft}/TravelService.deductDiscount`, { percent: 50 }) - expect(res2).to.contain({ TotalPrice: 724, BookingFee: 5 }) + expect(res2).to.contain({ TotalPrice: '724.000', BookingFee: '5.000' }) const { data:res3 } = await GET (Draft) - expect(res3).to.contain({ TotalPrice: 724, BookingFee: 5 }) + expect(res3).to.contain({ TotalPrice: '724.000', BookingFee: '5.000' }) await SAVE (Draft) const { data:res4 } = await GET (Active) - expect(res4).to.contain({ TotalPrice: 724, BookingFee: 5 }) + expect(res4).to.contain({ TotalPrice: '724.000', BookingFee: '5.000' }) }) })