Skip to content

Commit

Permalink
Add createChild and removeNode request types, quit using `success…
Browse files Browse the repository at this point in the history
…` in response for knowing if a request failed or not
  • Loading branch information
triwav committed Apr 22, 2024
1 parent 5139407 commit e0303f3
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 23 deletions.
95 changes: 95 additions & 0 deletions client/src/OnDeviceComponent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,101 @@ describe('OnDeviceComponent', function () {
});
});

describe('createChild', function () {
const baseKeyPath = '#temporaryNodesGroup';
this.afterEach(async () => {
const { value: childCount } = await odc.getValue({
keyPath: `${baseKeyPath}.getChildCount()`
});
if (childCount > 0) {
await odc.removeNodeChildren({
keyPath: baseKeyPath,
index: 0,
count: -1
});
}
});

it('should successfully create a child on the specified parent', async () => {
// Make sure there are no children to start
const { value: startingChildCount } = await odc.getValue({
keyPath: `${baseKeyPath}.getChildCount()`
});
expect(startingChildCount).to.equal(0);

// Add our child
const childId = utils.addRandomPostfix('child');
const customFieldValue = utils.addRandomPostfix('customFieldValue');
await odc.createChild({
keyPath: baseKeyPath,
subtype: 'Group',
fields: {
id: childId,
customField: customFieldValue
}
});

// Make sure it got added to the right parent
const { value: childCount } = await odc.getValue({
keyPath: `${baseKeyPath}.getChildCount()`
});
expect(childCount).to.equal(1);

// Make sure it added the fields we requested
const { value: child, found } = await odc.getValue({
keyPath: `${baseKeyPath}.#${childId}`
});
expect(found).to.be.true;
expect(child.customField).to.equal(customFieldValue);
});

it('should fail if the subtype for the child does not exist', async () => {
try {
await odc.createChild({
keyPath: baseKeyPath,
subtype: 'IDoNotExist'
});
} catch (e) {
// failed as expected
return;
}
throw new Error('Should have thrown an exception');
});
});

describe('removeNode', function () {
const baseKeyPath = '#temporaryNodesGroup';

it('should successfully remove a node', async () => {
// Add a child node
const nodeId = utils.addRandomPostfix('node');
await odc.createChild({
keyPath: baseKeyPath,
subtype: 'Group',
fields: {
id: nodeId
}
});

// Make sure the child got added
const { value: startingChildCount } = await odc.getValue({
keyPath: `${baseKeyPath}.getChildCount()`
});
expect(startingChildCount).to.equal(1);

// Remove the node
await odc.removeNode({
keyPath: `${baseKeyPath}.#${nodeId}`
});

// Make sure it got removed
const { value: childCount } = await odc.getValue({
keyPath: `${baseKeyPath}.getChildCount()`
});
expect(childCount).to.equal(0);
});
});

describe('removeNodeChildren', function () {
it('should successfully delete the child at the specified index', async () => {
// Add a child node
Expand Down
16 changes: 15 additions & 1 deletion client/src/OnDeviceComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,20 @@ export class OnDeviceComponent {
return result.json as ODC.ReturnTimeTaken;
}

public async createChild(args: ODC.CreateChildArgs, options: ODC.RequestOptions = {}) {
this.conditionallyAddDefaultBase(args);
this.conditionallyAddDefaultNodeReferenceKey(args);
const result = await this.sendRequest(ODC.RequestType.createChild, args, options);
return result.json as ODC.ReturnTimeTaken;
}

public async removeNode(args: ODC.RemoveNodeArgs, options: ODC.RequestOptions = {}) {
this.conditionallyAddDefaultBase(args);
this.conditionallyAddDefaultNodeReferenceKey(args);
const result = await this.sendRequest(ODC.RequestType.removeNode, args, options);
return result.json as ODC.ReturnTimeTaken;
}

public async removeNodeChildren(args: ODC.RemoveNodeChildrenArgs, options: ODC.RequestOptions = {}) {
this.conditionallyAddDefaultBase(args);
this.conditionallyAddDefaultNodeReferenceKey(args);
Expand Down Expand Up @@ -918,7 +932,7 @@ export class OnDeviceComponent {
try {
const json = response.json;
this.debugLog('Received response:', response.json);
if (json?.success) {
if (json?.error === undefined) {
resolve(response);
} else {
let error: Error;
Expand Down
11 changes: 10 additions & 1 deletion client/src/types/OnDeviceComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Socket } from 'net';
export enum RequestType {
callFunc = 'callFunc',
createDirectory = 'createDirectory',
createChild = 'createChild',
deleteFile = 'deleteFile',
deleteNodeReferences = 'deleteNodeReferences',
deleteRegistrySections = 'deleteRegistrySections',
Expand All @@ -27,6 +28,7 @@ export enum RequestType {
onFieldChangeOnce = 'onFieldChangeOnce',
readFile = 'readFile',
readRegistry = 'readRegistry',
removeNode = 'removeNode',
removeNodeChildren = 'removeNodeChildren',
renameFile = 'renameFile',
setSettings = 'setSettings',
Expand All @@ -40,7 +42,7 @@ export enum RequestType {
writeRegistry = 'writeRegistry',
}

export type RequestArgs = CallFuncArgs | GetFocusedNodeArgs | GetValueArgs | GetValuesArgs | HasFocusArgs | IsInFocusChainArgs | OnFieldChangeOnceArgs | SetValueArgs | ReadRegistryArgs | WriteRegistryArgs | DeleteRegistrySectionsArgs | DeleteEntireRegistrySectionsArgs | StoreNodeReferencesArgs | GetNodesInfoArgs | FindNodesAtLocationArgs | CreateDirectoryArgs | DeleteEntireRegistrySectionsArgs | DeleteFileArgs | DeleteNodeReferencesArgs | DisableScreensaverArgs | FocusNodeArgs | GetAllCountArgs | GetDirectoryListingArgs | GetNodesWithPropertiesArgs | GetRootsCountArgs | GetServerHostArgs | GetVolumeListArgs | ReadFileArgs | RenameFileArgs | SetSettingsArgs | StartResponsivenessTestingArgs | StatPathArgs | WriteFileArgs | RemoveNodeChildrenArgs | DisableScreensaverArgs;
export type RequestArgs = CallFuncArgs | CreateChildArgs | GetFocusedNodeArgs | GetValueArgs | GetValuesArgs | HasFocusArgs | IsInFocusChainArgs | OnFieldChangeOnceArgs | SetValueArgs | ReadRegistryArgs | WriteRegistryArgs | DeleteRegistrySectionsArgs | DeleteEntireRegistrySectionsArgs | StoreNodeReferencesArgs | GetNodesInfoArgs | FindNodesAtLocationArgs | CreateDirectoryArgs | DeleteEntireRegistrySectionsArgs | DeleteFileArgs | DeleteNodeReferencesArgs | DisableScreensaverArgs | FocusNodeArgs | GetAllCountArgs | GetDirectoryListingArgs | GetNodesWithPropertiesArgs | GetRootsCountArgs | GetServerHostArgs | GetVolumeListArgs | ReadFileArgs | RenameFileArgs | SetSettingsArgs | StartResponsivenessTestingArgs | StatPathArgs | WriteFileArgs | RemoveNodeArgs |RemoveNodeChildrenArgs | DisableScreensaverArgs;

export enum BaseType {
global = 'global',
Expand Down Expand Up @@ -265,6 +267,13 @@ export interface FocusNodeArgs extends BaseKeyPath {
on?: boolean;
}

export interface CreateChildArgs extends BaseKeyPath {
subtype: string;
fields?: Partial<NodeRepresentation>;
}

export interface RemoveNodeArgs extends BaseKeyPath {}

export interface RemoveNodeChildrenArgs extends BaseKeyPath {
/** The first index of the node(s) that we want to remove */
index: number;
Expand Down
95 changes: 81 additions & 14 deletions device/components/RTA_OnDeviceComponent.brs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,30 @@ sub init()
m.task.control = "RUN"
m.validRequestTypes = {
"callFunc": processCallFuncRequest
"getFocusedNode": processGetFocusedNodeRequest
"callFunc": processCallFuncRequest
"createChild": processCreateChildRequest
"deleteNodeReferences": processDeleteNodeReferencesRequest
"disableScreenSaver": processDisableScreenSaverRequest
"focusNode": processFocusNodeRequest
"getAllCount": processGetAllCountRequest
"getFocusedNode": processGetFocusedNodeRequest
"getNodesInfo": processGetNodesInfoRequest
"getNodesWithProperties": processGetNodesWithPropertiesRequest
"getResponsivenessTestingData": processGetResponsivenessTestingDataRequest
"getRootsCount": processGetRootsCountRequest
"getValue": processGetValueRequest
"getValues": processGetValuesRequest
"hasFocus": processHasFocusRequest
"isInFocusChain": processIsInFocusChainRequest
"isShowingOnScreen": processIsShowingOnScreenRequest
"onFieldChangeOnce": processOnFieldChangeOnceRequest
"removeNode": processRemoveNodeRequest
"removeNodeChildren": processRemoveNodeChildrenRequest
"setSettings": processSetSettingsRequest
"setValue": processSetValueRequest
"getAllCount": processGetAllCountRequest
"getRootsCount": processGetRootsCountRequest
"storeNodeReferences": processStoreNodeReferencesRequest
"deleteNodeReferences": processDeleteNodeReferencesRequest
"getNodesInfo": processGetNodesInfoRequest
"getNodesWithProperties": processGetNodesWithPropertiesRequest
"startResponsivenessTesting": processStartResponsivenessTestingRequest
"getResponsivenessTestingData": processGetResponsivenessTestingDataRequest
"stopResponsivenessTesting": processStopResponsivenessTestingRequest
"disableScreenSaver": processDisableScreenSaverRequest
"focusNode": processFocusNodeRequest
"removeNodeChildren": processRemoveNodeChildrenRequest
"isShowingOnScreen": processIsShowingOnScreenRequest
"setSettings": processSetSettingsRequest
"storeNodeReferences": processStoreNodeReferencesRequest
}

m.activeObserveFieldRequests = {}
Expand Down Expand Up @@ -1224,6 +1226,68 @@ function processFocusNodeRequest(request as Object) as Object
return {}
end function

function processCreateChildRequest(request as Object) as Object
args = request.args
result = processGetValueRequest(args)
if RTA_isErrorObject(result) then
return result
end if

if result.found <> true then
keyPath = RTA_getStringAtKeyPath(args, "keyPath")
return RTA_buildErrorResponseObject("No value found at key path '" + keyPath + "'")
end if

parent = result.value
if NOT RTA_isNode(parent) then
keyPath = RTA_getStringAtKeyPath(args, "keyPath")
return RTA_buildErrorResponseObject("Value at key path '" + keyPath + "' was not a node")
end if

nodeSubtype = RTA_getStringAtKeyPath(args, "subtype")
node = parent.createChild(nodeSubtype)
if node <> Invalid then
fields = args.fields
if fields <> invalid then
node.update(fields, true)
end if
else
return RTA_buildErrorResponseObject("Failed to create " + nodeSubtype + " node")
end if

return {}
end function

function processRemoveNodeRequest(request as Object) as Object
args = request.args
result = processGetValueRequest(args)
if RTA_isErrorObject(result) then
return result
end if

if result.found <> true then
keyPath = RTA_getStringAtKeyPath(args, "keyPath")
return RTA_buildErrorResponseObject("No value found at key path '" + keyPath + "'")
end if

node = result.value
if NOT RTA_isNode(node) then
keyPath = RTA_getStringAtKeyPath(args, "keyPath")
return RTA_buildErrorResponseObject("Value at key path '" + keyPath + "' was not a node")
end if

success = false
parent = node.getParent()
if parent <> Invalid then
success = parent.removeChild(node)
if NOT success then
return RTA_buildErrorResponseObject("Failed to remove node")
end if
end if

return {}
end function

function processRemoveNodeChildrenRequest(request as Object) as Object
args = request.args
result = processGetValueRequest(args)
Expand All @@ -1249,7 +1313,10 @@ function processRemoveNodeChildrenRequest(request as Object) as Object
count = node.getChildCount()
end if

node.removeChildrenIndex(count, index)
success = node.removeChildrenIndex(count, index)
if NOT success then
return RTA_buildErrorResponseObject("Failed to remove children")
end if

return {}
end function
Expand Down
6 changes: 1 addition & 5 deletions device/components/RTA_OnDeviceComponentTask.brs
Original file line number Diff line number Diff line change
Expand Up @@ -457,10 +457,6 @@ sub sendBackError(request as Object, message as String)
end sub

sub sendResponseToClient(request as Object, response as Object, binaryPayloadByteArray = Invalid as Dynamic)
if NOT RTA_isBoolean(response.success) then
response.success = true
end if

if request.timespan <> Invalid then
response["timeTaken"] = request.timespan.totalMilliseconds()
request.delete("timeTaken")
Expand Down Expand Up @@ -499,7 +495,7 @@ sub sendResponseToClient(request as Object, response as Object, binaryPayloadByt
if stringPayload.len() < 1024 then
RTA_logDebug("Sending back response for requestType: " + json.type, stringPayload)
else
RTA_logDebug("Sending back large response (id: " + json.id + ", requestType: " + json.type + ", success: " + response.success.toStr() + ", timeTaken: " + response.timeTaken.toStr() + ")")
RTA_logDebug("Sending back large response (id: " + json.id + ", requestType: " + json.type + ", timeTaken: " + response.timeTaken.toStr() + ")")
end if
end if

Expand Down
1 change: 0 additions & 1 deletion device/components/RTA_helpers.brs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ end function

function RTA_buildErrorResponseObject(message as String) as Object
return {
"success": false
"error": {
"message": message
}
Expand Down
2 changes: 1 addition & 1 deletion testProject/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"injectRaleTrackerTask": false,
"injectRdbOnDeviceComponent": true,
"bsConst": {
"ENABLE_RTA": true
"ENABLE_RTA": false
}
}, {
"type": "node",
Expand Down

0 comments on commit e0303f3

Please sign in to comment.