1
0
mirror of https://github.com/quay/quay.git synced 2026-01-27 18:42:52 +03:00
Files
quay/endpoints/api/test/test_robot.py
Syed Ahmed e71b50b992 ui: add entry for robot federation config (PROJQUAY-8050) (#3316)
* ui: add entry for robot federation config (PROJQUAY-8050)

adding entry for showing description in the UI for robot federation config changes
2024-10-15 11:25:36 -04:00

269 lines
7.5 KiB
Python

import json
from unittest.mock import Mock
import pytest
import requests
from data import model
from endpoints.api import api
from endpoints.api.robot import (
OrgRobot,
OrgRobotFederation,
OrgRobotList,
UserRobot,
UserRobotList,
)
from endpoints.api.test.shared import conduct_api_call
from endpoints.test.shared import client_with_identity
from test.fixtures import *
from test.test_ldap import mock_ldap
from util.names import parse_robot_username
@pytest.mark.parametrize(
"endpoint",
[
UserRobot,
OrgRobot,
],
)
@pytest.mark.parametrize(
"body",
[
None,
{},
{"description": "this is a description"},
{"unstructured_metadata": {"foo": "bar"}},
{"description": "this is a description", "unstructured_metadata": {"foo": "bar"}},
],
)
def test_create_robot_with_metadata(endpoint, body, app):
with client_with_identity("devtable", app) as cl:
# Create the robot with the specified body.
conduct_api_call(
cl,
endpoint,
"PUT",
{"orgname": "buynlarge", "robot_shortname": "somebot"},
body,
expected_code=201,
)
# Ensure the create succeeded.
resp = conduct_api_call(
cl,
endpoint,
"GET",
{
"orgname": "buynlarge",
"robot_shortname": "somebot",
},
)
body = body or {}
assert resp.json["description"] == (body.get("description") or "")
assert resp.json["unstructured_metadata"] == (body.get("unstructured_metadata") or {})
@pytest.mark.parametrize(
"endpoint, params",
[
(UserRobot, {"robot_shortname": "dtrobot"}),
(OrgRobot, {"orgname": "buynlarge", "robot_shortname": "coolrobot"}),
],
)
def test_retrieve_robot(endpoint, params, app):
with client_with_identity("devtable", app) as cl:
result = conduct_api_call(cl, endpoint, "GET", params, None)
assert result.json["token"] is not None
@pytest.mark.parametrize(
"endpoint, params, bot_endpoint",
[
(UserRobotList, {}, UserRobot),
(OrgRobotList, {"orgname": "buynlarge"}, OrgRobot),
],
)
@pytest.mark.parametrize(
"include_token",
[
True,
False,
],
)
@pytest.mark.parametrize(
"limit",
[
None,
1,
5,
],
)
def test_retrieve_robots(endpoint, params, bot_endpoint, include_token, limit, app):
params["token"] = "true" if include_token else "false"
if limit is not None:
params["limit"] = limit
with client_with_identity("devtable", app) as cl:
result = conduct_api_call(cl, endpoint, "GET", params, None)
if limit is not None:
assert len(result.json["robots"]) <= limit
for robot in result.json["robots"]:
assert (robot.get("token") is not None) == include_token
if include_token:
bot_params = dict(params)
bot_params["robot_shortname"] = parse_robot_username(robot["name"])[1]
result = conduct_api_call(cl, bot_endpoint, "GET", bot_params, None)
assert robot.get("token") == result.json["token"]
@pytest.mark.parametrize(
"username, is_admin",
[
("devtable", True),
("reader", False),
],
)
@pytest.mark.parametrize(
"with_permissions",
[
True,
False,
],
)
def test_retrieve_robots_token_permission(username, is_admin, with_permissions, app):
with client_with_identity(username, app) as cl:
params = {"orgname": "buynlarge", "token": "true"}
if with_permissions:
params["permissions"] = "true"
result = conduct_api_call(cl, OrgRobotList, "GET", params, None)
assert result.json["robots"]
for robot in result.json["robots"]:
assert (robot.get("token") is not None) == is_admin
assert (robot.get("repositories") is not None) == (is_admin and with_permissions)
def test_duplicate_robot_creation(app):
with client_with_identity("devtable", app) as cl:
resp = conduct_api_call(
cl,
UserRobot,
"PUT",
{"robot_shortname": "dtrobot"},
expected_code=400,
)
assert resp.json["error_message"] == "Existing robot with name: devtable+dtrobot"
resp = conduct_api_call(
cl,
OrgRobot,
"PUT",
{"orgname": "buynlarge", "robot_shortname": "coolrobot"},
expected_code=400,
)
assert resp.json["error_message"] == "Existing robot with name: buynlarge+coolrobot"
def test_robot_federation_create(app):
with client_with_identity("devtable", app) as cl:
# Create the robot with the specified body.
conduct_api_call(
cl,
OrgRobotFederation,
"POST",
{
"orgname": "buynlarge",
"robot_shortname": "coolrobot",
},
[{"issuer": "https://issuer1", "subject": "subject1"}],
expected_code=200,
)
# Ensure the create succeeded.
resp = conduct_api_call(
cl,
OrgRobotFederation,
"GET",
{
"orgname": "buynlarge",
"robot_shortname": "coolrobot",
},
expected_code=200,
)
assert len(resp.json) == 1
assert resp.json[0].get("issuer") == "https://issuer1"
assert resp.json[0].get("subject") == "subject1"
resp = conduct_api_call(
cl,
OrgRobotFederation,
"DELETE",
{
"orgname": "buynlarge",
"robot_shortname": "coolrobot",
},
expected_code=204,
)
resp = conduct_api_call(
cl,
OrgRobotFederation,
"GET",
{
"orgname": "buynlarge",
"robot_shortname": "coolrobot",
},
expected_code=200,
)
assert len(resp.json) == 0
@pytest.mark.parametrize(
"fed_config, raises_error, error_message",
[
(
[{"issuer": "issuer1", "subject": "subject1"}],
True,
"Issuer must be a URL (http:// or https://)",
),
([{"issuer": "https://issuer1", "subject": "subject1"}], False, None),
(
[{"bad_key": "issuer1", "subject": "subject1"}],
True,
"Missing one or more required fields",
),
(
[{"issuer": "https://issuer1", "subject": "subject1"}, {}],
True,
"Missing one or more required fields",
),
(
[
{"issuer": "https://issuer1", "subject": "subject1"},
{"issuer": "https://issuer2", "subject": "subject1"},
{"issuer": "https://issuer1", "subject": "subject1"},
],
True,
"Duplicate federation config entry",
),
],
)
def test_parse_federation_config(app, fed_config, raises_error, error_message):
request = Mock(requests.Request)
request.json = fed_config
with app.app_context():
if raises_error:
with pytest.raises(Exception) as ex:
parsed = OrgRobotFederation()._parse_federation_config(request)
assert error_message in str(ex.value)
else:
parsed = OrgRobotFederation()._parse_federation_config(request)