mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
fix(settings): preserve multiline proxy bypass rules (#20957)
This commit is contained in:
+63
@@ -0,0 +1,63 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { cleanup, fireEvent, render } from '@testing-library/react'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { getDefaultSettings } from '../../../../shared/constants'
|
||||
import { AdvancedNetworkSettingsSection } from './AdvancedNetworkSettingsSection'
|
||||
|
||||
afterEach(() => cleanup())
|
||||
|
||||
describe('AdvancedNetworkSettingsSection bypass rules control', () => {
|
||||
it('keeps newline input and canonicalizes it when focus leaves the textarea', async () => {
|
||||
const updateSettings = vi.fn()
|
||||
|
||||
const { container } = render(
|
||||
<AdvancedNetworkSettingsSection
|
||||
settings={{ ...getDefaultSettings('/tmp'), httpProxyBypassRules: '' }}
|
||||
updateSettings={updateSettings}
|
||||
/>
|
||||
)
|
||||
|
||||
const configureButton = Array.from(container.querySelectorAll('button')).find((button) =>
|
||||
button.textContent?.includes('Configure proxy')
|
||||
)
|
||||
expect(configureButton).not.toBeUndefined()
|
||||
fireEvent.click(configureButton!)
|
||||
|
||||
const textarea = container.querySelector<HTMLTextAreaElement>(
|
||||
'#settings-http-proxy-bypass-rules'
|
||||
)
|
||||
expect(textarea).not.toBeNull()
|
||||
|
||||
fireEvent.change(textarea!, { target: { value: 'localhost\n127.0.0.1\n*.internal.corp' } })
|
||||
fireEvent.blur(textarea!)
|
||||
|
||||
expect(updateSettings).toHaveBeenCalledWith({
|
||||
httpProxyBypassRules: 'localhost;127.0.0.1;*.internal.corp'
|
||||
})
|
||||
})
|
||||
|
||||
it('does not commit when Enter is pressed inside the textarea', () => {
|
||||
const updateSettings = vi.fn()
|
||||
const { container } = render(
|
||||
<AdvancedNetworkSettingsSection
|
||||
settings={{ ...getDefaultSettings('/tmp'), httpProxyBypassRules: '' }}
|
||||
updateSettings={updateSettings}
|
||||
/>
|
||||
)
|
||||
fireEvent.click(
|
||||
Array.from(container.querySelectorAll('button')).find((button) =>
|
||||
button.textContent?.includes('Configure proxy')
|
||||
)!
|
||||
)
|
||||
const textarea = container.querySelector<HTMLTextAreaElement>(
|
||||
'#settings-http-proxy-bypass-rules'
|
||||
)!
|
||||
|
||||
textarea.focus()
|
||||
fireEvent.keyDown(textarea, { key: 'Enter', code: 'Enter' })
|
||||
|
||||
expect(document.activeElement).toBe(textarea)
|
||||
expect(updateSettings).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,10 @@
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { createElement } from 'react'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { GlobalSettings } from '../../../../shared/global-settings-types'
|
||||
import { getDefaultSettings } from '../../../../shared/constants'
|
||||
import {
|
||||
AdvancedNetworkSettingsSection,
|
||||
createHttpProxyBypassRulesDraftState,
|
||||
createHttpProxyUrlDraftState,
|
||||
hasConfiguredNetworkProxy,
|
||||
@@ -11,6 +15,23 @@ import {
|
||||
} from './AdvancedNetworkSettingsSection'
|
||||
|
||||
describe('AdvancedNetworkSettingsSection proxy drafts', () => {
|
||||
it('renders bypass rules as a multiline textarea', () => {
|
||||
const markup = renderToStaticMarkup(
|
||||
createElement(AdvancedNetworkSettingsSection, {
|
||||
settings: {
|
||||
...getDefaultSettings('/tmp'),
|
||||
httpProxyBypassRules: 'localhost\n127.0.0.1\n*.internal.corp'
|
||||
},
|
||||
updateSettings: () => undefined
|
||||
})
|
||||
)
|
||||
|
||||
expect(markup).toMatch(/<textarea[^>]*id="settings-http-proxy-bypass-rules"[^>]*>/)
|
||||
expect(markup).toContain('localhost')
|
||||
expect(markup).toContain('127.0.0.1')
|
||||
expect(markup).toContain('*.internal.corp')
|
||||
})
|
||||
|
||||
it('keeps a committed proxy URL draft tied to the current persisted source', () => {
|
||||
const current = createHttpProxyUrlDraftState(undefined)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Button } from '../ui/button'
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible'
|
||||
import { Input } from '../ui/input'
|
||||
import { Label } from '../ui/label'
|
||||
import { Textarea } from '../ui/textarea'
|
||||
import { getAdvancedNetworkSearchEntries } from './advanced-network-search'
|
||||
import { SearchableSetting } from './SearchableSetting'
|
||||
import { matchesSettingsSearch, normalizeSettingsSearchQuery } from './settings-search'
|
||||
@@ -304,16 +305,11 @@ export function AdvancedNetworkSettingsSection({
|
||||
'Proxy Bypass Rules'
|
||||
)}
|
||||
</Label>
|
||||
<Input
|
||||
<Textarea
|
||||
id="settings-http-proxy-bypass-rules"
|
||||
value={httpProxyBypassRulesDraft}
|
||||
onChange={(e) => updateHttpProxyBypassRulesDraft(e.target.value)}
|
||||
onBlur={commitHttpProxyBypassRules}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.currentTarget.blur()
|
||||
}
|
||||
}}
|
||||
placeholder={translate(
|
||||
'auto.components.settings.AdvancedNetworkSettingsSection.3e431564b5',
|
||||
'localhost, 127.0.0.1, *.internal'
|
||||
@@ -322,6 +318,7 @@ export function AdvancedNetworkSettingsSection({
|
||||
autoCorrect="off"
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
rows={3}
|
||||
className="font-mono text-xs"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { test, expect } from './helpers/orca-app'
|
||||
import { waitForSessionReady } from './helpers/store'
|
||||
|
||||
test.describe('network proxy bypass rules', () => {
|
||||
test('preserves newline-separated hosts and canonicalizes them on blur', async ({ orcaPage }) => {
|
||||
await waitForSessionReady(orcaPage)
|
||||
|
||||
const original = await orcaPage.evaluate(() => window.api.settings.get())
|
||||
try {
|
||||
await orcaPage.evaluate(() => {
|
||||
const state = window.__store?.getState()
|
||||
state?.openSettingsTarget({ pane: 'advanced', repoId: null })
|
||||
state?.openSettingsPage()
|
||||
})
|
||||
|
||||
await expect(orcaPage.getByRole('heading', { name: 'Advanced', exact: true })).toBeVisible()
|
||||
await orcaPage.getByRole('button', { name: 'Configure proxy' }).click()
|
||||
const bypassRules = orcaPage.locator('#settings-http-proxy-bypass-rules')
|
||||
await expect(bypassRules).toBeVisible()
|
||||
await expect(bypassRules).toHaveJSProperty('tagName', 'TEXTAREA')
|
||||
|
||||
await bypassRules.fill('localhost\n127.0.0.1\n*.internal.corp')
|
||||
await expect(bypassRules).toHaveValue('localhost\n127.0.0.1\n*.internal.corp')
|
||||
await orcaPage.locator('#settings-http-proxy-url').focus()
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
async () =>
|
||||
(await orcaPage.evaluate(() => window.api.settings.get())).httpProxyBypassRules
|
||||
)
|
||||
.toBe('localhost;127.0.0.1;*.internal.corp')
|
||||
await expect(bypassRules).toHaveValue('localhost;127.0.0.1;*.internal.corp')
|
||||
} finally {
|
||||
await orcaPage.evaluate(
|
||||
(settings) =>
|
||||
window.api.settings.set({ httpProxyBypassRules: settings.httpProxyBypassRules ?? '' }),
|
||||
original
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user