"""Integration tests.""" import json from datetime import datetime import requests from tests.integration.consts import api def test_get_hello(): """Get Hello Endpoint.""" response = requests.get(api.HEALTH_CHECK) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() assert "status" in response_body assert "ok" in response_body["status"] def test_get_authorization_health_authorized(get_authorized_headers): """Get Hello Authorized Endpoint.""" response = requests.get( api.AUTHORIZATION_HEALTH, headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert "status" in response_body assert "authorization ok" in response_body["status"] def test_get_authorization_health_unauthorized(get_headers): """Get Hello Authorized Endpoint without auth should be unauthorized.""" response = requests.get( api.AUTHORIZATION_HEALTH, headers=get_headers ) assert response.status_code == 403, "\nReason: {}\nURL: {}".format( response.reason, response.url ) def test_get_canned_response_item(get_authorized_headers): """Get canned response item with authorization.""" canned_response_id = 1 response = requests.get( api.CANNED_RESPONSE.format(canned_response_id), headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert response_body["canned_response_id"] == canned_response_id def test_get_canned_response_items(get_authorized_headers): """Test get canned response items.""" response = requests.get( api.CANNED_RESPONSES, headers=get_authorized_headers ) assert response.status_code == 200 response_body = response.json() assert len(response_body["items"]) >= 1 def test_get_canned_response_note_dataloader(get_authorized_headers): """Dataload canned response notes with authorization.""" response = requests.post( api.CANNED_RESPONSE_NOTE_DATALOADER, json=[{ 'canned_response_id': 1, 'language_code': 'en' }, { 'canned_response_id': 2, 'language_code': 'en' }], headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert len(response_body) == 2 item = response_body[0] assert item["canned_response_id"] == 1 assert item["language_code"] == "en" def test_get_review_queue(get_authorized_headers): """Test get review queue.""" response = requests.get( api.REVIEW_QUEUE, headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 pagination = response_body.get("pagination") items = response_body.get("items") assert pagination["offset"] == 0 # pagination defaults to 50 assert pagination["limit"] == 50 assert len(items) <= 50 assert pagination["total_records"] >= len(items) expected_keys = ["review_queue_id", "product_id", "created_datetime", "status"] for item in items: for key in expected_keys: assert item[key] is not None # status defaults to new assert item["status"] == "new" def test_get_review_queue_items_by_id(get_authorized_headers, fixture_review_queue_id): """Test get review queue items by id.""" response = requests.post( api.REVIEW_QUEUE_DATALOADER, json=["32", "33"], headers=get_authorized_headers ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() expected_keys = ["review_queue_id", "product_id", "created_datetime", "status"] for item in response_body: for key in expected_keys: assert item[key] is not None def test_get_review_queue_filters(): """Test get review queue with filters.""" response = requests.get(api.REVIEW_QUEUE, {"status": "complete", "page_limit": 3}) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() items = response_body.get("items") pagination = response_body.get("pagination") assert pagination["limit"] == 3 assert len(items) <= 3 for item in items: assert item["status"] == "complete" def test_get_review_queue_item(fixture_product_id, reset_test_review_fixture): """Test get_review_queue_item.""" response = requests.get( api.REVIEW_QUEUE, {"review_queue_id": reset_test_review_fixture} ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() assert response_body["pagination"] == { "limit": 50, "offset": 0, "total_records": 1, "type": "standard", } items = response_body["items"] assert len(items) == 1 assert items[0].pop("created_datetime") is not None assert items[0] == { "error_correction_id": None, "locked_at_datetime": None, "locked_by_user_id": None, "locked_until_datetime": None, "review_queue_id": reset_test_review_fixture, "product_id": fixture_product_id, "status": "new", "submission_count": 1, "submission_type": "new", "queue_name": "initial", "moved_to_queue_by_user_id": None, "moved_to_target_id": None, "moved_to_target_name": None, "moved_to_target_email": None, "moved_to_orchadmin_user_id": None, "moved_at_datetime": None, "move_note": None, "submitted_by_user_id": None, "submission_datetime": None, } def test_approve(reset_test_review_fixture, get_authorized_headers): """Test approving a review.""" response = requests.post( api.APPROVE.format(reset_test_review_fixture), headers=get_authorized_headers, ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) def test_rejection(reset_test_review_fixture, get_authorized_headers): """Test rejecting a review.""" response = requests.post( api.REJECT.format(reset_test_review_fixture), data=json.dumps( { "note": "bad bad bad", } ), headers=get_authorized_headers, ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) def test_get_queue_move_history(reset_test_review_fixture, get_authorized_headers): """Get the queue move history for a review queue item.""" response = requests.get( api.GET_QUEUE_MOVE_HISTORY.format(reset_test_review_fixture), headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert "items" in response_body def test_move_review_queue_item_to_queue(fixture_product_id, reset_test_review_fixture, get_authorized_headers): """Test move review queue item to queue.""" response = requests.patch( api.MOVE_TO_QUEUE.format(reset_test_review_fixture), data=json.dumps( { "queue_name": "under_investigation", } ), headers=get_authorized_headers ) review_queue_item_queue_name = requests.get( api.REVIEW_QUEUE, {"review_queue_id": reset_test_review_fixture}, headers=get_authorized_headers ).json()["items"][0]["queue_name"] (queue_move_history_item,) = requests.get( api.GET_QUEUE_MOVE_HISTORY.format(reset_test_review_fixture), headers=get_authorized_headers ).json()["items"] assert response.status_code == 200 response_json = response.json() assert datetime.strptime( response_json.pop("created_datetime"), "%Y-%m-%dT%H:%M:%S.%fZ" ) assert datetime.strptime( response_json.pop("moved_at_datetime"), "%Y-%m-%dT%H:%M:%S.%fZ" ) assert response_json == { "error_correction_id": None, "locked_at_datetime": None, "locked_by_user_id": None, "locked_until_datetime": None, "product_id": fixture_product_id, "queue_name": "under_investigation", "review_queue_id": reset_test_review_fixture, "status": "new", "submission_count": 1, "submission_type": "new", "moved_to_queue_by_user_id": "13d94141-77e2-44c3-aa38-eabc83c4775c", "moved_to_target_id": None, "moved_to_target_name": None, "moved_to_target_email": None, "moved_to_orchadmin_user_id": None, "move_note": None, "submitted_by_user_id": None, "submission_datetime": None, } assert review_queue_item_queue_name == "under_investigation" assert datetime.strptime( queue_move_history_item.pop("moved_at_datetime"), "%Y-%m-%dT%H:%M:%S.%fZ" ) assert isinstance(queue_move_history_item.pop("queue_move_history_id"), int) assert queue_move_history_item == { "queue_name": "under_investigation", "previous_queue_name": "initial", "review_queue_id": reset_test_review_fixture, "moved_to_queue_by_user_id": "13d94141-77e2-44c3-aa38-eabc83c4775c", "moved_to_target_id": None, "moved_to_target_name": None, "moved_to_target_email": None, "moved_to_orchadmin_user_id": None, "move_note": None, "escalation_type": None } def test_get_rejection(fixture_product_id, test_rejection_fixture): """Test get rejection for workstation.""" response = requests.get(api.GET_REJECTION.format(fixture_product_id)) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() assert len(response_body["items"]) == 1 rejection = response_body["items"][0] rejection_id = rejection.pop("rejection_id") assert rejection_id is not None assert rejection == { "table_name": "releases", "field_name": "general_comments", "comments": "bad bad bad", "corrected": "N", "key_id": 0, } def test_get_product_history(fixture_product_id, test_approval_fixture, get_authorized_headers): """Test get complete review history for product.""" response = requests.get( api.REVIEW_HISTORY.format(fixture_product_id), headers=get_authorized_headers ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() assert response_body["pagination"] == { "limit": 50, "offset": 0, "total_records": 1, "type": "standard", } assert len(response_body["items"]) == 1 item = response_body["items"][0] assert item["rejection"] is None assert item["approval"] is not None assert item["review_queue_id"] == test_approval_fixture assert item["product_id"] == fixture_product_id def test_get_status_new(fixture_product_id, reset_test_review_fixture, get_authorized_headers): """Get product status.""" response = requests.get( api.STATUS.format(fixture_product_id), headers=get_authorized_headers ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() assert response_body["id"] == fixture_product_id assert response_body["ec_and_ar"] is False assert response_body["release_status"] == "transfer_to_content" assert response_body["release_approval_status"] == "checked_in" assert response_body["last_updated"] is not None def test_get_status_rejection(fixture_product_id, test_rejection_fixture): """Get product status.""" response = requests.get(api.STATUS.format(fixture_product_id)) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() assert response_body["id"] == fixture_product_id assert response_body["ec_and_ar"] is False assert response_body["release_status"] == "action_required" assert response_body["release_approval_status"] == "rejected" assert response_body["note"] == "bad bad bad" assert response_body["last_updated"] is not None def test_get_status_approval(fixture_product_id, test_approval_fixture): """Get product status.""" response = requests.get(api.STATUS.format(fixture_product_id)) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() assert response_body["id"] == fixture_product_id assert response_body["ec_and_ar"] is False assert response_body["release_status"] == "in_content" assert response_body["release_approval_status"] == "approved" assert response_body["last_updated"] is not None def test_eligible_product(fixture_product_id, get_authorized_headers): """Test an eligible product (vendor 16162, distro format 1).""" response = requests.get( api.ELIGIBILITY_CHECK.format(fixture_product_id), headers=get_authorized_headers ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) assert response.text == "eligible" def test_ineligible_product(get_authorized_headers): """Test an ineligible product (vendor 16162, distro format 57).""" response = requests.get( api.ELIGIBILITY_CHECK.format(2349142), headers=get_authorized_headers ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) assert response.text == "ineligible" def test_create_rejection(reset_test_review_fixture, get_authorized_headers): """Test creating rejection.""" response = requests.post( api.REVIEW_ITEM_REJECTION.format(reset_test_review_fixture), json={ "note": "test rejection", "user_id": "ows-product-review-integration-tests", "will_not_deliver": None, "created_datetime": None }, headers=get_authorized_headers ) assert response.status_code == 200 def test_get_sub_account_note_authorized(get_authorized_headers): """Get a subaccount note with authorization.""" subaccount_id = 1 response = requests.get( api.SUBACCOUNT_NOTE.format(subaccount_id), headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert response_body["subaccount_id"] == subaccount_id def test_get_sub_account_note_unauthorized(get_headers): """Get a subaccount note without auth should be forbidden.""" subaccount_id = 1 response = requests.get( api.SUBACCOUNT_NOTE.format(subaccount_id), headers=get_headers ) assert response.status_code == 403, "\nReason: {}\nURL: {}".format( response.reason, response.url ) def test_dataload_subaccount_notes(get_authorized_headers): """Dataload subaccount notes with authorization.""" response = requests.post( api.SUBACCOUNT_NOTE_DATALOADER, json=[1, 2], headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert len(response_body) == 2 item = response_body[0] assert item["subaccount_id"] == 1 assert item["note"] is not None def test_get_account_note(get_authorized_headers): """Get an account note with authorization.""" vendor_id = 1 response = requests.get( api.ACCOUNT_NOTE.format(vendor_id), headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert response_body["vendor_id"] == vendor_id def test_dataload_account_notes(get_authorized_headers): """Dataload account notes with authorization.""" response = requests.post( api.ACCOUNT_NOTE_DATALOADER, json=[1, 2], headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert len(response_body) == 2 item = response_body[0] assert item["vendor_id"] == 1 assert item["note"] is not None def test_add_account_note(get_authorized_headers): """Add an account note with authorization.""" vendor_id = 12345 note_content = "This is a test account note." response = requests.put( api.ACCOUNT_NOTE.format(vendor_id), data=json.dumps( { "note": note_content, } ), headers=get_authorized_headers ) assert response.status_code == 200 assert response.text == 'Successfully updated account note.' def test_add_subaccount_note(get_authorized_headers): """Add a subaccount note with authorization.""" subaccount_id = 3 note = "This is a test note." response = requests.put( api.SUBACCOUNT_NOTE.format(subaccount_id), data=json.dumps( { "note": note, } ), headers=get_authorized_headers ) assert response.status_code == 200 assert response.text == "Successfully updated subaccount note." def test_lock_and_unlock(reset_test_review_fixture, get_authorized_headers): """Lock/ unlock review queue item.""" lock_response = requests.patch( api.LOCK.format(reset_test_review_fixture), headers=get_authorized_headers ) assert lock_response.status_code == 200 assert lock_response.json()["review_queue_id"] == reset_test_review_fixture unlock_response = requests.patch( api.UNLOCK.format(reset_test_review_fixture), headers=get_authorized_headers ) assert unlock_response.status_code == 200 assert unlock_response.json()["review_queue_id"] == reset_test_review_fixture def test_unlock_error_not_found(reset_test_review_fixture, get_authorized_headers): """Unlock error 404 not found.""" response = requests.patch( api.UNLOCK.format(reset_test_review_fixture), headers=get_authorized_headers ) error_body = response.json() assert response.status_code == 404 assert error_body["code"] == "unable_to_unlock" assert error_body["message"] == "Unlockable review queue item not found." def test_create_approval(reset_test_review_fixture, get_authorized_headers): """Create an approval for a review queue item.""" response = requests.post( api.APPROVAL.format(reset_test_review_fixture), json={ "note": "test approval", "user_id":"ows-product-review-integration-tests", "created_datetime": None }, headers=get_authorized_headers ) assert response.status_code == 200 def test_get_target_group_by_item_ids_dataloader(reset_test_review_fixture, get_authorized_headers): """Test dataload target groups on review queue item.""" response = requests.post( api.TARGET_GROUP_DATALOADER, json=[ reset_test_review_fixture ], headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert len(response_body) == 1 item = response_body[0] assert item["review_queue_id"] == reset_test_review_fixture assert "moved_to_target_id" in item def test_apply_revisions_if_applicable(reset_test_review_fixture, get_authorized_headers): """Test apply revisions in VAPI if applicable.""" response = requests.post( api.APPLY_REVISIONS_LEGACY.format(reset_test_review_fixture), headers=get_authorized_headers ) assert response.status_code == 200 assert "applied_in_legacy" in response.json() def test_get_all_target_groups(get_authorized_headers): """Test get all target groups.""" response = requests.get( api.TARGET_GROUPS, headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert len(response_body) == 3 def test_get_canned_response_categories(get_authorized_headers): """Test get canned response categories.""" response = requests.get( api.CANNED_RESPONSE_CATEGORIES, headers=get_authorized_headers ) response_body = response.json() assert response.status_code == 200 assert len(response_body) == 15 def test_add_score_pass_validation(reset_test_review_fixture, get_authorized_headers): """Test adding a score with PASS validation.""" response = requests.post( api.SCORE.format(reset_test_review_fixture), json={ "validation_result": "PASS", "confidence_score": 95, "score_reasoning": {"reason": "High quality content"}, "score_version": 1 }, headers=get_authorized_headers, ) assert response.status_code == 200, "\nReason: {}\nURL: {}".format( response.reason, response.url ) def test_add_score_duplicate_version_conflict(reset_test_review_fixture, get_authorized_headers): """Test adding a duplicate score for the same version returns 409.""" # First score should succeed response1 = requests.post( api.SCORE.format(reset_test_review_fixture), json={ "validation_result": "PASS", "confidence_score": 95, "score_reasoning": {"reason": "First score"}, "score_version": 4.0 }, headers=get_authorized_headers, ) assert response1.status_code == 200 # Second score with same version should fail response2 = requests.post( api.SCORE.format(reset_test_review_fixture), json={ "validation_result": "PASS", "confidence_score": 98, "score_reasoning": {"reason": "Duplicate attempt"}, "score_version": 4.0 }, headers=get_authorized_headers, ) assert response2.status_code == 409, "\nReason: {}\nURL: {}".format( response2.reason, response2.url ) response_body = response2.json() assert response_body["code"] == "exists" assert "already a score record" in response_body["message"] def test_add_score_nonexistent_review_queue_item(get_authorized_headers): """Test adding a score for a non-existent review queue item returns 404.""" response = requests.post( api.SCORE.format(999999999), json={ "validation_result": "PASS", "confidence_score": 95, "score_reasoning": {"reason": "Test"}, "score_version": 1 }, headers=get_authorized_headers, ) assert response.status_code == 404, "\nReason: {}\nURL: {}".format( response.reason, response.url ) response_body = response.json() assert response_body["code"] == "not_found" assert "not found" in response_body["message"] def test_unsubmit_and_submit_product( fixture_product_id, reset_test_review_fixture, get_authorized_headers ): """Test unsubmit/ submit a product to the review queue.""" # remove test product from review queue unsubmit_response = requests.post( api.PRODUCT_UNSUBMIT.format(fixture_product_id), json={ "reason": "test unsubmit" }, headers=get_authorized_headers ) assert unsubmit_response.status_code == 204 # add test product to review queue response = requests.post( api.REVIEW_QUEUE_PRODUCT.format(fixture_product_id), headers=get_authorized_headers ) item = response.json() assert response.status_code == 201 assert item["status"] == "new" assert item["queue_name"] == "initial"