applications: shortcut to update an app (#71398)
This commit is contained in:
parent
e4fa439f49
commit
8ea3ded995
|
@ -17,7 +17,11 @@
|
|||
</h2>
|
||||
<span class="actions">
|
||||
<a class="extra-actions-menu-opener"></a>
|
||||
{% if app.editable %}<a rel="popup" href="{% url 'application-metadata' app_slug=app.slug %}">{% trans 'Metadata' %}</a>{% endif %}
|
||||
{% if app.editable %}
|
||||
<a rel="popup" href="{% url 'application-metadata' app_slug=app.slug %}">{% trans 'Metadata' %}</a>
|
||||
{% else %}
|
||||
<a rel="popup" href="{% url 'application-update' app_slug=app.slug %}">{% trans 'Update' %}</a>
|
||||
{% endif %}
|
||||
<ul class="extra-actions-menu">
|
||||
<li><a href="{% url 'application-versions' app_slug=app.slug %}">{% trans 'See all versions' %}</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
{% extends "hobo/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block appbar %}
|
||||
<h2>{% trans "Update" %}</h2>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<div class="buttons">
|
||||
<button class="submit-button">{% trans 'Update' %}</button>
|
||||
<a class="cancel" href="{% url 'application-manifest' app.slug %}">{% trans 'Cancel' %}</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -24,6 +24,7 @@ urlpatterns = [
|
|||
path('install/', views.install, name='application-install'),
|
||||
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-]+)/update/$', views.update, name='application-update'),
|
||||
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-]+)/scandeps/$', views.scandeps, name='application-scandeps'),
|
||||
|
|
|
@ -289,11 +289,17 @@ class Install(FormView):
|
|||
form_class = InstallForm
|
||||
template_name = 'hobo/applications/install.html'
|
||||
success_url = reverse_lazy('applications-home')
|
||||
application = None
|
||||
|
||||
def form_valid(self, form):
|
||||
tar_io = io.BytesIO(self.request.FILES['bundle'].read())
|
||||
tar = tarfile.open(fileobj=tar_io)
|
||||
manifest = json.loads(tar.extractfile('manifest.json').read().decode())
|
||||
if self.application and self.application.slug != manifest.get('slug'):
|
||||
form.add_error(
|
||||
'bundle', _('Can not update this application, wrong slug (%s).') % manifest.get('slug')
|
||||
)
|
||||
return self.form_invalid(form)
|
||||
app, created = Application.objects.get_or_create(
|
||||
slug=manifest.get('slug'), defaults={'name': manifest.get('application')}
|
||||
)
|
||||
|
@ -358,6 +364,21 @@ class Install(FormView):
|
|||
install = Install.as_view()
|
||||
|
||||
|
||||
class Update(Install):
|
||||
template_name = 'hobo/applications/update.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs['app'] = self.application
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.application = get_object_or_404(Application, slug=kwargs['app_slug'], editable=False)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
update = Update.as_view()
|
||||
|
||||
|
||||
class AppDeleteView(DeleteView):
|
||||
model = Application
|
||||
template_name = 'hobo/applications/app_confirm_delete.html'
|
||||
|
|
|
@ -783,7 +783,8 @@ def get_bundle(with_icon=False):
|
|||
return tar_io.getvalue()
|
||||
|
||||
|
||||
def test_deploy_application(app, admin_user, settings, app_bundle, app_bundle_with_icon):
|
||||
@pytest.mark.parametrize('action', ['Install', 'Update'])
|
||||
def test_deploy_application(app, admin_user, settings, app_bundle, app_bundle_with_icon, action):
|
||||
Application.objects.all().delete()
|
||||
Wcs.objects.create(base_url='https://wcs.example.invalid', slug='foobar', title='Foobar')
|
||||
|
||||
|
@ -800,8 +801,11 @@ def test_deploy_application(app, admin_user, settings, app_bundle, app_bundle_wi
|
|||
|
||||
login(app)
|
||||
|
||||
if action == 'Update':
|
||||
Application.objects.create(name='Test', slug='test', editable=False)
|
||||
|
||||
def install(resp, bundle):
|
||||
resp = resp.click('Install')
|
||||
resp = resp.click(action)
|
||||
resp.form['bundle'] = Upload('app.tar', bundle, 'application/x-tar')
|
||||
with HTTMock(mocked_http):
|
||||
resp = resp.form.submit().follow()
|
||||
|
@ -827,6 +831,9 @@ def test_deploy_application(app, admin_user, settings, app_bundle, app_bundle_wi
|
|||
return version
|
||||
|
||||
resp = app.get('/applications/')
|
||||
if action == 'Update':
|
||||
with HTTMock(mocked_http):
|
||||
resp = resp.click(href='/manifest/test/')
|
||||
version1 = install(resp, app_bundle)
|
||||
assert version1.application.version_set.count() == 1
|
||||
version2 = install(resp, app_bundle)
|
||||
|
@ -854,7 +861,11 @@ def test_deploy_application(app, admin_user, settings, app_bundle, app_bundle_wi
|
|||
return {'status_code': 500}
|
||||
return mocked_http(url, request)
|
||||
|
||||
resp = app.get('/applications/install/')
|
||||
resp = app.get('/applications/')
|
||||
if action == 'Update':
|
||||
with HTTMock(mocked_http):
|
||||
resp = resp.click(href='manifest/test/')
|
||||
resp = resp.click(action)
|
||||
resp.form['bundle'] = Upload('app.tar', app_bundle, 'application/x-tar')
|
||||
with HTTMock(response_content):
|
||||
with pytest.raises(DeploymentError) as e:
|
||||
|
@ -865,6 +876,36 @@ def test_deploy_application(app, admin_user, settings, app_bundle, app_bundle_wi
|
|||
assert job.exception == 'Failed to deploy module wcs (500)'
|
||||
|
||||
|
||||
def test_update_application(app, admin_user, settings, app_bundle):
|
||||
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', editable=True)
|
||||
|
||||
app.get('/applications/manifest/test/update/', status=404)
|
||||
|
||||
application.editable = False
|
||||
application.slug = 'wrong'
|
||||
application.save()
|
||||
|
||||
resp = app.get('/applications/manifest/wrong/update/')
|
||||
resp.form['bundle'] = Upload('app.tar', app_bundle, 'application/x-tar')
|
||||
resp = resp.form.submit()
|
||||
assert resp.context['form'].errors == {'bundle': ['Can not update this application, wrong slug (test).']}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_bundle_roles():
|
||||
tar_io = io.BytesIO()
|
||||
|
|
Loading…
Reference in New Issue