diff --git a/routers/bpa_register.py b/routers/bpa_register.py index fc3b20b0..b62d081a 100644 --- a/routers/bpa_register.py +++ b/routers/bpa_register.py @@ -46,6 +46,7 @@ async def register_bpa_user( name=settings.organizations[org_id], status="pending", last_updated=now, + initial_request_time=now, updated_by="system", ).model_dump(mode="json") bpa_resources.append(resource) @@ -54,6 +55,7 @@ async def register_bpa_user( bpa_service = Service( name="Bioplatforms Australia Data Portal", id="bpa", + initial_request_time=now, status="pending", last_updated=now, updated_by="system", diff --git a/routers/user.py b/routers/user.py index 15c7f03a..c21281fc 100644 --- a/routers/user.py +++ b/routers/user.py @@ -176,6 +176,7 @@ async def request_service( new_service = Service( name=service_request.name, id=service_request.id, + initial_request_time=datetime.now(timezone.utc), status="pending", last_updated=datetime.now(timezone.utc), updated_by=user.access_token.sub, diff --git a/schemas/biocommons.py b/schemas/biocommons.py index 70c430b7..e384f03d 100644 --- a/schemas/biocommons.py +++ b/schemas/biocommons.py @@ -139,6 +139,7 @@ def from_galaxy_registration( galaxy_service = Service( name="Galaxy Australia", id="galaxy", + initial_request_time=datetime.now(), status="approved", last_updated=datetime.now(), updated_by="" diff --git a/schemas/service.py b/schemas/service.py index 2e286398..4d24c97e 100644 --- a/schemas/service.py +++ b/schemas/service.py @@ -9,6 +9,7 @@ class Resource(BaseModel): status: Literal["approved", "revoked", "pending"] id: str last_updated: Optional[datetime] = None + initial_request_time: Optional[datetime] = None updated_by: Optional[str] = None def approve(self): @@ -21,6 +22,7 @@ def revoke(self): class Service(BaseModel): name: str id: str + initial_request_time: Optional[datetime] = None status: Literal["approved", "revoked", "pending"] last_updated: datetime updated_by: str diff --git a/tests/test_bpa_register.py b/tests/test_bpa_register.py index a53c47e0..be2d9535 100644 --- a/tests/test_bpa_register.py +++ b/tests/test_bpa_register.py @@ -47,7 +47,6 @@ def test_to_biocommons_register_data(valid_registration_data): ) assert register_data.username == bpa_data.username assert register_data.name == bpa_data.fullname - # Test we fill the registration_from field in app_metadata assert register_data.app_metadata.registration_from == "bpa" @@ -84,6 +83,7 @@ def test_successful_registration( for resource in bpa_service["resources"]: assert "last_updated" in resource assert "updated_by" in resource + assert "initial_request_time" in resource assert resource["updated_by"] == "system" assert ( @@ -106,12 +106,14 @@ def test_service_and_resources_have_updated_by_system(): "status": "pending", "last_updated": datetime.now(UTC), "updated_by": "system", + "initial_request_time": datetime.now(UTC), } ], ) assert service.updated_by == "system" assert service.resources[0].updated_by == "system" - + assert hasattr(service.resources[0], "initial_request_time") + assert isinstance(service.resources[0].initial_request_time, datetime) def test_registration_duplicate_user( test_client, mock_auth_token, mocker, valid_registration_data diff --git a/tests/test_models.py b/tests/test_models.py index 491aa33d..ae290273 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -19,9 +19,7 @@ def frozen_time(): def test_approve_service(frozen_time): - """ - Test we can approve a service and set metadata correctly. - """ + """Test we can approve a service and set metadata correctly.""" service = Service(name="Test Service", id="service1", status="pending", last_updated=FROZEN_TIME - timedelta(hours=1), updated_by="") service.approve(updated_by="admin@example.com") @@ -31,9 +29,7 @@ def test_approve_service(frozen_time): def test_approve_service_from_app_metadata(frozen_time): - """ - Test we can approve a service by ID from BiocommonsAppMetadata. - """ + """Test we can approve a service by ID from BiocommonsAppMetadata.""" service = Service(name="Test Service", id="service1", status="pending", last_updated=FROZEN_TIME - timedelta(hours=1), updated_by="") other = Service(name="Other Service", id="service2", status="pending", @@ -47,9 +43,7 @@ def test_approve_service_from_app_metadata(frozen_time): def test_revoke_service(frozen_time): - """ - Test we can revoke a service and set metadata correctly. - """ + """Test we can revoke a service and set metadata correctly.""" service = Service(name="Test Service", id="service1", status="approved", last_updated=FROZEN_TIME - timedelta(hours=1), updated_by="") service.revoke(updated_by="admin@example.com") @@ -59,9 +53,7 @@ def test_revoke_service(frozen_time): def test_revoke_service_from_app_metadata(frozen_time): - """ - Test we can revoke a service by ID from BiocommonsAppMetadata. - """ + """Test we can revoke a service by ID from BiocommonsAppMetadata.""" service = Service(name="Test Service", id="service1", status="approved", last_updated=FROZEN_TIME - timedelta(hours=1), updated_by="") other = Service(name="Other Service", id="service2", status="approved", @@ -73,39 +65,65 @@ def test_revoke_service_from_app_metadata(frozen_time): assert service.last_updated == FROZEN_TIME assert other.status == "approved" -def test_approve_resource(): - resource = Resource(name="Test Resource", id="resource1", status="pending") + +def test_approve_resource(frozen_time): + resource = Resource( + name="Test Resource", + id="resource1", + status="pending", + initial_request_time=FROZEN_TIME + ) resource.approve() assert resource.status == "approved" + assert resource.initial_request_time == FROZEN_TIME -def test_approve_resource_from_service(): - resource = Resource(name="Test Resource", id="resource1", status="pending") +def test_approve_resource_from_service(frozen_time): + """Test that trying to approve a resource from a pending service raises an error.""" + resource = Resource( + name="Test Resource", + id="resource1", + status="pending", + initial_request_time=FROZEN_TIME + ) service = Service(name="Test Service", id="service1", status="approved", last_updated=FROZEN_TIME - timedelta(hours=1), updated_by="", resources=[resource]) service.approve_resource(resource_id="resource1") assert resource.status == "approved" + assert resource.initial_request_time == FROZEN_TIME -def test_approve_resource_from_pending_service(): - """ - Test that trying to approve a resource from a pending service raises an error. - """ - resource = Resource(name="Test Resource", id="resource1", status="pending") +def test_approve_resource_from_pending_service(frozen_time): + """Test that trying to approve a resource from a pending service raises an error.""" + resource = Resource( + name="Test Resource", + id="resource1", + status="pending", + initial_request_time=FROZEN_TIME + ) + service = Service(name="Test Service", id="service1", status="pending", last_updated=FROZEN_TIME - timedelta(hours=1), updated_by="", resources=[resource]) with pytest.raises(PermissionError, match="Service must be approved before approving a resource."): service.approve_resource(resource_id="resource1") assert resource.status == "pending" + assert resource.initial_request_time == FROZEN_TIME -def test_approve_resource_from_app_metadata(): - resource = Resource(name="Test Resource", id="resource1", status="pending") +def test_approve_resource_from_app_metadata(frozen_time): + resource = Resource( + name="Test Resource", + id="resource1", + status="pending", + initial_request_time=FROZEN_TIME + ) service = Service(name="Test Service", id="service1", status="approved", last_updated=FROZEN_TIME - timedelta(hours=1), updated_by="", resources=[resource]) app_metadata = AppMetadataFactory.build(services=[service]) app_metadata.approve_resource(service_id="service1", resource_id="resource1", updated_by="admin@example.com") + assert resource.status == "approved" + assert resource.initial_request_time == FROZEN_TIME