From 9eaa2271bf058b36a94be94daf9e24d119c50bef Mon Sep 17 00:00:00 2001 From: Kevin O'Gorman Date: Fri, 4 Dec 2020 16:39:22 -0500 Subject: [PATCH] updated tests to maintain coverage --- securedrop/tests/test_journalist.py | 89 +++++++++++++++++++++++++++++ securedrop/tests/test_source.py | 47 +++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/securedrop/tests/test_journalist.py b/securedrop/tests/test_journalist.py index 0d8d241e9c..1c289331cc 100644 --- a/securedrop/tests/test_journalist.py +++ b/securedrop/tests/test_journalist.py @@ -1496,6 +1496,41 @@ def test_no_prevent_document_uploads(journalist_app, test_admin): app.post(url_for('admin.update_submission_preferences'), follow_redirects=True) ins.assert_message_flashed('Preferences saved.', 'submission-preferences-success') + assert InstanceConfig.get_current().allow_document_uploads is True + + +def test_prevent_document_uploads_invalid(journalist_app, test_admin): + with journalist_app.test_client() as app: + _login_user(app, test_admin['username'], test_admin['password'], + test_admin['otp_secret']) + form_true = journalist_app_module.forms.SubmissionPreferencesForm( + prevent_document_uploads=True) + app.post(url_for('admin.update_submission_preferences'), + data=form_true.data, + follow_redirects=True) + assert InstanceConfig.get_current().allow_document_uploads is False + + with patch('flask_wtf.FlaskForm.validate_on_submit') as fMock: + fMock.return_value = False + form_false = journalist_app_module.forms.SubmissionPreferencesForm( + prevent_document_uploads=False) + app.post(url_for('admin.update_submission_preferences'), + data=form_false.data, + follow_redirects=True) + assert InstanceConfig.get_current().allow_document_uploads is False + + +def test_orgname_default_set(journalist_app, test_admin): + + class dummy_current(): + organization_name = None + + with patch.object(InstanceConfig, 'get_current') as iMock: + with journalist_app.test_client() as app: + iMock.return_value = dummy_current() + _login_user(app, test_admin['username'], test_admin['password'], + test_admin['otp_secret']) + assert g.organization_name == "SecureDrop" def test_orgname_valid_succeeds(journalist_app, test_admin): @@ -1561,6 +1596,21 @@ def test_orgname_html_escaped(journalist_app, test_admin): assert InstanceConfig.get_current().organization_name == htmlescape(t_name, quote=True) +def test_logo_default_available(journalist_app): + # if the custom image is available, this test will fail + custom_image_location = os.path.join(config.SECUREDROP_ROOT, "static/i/custom_logo.png") + if os.path.exists(custom_image_location): + os.remove(custom_image_location) + + with journalist_app.test_client() as app: + response = app.get(url_for('main.select_logo'), follow_redirects=False) + + assert response.status_code == 302 + observed_headers = response.headers + assert 'Location' in list(observed_headers.keys()) + assert url_for('static', filename='i/logo.png') in observed_headers['Location'] + + def test_logo_upload_with_valid_image_succeeds(journalist_app, test_admin): # Save original logo to restore after test run logo_image_location = os.path.join(config.SECUREDROP_ROOT, @@ -1584,6 +1634,13 @@ def test_logo_upload_with_valid_image_succeeds(journalist_app, test_admin): follow_redirects=True) ins.assert_message_flashed("Image updated.", "logo-success") + with journalist_app.test_client() as app: + response = app.get(url_for('main.select_logo'), follow_redirects=False) + + assert response.status_code == 302 + observed_headers = response.headers + assert 'Location' in list(observed_headers.keys()) + assert url_for('static', filename='i/custom_logo.png') in observed_headers['Location'] finally: # Restore original image to logo location for subsequent tests with io.open(logo_image_location, 'wb') as logo_file: @@ -1608,6 +1665,38 @@ def test_logo_upload_with_invalid_filetype_fails(journalist_app, test_admin): assert "You can only upload PNG image files." in text +def test_logo_upload_save_fails(journalist_app, test_admin): + # Save original logo to restore after test run + logo_image_location = os.path.join(config.SECUREDROP_ROOT, + "static/i/logo.png") + with io.open(logo_image_location, 'rb') as logo_file: + original_image = logo_file.read() + + try: + with journalist_app.test_client() as app: + _login_user(app, test_admin['username'], test_admin['password'], + test_admin['otp_secret']) + # Create 1px * 1px 'white' PNG file from its base64 string + form = journalist_app_module.forms.LogoForm( + logo=(BytesIO(base64.decodebytes + (b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQ" + b"VR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=")), 'test.png') + ) + with InstrumentedApp(journalist_app) as ins: + with patch('werkzeug.datastructures.FileStorage.save') as sMock: + sMock.side_effect = Exception + app.post(url_for('admin.manage_config'), + data=form.data, + follow_redirects=True) + + ins.assert_message_flashed("Unable to process the image file." + " Try another one.", "logo-error") + finally: + # Restore original image to logo location for subsequent tests + with io.open(logo_image_location, 'wb') as logo_file: + logo_file.write(original_image) + + def test_creation_of_ossec_test_log_event(journalist_app, test_admin, mocker): mocked_error_logger = mocker.patch('journalist.app.logger.error') with journalist_app.test_client() as app: diff --git a/securedrop/tests/test_source.py b/securedrop/tests/test_source.py index 119aea7f7a..bb4275927e 100644 --- a/securedrop/tests/test_source.py +++ b/securedrop/tests/test_source.py @@ -3,6 +3,8 @@ import re import subprocess import time +import os +import shutil from io import BytesIO, StringIO from flask import session, escape, url_for, g, request @@ -21,10 +23,42 @@ from source_app import api as source_app_api from .utils.db_helper import new_codename from .utils.instrument import InstrumentedApp +from sdconfig import config overly_long_codename = 'a' * (PassphraseGenerator.MAX_PASSPHRASE_LENGTH + 1) +def test_logo_default_available(source_app): + # if the custom image is available, this test will fail + custom_image_location = os.path.join(config.SECUREDROP_ROOT, "static/i/custom_logo.png") + if os.path.exists(custom_image_location): + os.remove(custom_image_location) + + with source_app.test_client() as app: + response = app.get(url_for('main.select_logo'), follow_redirects=False) + + assert response.status_code == 302 + observed_headers = response.headers + assert 'Location' in list(observed_headers.keys()) + assert url_for('static', filename='i/logo.png') in observed_headers['Location'] + + +def test_logo_custom_available(source_app): + # if the custom image is available, this test will fail + custom_image = os.path.join(config.SECUREDROP_ROOT, "static/i/custom_logo.png") + default_image = os.path.join(config.SECUREDROP_ROOT, "static/i/logo.png") + if os.path.exists(default_image) and not os.path.exists(custom_image): + shutil.copyfile(default_image, custom_image) + + with source_app.test_client() as app: + response = app.get(url_for('main.select_logo'), follow_redirects=False) + + assert response.status_code == 302 + observed_headers = response.headers + assert 'Location' in list(observed_headers.keys()) + assert url_for('static', filename='i/custom_logo.png') in observed_headers['Location'] + + def test_page_not_found(source_app): """Verify the page not found condition returns the intended template""" with InstrumentedApp(source_app) as ins: @@ -34,6 +68,19 @@ def test_page_not_found(source_app): ins.assert_template_used('notfound.html') +def test_orgname_default_set(source_app): + + class dummy_current(): + organization_name = None + + with patch.object(InstanceConfig, 'get_current') as iMock: + with source_app.test_client() as app: + iMock.return_value = dummy_current() + resp = app.get(url_for('main.index')) + assert resp.status_code == 200 + assert g.organization_name == "SecureDrop" + + def test_index(source_app): """Test that the landing page loads and looks how we expect""" with source_app.test_client() as app: