messages: DoorbellPress is sent with the empty context of its page
proactiveEvent() built every proactive event without a context, so doorbellPress() and
device.raise(DoorbellEventSource, "DoorbellPress") left out the "context": {} that the example of
alexa-doorbelleventsource.html has. The Event of Alexa.SimpleEventSource is printed without one, so
the event descriptor says which it is (emptyContext) and raise() passes it on to the builder.
A raised DoorbellPress is now { event, context: {} }, 13 bytes longer; the Event of a button is
unchanged. The tests compare the keys and the context of the built message with the fixture of the
page, for the builder, the descriptor and raise(). 267 tests pass.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
3a07c861b1
commit
4a3dd81bcf
20 changed files with 86 additions and 18 deletions
1
dist/cjs/device/Device.js
vendored
1
dist/cjs/device/Device.js
vendored
|
|
@ -181,6 +181,7 @@ class Device extends events_1.EventEmitter {
|
||||||
instance,
|
instance,
|
||||||
payloadVersion: event.payloadVersion ?? capability.descriptor.version,
|
payloadVersion: event.payloadVersion ?? capability.descriptor.version,
|
||||||
payload: checked,
|
payload: checked,
|
||||||
|
emptyContext: event.emptyContext,
|
||||||
});
|
});
|
||||||
const bytes = Buffer.byteLength(JSON.stringify(message));
|
const bytes = Buffer.byteLength(JSON.stringify(message));
|
||||||
if (bytes > topics.EVENT_BYTES)
|
if (bytes > topics.EVENT_BYTES)
|
||||||
|
|
|
||||||
11
dist/cjs/messages/build.js
vendored
11
dist/cjs/messages/build.js
vendored
|
|
@ -113,7 +113,11 @@ function sceneEvent(fields) {
|
||||||
context: {},
|
context: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/** An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. */
|
/**
|
||||||
|
* An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. The
|
||||||
|
* pages differ on the context, so the caller says which it is: DoorbellPress is printed with an empty one
|
||||||
|
* (alexa-doorbelleventsource.html), the Event of Alexa.SimpleEventSource without.
|
||||||
|
*/
|
||||||
function proactiveEvent(fields) {
|
function proactiveEvent(fields) {
|
||||||
const { namespace, name, instance, messageId, payloadVersion, payload } = fields;
|
const { namespace, name, instance, messageId, payloadVersion, payload } = fields;
|
||||||
return {
|
return {
|
||||||
|
|
@ -122,13 +126,16 @@ function proactiveEvent(fields) {
|
||||||
endpoint: { endpointId: fields.endpointId },
|
endpoint: { endpointId: fields.endpointId },
|
||||||
payload,
|
payload,
|
||||||
},
|
},
|
||||||
|
...(fields.emptyContext ? { context: {} } : {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/** Somebody rang (alexa-doorbelleventsource.html). */
|
/** Somebody rang (alexa-doorbelleventsource.html). */
|
||||||
function doorbellPress(fields) {
|
function doorbellPress(fields) {
|
||||||
const { endpointId, messageId } = fields;
|
const { endpointId, messageId } = fields;
|
||||||
const payload = { cause: { type: fields.cause ?? "PHYSICAL_INTERACTION" }, timestamp: (0, property_js_1.isoTime)(fields.timestamp) };
|
const payload = { cause: { type: fields.cause ?? "PHYSICAL_INTERACTION" }, timestamp: (0, property_js_1.isoTime)(fields.timestamp) };
|
||||||
return proactiveEvent({ endpointId, messageId, namespace: "Alexa.DoorbellEventSource", name: "DoorbellPress", payload });
|
return proactiveEvent({
|
||||||
|
endpointId, messageId, namespace: "Alexa.DoorbellEventSource", name: "DoorbellPress", payload, emptyContext: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/** An event of a button or a sensor that routines start on (alexa-simpleeventsource.html). */
|
/** An event of a button or a sensor that routines start on (alexa-simpleeventsource.html). */
|
||||||
function simpleEvent(fields) {
|
function simpleEvent(fields) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ exports.DoorbellEventSource = (0, types_js_1.defineInterface)({
|
||||||
properties: {},
|
properties: {},
|
||||||
directives: {},
|
directives: {},
|
||||||
events: {
|
events: {
|
||||||
DoorbellPress: { name: "DoorbellPress", payload: (0, events_js_1.happened)("PHYSICAL_INTERACTION"), topic: "proactive" },
|
DoorbellPress: { name: "DoorbellPress", payload: (0, events_js_1.happened)("PHYSICAL_INTERACTION"), topic: "proactive", emptyContext: true },
|
||||||
},
|
},
|
||||||
// The capability is the announcement that the endpoint raises the event: proactivelyReported whatever was declared
|
// The capability is the announcement that the endpoint raises the event: proactivelyReported whatever was declared
|
||||||
discovery: () => ({ properties: false, topLevel: { proactivelyReported: true } }),
|
discovery: () => ({ properties: false, topLevel: { proactivelyReported: true } }),
|
||||||
|
|
|
||||||
1
dist/esm/device/Device.js
vendored
1
dist/esm/device/Device.js
vendored
|
|
@ -146,6 +146,7 @@ class Device extends EventEmitter {
|
||||||
instance,
|
instance,
|
||||||
payloadVersion: event.payloadVersion ?? capability.descriptor.version,
|
payloadVersion: event.payloadVersion ?? capability.descriptor.version,
|
||||||
payload: checked,
|
payload: checked,
|
||||||
|
emptyContext: event.emptyContext,
|
||||||
});
|
});
|
||||||
const bytes = Buffer.byteLength(JSON.stringify(message));
|
const bytes = Buffer.byteLength(JSON.stringify(message));
|
||||||
if (bytes > topics.EVENT_BYTES)
|
if (bytes > topics.EVENT_BYTES)
|
||||||
|
|
|
||||||
8
dist/esm/messages/build.d.ts
vendored
8
dist/esm/messages/build.d.ts
vendored
|
|
@ -88,8 +88,14 @@ export interface ProactiveEventFields extends Envelope {
|
||||||
/** Default: "3". */
|
/** Default: "3". */
|
||||||
payloadVersion?: string;
|
payloadVersion?: string;
|
||||||
payload: Record<string, unknown>;
|
payload: Record<string, unknown>;
|
||||||
|
/** true: the message has "context": {}, as the page of the event prints it. Default: no context. */
|
||||||
|
emptyContext?: boolean;
|
||||||
}
|
}
|
||||||
/** An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. */
|
/**
|
||||||
|
* An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. The
|
||||||
|
* pages differ on the context, so the caller says which it is: DoorbellPress is printed with an empty one
|
||||||
|
* (alexa-doorbelleventsource.html), the Event of Alexa.SimpleEventSource without.
|
||||||
|
*/
|
||||||
export declare function proactiveEvent(fields: ProactiveEventFields): ProactiveEventMessage;
|
export declare function proactiveEvent(fields: ProactiveEventFields): ProactiveEventMessage;
|
||||||
export interface DoorbellPressFields extends Envelope {
|
export interface DoorbellPressFields extends Envelope {
|
||||||
/** Default: "PHYSICAL_INTERACTION", somebody pressed the button. */
|
/** Default: "PHYSICAL_INTERACTION", somebody pressed the button. */
|
||||||
|
|
|
||||||
11
dist/esm/messages/build.js
vendored
11
dist/esm/messages/build.js
vendored
|
|
@ -99,7 +99,11 @@ export function sceneEvent(fields) {
|
||||||
context: {},
|
context: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/** An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. */
|
/**
|
||||||
|
* An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. The
|
||||||
|
* pages differ on the context, so the caller says which it is: DoorbellPress is printed with an empty one
|
||||||
|
* (alexa-doorbelleventsource.html), the Event of Alexa.SimpleEventSource without.
|
||||||
|
*/
|
||||||
export function proactiveEvent(fields) {
|
export function proactiveEvent(fields) {
|
||||||
const { namespace, name, instance, messageId, payloadVersion, payload } = fields;
|
const { namespace, name, instance, messageId, payloadVersion, payload } = fields;
|
||||||
return {
|
return {
|
||||||
|
|
@ -108,13 +112,16 @@ export function proactiveEvent(fields) {
|
||||||
endpoint: { endpointId: fields.endpointId },
|
endpoint: { endpointId: fields.endpointId },
|
||||||
payload,
|
payload,
|
||||||
},
|
},
|
||||||
|
...(fields.emptyContext ? { context: {} } : {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/** Somebody rang (alexa-doorbelleventsource.html). */
|
/** Somebody rang (alexa-doorbelleventsource.html). */
|
||||||
export function doorbellPress(fields) {
|
export function doorbellPress(fields) {
|
||||||
const { endpointId, messageId } = fields;
|
const { endpointId, messageId } = fields;
|
||||||
const payload = { cause: { type: fields.cause ?? "PHYSICAL_INTERACTION" }, timestamp: isoTime(fields.timestamp) };
|
const payload = { cause: { type: fields.cause ?? "PHYSICAL_INTERACTION" }, timestamp: isoTime(fields.timestamp) };
|
||||||
return proactiveEvent({ endpointId, messageId, namespace: "Alexa.DoorbellEventSource", name: "DoorbellPress", payload });
|
return proactiveEvent({
|
||||||
|
endpointId, messageId, namespace: "Alexa.DoorbellEventSource", name: "DoorbellPress", payload, emptyContext: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/** An event of a button or a sensor that routines start on (alexa-simpleeventsource.html). */
|
/** An event of a button or a sensor that routines start on (alexa-simpleeventsource.html). */
|
||||||
export function simpleEvent(fields) {
|
export function simpleEvent(fields) {
|
||||||
|
|
|
||||||
2
dist/esm/messages/types.d.ts
vendored
2
dist/esm/messages/types.d.ts
vendored
|
|
@ -73,4 +73,6 @@ export interface SceneEventMessage {
|
||||||
/** An event a device raises by itself: DoorbellPress, the Event of Alexa.SimpleEventSource. */
|
/** An event a device raises by itself: DoorbellPress, the Event of Alexa.SimpleEventSource. */
|
||||||
export interface ProactiveEventMessage {
|
export interface ProactiveEventMessage {
|
||||||
event: Event;
|
event: Event;
|
||||||
|
/** Only with an event whose page prints it: DoorbellPress has an empty one, the Event of a button has none. */
|
||||||
|
context?: {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export const DoorbellEventSource = defineInterface({
|
||||||
properties: {},
|
properties: {},
|
||||||
directives: {},
|
directives: {},
|
||||||
events: {
|
events: {
|
||||||
DoorbellPress: { name: "DoorbellPress", payload: happened("PHYSICAL_INTERACTION"), topic: "proactive" },
|
DoorbellPress: { name: "DoorbellPress", payload: happened("PHYSICAL_INTERACTION"), topic: "proactive", emptyContext: true },
|
||||||
},
|
},
|
||||||
// The capability is the announcement that the endpoint raises the event: proactivelyReported whatever was declared
|
// The capability is the announcement that the endpoint raises the event: proactivelyReported whatever was declared
|
||||||
discovery: () => ({ properties: false, topLevel: { proactivelyReported: true } }),
|
discovery: () => ({ properties: false, topLevel: { proactivelyReported: true } }),
|
||||||
|
|
|
||||||
2
dist/esm/registry/types.d.ts
vendored
2
dist/esm/registry/types.d.ts
vendored
|
|
@ -66,6 +66,8 @@ export interface EventDescriptor {
|
||||||
payload: Schema<any>;
|
payload: Schema<any>;
|
||||||
/** response: the answer to a directive. proactive: sent without one. */
|
/** response: the answer to a directive. proactive: sent without one. */
|
||||||
topic: "response" | "proactive";
|
topic: "response" | "proactive";
|
||||||
|
/** A proactive event that the page prints with "context": {}, DoorbellPress. Default: sent without a context. */
|
||||||
|
emptyContext?: boolean;
|
||||||
}
|
}
|
||||||
/** What an interface adds to the capability object in discovery, next to the fields every capability has. */
|
/** What an interface adds to the capability object in discovery, next to the fields every capability has. */
|
||||||
export interface CapabilityExtras {
|
export interface CapabilityExtras {
|
||||||
|
|
|
||||||
8
dist/types/messages/build.d.ts
vendored
8
dist/types/messages/build.d.ts
vendored
|
|
@ -88,8 +88,14 @@ export interface ProactiveEventFields extends Envelope {
|
||||||
/** Default: "3". */
|
/** Default: "3". */
|
||||||
payloadVersion?: string;
|
payloadVersion?: string;
|
||||||
payload: Record<string, unknown>;
|
payload: Record<string, unknown>;
|
||||||
|
/** true: the message has "context": {}, as the page of the event prints it. Default: no context. */
|
||||||
|
emptyContext?: boolean;
|
||||||
}
|
}
|
||||||
/** An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. */
|
/**
|
||||||
|
* An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. The
|
||||||
|
* pages differ on the context, so the caller says which it is: DoorbellPress is printed with an empty one
|
||||||
|
* (alexa-doorbelleventsource.html), the Event of Alexa.SimpleEventSource without.
|
||||||
|
*/
|
||||||
export declare function proactiveEvent(fields: ProactiveEventFields): ProactiveEventMessage;
|
export declare function proactiveEvent(fields: ProactiveEventFields): ProactiveEventMessage;
|
||||||
export interface DoorbellPressFields extends Envelope {
|
export interface DoorbellPressFields extends Envelope {
|
||||||
/** Default: "PHYSICAL_INTERACTION", somebody pressed the button. */
|
/** Default: "PHYSICAL_INTERACTION", somebody pressed the button. */
|
||||||
|
|
|
||||||
2
dist/types/messages/types.d.ts
vendored
2
dist/types/messages/types.d.ts
vendored
|
|
@ -73,4 +73,6 @@ export interface SceneEventMessage {
|
||||||
/** An event a device raises by itself: DoorbellPress, the Event of Alexa.SimpleEventSource. */
|
/** An event a device raises by itself: DoorbellPress, the Event of Alexa.SimpleEventSource. */
|
||||||
export interface ProactiveEventMessage {
|
export interface ProactiveEventMessage {
|
||||||
event: Event;
|
event: Event;
|
||||||
|
/** Only with an event whose page prints it: DoorbellPress has an empty one, the Event of a button has none. */
|
||||||
|
context?: {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
dist/types/registry/types.d.ts
vendored
2
dist/types/registry/types.d.ts
vendored
|
|
@ -66,6 +66,8 @@ export interface EventDescriptor {
|
||||||
payload: Schema<any>;
|
payload: Schema<any>;
|
||||||
/** response: the answer to a directive. proactive: sent without one. */
|
/** response: the answer to a directive. proactive: sent without one. */
|
||||||
topic: "response" | "proactive";
|
topic: "response" | "proactive";
|
||||||
|
/** A proactive event that the page prints with "context": {}, DoorbellPress. Default: sent without a context. */
|
||||||
|
emptyContext?: boolean;
|
||||||
}
|
}
|
||||||
/** What an interface adds to the capability object in discovery, next to the fields every capability has. */
|
/** What an interface adds to the capability object in discovery, next to the fields every capability has. */
|
||||||
export interface CapabilityExtras {
|
export interface CapabilityExtras {
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,7 @@ class Device extends EventEmitter {
|
||||||
instance,
|
instance,
|
||||||
payloadVersion: event.payloadVersion ?? capability.descriptor.version,
|
payloadVersion: event.payloadVersion ?? capability.descriptor.version,
|
||||||
payload: checked,
|
payload: checked,
|
||||||
|
emptyContext: event.emptyContext,
|
||||||
});
|
});
|
||||||
const bytes = Buffer.byteLength(JSON.stringify(message));
|
const bytes = Buffer.byteLength(JSON.stringify(message));
|
||||||
if (bytes > topics.EVENT_BYTES) return refuse(`it is ${bytes} bytes as JSON, Alex2MQTT takes ${topics.EVENT_BYTES}`);
|
if (bytes > topics.EVENT_BYTES) return refuse(`it is ${bytes} bytes as JSON, Alex2MQTT takes ${topics.EVENT_BYTES}`);
|
||||||
|
|
|
||||||
|
|
@ -182,9 +182,15 @@ export interface ProactiveEventFields extends Envelope {
|
||||||
/** Default: "3". */
|
/** Default: "3". */
|
||||||
payloadVersion?: string;
|
payloadVersion?: string;
|
||||||
payload: Record<string, unknown>;
|
payload: Record<string, unknown>;
|
||||||
|
/** true: the message has "context": {}, as the page of the event prints it. Default: no context. */
|
||||||
|
emptyContext?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. */
|
/**
|
||||||
|
* An event a device raises by itself, of any interface. The header has no correlationToken: nobody asked. The
|
||||||
|
* pages differ on the context, so the caller says which it is: DoorbellPress is printed with an empty one
|
||||||
|
* (alexa-doorbelleventsource.html), the Event of Alexa.SimpleEventSource without.
|
||||||
|
*/
|
||||||
export function proactiveEvent(fields: ProactiveEventFields): ProactiveEventMessage {
|
export function proactiveEvent(fields: ProactiveEventFields): ProactiveEventMessage {
|
||||||
const { namespace, name, instance, messageId, payloadVersion, payload } = fields;
|
const { namespace, name, instance, messageId, payloadVersion, payload } = fields;
|
||||||
return {
|
return {
|
||||||
|
|
@ -193,6 +199,7 @@ export function proactiveEvent(fields: ProactiveEventFields): ProactiveEventMess
|
||||||
endpoint: { endpointId: fields.endpointId },
|
endpoint: { endpointId: fields.endpointId },
|
||||||
payload,
|
payload,
|
||||||
},
|
},
|
||||||
|
...(fields.emptyContext ? { context: {} } : {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,7 +214,9 @@ export interface DoorbellPressFields extends Envelope {
|
||||||
export function doorbellPress(fields: DoorbellPressFields): ProactiveEventMessage {
|
export function doorbellPress(fields: DoorbellPressFields): ProactiveEventMessage {
|
||||||
const { endpointId, messageId } = fields;
|
const { endpointId, messageId } = fields;
|
||||||
const payload = { cause: { type: fields.cause ?? "PHYSICAL_INTERACTION" }, timestamp: isoTime(fields.timestamp) };
|
const payload = { cause: { type: fields.cause ?? "PHYSICAL_INTERACTION" }, timestamp: isoTime(fields.timestamp) };
|
||||||
return proactiveEvent({ endpointId, messageId, namespace: "Alexa.DoorbellEventSource", name: "DoorbellPress", payload });
|
return proactiveEvent({
|
||||||
|
endpointId, messageId, namespace: "Alexa.DoorbellEventSource", name: "DoorbellPress", payload, emptyContext: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SimpleEventFields extends Envelope {
|
export interface SimpleEventFields extends Envelope {
|
||||||
|
|
|
||||||
|
|
@ -70,4 +70,6 @@ export interface SceneEventMessage {
|
||||||
/** An event a device raises by itself: DoorbellPress, the Event of Alexa.SimpleEventSource. */
|
/** An event a device raises by itself: DoorbellPress, the Event of Alexa.SimpleEventSource. */
|
||||||
export interface ProactiveEventMessage {
|
export interface ProactiveEventMessage {
|
||||||
event: Event;
|
event: Event;
|
||||||
|
/** Only with an event whose page prints it: DoorbellPress has an empty one, the Event of a button has none. */
|
||||||
|
context?: {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const DoorbellEventSource = defineInterface({
|
||||||
properties: {},
|
properties: {},
|
||||||
directives: {},
|
directives: {},
|
||||||
events: {
|
events: {
|
||||||
DoorbellPress: { name: "DoorbellPress", payload: happened("PHYSICAL_INTERACTION"), topic: "proactive" },
|
DoorbellPress: { name: "DoorbellPress", payload: happened("PHYSICAL_INTERACTION"), topic: "proactive", emptyContext: true },
|
||||||
},
|
},
|
||||||
// The capability is the announcement that the endpoint raises the event: proactivelyReported whatever was declared
|
// The capability is the announcement that the endpoint raises the event: proactivelyReported whatever was declared
|
||||||
discovery: () => ({ properties: false, topLevel: { proactivelyReported: true } }),
|
discovery: () => ({ properties: false, topLevel: { proactivelyReported: true } }),
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ export interface EventDescriptor {
|
||||||
payload: Schema<any>;
|
payload: Schema<any>;
|
||||||
/** response: the answer to a directive. proactive: sent without one. */
|
/** response: the answer to a directive. proactive: sent without one. */
|
||||||
topic: "response" | "proactive";
|
topic: "response" | "proactive";
|
||||||
|
/** A proactive event that the page prints with "context": {}, DoorbellPress. Default: sent without a context. */
|
||||||
|
emptyContext?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** What an interface adds to the capability object in discovery, next to the fields every capability has. */
|
/** What an interface adds to the capability object in discovery, next to the fields every capability has. */
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ const refused = (raise, problem) => assert.throws(raise, (err) => err instanceof
|
||||||
|
|
||||||
test("raise() publishes the event on <root>/event, with the endpoint, a new messageId, the time and the usual cause", async () => {
|
test("raise() publishes the event on <root>/event, with the endpoint, a new messageId, the time and the usual cause", async () => {
|
||||||
const { device, sent } = doorbell();
|
const { device, sent } = doorbell();
|
||||||
const printed = doc("alexa-doorbelleventsource", "DoorbellPress.event").event;
|
const example = doc("alexa-doorbelleventsource", "DoorbellPress.event");
|
||||||
|
const printed = example.event;
|
||||||
const before = Date.now();
|
const before = Date.now();
|
||||||
|
|
||||||
assert.deepEqual(await device.raise(DoorbellEventSource, "DoorbellPress"), { ok: true, topic: "root/event" });
|
assert.deepEqual(await device.raise(DoorbellEventSource, "DoorbellPress"), { ok: true, topic: "root/event" });
|
||||||
|
|
@ -39,6 +40,10 @@ test("raise() publishes the event on <root>/event, with the endpoint, a new mess
|
||||||
|
|
||||||
assert.equal(topics.event("root"), "root/event");
|
assert.equal(topics.event("root"), "root/event");
|
||||||
assert.deepEqual(sent.published.map(({ topic }) => topic), ["root/event", "root/event", "root/event"]);
|
assert.deepEqual(sent.published.map(({ topic }) => topic), ["root/event", "root/event", "root/event"]);
|
||||||
|
for (const { message } of sent.published) {
|
||||||
|
assert.deepEqual(Object.keys(message).sort(), Object.keys(example).sort());
|
||||||
|
assert.deepEqual(message.context, example.context);
|
||||||
|
}
|
||||||
const [first, second, third] = sent.published.map(({ message }) => message.event);
|
const [first, second, third] = sent.published.map(({ message }) => message.event);
|
||||||
for (const event of [first, second, third]) {
|
for (const event of [first, second, third]) {
|
||||||
assert.deepEqual(event.endpoint, { endpointId: "door-1" });
|
assert.deepEqual(event.endpoint, { endpointId: "door-1" });
|
||||||
|
|
@ -62,7 +67,8 @@ test("raise() for an instance: the Event of a button has the instance in its hea
|
||||||
remote.publisher = sent;
|
remote.publisher = sent;
|
||||||
const top = remote.add(SimpleEventSource, button("TopButton", ["SinglePush", "DoublePush"]));
|
const top = remote.add(SimpleEventSource, button("TopButton", ["SinglePush", "DoublePush"]));
|
||||||
remote.add(SimpleEventSource, button("BottomButton", ["SinglePush"]));
|
remote.add(SimpleEventSource, button("BottomButton", ["SinglePush"]));
|
||||||
const printed = doc("alexa-simpleeventsource", "Event.event").event;
|
const example = doc("alexa-simpleeventsource", "Event.event");
|
||||||
|
const printed = example.event;
|
||||||
|
|
||||||
await remote.raise(SimpleEventSource, "Event", printed.payload, { instance: top.instance, messageId: "push-1" });
|
await remote.raise(SimpleEventSource, "Event", printed.payload, { instance: top.instance, messageId: "push-1" });
|
||||||
assert.deepEqual(sent.published, [{
|
assert.deepEqual(sent.published, [{
|
||||||
|
|
@ -76,6 +82,7 @@ test("raise() for an instance: the Event of a button has the instance in its hea
|
||||||
},
|
},
|
||||||
}]);
|
}]);
|
||||||
assert.equal(printed.header.payloadVersion, "1.0");
|
assert.equal(printed.header.payloadVersion, "1.0");
|
||||||
|
assert.deepEqual(Object.keys(sent.published[0].message), Object.keys(example));
|
||||||
|
|
||||||
const raised = "remote-1: Alexa.SimpleEventSource.Event was not raised: ";
|
const raised = "remote-1: Alexa.SimpleEventSource.Event was not raised: ";
|
||||||
assert.throws(() => remote.raise(SimpleEventSource, "Event", { id: "Button.SinglePush.1" }), {
|
assert.throws(() => remote.raise(SimpleEventSource, "Event", { id: "Button.SinglePush.1" }), {
|
||||||
|
|
@ -117,7 +124,7 @@ test("raise() refuses an event the device has no capability for, and one that wo
|
||||||
);
|
);
|
||||||
refused(
|
refused(
|
||||||
() => device.raise(DoorbellEventSource, "DoorbellPress", { picture: "x".repeat(topics.EVENT_BYTES) }),
|
() => device.raise(DoorbellEventSource, "DoorbellPress", { picture: "x".repeat(topics.EVENT_BYTES) }),
|
||||||
`${was("Alexa.DoorbellEventSource.DoorbellPress")}it is 16296 bytes as JSON, Alex2MQTT takes 16000`
|
`${was("Alexa.DoorbellEventSource.DoorbellPress")}it is 16309 bytes as JSON, Alex2MQTT takes 16000`
|
||||||
);
|
);
|
||||||
assert.deepEqual(sent.published, []);
|
assert.deepEqual(sent.published, []);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
const { test } = require("node:test");
|
const { test } = require("node:test");
|
||||||
const assert = require("node:assert/strict");
|
const assert = require("node:assert/strict");
|
||||||
const { messages, MessageError } = require("alex2node");
|
const { messages, MessageError } = require("alex2node");
|
||||||
|
const { doc } = require("../helpers/fixtures.js");
|
||||||
const { UUID_V4 } = require("../helpers/harness.js");
|
const { UUID_V4 } = require("../helpers/harness.js");
|
||||||
|
|
||||||
const AT = "2026-09-28T10:00:00.000Z";
|
const AT = "2026-09-28T10:00:00.000Z";
|
||||||
|
|
@ -134,17 +135,21 @@ test("sceneEvent: ActivationStarted and DeactivationStarted with the cause and t
|
||||||
assert.deepEqual(stopped.event.payload, { cause: { type: "APP_INTERACTION" }, timestamp: AT });
|
assert.deepEqual(stopped.event.payload, { cause: { type: "APP_INTERACTION" }, timestamp: AT });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("doorbellPress: an event without a correlationToken and without a context", () => {
|
test("doorbellPress: an event without a correlationToken, with the empty context of the page", () => {
|
||||||
assert.deepEqual(messages.doorbellPress({ endpointId: "door", messageId, timestamp: AT }), {
|
const built = messages.doorbellPress({ endpointId: "door", messageId, timestamp: AT });
|
||||||
|
assert.deepEqual(built, {
|
||||||
event: {
|
event: {
|
||||||
header: { namespace: "Alexa.DoorbellEventSource", name: "DoorbellPress", messageId, payloadVersion: "3" },
|
header: { namespace: "Alexa.DoorbellEventSource", name: "DoorbellPress", messageId, payloadVersion: "3" },
|
||||||
endpoint: { endpointId: "door" },
|
endpoint: { endpointId: "door" },
|
||||||
payload: { cause: { type: "PHYSICAL_INTERACTION" }, timestamp: AT },
|
payload: { cause: { type: "PHYSICAL_INTERACTION" }, timestamp: AT },
|
||||||
},
|
},
|
||||||
|
context: {},
|
||||||
});
|
});
|
||||||
|
assert.deepEqual(built.context, doc("alexa-doorbelleventsource", "DoorbellPress.event").context);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("simpleEvent: the instance in the header, payloadVersion 1.0", () => {
|
test("simpleEvent: the instance in the header, payloadVersion 1.0, no context as on the page", () => {
|
||||||
|
assert.equal("context" in doc("alexa-simpleeventsource", "Event.event"), false);
|
||||||
assert.deepEqual(messages.simpleEvent({ endpointId: "button", instance: "Button.Front", id: "Button.SinglePush.1", messageId, timestamp: AT }), {
|
assert.deepEqual(messages.simpleEvent({ endpointId: "button", instance: "Button.Front", id: "Button.SinglePush.1", messageId, timestamp: AT }), {
|
||||||
event: {
|
event: {
|
||||||
header: { namespace: "Alexa.SimpleEventSource", name: "Event", instance: "Button.Front", messageId, payloadVersion: "1.0" },
|
header: { namespace: "Alexa.SimpleEventSource", name: "Event", instance: "Button.Front", messageId, payloadVersion: "1.0" },
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,15 @@ test("the events of the pages fit the payload of their descriptor, and come back
|
||||||
["Alexa.WakeOnLANController", "alexa-wakeonlancontroller", "WakeUp", "response"],
|
["Alexa.WakeOnLANController", "alexa-wakeonlancontroller", "WakeUp", "response"],
|
||||||
];
|
];
|
||||||
for (const [namespace, page, name, topic] of printed) {
|
for (const [namespace, page, name, topic] of printed) {
|
||||||
const { header, payload } = doc(page, `${name}.event`).event;
|
const example = doc(page, `${name}.event`);
|
||||||
|
const { header, payload } = example.event;
|
||||||
const descriptor = registry.get(namespace);
|
const descriptor = registry.get(namespace);
|
||||||
const event = descriptor.events[name];
|
const event = descriptor.events[name];
|
||||||
|
// raise() sends a context where the page prints one, and the pages print an empty one or none
|
||||||
|
if (topic === "proactive") {
|
||||||
|
assert.equal(event.emptyContext === true, "context" in example, name);
|
||||||
|
assert.deepEqual(example.context ?? {}, {}, name);
|
||||||
|
}
|
||||||
assert.deepEqual([header.namespace, header.name, header.payloadVersion], [namespace, event.name, descriptor.version]);
|
assert.deepEqual([header.namespace, header.name, header.payloadVersion], [namespace, event.name, descriptor.version]);
|
||||||
assert.equal(event.topic, topic, name);
|
assert.equal(event.topic, topic, name);
|
||||||
assert.equal("correlationToken" in header, topic === "response", name);
|
assert.equal("correlationToken" in header, topic === "response", name);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue