diff --git a/backend/src/apis/IotaConnector.test.ts b/backend/src/apis/IotaConnector.test.ts index aee1095fb..160503c7b 100644 --- a/backend/src/apis/IotaConnector.test.ts +++ b/backend/src/apis/IotaConnector.test.ts @@ -1,59 +1,44 @@ -import { IndexationPayload } from '@iota/client/lib/types' - -import { sendDataMessage, getMessage, getAllMessages } from '@/apis/IotaConnector' +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import { IotaClientSingleton } from '@/apis/IotaConnector' import { CONFIG } from '@/config' -jest.mock('@/config', () => ({ - CONFIG: { - IOTA: true, - IOTA_COMMUNITY_ALIAS: 'GRADIDO: TestHelloWelt1', - IOTA_API_URL: 'https://chrysalis-nodes.iota.org', - }, -})) +CONFIG.IOTA = true +CONFIG.IOTA_COMMUNITY_ALIAS = 'GRADIDO: TestHelloWelt1' +CONFIG.IOTA_API_URL = 'https://chrysalis-nodes.iota.org' describe('apis/IotaConnector/enabled', () => { describe('Hello World', () => { const now = new Date() - let messageId = '' + let messageId: string const messageString = 'Hello World - ' + now.toString() const messageHexString = Buffer.from(messageString, 'utf8').toString('hex') const indexHexString = Buffer.from(CONFIG.IOTA_COMMUNITY_ALIAS, 'utf8').toString('hex') + const iota = IotaClientSingleton.getInstance() it('sends hello world message to iota tangle', async () => { - const iotaMessage = await sendDataMessage(messageString) - expect(iotaMessage).not.toBeNull() - if (iotaMessage) { - const indexationPayload = iotaMessage.message.payload as IndexationPayload - expect(indexationPayload.data).toBe(messageHexString) - expect(indexationPayload.index).toBe(indexHexString) - messageId = iotaMessage.messageId - } + const iotaMessage = await iota?.sendDataMessage(messageString) + expect(iotaMessage).toMatchObject({ + message: { + payload: { + data: messageHexString, + index: indexHexString, + }, + }, + messageId: expect.any(String), + }) + messageId = + iotaMessage?.messageId ?? '5498130bc3918e1a7143969ce05805502417e3e1bd596d3c44d6a0adeea22710' }) it('receives hello world message from iota tangle by message id', async () => { - const iotaMessage = await getMessage(messageId) - expect(iotaMessage).not.toBeNull() - if (iotaMessage) { - const indexationPayload = iotaMessage.message.payload as IndexationPayload - expect(indexationPayload.data).toBe(messageHexString) - expect(indexationPayload.index).toBe(indexHexString) - } - }) - it('receives hello world message from iota tangle by searching throw all', async () => { - const iotaMessages = await getAllMessages() - expect(iotaMessages).not.toBeNull() - if (iotaMessages) { - let foundMessage = false - for (const messageId of iotaMessages) { - const iotaMessage = await getMessage(messageId) - if (iotaMessage) { - const indexationPayload = iotaMessage.message.payload as IndexationPayload - if (indexationPayload.data.toString() === messageHexString) { - foundMessage = true - break - } - } - } - expect(foundMessage).toBeTruthy() - } + const iotaMessage = await iota?.getMessage(messageId) + expect(iotaMessage).toMatchObject({ + message: { + payload: { + data: messageHexString, + index: indexHexString, + }, + }, + messageId, + }) }) }) }) diff --git a/backend/src/apis/IotaConnector.ts b/backend/src/apis/IotaConnector.ts index 0a7392ed0..58a537dc5 100644 --- a/backend/src/apis/IotaConnector.ts +++ b/backend/src/apis/IotaConnector.ts @@ -12,8 +12,9 @@ import { backendLogger as logger } from '@/server/logger' */ // eslint-disable-next-line @typescript-eslint/no-extraneous-class class IotaClientSingleton { - private static IotaClient: Client - + // eslint-disable-next-line no-use-before-define + private static instance: IotaClientSingleton + private client: Client /** * The Singleton's constructor should always be private to prevent direct * construction calls with the `new` operator. @@ -27,56 +28,40 @@ class IotaClientSingleton { * This implementation let you subclass the Singleton class while keeping * just one instance of each subclass around. */ - public static getInstance(): Client | null { + public static getInstance(): IotaClientSingleton | null { if (!CONFIG.IOTA || !CONFIG.IOTA_API_URL) { logger.info(`Iota are disabled via config...`) return null } - if (!IotaClientSingleton.IotaClient) { - IotaClientSingleton.IotaClient = new ClientBuilder().node(CONFIG.IOTA_API_URL).build() + if (!IotaClientSingleton.instance) { + IotaClientSingleton.instance = new IotaClientSingleton() + IotaClientSingleton.instance.client = new ClientBuilder().node(CONFIG.IOTA_API_URL).build() } - return IotaClientSingleton.IotaClient + return IotaClientSingleton.instance + } + + /** + * send data message onto iota tangle + * use CONFIG.IOTA_COMMUNITY_ALIAS for index + * @param {string} message - the message as utf based string, will be converted to hex automatically from @iota/client + * @return {Promise} the iota message typed + */ + public sendDataMessage(message: string): Promise { + return this.client.message().index(CONFIG.IOTA_COMMUNITY_ALIAS).data(message).submit() + } + + /** + * receive message for known message id from iota tangle + * @param {string} messageId - as hex string + * @return {Promise} the iota message typed + */ + public getMessage(messageId: string): Promise { + return this.client.getMessage().data(messageId) } } -/** - * send data message onto iota tangle - * use CONFIG.IOTA_COMMUNITY_ALIAS for index - * @param {string} message - the message as utf based string, will be converted to hex automatically from @iota/client - * @return {MessageWrapper|null} the iota message as json object with transaction data from iota or null if iota is disabled in config - */ -export const sendDataMessage = (message: string): Promise | null => { - const client = IotaClientSingleton.getInstance() - if (!client) { - return null - } - return client.message().index(CONFIG.IOTA_COMMUNITY_ALIAS).data(message).submit() -} - -/** - * receive message for known message id from iota tangle - * @param {string} messageId - as hex string - * @return {MessageWrapper|null} the iota message as json object with transaction data from iota or null if iota is disabled in config - */ -export const getMessage = (messageId: string): Promise | null => { - const client = IotaClientSingleton.getInstance() - if (!client) { - return null - } - return client.getMessage().data(messageId) -} -/** - * receive all message ids belonging to our topic from iota tangle - * @returns array of messageIds - */ -export const getAllMessages = (): Promise | null => { - const client = IotaClientSingleton.getInstance() - if (!client) { - return null - } - return client.getMessage().index(CONFIG.IOTA_COMMUNITY_ALIAS) -} +export { IotaClientSingleton } /** * example for message: diff --git a/backend/src/apis/IotaConnector_disabled.test.ts b/backend/src/apis/IotaConnector_disabled.test.ts index be9a3c721..6169ef71f 100644 --- a/backend/src/apis/IotaConnector_disabled.test.ts +++ b/backend/src/apis/IotaConnector_disabled.test.ts @@ -1,19 +1,11 @@ -import { sendDataMessage, getMessage, getAllMessages } from '@/apis/IotaConnector' +import { IotaClientSingleton } from '@/apis/IotaConnector' jest.mock('@/config', () => ({ CONFIG: { IOTA: false }, })) describe('apis/IotaConnector/disabled', () => { - describe('disabled', () => { - it('sendDataMessage return null if iota is disabled', () => { - expect(sendDataMessage('empty')).toBeNull() - }) - it('getMessage return null if iota is disabled', () => { - expect(getMessage('empty')).toBeNull() - }) - it('getAllMessages return null if iota is disabled', () => { - expect(getAllMessages()).toBeNull() - }) + it('getInstance return null if iota is disabled', () => { + expect(IotaClientSingleton.getInstance()).toBeNull() }) })