mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
chore: Fix Redis mock not used consistently in tests (#9716)
This commit is contained in:
@@ -8,7 +8,7 @@ build:
|
||||
docker compose build --pull outline
|
||||
|
||||
test:
|
||||
docker compose up -d redis postgres
|
||||
docker compose up -d postgres
|
||||
NODE_ENV=test yarn sequelize db:drop
|
||||
NODE_ENV=test yarn sequelize db:create
|
||||
NODE_ENV=test yarn sequelize db:migrate
|
||||
|
||||
+3
-3
@@ -24,8 +24,8 @@ import { checkUpdates } from "./utils/updates";
|
||||
import onerror from "./onerror";
|
||||
import ShutdownHelper, { ShutdownOrder } from "./utils/ShutdownHelper";
|
||||
import { checkConnection, sequelize } from "./storage/database";
|
||||
import RedisAdapter from "./storage/redis";
|
||||
import Metrics from "./logging/Metrics";
|
||||
import Redis from "@server/storage/redis";
|
||||
import Metrics from "@server/logging/Metrics";
|
||||
import { PluginManager } from "./utils/PluginManager";
|
||||
|
||||
// The number of processes to run, defaults to the number of CPU's available
|
||||
@@ -149,7 +149,7 @@ async function start(_id: number, disconnect: () => void) {
|
||||
}
|
||||
|
||||
try {
|
||||
await RedisAdapter.defaultClient.ping();
|
||||
await Redis.defaultClient.ping();
|
||||
} catch (err) {
|
||||
Logger.error("Redis ping failed", err);
|
||||
ctx.status = 500;
|
||||
|
||||
+53
-22
@@ -1,29 +1,60 @@
|
||||
import { createQueue } from "@server/queues/queue";
|
||||
|
||||
export const globalEventQueue = createQueue("globalEvents", {
|
||||
attempts: 5,
|
||||
backoff: {
|
||||
type: "exponential",
|
||||
delay: 1000,
|
||||
let _globalEventQueue: ReturnType<typeof createQueue> | undefined;
|
||||
let _processorEventQueue: ReturnType<typeof createQueue> | undefined;
|
||||
let _websocketQueue: ReturnType<typeof createQueue> | undefined;
|
||||
let _taskQueue: ReturnType<typeof createQueue> | undefined;
|
||||
|
||||
export const globalEventQueue = new Proxy(
|
||||
{} as ReturnType<typeof createQueue>,
|
||||
{
|
||||
get(_target, prop) {
|
||||
_globalEventQueue ||= createQueue("globalEvents", {
|
||||
attempts: 5,
|
||||
backoff: {
|
||||
type: "exponential",
|
||||
delay: 1000,
|
||||
},
|
||||
});
|
||||
return _globalEventQueue[prop as keyof typeof _globalEventQueue];
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export const processorEventQueue = new Proxy(
|
||||
{} as ReturnType<typeof createQueue>,
|
||||
{
|
||||
get(_target, prop) {
|
||||
_processorEventQueue ||= createQueue("processorEvents", {
|
||||
attempts: 5,
|
||||
backoff: {
|
||||
type: "exponential",
|
||||
delay: 10 * 1000,
|
||||
},
|
||||
});
|
||||
return _processorEventQueue[prop as keyof typeof _processorEventQueue];
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export const websocketQueue = new Proxy({} as ReturnType<typeof createQueue>, {
|
||||
get(_target, prop) {
|
||||
_websocketQueue ||= createQueue("websockets", {
|
||||
timeout: 10 * 1000,
|
||||
});
|
||||
return _websocketQueue[prop as keyof typeof _websocketQueue];
|
||||
},
|
||||
});
|
||||
|
||||
export const processorEventQueue = createQueue("processorEvents", {
|
||||
attempts: 5,
|
||||
backoff: {
|
||||
type: "exponential",
|
||||
delay: 10 * 1000,
|
||||
},
|
||||
});
|
||||
|
||||
export const websocketQueue = createQueue("websockets", {
|
||||
timeout: 10 * 1000,
|
||||
});
|
||||
|
||||
export const taskQueue = createQueue("tasks", {
|
||||
attempts: 5,
|
||||
backoff: {
|
||||
type: "exponential",
|
||||
delay: 10 * 1000,
|
||||
export const taskQueue = new Proxy({} as ReturnType<typeof createQueue>, {
|
||||
get(_target, prop) {
|
||||
_taskQueue ||= createQueue("tasks", {
|
||||
attempts: 5,
|
||||
backoff: {
|
||||
type: "exponential",
|
||||
delay: 10 * 1000,
|
||||
},
|
||||
});
|
||||
return _taskQueue[prop as keyof typeof _taskQueue];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import snakeCase from "lodash/snakeCase";
|
||||
import { Second } from "@shared/utils/time";
|
||||
import env from "@server/env";
|
||||
import Metrics from "@server/logging/Metrics";
|
||||
import Redis from "@server/storage/redis";
|
||||
import Redis from "../storage/redis";
|
||||
import ShutdownHelper, { ShutdownOrder } from "@server/utils/ShutdownHelper";
|
||||
|
||||
export function createQueue(
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
import "reflect-metadata";
|
||||
import sharedEnv from "@shared/env";
|
||||
import env from "@server/env";
|
||||
import Redis from "@server/storage/redis";
|
||||
|
||||
require("@server/storage/database");
|
||||
|
||||
jest.mock("bull");
|
||||
|
||||
// Enable mocks for Redis-related modules
|
||||
jest.mock("@server/storage/redis");
|
||||
jest.mock("@server/utils/MutexLock");
|
||||
jest.mock("@server/utils/CacheHelper");
|
||||
|
||||
// This is needed for the relative manual mock to be picked up
|
||||
jest.mock("../queues");
|
||||
|
||||
// We never want to make real S3 requests in test environment
|
||||
jest.mock("@aws-sdk/client-s3", () => ({
|
||||
S3Client: jest.fn(() => ({
|
||||
@@ -39,10 +33,6 @@ jest.mock("@aws-sdk/s3-request-presigner", () => ({
|
||||
getSignedUrl: jest.fn(),
|
||||
}));
|
||||
|
||||
afterAll(() => {
|
||||
Redis.defaultClient.disconnect();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
env.URL = sharedEnv.URL = "https://app.outline.dev";
|
||||
});
|
||||
|
||||
@@ -20,13 +20,20 @@ export default class RateLimiter {
|
||||
duration: env.RATE_LIMITER_DURATION_WINDOW,
|
||||
});
|
||||
|
||||
static readonly defaultRateLimiter = new RateLimiterRedis({
|
||||
storeClient: Redis.defaultClient,
|
||||
points: env.RATE_LIMITER_REQUESTS,
|
||||
duration: env.RATE_LIMITER_DURATION_WINDOW,
|
||||
keyPrefix: this.RATE_LIMITER_REDIS_KEY_PREFIX,
|
||||
insuranceLimiter: this.insuranceRateLimiter,
|
||||
});
|
||||
private static _defaultRateLimiter: RateLimiterRedis | undefined;
|
||||
|
||||
static get defaultRateLimiter(): RateLimiterRedis {
|
||||
if (!this._defaultRateLimiter) {
|
||||
this._defaultRateLimiter = new RateLimiterRedis({
|
||||
storeClient: Redis.defaultClient,
|
||||
points: env.RATE_LIMITER_REQUESTS,
|
||||
duration: env.RATE_LIMITER_DURATION_WINDOW,
|
||||
keyPrefix: this.RATE_LIMITER_REDIS_KEY_PREFIX,
|
||||
insuranceLimiter: this.insuranceRateLimiter,
|
||||
});
|
||||
}
|
||||
return this._defaultRateLimiter;
|
||||
}
|
||||
|
||||
static getRateLimiter(path: string): RateLimiterRedis {
|
||||
return this.rateLimiterMap.get(path) || this.defaultRateLimiter;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { randomInt } from "crypto";
|
||||
import { Minute } from "@shared/utils/time";
|
||||
import RedisAdapter from "@server/storage/redis";
|
||||
import Redis from "@server/storage/redis";
|
||||
|
||||
/**
|
||||
* This class manages verification codes for email authentication.
|
||||
@@ -8,9 +8,11 @@ import RedisAdapter from "@server/storage/redis";
|
||||
*/
|
||||
export class VerificationCode {
|
||||
/**
|
||||
* Redis client instance
|
||||
* Redis client instance (lazy initialized)
|
||||
*/
|
||||
private static redis = RedisAdapter.defaultClient;
|
||||
private static get redis() {
|
||||
return Redis.defaultClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* TTL for verification codes in milliseconds (10 minutes)
|
||||
|
||||
Reference in New Issue
Block a user