Skip to content

Commit

Permalink
feature: support PUT to notification state and method
Browse files Browse the repository at this point in the history
fix: allow plugins to register for notification PUT instead
  • Loading branch information
sbender9 authored and tkurki committed May 16, 2024
1 parent 4748c17 commit bc7373f
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 1 deletion.
45 changes: 44 additions & 1 deletion src/put.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const Result = {
}

const actionHandlers = {}
let putMetaHandler, deleteMetaHandler
let putMetaHandler, deleteMetaHandler, putNotificationHandler

module.exports = {
start: function (app) {
Expand Down Expand Up @@ -240,6 +240,9 @@ module.exports = {

return { state: 'PENDING' }
}
putNotificationHandler = (context, path, value) => {
return putNotification(app, context, path, value)
}
},

registerActionHandler: registerActionHandler,
Expand Down Expand Up @@ -386,6 +389,10 @@ function putPath(app, contextParam, path, body, req, requestId, updateCb) {
return
}
}

if (!handler && parts[0] === 'notifications') {
handler = putNotificationHandler
}
}

if (handler) {
Expand Down Expand Up @@ -484,3 +491,39 @@ function deRegisterActionHandler(context, path, source, callback) {
debug(`de-registered action handler for ${context} ${path} ${source}`)
}
}

function putNotification(app, context, path, value) {
const parts = path.split('.')
const notifPath = parts.slice(0, parts.length - 1).join('.')
const key = parts[parts.length - 1]

const existing = _.get(app.signalk.self, notifPath)

if (_.isUndefined(existing) || !existing.value) {
return { state: 'COMPLETED', statusCode: 404 }
}

if (key !== 'method' && key !== 'state') {
return { state: 'COMPLETED', statusCode: 405 }
}

existing.value[key] = value
existing.timestamp = new Date().toISOString()

const delta = {
updates: [
{
$source: existing.$source,
values: [
{
path: notifPath,
value: existing.value
}
]
}
]
}
app.handleMessage('server', delta)

return { state: 'COMPLETED', statusCode: 200 }
}
72 changes: 72 additions & 0 deletions test/put.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const chai = require('chai')
chai.Should()
chai.use(require('chai-things'))
const assert = require('assert')
const freeport = require('freeport-promise')
const Server = require('../lib')
const fetch = require('node-fetch')
Expand Down Expand Up @@ -56,6 +57,22 @@ describe('Put Requests', () => {
null,
switch2Handler
)

server.app.handleMessage('test', {
updates: [
{
values: [
{
path: 'notifications.testNotification',
value: {
state: 'alarm',
method: [ 'visual', 'sound' ]
}
}
]
}
]
})
})

after(async function () {
Expand Down Expand Up @@ -172,6 +189,61 @@ describe('Put Requests', () => {
json.message.should.equal('invalid value')
})

it('HTTP successful PUT notication state', async function () {
let result = await fetch(
`${url}/signalk/v1/api/vessels/self/notifications/testNotification/state`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
value: 'normal'
})
}
)

result.status.should.equal(200)

console.log(result.href)

result = await fetch(`${url}/signalk/v1/api/vessels/self/notifications/testNotification/value`)

result.status.should.equal(200)

let response = await result.json()
response.should.have.property('state')
response.state.should.equal('normal')
})

it('HTTP successful PUT notication method', async function () {
let result = await fetch(
`${url}/signalk/v1/api/vessels/self/notifications/testNotification/method`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
value: [ 'visual' ]
})
}
)

result.status.should.equal(200)

console.log(result.href)

result = await fetch(`${url}/signalk/v1/api/vessels/self/notifications/testNotification/value`)

result.status.should.equal(200)

let response = await result.json()
response.should.have.property('method')
assert(response.method.length === 1, 'one method')
response.method[0].should.equal('visual')
})

it('WS put to unhandled path fails', async function () {
const ws = new WsPromiser(
`ws://0.0.0.0:${port}/signalk/v1/stream?subscribe=none`
Expand Down

0 comments on commit bc7373f

Please sign in to comment.