forked from enviPath/enviPy
[Fix] Remove all Scenarios, catch empty SMILES, prevent default Package delete (#134)
Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#134
This commit is contained in:
@ -233,6 +233,11 @@ def breadcrumbs(first_level_object=None, second_level_namespace=None, second_lev
|
|||||||
def set_scenarios(current_user, attach_object, scenario_urls: List[str]):
|
def set_scenarios(current_user, attach_object, scenario_urls: List[str]):
|
||||||
scens = []
|
scens = []
|
||||||
for scenario_url in scenario_urls:
|
for scenario_url in scenario_urls:
|
||||||
|
|
||||||
|
# As empty lists will be removed in POST request well send ['']
|
||||||
|
if scenario_url == '':
|
||||||
|
continue
|
||||||
|
|
||||||
package = PackageManager.get_package_by_url(current_user, scenario_url)
|
package = PackageManager.get_package_by_url(current_user, scenario_url)
|
||||||
scen = Scenario.objects.get(package=package, uuid=scenario_url.split('/')[-1])
|
scen = Scenario.objects.get(package=package, uuid=scenario_url.split('/')[-1])
|
||||||
scens.append(scen)
|
scens.append(scen)
|
||||||
@ -743,33 +748,43 @@ def package_model(request, package_uuid, model_uuid):
|
|||||||
current_model = EPModel.objects.get(package=current_package, uuid=model_uuid)
|
current_model = EPModel.objects.get(package=current_package, uuid=model_uuid)
|
||||||
|
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
|
classify = request.GET.get('classify', False)
|
||||||
|
ad_assessment = request.GET.get('app-domain-assessment', False)
|
||||||
|
|
||||||
if request.GET.get('classify', False):
|
if classify or ad_assessment:
|
||||||
smiles = request.GET['smiles']
|
smiles = request.GET.get('smiles', '').strip()
|
||||||
stand_smiles = FormatConverter.standardize(smiles)
|
|
||||||
pred_res = current_model.predict(stand_smiles)
|
|
||||||
res = []
|
|
||||||
|
|
||||||
for pr in pred_res:
|
# Check if smiles is non empty and valid
|
||||||
if len(pr) > 0:
|
if smiles == '':
|
||||||
products = []
|
return JsonResponse({'error': 'Received empty SMILES'}, status=400)
|
||||||
for prod_set in pr.product_sets:
|
|
||||||
logger.debug(f"Checking {prod_set}")
|
|
||||||
products.append(tuple([x for x in prod_set]))
|
|
||||||
|
|
||||||
res.append({
|
try:
|
||||||
'products': list(set(products)),
|
stand_smiles = FormatConverter.standardize(smiles)
|
||||||
'probability': pr.probability,
|
except ValueError as e:
|
||||||
'btrule': {k: getattr(pr.rule, k) for k in ['url', 'name']} if pr.rule is not None else None
|
return JsonResponse({'error': f'"{smiles}" is not a valid SMILES'}, status=400)
|
||||||
})
|
|
||||||
|
|
||||||
return JsonResponse(res, safe=False)
|
if classify:
|
||||||
|
pred_res = current_model.predict(stand_smiles)
|
||||||
|
res = []
|
||||||
|
|
||||||
elif request.GET.get('app-domain-assessment', False):
|
for pr in pred_res:
|
||||||
smiles = request.GET['smiles']
|
if len(pr) > 0:
|
||||||
stand_smiles = FormatConverter.standardize(smiles)
|
products = []
|
||||||
app_domain_assessment = current_model.app_domain.assess(stand_smiles)[0]
|
for prod_set in pr.product_sets:
|
||||||
return JsonResponse(app_domain_assessment, safe=False)
|
logger.debug(f"Checking {prod_set}")
|
||||||
|
products.append(tuple([x for x in prod_set]))
|
||||||
|
|
||||||
|
res.append({
|
||||||
|
'products': list(set(products)),
|
||||||
|
'probability': pr.probability,
|
||||||
|
'btrule': {k: getattr(pr.rule, k) for k in ['url', 'name']} if pr.rule is not None else None
|
||||||
|
})
|
||||||
|
|
||||||
|
return JsonResponse(res, safe=False)
|
||||||
|
|
||||||
|
else:
|
||||||
|
app_domain_assessment = current_model.app_domain.assess(stand_smiles)[0]
|
||||||
|
return JsonResponse(app_domain_assessment, safe=False)
|
||||||
|
|
||||||
context = get_base_context(request)
|
context = get_base_context(request)
|
||||||
context['title'] = f'enviPath - {current_package.name} - {current_model.name}'
|
context['title'] = f'enviPath - {current_package.name} - {current_model.name}'
|
||||||
@ -860,6 +875,11 @@ def package(request, package_uuid):
|
|||||||
|
|
||||||
if hidden := request.POST.get('hidden', None):
|
if hidden := request.POST.get('hidden', None):
|
||||||
if hidden == 'delete':
|
if hidden == 'delete':
|
||||||
|
|
||||||
|
if current_user.default_package == current_package:
|
||||||
|
return error(request, f'Package "{current_package.name}" is the default and cannot be deleted!',
|
||||||
|
'You cannot delete the default package. If you want to delete this package you have to set another default package first.')
|
||||||
|
|
||||||
logger.debug(current_package.delete())
|
logger.debug(current_package.delete())
|
||||||
return redirect(s.SERVER_URL + '/package')
|
return redirect(s.SERVER_URL + '/package')
|
||||||
elif hidden == 'publish-package':
|
elif hidden == 'publish-package':
|
||||||
@ -1017,9 +1037,9 @@ def package_compound(request, package_uuid, compound_uuid):
|
|||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
selected_scenarios = request.POST.getlist('selected-scenarios')
|
if 'selected-scenarios' in request.POST:
|
||||||
|
selected_scenarios = request.POST.getlist('selected-scenarios')
|
||||||
|
|
||||||
if selected_scenarios is not None:
|
|
||||||
set_scenarios(current_user, current_compound, selected_scenarios)
|
set_scenarios(current_user, current_compound, selected_scenarios)
|
||||||
return redirect(current_compound.url)
|
return redirect(current_compound.url)
|
||||||
|
|
||||||
@ -1126,9 +1146,9 @@ def package_compound_structure(request, package_uuid, compound_uuid, structure_u
|
|||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
selected_scenarios = request.POST.getlist('selected-scenarios')
|
if 'selected-scenarios' in request.POST:
|
||||||
|
selected_scenarios = request.POST.getlist('selected-scenarios')
|
||||||
|
|
||||||
if selected_scenarios is not None:
|
|
||||||
set_scenarios(current_user, current_structure, selected_scenarios)
|
set_scenarios(current_user, current_structure, selected_scenarios)
|
||||||
return redirect(current_structure.url)
|
return redirect(current_structure.url)
|
||||||
|
|
||||||
@ -1253,9 +1273,9 @@ def package_rule(request, package_uuid, rule_uuid):
|
|||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
selected_scenarios = request.POST.getlist('selected-scenarios')
|
if 'selected-scenarios' in request.POST:
|
||||||
|
selected_scenarios = request.POST.getlist('selected-scenarios')
|
||||||
|
|
||||||
if selected_scenarios is not None:
|
|
||||||
set_scenarios(current_user, current_rule, selected_scenarios)
|
set_scenarios(current_user, current_rule, selected_scenarios)
|
||||||
return redirect(current_rule.url)
|
return redirect(current_rule.url)
|
||||||
|
|
||||||
@ -1356,9 +1376,9 @@ def package_reaction(request, package_uuid, reaction_uuid):
|
|||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
selected_scenarios = request.POST.getlist('selected-scenarios')
|
if 'selected-scenarios' in request.POST:
|
||||||
|
selected_scenarios = request.POST.getlist('selected-scenarios')
|
||||||
|
|
||||||
if selected_scenarios is not None:
|
|
||||||
set_scenarios(current_user, current_reaction, selected_scenarios)
|
set_scenarios(current_user, current_reaction, selected_scenarios)
|
||||||
return redirect(current_reaction.url)
|
return redirect(current_reaction.url)
|
||||||
|
|
||||||
@ -1421,10 +1441,10 @@ def package_pathways(request, package_uuid):
|
|||||||
|
|
||||||
name = request.POST.get('name')
|
name = request.POST.get('name')
|
||||||
description = request.POST.get('description')
|
description = request.POST.get('description')
|
||||||
pw_mode = request.POST.get('predict', 'predict')
|
pw_mode = request.POST.get('predict', 'predict').strip()
|
||||||
smiles = request.POST.get('smiles')
|
smiles = request.POST.get('smiles', '').strip()
|
||||||
|
|
||||||
if smiles is None or smiles.strip() == '':
|
if 'smiles' in request.POST and smiles == '':
|
||||||
return error(request, "Pathway prediction failed!",
|
return error(request, "Pathway prediction failed!",
|
||||||
"Pathway prediction failed due to missing or empty SMILES")
|
"Pathway prediction failed due to missing or empty SMILES")
|
||||||
|
|
||||||
@ -1543,9 +1563,9 @@ def package_pathway(request, package_uuid, pathway_uuid):
|
|||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
selected_scenarios = request.POST.getlist('selected-scenarios')
|
if 'selected-scenarios' in request.POST:
|
||||||
|
selected_scenarios = request.POST.getlist('selected-scenarios')
|
||||||
|
|
||||||
if selected_scenarios is not None:
|
|
||||||
set_scenarios(current_user, current_pathway, selected_scenarios)
|
set_scenarios(current_user, current_pathway, selected_scenarios)
|
||||||
return redirect(current_pathway.url)
|
return redirect(current_pathway.url)
|
||||||
|
|
||||||
@ -1689,9 +1709,9 @@ def package_pathway_node(request, package_uuid, pathway_uuid, node_uuid):
|
|||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
selected_scenarios = request.POST.getlist('selected-scenarios')
|
if 'selected-scenarios' in request.POST:
|
||||||
|
selected_scenarios = request.POST.getlist('selected-scenarios')
|
||||||
|
|
||||||
if selected_scenarios is not None:
|
|
||||||
set_scenarios(current_user, current_node, selected_scenarios)
|
set_scenarios(current_user, current_node, selected_scenarios)
|
||||||
return redirect(current_node.url)
|
return redirect(current_node.url)
|
||||||
|
|
||||||
@ -1798,9 +1818,9 @@ def package_pathway_edge(request, package_uuid, pathway_uuid, edge_uuid):
|
|||||||
current_edge.delete()
|
current_edge.delete()
|
||||||
return redirect(current_pathway.url)
|
return redirect(current_pathway.url)
|
||||||
|
|
||||||
selected_scenarios = request.POST.getlist('selected-scenarios')
|
if 'selected-scenarios' in request.POST:
|
||||||
|
selected_scenarios = request.POST.getlist('selected-scenarios')
|
||||||
|
|
||||||
if selected_scenarios is not None:
|
|
||||||
set_scenarios(current_user, current_edge, selected_scenarios)
|
set_scenarios(current_user, current_edge, selected_scenarios)
|
||||||
return redirect(current_edge.url)
|
return redirect(current_edge.url)
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
<h4 class="alert-heading">{{ error_message }}</h4>
|
<h4 class="alert-heading">{{ error_message }}</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<p class="mb-0">
|
<p class="mb-0">
|
||||||
{{ error_detail }}<br>
|
{{ error_detail }}
|
||||||
The error was logged and will be investigated.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -89,7 +89,7 @@
|
|||||||
<div class="collapse navbar-collapse collapse-framework navbar-collapse-framework" id="navbarCollapse">
|
<div class="collapse navbar-collapse collapse-framework navbar-collapse-framework" id="navbarCollapse">
|
||||||
<ul class="nav navbar-nav navbar-nav-framework">
|
<ul class="nav navbar-nav navbar-nav-framework">
|
||||||
<li>
|
<li>
|
||||||
<a class="button" data-toggle="modal" data-target="#predict_modal">
|
<a href="#" data-toggle="modal" data-target="#predict_modal">
|
||||||
Predict Pathway
|
Predict Pathway
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -103,6 +103,7 @@
|
|||||||
var textSmiles = $('#index-form-text-input').val().trim();
|
var textSmiles = $('#index-form-text-input').val().trim();
|
||||||
|
|
||||||
if (textSmiles === '') {
|
if (textSmiles === '') {
|
||||||
|
$(this).prop("disabled", false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -64,6 +64,9 @@
|
|||||||
|
|
||||||
$('#set_scenario_modal_form_submit').on('click', function (e) {
|
$('#set_scenario_modal_form_submit').on('click', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if ($('##scenario-select').val().length == 0) {
|
||||||
|
$('##scenario-select').val([''])
|
||||||
|
}
|
||||||
$('#set_scenario_modal_form').submit();
|
$('#set_scenario_modal_form').submit();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -315,12 +315,18 @@
|
|||||||
$("#predict-button").on("click", function (e) {
|
$("#predict-button").on("click", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
clear("predictResultTable");
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"smiles": $("#smiles-to-predict").val(),
|
"smiles": $("#smiles-to-predict").val(),
|
||||||
"classify": "ILikeCats!"
|
"classify": "ILikeCats!"
|
||||||
}
|
}
|
||||||
|
|
||||||
clear("predictResultTable");
|
if (data["smiles"].trim() === "") {
|
||||||
|
$("#predictResultTable").addClass("alert alert-danger");
|
||||||
|
$("#predictResultTable").append("Please enter a SMILES string to predict!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
makeLoadingGif("#predictLoading", "{% static '/images/wait.gif' %}");
|
makeLoadingGif("#predictLoading", "{% static '/images/wait.gif' %}");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -332,17 +338,17 @@
|
|||||||
$("#predictLoading").empty();
|
$("#predictLoading").empty();
|
||||||
handlePredictionResponse(data);
|
handlePredictionResponse(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error");
|
|
||||||
$("#predictLoading").empty();
|
$("#predictLoading").empty();
|
||||||
$("#predictResultTable").addClass("alert alert-danger");
|
$("#predictResultTable").addClass("alert alert-danger");
|
||||||
$("#predictResultTable").append("Error while processing request :/");
|
$("#predictResultTable").append("Error while processing response :/");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function (jqXHR, textStatus, errorThrown) {
|
error: function (jqXHR, textStatus, errorThrown, x) {
|
||||||
$("#predictLoading").empty();
|
$("#predictLoading").empty();
|
||||||
$("#predictResultTable").addClass("alert alert-danger");
|
$("#predictResultTable").addClass("alert alert-danger");
|
||||||
$("#predictResultTable").append("Error while processing request :/");
|
$("#predictResultTable").append(jqXHR.responseJSON.error);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -351,12 +357,20 @@
|
|||||||
$("#assess-button").on("click", function (e) {
|
$("#assess-button").on("click", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
clear("appDomainAssessmentResultTable");
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"smiles": $("#smiles-to-assess").val(),
|
"smiles": $("#smiles-to-assess").val(),
|
||||||
"app-domain-assessment": "ILikeCats!"
|
"app-domain-assessment": "ILikeCats!"
|
||||||
}
|
}
|
||||||
|
|
||||||
clear("appDomainAssessmentResultTable");
|
if (data["smiles"].trim() === "") {
|
||||||
|
$("#appDomainAssessmentResultTable").addClass("alert alert-danger");
|
||||||
|
$("#appDomainAssessmentResultTable").append("Please enter a SMILES string to predict!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
makeLoadingGif("#appDomainLoading", "{% static '/images/wait.gif' %}");
|
makeLoadingGif("#appDomainLoading", "{% static '/images/wait.gif' %}");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -369,16 +383,15 @@
|
|||||||
handleAssessmentResponse("{% url 'depict' %}", data);
|
handleAssessmentResponse("{% url 'depict' %}", data);
|
||||||
console.log(data);
|
console.log(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error");
|
|
||||||
$("#appDomainLoading").empty();
|
$("#appDomainLoading").empty();
|
||||||
$("#appDomainAssessmentResultTable").addClass("alert alert-danger");
|
$("#appDomainAssessmentResultTable").addClass("alert alert-danger");
|
||||||
$("#appDomainAssessmentResultTable").append("Error while processing request :/");
|
$("#appDomainAssessmentResultTable").append("Error while processing response :/");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function (jqXHR, textStatus, errorThrown) {
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
$("#appDomainLoading").empty();
|
$("#appDomainLoading").empty();
|
||||||
$("#appDomainAssessmentResultTable").addClass("alert alert-danger");
|
$("#appDomainAssessmentResultTable").addClass("alert alert-danger");
|
||||||
$("#appDomainAssessmentResultTable").append("Error while processing request :/");
|
$("#appDomainAssessmentResultTable").append(jqXHR.responseJSON.error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
113
tests/views/test_model_views.py
Normal file
113
tests/views/test_model_views.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
from django.test import TestCase, override_settings
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.conf import settings as s
|
||||||
|
|
||||||
|
from epdb.logic import UserManager, PackageManager
|
||||||
|
from epdb.models import Pathway, Edge, Package, User
|
||||||
|
|
||||||
|
|
||||||
|
@override_settings(MODEL_DIR=s.FIXTURE_DIRS[0] / "models")
|
||||||
|
class PathwayViewTest(TestCase):
|
||||||
|
fixtures = ["test_fixtures_incl_model.jsonl.gz"]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super(PathwayViewTest, cls).setUpClass()
|
||||||
|
cls.user1 = UserManager.create_user("user1", "user1@envipath.com", "SuperSafe",
|
||||||
|
set_setting=True, add_to_group=True, is_active=True)
|
||||||
|
cls.user1_default_package = cls.user1.default_package
|
||||||
|
cls.model_package = Package.objects.get(name='Fixtures')
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.client.force_login(self.user1)
|
||||||
|
|
||||||
|
def test_predict(self):
|
||||||
|
self.client.force_login(User.objects.get(username="admin"))
|
||||||
|
response = self.client.get(
|
||||||
|
reverse("package model detail", kwargs={
|
||||||
|
'package_uuid': str(self.model_package.uuid),
|
||||||
|
'model_uuid': str(self.model_package.models.first().uuid)
|
||||||
|
}), {
|
||||||
|
'classify': 'ILikeCats!',
|
||||||
|
'smiles': 'CCN(CC)C(=O)C1=CC(=CC=C1)CO',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
{
|
||||||
|
'products': [
|
||||||
|
[
|
||||||
|
'O=C(O)C1=CC(CO)=CC=C1',
|
||||||
|
'CCNCC'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'probability': 0.25,
|
||||||
|
'btrule': {
|
||||||
|
'url': 'http://localhost:8000/package/1869d3f0-60bb-41fd-b6f8-afa75ffb09d3/simple-ambit-rule/0e6e9290-b658-4450-b291-3ec19fa19206',
|
||||||
|
'name': 'bt0430-4011'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'products': [
|
||||||
|
[
|
||||||
|
'CCNC(=O)C1=CC(CO)=CC=C1',
|
||||||
|
'CC=O'
|
||||||
|
]
|
||||||
|
], 'probability': 0.0,
|
||||||
|
'btrule': {
|
||||||
|
'url': 'http://localhost:8000/package/1869d3f0-60bb-41fd-b6f8-afa75ffb09d3/simple-ambit-rule/27a3a353-0b66-4228-bd16-e407949e90df',
|
||||||
|
'name': 'bt0243-4301'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'products': [
|
||||||
|
[
|
||||||
|
'CCN(CC)C(=O)C1=CC(C=O)=CC=C1'
|
||||||
|
]
|
||||||
|
], 'probability': 0.75,
|
||||||
|
'btrule': {
|
||||||
|
'url': 'http://localhost:8000/package/1869d3f0-60bb-41fd-b6f8-afa75ffb09d3/simple-ambit-rule/2f2e0c39-e109-4836-959f-2bda2524f022',
|
||||||
|
'name': 'bt0001-3568'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
actual = response.json()
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
reverse("package model detail", kwargs={
|
||||||
|
'package_uuid': str(self.model_package.uuid),
|
||||||
|
'model_uuid': str(self.model_package.models.first().uuid)
|
||||||
|
}), {
|
||||||
|
'classify': 'ILikeCats!',
|
||||||
|
'smiles': '',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
self.assertEqual(response.json()['error'], 'Received empty SMILES')
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
reverse("package model detail", kwargs={
|
||||||
|
'package_uuid': str(self.model_package.uuid),
|
||||||
|
'model_uuid': str(self.model_package.models.first().uuid)
|
||||||
|
}), {
|
||||||
|
'classify': 'ILikeCats!',
|
||||||
|
'smiles': ' ', # Input should be stripped
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
self.assertEqual(response.json()['error'], 'Received empty SMILES')
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
reverse("package model detail", kwargs={
|
||||||
|
'package_uuid': str(self.model_package.uuid),
|
||||||
|
'model_uuid': str(self.model_package.models.first().uuid)
|
||||||
|
}), {
|
||||||
|
'classify': 'ILikeCats!',
|
||||||
|
'smiles': 'RandomInput',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
self.assertEqual(response.json()['error'], '"RandomInput" is not a valid SMILES')
|
||||||
@ -178,3 +178,15 @@ class PackageViewTest(TestCase):
|
|||||||
|
|
||||||
response = self.client.get(package_url)
|
response = self.client.get(package_url)
|
||||||
self.assertEqual(response.status_code, 404)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
def test_delete_default_package(self):
|
||||||
|
self.client.force_login(self.user1)
|
||||||
|
# Try to delete the default package
|
||||||
|
response = self.client.post(self.user1.default_package.url, {
|
||||||
|
"hidden": "delete"
|
||||||
|
})
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
self.assertTrue(f'You cannot delete the default package. '
|
||||||
|
f'If you want to delete this package you have to '
|
||||||
|
f'set another default package first' in response.content.decode())
|
||||||
|
|||||||
@ -161,7 +161,8 @@ class RuleViewTest(TestCase):
|
|||||||
'package_uuid': str(r.package.uuid),
|
'package_uuid': str(r.package.uuid),
|
||||||
'rule_uuid': str(r.uuid)
|
'rule_uuid': str(r.uuid)
|
||||||
}), {
|
}), {
|
||||||
"selected-scenarios": []
|
# We have to set an empty string to avoid that the parameter is removed
|
||||||
|
"selected-scenarios": ""
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user