Migrate to Vite 7, improve UI (Copy/Download), and enhance API security
This commit is contained in:
@@ -83,22 +83,10 @@ function App() {
|
||||
|
||||
// Get headers for API requests
|
||||
const getApiHeaders = () => {
|
||||
const headers = {
|
||||
return {
|
||||
Accept: "application/json",
|
||||
"X-API-Key": apiKey,
|
||||
};
|
||||
|
||||
// Only send API key for non-localhost requests
|
||||
// For localhost, let server use its default LOCALHOST_API_KEY
|
||||
if (
|
||||
window.location.hostname !== "localhost" &&
|
||||
window.location.hostname !== "127.0.0.1" &&
|
||||
!window.location.hostname.startsWith("127.") &&
|
||||
window.location.hostname !== "::1"
|
||||
) {
|
||||
headers["X-API-Key"] = apiKey;
|
||||
}
|
||||
|
||||
return headers;
|
||||
};
|
||||
|
||||
// Load sample data from API on startup and setup periodic state checking
|
||||
@@ -1,13 +1,27 @@
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import App from './App';
|
||||
import { vi } from 'vitest';
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
// Mock localStorage
|
||||
const localStorageMock = (function() {
|
||||
let store = {};
|
||||
return {
|
||||
getItem: vi.fn((key) => store[key] || null),
|
||||
setItem: vi.fn((key, value) => { store[key] = value.toString(); }),
|
||||
clear: vi.fn(() => { store = {}; }),
|
||||
removeItem: vi.fn((key) => { delete store[key]; })
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(window, 'localStorage', { value: localStorageMock });
|
||||
|
||||
// Mock fetch for API calls
|
||||
global.fetch = jest.fn();
|
||||
global.fetch = vi.fn();
|
||||
|
||||
describe('App Component', () => {
|
||||
beforeEach(() => {
|
||||
fetch.mockClear();
|
||||
vi.clearAllMocks();
|
||||
// Mock successful API responses
|
||||
fetch.mockImplementation((url) => {
|
||||
if (url.includes('/api/v1/sample')) {
|
||||
@@ -55,8 +55,7 @@ function ApiKeyPage({ apiKey, onRegenerateApiKey }) {
|
||||
</button>
|
||||
</div>
|
||||
<div className="form-text">
|
||||
This API key is used to encrypt and authenticate data uploads from remote clients.
|
||||
<strong>Note:</strong> Requests from localhost (127.0.0.1) do not require an API key.
|
||||
This API key is used to encrypt and authenticate data uploads.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +63,7 @@ function ApiKeyPage({ apiKey, onRegenerateApiKey }) {
|
||||
<h6>📡 Remote Data Upload API</h6>
|
||||
<p className="text-muted">
|
||||
External tools can upload sample data remotely using the REST API.
|
||||
For remote clients, the API key is required for authentication. Define two
|
||||
The API key is required for authentication. Define two
|
||||
environment variables in your <code>.bashrc</code>.
|
||||
</p>
|
||||
<pre className="bg-light p-3 rounded border">
|
||||
@@ -80,10 +79,9 @@ function ApiKeyPage({ apiKey, onRegenerateApiKey }) {
|
||||
"$\{JMESPATH_PLAYGROUND_API_URL}/api/v1/upload"`}</code>
|
||||
</pre>
|
||||
<div className="form-text">
|
||||
Replace <code>{'__JSON_FILE_NAME__'}</code> with the path to your JSON file containing the sample data.
|
||||
or use <code>-</code> to read from standard input.
|
||||
<br />
|
||||
<strong>For localhost clients:</strong> The X-API-Key should be omitted.
|
||||
Replace <code>{"__JSON_FILE_NAME__"}</code> with the path to your
|
||||
JSON file containing the sample data. or use <code>-</code> to
|
||||
read from standard input.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,46 +0,0 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
// Add TextEncoder/TextDecoder for Node.js compatibility
|
||||
if (typeof TextEncoder === 'undefined') {
|
||||
global.TextEncoder = require('util').TextEncoder;
|
||||
}
|
||||
|
||||
if (typeof TextDecoder === 'undefined') {
|
||||
global.TextDecoder = require('util').TextDecoder;
|
||||
}
|
||||
|
||||
// Mock crypto.getRandomValues for test environment
|
||||
if (typeof global.crypto === 'undefined') {
|
||||
global.crypto = {
|
||||
getRandomValues: (array) => {
|
||||
// Simple predictable mock for testing
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
array[i] = Math.floor(Math.random() * 256);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Suppress console errors during tests
|
||||
const originalError = console.error;
|
||||
beforeAll(() => {
|
||||
console.error = (...args) => {
|
||||
if (
|
||||
typeof args[0] === 'string' &&
|
||||
(args[0].includes('Warning: ReactDOMTestUtils.act is deprecated') ||
|
||||
args[0].includes('Warning: An update to App inside a test was not wrapped in act'))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
originalError.call(console, ...args);
|
||||
};
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
console.error = originalError;
|
||||
});
|
||||
Reference in New Issue
Block a user