Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup tests #16

Merged
merged 18 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,63 @@ jobs:
- name: Run twine checker
run: twine check dist/*

test:
name: Test
strategy:
matrix:
pyver: ['3.11', '3.12', '3.13']
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python ${{ matrix.pyver }}
uses: actions/setup-python@v5
with:
allow-prereleases: true
python-version: ${{ matrix.pyver }}
cache: 'pip'
cache-dependency-path: 'requirements*.txt'
- name: Install dependencies
uses: py-actions/py-dependency-install@v4
with:
path: requirements.txt
- name: Install itself
run: |
pip install .
- name: Run unittests
run: pytest
env:
COLOR: 'yes'
JUNCTION_API_KEY: ${{ secrets.JUNCTION_API_KEY }}
- run: python -m coverage xml
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}

check: # This job does nothing and is only used for the branch protection
if: always()

needs: [lint, test]

runs-on: ubuntu-latest

steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}

deploy:
name: Deploy
environment: release
permissions:
id-token: write
contents: write
runs-on: ubuntu-latest
needs: [lint]
needs: [check]
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .mypy.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[mypy]
files = junction
files = junction, tests
check_untyped_defs = True
follow_imports_for_stubs = True
disallow_any_decorated = True
Expand Down
6 changes: 5 additions & 1 deletion junction/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from junction.client import JunctionClient as JunctionClient
from junction.client import (

Check warning on line 1 in junction/__init__.py

View check run for this annotation

Codecov / codecov/patch

junction/__init__.py#L1

Added line #L1 was not covered by tests
PROD as PROD,
SANDBOX as SANDBOX,
JunctionClient as JunctionClient,
)
from junction.typedefs import (
Passenger as Passenger,
PlaceId as PlaceId,
Expand Down
26 changes: 12 additions & 14 deletions junction/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,19 @@
from functools import partial
from textwrap import indent
from types import TracebackType
from typing import Any, Generic, NoReturn, TypeVar
from typing import Any, Generic, NoReturn, Self, TypeVar

Check warning on line 10 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L10

Added line #L10 was not covered by tests

import aiojobs
from aiohttp import ClientResponse, ClientResponseError, ClientSession, ContentTypeError
from yarl import URL

from junction import typedefs as t

if sys.version_info >= (3, 11):
from typing import Self
else:
from typing import Any as Self


_T = TypeVar("_T")

HOST = "content-api.junction.dev"
PROD = "api.junction.travel"
SANDBOX = "content-api.sandbox.junction.dev"

Check warning on line 22 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L21-L22

Added lines #L21 - L22 were not covered by tests


class CustomEncoder(json.JSONEncoder):
Expand Down Expand Up @@ -94,8 +90,9 @@
class Booking:
_id: t.BookingId

def __init__(self, client: ClientSession, offer: t.OfferId, passengers: tuple[t.Passenger, ...]):
def __init__(self, client: ClientSession, offer: t.OfferId, passengers: tuple[t.Passenger, ...], host: str = PROD):

Check warning on line 93 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L93

Added line #L93 was not covered by tests
self._client = client
self._host = host # TODO: Use base_url in ClientSession and remove host parameter here.

Check warning on line 95 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L95

Added line #L95 was not covered by tests
self._offer = offer
self._passengers = passengers
self._confirmed = False
Expand All @@ -117,7 +114,7 @@
return self._price

async def confirm(self) -> None:
url = URL.build(scheme="https", host=HOST, path="/bookings")
url = URL.build(scheme="https", host=self._host, path="/bookings")

Check warning on line 117 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L117

Added line #L117 was not covered by tests
body = {"offerId": self._offer, "passengers": self._passengers}
async with self._client.post(url, json=body) as resp:
if not resp.ok:
Expand All @@ -133,7 +130,7 @@
if self._confirmed:
raise RuntimeError("Booking already confirmed")

url = URL.build(scheme="https", host=HOST, path="/bookings")
url = URL.build(scheme="https", host=self._host, path="/bookings")

Check warning on line 133 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L133

Added line #L133 was not covered by tests
body = {"offerId": self._offer, "passengers": self._passengers}
#print(json.dumps(body, cls=CustomEncoder))
async with self._client.post(url, json=body) as resp:
Expand All @@ -151,8 +148,9 @@
This is the JunctionClient. Use this class to make calls to the JunctionAPI.
You can use this to do a search for places and the use the placeids to do FlightSearch, TrainSearch, etc.
'''
def __init__(self, api_key: str):
def __init__(self, api_key: str, host: str = PROD):

Check warning on line 151 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L151

Added line #L151 was not covered by tests
self._api_key = api_key
self._host = host

Check warning on line 153 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L153

Added line #L153 was not covered by tests

def search_places(
self,
Expand All @@ -174,7 +172,7 @@
if search_within is not None:
query["query[placeToSearchWithin]"] = search_within

url = URL.build(scheme="https", host=HOST, path="/places", query=query)
url = URL.build(scheme="https", host=self._host, path="/places", query=query)

Check warning on line 175 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L175

Added line #L175 was not covered by tests
return ResultsIterator[t.Place](self._client, self._scheduler, url)

async def flight_search(
Expand All @@ -184,7 +182,7 @@
depart_after: datetime,
passenger_birth_dates: Iterable[date]
) -> ResultsIterator[t.FlightOffer]:
url = URL.build(scheme="https", host=HOST, path="/flight-searches")
url = URL.build(scheme="https", host=self._host, path="/flight-searches")

Check warning on line 185 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L185

Added line #L185 was not covered by tests
ages = tuple({"dateOfBirth": d} for d in passenger_birth_dates)
query = {"originId": origin, "destinationId": destination,
"departureAfter": depart_after, "passengerAges": ages}
Expand All @@ -202,7 +200,7 @@
return_depart_after: datetime | None,
passenger_birth_dates: Iterable[date]
) -> ResultsIterator[t.TrainOffer]:
url = URL.build(scheme="https", host=HOST, path="/train-searches")
url = URL.build(scheme="https", host=self._host, path="/train-searches")

Check warning on line 203 in junction/client.py

View check run for this annotation

Codecov / codecov/patch

junction/client.py#L203

Added line #L203 was not covered by tests
ages = tuple({"dateOfBirth": d} for d in passenger_birth_dates)
query = {"originId": origin, "destinationId": destination,
"departureAfter": depart_after, "passengerAges": ages,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ dependencies = ["aiohttp>=3.10,<4", "aiojobs>=1.3,<2"]
description = "SDK for Junction"
dynamic = ["version"]
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.11"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: BSD License",
Expand Down
17 changes: 17 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[pytest]
addopts =
# show 10 slowest invocations:
--durations=10
# a bit of verbosity doesn't hurt:
-v
# report all the things == -rxXs:
-ra
# show values of the local vars in errors:
--showlocals
# coverage reports
--cov=junction/ --cov=tests/ --cov-report term
asyncio_mode = auto
filterwarnings =
error
testpaths = tests/
xfail_strict = true
5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
aiohttp==3.10.6
aiojobs==1.3.0
coverage==7.6.1
mypy==1.11.2
pytest==8.3.3
pytest-aiohttp==1.0.5
pytest-asyncio==0.24
pytest-cov==5.0.0
13 changes: 13 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import os
from typing import AsyncIterator

import pytest

from junction import SANDBOX, JunctionClient

@pytest.fixture
async def client() -> AsyncIterator[JunctionClient]:
key = os.environ["JUNCTION_API_KEY"]
assert key
async with JunctionClient(key, SANDBOX) as client:
yield client
11 changes: 11 additions & 0 deletions tests/test_places.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from junction import JunctionClient

async def test_no_results_iter(client: JunctionClient) -> None:
no_result = False

async for place in client.search_places(coords=(51.01, -32.51, 50)):
assert False

Check warning on line 7 in tests/test_places.py

View check run for this annotation

Codecov / codecov/patch

tests/test_places.py#L7

Added line #L7 was not covered by tests
else:
no_result = True

assert no_result