# ワークビジットAPIテスト このガイドでは、一般的な[APIテスト](https://docs.equinix.com/ja/equinix-api/testing.md)の原則に基づき、Equinix Work Visits APIの具体的なテストアプローチと例を示します。 ## ワークビジットAPIの概要 Work Visits APIを利用すると、エクイニクスIBXデータセンターへの訪問をプログラムでスケジュール・管理できます: * 最大14日間の業務訪問のスケジューリング * 訪問者情報とアクセス許可の管理 * 業務訪問の詳細と連絡先の更新 * ケージとキャビネットのアクセス要件の取り扱い * 登録ユーザーと非登録ユーザーの両方を持つ訪問者リストの管理 **重要事項**: 訪問業務が適用されるのは14日間までです。14日を超える訪問には、セキュリティ・アクセスの承認が必要です。このサービスは、IBXアクセスサービスの発注権限を持つユーザーのみがスケジュールできます。 ## WorkVisit テストワークフロー Work Visits API をテストする前に、以下を確認してください: * 有効なAPI認証情報と作業訪問の注文権限 * お客様がケージをお持ちのエクイニクスIBX拠点へのアクセス * 出張先で有効なケージID * 訪問者の要件と本人確認プロセスの理解 **業務訪問リクエストの作成** ``` import requests import json from datetime import datetime, timedelta # Setup authentication auth_url = "https://api.equinix.com/oauth2/v1/token" auth_payload = { "grant_type": "client_credentials", "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET" } auth_response = requests.post(auth_url, data=auth_payload) token = auth_response.json()["access_token"] # Test creating a work visit request base_url = "https://api.equinix.com/colocations/v2" headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json" } # Calculate visit dates (future dates) visit_start = (datetime.utcnow() + timedelta(days=3)).isoformat() + "Z" visit_end = (datetime.utcnow() + timedelta(days=3, hours=8)).isoformat() + "Z" # Example: Create a work visit request work_visit_payload = { "description": "Monthly routine maintenance and equipment inspection", "customerReferenceId": "WV-REF-12345", "purchaseOrder": { "type": "EXISTING", "number": "PO-789456" }, "attachments": [ { "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "name": "maintenance_checklist.pdf" } ], "contacts": [ { "type": "TECHNICAL", "registeredUsers": ["tech.admin@example.com"], "availability": "WORK_HOURS", "timezone": "America/New_York" }, { "type": "NOTIFICATION", "registeredUsers": ["notifications@example.com"] } ], "details": { "cages": [ { "id": "SV1:01:001MC3", "accountNumber": "12345", "cabinetId": "SV1:01:001MC3:0101" } ], "visitStartDateTime": visit_start, "visitEndDateTime": visit_end, "openCabinet": True, "visitors": [ { "registeredUsers": ["john.doe@example.com"] }, { "firstName": "Jane", "lastName": "Smith", "companyName": "Acme Corporation", "details": [ { "type": "EMAIL", "value": "jane.smith@acme.com" }, { "type": "MOBILE", "value": "+1-555-123-4567" } ] } ] } } create_response = requests.post( f"{base_url}/orders/workVisits", headers=headers, data=json.dumps(work_visit_payload) ) # Verify response assert create_response.status_code == 201, f"Failed to create work visit: {create_response.text}" # Extract order ID from Location header order_number = create_response.json()["OrderNumber"] print(f"Successfully created inbound shipment with order ID: {order_number}") ``` **複数日の出張の作成** ``` # Example: Create a multi-day work visit (up to 14 days) multi_day_start = (datetime.utcnow() + timedelta(days=5)).isoformat() + "Z" multi_day_end = (datetime.utcnow() + timedelta(days=12)).isoformat() + "Z" multi_day_payload = { "description": "Data center migration project - Phase 1", "customerReferenceId": "MIGRATION-PHASE1-2025", "purchaseOrder": { "type": "NEW", "number": "PO-MIGRATION-001", "amount": 5000, "startDate": "2025-08-01", "endDate": "2025-12-31" }, "contacts": [ { "type": "TECHNICAL", "registeredUsers": ["migration.lead@example.com"], "availability": "ANYTIME", "timezone": "America/Los_Angeles" } ], "details": { "cages": [ { "id": "LA1:01:002MC5", "accountNumber": "67890" }, { "id": "LA1:01:003MC1", "accountNumber": "67890" } ], "visitStartDateTime": multi_day_start, "visitEndDateTime": multi_day_end, "openCabinet": False, "visitors": [ { "firstName": "Michael", "lastName": "Johnson", "companyName": "Migration Experts Inc", "details": [ { "type": "EMAIL", "value": "mjohnson@migrationexperts.com" }, { "type": "MOBILE", "value": "+1-310-555-9876" } ] }, { "firstName": "Sarah", "lastName": "Wilson", "companyName": "Migration Experts Inc", "details": [ { "type": "EMAIL", "value": "swilson@migrationexperts.com" } ] } ] } } multi_day_response = requests.post( f"{base_url}/orders/workVisits", headers=headers, data=json.dumps(multi_day_payload) ) assert multi_day_response.status_code == 201, f"Failed to create multi-day work visit: {multi_day_response.text}" print("Successfully created multi-day work visit request") ``` **業務訪問リクエストの更新** ``` # Test updating work visit details if order_id: # Update work visit with new contact information update_payload = { "contacts": [ { "type": "NOTIFICATION", "registeredUsers": ["updated.notifications@example.com", "backup.contact@example.com"] } ], "details": { "visitStartDateTime": (datetime.utcnow() + timedelta(days=4)).isoformat() + "Z", "visitEndDateTime": (datetime.utcnow() + timedelta(days=4, hours=6)).isoformat() + "Z", "openCabinet": False } } update_response = requests.patch( f"{base_url}/orders/workVisits/{order_id}", headers=headers, data=json.dumps(update_payload) ) # Verify update response assert update_response.status_code in [202, 204], f"Failed to update work visit: {update_response.text}" print(f"Successfully updated work visit {order_id}") ``` ## エラーシナリオのテスト API実装のエラー処理は必ずテストしてください: ``` # Test with missing required fields invalid_payload = { "description": "Invalid request test", "details": { "visitStartDateTime": visit_start, "visitEndDateTime": visit_end # Missing required 'cages' and 'visitors' fields } } error_response = requests.post( f"{base_url}/orders/workVisits", headers=headers, data=json.dumps(invalid_payload) ) # Verify error response assert error_response.status_code == 400, f"Expected error but got: {error_response.status_code}" error_data = error_response.json() assert any("cages" in error.get("additionalInfo", {}).get("property", "") for error in error_data), "Expected cages validation error" # Test with invalid visit duration (over 14 days) long_visit_payload = { "description": "Invalid long visit test", "details": { "cages": [{"id": "SV1:01:001MC3"}], "visitStartDateTime": visit_start, "visitEndDateTime": (datetime.utcnow() + timedelta(days=20)).isoformat() + "Z", # Over 14 days "visitors": [{"registeredUsers": ["test@example.com"]}] } } long_visit_response = requests.post( f"{base_url}/orders/workVisits", headers=headers, data=json.dumps(long_visit_payload) ) assert long_visit_response.status_code == 400, f"Expected duration validation error but got: {long_visit_response.status_code}" # Test with invalid cage ID invalid_cage_payload = { "description": "Invalid cage test", "details": { "cages": [{"id": "INVALID:CAGE:ID"}], "visitStartDateTime": visit_start, "visitEndDateTime": visit_end, "visitors": [{"registeredUsers": ["test@example.com"]}] } } cage_error_response = requests.post( f"{base_url}/orders/workVisits", headers=headers, data=json.dumps(invalid_cage_payload) ) assert cage_error_response.status_code in [400, 403], f"Expected cage validation error but got: {cage_error_response.status_code}" ``` ## ワークビジットAPIテストのベストプラクティス 1. **訪問期間の制限** :訪問期間が14日を超えないようにしてください。 2. **有効なケージアクセス** :テスト前のケージIDとアカウント権限の確認 3. **訪問者情報** :登録ビジターと非登録ビジターによるテスト 4. **コンタクトバリデーション** :適切な連絡先情報と可用性設定の確認 5. **タイムゾーンハンドリング** :海外拠点の異なるタイムゾーンでのテスト 6. **キャビネット・アクセス** :キャビネット開放要求の有無のテスト 7. **発注書タイプ** :3つのPOタイプ(NEW、EXISTING、EXEMPTED)をすべてテストします。 8. **ファイル添付** :ドキュメント用添付ファイルのテストアップロード 9. **権限検証** :IBX Access Servicesの適切な注文権限の確認 ## 自動化に関する考察 ワークビジットAPIを中心にオートメーションを構築する場合: * 最大訪問期間14日間のバリデーションを導入 * 訪問者数制限の組み込み(登録されていない訪問者は最大50人まで) * ケージへのアクセスやパーミッションの問題に対する適切なエラー処理を含みます。 * 仕事の訪問状況更新のためのWebhookレシーバーの実装 * すべての業務訪問トランザクションの監査ロギングの構築 * リクエスト作成前に訪問者情報の完全性を検証 * 海外拠点のタイムゾーンを適切に処理 * 登録ユーザーと非登録ユーザーの両方に適切な連絡先検証を実装します。 ## 追加リソース * [Work Visits API Reference](https://docs.equinix.com/ja/api-catalog/workvisitsv2.md) * [Smart Hands Service Guide](https://docs.equinix.com/ja/smart-hands.md) * [API Authentication](https://docs.equinix.com/ja/equinix-api/api-authentication.md) * [IBX Access Services](https://docs.equinix.com/ja/visiting-an-ibx.md)