Skip offering selection if there is only one
All checks were successful
Tests / test (push) Successful in 26s

closes #258
This commit is contained in:
Tobias Kunze 2025-11-06 16:38:13 +01:00
parent 29edfd2d3a
commit fa7a170871
2 changed files with 124 additions and 4 deletions

View file

@ -66,14 +66,33 @@ class ServiceDetailView(OrganizationViewMixin, DetailView):
def get_queryset(self): def get_queryset(self):
return self.request.organization.get_visible_services() return self.request.organization.get_visible_services()
def get_context_data(self, **kwargs): @cached_property
context = super().get_context_data(**kwargs) def visible_offerings(self):
offerings = context["service"].offerings.all() offerings = self.object.offerings.all()
if self.request.organization.limit_cloudproviders.exists(): if self.request.organization.limit_cloudproviders.exists():
offerings = offerings.filter( offerings = offerings.filter(
provider__in=self.request.organization.limit_cloudproviders.all() provider__in=self.request.organization.limit_cloudproviders.all()
) )
context["visible_offerings"] = offerings.select_related("provider") return offerings
def get(self, request, *args, **kwargs):
self.object = self.get_object()
# If there's exactly one offering, skip provider selection and go directly to it
if self.visible_offerings.count() == 1:
offering = self.visible_offerings.first()
return redirect(
"frontend:organization.offering",
organization=self.request.organization.slug,
slug=self.object.slug,
pk=offering.pk,
)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["visible_offerings"] = self.visible_offerings.select_related("provider")
return context return context

View file

@ -1,5 +1,6 @@
import pytest import pytest
from servala.core.models.service import CloudProvider, ServiceOffering
@pytest.mark.parametrize( @pytest.mark.parametrize(
"url,redirect", "url,redirect",
@ -45,3 +46,103 @@ def test_organization_linked_in_sidebar(
assert response.status_code == 200 assert response.status_code == 200
assert organization.name in response.content.decode() assert organization.name in response.content.decode()
assert other_organization.name not in response.content.decode() assert other_organization.name not in response.content.decode()
@pytest.mark.django_db
def test_service_detail_redirects_with_single_offering(
client, org_owner, organization, test_service, test_service_offering
):
client.force_login(org_owner)
url = f"/org/{organization.slug}/services/{test_service.slug}/"
response = client.get(url)
assert response.status_code == 302
expected_url = f"/org/{organization.slug}/services/{test_service.slug}/offering/{test_service_offering.pk}/"
assert response.url == expected_url
@pytest.mark.django_db
def test_service_detail_shows_multiple_offerings(
client, org_owner, organization, test_service, test_service_offering
):
second_provider = CloudProvider.objects.create(
name="AWS", description="Amazon Web Services"
)
second_offering = ServiceOffering.objects.create(
service=test_service,
provider=second_provider,
description="Redis on AWS",
osb_plan_id="test-plan-456",
)
client.force_login(org_owner)
url = f"/org/{organization.slug}/services/{test_service.slug}/"
response = client.get(url)
assert response.status_code == 200
content = response.content.decode()
assert test_service_offering.provider.name in content
assert second_offering.provider.name in content
assert "Create Instance" in content
@pytest.mark.django_db
def test_service_detail_respects_cloud_provider_restrictions(
client, org_owner, organization, test_service, test_service_offering
):
second_provider = CloudProvider.objects.create(
name="AWS", description="Amazon Web Services"
)
ServiceOffering.objects.create(
service=test_service,
provider=second_provider,
description="Redis on AWS",
osb_plan_id="test-plan-456",
)
organization.origin.limit_cloudproviders.add(test_service_offering.provider)
client.force_login(org_owner)
url = f"/org/{organization.slug}/services/{test_service.slug}/"
response = client.get(url)
assert response.status_code == 302
expected_url = f"/org/{organization.slug}/services/{test_service.slug}/offering/{test_service_offering.pk}/"
assert response.url == expected_url
@pytest.mark.django_db
def test_service_detail_no_redirect_with_restricted_multiple_offerings(
client, org_owner, organization, test_service, test_service_offering
):
second_provider = CloudProvider.objects.create(
name="AWS", description="Amazon Web Services"
)
second_offering = ServiceOffering.objects.create(
service=test_service,
provider=second_provider,
description="Redis on AWS",
osb_plan_id="test-plan-456",
)
third_provider = CloudProvider.objects.create(
name="Azure", description="Microsoft Azure"
)
third_offering = ServiceOffering.objects.create(
service=test_service,
provider=third_provider,
description="Redis on Azure",
osb_plan_id="test-plan-789",
)
organization.origin.limit_cloudproviders.add(
test_service_offering.provider, second_provider
)
client.force_login(org_owner)
url = f"/org/{organization.slug}/services/{test_service.slug}/"
response = client.get(url)
assert response.status_code == 200
content = response.content.decode()
assert test_service_offering.provider.name in content
assert second_offering.provider.name in content
assert third_offering.provider.name not in content