Skip to content

Commit

Permalink
fix unttest
Browse files Browse the repository at this point in the history
  • Loading branch information
joelee2012 committed Aug 16, 2023
1 parent 34d7cdd commit 5dc4af4
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 35 deletions.
9 changes: 5 additions & 4 deletions api4jenkins/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
logger = logging.getLogger(__name__)


def log_request(request):
def log_request(request: httpx.Request) -> None:
logger.debug(
f"Send Request: {request.method} {request.url} - Waiting for response")


def check_response(response):
def check_response(response: httpx.Response) -> None:
if response.is_success or response.is_redirect:
return
if response.status_code == 404:
Expand All @@ -30,7 +30,7 @@ def check_response(response):
response.raise_for_status()


def new_http_client(**kwargs):
def new_http_client(**kwargs) -> httpx.Client:
return Client(
transport=HTTPTransport(retries=kwargs.pop('retries', 0)),
**kwargs,
Expand All @@ -51,5 +51,6 @@ def new_async_http_client(**kwargs) -> AsyncClient:
return AsyncClient(
transport=AsyncHTTPTransport(retries=kwargs.pop('retries', 0)),
**kwargs,
event_hooks={'request': [async_log_request], 'response': [async_check_response]}
event_hooks={'request': [async_log_request],
'response': [async_check_response]}
)
52 changes: 36 additions & 16 deletions api4jenkins/input.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# encoding: utf-8
import json

from .item import Item
from .mix import RawJsonMixIn
from .item import AsyncItem, Item
from .mix import AsyncRawJsonMixIn, RawJsonMixIn


class PendingInputAction(RawJsonMixIn, Item):
Expand All @@ -12,7 +12,7 @@ class PendingInputAction(RawJsonMixIn, Item):

def __init__(self, jenkins, raw):
super().__init__(
jenkins, f"{jenkins.url}{raw['abortUrl'].rstrip('abort')}")
jenkins, f"{jenkins.url}{raw['abortUrl'].rstrip('abort').lstrip('/')}")
self.raw = raw
self.raw['_class'] = 'PendingInputAction'

Expand All @@ -23,22 +23,42 @@ def abort(self):
def submit(self, **params):
'''submit `input step <https://www.jenkins.io/doc/pipeline/steps/pipeline-input-step/>`_
- for input requires parametes:
- if input requires parameters:
- if submit without parameters, it will use default value of parameters
- if submit with wrong parameters, exception raised
- for input does not requires parameters, but submit with paramters, exception raised
- if input does not requires parameters, but submit with parameters, exception raised
'''
if params:
args = [a['name'] for a in self.raw['inputs']]
params_keys = list(params.keys())
if not args:
raise TypeError(
f'input takes 0 argument, but got {params_keys}')
if not all(k in args for k in params_keys):
raise TypeError(
f'input takes arguments: {args}, but got {params_keys}')
params = [{'name': k, 'value': v} for k, v in params.items()]
data = {'proceed': self.raw['proceedText'],
'json': json.dumps({'parameter': params})}
data = _make_input_params(self.raw, **params)

Check warning on line 32 in api4jenkins/input.py

View check run for this annotation

Codecov / codecov/patch

api4jenkins/input.py#L32

Added line #L32 was not covered by tests
return self.handle_req('POST', 'submit', data=data)
return self.handle_req('POST', 'proceedEmpty')


def _make_input_params(api_json, **params):
input_args = [input['name'] for input in api_json['inputs']]
params_keys = list(params.keys())
if not input_args:
raise TypeError(f'input takes 0 argument, but got {params_keys}')
if any(k not in input_args for k in params_keys):
raise TypeError(

Check warning on line 43 in api4jenkins/input.py

View check run for this annotation

Codecov / codecov/patch

api4jenkins/input.py#L38-L43

Added lines #L38 - L43 were not covered by tests
f'input takes arguments: {input_args}, but got {params_keys}')
params = [{'name': k, 'value': v} for k, v in params.items()]
return {'proceed': api_json['proceedText'],

Check warning on line 46 in api4jenkins/input.py

View check run for this annotation

Codecov / codecov/patch

api4jenkins/input.py#L45-L46

Added lines #L45 - L46 were not covered by tests
'json': json.dumps({'parameter': params})}


class AsyncPendingInputAction(AsyncRawJsonMixIn, AsyncItem):
def __init__(self, jenkins, raw):
super().__init__(

Check warning on line 52 in api4jenkins/input.py

View check run for this annotation

Codecov / codecov/patch

api4jenkins/input.py#L52

Added line #L52 was not covered by tests
jenkins, f"{jenkins.url}{raw['abortUrl'].rstrip('abort').lstrip('/')}")
self.raw = raw
self.raw['_class'] = 'AsyncPendingInputAction'

Check warning on line 55 in api4jenkins/input.py

View check run for this annotation

Codecov / codecov/patch

api4jenkins/input.py#L54-L55

Added lines #L54 - L55 were not covered by tests

async def abort(self):
return await self.handle_req('POST', 'abort')

Check warning on line 58 in api4jenkins/input.py

View check run for this annotation

Codecov / codecov/patch

api4jenkins/input.py#L58

Added line #L58 was not covered by tests

async def submit(self, **params):
if params:
data = _make_input_params(self.raw, **params)
return await self.handle_req('POST', 'submit', data=data)
return await self.handle_req('POST', 'proceedEmpty')

Check warning on line 64 in api4jenkins/input.py

View check run for this annotation

Codecov / codecov/patch

api4jenkins/input.py#L61-L64

Added lines #L61 - L64 were not covered by tests
6 changes: 5 additions & 1 deletion api4jenkins/mix.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# encoding: utf-8

# pylint: disable=no-member

# type: ignore
from collections import namedtuple
from pathlib import PurePosixPath

Expand Down Expand Up @@ -134,7 +134,11 @@ async def enable(self):
async def disable(self):
return await self.handle_req('POST', 'disable')

class AsyncRawJsonMixIn:

async def api_json(self, tree='', depth=0):
return self.raw

class AsyncActionsMixIn:

async def get_parameters(self):
Expand Down
69 changes: 55 additions & 14 deletions tests/unit/test_input.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import pytest
from api4jenkins.input import PendingInputAction
from api4jenkins.input import AsyncPendingInputAction, PendingInputAction, _make_input_params


raw = {
"id": "3eaa25d43fac6e39a12c3936942b72c8",
"proceedText": "Proceed",
"message": "Is the build okay?",
"inputs": [],
"proceedUrl": "/job/input-pipeline/47/wfapi/inputSubmit?inputId=3eaa25d43fac6e39a12c3936942b72c8",
"abortUrl": "/job/input-pipeline/47/input/3eaa25d43fac6e39a12c3936942b72c8/abort",
"redirectApprovalUrl": "/job/input-pipeline/47/input/"
}
@pytest.fixture
def pending_input(jenkins):
raw = {
"id": "3eaa25d43fac6e39a12c3936942b72c8",
"proceedText": "Proceed",
"message": "Is the build okay?",
"inputs": [],
"proceedUrl": "/job/input-pipeline/47/wfapi/inputSubmit?inputId=3eaa25d43fac6e39a12c3936942b72c8",
"abortUrl": "/job/input-pipeline/47/input/3eaa25d43fac6e39a12c3936942b72c8/abort",
"redirectApprovalUrl": "/job/input-pipeline/47/input/"
}

return PendingInputAction(jenkins, raw)


@pytest.mark.skip
@pytest.fixture
def async_pending_input(async_jenkins):
return AsyncPendingInputAction(async_jenkins, raw)
# @pytest.mark.skip
class TestPendingInput:

def test_access_attrs(self, pending_input):
Expand Down Expand Up @@ -45,10 +46,50 @@ def test_submit_arg(self, pending_input, respx_mock):
assert respx_mock.calls[0].request.url == f'{pending_input.url}submit'

def test_submit_empty_with_arg(self, pending_input):
pending_input.raw['inputs'] = []
with pytest.raises(TypeError):
pending_input.submit(arg1='x')

def test_submit_wrong_arg(self, pending_input):
pending_input.raw['inputs'] = {'name': 'arg1'}
pending_input.raw['inputs'] = [{'name': 'arg1'}]
with pytest.raises(TypeError):
pending_input.submit(arg2='x')


class TestAsyncPendingInput:

async def test_access_attrs(self, async_pending_input):
assert isinstance(async_pending_input, AsyncPendingInputAction)
assert await async_pending_input.message == "Is the build okay?"
assert await async_pending_input.id == "3eaa25d43fac6e39a12c3936942b72c8"
assert await async_pending_input.proceed_url == "/job/input-pipeline/47/wfapi/inputSubmit?inputId=3eaa25d43fac6e39a12c3936942b72c8"
assert await async_pending_input.abort_url == "/job/input-pipeline/47/input/3eaa25d43fac6e39a12c3936942b72c8/abort"

async def test_abort(self, async_pending_input, respx_mock):
url = f'{async_pending_input.url}abort'
respx_mock.post(url)
await async_pending_input.abort()
assert respx_mock.calls[0].request.url == url

async def test_submit_empty(self, async_pending_input, respx_mock):
url=f'{async_pending_input.url}proceedEmpty'
respx_mock.post(url)
await async_pending_input.submit()
assert respx_mock.calls[0].request.url == url

async def test_submit_arg(self, async_pending_input, respx_mock):
async_pending_input.raw['inputs'] = [{'name': 'arg1'}]
url = f'{async_pending_input.url}submit'
respx_mock.post(url)
await async_pending_input.submit(arg1='x')
assert respx_mock.calls[0].request.url == url

async def test_submit_empty_with_arg(self, async_pending_input):
async_pending_input.raw['inputs'] = []
with pytest.raises(TypeError):
await async_pending_input.submit(arg1='x')

async def test_submit_wrong_arg(self, async_pending_input):
async_pending_input.raw['inputs'] = [{'name': 'arg1'}]
with pytest.raises(TypeError):
await async_pending_input.submit(arg2='x')

0 comments on commit 5dc4af4

Please sign in to comment.