This is an automated email from the ASF dual-hosted git repository.
lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git
The following commit(s) were added to refs/heads/rocketmq-studio by this push:
new 717d4577 fix(web): initialize data mode from VITE_USE_MOCK (#1503)
717d4577 is described below
commit 717d4577a8c757ee0c973f6f127a1b6d4e01b58f
Author: majialong <[email protected]>
AuthorDate: Tue Aug 11 20:18:29 2026 +0800
fix(web): initialize data mode from VITE_USE_MOCK (#1503)
---
web/.env.test | 2 ++
web/src/App.test.tsx | 14 ++++++++-
web/src/stores/dataModeStore.test.ts | 58 ++++++++++++++++++++++++++++++++++++
web/src/stores/dataModeStore.ts | 4 ++-
4 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/web/.env.test b/web/.env.test
new file mode 100644
index 00000000..eb2b6dab
--- /dev/null
+++ b/web/.env.test
@@ -0,0 +1,2 @@
+# Keep tests in real-API mode unless a test explicitly selects mock data.
+VITE_USE_MOCK=false
diff --git a/web/src/App.test.tsx b/web/src/App.test.tsx
index 3a5d69ec..3643293d 100644
--- a/web/src/App.test.tsx
+++ b/web/src/App.test.tsx
@@ -28,8 +28,10 @@ vi.mock('./api/auth', async (importOriginal) => {
return { ...actual, getAuthStatus: vi.fn() };
});
+const dataModeMocks = vi.hoisted(() => ({ isMockMode: vi.fn(() => false) }));
+
vi.mock('./config', () => ({ API_BASE_URL: '/api', USE_MOCK: false }));
-vi.mock('./services/dataMode', () => ({ isMockMode: () => false }));
+vi.mock('./services/dataMode', () => dataModeMocks);
const mockedGetAuthStatus = vi.mocked(getAuthStatus);
@@ -85,6 +87,7 @@ function renderGate() {
describe('AuthGate', () => {
beforeEach(() => {
mockedGetAuthStatus.mockReset();
+ dataModeMocks.isMockMode.mockReturnValue(false);
localStorage.setItem('token', 'stale-token');
localStorage.setItem('rocketmq-studio-user', 'admin');
});
@@ -94,6 +97,15 @@ describe('AuthGate', () => {
localStorage.clear();
});
+ it('skips the authentication status request in mock mode', async () => {
+ dataModeMocks.isMockMode.mockReturnValue(true);
+
+ renderGate();
+
+ expect(await screen.findByText('protected content')).toBeInTheDocument();
+ expect(mockedGetAuthStatus).not.toHaveBeenCalled();
+ });
+
it('allows protected routes when login protection is disabled', async () => {
mockedGetAuthStatus.mockResolvedValue({ loginRequired: false,
authenticated: false });
diff --git a/web/src/stores/dataModeStore.test.ts
b/web/src/stores/dataModeStore.test.ts
new file mode 100644
index 00000000..75c94d41
--- /dev/null
+++ b/web/src/stores/dataModeStore.test.ts
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { afterEach, describe, expect, it, vi } from 'vitest';
+
+const STORAGE_KEY = 'rocketmq-studio-data-mode';
+
+async function loadStore(envValue: string, persistedValue?: boolean) {
+ vi.stubEnv('VITE_USE_MOCK', envValue);
+ vi.resetModules();
+ if (persistedValue !== undefined) {
+ localStorage.setItem(
+ STORAGE_KEY,
+ JSON.stringify({ state: { useMock: persistedValue }, version: 0 }),
+ );
+ }
+ return (await import('./dataModeStore')).useDataModeStore;
+}
+
+describe('dataModeStore', () => {
+ afterEach(() => {
+ vi.unstubAllEnvs();
+ vi.resetModules();
+ localStorage.clear();
+ });
+
+ it.each([
+ ['true', true],
+ ['false', false],
+ ])('uses VITE_USE_MOCK=%s as the initial mode', async (envValue, expected)
=> {
+ const store = await loadStore(envValue);
+
+ expect(store.getState().useMock).toBe(expected);
+ });
+
+ it.each([
+ ['true', false],
+ ['false', true],
+ ])('prefers a persisted mode over VITE_USE_MOCK=%s', async (envValue,
persistedValue) => {
+ const store = await loadStore(envValue, persistedValue);
+
+ expect(store.getState().useMock).toBe(persistedValue);
+ });
+});
diff --git a/web/src/stores/dataModeStore.ts b/web/src/stores/dataModeStore.ts
index 195c40be..8fc8f67b 100644
--- a/web/src/stores/dataModeStore.ts
+++ b/web/src/stores/dataModeStore.ts
@@ -23,10 +23,12 @@ interface DataModeState {
toggle: () => void;
}
+const DEFAULT_USE_MOCK = import.meta.env.VITE_USE_MOCK === 'true';
+
export const useDataModeStore = create<DataModeState>()(
persist(
(set) => ({
- useMock: false,
+ useMock: DEFAULT_USE_MOCK,
toggle: () => set((state) => ({ useMock: !state.useMock })),
}),
{