Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

bug fixes and unit tests #14

Merged
merged 2 commits into from
Nov 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/get_action_traces.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { socketFactory } from "./config"
import { EOSClient, InboundMessage, InboundMessageType, ActionTrace } from "@dfuse/eosws-js"
import { EoswsClient, InboundMessage, InboundMessageType, ActionTrace } from "@dfuse/eosws-js"

const client = new EOSClient(socketFactory)
const client = new EoswsClient(socketFactory)

interface Transfer {
from: string
Expand Down
7 changes: 3 additions & 4 deletions examples/get_multiple.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { socketFactory } from "./config"
import { EOSClient, OutboundMessageType } from "@dfuse/eosws-js"
import { InboundMessageType } from "../src/client"
import { EoswsClient, OutboundMessageType, InboundMessageType } from "@dfuse/eosws-js"

const client = new EOSClient(socketFactory)
const client = new EoswsClient(socketFactory)

client.connect().then(() => {
const requestRows = client.getTableRows({ code: "eosio", scope: "eosio", tableName: "global" })
Expand All @@ -16,7 +15,7 @@ client.connect().then(() => {
requestRows!.unlisten()
}, 1000)

const requestActions = client.getActions({ account: "eosio.token", actionName: "transfer" })
const requestActions = client.getActionTraces({ account: "eosio.token", actionName: "transfer" })

requestActions!.listen((type: InboundMessageType) => {
console.log("received message of type: ", type)
Expand Down
4 changes: 2 additions & 2 deletions examples/get_table_rows.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EOSClient } from "../src/client/eos-client"
import { EoswsClient } from "../src/client/eosws-client"
import { socketFactory } from "./config"

const client = new EOSClient(socketFactory)
const client = new EoswsClient(socketFactory)

client.connect().then(() => {
const request = client.getTableRows({ code: "eosio", scope: "eosio", tableName: "global" })
Expand Down
12 changes: 8 additions & 4 deletions examples/get_transaction.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { EOSClient } from "../src/client/eos-client"
import { socketFactory } from "./config"
import { InboundMessage, InboundMessageType } from "../src/client"
import { TransactionLifeCycle } from "../src"
import {
EoswsClient,
OutboundMessageType,
InboundMessageType,
TransactionLifeCycle,
InboundMessage
} from "@dfuse/eosws-js"

const client = new EOSClient(socketFactory)
const client = new EoswsClient(socketFactory)

client.connect().then(() => {
const request = client.getTransaction(
Expand Down
10 changes: 5 additions & 5 deletions src/client/__tests__/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createClient, getActionsMessage, InboundMessage, InboundMessageType } from ".."
import { createClient, getActionTracesMessage, InboundMessage, InboundMessageType } from ".."

describe("client", () => {
let controller: ReturnType<typeof createSocketController>
Expand Down Expand Up @@ -145,7 +145,7 @@ describe("client", () => {
setTimeout(() => {
openConnection()
}, 0)
await client.send(getActionsMessage({ account: "test" }))
await client.send(getActionTracesMessage({ account: "test" }))

expect(controller.send).toHaveBeenCalledTimes(1)
})
Expand All @@ -161,7 +161,7 @@ describe("client", () => {
openConnection()
}, 0)

await client.send(getActionsMessage({ account: "test" }))
await client.send(getActionTracesMessage({ account: "test" }))
expect(controller.send).toHaveBeenCalledTimes(1)
})

Expand All @@ -173,11 +173,11 @@ describe("client", () => {

expect.hasAssertions()
await expect(client.connect(noopListener)).resolves.toBeUndefined()
await client.send(getActionsMessage({ account: "test" }))
await client.send(getActionTracesMessage({ account: "test" }, { listen: true }))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to have { listen: true } has the default for getActionTraces. In fact, later on, we should even not permit to not use listen on some of the callbacks (like getActionTraces).


expect(controller.send).toHaveBeenCalledTimes(1)
expect(controller.send).toHaveBeenCalledWith(
'{"type":"get_actions","listen":true,"data":{"account":"test"}}'
'{"type":"get_action_traces","listen":true,"data":{"account":"test"}}'
)
})

Expand Down
Empty file.
115 changes: 115 additions & 0 deletions src/client/__tests__/eosws-client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { EoswsClient } from "../eosws-client"
import { InboundMessage } from "../inbound"
import {
GetActionTracesMessageBackendParameters,
OutboundMessage,
OutboundMessageType
} from "../outbound"

describe("EoswsClient", function() {
let controller: ReturnType<typeof createSocketController>
let factory: () => WebSocket
let receivedMessages: Array<InboundMessage<any>>

beforeEach(() => {
controller = createSocketController()
factory = () => controller as any
receivedMessages = []
})

describe("constructor", () => {
it("should build the client", () => {
const client = new EoswsClient(factory)
expect(client.client).toBeDefined()
})
})

describe("connect", () => {
it("should add a listener", () => {
const client = new EoswsClient(factory)
spyOn(client.client, "connect")
client.connect()
expect(client.client.connect).toHaveBeenCalled()
})
})

describe("send", () => {
it("return a listener if listen is set to true", () => {
const client = new EoswsClient(factory)
expect(
client.send<OutboundMessage<GetActionTracesMessageBackendParameters>>(basicGetActionMessage)
).toEqual({ requestId: "abc", listen: expect.any(Function), unlisten: expect.any(Function) })
})

it("should return null if listen is set to false", () => {
const client = new EoswsClient(factory)
expect(
client.send<OutboundMessage<GetActionTracesMessageBackendParameters>>(
Object.assign({}, basicGetActionMessage, { listen: false })
)
).toEqual(null)
})
})

describe("getActionTraces", () => {
it("should return the same object as the basic send", () => {
const client = new EoswsClient(factory)

expect(
client.getActionTraces(
{ receiver: "test", account: "account_name", actionName: "test" },
{ listen: true, requestId: "abc" }
)
).toEqual({ requestId: "abc", listen: expect.any(Function), unlisten: expect.any(Function) })
})
})

describe("getTableRows", () => {
it("should return the same object as the basic send", () => {
const client = new EoswsClient(factory)

expect(
client.getTableRows(
{ scope: "test", code: "code", tableName: "test" },
{ listen: true, requestId: "abc" }
)
).toEqual({ requestId: "abc", listen: expect.any(Function), unlisten: expect.any(Function) })
})
})

describe("getTransaction", () => {
it("should return the same object as the basic send", () => {
const client = new EoswsClient(factory)

expect(client.getTransaction("id", { listen: true, requestId: "abc" })).toEqual({
requestId: "abc",
listen: expect.any(Function),
unlisten: expect.any(Function)
})
})
})
})

const basicGetActionMessage = {
type: OutboundMessageType.GET_ACTION_TRACES,
listen: true,
req_id: "abc",
data: { receiver: "test", account: "account_name", action_name: "test" }
}

interface WebSocketController {
close: jest.Mock<() => void>
send: jest.Mock<(data: any) => void>

onclose?: (event: CloseEvent) => void
onerror?: (event: Event) => void
onopen?: () => void
onmessage?: (event: MessageEvent) => void
}

function createSocketController(): WebSocketController {
return {
close: jest.fn<() => void>(),
send: jest.fn<(data: any) => void>()
}
}
90 changes: 90 additions & 0 deletions src/client/__tests__/eosws-listeners.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { EoswsListeners, ListenerObject } from "../eosws-listeners"
import { InboundMessageType } from "../inbound"

describe("EoswsListeners", function() {
describe("addListener", () => {
it("should add a listener to the list", () => {
const listenerObject: ListenerObject = {
requestId: "abc",
messageTypes: [InboundMessageType.TABLE_DELTA],
callback: () => {
console.log("test")
}
}

const listeners = new EoswsListeners()

listeners.addListener(listenerObject)

expect(listeners.registeredListeners).toEqual([listenerObject])
})
})

describe("removeListener", () => {
it("should add a listener to the list", () => {
const listenerObject1: ListenerObject = {
requestId: "abc",
messageTypes: [InboundMessageType.TABLE_DELTA],
callback: () => {
console.log("test")
}
}

const listenerObject2: ListenerObject = {
requestId: "abcd",
messageTypes: [InboundMessageType.TABLE_DELTA],
callback: () => {
console.log("test")
}
}

const listeners = new EoswsListeners()

listeners.addListener(listenerObject1)
listeners.addListener(listenerObject2)
expect(listeners.registeredListeners).toEqual([listenerObject1, listenerObject2])

listeners.removeListener("abc")

expect(listeners.registeredListeners).toEqual([listenerObject2])
})
})

describe("handleMessage", () => {
it("should process the callback given the right id and type", () => {
const listenerObject1: ListenerObject = {
requestId: "abc",
messageTypes: [InboundMessageType.TABLE_DELTA],
callback: () => {
console.log("test")
}
}

spyOn(listenerObject1, "callback")

const listenerObject2: ListenerObject = {
requestId: "abcd",
messageTypes: [InboundMessageType.TABLE_DELTA],
callback: () => {
console.log("test")
}
}
const listeners = new EoswsListeners()

listeners.addListener(listenerObject1)
listeners.addListener(listenerObject2)

listeners.handleMessage(InboundMessageType.TABLE_DELTA, {
type: InboundMessageType.TABLE_DELTA,
req_id: "abc",
data: { test: "foo" }
})

expect(listenerObject1.callback).toHaveBeenCalledWith(InboundMessageType.TABLE_DELTA, {
type: InboundMessageType.TABLE_DELTA,
req_id: "abc",
data: { test: "foo" }
})
})
})
})
3 changes: 0 additions & 3 deletions src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ export type ClientMessageListener = (type: InboundMessageType, message: InboundM

export interface ClientOptions {
id?: string

autoReconnect?: boolean

onInvalidMessage?: (message: object) => void

onReconnect?: () => void
onError?: () => void
onClose?: () => void
Expand Down
31 changes: 9 additions & 22 deletions src/client/eos-client.ts → src/client/eosws-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,36 @@ import {
GetTableRowsMessageParameters,
getTransactionMessage,
OutboundMessage,
OutboundMessageType,
StreamOptions,
unlistenMessage
} from "./outbound"
import { InboundMessage, InboundMessageType } from "./inbound"
import { EoswsListeners } from "./eosws-listeners"

export class EOSClient {
private client: Client
private registeredListeners: ListenerObject[] = []
export class EoswsClient {
public client: Client
public listeners: EoswsListeners

constructor(socketFactory: SocketFactory, options?: ClientOptions) {
this.client = createClient(socketFactory, options)
}

private registerListener(listener: ListenerObject) {
this.registeredListeners.push(listener)
this.listeners = new EoswsListeners()
}

public connect(): Promise<void> {
const onMessage = (type: InboundMessageType, message: InboundMessage<any>) => {
this.registeredListeners.forEach((listener: ListenerObject) => {
if (listener.messageTypes.indexOf(type) > -1 && message.req_id === listener.requestId) {
listener.callback(type, message)
}
})
this.listeners.handleMessage(type, message)
}

return this.client.connect(onMessage)
}

public send<T extends OutboundMessage<{}>>(
type: OutboundMessageType,
messageOptions: T,
...messageTypes: InboundMessageType[]
) {
return this.sendAndListen<T>(
messageOptions,
messageOptions.req_id === undefined ? type : messageOptions.req_id,
messageOptions.req_id === undefined ? messageOptions.type : messageOptions.req_id,
messageOptions.listen === undefined ? true : messageOptions.listen,
...messageTypes
)
Expand Down Expand Up @@ -110,7 +102,7 @@ export class EOSClient {
) {
const listen = (callback: ClientMessageListener) => {
try {
this.registerListener({ messageTypes, requestId, callback })
this.listeners.addListener({ messageTypes, requestId, callback })
} finally {
this.client.send(parameters)
}
Expand All @@ -124,6 +116,7 @@ export class EOSClient {
}

private unlisten(requestId: string) {
this.listeners.removeListener(requestId)
this.client.send(unlistenMessage(requestId))
}
}
Expand All @@ -135,9 +128,3 @@ function withDefaults(defaults: any, options: StreamOptions): StreamOptions {

return Object.assign({}, { requestId: randomRequestId }, defaults, options)
}

interface ListenerObject {
messageTypes: InboundMessageType[]
requestId: string
callback: ClientMessageListener
}
Loading