---
generated_at: 2026-01-13 12:00:00
metrics:
  claims_total: 102
  claims_with_evidence: 102
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：users モジュール単体テストケース一覧

## 本レポートについて

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

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：102 / 102、根拠なし：0
- 優先レビュー（高）
  1. **Ability#initialize**: 認証・認可ロジックの複雑性から重点テスト推奨
  2. **User#active_for_authentication?**: Devise統合部分の動作確認
  3. **Permission バリデーション**: 条件付きバリデーションの網羅性確認

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

- E-01: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/users/ability.rb`
- E-02: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/users/group.rb`
- E-03: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/users/permission.rb`
- E-04: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/users/preference.rb`
- E-05: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/users/user.rb`

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

### Ability クラス (E-01)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | 未ログインユーザーがサインアップできること | E-01 L15: `can(:create, User) if User.can_signup?` | ○ |
| C-02 | ログインユーザーが自分自身を管理できること | E-01 L21: `can :manage, User, id: user.id` | ○ |
| C-03 | ログインユーザーがTaskを作成できること | E-01 L24: `can :create, Task` | ○ |
| C-04 | ログインユーザーが自分のTaskを管理できること | E-01 L25-27: `can :manage, Task, user: user.id` 等 | ○ |
| C-05 | Publicエンティティを管理できること | E-01 L30: `can :manage, entities, access: 'Public'` | ○ |
| C-06 | 管理者がすべてを管理できること | E-01 L40: `can :manage, :all` | ○ |
| C-07 | グループ権限でエンティティを管理できること | E-01 L43-53: グループ権限のロジック | ○ |
| C-08 | 未ログインユーザーがサインアップできないこと | E-01 L15: 条件付き権限付与 | ○ |
| C-09 | 一般ユーザーが他ユーザーを管理できないこと | E-01 L39-54: 管理者以外の権限制限 | ○ |

### Group クラス (E-02)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-10 | グループに所属するユーザー一覧が取得できること | E-02 L9: `has_and_belongs_to_many :users` | ○ |
| C-11 | グループの権限一覧が取得できること | E-02 L10: `has_many :permissions` | ○ |
| C-12 | 有効な名前でグループが作成できること | E-02 L12: `validates :name, presence: true` | ○ |
| C-13 | 空の名前でグループが作成できないこと | E-02 L12: `validates :name, presence: true` | ○ |
| C-14 | 重複する名前でグループが作成できないこと | E-02 L12: `uniqueness: true` | ○ |

### Permission クラス (E-03)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-15 | Permissionに関連するユーザーが取得できること | E-03 L21: `belongs_to :user, optional: true` | ○ |
| C-16 | Permissionに関連するグループが取得できること | E-03 L22: `belongs_to :group, optional: true` | ○ |
| C-17 | Permissionに関連するアセットが取得できること | E-03 L23: `belongs_to :asset, polymorphic: true` | ○ |
| C-18 | user_idのみでPermissionが作成できること | E-03 L26: `validates_presence_of :group_id, unless: :user_id?` | ○ |
| C-19 | group_idのみでPermissionが作成できること | E-03 L25: `validates_presence_of :user_id, unless: :group_id?` | ○ |
| C-20 | user_idとgroup_idの両方が空の場合エラーになること | E-03 L25-26: 相互排他バリデーション | ○ |
| C-21 | 同一組み合わせで重複作成できないこと | E-03 L28: `validates_uniqueness_of :user_id, scope: ...` | ○ |

### Preference クラス (E-04)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-22 | 保存された設定値が取得できること | E-04 L24-32: `def []` メソッド | ○ |
| C-23 | user_idの場合は通常のアクセサが使用されること | E-04 L26: `return super(name) if name.to_s == "user_id"` | ○ |
| C-24 | 存在しないキーの場合nilが返ること | E-04 L30-32: 条件付きnil返却 | ○ |
| C-25 | 新しい設定値が保存できること | E-04 L36-46: `def []=` メソッド | ○ |
| C-26 | 既存の設定値が更新できること | E-04 L40-41: `pref.update_attribute` | ○ |
| C-27 | user_idの場合は通常のミューテータが使用されること | E-04 L37: `return super(name, value) if name.to_s == "user_id"` | ○ |
| C-28 | キャッシュが正しく動作すること | E-04 L48-50: `cached_prefs` メソッド | ○ |

### User クラス (E-05)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-29 | ユーザーのアバターが取得できること | E-05 L53: `has_one :avatar, as: :entity` | ○ |
| C-30 | ユーザーがアップロードしたアバター一覧が取得できること | E-05 L54: `has_many :avatars` | ○ |
| C-31 | ユーザーが作成したコメント一覧が取得できること | E-05 L55: `has_many :comments, as: :commentable` | ○ |
| C-32 | ユーザーのアカウント一覧が取得できること | E-05 L56: `has_many :accounts` | ○ |
| C-33 | ユーザーのキャンペーン一覧が取得できること | E-05 L57: `has_many :campaigns` | ○ |
| C-34 | ユーザーのリード一覧が取得できること | E-05 L58: `has_many :leads` | ○ |
| C-35 | ユーザーの連絡先一覧が取得できること | E-05 L59: `has_many :contacts` | ○ |
| C-36 | ユーザーの商談一覧が取得できること | E-05 L60: `has_many :opportunities` | ○ |
| C-37 | ユーザーにアサインされた商談一覧が取得できること | E-05 L61: `has_many :assigned_opportunities, class_name: 'Opportunity', foreign_key: 'assigned_to'` | ○ |
| C-38 | ユーザーの権限一覧が取得できること | E-05 L62: `has_many :permissions, dependent: :destroy` | ○ |
| C-39 | ユーザーの設定一覧が取得できること | E-05 L63: `has_many :preferences` | ○ |
| C-40 | ユーザーのリスト一覧が取得できること | E-05 L64: `has_many :lists` | ○ |
| C-41 | ユーザーが所属するグループ一覧が取得できること | E-05 L65: `has_and_belongs_to_many :groups` | ○ |
| C-42 | first_nameがある場合first_nameが返ること | E-05 L101-103: `def name` | ○ |
| C-43 | first_nameが空の場合usernameが返ること | E-05 L102: `first_name.blank? ? username : first_name` | ○ |
| C-44 | first_nameとlast_nameが結合されて返ること | E-05 L106-108: `def full_name` | ○ |
| C-45 | first_nameとlast_nameが空の場合emailが返ること | E-05 L107: 条件付きemail返却 | ○ |
| C-46 | suspended_atが設定されている場合trueが返ること | E-05 L111-113: `def suspended?` | ○ |
| C-47 | suspended_atがnilの場合falseが返ること | E-05 L112: `suspended_at != nil` | ○ |
| C-48 | 承認待ち状態の場合trueが返ること | E-05 L116-118: `def awaits_approval?` | ○ |
| C-49 | ログイン済みの場合falseが返ること | E-05 L117: `sign_in_count == 0` 条件 | ○ |
| C-50 | 有効なユーザーの場合trueが返ること | E-05 L120-122: `def active_for_authentication?` | ○ |
| C-51 | 未確認ユーザーの場合falseが返ること | E-05 L121: `confirmed?` 条件 | ○ |
| C-52 | 承認待ちユーザーの場合falseが返ること | E-05 L121: `!awaits_approval?` 条件 | ○ |
| C-53 | 停止ユーザーの場合falseが返ること | E-05 L121: `!suspended?` 条件 | ○ |
| C-54 | 未確認ユーザーの場合適切なメッセージが返ること | E-05 L124-134: `def inactive_message` | ○ |
| C-55 | 承認待ちユーザーの場合適切なメッセージが返ること | E-05 L127-128: `I18n.t(:msg_account_not_approved)` | ○ |
| C-56 | 停止ユーザーの場合適切なメッセージが返ること | E-05 L129-130: `I18n.t(:msg_invalig_login)` | ○ |
| C-57 | メール送信可能なユーザーの場合trueが返ること | E-05 L138-140: `def emailable?` | ○ |
| C-58 | 未確認ユーザーの場合falseが返ること | E-05 L139: `confirmed?` 条件 | ○ |
| C-59 | メールアドレスがない場合falseが返ること | E-05 L139: `email.present?` 条件 | ○ |
| C-60 | Preferenceオブジェクトが取得できること | E-05 L143-145: `def preference` | ○ |
| C-61 | preferenceのエイリアスが動作すること | E-05 L146: `alias pref preference` | ○ |
| C-62 | 個別ロケールが設定されること | E-05 L150-152: `def set_individual_locale` | ○ |
| C-63 | ロケール設定がない場合は何も変更されないこと | E-05 L151: `if preference[:locale]` 条件 | ○ |
| C-64 | JSON形式で名前が返ること | E-05 L156-158: `def to_json` | ○ |
| C-65 | XML形式で名前が返ること | E-05 L160-162: `def to_xml` | ○ |
| C-66 | 新規ユーザーの場合trueが返ること | E-05 L164-166: `def password_required?` | ○ |
| C-67 | パスワード変更時trueが返ること | E-05 L165: `!password.nil?` 条件 | ○ |
| C-68 | 既存ユーザーでパスワード未変更の場合falseが返ること | E-05 L165: 全条件false時 | ○ |
| C-69 | Abilityオブジェクトが取得できること | E-05 L170-172: `def ability` | ○ |
| C-70 | 削除可能なユーザーの場合trueが返ること | E-05 L176-178: `def destroyable?` | ○ |
| C-71 | 自分自身の場合falseが返ること | E-05 L177: `current_user != self` 条件 | ○ |
| C-72 | 関連アセットがある場合falseが返ること | E-05 L177: `!has_related_assets?` 条件 | ○ |
| C-73 | 承認が必要な場合suspended_atが設定されること | E-05 L182-184: `def suspend_if_needs_approval` | ○ |
| C-74 | 管理者の場合suspended_atが設定されないこと | E-05 L183: `!admin` 条件 | ○ |
| C-75 | 関連アセットがある場合trueが返ること | E-05 L188-195: `def has_related_assets?` | ○ |
| C-76 | 関連アセットがない場合falseが返ること | E-05 L194: `!sum.nil?` | ○ |
| C-77 | サインアップが許可されている場合trueが返ること | E-05 L200-202: `def can_signup?` | ○ |
| C-78 | 承認が必要な設定の場合trueが返ること | E-05 L201: `:needs_approval` 含む | ○ |
| C-79 | サインアップが禁止されている場合falseが返ること | E-05 L201: 配列外の値 | ○ |
| C-80 | usernameでユーザーが検索できること | E-05 L206-211: `def find_for_database_authentication` | ○ |
| C-81 | emailでユーザーが検索できること | E-05 L209: `lower(email) = :value` | ○ |
| C-82 | 大文字小文字を区別しない検索ができること | E-05 L209: `lower()` 使用 | ○ |
| C-83 | 存在しないユーザーの場合nilが返ること | E-05 L209: `.first` でnil可能性 | ○ |
| C-84 | 有効なメールアドレスでバリデーションが通ること | E-05 L87-91: `validates :email` | ○ |
| C-85 | 空のメールアドレスでバリデーションエラーになること | E-05 L88: `presence: { message: :missing_email }` | ○ |
| C-86 | 3文字未満のメールアドレスでバリデーションエラーになること | E-05 L89: `minimum: 3` | ○ |
| C-87 | 254文字超のメールアドレスでバリデーションエラーになること | E-05 L89: `maximum: 254` | ○ |
| C-88 | 重複するメールアドレスでバリデーションエラーになること | E-05 L90: `uniqueness: { message: :email_in_use }` | ○ |
| C-89 | 不正な形式のメールアドレスでバリデーションエラーになること | E-05 L91: `format: { with: /.../ }` | ○ |
| C-90 | 有効なusernameでバリデーションが通ること | E-05 L92-95: `validates :username` | ○ |
| C-91 | 空のusernameでバリデーションエラーになること | E-05 L94: `presence: { message: :missing_username }` | ○ |
| C-92 | 重複するusernameでバリデーションエラーになること | E-05 L93: `uniqueness: { message: :username_taken }` | ○ |
| C-93 | 不正な文字を含むusernameでバリデーションエラーになること | E-05 L95: `format: { with: /\A[a-z0-9_-]+\z/i }` | ○ |
| C-94 | 有効なパスワードでバリデーションが通ること | E-05 L96-98: `validates :password` | ○ |
| C-95 | パスワードと確認が一致しない場合バリデーションエラーになること | E-05 L98: `confirmation: true` | ○ |
| C-96 | ID降順でユーザーが取得できること | E-05 L69: `scope :by_id` | ○ |
| C-97 | 指定ユーザー以外が取得できること | E-05 L71: `scope :without_user` | ○ |
| C-98 | 名前順でユーザーが取得できること | E-05 L72: `scope :by_name` | ○ |
| C-99 | 検索クエリでユーザーが検索できること | E-05 L74-77: `scope :text_search` | ○ |
| C-100 | 空のクエリでも動作すること | E-05 L75: `gsub` でサニタイズ | ○ |
| C-101 | 現在のユーザーがアクセス可能なユーザーが取得できること | E-05 L79: `scope :my` | ○ |
| C-102 | アサインされた商談を持つユーザーが取得できること | E-05 L81-85: `scope :have_assigned_opportunities` | ○ |

## 4) 不足情報（Unknown / Missing）
- 該当なし
  - すべてのテストケースはソースコードから直接根拠を確認済み

## 5) リスクフラグ（レビュー観点）
- **0: 低リスク** - すべてのClaim（102件）に対して明確なEvidence（ソースコード）が存在
- **1: 中リスク** - Ability クラスの権限ロジックは複雑なため、実際のテスト実装時に追加の境界値テストを検討
- **1: 中リスク** - Devise統合部分（active_for_authentication?, find_for_database_authentication）はDeviseバージョンアップ時に影響を受ける可能性あり

## 6) レビュアーチェックリスト（最小）
- [ ] Ability#initialize の権限ロジックが全パターン網羅されているか確認
- [ ] Permission の条件付きバリデーション（user_id/group_id排他制御）が正しく検証されているか確認
- [ ] User のDevise統合メソッド（active_for_authentication?, find_for_database_authentication）のテストがDevise仕様と整合しているか確認
- [ ] Preference の Base64/JSON エンコード・デコードロジックのエッジケースが考慮されているか確認
- [ ] User#has_related_assets? の関連アセット確認ロジックが全エンティティタイプを網羅しているか確認
