-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Expand file tree
/
Copy pathstore.test.ts
More file actions
158 lines (134 loc) · 5.23 KB
/
Copy pathstore.test.ts
File metadata and controls
158 lines (134 loc) · 5.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import {
createGovernanceStoreFromEnv,
createRedisClientFromUrl,
} from "./store.js";
interface RedisClusterTestOptions {
rootNodes: Array<{ url?: string }>;
defaults?: {
username?: string;
password?: string;
socket?: { tls?: boolean };
};
}
function clusterOptions(redisUrl: string): RedisClusterTestOptions {
const client = createRedisClientFromUrl(redisUrl) as unknown as {
_options: RedisClusterTestOptions;
};
return client._options;
}
describe("createRedisClientFromUrl", () => {
it("propagates ACL credentials and TLS to every cluster node", () => {
expect(
clusterOptions(
"redis-cluster://appsmith:p%40ssword@clustercfg.example.cache.amazonaws.com:6379",
),
).toMatchObject({
rootNodes: [
{
url: "rediss://clustercfg.example.cache.amazonaws.com:6379",
},
],
defaults: {
username: "appsmith",
password: "p@ssword",
socket: { tls: true },
},
});
});
it("secures password-only cluster URLs without forcing an empty ACL username", () => {
expect(
clusterOptions(
"redis-cluster://:secret@clustercfg.example.cache.amazonaws.com:6379",
),
).toMatchObject({
rootNodes: [
{
url: "rediss://clustercfg.example.cache.amazonaws.com:6379",
},
],
defaults: {
password: "secret",
socket: { tls: true },
},
});
});
it("rejects cluster credentials that cannot be safely parsed", () => {
expect(
createRedisClientFromUrl(
"redis-cluster://appsmith:%ZZ@clustercfg.example.cache.amazonaws.com:6379",
),
).toBeUndefined();
});
});
// Unit coverage for the env-driven governance-store factory. MongoClient/redis clients do not open a connection at
// construction time, so these assertions never touch the network — they only exercise the URL-scheme fail-safe.
describe("createGovernanceStoreFromEnv", () => {
const ENV_KEYS = [
"APPSMITH_MONGODB_URI",
"APPSMITH_DB_URL",
"APPSMITH_REDIS_URL",
] as const;
const saved: Record<string, string | undefined> = {};
beforeEach(() => {
for (const key of ENV_KEYS) {
saved[key] = process.env[key];
delete process.env[key];
}
});
afterEach(() => {
for (const key of ENV_KEYS) {
if (saved[key] === undefined) delete process.env[key];
else process.env[key] = saved[key];
}
});
it("returns undefined when the mongo/redis env vars are absent", () => {
expect(createGovernanceStoreFromEnv()).toBeUndefined();
});
it("skips governance (does not throw) when the DB URL is not a Mongo URL", () => {
// APPSMITH_DB_URL points at Postgres on some deployments; handing that to MongoClient would throw at startup.
process.env.APPSMITH_DB_URL =
"postgresql://user:pass@localhost:5432/appsmith";
process.env.APPSMITH_REDIS_URL = "redis://127.0.0.1:6379";
expect(() => createGovernanceStoreFromEnv()).not.toThrow();
expect(createGovernanceStoreFromEnv()).toBeUndefined();
});
it("prefers APPSMITH_DB_URL over APPSMITH_MONGODB_URI when both are set", () => {
// A leftover docker.env Mongo URI must not override the product DB URL (Java/RTS order).
process.env.APPSMITH_DB_URL =
"postgresql://user:pass@localhost:5432/appsmith";
process.env.APPSMITH_MONGODB_URI = "mongodb://127.0.0.1:27017/appsmith";
process.env.APPSMITH_REDIS_URL = "redis://127.0.0.1:6379";
expect(createGovernanceStoreFromEnv()).toBeUndefined();
});
it("builds a store when the DB URL is a MongoDB URL", () => {
process.env.APPSMITH_MONGODB_URI = "mongodb://127.0.0.1:27017/appsmith";
process.env.APPSMITH_REDIS_URL = "redis://127.0.0.1:6379";
expect(createGovernanceStoreFromEnv()).toBeDefined();
});
it("accepts a mongodb+srv URL", () => {
process.env.APPSMITH_MONGODB_URI =
"mongodb+srv://user:pass@cluster.example.net/appsmith";
process.env.APPSMITH_REDIS_URL = "redis://127.0.0.1:6379";
expect(createGovernanceStoreFromEnv()).toBeDefined();
});
it("builds a store for a redis-cluster URL instead of throwing Invalid protocol", () => {
// Cloud / ElastiCache cluster mode uses redis-cluster://, which Java RedisConfig rewrites. node-redis
// createClient rejects that scheme with TypeError("Invalid protocol") and used to crash MCP startup.
process.env.APPSMITH_MONGODB_URI = "mongodb://127.0.0.1:27017/appsmith";
process.env.APPSMITH_REDIS_URL =
"redis-cluster://:secret@clustercfg.example.cache.amazonaws.com:6379";
expect(() => createGovernanceStoreFromEnv()).not.toThrow();
expect(createGovernanceStoreFromEnv()).toBeDefined();
});
it("builds a store for a rediss URL", () => {
process.env.APPSMITH_MONGODB_URI = "mongodb://127.0.0.1:27017/appsmith";
process.env.APPSMITH_REDIS_URL = "rediss://:secret@127.0.0.1:6379";
expect(createGovernanceStoreFromEnv()).toBeDefined();
});
it("skips governance (does not throw) when the Redis URL scheme is unsupported", () => {
process.env.APPSMITH_MONGODB_URI = "mongodb://127.0.0.1:27017/appsmith";
process.env.APPSMITH_REDIS_URL = "http://127.0.0.1:6379";
expect(() => createGovernanceStoreFromEnv()).not.toThrow();
expect(createGovernanceStoreFromEnv()).toBeUndefined();
});
});