"No","テストID","対象クラス","対象メソッド","テスト観点","テストケース名","前提条件","入力値","期待結果","優先度","備考"
"1","UT-INT-001","Integrations::App","initialize","正常系","paramsが正しく設定されること","なし","params={id: 'slack', i18n_key: 'slack'}","@paramsにパラメータが設定される","中","コンストラクタ"
"2","UT-INT-002","Integrations::App","id","正常系","params[:id]が返却されること","paramsにidが設定済み","なし","params[:id]の値が返却される","中","アクセサ"
"3","UT-INT-003","Integrations::App","name","正常系","I18n翻訳された名前が返却されること","i18nキーが存在","params={i18n_key: 'slack'}","I18n.t(""integration_apps.slack.name"")の結果","中","I18n連携"
"4","UT-INT-004","Integrations::App","name","異常系","存在しないi18nキーの場合","i18nキーが存在しない","params={i18n_key: 'invalid'}","translation missing文字列が返却される","低","I18nエラーハンドリング"
"5","UT-INT-005","Integrations::App","description","正常系","I18n翻訳された説明が返却されること","i18nキーが存在","params={i18n_key: 'slack'}","I18n.t(""integration_apps.slack.description"")の結果","中","I18n連携"
"6","UT-INT-006","Integrations::App","short_description","正常系","I18n翻訳された短い説明が返却されること","i18nキーが存在","params={i18n_key: 'slack'}","I18n.t(""integration_apps.slack.short_description"")の結果","低","I18n連携"
"7","UT-INT-007","Integrations::App","logo","正常系","params[:logo]が返却されること","paramsにlogoが設定済み","params={logo: 'slack.png'}","'slack.png'が返却される","低","アクセサ"
"8","UT-INT-008","Integrations::App","fields","正常系","params[:fields]が返却されること","paramsにfieldsが設定済み","params={fields: [...]}","fields配列が返却される","低","アクセサ"
"9","UT-INT-009","Integrations::App","encode_state","正常系","Linear用のJWTトークンが生成されること","Current.accountが設定済み、LINEAR_CLIENT_SECRETが設定済み","なし","JWTトークン文字列が返却される","高","Linear認証連携"
"10","UT-INT-010","Integrations::App","encode_state","異常系","CLIENT_SECRETが未設定の場合","LINEAR_CLIENT_SECRETが未設定","なし","nilが返却される","高","設定不足時の挙動"
"11","UT-INT-011","Integrations::App","action","正常系","Slack統合の場合、OAuth URLが構築されること","SLACK_CLIENT_IDが設定済み","params={id: 'slack', action: 'https://slack.com/oauth'}","client_idとredirect_uriを含むURLが返却される","高","Slack OAuth"
"12","UT-INT-012","Integrations::App","action","正常系","Linear統合の場合、OAuth URLが構築されること","LINEAR_CLIENT_IDが設定済み","params={id: 'linear', action: 'https://linear.app/oauth'}","build_linear_actionの結果が返却される","高","Linear OAuth"
"13","UT-INT-013","Integrations::App","action","正常系","その他の統合の場合、params[:action]がそのまま返却されること","なし","params={id: 'dialogflow', action: '/dialogflow'}","'/dialogflow'が返却される","中","デフォルトaction"
"14","UT-INT-014","Integrations::App","active?","正常系","Slack統合でSLACK_CLIENT_SECRETが設定済みの場合trueが返却されること","SLACK_CLIENT_SECRETが設定済み","account, params={id: 'slack'}","trueが返却される","高","統合有効判定"
"15","UT-INT-015","Integrations::App","active?","正常系","Slack統合でSLACK_CLIENT_SECRETが未設定の場合falseが返却されること","SLACK_CLIENT_SECRETが未設定","account, params={id: 'slack'}","falseが返却される","高","統合無効判定"
"16","UT-INT-016","Integrations::App","active?","正常系","Linear統合でfeature_enabledかつCLIENT_IDが設定済みの場合trueが返却されること","linear_integration有効、LINEAR_CLIENT_ID設定済み","account, params={id: 'linear'}","trueが返却される","高","Linear有効判定"
"17","UT-INT-017","Integrations::App","active?","正常系","Linear統合でfeature_enabledがfalseの場合falseが返却されること","linear_integration無効","account, params={id: 'linear'}","falseが返却される","高","Linear無効判定"
"18","UT-INT-018","Integrations::App","active?","正常系","Shopify統合の有効判定","shopify_integration有効、SHOPIFY_CLIENT_ID設定済み","account, params={id: 'shopify'}","trueが返却される","高","Shopify有効判定"
"19","UT-INT-019","Integrations::App","active?","正常系","Leadsquared統合でcrm_integrationが有効の場合trueが返却されること","crm_integration有効","account, params={id: 'leadsquared'}","trueが返却される","高","CRM統合判定"
"20","UT-INT-020","Integrations::App","active?","正常系","Notion統合の有効判定","notion_integration有効、NOTION_CLIENT_ID設定済み","account, params={id: 'notion'}","trueが返却される","中","Notion有効判定"
"21","UT-INT-021","Integrations::App","active?","正常系","その他の統合は常にtrueが返却されること","なし","account, params={id: 'dialogflow'}","trueが返却される","中","デフォルト有効"
"22","UT-INT-022","Integrations::App","build_linear_action","正常系","Linear OAuth URLが正しく構築されること","LINEAR_CLIENT_ID設定済み、Current.account設定済み","なし","response_type, client_id, redirect_uri, state, scope, prompt, actorを含むURL","高","Linear OAuth URL構築"
"23","UT-INT-023","Integrations::App","enabled?","正常系","webhook統合でwebhooksが存在する場合trueが返却されること","account.webhooksが存在","account, params={id: 'webhook'}","trueが返却される","中","Webhook有効判定"
"24","UT-INT-024","Integrations::App","enabled?","正常系","webhook統合でwebhooksが存在しない場合falseが返却されること","account.webhooksが空","account, params={id: 'webhook'}","falseが返却される","中","Webhook無効判定"
"25","UT-INT-025","Integrations::App","enabled?","正常系","dashboard_apps統合でdashboard_appsが存在する場合trueが返却されること","account.dashboard_appsが存在","account, params={id: 'dashboard_apps'}","trueが返却される","中","Dashboard Apps有効判定"
"26","UT-INT-026","Integrations::App","enabled?","正常系","その他の統合でhooksが存在する場合trueが返却されること","account.hooksにapp_id一致のレコードが存在","account, params={id: 'slack'}","trueが返却される","中","Hook有効判定"
"27","UT-INT-027","Integrations::App","hooks","正常系","Current.accountのhooksからapp_id一致のものが返却されること","Current.account設定済み、hooks存在","なし","app_idが一致するhooksのコレクション","中","Hooks取得"
"28","UT-INT-028","Integrations::App","self.slack_integration_url","正常系","Slack統合のリダイレクトURLが返却されること","FRONTEND_URL設定済み、Current.account設定済み","なし","{FRONTEND_URL}/app/accounts/{account_id}/settings/integrations/slack","中","Slack URL生成"
"29","UT-INT-029","Integrations::App","self.linear_integration_url","正常系","Linear統合のリダイレクトURLが返却されること","FRONTEND_URL設定済み","なし","{FRONTEND_URL}/linear/callback","中","Linear URL生成"
"30","UT-INT-030","Integrations::App","self.apps","正常系","APPS_CONFIGがHashie::Mashとして返却されること","APPS_CONFIG定義済み","なし","Hashie::Mashオブジェクト","中","設定取得"
"31","UT-INT-031","Integrations::App","self.all","正常系","全ての統合アプリがIntegrations::Appインスタンスとして返却されること","APPS_CONFIG定義済み","なし","Integrations::Appの配列","中","全アプリ取得"
"32","UT-INT-032","Integrations::App","self.find","正常系","指定IDの統合アプリが返却されること","APPS_CONFIG定義済み","params={id: 'slack'}","Slackアプリのインスタンス","中","アプリ検索"
"33","UT-INT-033","Integrations::App","self.find","境界値","存在しないIDを指定した場合nilが返却されること","APPS_CONFIG定義済み","params={id: 'nonexistent'}","nilが返却される","中","アプリ検索失敗"
"34","UT-INT-034","Integrations::Hook","belongs_to :account","正常系","accountリレーションが正しく取得できること","Hookにaccount_idが設定済み","なし","関連するAccountオブジェクトが返却される","高","リレーション"
"35","UT-INT-035","Integrations::Hook","belongs_to :inbox","正常系","inboxリレーションが正しく取得できること（inbox hookの場合）","Hookにinbox_idが設定済み、hook_type=inbox","なし","関連するInboxオブジェクトが返却される","高","リレーション"
"36","UT-INT-036","Integrations::Hook","belongs_to :inbox","正常系","inboxがnilでもエラーにならないこと（account hookの場合）","hook_type=account","なし","nilが返却される","中","オプショナルリレーション"
"37","UT-INT-037","Integrations::Hook","validates :account_id","異常系","account_idが未設定の場合バリデーションエラーになること","なし","account_id=nil","バリデーションエラー（account_id presence）","高","必須バリデーション"
"38","UT-INT-038","Integrations::Hook","validates :app_id","異常系","app_idが未設定の場合バリデーションエラーになること","なし","app_id=nil","バリデーションエラー（app_id presence）","高","必須バリデーション"
"39","UT-INT-039","Integrations::Hook","validates :inbox_id","異常系","hook_type=inboxでinbox_idが未設定の場合バリデーションエラーになること","なし","hook_type='inbox', inbox_id=nil","バリデーションエラー（inbox_id presence）","高","条件付き必須バリデーション"
"40","UT-INT-040","Integrations::Hook","validates :inbox_id","正常系","hook_type=accountでinbox_idが未設定でもエラーにならないこと","なし","hook_type='account', inbox_id=nil","バリデーション成功","中","条件付きバリデーション"
"41","UT-INT-041","Integrations::Hook","validates :app_id uniqueness","異常系","同一account_idで同一app_idのHookを作成しようとした場合エラーになること（allow_multiple_hooks=false）","既存Hookが存在","account_id=1, app_id='slack'","バリデーションエラー（app_id uniqueness）","高","一意性バリデーション"
"42","UT-INT-042","Integrations::Hook","validates :app_id uniqueness","正常系","allow_multiple_hooks=trueの場合、同一app_idで複数作成可能なこと","既存Hookが存在","account_id=1, app_id='dialogflow'","バリデーション成功","高","複数Hook許可"
"43","UT-INT-043","Integrations::Hook","validate_settings_json_schema","異常系","settingsがJSON Schemaに違反する場合エラーになること","app.params[:settings_json_schema]が定義済み","settings={invalid: 'data'}","バリデーションエラー（settings invalid）","高","JSON Schemaバリデーション"
"44","UT-INT-044","Integrations::Hook","validate_settings_json_schema","正常系","settingsがJSON Schemaに適合する場合成功すること","app.params[:settings_json_schema]が定義済み","settings={api_key: 'valid_key'}","バリデーション成功","高","JSON Schemaバリデーション"
"45","UT-INT-045","Integrations::Hook","validate_settings_json_schema","正常系","settings_json_schemaが未定義の場合スキップされること","appにsettings_json_schemaなし","settings={any: 'data'}","バリデーション成功","中","Schemaなし時のスキップ"
"46","UT-INT-046","Integrations::Hook","ensure_feature_enabled","異常系","feature_flagが無効の場合エラーになること","app.params[:feature_flag]が定義、account.feature_enabled?=false","app_id='leadsquared'","バリデーションエラー（feature not enabled）","高","機能フラグバリデーション"
"47","UT-INT-047","Integrations::Hook","ensure_feature_enabled","正常系","feature_flagが有効の場合成功すること","app.params[:feature_flag]が定義、account.feature_enabled?=true","app_id='leadsquared'","バリデーション成功","高","機能フラグバリデーション"
"48","UT-INT-048","Integrations::Hook","ensure_hook_type","正常系","app.params[:hook_type]からhook_typeが設定されること","appが存在","app_id='slack'","hook_type='account'が設定される","中","hook_type自動設定"
"49","UT-INT-049","Integrations::Hook","ensure_hook_type","正常系","inbox hookの場合hook_type=inboxが設定されること","appが存在","app_id='dialogflow'","hook_type='inbox'が設定される","中","inbox hook_type設定"
"50","UT-INT-050","Integrations::Hook","enum status","正常系","status=enabledが正しく動作すること","なし","status: :enabled","status='enabled'として保存される","中","enumステータス"
"51","UT-INT-051","Integrations::Hook","enum status","正常系","status=disabledが正しく動作すること","なし","status: :disabled","status='disabled'として保存される","中","enumステータス"
"52","UT-INT-052","Integrations::Hook","enum hook_type","正常系","hook_type=accountが正しく動作すること","なし","hook_type: :account","hook_type='account'として保存される","中","enum hook_type"
"53","UT-INT-053","Integrations::Hook","enum hook_type","正常系","hook_type=inboxが正しく動作すること","なし","hook_type: :inbox","hook_type='inbox'として保存される","中","enum hook_type"
"54","UT-INT-054","Integrations::Hook","scope :account_hooks","正常系","hook_type=accountのレコードのみ返却されること","account/inbox両方のhookが存在","なし","hook_type='account'のレコードのみ","中","スコープ"
"55","UT-INT-055","Integrations::Hook","scope :inbox_hooks","正常系","hook_type=inboxのレコードのみ返却されること","account/inbox両方のhookが存在","なし","hook_type='inbox'のレコードのみ","中","スコープ"
"56","UT-INT-056","Integrations::Hook","app","正常系","関連するIntegrations::Appが返却されること","app_id='slack'","なし","Slackアプリのインスタンス","中","アプリ取得"
"57","UT-INT-057","Integrations::Hook","app","境界値","存在しないapp_idの場合nilが返却されること","app_id='nonexistent'","なし","nilが返却される","中","存在しないアプリ"
"58","UT-INT-058","Integrations::Hook","slack?","正常系","app_id='slack'の場合trueが返却されること","app_id='slack'","なし","trueが返却される","中","Slack判定"
"59","UT-INT-059","Integrations::Hook","slack?","正常系","app_id!='slack'の場合falseが返却されること","app_id='dialogflow'","なし","falseが返却される","中","Slack判定"
"60","UT-INT-060","Integrations::Hook","dialogflow?","正常系","app_id='dialogflow'の場合trueが返却されること","app_id='dialogflow'","なし","trueが返却される","中","Dialogflow判定"
"61","UT-INT-061","Integrations::Hook","dialogflow?","正常系","app_id!='dialogflow'の場合falseが返却されること","app_id='slack'","なし","falseが返却される","中","Dialogflow判定"
"62","UT-INT-062","Integrations::Hook","notion?","正常系","app_id='notion'の場合trueが返却されること","app_id='notion'","なし","trueが返却される","中","Notion判定"
"63","UT-INT-063","Integrations::Hook","notion?","正常系","app_id!='notion'の場合falseが返却されること","app_id='slack'","なし","falseが返却される","中","Notion判定"
"64","UT-INT-064","Integrations::Hook","disable","正常系","statusがdisabledに更新されること","status='enabled'","なし","status='disabled'に更新される","中","無効化処理"
"65","UT-INT-065","Integrations::Hook","process_event","正常系","エラーメッセージが返却されること","なし","event=任意","{error: 'No processor found'}が返却される","低","イベント処理（現在未実装）"
"66","UT-INT-066","Integrations::Hook","feature_allowed?","正常系","appがnilの場合trueが返却されること","app=nil","なし","trueが返却される","中","機能許可判定"
"67","UT-INT-067","Integrations::Hook","feature_allowed?","正常系","feature_flagがnilの場合trueが返却されること","app.params[:feature_flag]=nil","なし","trueが返却される","中","機能許可判定"
"68","UT-INT-068","Integrations::Hook","feature_allowed?","正常系","feature_enabled?がtrueの場合trueが返却されること","feature_flag設定済み、feature_enabled?=true","なし","trueが返却される","中","機能許可判定"
"69","UT-INT-069","Integrations::Hook","feature_allowed?","正常系","feature_enabled?がfalseの場合falseが返却されること","feature_flag設定済み、feature_enabled?=false","なし","falseが返却される","中","機能許可判定"
"70","UT-INT-070","Integrations::Hook","trigger_setup_if_crm","正常系","leadsquaredの場合Crm::SetupJobがキューに追加されること","app_id='leadsquared'","なし","Crm::SetupJob.perform_laterが呼び出される","高","CRMセットアップ"
"71","UT-INT-071","Integrations::Hook","trigger_setup_if_crm","正常系","leadsquared以外の場合Jobがキューに追加されないこと","app_id='slack'","なし","Crm::SetupJob.perform_laterが呼び出されない","中","CRMセットアップスキップ"
"72","UT-INT-072","Integrations::Hook","crm_integration?","正常系","app_id='leadsquared'の場合trueが返却されること","app_id='leadsquared'","なし","trueが返却される","中","CRM統合判定"
"73","UT-INT-073","Integrations::Hook","crm_integration?","正常系","その他のapp_idの場合falseが返却されること","app_id='slack'","なし","falseが返却される","中","CRM統合判定"
"74","UT-INT-074","Integrations::Hook","has_secure_token :access_token","正常系","access_tokenが自動生成されること","新規Hook作成","なし","access_tokenが自動生成される","高","セキュアトークン"
"75","UT-INT-075","Integrations::Hook","encrypts :access_token","正常系","access_tokenが暗号化されて保存されること","Chatwoot.encryption_configured?=true","なし","暗号化された状態でDBに保存される","高","暗号化"
"76","UT-INT-076","Integrations::Hook","attr_readonly","正常系","app_id, account_id, inbox_id, hook_typeが更新不可であること","既存Hook","app_id='new_value'を設定して保存","値が変更されない","高","読み取り専用属性"
"77","UT-INT-077","Integrations::Hook（Reauthorizable）","reauthorization_required?","正常系","Redis keyが存在する場合trueが返却されること","Redisにreauthorization_required_key設定済み","なし","trueが返却される","高","再認証要否判定"
"78","UT-INT-078","Integrations::Hook（Reauthorizable）","reauthorization_required?","正常系","Redis keyが存在しない場合falseが返却されること","Redisにreauthorization_required_keyなし","なし","falseが返却される","高","再認証要否判定"
"79","UT-INT-079","Integrations::Hook（Reauthorizable）","authorization_error_count","正常系","エラーカウントが正しく取得されること","Redisにauthorization_error_count_key=3","なし","3が返却される","中","エラーカウント取得"
"80","UT-INT-080","Integrations::Hook（Reauthorizable）","authorization_error_count","境界値","キーが存在しない場合0が返却されること","Redisにキーなし","なし","0が返却される","中","エラーカウント初期値"
"81","UT-INT-081","Integrations::Hook（Reauthorizable）","authorization_error!","正常系","エラーカウントがインクリメントされること","authorization_error_count=0","なし","authorization_error_count=1","高","エラーカウント増加"
"82","UT-INT-082","Integrations::Hook（Reauthorizable）","authorization_error!","正常系","閾値到達時にprompt_reauthorization!が呼び出されること","authorization_error_count=1","なし","reauthorization_required?=trueになる","高","閾値到達時の再認証要求"
"83","UT-INT-083","Integrations::Hook（Reauthorizable）","prompt_reauthorization!","正常系","Redisにreauthorization_required_keyが設定されること","なし","なし","reauthorization_required?=true","高","再認証要求フラグ設定"
"84","UT-INT-084","Integrations::Hook（Reauthorizable）","prompt_reauthorization!","正常系","Slackの場合slack_disconnectメールが送信されること","app_id='slack'","なし","slack_disconnectメールがキューに追加される","高","Slack切断通知"
"85","UT-INT-085","Integrations::Hook（Reauthorizable）","prompt_reauthorization!","正常系","Dialogflowの場合dialogflow_disconnectメールが送信されること","app_id='dialogflow'","なし","dialogflow_disconnectメールがキューに追加される","高","Dialogflow切断通知"
"86","UT-INT-086","Integrations::Hook（Reauthorizable）","reauthorized!","正常系","authorization_error_countがクリアされること","authorization_error_count=2","なし","authorization_error_count=0","高","再認証成功後のクリア"
"87","UT-INT-087","Integrations::Hook（Reauthorizable）","reauthorized!","正常系","reauthorization_required?がfalseになること","reauthorization_required?=true","なし","reauthorization_required?=false","高","再認証成功後のフラグクリア"
