Skip to content

Commit

Permalink
Merge pull request #7 from ScreenPyHQ/6/add-indexing-to-bodyofthelast…
Browse files Browse the repository at this point in the history
…request

Closes #6.
  • Loading branch information
perrygoy authored Feb 13, 2024
2 parents ed63a43 + 23df87b commit f164c41
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 8 deletions.
4 changes: 2 additions & 2 deletions screenpy_requests/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ def generate_send_method_class(method: str) -> Type[APIMethodAction]:
"""

class SendMETHODRequest:
"Will be programmatically replaced."
"""Will be programmatically replaced."""

@staticmethod
def to(url: str) -> SendAPIRequest:
"Will be programmatically replaced."
"""Will be programmatically replaced."""
return SendAPIRequest(method, url)

SendMETHODRequest.__doc__ = f"""Send a {method} request to a URL.
Expand Down
45 changes: 42 additions & 3 deletions screenpy_requests/questions/body_of_the_last_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Investigate the body of the last API response received by the Actor.
"""

from __future__ import annotations

from json.decoder import JSONDecodeError
from typing import Union

Expand All @@ -11,35 +13,72 @@

from ..abilities import MakeAPIRequests

subscripts = Union[str, int, slice]


class BodyOfTheLastResponse:
"""Ask about the body of the last API response received by the Actor.
If you are expecting a JSON response, this Question can be indexed to
return only a section of that response. See the examples below.
If you are expecting a text response, you can also slice the text.
Abilities Required:
:class:`~screenpy_requests.abilities.MakeAPIRequests`
Examples::
# JSON response
the_actor.should(
See.the(BodyOfTheLastResponse(), ContainsTheEntry(play="Hamlet"))
)
# JSON response, picked
the_actor.should(
See.the(
BodyOfTheLastResponse()["users"][0]["first_name"],
ReadsExactly("Monty")
),
)
# text response
the_actor.should(
See.the(BodyOfTheLastResponse(), ReadsExactly("To be, or not to be"))
)
# text response, sliced
the_actor.should(
See.the(BodyOfTheLastResponse()[6:12], ReadsExactly("Python"))
)
"""

body_parts: list[subscripts]

def __getitem__(self, key: subscripts) -> BodyOfTheLastResponse:
self.body_parts.append(key)
return self

def __init__(self) -> None:
self.body_parts = []

def describe(self) -> str:
"""Describe the Question.."""
return "The body of the last response."

@beat("{} examines the body of the last response they received.")
def answered_by(self, the_actor: Actor) -> Union[dict, str]:
def answered_by(self, the_actor: Actor) -> dict | str:
"""Direct the Actor to investigate the body of the last response."""
responses = the_actor.ability_to(MakeAPIRequests).responses
if len(responses) < 1:
raise UnableToAnswer(f"{the_actor} has not yet received any API responses.")
try:
return responses[-1].json()
response = responses[-1].json()
for part in self.body_parts:
response = response[part]
return response
except JSONDecodeError:
return responses[-1].text
response = responses[-1].text
for part in self.body_parts:
response = response[part]
return response
1 change: 0 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from unittest import mock

import pytest

from screenpy import AnActor

from screenpy_requests.abilities import MakeAPIRequests
Expand Down
3 changes: 2 additions & 1 deletion tests/test_actions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging

import pytest

from screenpy_requests.abilities import MakeAPIRequests
Expand All @@ -13,8 +14,8 @@
SendPATCHRequest,
SendPOSTRequest,
SendPUTRequest,
generate_send_method_class,
SetHeaders,
generate_send_method_class,
)


Expand Down
27 changes: 26 additions & 1 deletion tests/test_questions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from unittest import mock

import pytest

from requests.cookies import RequestsCookieJar
from screenpy.exceptions import UnableToAnswer

Expand Down Expand Up @@ -53,6 +52,32 @@ def test_ask_for_body_of_the_last_response(self, APITester):

assert BodyOfTheLastResponse().answered_by(APITester) == test_json

def test_stores_index_path(self):
botlr = BodyOfTheLastResponse()["shuffled"]["off"][10]["mortal"]["coils"]

assert botlr.body_parts == ["shuffled", "off", 10, "mortal", "coils"]

def test_digs_into_json(self, APITester):
test_json = {"plays": [{"name": "Hamlet"}]}
fake_response = mock.Mock()
fake_response.json.return_value = test_json
mocked_mar = APITester.ability_to(MakeAPIRequests)
mocked_mar.responses = [fake_response]

botlr = BodyOfTheLastResponse()["plays"][0]["name"]

assert botlr.answered_by(APITester) == "Hamlet"

def test_slices_text(self, APITester):
test_text = "My favorite play is Hamlet."
fake_response = mock.Mock()
fake_response.json.return_value = test_text
mocked_mar = APITester.ability_to(MakeAPIRequests)
mocked_mar.responses = [fake_response]

assert BodyOfTheLastResponse()[-7:-1].answered_by(APITester) == "Hamlet"



class TestCookies:
def test_can_be_instantiated(self):
Expand Down

0 comments on commit f164c41

Please sign in to comment.