From 5a58d39b71826f7f2b912bddb077c691d97b278a Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Fri, 12 Jan 2024 14:04:16 +0100 Subject: [PATCH] test(coap-server): add test for cov:observe subprotocol --- packages/binding-coap/src/util.ts | 14 ++- .../binding-coap/test/coap-server-test.ts | 90 ++++++++++++++++++- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/packages/binding-coap/src/util.ts b/packages/binding-coap/src/util.ts index 89157e9a6..cf4f4529e 100644 --- a/packages/binding-coap/src/util.ts +++ b/packages/binding-coap/src/util.ts @@ -18,6 +18,7 @@ import { PropertyElement } from "wot-thing-description-types"; const observeOpFilter = ["observeproperty", "unobserveproperty"]; const readWriteOpFilter = ["readproperty", "writeproperty"]; +const eventOpFilter = ["subscribeevent", "unsubscribeevent"]; function filterOpValues(opValues: string[], filterValues: string[]) { return opValues.filter((opValue) => filterValues.includes(opValue)); @@ -41,10 +42,21 @@ export function filterPropertyObserveOperations(opValues: string[]) { * @param opValues The `op` values to be filtered. * @returns A filtered array that might be empty. */ -function filterPropertyReadWriteOperations(opValues: string[]) { +export function filterPropertyReadWriteOperations(opValues: string[]) { return filterOpValues(opValues, readWriteOpFilter); } +/** + * Convenience function to filter out the `op` values "subscribeevent" and + * "unsubscribeevent" from a string array. + * + * @param opValues The `op` values to be filtered. + * @returns A filtered array that might be empty. + */ +export function filterEventOperations(opValues: string[]) { + return filterOpValues(opValues, eventOpFilter); +} + /** * Function to (potentially) generate two arrays of `op` values: One with the * values "readproperty" and "writeproperty", and one with diff --git a/packages/binding-coap/test/coap-server-test.ts b/packages/binding-coap/test/coap-server-test.ts index 55c9f5e50..5a6aeda87 100644 --- a/packages/binding-coap/test/coap-server-test.ts +++ b/packages/binding-coap/test/coap-server-test.ts @@ -20,12 +20,13 @@ import Servient, { ExposedThing, Content } from "@node-wot/core"; import { suite, test } from "@testdeck/mocha"; import { expect, should } from "chai"; -import { DataSchemaValue, InteractionInput, InteractionOptions } from "wot-typescript-definitions"; +import { DataSchemaValue, InteractionInput, InteractionOptions, ThingDescription } from "wot-typescript-definitions"; import * as TD from "@node-wot/td-tools"; import CoapServer from "../src/coap-server"; import { CoapClient } from "../src/coap"; import { Readable } from "stream"; import { IncomingMessage, registerFormat, request } from "coap"; +import { filterEventOperations, filterPropertyObserveOperations, filterPropertyReadWriteOperations } from "../src/util"; // should must be called to augment all variables should(); @@ -634,4 +635,91 @@ class CoapServerTest { await coapServer.stop(); } + + @test async "should add the cov:observe subprotocol value to obervable properties and events "() { + const coapServer = new CoapServer({ port: 5683 }); + const servient = new Servient(); + servient.addServer(coapServer); + + await coapServer.start(servient); + + const covObserveThing = new ExposedThing(servient, { + title: "Test", + properties: { + observableProperty: { + observable: true, + }, + nonObservableProperty: {}, + }, + events: { + testEvent: {}, + }, + }); + + await coapServer.expose(covObserveThing); + + await new Promise((resolve) => { + const req = request({ + host: "localhost", + pathname: "test", + port: 5683, + method: "GET", + }); + req.on("response", (res: IncomingMessage) => { + const payload = res.payload.toString(); + const td = JSON.parse(payload) as ThingDescription; + + for (const property of Object.values(td.properties!)) { + let observeOpValueFormCount = 0; + for (const form of property.forms) { + const opValues = form.op!; + expect(opValues.length).to.be.greaterThan(0); + + const observeOpValueCount = filterPropertyObserveOperations(opValues as Array).length; + const observeOpValuePresent = observeOpValueCount > 0; + + if (observeOpValuePresent) { + observeOpValueFormCount++; + expect(form.subprotocol).to.eql("cov:observe"); + } + + const readWriteOpValueCount = filterPropertyReadWriteOperations( + opValues as Array + ).length; + const readWriteOpValuePresent = readWriteOpValueCount > 0; + + // eslint-disable-next-line no-unused-expressions + expect(observeOpValuePresent && readWriteOpValuePresent).to.not.be.true; + + if (property.observable !== true) { + expect(observeOpValueCount).to.eql(0); + } + } + + if (property.observable === true) { + expect(observeOpValueFormCount).to.be.greaterThan(0); + } + } + + for (const event of Object.values(td.events!)) { + for (const form of event.forms) { + const opValues = form.op!; + expect(opValues.length > 0); + + const eventOpValueCount = filterEventOperations(opValues as Array).length; + const eventOpValueCountPresent = eventOpValueCount > 0; + + expect(eventOpValueCountPresent); + + expect(form.subprotocol === "cov:observe"); + } + } + + resolve(); + }); + req.end(); + }); + + await coapServer.stop(); + } }