From b4134bd4a180603617592b2f949f491295ad951b Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 8 Sep 2022 16:59:58 +0200 Subject: [PATCH 1/4] Fix DateTime with ZoneId for years between 00-99 The error was happening because Date.UTC factory doesn't treats dates between 00-99 as 1900-1999. Removing the usage of this factory makes the code slighty faster while resolves the issue. --- .../bolt-protocol-v5x0.utc.transformer.js | 13 ++----- .../test/bolt/bolt-protocol-v4x3.test.js | 4 ++ .../test/bolt/bolt-protocol-v4x4.test.js | 4 ++ .../test/bolt/bolt-protocol-v5x0.test.js | 4 ++ .../neo4j-driver/test/temporal-types.test.js | 38 +++++++++++++++++-- 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/packages/bolt-connection/src/bolt/bolt-protocol-v5x0.utc.transformer.js b/packages/bolt-connection/src/bolt/bolt-protocol-v5x0.utc.transformer.js index 905b77ef0..6ae4a77dc 100644 --- a/packages/bolt-connection/src/bolt/bolt-protocol-v5x0.utc.transformer.js +++ b/packages/bolt-connection/src/bolt/bolt-protocol-v5x0.utc.transformer.js @@ -172,15 +172,10 @@ function getTimeInZoneId (timeZoneId, epochSecond, nano) { era: 'narrow' }) - const l = epochSecondAndNanoToLocalDateTime(epochSecond, nano) - const utc = Date.UTC( - int(l.year).toNumber(), - int(l.month).toNumber() - 1, - int(l.day).toNumber(), - int(l.hour).toNumber(), - int(l.minute).toNumber(), - int(l.second).toNumber() - ) + const utc = int(epochSecond) + .multiply(1000) + .add(int(nano).div(1_000_000)) + .toNumber() const formattedUtcParts = formatter.formatToParts(utc) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v4x3.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v4x3.test.js index 9ca0e71ac..ffdbb33d6 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v4x3.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v4x3.test.js @@ -813,6 +813,10 @@ describe('#unit BoltProtocolV4x3', () => { [ 'DateWithWithZoneId / Min Date', new DateTime(-99_999, 12, 31, 23, 59, 59, 999_999_999, undefined, 'Pacific/Samoa') + ], + [ + 'DateWithWithZoneId / Ambiguous date between 00 and 99', + new DateTime(50, 12, 31, 23, 59, 59, 999_999_999, undefined, 'Pacific/Samoa') ] ])('should pack and unpack DateTimeWithZoneId and without offset (%s)', (_, object) => { const packable = protocol.packable(object) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v4x4.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v4x4.test.js index 0a0bcc27a..53c6f26a3 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v4x4.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v4x4.test.js @@ -846,6 +846,10 @@ describe('#unit BoltProtocolV4x4', () => { [ 'DateWithWithZoneId / Min Date', new DateTime(-99_999, 12, 31, 23, 59, 59, 999_999_999, undefined, 'Pacific/Samoa') + ], + [ + 'DateWithWithZoneId / Ambiguous date between 00 and 99', + new DateTime(50, 12, 31, 23, 59, 59, 999_999_999, undefined, 'Pacific/Samoa') ] ])('should pack and unpack DateTimeWithZoneId and without offset (%s)', (_, object) => { const packable = protocol.packable(object) diff --git a/packages/bolt-connection/test/bolt/bolt-protocol-v5x0.test.js b/packages/bolt-connection/test/bolt/bolt-protocol-v5x0.test.js index 9d61d7c77..0d4ce7c1b 100644 --- a/packages/bolt-connection/test/bolt/bolt-protocol-v5x0.test.js +++ b/packages/bolt-connection/test/bolt/bolt-protocol-v5x0.test.js @@ -539,6 +539,10 @@ describe('#unit BoltProtocolV5x0', () => { [ 'DateWithWithZoneId / Min Date', new DateTime(-99_999, 12, 31, 23, 59, 59, 999_999_999, undefined, 'Pacific/Samoa') + ], + [ + 'DateWithWithZoneId / Ambiguous date between 00 and 99', + new DateTime(50, 12, 31, 23, 59, 59, 999_999_999, undefined, 'Pacific/Samoa') ] ])('should pack and unpack DateTimeWithZoneId and without offset (%s)', (_, object) => { const buffer = alloc(256) diff --git a/packages/neo4j-driver/test/temporal-types.test.js b/packages/neo4j-driver/test/temporal-types.test.js index 6840fbc39..240799259 100644 --- a/packages/neo4j-driver/test/temporal-types.test.js +++ b/packages/neo4j-driver/test/temporal-types.test.js @@ -1439,7 +1439,24 @@ describe('#integration temporal-types', () => { expect(records.length).toEqual(1) const value = records[0].get(0) - expect(value).toEqual(expectedValue) + + if ( + expectedValue.timeZoneId != null && + value.timeZoneOffsetSeconds != null && + neo4j.isDateTime(value) && + neo4j.isDateTime(expectedValue)) { + expect(value).toEqual(jasmine.objectContaining({ + year: expectedValue.year, + month: expectedValue.month, + day: expectedValue.day, + hour: expectedValue.hour, + second: expectedValue.second, + nanosecond: expectedValue.nanosecond, + timeZoneId: expectedValue.timeZoneId + })) + } else { + expect(value).toEqual(expectedValue) + } } finally { await session.close() } @@ -1457,10 +1474,23 @@ describe('#integration temporal-types', () => { const receivedValue = records[0].get(0) // Amend test to ignore timeZoneOffsetInSeconds returned by the // new servers in ZonedDateTime with the utc fix - if (value.timeZoneId != null && receivedValue.timeZoneOffsetSeconds != null) { - receivedValue.timeZoneOffsetInSeconds = undefined + if ( + value.timeZoneId != null && + receivedValue.timeZoneOffsetSeconds != null && + neo4j.isDateTime(value) && + neo4j.isDateTime(receivedValue)) { + expect(receivedValue).toEqual(jasmine.objectContaining({ + year: value.year, + month: value.month, + day: value.day, + hour: value.hour, + second: value.second, + nanosecond: value.nanosecond, + timeZoneId: value.timeZoneId + })) + } else { + expect(receivedValue).toEqual(value) } - expect(receivedValue).toEqual(value) } async function testDurationToString (values) { From c071df93b78142807cb8508ce8d35f6b2bbff46e Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 8 Sep 2022 19:44:24 +0200 Subject: [PATCH 2/4] Fix wrong port --- packages/neo4j-driver/test/examples.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/neo4j-driver/test/examples.test.js b/packages/neo4j-driver/test/examples.test.js index 27b4d420c..62e335751 100644 --- a/packages/neo4j-driver/test/examples.test.js +++ b/packages/neo4j-driver/test/examples.test.js @@ -708,7 +708,7 @@ describe('#integration examples', () => { it('service unavailable example', done => { const console = consoleOverride const consoleLoggedMsg = consoleOverridePromise - const uri = `bolt://${sharedNeo4j.hostname}:7688` // wrong port + const uri = `bolt://${sharedNeo4j.hostname}:7686` // wrong port const password = 'wrongPassword' // tag::service-unavailable[] From 3ee171c9389374fd8efef881ca8425879a9eb9d2 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Fri, 9 Sep 2022 11:24:51 +0200 Subject: [PATCH 3/4] Addressing comments in the pr --- .../src/bolt/bolt-protocol-v5x0.utc.transformer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bolt-connection/src/bolt/bolt-protocol-v5x0.utc.transformer.js b/packages/bolt-connection/src/bolt/bolt-protocol-v5x0.utc.transformer.js index 6ae4a77dc..99acd0994 100644 --- a/packages/bolt-connection/src/bolt/bolt-protocol-v5x0.utc.transformer.js +++ b/packages/bolt-connection/src/bolt/bolt-protocol-v5x0.utc.transformer.js @@ -182,7 +182,7 @@ function getTimeInZoneId (timeZoneId, epochSecond, nano) { const localDateTime = formattedUtcParts.reduce((obj, currentValue) => { if (currentValue.type === 'era') { obj.adjustEra = - currentValue.value.toLocaleUpperCase() === 'B' + currentValue.value.toUpperCase() === 'B' ? year => year.subtract(1).negate() // 1BC equals to year 0 in astronomical year numbering : identity } else if (currentValue.type !== 'literal') { From b57c6580b1b46b13461bdfcc184471be580cf819 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Fri, 9 Sep 2022 13:27:38 +0200 Subject: [PATCH 4/4] Move TransactionExecutor test to run along with unit tests --- .../neo4j-driver/test/internal/transaction-executor.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/neo4j-driver/test/internal/transaction-executor.test.js b/packages/neo4j-driver/test/internal/transaction-executor.test.js index 1d4b0ea2c..98a40690a 100644 --- a/packages/neo4j-driver/test/internal/transaction-executor.test.js +++ b/packages/neo4j-driver/test/internal/transaction-executor.test.js @@ -35,8 +35,7 @@ const LOCKS_TERMINATED_ERROR = 'Neo.TransientError.Transaction.LockClientStopped' const OOM_ERROR = 'Neo.DatabaseError.General.OutOfMemoryError' -// Not exactly integration tests but annoyingly slow for being a unit tests. -describe('#integration TransactionExecutor', () => { +describe('#unit TransactionExecutor', () => { it('should retry until database error happens', async () => { await testNoRetryOnUnknownError( [