1+ from typing import Callable , Generator , TypeVar , List
2+ from urllib .parse import urljoin
3+ from uuid import uuid4
4+ import pytest
5+ from datetime import datetime , timezone , timedelta
6+ from geojson_pydantic import Point
7+ from pytest import Parser , fixture
8+
9+ from stapi_fastapi .models .product import Product , Provider , ProviderRole
10+ from stapi_fastapi .main_router import MainRouter
11+ from stapi_fastapi .models .shared import Link
12+ from stapi_fastapi .models .opportunity import OpportunityProperties , Opportunity
13+ from stapi_fastapi .types .datetime_interval import DatetimeInterval
14+
115from collections .abc import Iterator
216from datetime import UTC , datetime
317from typing import Callable
822from fastapi .testclient import TestClient
923from geojson_pydantic import Point
1024from pydantic import BaseModel
11- from stapi_fastapi .api import StapiRouter
1225from stapi_fastapi .models .opportunity import Opportunity , OpportunityRequest
1326from stapi_fastapi .models .product import Product , Provider , ProviderRole
27+ from stapi_fastapi .products_router import ProductRouter
1428
1529from .backend import TestBackend
1630
@@ -30,7 +44,7 @@ def stapi_client(stapi_backend, base_url: str) -> Iterator[TestClient]:
3044 app = FastAPI ()
3145
3246 app .include_router (
33- StapiRouter (backend = stapi_backend ).router ,
47+ ProductRouter (backend = stapi_backend ).router ,
3448 prefix = "" ,
3549 )
3650
@@ -100,3 +114,107 @@ def allowed_payloads(products: list[Product]) -> Iterator[list[OpportunityReques
100114 filter = {},
101115 ),
102116 ]
117+
118+ T = TypeVar ("T" )
119+
120+ YieldFixture = Generator [T , None , None ]
121+
122+
123+ def pytest_addoption (parser : Parser ):
124+ parser .addoption (
125+ "--stapi-backend" ,
126+ action = "store" ,
127+ default = "stapi_fastapi_test_backend:TestBackend" ,
128+ )
129+ parser .addoption ("--stapi-prefix" , action = "store" , default = "/stapi" )
130+ parser .addoption ("--stapi-product-id" , action = "store" , default = "mock:standard" )
131+
132+
133+ @fixture (scope = "session" )
134+ def base_url () -> YieldFixture [str ]:
135+ yield "http://stapiserver"
136+
137+
138+ @fixture
139+ def stapi_backend ():
140+ yield TestBackend ()
141+
142+
143+ @fixture
144+ def stapi_client (stapi_backend , base_url : str ) -> YieldFixture [TestClient ]:
145+ app = FastAPI ()
146+
147+ app .include_router (
148+ MainRouter (backend = stapi_backend ).router ,
149+ prefix = "" ,
150+ )
151+
152+ yield TestClient (app , base_url = f"{ base_url } " )
153+
154+
155+ @fixture (scope = "session" )
156+ def url_for (base_url : str ) -> YieldFixture [Callable [[str ], str ]]:
157+ def with_trailing_slash (value : str ) -> str :
158+ return value if value .endswith ("/" ) else f"{ value } /"
159+
160+ def url_for (value : str ) -> str :
161+ return urljoin (with_trailing_slash (base_url ), f"./{ value .lstrip ('/' )} " )
162+
163+ yield url_for
164+
165+ @pytest .fixture
166+ def mock_provider_umbra () -> Provider :
167+ return Provider (
168+ name = "Umbra Provider" ,
169+ description = "A provider for Umbra data" ,
170+ roles = [ProviderRole .producer ], # Example role
171+ url = "https://umbra-provider.example.com" # Must be a valid URL
172+ )
173+
174+ # Define a mock OpportunityProperties class for Umbra
175+ class UmbraSpotlightProperties (OpportunityProperties ):
176+ datetime : DatetimeInterval
177+
178+ @pytest .fixture
179+ def mock_product_umbra_spotlight (mock_provider_umbra : Provider ) -> Product :
180+ """Fixture for a mock Umbra Spotlight product."""
181+
182+ return Product (
183+ id = str (uuid4 ()),
184+ title = "Umbra Spotlight Product" ,
185+ description = "Test product for umbra spotlight" ,
186+ license = "CC-BY-4.0" ,
187+ keywords = ["test" , "umbra" , "satellite" ],
188+ providers = [mock_provider_umbra ],
189+ links = [
190+ Link (href = "http://example.com" , rel = "self" ),
191+ Link (href = "http://example.com/catalog" , rel = "parent" ),
192+ ],
193+ parameters = UmbraSpotlightProperties
194+ )
195+
196+ @pytest .fixture
197+ def mock_products (mock_product_umbra_spotlight : Product ) -> List [Product ]:
198+ """Fixture to return a list of mock products."""
199+ return [mock_product_umbra_spotlight ]
200+
201+ @pytest .fixture
202+ def mock_umbra_spotlight_opportunities () -> List [Opportunity ]:
203+ """Fixture to create mock data for Opportunities for `umbra-spotlight-1`."""
204+ now = datetime .now (timezone .utc ) # Use timezone-aware datetime
205+ start = now
206+ end = start + timedelta (days = 5 )
207+ datetime_interval = f"{ start .isoformat ()} /{ end .isoformat ()} "
208+
209+ # Create a list of mock opportunities for the given product
210+ return [
211+ Opportunity (
212+ id = str (uuid4 ()),
213+ type = "Feature" ,
214+ geometry = Point (type = "Point" , coordinates = [0 , 0 ]), # Simple point geometry
215+ properties = UmbraSpotlightProperties (
216+ datetime = datetime_interval ,
217+ off_nadir = 20 ,
218+ ),
219+ ),
220+ ]
0 commit comments