environment: delete service page (#64924) #107

Open
yweber wants to merge 4 commits from wip/64924-delete-services-page into main
12 changed files with 335 additions and 216 deletions

View File

@ -13,7 +13,7 @@
</p>
<div class="buttons">
<button>{% trans 'Delete' %}</button>
<a class="cancel" href="{% url 'environment-home' %}">{% trans 'Cancel' %}</a>
<a class="cancel" href="{% url 'home' %}">{% trans 'Cancel' %}</a>
</div>
</form>
{% endblock %}

View File

@ -1,135 +0,0 @@
{% extends "hobo/base.html" %}
{% load i18n service %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'environment-home' %}">{% trans 'Sites' %}</a>
{% endblock %}
{% block appbar %}
<h2>{% trans 'Sites' %}</h2>
{% endblock %}
{% block content %}
<p>
<span>{% trans 'Add new service:' %}</span>
<span id="new-service">
{% for service in available_services %}
<a rel="popup" data-service="{{ service.id }}" href="{% url 'create-service' service=service.id %}">{{ service.label }}</a>
{% endfor %}
</span>
</p>
{% for service in installed_services %}
<div data-service-id="{{ service.Extra.service_id }}"
data-slug="{{ service.slug }}"
class="bo-block service-block {{ service.Extra.service_id }}-block"
{% if service.wants_frequent_checks %}data-wants-check="true"{% endif %}>
<h3>{{ service.title }} <span class="slug">[{{service.slug}},
<a href="{{service.base_url}}">{{service.base_url}}</a>]</span></h3>
{% if not service.is_operational %}
{% if service.wants_frequent_checks %}
<p class="info being-deployed">
{% trans 'This service is still being deployed.' %}
</p>
{% else %}
<p class="warning">
{% trans 'This service is not operational.' %}
<a rel="popup" class="icon-remove-sign" href="{% url 'delete-service' service=service.Extra.service_id slug=service.slug %}" title="{% trans 'Delete service' %}"></a>
</p>
{% endif %}
{% endif %}
<form class="small" method="post" action=" {{ service|save_url }}" >
{% csrf_token %}
{{ service|as_update_form }}
<button class="enable-on-change" disabled="disabled">{% trans 'Save' %}</button>
<h4 class="custom-variables untoggled">{% trans "Custom variables" %}</h4>
<div>
{% for variable in service.variables.all %}
{% if not variable.auto %}
<p class="variable">
<label data-variable-id="{{ variable.id }}">{{ variable.get_field_label }}</label>
<input type="text" size="80" value="{{ variable.value }}" readonly>
<a rel="popup" class="update-variable" href="{% url 'update-variable' pk=variable.id %}" title="{% trans 'Update variable' %}">{% trans 'edit' %}</a>
<a rel="popup" class="icon-remove-sign" href="{% url 'delete-variable' pk=variable.id %}" title="{% trans 'Delete variable' %}"></a>
</p>
{% endif %}
{% endfor %}
<a rel="popup" class="button" href="{% url 'new-variable-service' service=service.Extra.service_id slug=service.slug %}">{% trans 'Add new variable' %}</a>
</div>
</form>
{% if service.legacy_urls %}
<h4>
{% blocktrans trimmed count counter=service.legacy_urls|length %}
Legacy URL
{% plural%}
Legacy URLS
{% endblocktrans %}
</h4>
<ul>
{% for legacy_url in service.legacy_urls %}
<li>{{ legacy_url.base_url }} {% if legacy_url.datetime %}({% trans 'until' %} {{ legacy_url.datetime }}){% endif %}</li>
{% endfor %}
</ul>
{% endif%}
</div>
{% endfor %}
{% endblock %}
{% block page-end %}
<script>
jQuery.fn.extend({
operational_check: function() {
return this.each(function() {
var div = $(this)
var p_info = $(div).find('p.info');
var url = 'check_operational/' + $(div).data('service-id') + '/' + $(div).data('slug');
$.getJSON(url, function(data) {
if (data.operational == true) {
$(p_info).hide('size');
} else {
setTimeout(function() { $(div).operational_check(); }, 10000);
}
});
});
}
});
$(function() {
/* turn the new service links into a select box */
var select_new_service = $('<select><option></option></select>').insertAfter($('#new-service'));
$('#new-service').hide();
$('#new-service a').each(function(index, element) {
var text = $(element).text();
var option = $('<option value="' + $(element).data('service') + '">' + text + "</option>"
).appendTo(select_new_service);
});
$(select_new_service).change(function() {
var service_id = $(this).val();
if (service_id) {
$('#new-service a[data-service=' + service_id + ']').click();
$(this).val('');
}
});
$('a.update-variable').hide();
$('p.variable label, p.variable input').click(function() {
$(this).parent().find('a.update-variable').click();
});
$("div[data-wants-check='true']").each(function(index, element) {
$(element).operational_check();
});
$('button.enable-on-change').each(function(index, element) {
var button = $(element);
$(element).parent('form').find('input').on('change keydown',
function() { $(button).prop('disabled', null); });
});
});
</script>
{% endblock %}

View File

@ -0,0 +1,62 @@
{% extends "hobo/base.html" %}
{% load i18n service %}
{% block appbar %}
<h2>{% trans 'Add a service' %}</h2>
{% endblock %}
{% block content %}
<form method="post">
<div id="form-content">
<span>{% trans 'Add new service:' %}</span>
<span id="new-service">
{% for service in available_services %}
<p>
<a rel="popup" data-service="{{ service.id }}" href="{% url 'create-service' service=service.id %}">{{ service.label }}</a>a
</p>
{% endfor %}
</span>
{% block buttons %}
<div class="buttons">
<a class="cancel" href="{% url 'home' %}">{% trans 'Cancel' %}</a>
</div>
{% endblock %}
</div>
<script>
$(function() {
/* turn the new service links into a select box */
var select_new_service = $('<select><option></option></select>').insertAfter($('#new-service'));
$('#new-service').hide();
$('#new-service a').each(function(index, element) {
var text = $(element).text();
var option = $('<option value="' + $(element).data('service') + '">' + text + "</option>"
).appendTo(select_new_service);
});
$(select_new_service).change(function() {
var service_id = $(this).val();
if (service_id) {
$('#new-service a[data-service=' + service_id + ']').click();
$(this).val('');
}
});
$('a.update-variable').hide();
$('p.variable label, p.variable input').click(function() {
$(this).parent().find('a.update-variable').click();
});
$("div[data-wants-check='true']").each(function(index, element) {
$(element).operational_check();
});
$('button.enable-on-change').each(function(index, element) {
var button = $(element);
$(element).parent('form').find('input').on('change keydown',
function() { $(button).prop('disabled', null); });
});
});
</script>
</form>
{% endblock %}

View File

@ -15,7 +15,7 @@
{% block buttons %}
<div class="buttons">
<button class="submit-button">{% trans 'Save' %}</button>
<a class="cancel" href="{% url 'environment-home' %}">{% trans 'Cancel' %}</a>
<a class="cancel" href="{% url 'home' %}">{% trans 'Cancel' %}</a>
</div>
{% endblock %}
</form>

View File

@ -0,0 +1,24 @@
{% extends "hobo/base.html" %}
{% load i18n service %}
{% block appbar %}
<h2>{{ model_name }}</h2>
{% endblock %}
{% block content %}
<form method="post" enctype="multipart/form-data">
<div id="form-content">
{% csrf_token %}
{{ object|as_update_form }}
</div>
{% block buttons %}
<div class="buttons">
<button class="submit-button">{% trans 'Save' %}</button>
<a class="cancel" href="{% url 'home' %}">{% trans 'Cancel' %}</a>
</div>
{% endblock %}
</form>
{% endblock %}

View File

@ -15,7 +15,7 @@
{% block buttons %}
<div class="buttons">
<button class="submit-button">{% trans 'Save' %}</button>
<a class="cancel" href="{% url 'environment-home' %}">{% trans 'Cancel' %}</a>
<a class="cancel" href="{% url 'home' %}">{% trans 'Cancel' %}</a>
</div>
{% endblock %}
</form>

View File

@ -2,12 +2,20 @@
{% load i18n %}
{% block appbar %}
<h2>{% trans 'Variables' %}</h2>
{% if service %}
<h2>{% trans 'Variables for' %} {{service.name}} <small>[{{service.slug}}, <a href="{{service.base_url}}">{{service.base_url}}</a>]</small></h2<>
{% else %}
<h2>{% trans 'Variables' %}</h2>
{% endif %}
{% endblock %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'environment-variables' %}">{% trans 'Variables' %}</a>
{% if service %}
<a href="{% url 'edit-variable-service' service=service.Extra.service_id slug=service.slug %}">{% trans 'Variables for' %} {{service.name}} ({{service.slug}})</a>
{% else %}
<a href="{% url 'environment-variables' %}">{% trans 'Variables' %}</a>
{% endif %}
{% endblock %}
{% block content %}
@ -20,7 +28,11 @@
<a rel="popup" class="icon-remove-sign" href="{% url 'delete-variable' pk=variable.id %}" title="{% trans 'Delete variable' %}"></a>
</p>
{% endfor %}
<a rel="popup" class="button" href="{% url 'new-variable' %}">{% trans 'Add new variable' %}</a>
{% if service %}
<a rel="popup" class="button" href="{% url 'new-variable-service' service=service.Extra.service_id slug=service.slug %}">{% trans 'Add new variable' %}</a>
{% else %}
<a rel="popup" class="button" href="{% url 'new-variable' %}">{% trans 'Add new variable' %}</a>
{% endif %}
</form>
{% endblock %}

View File

@ -19,8 +19,12 @@ from django.urls import path, re_path
from . import views
urlpatterns = [
path('', views.HomeView.as_view(), name='environment-home'),
path('variables', views.VariablesView.as_view(), name='environment-variables'),
re_path(
r'^variables-(?P<service>\w+)/(?P<slug>[\w-]+)$',
views.VariablesView.as_view(),
name='edit-variable-service',
),
path(
'new-variable',
views.VariableCreateView.as_view(),
@ -33,6 +37,7 @@ urlpatterns = [
views.operational_check_view,
name='operational-check',
),
path('select_create_service', views.ServiceSelectCreateView.as_view(), name='select-create-service'),
re_path(r'^new-(?P<service>\w+)$', views.ServiceCreateView.as_view(), name='create-service'),
re_path(
r'^save-(?P<service>\w+)/(?P<slug>[\w-]+)$', views.ServiceUpdateView.as_view(), name='save-service'

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
import json
from django.contrib.contenttypes.models import ContentType
@ -37,31 +36,27 @@ class AvailableService:
self.label = klass._meta.verbose_name
class HomeView(TemplateView):
template_name = 'environment/home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['available_services'] = [AvailableService(x) for x in AVAILABLE_SERVICES if x.is_enabled()]
installed_services = [x for x in utils.get_installed_services() if not x.secondary]
for service in installed_services:
for legacy_url in service.legacy_urls:
try:
legacy_url['datetime'] = datetime.datetime.strptime(
legacy_url['timestamp'], '%Y-%m-%d %H:%M:%S'
)
except ValueError:
pass
context['installed_services'] = installed_services
return context
class VariablesView(TemplateView):
template_name = 'environment/variables.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['variables'] = Variable.objects.filter(auto=False, service_pk__isnull=True).order_by('label')
if 'service' in self.kwargs:
service_id = self.kwargs.pop('service')
service_slug = self.kwargs.pop('slug')
for service in AVAILABLE_SERVICES:
if service.Extra.service_id == service_id:
context['service'] = service.objects.get(slug=service_slug)
break
context['variables'] = Variable.objects.filter(
auto=False, service_pk=context['service'].pk
).order_by('label')
else:
context['variables'] = Variable.objects.filter(auto=False, service_pk__isnull=True).order_by(
'label'
)
context['service'] = None
context['service_id'] = None
return context
@ -101,7 +96,10 @@ class VariableCreateView(CreateView):
def get_success_url(self):
if self.object.service is None:
return reverse_lazy('environment-variables')
return reverse_lazy('environment-home')
return reverse_lazy(
'edit-variable-service',
kwargs={'service': self.object.service.Extra.service_id, 'slug': self.object.service.slug},
)
class VariableUpdateView(UpdateView):
@ -111,7 +109,10 @@ class VariableUpdateView(UpdateView):
def get_success_url(self):
if self.object.service is None:
return reverse_lazy('environment-variables')
return reverse_lazy('environment-home')
return reverse_lazy(
'edit-variable-service',
kwargs={'service': self.object.service.Extra.service_id, 'slug': self.object.service.slug},
)
class VariableDeleteView(DeleteView):
@ -121,11 +122,23 @@ class VariableDeleteView(DeleteView):
def get_success_url(self):
if self.object.service is None:
return reverse_lazy('environment-variables')
return reverse_lazy('environment-home')
return reverse_lazy(
'edit-variable-service',
kwargs={'service': self.object.service.Extra.service_id, 'slug': self.object.service.slug},
)
class ServiceSelectCreateView(TemplateView):
template_name = 'environment/select_new_service.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['available_services'] = [AvailableService(x) for x in AVAILABLE_SERVICES if x.is_enabled()]
return context
class ServiceCreateView(CreateView):
success_url = reverse_lazy('environment-home')
success_url = reverse_lazy('home')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -141,7 +154,7 @@ class ServiceCreateView(CreateView):
return initial
def get_template_names(self):
return 'environment/service_form.html'
return 'environment/service_create_form.html'
def get(self, request, *args, **kwargs):
self.service_id = kwargs.pop('service')
@ -161,7 +174,7 @@ class ServiceCreateView(CreateView):
class ServiceUpdateView(UpdateView):
success_url = reverse_lazy('environment-home')
success_url = reverse_lazy('home')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -169,7 +182,7 @@ class ServiceUpdateView(UpdateView):
return context
def get_template_names(self):
return 'environment/service_form.html'
return 'environment/service_edit_form.html'
def get(self, request, *args, **kwargs):
self.service_id = kwargs.pop('service')
@ -191,7 +204,7 @@ class ServiceUpdateView(UpdateView):
class ServiceDeleteView(DeleteView):
success_url = reverse_lazy('environment-home')
success_url = reverse_lazy('home')
template_name = 'environment/generic_confirm_delete.html'
context_object_name = 'object'

View File

@ -6,6 +6,7 @@
<span class="actions">
<a class="extra-actions-menu-opener"></a>
<ul class="extra-actions-menu">
<li><a rel="popup" href="{% url 'select-create-service' %}">{% trans 'Add new service' %}</a></li>
<li><a rel="popup" href="{% url 'environment-import' %}">{% trans 'Import' %}</a></li>
<li><a href="{% url 'environment-export' %}">{% trans 'Export' %}</a></li>
</ul>
@ -17,18 +18,50 @@
{% if services %}
<div class="services">
{% for service in services %}
<a href="{{ service.base_url }}" class="service-link" data-service-slug="{{ service.slug }}">
<div class="service" data-service-slug="{{ service.slug }}">
<h3 class="service-title">{{ service.title }} <span class="service-url">{{ service.base_url }}</span></h3>
<p class="service-status-items">
<span class="checking">{% trans "checking..." %}</span>
<span style="display: none" class="dns">{% trans "DNS" %}</span>
<span style="display: none" class="certificate">{% trans "Certificate" %}</span>
<span style="display: none" class="web">{% trans "Web" %}</span>
<span style="display: none" class="security">{% trans "Security" %}</span>
</p>
<div class="service-link" data-service-slug="{{ service.slug }}">
<a href="{{ service.base_url }}" data-service-slug="{{ service.slug }}">
<div class="service" data-service-slug="{{ service.slug }}">
<h3 class="service-title">{{ service.title }} <span class="slug">[{{service.slug}}, <span class="service-url">{{ service.base_url }}</span>]</span></h3>
<p class="service-status-items">
<span class="checking">{% trans "checking..." %}</span>
{% if not service.is_operational and service.wants_frequent_checks %}
<span style="display: none" class="info being-deployed">{% trans 'This service is still being deployed.' %}</span>
{% endif %}
<span style="display: none" class="dns">{% trans "DNS" %}</span>
<span style="display: none" class="certificate">{% trans "Certificate" %}</span>
<span style="display: none" class="web">{% trans "Web" %}</span>
<span style="display: none" class="security">{% trans "Security" %}</span>
</p>
</div>
</a>
{% if service.legacy_urls %}
<h4>
{% blocktrans trimmed count counter=service.legacy_urls|length %}
Legacy URL
{% plural %}
Legacy URLS
{% endblocktrans %}
</h4>
<ul>
{% for legacy_url in service.legacy_urls %}
<li>{{ legacy_url.base_url }} {% if legacy_url.datetime %}({% trans 'until' %} {{ legacy_url.datetime }}){% endif %}</li>
{% endfor %}
</ul>
{% endif %}
<div class="menu-opener">
<span class="actions">
<a class="extra-actions-menu-opener"></a>
<ul class="extra-actions-menu">
<li><a rel="popup" href="{% url 'save-service' service=service.Extra.service_id slug=service.slug %}">{% trans 'Edit' %}</a></li>
<li><a href="{% url 'edit-variable-service' service=service.Extra.service_id slug=service.slug %}">{% trans 'Variables' %}</a></li>
{% if not service.is_operational and not service.wants_frequent_checks %}
<li><a rel="popup" href="{% url 'delete-service' service=service.Extra.service_id slug=service.slug %}">{% trans 'Delete service' %}</a></li>
{% endif %}
</ul>
</span>
</div>
</a>
</div>
{% endfor %}
</div>
{% else %}
@ -113,7 +146,6 @@
<a class="button button-paragraph" href="{% url 'sms-home' %}">{% trans 'SMS' %}</a>
<a class="button button-paragraph" href="{% url 'matomo-home' %}">{% trans 'User tracking' %}</a>
<a class="button button-paragraph" href="{% url 'seo-home' %}">{% trans 'Indexing' %}</a>
<a class="button button-paragraph" href="{% url 'environment-home' %}">{% trans 'Services' %}</a>
<a class="button button-paragraph" href="{% url 'environment-variables' %}">{% trans 'Variables' %}</a>
<a class="button button-paragraph" href="{% url 'debug-home' %}">{% trans 'Debugging' %}</a>
{% if show_maintenance_menu %}<a class="button button-paragraph" href="{% url 'maintenance-home' %}">{% trans 'Maintenance' %}</a>{% endif %}

View File

@ -1,3 +1,4 @@
import datetime
import json
from django.conf import settings
@ -33,6 +34,14 @@ class Home(TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['services'] = [x for x in get_installed_services() if not x.secondary]
for service in context['services']:
for legacy_url in service.legacy_urls:
try:
legacy_url['datetime'] = datetime.datetime.strptime(
legacy_url['timestamp'], '%Y-%m-%d %H:%M:%S'
)
except ValueError:
pass
context['has_authentic'] = bool(Authentic.objects.filter(secondary=False))
context['has_global_title'] = Variable.objects.filter(name='global_title').exists()
context['has_default_from_email'] = Variable.objects.filter(name='default_from_email').exists()

View File

@ -4,11 +4,22 @@ import pytest
from django.core.exceptions import ValidationError
from django.core.management import call_command
from django.db.utils import IntegrityError
from django.urls import reverse
from django.utils import timezone
from webtest import Upload
from hobo.environment import models as environment_models
from hobo.environment.models import AVAILABLE_SERVICES, Combo, Passerelle, ServiceBase, Variable
from hobo.environment.models import (
AVAILABLE_SERVICES,
Authentic,
Chrono,
Combo,
Hobo,
Passerelle,
ServiceBase,
Variable,
Wcs,
)
from hobo.environment.utils import get_installed_services_dict
from hobo.profile.models import AttributeDefinition
@ -122,47 +133,72 @@ def test_base_url_field_validator():
combo.save()
def test_service_creation_filling(app, admin_user, monkeypatch):
@pytest.mark.parametrize(
'service_name,',
['authentic', 'chrono', 'combo', 'hobo', 'passerelle', 'wcs'],
)
def test_service_creation_filling(app, admin_user, monkeypatch, service_name):
from django.http.request import HttpRequest
monkeypatch.setattr(HttpRequest, 'get_host', lambda x: 'test.example.net')
app = login(app)
response = app.get('/sites/new-combo')
assert 'value="http://portal.example.net"' in response.text
response = app.get('/sites/new-%s' % service_name)
slug = response.pyquery('#id_slug').val()
url = response.pyquery('#id_base_url').val()
assert url == 'http://%s.example.net' % slug
monkeypatch.setattr(HttpRequest, 'get_host', lambda x: 'hobo-test.example.net')
monkeypatch.setattr(HttpRequest, 'get_host', lambda x: 'some-test.example.net')
app = login(app)
response = app.get('/sites/new-combo')
assert 'value="http://portal-test.example.net"' in response.text
response = app.get('/sites/new-%s' % service_name)
slug = response.pyquery('#id_slug').val()
url = response.pyquery('#id_base_url').val()
assert url == 'http://%s-test.example.net' % slug
def test_service_creation_url_validation(app, admin_user, monkeypatch):
@pytest.mark.parametrize(
'service_name,service_cls',
[
('authentic', Authentic),
('chrono', Chrono),
('combo', Combo),
('hobo', Hobo),
('passerelle', Passerelle),
('wcs', Wcs),
],
)
def test_service_creation_url_validation(app, admin_user, monkeypatch, service_name, service_cls):
app = login(app)
response = app.get('/sites/new-combo')
response = app.get('/sites/new-%s' % service_name)
form = response.form
form['title'] = 'test'
form['base_url'] = 'http://portal-test.example.net'
form['base_url'] = 'http://some-test.example.net'
response = form.submit()
assert 'not resolvable' in response
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
form = response.form
form.fields['slug'][0].value += '-uniq'
response = form.submit()
assert 'no valid certificate' in response
assert not Combo.objects.exists()
if service_name == 'hobo':
assert service_cls.objects.count() == 1
else:
assert not service_cls.objects.exists()
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
form = response.form
form.fields['slug'][0].value += '-uniq'
response = form.submit()
assert Combo.objects.exists()
if service_name == 'hobo':
assert service_cls.objects.count() == 2
else:
assert service_cls.objects.exists()
def test_home_view(app, admin_user, settings):
def test_service_creation_selection(app, admin_user, settings):
app = login(app)
combo = Combo.objects.create(
base_url='https://combo.agglo.love', template_name='...portal-user...', slug='portal'
)
response = app.get('/sites').follow()
response = app.get(reverse('select-create-service'))
assert 'Add new service:' in response.text
for service in AVAILABLE_SERVICES:
if service.is_enabled():
@ -176,7 +212,6 @@ def test_home_view(app, admin_user, settings):
'passerelle',
'wcs',
}
assert response.html.find('span', {'class': 'slug'}).a.text == 'https://combo.agglo.love/'
# check HOBO_SERVICES_ENABLED works
settings.HOBO_SERVICES_ENABLED = ['lingo']
@ -192,18 +227,33 @@ def test_home_view(app, admin_user, settings):
'lingo',
}
def test_home_view(app, admin_user):
app = login(app)
combo = Combo.objects.create(
base_url='https://combo.agglo.love', template_name='...portal-user...', slug='portal'
)
response = app.get(reverse('home'))
assert response.html.find('div', {'class': 'service-link'}).a.attrs['href'] == 'https://combo.agglo.love/'
assert response.html.find('span', {'class': 'service-url'}).text == 'https://combo.agglo.love/'
# add legacy urls
combo.change_base_url('https://combo1.agglo.love')
combo.save()
response = app.get('/sites').follow()
assert response.html.find('span', {'class': 'slug'}).a.text == 'https://combo1.agglo.love/'
response = app.get(reverse('home'))
assert (
response.html.find('div', {'class': 'service-link'}).a.attrs['href'] == 'https://combo1.agglo.love/'
)
assert response.html.find('span', {'class': 'service-url'}).text == 'https://combo1.agglo.love/'
h4 = response.html.find_all('h4')[-1]
assert h4.text.strip() == 'Legacy URL'
combo.change_base_url('https://combo2.agglo.love')
combo.save()
response = app.get('/sites').follow()
assert response.html.find('span', {'class': 'slug'}).a.text == 'https://combo2.agglo.love/'
response = app.get(reverse('home'))
assert (
response.html.find('div', {'class': 'service-link'}).a.attrs['href'] == 'https://combo2.agglo.love/'
)
assert response.html.find('span', {'class': 'service-url'}).text == 'https://combo2.agglo.love/'
h4 = response.html.find_all('h4')[-1]
assert h4.text.strip() == 'Legacy URLS'
@ -259,7 +309,7 @@ def test_new_variable_templated_value(app, admin_user):
def test_new_variable_service_view(app, admin_user):
app = login(app)
Combo.objects.create(
service = Combo.objects.create(
base_url='https://combo.agglo.love', template_name='...portal-user...', slug='portal'
)
response = app.get('/sites/new-variable-combo/portal')
@ -267,7 +317,9 @@ def test_new_variable_service_view(app, admin_user):
response.form['label'] = 'bar'
response.form['value'] = 'barbar'
response = response.form.submit()
assert response.location == '/sites/'
assert response.location == reverse(
'edit-variable-service', kwargs={'service': service.Extra.service_id, 'slug': service.slug}
)
assert Variable.objects.all()[0].name == 'foo'
assert Variable.objects.all()[0].label == 'bar'
assert Variable.objects.all()[0].value == 'barbar'
@ -284,6 +336,20 @@ def test_variable_update_view(app, admin_user):
assert response.location == '/sites/variables'
assert Variable.objects.all()[0].value == 'barbar'
service = Combo.objects.create(
base_url='https://combo.agglo.love', template_name='...portal-user...', slug='portal'
)
var = Variable.objects.create(name='foo', value='bar', label='foobar', service=service)
response = app.get('/sites/update-variable/%s' % var.pk)
assert response.html.find('input', {'name': 'name'})['value'] == 'foo'
assert response.html.find('textarea').text == '\nbar'
response.form['value'] = 'foofoobarbar'
response = response.form.submit()
assert response.location == reverse(
'edit-variable-service', kwargs={'service': service.Extra.service_id, 'slug': service.slug}
)
assert Variable.objects.get(pk=var.pk).value == 'foofoobarbar'
def test_variable_delete_view(app, admin_user):
app = login(app)
@ -295,16 +361,47 @@ def test_variable_delete_view(app, admin_user):
assert Variable.objects.count() == 0
def test_service_update_view(app, admin_user):
@pytest.mark.parametrize(
'service_name,service_cls',
[
('authentic', Authentic),
('chrono', Chrono),
('combo', Combo),
('hobo', Hobo),
('passerelle', Passerelle),
('wcs', Wcs),
],
)
def test_service_update_view(app, admin_user, monkeypatch, service_name, service_cls):
import socket
monkeypatch.setattr(socket, 'gethostbyname', lambda _: '127.1.2.3')
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
app = login(app)
Combo.objects.create(
base_url='https://combo.agglo.love', template_name='...portal-user...', slug='portal'
)
response = app.get('/sites/save-combo/portal')
response.form['title'] = 'foobar'
response = app.get('/sites/new-%s' % service_name)
form = response.form
form['title'] = 'test-%s' % service_name
hostname = '%s-test.agglo.love' % service_name
form['base_url'] = 'https://%s/foobar' % hostname
slug = 'slug-%s' % service_name
form['slug'] = slug
form.submit()
if service_name == 'authentic':
# Fake operationnal authentic with IDP set
authentic_service = service_cls.objects.filter(slug=slug)[0]
authentic_service.use_as_idp_for_self = True
authentic_service.save()
monkeypatch.setattr(authentic_service, 'is_operational', lambda _: True)
response = app.get(reverse('save-service', kwargs={'service': service_name, 'slug': slug}))
response.form['title'] = 'foobar-%s' % service_name
if service_name == 'authentic':
response.form['use_as_idp_for_self'] = False
response = response.form.submit()
assert response.location == '/sites/'
assert Combo.objects.all()[0].title == 'foobar'
assert response.location == '/'
assert service_cls.objects.filter(slug=slug)[0].title == ('foobar-%s' % service_name)
if service_name == 'authentic':
assert not service_cls.objects.filter(slug=slug)[0].use_as_idp_for_self
def test_service_save_extra_variables(app, admin_user, settings):
@ -334,7 +431,7 @@ def test_service_delete_view(app, admin_user):
response = app.get('/sites/delete-combo/portal')
assert response.html.find('h2').text == 'Removal of "foo"'
response = response.form.submit()
assert response.location == '/sites/'
assert response.location == '/'
assert Combo.objects.count() == 0