Skip to content

Commit

Permalink
Update tests and default_interface property
Browse files Browse the repository at this point in the history
  • Loading branch information
amickan committed Dec 9, 2024
1 parent dd6b92c commit 6cd94ed
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 13 deletions.
28 changes: 21 additions & 7 deletions app/grandchallenge/algorithms/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db.models import Count, Sum
from django.forms import ModelForm
from django.urls import reverse
from django.utils.html import format_html
from guardian.admin import GuardedModelAdmin

Expand Down Expand Up @@ -52,12 +53,17 @@ class Meta:

@admin.register(Algorithm)
class AlgorithmAdmin(GuardedModelAdmin):
readonly_fields = ("algorithm_forge_json", "inputs", "outputs")
readonly_fields = (
"algorithm_forge_json",
"default_interface_link",
"inputs",
"outputs",
)
list_display = (
"title",
"created",
"public",
"default_io",
"default_interface_link",
"time_limit",
"job_requires_gpu_type",
"job_requires_memory_gb",
Expand All @@ -72,18 +78,26 @@ class AlgorithmAdmin(GuardedModelAdmin):
def container_count(self, obj):
return obj.container_count

def default_interface_link(self, obj):
if obj.default_interface:
return format_html(
'<a href="{link}">{default_interface}</a>',
link=reverse(
"admin:algorithms_algorithminterface_change",
kwargs={"object_id": obj.default_interface.pk},
),
default_interface=obj.default_interface,
)
else:
return None

@staticmethod
def algorithm_forge_json(obj):
json_desc = get_forge_algorithm_template_context(algorithm=obj)
return format_html(
"<pre>{json_desc}</pre>", json_desc=json.dumps(json_desc, indent=2)
)

def default_io(self, obj):
return AlgorithmAlgorithmInterface.objects.get(
algorithm=obj, is_default=True
)

def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(
Expand Down
2 changes: 1 addition & 1 deletion app/grandchallenge/algorithms/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,7 @@ def __init__(self, *args, algorithm, **kwargs):
super().__init__(*args, **kwargs)
self._algorithm = algorithm

if self._algorithm.needs_default_interface:
if not self._algorithm.default_interface:
self.fields["set_as_default"].initial = True

def clean(self):
Expand Down
11 changes: 8 additions & 3 deletions app/grandchallenge/algorithms/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,14 @@ def default_workstation(self):

return w

@property
def needs_default_interface(self):
return not self.interfaces.exists()
@cached_property
def default_interface(self):
try:
return self.interfaces.get(
algorithmalgorithminterface__is_default=True
)
except ObjectDoesNotExist:
return None

def is_editor(self, user):
return user.groups.filter(pk=self.editors_group.pk).exists()
Expand Down
13 changes: 13 additions & 0 deletions app/tests/algorithms_tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1497,3 +1497,16 @@ def test_algorithminterface_create():
io = AlgorithmInterface.objects.create(inputs=inputs, outputs=outputs)
assert list(io.inputs.all()) == inputs
assert list(io.outputs.all()) == outputs


@pytest.mark.django_db
def test_has_default_interface():
alg1, alg2, alg3 = AlgorithmFactory.create_batch(3)
io1, io2 = AlgorithmInterfaceFactory.create_batch(2)

alg1.interfaces.add(io1, through_defaults={"is_default": True})
alg2.interfaces.add(io2)

assert alg1.default_interface == io1
assert not alg2.default_interface
assert not alg3.default_interface
8 changes: 6 additions & 2 deletions app/tests/algorithms_tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2218,7 +2218,11 @@ def test_algorithm_interface_create(client):
client=client,
method=client.post,
reverse_kwargs={"slug": alg.slug},
data={"inputs": [ci_1.pk], "outputs": [ci_2.pk]},
data={
"inputs": [ci_1.pk],
"outputs": [ci_2.pk],
"set_as_default": True,
},
user=user,
)
assert response.status_code == 302
Expand Down Expand Up @@ -2247,7 +2251,7 @@ def test_algorithm_interfaces_list_queryset(client):
alg.interfaces.set([io1, io2])
alg2.interfaces.set([io3, io4])

iots = AlgorithmAlgorithmInterface.objects.order_by("created").all()
iots = AlgorithmAlgorithmInterface.objects.order_by("id").all()

VerificationFactory(user=user, is_verified=True)

Expand Down

0 comments on commit 6cd94ed

Please sign in to comment.