Ignore updatedAt timestamp when comparing entities
All checks were successful
/ build (push) Successful in 1m28s
/ deploy (push) Successful in 16s

To determine if the entity received from the server is the same as the
entity the client has the equals method is use.  To avoid problems with
clients that have incorrect clocks the timestamp is overriden with the
server's time when the entities are saved on the server.

This means that the entities received back from the server when the
client saves will have different timestamps than what the client set.
Ignore the updatedAt timestamp when comparing entities for equality so
that the update logic correctly replaces entities that only differ by
the update timestamp.
This commit is contained in:
Hornwitser 2025-06-13 21:06:48 +02:00
parent 8c63c1cfbb
commit fad1bb2482
2 changed files with 14 additions and 12 deletions

View file

@ -6,6 +6,7 @@ import { DateTime, FixedOffsetZone } from "~/shared/utils/luxon";
const locale = "en-GB";
const now = DateTime.now().setLocale(locale);
const later = now.plus({ minutes: 2 });
const zone = now.zone;
const nowIso = now.setZone(FixedOffsetZone.utcInstance).toISO();
@ -172,19 +173,24 @@ describe("class ClientSchedule", () => {
];
for (const pattern of updatePatterns) {
test(`apply diff pattern ${pattern}`, () => {
const fixture: Record<string, ClientScheduleLocation> = {
const fixtureClient: Record<string, ClientScheduleLocation> = {
a: new ClientScheduleLocation(1, now, false, "A", ""),
b: new ClientScheduleLocation(1, now, false, "B", ""),
x: new ClientScheduleLocation(1, now, true, "X", ""),
};
const fixtureServer: Record<string, ClientScheduleLocation> = {
a: new ClientScheduleLocation(1, later, false, "A", ""),
b: new ClientScheduleLocation(1, later, false, "B", ""),
x: new ClientScheduleLocation(1, later, true, "X", ""),
};
const schedule = new ClientSchedule(111, now, false, new Map(), new Map(), new Map(), new Map());
if (fixture[pattern[0]])
schedule.originalLocations.set(1, fixture[pattern[0]]);
if (fixture[pattern[1]])
schedule.locations.set(1, fixture[pattern[1]]);
const update = fixture[pattern[3]];
const expectedOriginalLocation = pattern[5] === "x" ? undefined : fixture[pattern[5]];
const expectedLocation = fixture[pattern[6]];
if (fixtureClient[pattern[0]])
schedule.originalLocations.set(1, fixtureClient[pattern[0]]);
if (fixtureClient[pattern[1]])
schedule.locations.set(1, fixtureClient[pattern[1]]);
const update = fixtureServer[pattern[3]];
const expectedOriginalLocation = pattern[5] === "x" ? undefined : fixtureServer[pattern[5]];
const expectedLocation = pattern[5] === pattern[6] ? fixtureServer[pattern[6]] : fixtureClient[pattern[6]];
schedule.applyUpdate({
id: 111,

View file

@ -62,7 +62,6 @@ export class ClientScheduleLocation extends ClientEntity {
equals(other: ClientScheduleLocation) {
return (
this.id === other.id
&& this.updatedAt.toMillis() === other.updatedAt.toMillis()
&& this.deleted === other.deleted
&& this.name === other.name
&& this.description === other.description
@ -130,7 +129,6 @@ export class ClientScheduleEvent extends ClientEntity {
equals(other: ClientScheduleEvent) {
return (
this.id === other.id
&& this.updatedAt.toMillis() === other.updatedAt.toMillis()
&& this.deleted === other.deleted
&& this.name === other.name
&& this.crew === other.crew
@ -267,7 +265,6 @@ export class ClientScheduleRole extends ClientEntity {
equals(other: ClientScheduleRole) {
return (
this.id === other.id
&& this.updatedAt.toMillis() === other.updatedAt.toMillis()
&& this.deleted === other.deleted
&& this.name === other.name
&& this.description === other.description
@ -329,7 +326,6 @@ export class ClientScheduleShift extends ClientEntity {
equals(other: ClientScheduleShift) {
return (
this.id === other.id
&& this.updatedAt.toMillis() === other.updatedAt.toMillis()
&& this.deleted === other.deleted
&& this.role.id === other.role.id
&& this.name === other.name