Skip to content

Commit

Permalink
Improving coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
robmoffat committed Mar 13, 2024
1 parent 39b2ee9 commit 75500c0
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 32 deletions.
4 changes: 2 additions & 2 deletions packages/da-server/src/BasicFDC3Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ export class BasicFDC3Server implements FDC3Server {

export class DefaultFDC3Server extends BasicFDC3Server {

constructor(sc: ServerContext, directory: Directory, name: string) {
constructor(sc: ServerContext, directory: Directory, name: string, timeoutMs: number = 20000) {
super([
new BroadcastHandler(name),
new IntentHandler(directory)
new IntentHandler(directory, timeoutMs)
], sc)
}
}
20 changes: 13 additions & 7 deletions packages/da-server/src/directory/BasicDirectory.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { Directory, DirectoryApp, DirectoryIntent } from "./DirectoryInterface"

export function genericResultType(rt: string | undefined): string | undefined {
if (rt == undefined) {
return undefined;
} else if (rt.indexOf('channel<') == 0) {
return 'channel';
export function genericResultTypeSame(a: string | undefined, b: string | undefined) {
if (a == b) {
return true;
} else if (a == undefined) {
return true;
} else if (b == undefined) {
return true;
} else if (a.startsWith("channel<") && b == "channel") {
return true;
} else if (b.startsWith("channel<") && a == "channel") {
return true;
} else {
return rt;
return false;
}
}

Expand All @@ -30,7 +36,7 @@ export class BasicDirectory implements Directory {
intentMatches(i: DirectoryIntent, contextType: string | undefined, intentName: string | undefined, resultType: string | undefined): boolean {
return ((intentName == undefined) || (i.intentName == intentName)) &&
((contextType == undefined) || (i.contexts.includes(contextType))) &&
((resultType == undefined) || (i.resultType == resultType) || (genericResultType(i.resultType) == resultType))
(genericResultTypeSame(i.resultType, resultType))
}

retrieveAllIntents(): DirectoryIntent[] {
Expand Down
40 changes: 20 additions & 20 deletions packages/da-server/src/handlers/IntentHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { AppMetadata, ErrorMessage, FindIntentAgentRequest, FindIntentAgentRespo
import { MessageHandler } from "../BasicFDC3Server";
import { ServerContext } from "../ServerContext";
import { Directory } from "../directory/DirectoryInterface";
import { genericResultType } from "../directory/BasicDirectory";
import { genericResultTypeSame } from "../directory/BasicDirectory";
import { ResolveError } from "@finos/fdc3";


type ListenerRegistration = {
appId: string,
appId: string | undefined,
instanceId: string | undefined,
intentName: string,
contextType: string | undefined,
Expand All @@ -25,12 +25,15 @@ function createListenerRegistration(msg: any): ListenerRegistration {
}
}

function matches(template: ListenerRegistration, actual: ListenerRegistration): boolean {
return (template.appId == actual.appId) &&
((template.instanceId == actual.instanceId) || (template.instanceId == undefined)) &&
(template.intentName == actual.intentName) &&
((template.contextType == actual.contextType) || (template.contextType == undefined)) &&
((template.resultType == actual.resultType) || (template.resultType == undefined))
function sameOrUndefined(a: string | undefined, b: string | undefined) {
return (a == b) || (a == undefined) || (b == undefined)
}

function matches(a: ListenerRegistration, b: ListenerRegistration): boolean {
return (sameOrUndefined(a.appId, b.appId)) &&
(a.intentName == b.intentName) &&
(sameOrUndefined(a.contextType, b.contextType)) &&
(genericResultTypeSame(a.resultType, b.resultType))
}

/**
Expand Down Expand Up @@ -100,13 +103,9 @@ class PendingIntent {
}

async accept(arg0: any): Promise<void> {
if (this.complete) {
return
}

if (arg0.type == 'onAddIntentListener') {
const actual = createListenerRegistration(arg0)
if (matches(this.expecting, actual)) {
if (matches(this.expecting, actual) && !this.complete) {
this.complete = true
forwardRequest(this.r, arg0.meta.source, this.sc)
}
Expand All @@ -121,7 +120,7 @@ export class IntentHandler implements MessageHandler {
private readonly regs: ListenerRegistration[] = []
private readonly pendingIntents: Set<PendingIntent> = new Set()

constructor(d: Directory, timeoutMs: number = 8000) {
constructor(d: Directory, timeoutMs: number) {
this.directory = d
this.timeoutMs = timeoutMs
}
Expand Down Expand Up @@ -216,13 +215,14 @@ export class IntentHandler implements MessageHandler {
}

retrieveListeners(contextType: string | undefined, intentName: string, resultType: string | undefined): ListenerRegistration[] {

function matches(i: ListenerRegistration): boolean {
return ((intentName == undefined) || (i.intentName == intentName)) &&
((contextType == undefined) || (i.contextType == contextType)) &&
((resultType == undefined) || (i.resultType == resultType) || (genericResultType(i.resultType) == resultType))
const template: ListenerRegistration = {
appId: undefined,
instanceId: undefined,
contextType,
intentName,
resultType
}

return this.regs.filter(r => matches(r))
return this.regs.filter(r => matches(template, r))
}
}
3 changes: 2 additions & 1 deletion packages/da-server/test/features/broadcast.feature
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ Feature: Relaying Broadcast messages
Then messaging will have outgoing posts
| msg.source.AppId | msg.source.instanceId | msg.payload.context.type |

Scenario: Handle disconnection, channel state synchronisation
Scenario: Handle channel state synchronisation for new apps
When "App1/a1" broadcasts "fdc3.instrument" on "channel1"
And "App1/a1" broadcasts "fdc3.instrument" on "channel1"
And "App2/a2" sends hello
Then messaging will have outgoing posts
| msg.type | msg.payload.requestedName | msg.payload.channelsState['channel1'].length | msg.payload.channelsState['channel1'][0].type |
Expand Down
24 changes: 24 additions & 0 deletions packages/da-server/test/features/intents.feature
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,27 @@ Feature: Responding to Directory Requests about Intents
Then messaging will have outgoing posts
| msg.type | msg.payload.intent | to.instanceId | to.appId | msg.payload.context.type |
| raiseIntentRequest | returnBook | 0 | libraryApp | fdc3.book |

Scenario: Raising An Intent To A Non-Running App without A Context Type in the listener
When "App1/a1" raises an intent for "stampBook" with contextType "fdc3.book" on app "libraryApp"
And "libraryApp/0" registers an intent listener for "stampBook" with contextType "{empty}" and result type "channel<messages>"
Then running apps will be
| appId | instanceId |
| App1 | a1 |
| App1 | b1 |
| libraryApp | 0 |
Then messaging will have outgoing posts
| msg.type | msg.payload.intent | to.instanceId | to.appId | msg.payload.context.type |
| raiseIntentRequest | stampBook | 0 | libraryApp | fdc3.book |

Scenario: Raising An Intent To A Broken App that doesn't add an intent listener
When "App1/a1" raises an intent for "returnBook" with contextType "fdc3.book" on app "libraryApp"
And we wait for the intent timeout
Then running apps will be
| appId | instanceId |
| App1 | a1 |
| App1 | b1 |
| libraryApp | 0 |
Then messaging will have outgoing posts
| msg.type | msg.payload.error | to.instanceId | to.appId |
| raiseIntentResponse | IntentDeliveryFailed | a1 | App1 |
2 changes: 1 addition & 1 deletion packages/da-server/test/step-definitions/generic.steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ Given('A newly instantiated FDC3 Server', function (this: CustomWorld) {


this.sc = new TestServerContext(this)
this.server = new DefaultFDC3Server(this.sc, d, "cucumber-fdc3-server")
this.server = new DefaultFDC3Server(this.sc, d, "cucumber-fdc3-server", 2000)

});
9 changes: 8 additions & 1 deletion packages/da-server/test/step-definitions/intents.steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,11 @@ When('{string} raises an intent for {string} with contextType {string} on app {s
}
} as RaiseIntentAgentRequest
this.server.receive(message, meta.source)
});
});


When('we wait for the intent timeout', function (this: CustomWorld) {
return new Promise<void>((resolve, _reject) => {
setTimeout(() => resolve(), 2100)
})
});

0 comments on commit 75500c0

Please sign in to comment.