Example #1
0
def _get_organization(api: APIClient, organization_id: Optional[int] = None) -> dict:
    if organization_id is None:
        user_url = get_json(api.get("auth/user"))["url"]
        organziation_url = get_json(api.get_url(user_url))["organization"]
        res = api.get_url(organziation_url)
    else:
        res = api.get(f"organizations/{organization_id}")
    return get_json(res)
Example #2
0
class TestAPIClient:
    api_client = APIClient(None)

    def test_get_token_success(self, requests_mock, isolated_cli_runner):
        requests_mock.post(LOGIN_URL, json={"key": TOKEN})
        with isolated_cli_runner.isolation():
            assert TOKEN == self.api_client.get_token()

    def test_get_token_failed(self, requests_mock, isolated_cli_runner):
        requests_mock.post(LOGIN_URL, status_code=401)
        with isolated_cli_runner.isolation(), pytest.raises(click.ClickException) as e:
            self.api_client.get_token()
        assert "Login failed with the provided credentials." == str(e.value)

    def test_get_token_error(self, requests_mock, isolated_cli_runner):
        error_json = {"password": ["required"]}
        requests_mock.post(LOGIN_URL, status_code=400, json=error_json)
        with isolated_cli_runner.isolation(), pytest.raises(click.ClickException) as e:
            self.api_client.get_token()
        assert f"Invalid response [{LOGIN_URL}]: {json.dumps(error_json)}" == str(e.value)

    @pytest.mark.usefixtures("mock_login_request")
    def test_user_agent_header(self, requests_mock, isolated_cli_runner):
        requests_mock.get(API_URL + "/v1/", request_headers=REQUEST_HEADERS)
        with isolated_cli_runner.isolation():
            self.api_client.get("")
        assert requests_mock.called
Example #3
0
def change_command(
    id_: str,
    queue_id: Tuple[str],
    group: Optional[str],
    locale: Optional[str],
    password: Optional[str],
) -> None:
    if not any([queue_id, group, locale, password]):
        return

    data: Dict[str, Any] = {}
    if password is not None:
        data["password"] = password

    with APIClient() as api_client:
        if queue_id:
            data["queues"] = [
                get_json(api_client.get(f"queues/{queue}"))["url"]
                for queue in queue_id
            ]
        if group is not None:
            data["groups"] = get_groups(api_client, group)
        if locale is not None:
            ui_settings = get_json(
                api_client.get(f"users/{id_}"))["ui_settings"]
            data["ui_settings"] = {**ui_settings, "locale": locale}

        api_client.patch(f"users/{id_}", data)
Example #4
0
class TestAPIClient:
    api_client = APIClient(None)
    username = "******"
    password = "******"
    login_data = {"username": username, "password": password}

    def test_get_token_success(self, requests_mock, isolated_cli_runner):
        requests_mock.post(
            LOGIN_URL,
            additional_matcher=partial(match_uploaded_json, self.login_data),
            json={"key": TOKEN},
        )
        with isolated_cli_runner.isolation():
            assert TOKEN == self.api_client.get_token()

    def test_get_token_with_custom_lifetime(self, requests_mock):
        token_lifetime = 3600
        login_data = {
            "username": self.username,
            "password": self.password,
            "max_token_lifetime_s": token_lifetime,
        }
        requests_mock.post(
            LOGIN_URL,
            additional_matcher=partial(match_uploaded_json, login_data),
            json={"key": TOKEN},
        )
        assert TOKEN == APIClient(
            None, max_token_lifetime=token_lifetime).get_token()

    def test_get_token_failed(self, requests_mock):
        requests_mock.post(
            LOGIN_URL,
            additional_matcher=partial(match_uploaded_json, self.login_data),
            status_code=401,
        )
        with pytest.raises(click.ClickException) as e:
            self.api_client.get_token()
        assert "Login failed with the provided credentials." == str(e.value)

    def test_get_token_error(self, requests_mock):
        error_json = {"password": ["required"]}
        requests_mock.post(
            LOGIN_URL,
            additional_matcher=partial(match_uploaded_json, self.login_data),
            status_code=400,
            json=error_json,
        )
        with pytest.raises(click.ClickException) as e:
            self.api_client.get_token()
        assert f"Invalid response [{LOGIN_URL}]: {json.dumps(error_json)}" == str(
            e.value)

    @pytest.mark.usefixtures("mock_login_request")
    def test_user_agent_header(self, requests_mock, isolated_cli_runner):
        requests_mock.get(API_URL + "/v1/", request_headers=REQUEST_HEADERS)
        with isolated_cli_runner.isolation():
            self.api_client.get("")
        assert requests_mock.called
Example #5
0
class TestSideload:
    api_client = APIClient(None)
    url = f"{API_URL}/v1/tests"
    obj_url = f"{url}/1"
    sideloaded_obj = {"url": obj_url, "some": "test"}
    TESTS = APIObject("tests")

    def test_sideload_singular(self, requests_mock, isolated_cli_runner):
        requests_mock.get(self.url, json=self._paginated_rsp())

        with isolated_cli_runner.isolation():
            res = self.api_client._sideload([{
                "test": self.obj_url
            }], (self.TESTS, ))
        assert res == [{"test": self.sideloaded_obj}]

    def test_sideload_plural(self, requests_mock, isolated_cli_runner):
        requests_mock.get(self.url, json=self._paginated_rsp())

        with isolated_cli_runner.isolation():
            res = self.api_client._sideload([{
                "tests": [self.obj_url]
            }], (self.TESTS, ))
        assert res == [{"tests": [self.sideloaded_obj]}]

    def test_sideload_not_reachable_singular(self, requests_mock,
                                             isolated_cli_runner):
        requests_mock.get(self.url, json=self._paginated_rsp(0))

        with isolated_cli_runner.isolation():
            res = self.api_client._sideload([{
                "test": self.obj_url
            }], (self.TESTS, ))
        assert res == [{"test": {}}]

    def test_sideload_not_reachable_plural(self, requests_mock,
                                           isolated_cli_runner):
        requests_mock.get(self.url, json=self._paginated_rsp(0))

        with isolated_cli_runner.isolation():
            res = self.api_client._sideload([{
                "tests": [self.obj_url]
            }], (self.TESTS, ))
        assert res == [{"tests": []}]

    def _paginated_rsp(self, total: int = 1):
        assert total <= 1, "URL in sideloaded_obj is not unique."
        return {
            "results": [self.sideloaded_obj for _ in range(total)],
            "pagination": {
                "next": None,
                "total": total
            },
        }
Example #6
0
 def test_get_token_with_custom_lifetime(self, requests_mock):
     token_lifetime = 3600
     login_data = {
         "username": self.username,
         "password": self.password,
         "max_token_lifetime_s": token_lifetime,
     }
     requests_mock.post(
         LOGIN_URL,
         additional_matcher=partial(match_uploaded_json, login_data),
         json={"key": TOKEN},
     )
     assert TOKEN == APIClient(
         None, max_token_lifetime=token_lifetime).get_token()
Example #7
0
def download_command(ctx: click.Context, start: datetime.datetime,
                     stop: datetime.datetime, float_step: float) -> None:
    api_client = APIClient.csv()

    step = datetime.timedelta(days=float_step)
    dfs = []
    while stop > start:
        start += step
        rsp = api_client.get(
            f"byperiod/{ceil(step.total_seconds())}/{int(start.timestamp())}")
        dfs.append(pd.read_csv(StringIO(get_text(rsp)), sep=";"))

    df = pd.concat(dfs)
    with StringIO() as buffer:
        df.to_csv(buffer, sep=";", index=False)
        click.echo(buffer.getvalue())
Example #8
0
def list_command():
    with APIClient() as api_client:
        users_list, _ = api_client.get_paginated("users", {"is_active": True})
        groups_list, _ = api_client.get_paginated("groups")
        queues_list, _ = api_client.get_paginated("queues")
    groups = {group["url"]: group.get("name", "") for group in groups_list}
    queues = {queue["url"]: queue.get("id", "") for queue in queues_list}

    table = [[
        user["id"],
        user["username"],
        ", ".join(str(groups[g]) for g in user["groups"]),
        ", ".join(str(queues[q]) for q in user["queues"]),
    ] for user in users_list]

    click.echo(tabulate(table, headers=["id", "username", "groups", "queues"]))
Example #9
0
def download_command(
    ctx: click.Context, start: datetime.datetime, stop: datetime.datetime, float_step: float
) -> None:
    api_client = APIClient.csv(context=ctx.obj)

    step = datetime.timedelta(days=float_step)
    dfs = []
    while stop > start:
        start += step
        rsp = api_client.get(f"byperiod/{ceil(step.total_seconds())}/{int(start.timestamp())}")
        dfs.append(pd.read_csv(StringIO(get_text(rsp)), sep=";"))

    df = pd.concat(dfs)
    with StringIO() as buffer:
        # set line_terminator to ensure universal newline support for all the OS
        df.to_csv(buffer, sep=";", index=False, line_terminator="\n")
        click.echo(buffer.getvalue())
Example #10
0
def download_command(
    ctx: click.Context,
    id_: str,
    indent: int,
    ensure_ascii: bool,
    format_: str,
    output_file: Optional[IO[str]],
):
    with APIClient(context=ctx.obj) as api_client:
        schema_dict = get_json(api_client.get(f"schemas/{id_}"))
    if format_ == "json":
        schema_file = json.dumps(schema_dict["content"],
                                 indent=indent,
                                 ensure_ascii=ensure_ascii,
                                 sort_keys=True).encode("utf-8")
    else:
        schema_file = SchemaToXlsx().convert(schema_dict["content"])

    click.echo(schema_file, file=output_file, nl=False)
Example #11
0
def create_command(
    username: str,
    password: Optional[str],
    queue_id: Tuple[int],
    organization_id: Optional[int],
    group: str,
    locale: str,
) -> None:
    """
    Create user with USERNAME and add him to QUEUES specified by ids.
    """
    password = password or _generate_password()
    with APIClient() as api:
        _check_user_does_not_exists(api, username)
        organization_dict = _get_organization(api, organization_id)

        workspace_urls = {
            w["url"]
            for w in get_json(api.get("workspaces", {"organization": organization_dict["id"]}))[
                "results"
            ]
        }
        queue_urls = []
        for queue in queue_id:
            queue_dict = get_json(api.get(f"queues/{queue}"))
            if queue_dict["workspace"] in workspace_urls:
                queue_urls.append(queue_dict["url"])

        response = api.post(
            "users",
            {
                "username": username,
                "email": username,
                "organization": organization_dict["url"],
                "password": password,
                "groups": get_groups(api, group),
                "queues": queue_urls,
                "ui_settings": {"locale": locale},
            },
        )
        click.echo(f"{get_json(response)['id']}, {password}")
Example #12
0
def get_groups(api: APIClient, group_name: Optional[str]) -> List[str]:
    if group_name is None:
        return []
    return [g["url"] for g in get_json(api.get("groups", {"name": group_name}))["results"]]
Example #13
0
def _check_user_does_not_exists(api: APIClient, username: str) -> None:
    total_users = get_json(api.get(f"users", {"username": username}))["pagination"]["total"]
    if total_users:
        raise click.ClickException(f"User with username {username} already exists.")
Example #14
0
def delete_command(id_: str) -> None:
    with APIClient() as api_client:
        api_client.patch(f"users/{id_}", {"is_active": False})