applications: refresh elements when install is done (#78095)
gitea/hobo/pipeline/head This commit looks good Details

This commit is contained in:
Lauréline Guérin 2023-06-02 17:35:20 +02:00
parent 1ebd61d47a
commit db91bd9730
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 80 additions and 2 deletions

View File

@ -25,6 +25,7 @@ urlpatterns = [
re_path(r'^manifest/(?P<slug>[\w-]+)/delete/$', views.delete, name='application-delete'), re_path(r'^manifest/(?P<slug>[\w-]+)/delete/$', views.delete, name='application-delete'),
re_path(r'^manifest/(?P<app_slug>[\w-]+)/$', views.manifest, name='application-manifest'), re_path(r'^manifest/(?P<app_slug>[\w-]+)/$', views.manifest, name='application-manifest'),
re_path(r'^manifest/(?P<app_slug>[\w-]+)/update/$', views.update, name='application-update'), re_path(r'^manifest/(?P<app_slug>[\w-]+)/update/$', views.update, name='application-update'),
re_path(r'^manifest/(?P<app_slug>[\w-]+)/refresh/$', views.refresh, name='application-refresh'),
re_path(r'^manifest/(?P<app_slug>[\w-]+)/versions/$', views.versions, name='application-versions'), re_path(r'^manifest/(?P<app_slug>[\w-]+)/versions/$', views.versions, name='application-versions'),
re_path(r'^manifest/(?P<app_slug>[\w-]+)/metadata/$', views.metadata, name='application-metadata'), re_path(r'^manifest/(?P<app_slug>[\w-]+)/metadata/$', views.metadata, name='application-metadata'),
re_path(r'^manifest/(?P<app_slug>[\w-]+)/scandeps/$', views.scandeps, name='application-scandeps'), re_path(r'^manifest/(?P<app_slug>[\w-]+)/scandeps/$', views.scandeps, name='application-scandeps'),

View File

@ -28,7 +28,7 @@ from django.urls import reverse, reverse_lazy
from django.utils.text import slugify from django.utils.text import slugify
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, FormView, ListView, TemplateView from django.views.generic import DetailView, FormView, ListView, RedirectView, TemplateView
from django.views.generic.edit import CreateView, DeleteView, UpdateView from django.views.generic.edit import CreateView, DeleteView, UpdateView
from hobo.environment.models import Variable from hobo.environment.models import Variable
@ -37,6 +37,7 @@ from .forms import GenerateForm, InstallForm, MetadataForm
from .models import ( from .models import (
STATUS_CHOICES, STATUS_CHOICES,
Application, Application,
ApplicationError,
AsyncJob, AsyncJob,
Element, Element,
Parameter, Parameter,
@ -392,6 +393,19 @@ class Update(Install):
update = Update.as_view() update = Update.as_view()
class Refresh(RedirectView):
def get_redirect_url(self, *args, **kwargs):
application = get_object_or_404(Application, slug=kwargs['app_slug'])
try:
application.refresh_elements(cache_only=True)
except ApplicationError:
pass
return reverse('application-manifest', kwargs={'app_slug': self.kwargs['app_slug']})
refresh = Refresh.as_view()
class AppDeleteView(DeleteView): class AppDeleteView(DeleteView):
model = Application model = Application
template_name = 'hobo/applications/app_confirm_delete.html' template_name = 'hobo/applications/app_confirm_delete.html'
@ -450,6 +464,8 @@ class AsyncJobView(DetailView):
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
def get_redirect_url(self): def get_redirect_url(self):
if self.object.action == 'deploy':
return reverse('application-refresh', kwargs={'app_slug': self.kwargs['app_slug']})
return reverse('application-manifest', kwargs={'app_slug': self.kwargs['app_slug']}) return reverse('application-manifest', kwargs={'app_slug': self.kwargs['app_slug']})

View File

@ -1023,6 +1023,67 @@ def test_update_application(app, admin_user, settings, app_bundle):
assert resp.context['form'].errors == {'bundle': ['Can not update this application, wrong slug (test).']} assert resp.context['form'].errors == {'bundle': ['Can not update this application, wrong slug (test).']}
def test_refresh_application(app, admin_user, settings):
Wcs.objects.create(base_url='https://wcs.example.invalid', slug='foobar', title='Foobar')
settings.KNOWN_SERVICES = {
'wcs': {
'foobar': {
'title': 'Foobar',
'url': 'https://wcs.example.invalid/',
'orig': 'example.org',
'secret': 'xxx',
}
}
}
login(app)
application = Application.objects.create(name='Test', slug='test')
element = Element.objects.create(type='forms', slug='test', name='Test', cache={})
Relation.objects.create(application=application, element=element)
form_def = {
"id": "test",
"text": "Test",
"type": "forms",
"urls": {
"export": "https://wcs.example.invalid/api/export-import/forms/test/",
"dependencies": "https://wcs.example.invalid/api/export-import/forms/test/dependencies/",
"redirect": "https://wcs.example.invalid/api/export-import/forms/test/redirect/",
},
}
def response_content(url, request):
if url.path == '/api/export-import/forms/':
return {
'content': {"data": [form_def]},
'status_code': 200,
}
return mocked_http(url, request)
with HTTMock(response_content):
resp = app.get('/applications/manifest/test/refresh/')
application = Application.objects.get(slug='test')
element.refresh_from_db()
assert element.cache == form_def
assert resp.location.endswith('/applications/manifest/test/')
def response_content(url, request):
if url.path == '/api/export-import/forms/':
return {'status_code': 500}
return mocked_http(url, request)
element.cache = {'foo': 'bar'}
element.save()
with HTTMock(response_content):
resp = app.get('/applications/manifest/test/refresh/')
application = Application.objects.get(slug='test')
element.refresh_from_db()
assert element.cache == {'foo': 'bar'}
assert resp.location.endswith('/applications/manifest/test/')
@pytest.fixture @pytest.fixture
def app_bundle_roles(): def app_bundle_roles():
tar_io = io.BytesIO() tar_io = io.BytesIO()
@ -1222,7 +1283,7 @@ def test_job_status_page(app, admin_user, settings):
assert 'Please wait…' in resp assert 'Please wait…' in resp
assert 'Completed: 100%' in resp assert 'Completed: 100%' in resp
assert 'window.location.reload' not in resp assert 'window.location.reload' not in resp
assert 'window.location = "/applications/manifest/test/"' in resp assert 'window.location = "/applications/manifest/test/refresh/"' in resp
job.status = 'failed' job.status = 'failed'
job.exception = 'foo bar exception' job.exception = 'foo bar exception'