Joseph Nuthalapati 6bfffeee13
calibre: Add new e-book library app
[joseph: initial code for the app]
Signed-off-by: Joseph Nuthalapati <njoseph@thoughtworks.com>
[sunil: use the modified framework API]
[sunil: simplify setup logic, move to service file]
[sunil: strict security for service file, dynamic users]
[sunil: interface for managing libraries]
[sunil: implement backup/restore]
[sunil: add functional, action, and view tests]
[sunil: use svg icon]
[sunil: update description]
[sunil: fix apache configuration]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Joseph Nuthalapati <njoseph@riseup.net>
2020-09-27 22:16:07 +05:30

147 lines
5.5 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 actions, 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.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.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.create_library')
def test_create_library_failed(create_library, rf):
"""Test that create library fails as expected."""
create_library.side_effect = actions.ActionError('calibre', 'TestOutput',
'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.modules.calibre.app')
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.delete_library')
@patch('plinth.modules.calibre.app')
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.delete_library')
def test_delete_library_error(delete_library, rf):
"""Test that deleting a library shows error when operation fails."""
delete_library.side_effect = actions.ActionError('calibre', 'TestInput',
'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: '\
"('calibre', 'TestInput', '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')