Sunil Mohan Adapa d7a60b1aca
calibre: Use privileged decorator for actions
Tests:

- Unit and functional tests work.
- Creating a library works.
  - An error while creating library shows as proper message.
- Deleting a library works.
  - An error while deleting library shows as proper messages.
- Creating/deleting library reflects properly in the list of libraries.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2022-10-08 18:51:24 -04:00

145 lines
5.4 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Tests for calibre views.
"""
from unittest.mock import call, patch
import pytest
from django import urls
from django.contrib.messages.storage.fallback import FallbackStorage
from django.http.response import Http404
from plinth import module_loader
from plinth.modules.calibre import views
# For all tests, use plinth.urls instead of urls configured for testing
pytestmark = pytest.mark.urls('plinth.urls')
@pytest.fixture(autouse=True, scope='module')
def fixture_calibre_urls():
"""Make sure calibre app's URLs are part of plinth.urls."""
with patch('plinth.module_loader._modules_to_load', new=[]) as modules, \
patch('plinth.urls.urlpatterns', new=[]):
modules.append('plinth.modules.calibre')
module_loader.include_urls()
yield
@pytest.fixture(autouse=True)
def calibre_patch():
"""Patch calibre methods."""
with patch('plinth.modules.calibre.privileged.list_libraries'
) as list_libraries:
list_libraries.return_value = ['TestExistingLibrary']
yield
def make_request(request, view, **kwargs):
"""Make request with a message storage."""
setattr(request, 'session', 'session')
messages = FallbackStorage(request)
setattr(request, '_messages', messages)
response = view(request, **kwargs)
return response, messages
@patch('plinth.modules.calibre.privileged.create_library')
def test_create_library(create_library, rf):
"""Test that create library view works."""
form_data = {'calibre-name': 'TestLibrary'}
request = rf.post(urls.reverse('calibre:create-library'), data=form_data)
view = views.CreateLibraryView.as_view()
response, messages = make_request(request, view)
assert response.status_code == 302
assert response.url == urls.reverse('calibre:index')
assert list(messages)[0].message == 'Library created.'
create_library.assert_has_calls([call('TestLibrary')])
@patch('plinth.modules.calibre.privileged.create_library')
def test_create_library_failed(create_library, rf):
"""Test that create library fails as expected."""
create_library.side_effect = RuntimeError('TestError')
form_data = {'calibre-name': 'TestLibrary'}
request = rf.post(urls.reverse('calibre:create-library'), data=form_data)
view = views.CreateLibraryView.as_view()
response, messages = make_request(request, view)
assert response.status_code == 302
assert response.url == urls.reverse('calibre:index')
assert list(messages)[0].message == \
'An error occurred while creating the library. TestError'
def test_create_library_existing_library(rf):
"""Test that create library errors out for an existing library name."""
form_data = {'calibre-name': 'TestExistingLibrary'}
request = rf.post(urls.reverse('calibre:create-library'), data=form_data)
view = views.CreateLibraryView.as_view()
response, _ = make_request(request, view)
assert response.context_data['form'].errors['name'][
0] == 'A library with this name already exists.'
assert response.status_code == 200
def test_create_library_invalid_name(rf):
"""Test that create library errors out for invalid name."""
form_data = {'calibre-name': 'Invalid Library'}
request = rf.post(urls.reverse('calibre:create-library'), data=form_data)
view = views.CreateLibraryView.as_view()
response, _ = make_request(request, view)
assert response.context_data['form'].errors['name'][
0] == 'Enter a valid value.'
assert response.status_code == 200
@patch('plinth.app.App.get')
def test_delete_library_confirmation_view(_app, rf):
"""Test that deleting library confirmation shows correct name."""
response, _ = make_request(rf.get(''), views.delete_library,
name='TestExistingLibrary')
assert response.status_code == 200
assert response.context_data['name'] == 'TestExistingLibrary'
@patch('plinth.modules.calibre.privileged.delete_library')
@patch('plinth.app.App.get')
def test_delete_library(_app, delete_library, rf):
"""Test that deleting a library works."""
response, messages = make_request(rf.post(''), views.delete_library,
name='TestExistingLibrary')
assert response.status_code == 302
assert response.url == urls.reverse('calibre:index')
assert list(messages)[0].message == 'TestExistingLibrary deleted.'
delete_library.assert_has_calls([call('TestExistingLibrary')])
@patch('plinth.modules.calibre.privileged.delete_library')
def test_delete_library_error(delete_library, rf):
"""Test that deleting a library shows error when operation fails."""
delete_library.side_effect = ValueError('TestError')
response, messages = make_request(rf.post(''), views.delete_library,
name='TestExistingLibrary')
assert response.status_code == 302
assert response.url == urls.reverse('calibre:index')
assert list(messages)[0].message == \
'Could not delete TestExistingLibrary: TestError'
def test_delete_library_non_existing(rf):
"""Test that deleting a library shows error when operation fails."""
with pytest.raises(Http404):
make_request(rf.post(''), views.delete_library,
name='TestNonExistingLibrary')
with pytest.raises(Http404):
make_request(rf.get(''), views.delete_library,
name='TestNonExistingLibrary')