def test_get_trial_by_trial_id(cidc_api, clean_db, monkeypatch):
    """Check that getting a single trial by trial id works as expected"""
    user_id = setup_user(cidc_api, monkeypatch)
    trial_id, _ = set(setup_trial_metadata(cidc_api))
    with cidc_api.app_context():
        trial = TrialMetadata.find_by_id(trial_id)

    client = cidc_api.test_client()

    # Non-admins can't get single trials
    res = client.get(f"/trial_metadata/{trial.trial_id}")
    assert res.status_code == 401

    # Allowed users can get single trials
    for role in trial_modifier_roles:
        make_role(user_id, role, cidc_api)
        res = client.get(f"/trial_metadata/{trial.trial_id}")
        assert res.status_code == 200
        assert res.json == TrialMetadataSchema().dump(trial)

        # Getting non-existent trials yields 404
        res = client.get(f"/trial_metadata/foobar")
        assert res.status_code == 404
def test_update_trial(cidc_api, clean_db, monkeypatch):
    """Check that updating a trial works as expected"""
    user_id = setup_user(cidc_api, monkeypatch)
    trial_record_id, _ = set(setup_trial_metadata(cidc_api))
    with cidc_api.app_context():
        trial = TrialMetadata.find_by_id(trial_record_id)

    client = cidc_api.test_client()

    # Non-admins can't update single trials
    res = client.patch(f"/trial_metadata/{trial.trial_id}")
    assert res.status_code == 401

    for role in trial_modifier_roles:
        make_role(user_id, role, cidc_api)

        # A missing ETag blocks an update
        res = client.patch(f"/trial_metadata/{trial.trial_id}")
        assert res.status_code == 428

        # An incorrect ETag blocks an update
        res = client.patch(f"/trial_metadata/{trial.trial_id}",
                           headers={"If-Match": "foo"})
        assert res.status_code == 412

        # No trial can be updated to have invalid metadata
        res = client.patch(
            f"/trial_metadata/{trial.trial_id}",
            headers={"If-Match": trial._etag},
            json={"metadata_json": bad_trial_json["metadata_json"]},
        )
        assert res.status_code == 422
        assert res.json["_error"]["message"] == bad_trial_error_message

        # No protected fields on a trial's metadata can be updated
        for field in TrialMetadata.PROTECTED_FIELDS:
            metadata = trial.metadata_json.copy()
            if field == "participants":
                metadata["participants"] = []
            elif field == "protocol_identifier":
                metadata["protocol_identifier"] = "uh oh!"
            else:
                metadata.pop(field)
            res = client.patch(
                f"/trial_metadata/{trial.trial_id}",
                headers={"If-Match": trial._etag},
                json={"metadata_json": metadata},
            )
            assert res.status_code == 400
            assert (
                res.json["_error"]["message"] ==
                f"updating metadata_json['{field}'] via the API is prohibited")

        # An admin can successfully update a trial
        new_metadata_json = {
            **trial.metadata_json,
            "allowed_collection_event_names": [
                *trial.metadata_json["allowed_collection_event_names"],
                "bazz",
            ],
            "allowed_cohort_names": ["buzz"],
        }
        res = client.patch(
            f"/trial_metadata/{trial.trial_id}",
            headers={"If-Match": trial._etag},
            json={"metadata_json": new_metadata_json},
        )
        assert res.status_code == 200
        assert res.json["id"] == trial.id
        assert res.json["trial_id"] == trial.trial_id
        assert res.json["metadata_json"] == new_metadata_json

        with cidc_api.app_context():
            trial = TrialMetadata.find_by_id(trial.id)