비활성화된 미분류가 카테고리 드롭다운에 표시됩니다

아, 그렇군요. 로컬 디버깅을 조금 해보았는데, 기본 Discourse 설치 환경에서 100% 재현 가능하다는 것을 확인했습니다.

여기서 내용을 정리해 보겠습니다:

‘미분류(uncategorized)’ 관련 설정이 2가지 있습니다:

allow_uncategorized_topics 기본값 꺼짐(off)
suppress_uncategorized_badge 기본값 켜짐(on)

allow_uncategorized_topics가 비활성화된 경우(기본 설정)에도 이 카테고리의 존재가 특정 장소에서 노출(leak)되고 있습니다.

이를 우회하려고 미분류를 활성화하여 삭제하려 하면 다음과 같은 화면이 표시됩니다:

Discourse에서 이 카테고리는 매우 특이한 성격을 가지고 있습니다:

  1. 반드시 존재해야 합니다.
  2. 삭제할 수 없습니다.
  3. 수많은 로직과 장소에 주입(inject)되어 있습니다:

조건문(conditional)을 계속 추가함으로써 누출을 수정할 수는 있지만, 클라이언트와 서버 양쪽 모두에서 이미 적어도 10개나 쌓여 있을 것입니다.

아니면 근본적으로 이 문제를 해결할 수 있습니다. 관리자가 카테고리를 삭제할 수 있도록 허용하면, 해당 카테고리가 사라지므로 더 이상 이를 검사할 필요가 없게 됩니다.

제 제안은 다음과 같습니다.

  1. 두 설정과 숨겨진 설정 uncategorized_category_id를 모두 삭제합니다.
  2. 기본 카테고리(default category)의 개념을 유지합니다(이미 존재하는 개념입니다) - 이미 default_composer_category가 있습니다.
  3. '미분류(uncategorized)'는 더 이상 특별한 개념이 아니게 되므로, 고려해야 할 사항이 줄어듭니다.
  4. "배지 없는 카테고리"가 반드시 필요한 사람들을 위한 테마 컴포넌트를 제공합니다.

현재 검색 버그는 다음과 같은 방식으로 수정할 수 있습니다.

diff --git a/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js b/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js
index a678919d16..83a9ed27db 100644
--- a/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js
+++ b/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js
@@ -1,4 +1,5 @@
 import { classNames } from "@ember-decorators/component";
+import { setting } from "discourse/lib/computed";
 import CategoryChooserComponent from "select-kit/components/category-chooser";
 import {
   pluginApiIdentifiers,
@@ -7,11 +8,13 @@ import {
 
 @classNames("search-advanced-category-chooser")
 @selectKitOptions({
-  allowUncategorized: true,
+  allowUncategorized: "allowUncategorized",
   clearable: true,
   none: "category.all",
   displayCategoryDescription: false,
   permissionType: null,
 })
 @pluginApiIdentifiers("search-advanced-category-chooser")
-export default class SearchAdvancedCategoryChooser extends CategoryChooserComponent {}
+export default class SearchAdvancedCategoryChooser extends CategoryChooserComponent {
+  @setting("allow_uncategorized_topics") allowUncategorized;
+}
import { render } from "@ember/test-helpers";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import SearchAdvancedCategoryChooser from "select-kit/components/search-advanced-category-chooser";

module(
  "Integration | Component | select-kit/search-advanced-category-chooser",
  function (hooks) {
    setupRenderingTest(hooks);

    hooks.beforeEach(function () {
      this.set("subject", selectKit());
    });

    test("respects allow_uncategorized_topics setting when false", async function (assert) {
      this.siteSettings.allow_uncategorized_topics = false;

      await render(<template><SearchAdvancedCategoryChooser /></template>);

      await this.subject.expand();

      // Uncategorized category (ID 17 in test data) should not be present when setting is false
      assert.false(
        this.subject.rowByValue(17).exists(),
        "uncategorized category is not available when allow_uncategorized_topics is false"
      );
    });

    test("shows uncategorized category when allow_uncategorized_topics is true", async function (assert) {
      this.siteSettings.allow_uncategorized_topics = true;

      await render(<template><SearchAdvancedCategoryChooser /></template>);

      await this.subject.expand();

      // Uncategorized category (ID 17 in test data) should be present when setting is true
      assert.true(
        this.subject.rowByValue(17).exists(),
        "uncategorized category is available when allow_uncategorized_topics is true"
      );
    });

    test("has correct default options", async function (assert) {
      await render(<template><SearchAdvancedCategoryChooser /></template>);

      assert.strictEqual(
        this.subject.header().label(),
        "All categories",
        "has correct default none label"
      );
    });
  }
);

하지만 이는 고급 검색 버그만 해결하는 것이며, 우리는 여전히 구슬치기(wack-a-mole) 게임을 하고 있는 셈입니다…

3개의 좋아요