add timestamps to session model
This commit is contained in:
parent
80c65212ca
commit
5974e161a6
@ -36,6 +36,30 @@ export default class Session extends EventTarget {
|
|||||||
if (this.#id !== null)
|
if (this.#id !== null)
|
||||||
throw new Error("the ID cannot be changed if it has been set");
|
throw new Error("the ID cannot be changed if it has been set");
|
||||||
this.#id = value;
|
this.#id = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The time when this session was initially created. */
|
||||||
|
#created = new Date();
|
||||||
|
|
||||||
|
/** Get the time when this session was initially created. */
|
||||||
|
get created() {
|
||||||
|
return this.#created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The time when this session was last updated. */
|
||||||
|
#updated = new Date();
|
||||||
|
|
||||||
|
/** Get the time when this session was last updated. */
|
||||||
|
get updated() {
|
||||||
|
return this.#updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mark this session as changed.
|
||||||
|
*
|
||||||
|
* Triggers the `Session.EVENT_CHANGE` event and sets the update time.
|
||||||
|
*/
|
||||||
|
#changed() {
|
||||||
|
this.#updated = new Date();
|
||||||
this.dispatchEvent(new CustomEvent(Session.EVENT_CHANGE));
|
this.dispatchEvent(new CustomEvent(Session.EVENT_CHANGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +81,7 @@ export default class Session extends EventTarget {
|
|||||||
if (!Number.isInteger(value) || value < 1)
|
if (!Number.isInteger(value) || value < 1)
|
||||||
throw new RangeError("goal must be integer >= 1");
|
throw new RangeError("goal must be integer >= 1");
|
||||||
this.#goal = value;
|
this.#goal = value;
|
||||||
this.dispatchEvent(new CustomEvent(Session.EVENT_CHANGE));
|
this.#changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The name or members of the "we" team. */
|
/** The name or members of the "we" team. */
|
||||||
@ -71,7 +95,7 @@ export default class Session extends EventTarget {
|
|||||||
/** Set the name or members of the "we" team. */
|
/** Set the name or members of the "we" team. */
|
||||||
set ourTeam(value) {
|
set ourTeam(value) {
|
||||||
this.#ourTeam = value;
|
this.#ourTeam = value;
|
||||||
this.dispatchEvent(new CustomEvent(Session.EVENT_CHANGE));
|
this.#changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The name or members of the "they" team. */
|
/** The name or members of the "they" team. */
|
||||||
@ -85,7 +109,7 @@ export default class Session extends EventTarget {
|
|||||||
/** Set the name or members of the "they" team. */
|
/** Set the name or members of the "they" team. */
|
||||||
set theirTeam(value) {
|
set theirTeam(value) {
|
||||||
this.#theirTeam = value;
|
this.#theirTeam = value;
|
||||||
this.dispatchEvent(new CustomEvent(Session.EVENT_CHANGE));
|
this.#changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The finished games.
|
/** The finished games.
|
||||||
@ -117,7 +141,7 @@ export default class Session extends EventTarget {
|
|||||||
this.#currentGame = new Game(this.goal);
|
this.#currentGame = new Game(this.goal);
|
||||||
this.#currentGame.addEventListener(
|
this.#currentGame.addEventListener(
|
||||||
Game.EVENT_CHANGE, this.#boundHandleGameChange);
|
Game.EVENT_CHANGE, this.#boundHandleGameChange);
|
||||||
this.dispatchEvent(new CustomEvent(Session.EVENT_CHANGE));
|
this.#changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +173,7 @@ export default class Session extends EventTarget {
|
|||||||
this.#games.push(this.#currentGame);
|
this.#games.push(this.#currentGame);
|
||||||
this.#currentGame = null;
|
this.#currentGame = null;
|
||||||
}
|
}
|
||||||
this.dispatchEvent(new CustomEvent(Session.EVENT_CHANGE));
|
this.#changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** #handleGameChange, but bound to this instance. */
|
/** #handleGameChange, but bound to this instance. */
|
||||||
@ -186,6 +210,8 @@ export default class Session extends EventTarget {
|
|||||||
games: this.#games.map((g) => g.toStruct()),
|
games: this.#games.map((g) => g.toStruct()),
|
||||||
currentGame:
|
currentGame:
|
||||||
this.#currentGame !== null ? this.#currentGame.toStruct() : null,
|
this.#currentGame !== null ? this.#currentGame.toStruct() : null,
|
||||||
|
created: this.#created,
|
||||||
|
updated: this.#updated,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.#id !== null)
|
if (this.#id !== null)
|
||||||
@ -216,7 +242,7 @@ export default class Session extends EventTarget {
|
|||||||
|
|
||||||
if (typeof value.ourTeam !== "string")
|
if (typeof value.ourTeam !== "string")
|
||||||
throw new TypeError("struct must contain ourTeam as string");
|
throw new TypeError("struct must contain ourTeam as string");
|
||||||
this.ourTeam = value.ourTeam;
|
this.#ourTeam = value.ourTeam;
|
||||||
|
|
||||||
if (typeof value.theirTeam !== "string")
|
if (typeof value.theirTeam !== "string")
|
||||||
throw new TypeError("struct must contain theirTeam as string");
|
throw new TypeError("struct must contain theirTeam as string");
|
||||||
@ -240,5 +266,21 @@ export default class Session extends EventTarget {
|
|||||||
if (this.#currentGame.result.winner !== null)
|
if (this.#currentGame.result.winner !== null)
|
||||||
throw new Error("currentGame in struct must not be finished");
|
throw new Error("currentGame in struct must not be finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("created" in value) {
|
||||||
|
if (!(value.created instanceof Date))
|
||||||
|
throw new TypeError(
|
||||||
|
"if struct contains creation time, it must be a date");
|
||||||
|
this.#created = value.created;
|
||||||
|
} else
|
||||||
|
this.#created = new Date("2026-02-26T22:00:00");
|
||||||
|
|
||||||
|
if ("updated" in value) {
|
||||||
|
if (!(value.updated instanceof Date))
|
||||||
|
throw new TypeError(
|
||||||
|
"if struct contains update time, it must be a date");
|
||||||
|
this.#updated = value.updated;
|
||||||
|
} else
|
||||||
|
this.#updated = new Date("2026-02-26T22:00:00");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import Session from "/models/session.js";
|
|||||||
export default function() {
|
export default function() {
|
||||||
QUnit.module("session", function() {
|
QUnit.module("session", function() {
|
||||||
QUnit.test("initial state", function(assert) {
|
QUnit.test("initial state", function(assert) {
|
||||||
|
let now = new Date();
|
||||||
let session = new Session();
|
let session = new Session();
|
||||||
assert.strictEqual(session.goal, 11, "initial goal");
|
assert.strictEqual(session.goal, 11, "initial goal");
|
||||||
assert.strictEqual(session.games.length, 0, "no finished games");
|
assert.strictEqual(session.games.length, 0, "no finished games");
|
||||||
@ -17,6 +18,9 @@ export default function() {
|
|||||||
"initially no points");
|
"initially no points");
|
||||||
assert.strictEqual(session.ourTeam, "", "our team name");
|
assert.strictEqual(session.ourTeam, "", "our team name");
|
||||||
assert.strictEqual(session.theirTeam, "", "their team name");
|
assert.strictEqual(session.theirTeam, "", "their team name");
|
||||||
|
assert.true(session.created >= now, "was created after start");
|
||||||
|
assert.true(
|
||||||
|
session.created >= session.updated, "updated at or after creation");
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("invalid constructor", function(assert) {
|
QUnit.test("invalid constructor", function(assert) {
|
||||||
@ -49,6 +53,7 @@ export default function() {
|
|||||||
"small goal");
|
"small goal");
|
||||||
|
|
||||||
assert.verifySteps(["event"], "event happened once");
|
assert.verifySteps(["event"], "event happened once");
|
||||||
|
assert.true(session.updated >= session.created, "was updated");
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("start game", function(assert) {
|
QUnit.test("start game", function(assert) {
|
||||||
@ -131,6 +136,7 @@ export default function() {
|
|||||||
});
|
});
|
||||||
session.anotherGame();
|
session.anotherGame();
|
||||||
assert.verifySteps(["event"], "event was triggered");
|
assert.verifySteps(["event"], "event was triggered");
|
||||||
|
assert.true(session.updated >= session.created, "was updated");
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("game change triggers change event", function(assert) {
|
QUnit.test("game change triggers change event", function(assert) {
|
||||||
@ -141,6 +147,7 @@ export default function() {
|
|||||||
});
|
});
|
||||||
session.currentGame.currentRound.raise(Team.They);
|
session.currentGame.currentRound.raise(Team.They);
|
||||||
assert.verifySteps(["event"], "event was triggered");
|
assert.verifySteps(["event"], "event was triggered");
|
||||||
|
assert.true(session.updated >= session.created, "was updated");
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("setting ID", function(assert){
|
QUnit.test("setting ID", function(assert){
|
||||||
@ -152,7 +159,7 @@ export default function() {
|
|||||||
|
|
||||||
session.id = 18;
|
session.id = 18;
|
||||||
assert.strictEqual(session.id, 18, "correct id");
|
assert.strictEqual(session.id, 18, "correct id");
|
||||||
assert.verifySteps(["event"], "event happened");
|
assert.verifySteps([], "no event happened");
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("setting our team", function(assert){
|
QUnit.test("setting our team", function(assert){
|
||||||
@ -165,6 +172,7 @@ export default function() {
|
|||||||
session.ourTeam = "This is us!";
|
session.ourTeam = "This is us!";
|
||||||
assert.strictEqual(session.ourTeam, "This is us!", "correct ourTeam");
|
assert.strictEqual(session.ourTeam, "This is us!", "correct ourTeam");
|
||||||
assert.verifySteps(["event"], "event happened");
|
assert.verifySteps(["event"], "event happened");
|
||||||
|
assert.true(session.updated >= session.created, "was updated");
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("setting their team", function(assert){
|
QUnit.test("setting their team", function(assert){
|
||||||
@ -178,6 +186,7 @@ export default function() {
|
|||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
session.theirTeam, "This is them!", "correct theirTeam");
|
session.theirTeam, "This is them!", "correct theirTeam");
|
||||||
assert.verifySteps(["event"], "event happened");
|
assert.verifySteps(["event"], "event happened");
|
||||||
|
assert.true(session.updated >= session.created, "was updated");
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("toStruct - new session", function(assert) {
|
QUnit.test("toStruct - new session", function(assert) {
|
||||||
@ -190,6 +199,8 @@ export default function() {
|
|||||||
theirTeam: "",
|
theirTeam: "",
|
||||||
games: [],
|
games: [],
|
||||||
currentGame: null,
|
currentGame: null,
|
||||||
|
created: session.created,
|
||||||
|
updated: session.updated,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.deepEqual(struct, expected, "successfull structurizing");
|
assert.deepEqual(struct, expected, "successfull structurizing");
|
||||||
@ -219,7 +230,9 @@ export default function() {
|
|||||||
ourTeam: "This is us!",
|
ourTeam: "This is us!",
|
||||||
theirTeam: "This is them!",
|
theirTeam: "This is them!",
|
||||||
games: [ finished.toStruct() ],
|
games: [ finished.toStruct() ],
|
||||||
currentGame: unfinished.toStruct()
|
currentGame: unfinished.toStruct(),
|
||||||
|
created: session.created,
|
||||||
|
updated: session.updated,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.deepEqual(struct, expected, "successfull structurizing");
|
assert.deepEqual(struct, expected, "successfull structurizing");
|
||||||
@ -242,6 +255,8 @@ export default function() {
|
|||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
copy.currentGame, orig.currentGame, "no current games");
|
copy.currentGame, orig.currentGame, "no current games");
|
||||||
assert.deepEqual(copy.result, orig.result, "results match");
|
assert.deepEqual(copy.result, orig.result, "results match");
|
||||||
|
assert.strictEqual(copy.created, orig.created, "same creation time");
|
||||||
|
assert.strictEqual(copy.updated, orig.updated, "same update time");
|
||||||
|
|
||||||
orig.anotherGame();
|
orig.anotherGame();
|
||||||
orig.id = 15;
|
orig.id = 15;
|
||||||
@ -263,6 +278,8 @@ export default function() {
|
|||||||
orig.currentGame.toStruct(),
|
orig.currentGame.toStruct(),
|
||||||
"current game");
|
"current game");
|
||||||
assert.deepEqual(copy.result, orig.result, "results match");
|
assert.deepEqual(copy.result, orig.result, "results match");
|
||||||
|
assert.strictEqual(copy.created, orig.created, "same creation time");
|
||||||
|
assert.strictEqual(copy.updated, orig.updated, "same update time");
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("fromStruct - invalid", function(assert) {
|
QUnit.test("fromStruct - invalid", function(assert) {
|
||||||
@ -347,6 +364,17 @@ export default function() {
|
|||||||
new Error("currentGame in struct must not be finished"));
|
new Error("currentGame in struct must not be finished"));
|
||||||
struct.currentGame = unfinished.toStruct();
|
struct.currentGame = unfinished.toStruct();
|
||||||
|
|
||||||
|
struct.created = "2026-02-26T22:00:00";
|
||||||
|
doIt(
|
||||||
|
"string created",
|
||||||
|
new TypeError("if struct contains creation time, it must be a date"));
|
||||||
|
struct.created = new Date(struct.created);
|
||||||
|
struct.updated = "2026-02-26T22:00:00";
|
||||||
|
doIt(
|
||||||
|
"string updated",
|
||||||
|
new TypeError("if struct contains update time, it must be a date"));
|
||||||
|
struct.updated = new Date(struct.updated);
|
||||||
|
|
||||||
new Session(struct);
|
new Session(struct);
|
||||||
|
|
||||||
struct.games = [];
|
struct.games = [];
|
||||||
@ -386,6 +414,8 @@ export default function() {
|
|||||||
theirTeam: "",
|
theirTeam: "",
|
||||||
games: [],
|
games: [],
|
||||||
currentGame: null,
|
currentGame: null,
|
||||||
|
created: new Date("2026-02-26T22:00:00"),
|
||||||
|
updated: new Date("2026-02-26T22:00:00"),
|
||||||
};
|
};
|
||||||
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
||||||
});
|
});
|
||||||
@ -412,6 +442,8 @@ export default function() {
|
|||||||
theirTeam: "This is them!",
|
theirTeam: "This is them!",
|
||||||
games: [ finished.toStruct() ],
|
games: [ finished.toStruct() ],
|
||||||
currentGame: unfinished.toStruct(),
|
currentGame: unfinished.toStruct(),
|
||||||
|
created: new Date("2026-02-26T22:00:00"),
|
||||||
|
updated: new Date("2026-02-26T22:00:00"),
|
||||||
};
|
};
|
||||||
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
||||||
});
|
});
|
||||||
@ -434,6 +466,8 @@ export default function() {
|
|||||||
theirTeam: "",
|
theirTeam: "",
|
||||||
games: [],
|
games: [],
|
||||||
currentGame: null,
|
currentGame: null,
|
||||||
|
created: new Date("2026-02-26T22:00:00"),
|
||||||
|
updated: new Date("2026-02-26T22:00:00"),
|
||||||
};
|
};
|
||||||
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
||||||
});
|
});
|
||||||
@ -462,6 +496,66 @@ export default function() {
|
|||||||
theirTeam: "This is them!",
|
theirTeam: "This is them!",
|
||||||
games: [ finished.toStruct() ],
|
games: [ finished.toStruct() ],
|
||||||
currentGame: unfinished.toStruct(),
|
currentGame: unfinished.toStruct(),
|
||||||
|
created: new Date("2026-02-26T22:00:00"),
|
||||||
|
updated: new Date("2026-02-26T22:00:00"),
|
||||||
|
};
|
||||||
|
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("fromStruct - v3 - new session", function(assert) {
|
||||||
|
let struct = {
|
||||||
|
id: 23,
|
||||||
|
goal: 3,
|
||||||
|
ourTeam: "",
|
||||||
|
theirTeam: "",
|
||||||
|
games: [],
|
||||||
|
currentGame: null,
|
||||||
|
created: new Date("2026-02-26T20:05:00"),
|
||||||
|
updated: new Date("2026-02-26T20:05:00"),
|
||||||
|
};
|
||||||
|
let session = new Session(struct);
|
||||||
|
|
||||||
|
let expected = {
|
||||||
|
id: 23,
|
||||||
|
goal: 3,
|
||||||
|
ourTeam: "",
|
||||||
|
theirTeam: "",
|
||||||
|
games: [],
|
||||||
|
currentGame: null,
|
||||||
|
created: new Date("2026-02-26T20:05:00"),
|
||||||
|
updated: new Date("2026-02-26T20:05:00"),
|
||||||
|
};
|
||||||
|
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("fromStruct - v3 - finished & unfinished", function(assert) {
|
||||||
|
let finished = new Game(3);
|
||||||
|
finished.currentRound.raise(Team.We);
|
||||||
|
finished.currentRound.winner = Team.They;
|
||||||
|
let unfinished = new Game(3);
|
||||||
|
unfinished.currentRound.winner = Team.We;
|
||||||
|
|
||||||
|
let struct = {
|
||||||
|
id: 17,
|
||||||
|
goal: 3,
|
||||||
|
ourTeam: "This is us!",
|
||||||
|
theirTeam: "This is them!",
|
||||||
|
games: [ finished.toStruct() ],
|
||||||
|
currentGame: unfinished.toStruct(),
|
||||||
|
created: new Date("2026-02-26T20:05:00"),
|
||||||
|
updated: new Date("2026-02-26T20:05:00"),
|
||||||
|
};
|
||||||
|
let session = new Session(struct);
|
||||||
|
|
||||||
|
let expected = {
|
||||||
|
id: 17,
|
||||||
|
goal: 3,
|
||||||
|
ourTeam: "This is us!",
|
||||||
|
theirTeam: "This is them!",
|
||||||
|
games: [ finished.toStruct() ],
|
||||||
|
currentGame: unfinished.toStruct(),
|
||||||
|
created: new Date("2026-02-26T20:05:00"),
|
||||||
|
updated: new Date("2026-02-26T20:05:00"),
|
||||||
};
|
};
|
||||||
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
assert.deepEqual(session.toStruct(), expected, "reexport matches");
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user