Gate was process.env.NODE_ENV === 'development' — unsafe default. react-scripts inlines NODE_ENV=development when unset, so prod deploys forgetting the env var exposed the delete-all button. Switched to explicit opt-in REACT_APP_DEV_TOOLS=1. process.env.REACT_APP_DEV_TOOLS as static literal gets inlined by DefinePlugin at webpack build time — runtime mutations in tests had no effect, and dev-start without the env produced bundles with the branch dead-stripped. Extracted gate to src/config/devTools.js using dynamic key access (process.env['REACT_APP_' + 'DEV_TOOLS']) so DefinePlugin cannot inline it; the value is read at runtime. dev-start.sh now exports REACT_APP_DEV_TOOLS=1. Button had also drifted outside the campaigns collapse block to the page bottom; moved it back inside the campaigns section after the grid. Tests cover both paths: gate logic (unset/0/arbitrary/1) in BulkDelete.gate.test.js, prod safety render (button absent when unset) in BulkDelete.render-hidden.test.js, dev feature render (button present when DEV_TOOLS=1) in BulkDelete.render-shown.test.js.
37 lines
1.3 KiB
JavaScript
37 lines
1.3 KiB
JavaScript
import React from 'react';
|
|
import { render, screen, waitFor, fireEvent, cleanup, act } from '@testing-library/react';
|
|
import App from '../App';
|
|
|
|
describe('Bulk-delete-all button render gating', () => {
|
|
const orig = process.env.REACT_APP_DEV_TOOLS;
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
if (orig === undefined) delete process.env.REACT_APP_DEV_TOOLS;
|
|
else process.env.REACT_APP_DEV_TOOLS = orig;
|
|
});
|
|
|
|
async function renderAndCreateCampaign() {
|
|
window.history.replaceState({}, '', '/');
|
|
global.alert = jest.fn();
|
|
global.window.open = jest.fn();
|
|
render(<App />);
|
|
await waitFor(() => screen.getByRole('button', { name: /Create Campaign/i }));
|
|
await act(async () => {
|
|
fireEvent.click(screen.getByRole('button', { name: /Create Campaign/i }));
|
|
});
|
|
await waitFor(() => screen.getByLabelText(/Campaign Name/i));
|
|
await act(async () => {
|
|
fireEvent.change(screen.getByLabelText(/Campaign Name/i), { target: { value: 'Gate Render Test' } });
|
|
fireEvent.click(screen.getByRole('button', { name: /^Create$/i }));
|
|
await new Promise(r => setTimeout(r, 200));
|
|
});
|
|
}
|
|
|
|
test('prod safety: button absent when DEV_TOOLS unset', async () => {
|
|
delete process.env.REACT_APP_DEV_TOOLS;
|
|
await renderAndCreateCampaign();
|
|
expect(screen.queryByText(/Delete All Campaigns/i)).not.toBeInTheDocument();
|
|
});
|
|
});
|