From ba50ace8cbe174d8eded3d422d4d038ca743585e Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 27 Jun 2024 17:09:57 +0100 Subject: [PATCH] Removing more mocking. --- packages/pro | 2 +- .../src/api/routes/tests/application.spec.ts | 13 -- .../src/automations/tests/automation.spec.ts | 10 +- packages/server/src/integrations/redis.ts | 32 +--- .../src/integrations/tests/redis.spec.ts | 146 +++++++----------- packages/server/src/utilities/redis.ts | 5 +- packages/server/src/websockets/index.ts | 10 +- 7 files changed, 69 insertions(+), 149 deletions(-) diff --git a/packages/pro b/packages/pro index 6c8d0174ca..e34078a347 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit 6c8d0174ca58c578a37022965ddb923fdbf8e32a +Subproject commit e34078a347f8a1f6ad7d2e13b64bbeb95d8577c4 diff --git a/packages/server/src/api/routes/tests/application.spec.ts b/packages/server/src/api/routes/tests/application.spec.ts index c204eb3712..fcf363a21e 100644 --- a/packages/server/src/api/routes/tests/application.spec.ts +++ b/packages/server/src/api/routes/tests/application.spec.ts @@ -1,16 +1,3 @@ -jest.mock("../../../utilities/redis", () => ({ - init: jest.fn(), - getLocksById: () => { - return {} - }, - doesUserHaveLock: () => { - return true - }, - updateLock: jest.fn(), - setDebounce: jest.fn(), - checkDebounce: jest.fn(), - shutdown: jest.fn(), -})) import { checkBuilderEndpoint } from "./utilities/TestFunctions" import { AppStatus } from "../../../db/utils" import { events, utils, context } from "@budibase/backend-core" diff --git a/packages/server/src/automations/tests/automation.spec.ts b/packages/server/src/automations/tests/automation.spec.ts index 857be01472..58225e4b3f 100644 --- a/packages/server/src/automations/tests/automation.spec.ts +++ b/packages/server/src/automations/tests/automation.spec.ts @@ -1,12 +1,4 @@ jest.mock("../../threads/automation") -jest.mock("../../utilities/redis", () => ({ - init: jest.fn(), - checkTestFlag: () => { - return false - }, - shutdown: jest.fn(), -})) - jest.spyOn(global.console, "error") import "../../environment" @@ -36,6 +28,7 @@ describe("Run through some parts of the automations system", () => { it("should be able to init in builder", async () => { const automation: Automation = { ...basicAutomation(), + _id: "test", appId: config.appId!, } const fields: any = { a: 1, appId: config.appId } @@ -47,6 +40,7 @@ describe("Run through some parts of the automations system", () => { it("should check coercion", async () => { const table = await config.createTable() const automation: any = basicAutomation() + automation._id = "test" automation.definition.trigger.inputs.tableId = table._id automation.definition.trigger.stepId = "APP" automation.definition.trigger.inputs.fields = { a: "number" } diff --git a/packages/server/src/integrations/redis.ts b/packages/server/src/integrations/redis.ts index e127cddd56..1ae9cd127e 100644 --- a/packages/server/src/integrations/redis.ts +++ b/packages/server/src/integrations/redis.ts @@ -5,17 +5,9 @@ import { Integration, QueryType, } from "@budibase/types" -import Redis from "ioredis" +import Redis, { RedisOptions } from "ioredis" import { HOST_ADDRESS } from "./utils" -interface RedisConfig { - host: string - port: number - username: string - password?: string - db?: number -} - const SCHEMA: Integration = { docs: "https://redis.io/docs/", description: @@ -95,19 +87,13 @@ const SCHEMA: Integration = { }, } -class RedisIntegration { - private readonly config: RedisConfig +export class RedisIntegration { + private readonly config: RedisOptions private client - constructor(config: RedisConfig) { + constructor(config: RedisOptions) { this.config = config - this.client = new Redis({ - host: this.config.host, - port: this.config.port, - username: this.config.username, - password: this.config.password, - db: this.config.db, - }) + this.client = new Redis(this.config) } async testConnection() { @@ -163,21 +149,19 @@ class RedisIntegration { async command(query: { json: string }) { return this.redisContext(async () => { - // commands split line by line const commands = query.json.trim().split("\n") let pipelineCommands = [] let tokenised - // process each command separately for (let command of commands) { - const valueToken = command.trim().match(/".*"/) - if (valueToken?.[0]) { + const valueToken = command.trim().match(/"(.*)"/) + if (valueToken?.[1]) { tokenised = [ ...command .substring(0, command.indexOf(valueToken[0]) - 1) .trim() .split(" "), - valueToken?.[0], + valueToken?.[1], ] } else { tokenised = command.trim().split(" ") diff --git a/packages/server/src/integrations/tests/redis.spec.ts b/packages/server/src/integrations/tests/redis.spec.ts index bec0e53bc3..67997e9e55 100644 --- a/packages/server/src/integrations/tests/redis.spec.ts +++ b/packages/server/src/integrations/tests/redis.spec.ts @@ -1,106 +1,68 @@ -const Redis = require("ioredis-mock") - -import { default as RedisIntegration } from "../redis" - -class TestConfiguration { - integration: any - - constructor(config: any = {}) { - this.integration = new RedisIntegration.integration(config) - // have to kill the basic integration before replacing it - this.integration.client.quit() - this.integration.client = new Redis({ - data: { - test: "test", - result: "1", - }, - }) - } -} +import { redis } from "@budibase/backend-core" +import { RedisIntegration } from "../redis" +import { Redis, RedisOptions } from "ioredis" +import { randomUUID } from "crypto" describe("Redis Integration", () => { - let config: any + let integration: RedisIntegration + let client: Redis beforeEach(() => { - config = new TestConfiguration() - }) - - afterAll(() => { - config.integration.disconnect() - }) - - it("calls the create method with the correct params", async () => { - const body = { - key: "key", - value: "value", + const { host, password, port } = redis.utils.getRedisConnectionDetails() + if (!host) { + throw new Error("Redis host not found") } - await config.integration.create(body) - expect(await config.integration.client.get("key")).toEqual("value") + if (!port) { + throw new Error("Redis port not found") + } + if (!password) { + throw new Error("Redis password not found") + } + + const config: RedisOptions = { + host, + port, + password, + } + + integration = new RedisIntegration(config) + client = new Redis(config) }) - it("calls the read method with the correct params", async () => { - const body = { - key: "test", - } - const response = await config.integration.read(body) + afterEach(async () => { + await client.flushall() + await client.quit() + }) + + it("can write", async () => { + const key = randomUUID() + await integration.create({ key, value: "value", ttl: 100 }) + expect(await client.get(key)).toEqual("value") + }) + + it("can read", async () => { + const key = randomUUID() + await client.set(key, "test") + const response = await integration.read({ key }) expect(response).toEqual("test") }) - it("calls the delete method with the correct params", async () => { - const body = { - key: "test", - } - await config.integration.delete(body) - expect(await config.integration.client.get(body.key)).toEqual(null) + it("can delete", async () => { + const key = randomUUID() + await client.set(key, "test") + expect(await client.get(key)).toEqual("test") + + await integration.delete({ key }) + expect(await client.get(key)).toEqual(null) }) - it("calls the pipeline method with the correct params", async () => { - const body = { - json: "KEYS *", - } - - // ioredis-mock doesn't support pipelines - config.integration.client.pipeline = jest.fn(() => ({ - exec: jest.fn(() => [[]]), - })) - - await config.integration.command(body) - expect(config.integration.client.pipeline).toHaveBeenCalledWith([ - ["keys", "*"], - ]) - }) - - it("calls the pipeline method with several separated commands when there are newlines", async () => { - const body = { - json: 'SET foo "bar"\nGET foo', - } - - // ioredis-mock doesn't support pipelines - config.integration.client.pipeline = jest.fn(() => ({ - exec: jest.fn(() => [[]]), - })) - - await config.integration.command(body) - expect(config.integration.client.pipeline).toHaveBeenCalledWith([ - ["set", "foo", '"bar"'], - ["get", "foo"], - ]) - }) - - it("calls the pipeline method with double quoted phrase values", async () => { - const body = { - json: 'SET foo "What a wonderful world!"\nGET foo', - } - - // ioredis-mock doesn't support pipelines - config.integration.client.pipeline = jest.fn(() => ({ - exec: jest.fn(() => [[]]), - })) - - await config.integration.command(body) - expect(config.integration.client.pipeline).toHaveBeenCalledWith([ - ["set", "foo", '"What a wonderful world!"'], - ["get", "foo"], - ]) + it("can run pipelines commands", async () => { + const key1 = randomUUID() + const key2 = randomUUID() + await integration.command({ + json: `SET ${key1} "bar"\n SET ${key2} "hello world"`, + }) + expect(await client.get(key1)).toEqual("bar") + expect(await client.get(key2)).toEqual("hello world") }) }) diff --git a/packages/server/src/utilities/redis.ts b/packages/server/src/utilities/redis.ts index a4154b7b95..75d68ccf20 100644 --- a/packages/server/src/utilities/redis.ts +++ b/packages/server/src/utilities/redis.ts @@ -1,7 +1,6 @@ import { redis, RedisClient } from "@budibase/backend-core" import { getGlobalIDFromUserMetadataID } from "../db/utils" import { ContextUser } from "@budibase/types" -import env from "../environment" const APP_DEV_LOCK_SECONDS = 600 const AUTOMATION_TEST_FLAG_SECONDS = 60 @@ -25,9 +24,7 @@ export async function init() { // Duplicate the socket client for pub/sub socketClient = await redis.clients.getSocketClient() - if (!env.isTest()) { - socketSubClient = socketClient.getClient().duplicate() - } + socketSubClient = socketClient.getClient().duplicate() } export async function shutdown() { diff --git a/packages/server/src/websockets/index.ts b/packages/server/src/websockets/index.ts index bb530b559e..5e312233c1 100644 --- a/packages/server/src/websockets/index.ts +++ b/packages/server/src/websockets/index.ts @@ -3,19 +3,15 @@ import Koa from "koa" import ClientAppSocket from "./client" import GridSocket from "./grid" import BuilderSocket from "./builder" -import env from "../environment" let clientAppSocket: ClientAppSocket | undefined let gridSocket: GridSocket | undefined let builderSocket: BuilderSocket | undefined export const initialise = (app: Koa, server: http.Server) => { - // have to remove these for testing until ioredis-mock can be fully removed - if (!env.isTest()) { - clientAppSocket = new ClientAppSocket(app, server) - gridSocket = new GridSocket(app, server) - builderSocket = new BuilderSocket(app, server) - } + clientAppSocket = new ClientAppSocket(app, server) + gridSocket = new GridSocket(app, server) + builderSocket = new BuilderSocket(app, server) } export { clientAppSocket, gridSocket, builderSocket }