---
generated_at: 2026-02-10 15:30:00
metrics:
  claims_total: 130
  claims_with_evidence: 130
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：admin-src 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：130 / 130、根拠なし：0
- 優先レビュー（高）
  1. **なし**：全てのテストケースに根拠あり

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `admin/src/utils/utils.ts` - cleanComments, minify, isJSONClean関数の実装
- E-02: `admin/src/utils/sorting.ts` - determineSorting関数の実装
- E-03: `admin/src/utils/useDebounce.ts` - useDebounceカスタムフックの実装
- E-04: `admin/src/utils/AnimationFrameHook.ts` - useAnimationFrameカスタムフックの実装
- E-05: `admin/src/utils/PadSearch.ts` - PadSearchQuery, PadSearchResult, PadType型定義
- E-06: `admin/src/utils/LoadingScreen.tsx` - LoadingScreenコンポーネントの実装
- E-07: `admin/src/utils/Toast.tsx` - ToastDialogコンポーネントの実装
- E-08: `admin/src/store/store.ts` - Zustandストアの実装（StoreState型、各setter関数）
- E-09: `admin/src/localization/i18n.ts` - i18n設定とLazyImportPluginバックエンドの実装
- E-10: `admin/src/components/SearchField.tsx` - SearchFieldコンポーネントの実装
- E-11: `admin/src/components/IconButton.tsx` - IconButtonコンポーネントの実装
- E-12: `admin/src/components/ShoutType.ts` - ShoutType型定義
- E-13: `admin/src/pages/Plugin.ts` - PluginDef, InstalledPlugin, SearchParams, HelpObj型定義
- E-14: `admin/src/App.tsx` - Appコンポーネントの実装（認証、WebSocket接続、ナビゲーション）
- E-15: `admin/src/pages/LoginScreen.tsx` - LoginScreenコンポーネントの実装
- E-16: `admin/src/pages/SettingsPage.tsx` - SettingsPageコンポーネントの実装
- E-17: `admin/src/pages/HomePage.tsx` - HomePageコンポーネントの実装（プラグイン管理）
- E-18: `admin/src/pages/PadPage.tsx` - PadPageコンポーネントの実装（Pad管理）
- E-19: `admin/src/pages/HelpPage.tsx` - HelpPageコンポーネントの実装
- E-20: `admin/src/pages/ShoutPage.tsx` - ShoutPageコンポーネントの実装（コミュニケーション機能）
- E-21: `admin/src/main.tsx` - アプリケーションエントリーポイントとルーティング設定

## 3) Claims と根拠の対応（レビューの主戦場）

### ユーティリティ関数（utils.ts）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | cleanComments - 単一行コメント削除 | E-01 (L1-9: 正規表現による削除処理) | ○ |
| C-02 | cleanComments - 複数行コメント削除 | E-01 (L4: 複数行コメント正規表現) | ○ |
| C-03 | cleanComments - 末尾スペース削除 | E-01 (L5: trim trailing spaces) | ○ |
| C-04 | cleanComments - 空行削除 | E-01 (L6: remove empty lines) | ○ |
| C-05 | cleanComments - undefined処理 | E-01 (L2: if条件でundefinedチェック) | ○ |
| C-06 | minify - JSON圧縮 | E-01 (L11-59: トークナイザーによる圧縮処理) | ○ |
| C-07 | minify - 文字列内スペース保持 | E-01 (L26-28: in_string時の処理分岐) | ○ |
| C-08 | minify - 単一行コメント除去 | E-01 (L47-48: // コメント検出) | ○ |
| C-09 | minify - 複数行コメント除去 | E-01 (L41-46: /* */ コメント検出) | ○ |
| C-10 | minify - エスケープダブルクォート | E-01 (L33-40: エスケープシーケンス処理) | ○ |
| C-11 | minify - 空文字列処理 | E-01 (L11-59: 入力依存の処理) | ○ |
| C-12 | isJSONClean - 有効なJSON検証 | E-01 (L61-70: JSON.parseとtypeof検証) | ○ |
| C-13 | isJSONClean - 配列JSON検証 | E-01 (L66: typeof === 'object'でオブジェクト/配列両方を検証) | ○ |
| C-14 | isJSONClean - 末尾カンマ修正 | E-01 (L64: replace(',]', ']').replace(',}', '}')) | ○ |
| C-15 | isJSONClean - 無効なJSON検出 | E-01 (L67-69: try-catch でfalse返却) | ○ |
| C-16 | isJSONClean - プリミティブ値拒否 | E-01 (L66: typeof === 'object'チェック) | ○ |
| C-17 | isJSONClean - 空オブジェクト検証 | E-01 (L66: オブジェクト型チェック) | ○ |

### ソート関数（sorting.ts）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-18 | determineSorting - 昇順クラス返却 | E-02 (L2-3: ascending ? 'sort up') | ○ |
| C-19 | determineSorting - 降順クラス返却 | E-02 (L3: 'sort down') | ○ |
| C-20 | determineSorting - 非対象列クラス返却 | E-02 (L5: 'sort none') | ○ |
| C-21 | determineSorting - 空文字列一致 | E-02 (L2: sortBy === currentSymbol比較) | ○ |

### カスタムフック（useDebounce.ts, AnimationFrameHook.ts）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-22 | useDebounce - 待機後コールバック実行 | E-03 (L12: useAnimationFrame呼び出し), E-04 (L15-21: wait時間後実行) | ○ |
| C-23 | useDebounce - 初回レンダリングスキップ | E-03 (L11, L15-17: isFirstRenderチェック) | ○ |
| C-24 | useDebounce - 依存配列による再スケジュール | E-03 (L14-21: useMemoのdeps) | ○ |
| C-25 | useDebounce - ゼロ待機時間 | E-03, E-04 (L16: wait時間比較) | ○ |
| C-26 | useAnimationFrame - 指定時間後コールバック | E-04 (L15-21: renderFrame関数) | ○ |
| C-27 | useAnimationFrame - 前回キャンセル | E-04 (L12: cancelAnimationFrame) | ○ |
| C-28 | useAnimationFrame - アンマウント時キャンセル | E-04 (L27: useEffect cleanup) | ○ |
| C-29 | useAnimationFrame - 引数伝達 | E-04 (L20: callback(...args)) | ○ |

### ストア（store.ts）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-30 | setSettings - 設定保存 | E-08 (L34: set({settings})) | ○ |
| C-31 | setSettings - undefined処理 | E-08 (L34: 型定義でstring|undefined) | ○ |
| C-32 | setSettingsSocket - ソケット保存 | E-08 (L36: set({settingsSocket: socket})) | ○ |
| C-33 | setShowLoading - true設定 | E-08 (L38: set({showLoading: show})) | ○ |
| C-34 | setShowLoading - false設定 | E-08 (L38: set({showLoading: show})) | ○ |
| C-35 | setPluginsSocket - プラグインソケット保存 | E-08 (L40: set({pluginsSocket: socket})) | ○ |
| C-36 | setToastState - トースト状態更新 | E-08 (L41: set({toastState: val})) | ○ |
| C-37 | setToastState - 成功トースト | E-08 (L41: success: true対応) | ○ |
| C-38 | setToastState - 失敗トースト | E-08 (L41: success: false対応) | ○ |
| C-39 | setPads - Pad一覧保存 | E-08 (L49: set({pads})) | ○ |
| C-40 | setPads - 空結果設定 | E-08 (L49: PadSearchResult型対応) | ○ |
| C-41 | setInstalledPlugins - プラグイン一覧保存 | E-08 (L51: set({installedPlugins: plugins})) | ○ |
| C-42 | setInstalledPlugins - 空配列設定 | E-08 (L51: InstalledPlugin[]型対応) | ○ |
| C-43 | 初期状態 - 正しい初期値 | E-08 (L33-51: 初期値定義) | ○ |

### i18n（i18n.ts）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-44 | LazyImportPlugin - 翻訳ファイル読み込み | E-09 (L12-36: read関数) | ○ |
| C-45 | LazyImportPlugin - プラグイン翻訳読み込み | E-09 (L15-21: namespace分岐) | ○ |
| C-46 | LazyImportPlugin - JSON解析エラー | E-09 (L30-31: catch block) | ○ |
| C-47 | LazyImportPlugin - キャッシュ設定 | E-09 (L23-24: cache: "force-cache") | ○ |

### コンポーネント（SearchField.tsx, IconButton.tsx）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-48 | SearchField - 入力値表示 | E-10 (L11: value={value}) | ○ |
| C-49 | SearchField - onChangeコールバック | E-10 (L11: onChange={onChange}) | ○ |
| C-50 | SearchField - プレースホルダー表示 | E-10 (L11: placeholder={placeholder}) | ○ |
| C-51 | SearchField - 空props処理 | E-10 (L3-7: オプショナルprops) | ○ |
| C-52 | IconButton - クリックイベント | E-11 (L13: onClick={onClick}) | ○ |
| C-53 | IconButton - アイコン表示 | E-11 (L14: {icon}) | ○ |
| C-54 | IconButton - タイトル表示 | E-11 (L15: {title}) | ○ |
| C-55 | IconButton - disabled機能 | E-11 (L13: disabled={disabled}) | ○ |
| C-56 | IconButton - カスタムクラス | E-11 (L13: className={"icon-button "+ className}) | ○ |
| C-57 | IconButton - カスタムスタイル | E-11 (L13: style={style}) | ○ |

### LoadingScreen, Toast
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-58 | LoadingScreen - 表示制御 | E-06 (L8: open={showLoading}) | ○ |
| C-59 | LoadingScreen - 非表示制御 | E-06 (L8: open={showLoading}) | ○ |
| C-60 | ToastDialog - 成功クラス | E-07 (L7-9: success ? 'ToastRootSuccess') | ○ |
| C-61 | ToastDialog - 失敗クラス | E-07 (L8: 'ToastRootFailure') | ○ |
| C-62 | ToastDialog - タイトル表示 | E-07 (L19: {toastState.title}) | ○ |
| C-63 | ToastDialog - 説明表示 | E-07 (L20-22: {toastState.description}) | ○ |
| C-64 | ToastDialog - 開閉制御 | E-07 (L13-17: onOpenChange) | ○ |

### App.tsx
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-65 | App - 認証成功時表示 | E-14 (L19-27: fetch成功時の処理) | ○ |
| C-66 | App - 認証失敗時リダイレクト | E-14 (L22-23, L25-26: navigate('/login')) | ○ |
| C-67 | App - WebSocket接続確立 | E-14 (L34-40: connect呼び出し) | ○ |
| C-68 | App - 設定受信時ストア更新 | E-14 (L71-72: setSettings) | ○ |
| C-69 | App - NOT_ALLOWED設定拒否 | E-14 (L65-68: results === 'NOT_ALLOWED'チェック) | ○ |
| C-70 | App - 無効なJSONアラート | E-14 (L73-74: alert('Invalid JSON')) | ○ |
| C-71 | App - 切断時再接続 | E-14 (L54-60: disconnect handler) | ○ |
| C-72 | App - サイドバー開閉 | E-14 (L111-113: setSidebarOpen) | ○ |
| C-73 | App - モバイルメニュー動作 | E-14 (L97-100: innerWidth < 768) | ○ |
| C-74 | App - アンマウント時切断 | E-14 (L83-86: cleanup function) | ○ |

### LoginScreen.tsx
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-75 | LoginScreen - ログイン成功 | E-15 (L33-34: navigate('/')) | ○ |
| C-76 | LoginScreen - ログイン失敗 | E-15 (L27-32: setToastState) | ○ |
| C-77 | LoginScreen - ネットワークエラー | E-15 (L36-38: catch block) | ○ |
| C-78 | LoginScreen - パスワード表示切替 | E-15 (L54-55: onClick toggle) | ○ |
| C-79 | LoginScreen - 必須バリデーション | E-15 (L46-47, L51-52: required: true) | ○ |

### SettingsPage.tsx
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-80 | SettingsPage - 設定表示 | E-16 (L13: value={settings}) | ○ |
| C-81 | SettingsPage - 設定編集 | E-16 (L13-14: onChange) | ○ |
| C-82 | SettingsPage - 保存成功トースト | E-16 (L22-26: success: true) | ○ |
| C-83 | SettingsPage - 保存失敗トースト | E-16 (L28-32: success: false) | ○ |
| C-84 | SettingsPage - サーバー再起動 | E-16 (L37: emit('restartServer')) | ○ |

### HomePage.tsx
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-85 | HomePage - インストール済みプラグイン表示 | E-17 (L168-191: installed-plugins table) | ○ |
| C-86 | HomePage - 利用可能プラグイン表示 | E-17 (L198-244: available-plugins table) | ○ |
| C-87 | HomePage - プラグインインストール | E-17 (L149-152: installPlugin function) | ○ |
| C-88 | HomePage - プラグインアンインストール | E-17 (L143-147: uninstallPlugin function) | ○ |
| C-89 | HomePage - コアプラグイン保護 | E-17 (L185: disabled={plugin.name == "ep_etherpad-lite"}) | ○ |
| C-90 | HomePage - 名前ソート昇順 | E-17 (L26-47: filteredInstallablePlugins useMemo) | ○ |
| C-91 | HomePage - バージョンソート降順 | E-17 (L27-31: version sort) | ○ |
| C-92 | HomePage - 更新日時ソート | E-17 (L33-37: last-updated sort) | ○ |
| C-93 | HomePage - インストール済みソート | E-17 (L52-64: sortedInstalledPlugins) | ○ |
| C-94 | HomePage - プラグイン検索 | E-17 (L154-160: useDebounce with searchTerm) | ○ |
| C-95 | HomePage - アップデート可能表示 | E-17 (L183-184: plugin.updatable) | ○ |
| C-96 | HomePage - 検索エラー処理 | E-17 (L133-139: results:searcherror handler) | ○ |

### PadPage.tsx
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-97 | PadPage - Pad一覧表示 | E-18 (L207-265: table) | ○ |
| C-98 | PadPage - Pad削除 | E-18 (L126-128: deletePad function) | ○ |
| C-99 | PadPage - 削除キャンセル | E-18 (L153-155: Cancel button) | ○ |
| C-100 | PadPage - Padクリーンアップ | E-18 (L130-132: cleanupPad function) | ○ |
| C-101 | PadPage - Pad作成 | E-18 (L134-138: onPadCreate function) | ○ |
| C-102 | PadPage - Pad作成成功 | E-18 (L93-101: success handler) | ○ |
| C-103 | PadPage - Pad作成失敗 | E-18 (L87-92: error handler) | ○ |
| C-104 | PadPage - Pad名ソート | E-18 (L210-216: padName sort click) | ○ |
| C-105 | PadPage - ユーザー数ソート | E-18 (L217-223: userCount sort click) | ○ |
| C-106 | PadPage - 最終編集日時ソート | E-18 (L224-230: lastEdited sort click) | ○ |
| C-107 | PadPage - リビジョン番号ソート | E-18 (L231-237: revisionNumber sort click) | ○ |
| C-108 | PadPage - 次ページ遷移 | E-18 (L274-281: Next Page button) | ○ |
| C-109 | PadPage - 前ページ遷移 | E-18 (L267-272: Previous Page button) | ○ |
| C-110 | PadPage - 最初のページ制限 | E-18 (L267: disabled={currentPage == 0}) | ○ |
| C-111 | PadPage - 最後のページ制限 | E-18 (L274: disabled condition) | ○ |
| C-112 | PadPage - Pad検索 | E-18 (L43-49: useDebounce with searchTerm) | ○ |
| C-113 | PadPage - Pad閲覧 | E-18 (L258: window.open) | ○ |
| C-114 | PadPage - クリーンアップエラー | E-18 (L108-111: error handling) | ○ |

### HelpPage.tsx
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-115 | HelpPage - ヘルプデータ表示 | E-19 (L37-69: help content) | ○ |
| C-116 | HelpPage - ヘルプデータ取得 | E-19 (L16: emit('help')) | ○ |
| C-117 | HelpPage - サーバーフック表示 | E-19 (L19-31: renderHooks function) | ○ |
| C-118 | HelpPage - クライアントフック表示 | E-19 (L64-66: renderHooks for client hooks) | ○ |
| C-119 | HelpPage - プラグイン表示 | E-19 (L48-50: installedPlugins.map) | ○ |
| C-120 | HelpPage - パーツ表示 | E-19 (L53-55: installedParts.map) | ○ |
| C-121 | HelpPage - ヘルプデータなし | E-19 (L35: if (!helpData) return) | ○ |

### ShoutPage.tsx
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-122 | ShoutPage - ユーザー数表示 | E-20 (L46: totalUsers表示) | ○ |
| C-123 | ShoutPage - 単数形ユーザー表示 | E-20 (L46: 三項演算子による文法変更) | ○ |
| C-124 | ShoutPage - メッセージ送信 | E-20 (L35-41: sendMessage function) | ○ |
| C-125 | ShoutPage - スティッキーメッセージ | E-20 (L37-38: sticky flag) | ○ |
| C-126 | ShoutPage - 入力欄クリア | E-20 (L40: setMessage('')) | ○ |
| C-127 | ShoutPage - メッセージ受信 | E-20 (L19-21: shout event handler) | ○ |
| C-128 | ShoutPage - タイムスタンプ表示 | E-20 (L56-58: timestamp formatting) | ○ |
| C-129 | ShoutPage - スティッキースイッチ | E-20 (L69-74: Switch component) | ○ |
| C-130 | ShoutPage - 統計取得 | E-20 (L31: emit('getStats')) | ○ |

## 4) 不足情報（Unknown / Missing）
- 全てのテストケースについてソースコードから根拠を確認できました
- 追加で必要な情報源はありません

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - 全てのテストケースがソースコードの実装に基づいて生成されています

## 6) レビュアーチェックリスト（最小）
- [ ] テストケースの入力値と期待結果が実装と整合しているか確認
- [ ] 境界値テストが適切なエッジケースをカバーしているか確認
- [ ] 異常系テストがエラーハンドリングロジックと一致しているか確認
- [ ] Reactコンポーネントのテストケースがpropsとstateの変更を適切にカバーしているか確認
- [ ] WebSocket通信のテストケースがイベント送受信を網羅しているか確認
- [ ] ストア操作のテストケースが状態管理を正しく検証しているか確認
