-
Notifications
You must be signed in to change notification settings - Fork 1
added Meeting object - for review #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| export * from "./acp/mod.js" | ||
| export * from "./solid/mod.js" | ||
| export * from "./webid/mod.js" | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,52 @@ | ||||||||||||||||||||||
| import { TermMappings, ValueMappings, TermWrapper, DatasetWrapper } from "rdfjs-wrapper" | ||||||||||||||||||||||
| import { ICAL } from "../vocabulary/mod.js" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export class MeetingDataset extends DatasetWrapper { | ||||||||||||||||||||||
|
Comment on lines
+2
to
+5
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
| get meeting(): Iterable<Meeting> { | ||||||||||||||||||||||
| return this.instancesOf(ICAL.vevent, Meeting) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+5
to
+9
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should live in its own file: Also, fix capitalisation (reflects further review comments):
Suggested change
It would be interesting to add a link to ical to justify why we use classification based selection (no properties used in the context of this "shape" actually has only domain Vevent: https://www.w3.org/2002/12/cal/ical.n3). And maybe consider actually using a union pattern with subjectof the various used properties (because in this context, we might only use the properties for Vevents). Example:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Corollary: If See https://github.com/solid/object/blob/main/src/acp/Typed.ts for a pattern for working with type statements. |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export class Meeting extends TermWrapper { | ||||||||||||||||||||||
| get summary(): string | undefined { | ||||||||||||||||||||||
| return this.singularNullable(ICAL.summary, ValueMappings.literalToString) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| set summary(value: string | undefined) { | ||||||||||||||||||||||
| this.overwriteNullable(ICAL.summary, value, TermMappings.stringToLiteral) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| get location(): string | undefined { | ||||||||||||||||||||||
| return this.singularNullable(ICAL.location, ValueMappings.literalToString) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| set location(value: string | undefined) { | ||||||||||||||||||||||
| this.overwriteNullable(ICAL.location, value, TermMappings.stringToLiteral) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| get comment(): string | undefined { | ||||||||||||||||||||||
| return this.singularNullable(ICAL.comment, ValueMappings.literalToString) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| set comment(value: string | undefined) { | ||||||||||||||||||||||
| this.overwriteNullable(ICAL.comment, value, TermMappings.stringToLiteral) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| get startDate(): Date | undefined { | ||||||||||||||||||||||
| return this.singularNullable(ICAL.dtstart, ValueMappings.literalToDate) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| set startDate(value: Date | undefined) { | ||||||||||||||||||||||
| this.overwriteNullable(ICAL.dtstart, value, TermMappings.dateToLiteral) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| get endDate(): Date | undefined { | ||||||||||||||||||||||
| return this.singularNullable(ICAL.dtend, ValueMappings.literalToDate) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| set endDate(value: Date | undefined) { | ||||||||||||||||||||||
| this.overwriteNullable(ICAL.dtend, value, TermMappings.dateToLiteral) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+50
to
+52
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,4 @@ | ||||||||
| export * from "./Container.js" | ||||||||
| export * from "./ContainerDataset.js" | ||||||||
| export * from "./Resource.js" | ||||||||
| export * from "./Meeting.js" | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,4 +4,5 @@ export const ICAL = { | |||||
| dtstart: "http://www.w3.org/2002/12/cal/ical#dtstart", | ||||||
| location: "http://www.w3.org/2002/12/cal/ical#location", | ||||||
| summary: "http://www.w3.org/2002/12/cal/ical#summary", | ||||||
| vevent: "http://www.w3.org/2002/12/cal/ical#Vevent" | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| } as const; | ||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,3 +8,4 @@ export * from "./rdf.js" | |||||||
| export * from "./rdfs.js" | ||||||||
| export * from "./solid.js" | ||||||||
| export * from "./vcard.js" | ||||||||
| export * from "./ical.js" | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that it would be worth considering a test pattern for mutations where
This is more robust in a way because it does not rely on ther wrappers for reading out values modified by the wrapper itself. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,145 @@ | ||||||||||||||||||||||||||||
| import { DataFactory, Parser, Store } from "n3" | ||||||||||||||||||||||||||||
| import assert from "node:assert" | ||||||||||||||||||||||||||||
| import { describe, it } from "node:test" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import { MeetingDataset } from "@solid/object"; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| describe("MeetingDataset / Meeting tests", () => { | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const sampleRDF = ` | ||||||||||||||||||||||||||||
|
Comment on lines
+3
to
+10
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
| @prefix cal: <http://www.w3.org/2002/12/cal/ical#> . | ||||||||||||||||||||||||||||
| @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . | ||||||||||||||||||||||||||||
| <https://example.org/meeting/1> a cal:Vevent ; | ||||||||||||||||||||||||||||
| cal:summary "Team Sync" ; | ||||||||||||||||||||||||||||
| cal:location "Zoom Room 123" ; | ||||||||||||||||||||||||||||
| cal:comment "Discuss project updates" ; | ||||||||||||||||||||||||||||
| cal:dtstart "2026-02-09T10:00:00Z"^^xsd:dateTime ; | ||||||||||||||||||||||||||||
| cal:dtend "2026-02-09T11:00:00Z"^^xsd:dateTime . | ||||||||||||||||||||||||||||
|
Comment on lines
+14
to
+20
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know that is what corresponds to the current shape in the pane. However, could you find a few slightly more comprehensive ical events examples so that we create a class that might be a bit more usable? I wonder if we can get at least the properties corresponding to the main fields in all well known calendar systems. See maybe RFC5545 section 4 for examples. |
||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| it("should parse and retrieve meeting properties", () => { | ||||||||||||||||||||||||||||
| const store = new Store(); | ||||||||||||||||||||||||||||
| store.addQuads(new Parser().parse(sampleRDF)); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const dataset = new MeetingDataset(store, DataFactory); | ||||||||||||||||||||||||||||
| const meetings = Array.from(dataset.meeting); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const meeting = meetings[0]; | ||||||||||||||||||||||||||||
| assert.ok(meeting, "No meeting found") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Check property types and values | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.equal(meeting.summary, "Team Sync"); | ||||||||||||||||||||||||||||
|
Comment on lines
+33
to
+35
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
| assert.equal(meeting.location, "Zoom Room 123"); | ||||||||||||||||||||||||||||
| assert.equal(meeting.comment, "Discuss project updates"); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.ok(meeting.startDate instanceof Date); | ||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+40
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
| assert.ok(meeting.endDate instanceof Date); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.equal(meeting.startDate?.toISOString(), "2026-02-09T10:00:00.000Z"); | ||||||||||||||||||||||||||||
| assert.equal(meeting.endDate?.toISOString(), "2026-02-09T11:00:00.000Z"); | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| it("should allow setting of meeting properties", () => { | ||||||||||||||||||||||||||||
|
Comment on lines
+45
to
+49
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
| const store = new Store(); | ||||||||||||||||||||||||||||
| store.addQuads(new Parser().parse(sampleRDF)); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const dataset = new MeetingDataset(store, DataFactory); | ||||||||||||||||||||||||||||
| const meetings = Array.from(dataset.meeting); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.ok(meetings.length > 0, "No meetings found"); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const meeting = Array.from(dataset.meeting)[0]!; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Set new values | ||||||||||||||||||||||||||||
| meeting.summary = "Updated Meeting"; | ||||||||||||||||||||||||||||
| meeting.location = "Conference Room A"; | ||||||||||||||||||||||||||||
| meeting.comment = "New agenda"; | ||||||||||||||||||||||||||||
| const newStart = new Date("2026-02-09T12:00:00Z"); | ||||||||||||||||||||||||||||
| const newEnd = new Date("2026-02-09T13:00:00Z"); | ||||||||||||||||||||||||||||
| meeting.startDate = newStart; | ||||||||||||||||||||||||||||
| meeting.endDate = newEnd; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Retrieve again | ||||||||||||||||||||||||||||
| assert.equal(meeting.summary, "Updated Meeting"); | ||||||||||||||||||||||||||||
| assert.equal(meeting.location, "Conference Room A"); | ||||||||||||||||||||||||||||
| assert.equal(meeting.comment, "New agenda"); | ||||||||||||||||||||||||||||
| assert.equal(meeting.startDate.toISOString(), newStart.toISOString()); | ||||||||||||||||||||||||||||
| assert.equal(meeting.endDate.toISOString(), newEnd.toISOString()); | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| it("should ensure all properties are correct type", () => { | ||||||||||||||||||||||||||||
|
Comment on lines
+75
to
+79
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
| const store = new Store(); | ||||||||||||||||||||||||||||
| store.addQuads(new Parser().parse(sampleRDF)); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const dataset = new MeetingDataset(store, DataFactory); | ||||||||||||||||||||||||||||
| const meeting = Array.from(dataset.meeting)[0]; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.ok(meeting, "No meeting found") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Check property types | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.equal(typeof meeting.summary, "string"); | ||||||||||||||||||||||||||||
|
Comment on lines
+88
to
+90
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
| assert.equal(typeof meeting.location, "string"); | ||||||||||||||||||||||||||||
| assert.equal(typeof meeting.comment, "string"); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.ok(meeting.startDate instanceof Date, "startDate should be a Date"); | ||||||||||||||||||||||||||||
| assert.ok(meeting.endDate instanceof Date, "endDate should be a Date"); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| it("should ensure all properties are unique text or date values", () => { | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const duplicateRDF = ` | ||||||||||||||||||||||||||||
|
Comment on lines
+95
to
+102
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
| @prefix cal: <http://www.w3.org/2002/12/cal/ical#> . | ||||||||||||||||||||||||||||
| @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . | ||||||||||||||||||||||||||||
| <https://example.org/meeting/1> a cal:Vevent ; | ||||||||||||||||||||||||||||
| cal:summary "Team Sync" ; | ||||||||||||||||||||||||||||
| cal:summary "Duplicate Summary" ; | ||||||||||||||||||||||||||||
| cal:location "Zoom Room 123" ; | ||||||||||||||||||||||||||||
| cal:location "Duplicate Location" ; | ||||||||||||||||||||||||||||
| cal:comment "Discuss project updates" ; | ||||||||||||||||||||||||||||
| cal:comment "Duplicate Comment" ; | ||||||||||||||||||||||||||||
| cal:dtstart "2026-02-09T10:00:00Z"^^xsd:dateTime ; | ||||||||||||||||||||||||||||
| cal:dtstart "2026-02-09T09:00:00Z"^^xsd:dateTime ; | ||||||||||||||||||||||||||||
| cal:dtend "2026-02-09T11:00:00Z"^^xsd:dateTime ; | ||||||||||||||||||||||||||||
| cal:dtend "2026-02-09T12:00:00Z"^^xsd:dateTime . | ||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const store = new Store(); | ||||||||||||||||||||||||||||
| store.addQuads(new Parser().parse(duplicateRDF)); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const dataset = new MeetingDataset(store, DataFactory); | ||||||||||||||||||||||||||||
| const meeting = Array.from(dataset.meeting)[0]; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.ok(meeting, "No meeting found"); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Ensure exposed values are single (unique) and correct type | ||||||||||||||||||||||||||||
| assert.equal(typeof meeting.summary, "string"); | ||||||||||||||||||||||||||||
| assert.equal(typeof meeting.location, "string"); | ||||||||||||||||||||||||||||
| assert.equal(typeof meeting.comment, "string"); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| assert.ok(meeting.startDate instanceof Date); | ||||||||||||||||||||||||||||
| assert.ok(meeting.endDate instanceof Date); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Ensure no arrays are returned | ||||||||||||||||||||||||||||
| assert.ok(!Array.isArray(meeting.summary)); | ||||||||||||||||||||||||||||
| assert.ok(!Array.isArray(meeting.location)); | ||||||||||||||||||||||||||||
| assert.ok(!Array.isArray(meeting.comment)); | ||||||||||||||||||||||||||||
| assert.ok(!Array.isArray(meeting.startDate)); | ||||||||||||||||||||||||||||
| assert.ok(!Array.isArray(meeting.endDate)); | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
Comment on lines
+141
to
+145
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.