feat: expose google_search as operator manual text-query provider
This commit is contained in:
parent
4abb837aaa
commit
cf342425c5
3 changed files with 26 additions and 17 deletions
|
|
@ -458,7 +458,10 @@ def test_safety_rules_are_visible_in_ui_contract():
|
||||||
|
|
||||||
assert 'id="decision-memo"' in html
|
assert 'id="decision-memo"' in html
|
||||||
assert 'id="manual-query-provider"' in html
|
assert 'id="manual-query-provider"' in html
|
||||||
assert 'option value="google_search"' not in html
|
# 2026-06-12 안전 규칙 개정(설계 승인 2026-06-11): 운영자 수동 검색에
|
||||||
|
# 구글 근거 검색(텍스트 쿼리)을 동적 옵션으로 노출한다. 정적 HTML 기본값은
|
||||||
|
# 네이버만 유지하고, 이미지 업로드 역검색 금지는 그대로다.
|
||||||
|
assert '{ id: "google_search", label: providerLabels.google_search }' in script
|
||||||
assert "네이버" in html
|
assert "네이버" in html
|
||||||
assert "reverse search" not in html.lower()
|
assert "reverse search" not in html.lower()
|
||||||
assert "sourceEvidenceIds" in script
|
assert "sourceEvidenceIds" in script
|
||||||
|
|
@ -601,13 +604,18 @@ def test_operator_gui_exposes_keyword_candidate_collection_workflow():
|
||||||
assert "제출 제목/파일명 기반" in search
|
assert "제출 제목/파일명 기반" in search
|
||||||
|
|
||||||
|
|
||||||
def test_google_custom_search_is_not_exposed_as_operator_choice():
|
def test_google_custom_search_is_exposed_as_operator_text_query_choice():
|
||||||
html = _read(INDEX)
|
html = _read(INDEX)
|
||||||
script = _read(APP_JS)
|
script = _read(APP_JS)
|
||||||
|
search = _read(OPERATOR_SEARCH_JS)
|
||||||
|
labels = _read(OPERATOR_LABELS_JS)
|
||||||
|
|
||||||
assert "구글 맞춤 검색" not in html
|
# 정적 HTML은 네이버 기본값만 두고 부트스트랩 후 동적으로 채운다.
|
||||||
assert "구글 맞춤 검색" not in script
|
|
||||||
assert 'value="google_search"' not in html
|
assert 'value="google_search"' not in html
|
||||||
|
assert '{ id: "google_search", label: providerLabels.google_search }' in script
|
||||||
|
assert "구글 근거 검색" in labels
|
||||||
|
assert 'provider === "google_search" ? "google_search" : "naver"' in search
|
||||||
|
assert "reverse search" not in html.lower()
|
||||||
assert "operatorSearchProviders" in script
|
assert "operatorSearchProviders" in script
|
||||||
assert "visibleProviderControls" in script
|
assert "visibleProviderControls" in script
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,10 @@
|
||||||
} = window.OperatorLabels;
|
} = window.OperatorLabels;
|
||||||
|
|
||||||
const retiredProviderIds = new Set(["google_search"]);
|
const retiredProviderIds = new Set(["google_search"]);
|
||||||
const operatorSearchProviders = [{ id: "naver", label: providerLabels.naver }];
|
const operatorSearchProviders = [
|
||||||
|
{ id: "naver", label: providerLabels.naver },
|
||||||
|
{ id: "google_search", label: providerLabels.google_search },
|
||||||
|
];
|
||||||
const submissions = [];
|
const submissions = [];
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -616,27 +619,25 @@ function visibleProviderStateEntries(providerState) {
|
||||||
|
|
||||||
|
|
||||||
function renderOperatorSearchProviderOptions() {
|
function renderOperatorSearchProviderOptions() {
|
||||||
|
|
||||||
const optionHtml = operatorSearchProviders
|
const optionHtml = operatorSearchProviders
|
||||||
|
.map((provider) => {
|
||||||
.map((provider) => `<option value="${escapeHtml(provider.id)}">${escapeHtml(provider.label)}</option>`)
|
const runtime = providers.find((item) => item.id === provider.id);
|
||||||
|
const unavailable = Boolean(runtime) && !runtime.enabled;
|
||||||
|
const label = unavailable ? `${provider.label} (비활성)` : provider.label;
|
||||||
|
return `<option value="${escapeHtml(provider.id)}" ${unavailable ? "disabled" : ""}>${escapeHtml(label)}</option>`;
|
||||||
|
})
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
["manual-query-provider", "collection-provider"].forEach((elementId) => {
|
["manual-query-provider", "collection-provider"].forEach((elementId) => {
|
||||||
|
|
||||||
const select = document.getElementById(elementId);
|
const select = document.getElementById(elementId);
|
||||||
|
|
||||||
if (!select) return;
|
if (!select) return;
|
||||||
|
|
||||||
const current = select.value;
|
const current = select.value;
|
||||||
|
|
||||||
select.innerHTML = optionHtml;
|
select.innerHTML = optionHtml;
|
||||||
|
|
||||||
select.value = operatorSearchProviders.some((provider) => provider.id === current) ? current : operatorSearchProviders[0].id;
|
select.value = operatorSearchProviders.some((provider) => provider.id === current) ? current : operatorSearchProviders[0].id;
|
||||||
|
if (select.selectedOptions[0] && select.selectedOptions[0].disabled) {
|
||||||
|
select.value = operatorSearchProviders[0].id;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeManualSearchProvider(provider) {
|
function normalizeManualSearchProvider(provider) {
|
||||||
return "naver";
|
return provider === "google_search" ? "google_search" : "naver";
|
||||||
}
|
}
|
||||||
|
|
||||||
global.OperatorSearch = {
|
global.OperatorSearch = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue