"""Unit tests for the release approval queue model.""" import datetime from unittest import mock import pytest from product_workflow.connectors import mysql from product_workflow.models import rejection_notes, release_approval_queue, release_correction from product_workflow.utils import error_handling from tests.factories import rejection_notes as rejection_notes_factory from tests.testutils import db @pytest.fixture def release_id(): """Create a release id for testing.""" return 123 @pytest.fixture def release_approval_queue_data(): """Return a dictionary of release approval queue properties for testing.""" return { 'release_id': 1, 'status': 'transfer_to_content', 'admin_approval': 'N', 'checked_out_by': 1234, 'last_updated': datetime.datetime(2017, 6, 10, 0, 0, 0), 'date_submitted': datetime.datetime(2017, 6, 10, 0, 0, 0) } def test_to_dict(release_id): """Test that the expected properties are returned.""" release_approval_id = 123 status = 'rejected' admin_approval = 'N' checked_out_by = 1234 approval = release_approval_queue.ReleaseApprovalQueue( release_approval_id=release_approval_id, release_id=release_id, status=status, admin_approval=admin_approval, checked_out_by=checked_out_by) assert approval.to_dict() == { 'release_approval_id': release_approval_id, 'release_correction_id': None, 'release_id': release_id, 'status': status, 'checked_out_by': checked_out_by} @db.test_schema def test_create_release_approval_queue(release_approval_queue_data): """Test that a new release approval queue is returned.""" response = release_approval_queue.create(release_approval_queue_data) approval = response.message assert response.status == 201 assert approval['release_id'] == release_approval_queue_data['release_id'] assert approval['status'] == release_approval_queue_data['status'] @db.test_schema def test_create_release_approval_queue_with_release_correction( release_approval_queue_data ): """Test that you can create release_approval_queue with correction id.""" release_approval_queue_data_copy = dict(release_approval_queue_data) correction_id = 123 release_approval_queue_data_copy['release_correction_id'] = correction_id response = release_approval_queue.create(release_approval_queue_data_copy) approval = response.message assert response.status == 201 assert approval['release_correction_id'] == correction_id @db.test_schema def test_get_last_approval_success(release_id): """Test that the last approval queue in the db is returned.""" should_be_first = release_approval_queue.ReleaseApprovalQueue( release_id=release_id, status='rejected', admin_approval='N', last_updated=datetime.datetime(2017, 6, 10, 0, 0, 0), date_submitted=datetime.datetime(2017, 6, 10, 0, 0, 0)) should_be_last = release_approval_queue.ReleaseApprovalQueue( release_id=release_id, status='approved', admin_approval='Y', last_updated=datetime.datetime(2017, 6, 10, 0, 0, 0), date_submitted=datetime.datetime(2017, 6, 10, 0, 0, 0)) db.seed_models([should_be_first, should_be_last]) result = release_approval_queue.get_last_approval(release_id=release_id) assert result.status == 200 assert result.message == should_be_last.to_dict() @db.test_schema def test_get_last_approval_no_records(release_id): """Test that a 404 status is returned if there are no records.""" result = release_approval_queue.get_last_approval(release_id=release_id) assert result.status == 404 assert result.errors == { 'code': 'not_found_error', 'message': 'no release approval record found'} def test_get_last_approval_db_error(db_exception, mocker, release_id): """Test that a DB exception is logged and a 500 status is returned.""" mock_session = db.mock_db_session(mocker) mock_session.query.side_effect = db_exception mocker.patch.object(error_handling, 'log_db_exception', mock.Mock()) result = release_approval_queue.get_last_approval(release_id=release_id) assert result.status == 500 error_handling.log_db_exception.assert_called_once_with(db_exception) @db.test_schema def test_delete_release_approval(release_id): """Test that rejection_notes are deleted on cascade.""" release_approval_id = 666 approval = release_approval_queue.ReleaseApprovalQueue( release_id=release_id, status='rejected', release_approval_id=release_approval_id, last_updated=datetime.datetime(2017, 6, 10, 0, 0, 0), date_submitted=datetime.datetime(2017, 6, 10, 0, 0, 0) ) rejection_one = rejection_notes_factory.RejectionNoteFactory.build( release_approval_id=release_approval_id) rejection_two = rejection_notes_factory.RejectionNoteFactory.build( release_approval_id=release_approval_id) db.seed_models([approval, rejection_one, rejection_two]) with mysql.db_session() as session: session.delete(approval) notes = session.query(rejection_notes.RejectionNote).filter_by( release_approval_id=release_approval_id).all() assert not notes @db.test_schema def test_delete_latest_release_approval_success(release_id, account_id, account_type): """Test that rejection_notes are deleted on cascade.""" release_approval_id = 666 approval = release_approval_queue.ReleaseApprovalQueue( release_id=release_id, status='rejected', release_approval_id=release_approval_id, last_updated=datetime.datetime(2017, 6, 10), date_submitted=datetime.datetime(2017, 6, 10) ) correction = release_correction.ReleaseCorrection( release_correction_id=1234, release_id=release_id, status='submitted', last_updated=datetime.datetime(2018, 6, 10), last_updated_by=1) release_approval_id_latest = 777 latest_approval = release_approval_queue.ReleaseApprovalQueue( release_id=release_id, status='checked_in', release_correction_id=1234, release_approval_id=release_approval_id_latest, last_updated=datetime.datetime(2018, 6, 10, 0, 0, 0), date_submitted=datetime.datetime(2018, 6, 10, 0, 0, 0) ) rejection_one = rejection_notes_factory.RejectionNoteFactory.build( release_approval_id=release_approval_id_latest) rejection_two = rejection_notes_factory.RejectionNoteFactory.build( release_approval_id=release_approval_id_latest) db.seed_models([approval, correction, latest_approval, rejection_one, rejection_two]) result = release_approval_queue.delete_latest_release_approval_queue(release_id, account_id, account_type) assert result.status == 200 with mysql.db_session() as session: approvals = session.query(release_approval_queue.ReleaseApprovalQueue).filter_by(release_id=release_id).all() assert approvals assert approvals[0].status == 'rejected' assert approvals[0].release_approval_id == 666 notes = session.query(rejection_notes.RejectionNote).filter_by( release_approval_id=release_approval_id_latest).all() assert not notes correction = session.query(release_correction.ReleaseCorrection).filter_by(release_correction_id=1234).first() assert correction.status == 'active' @db.test_schema def test_delete_latest_release_approval_failure(release_id, account_id, account_type): """Test that rejection_notes are deleted on cascade.""" release_approval_id = 666 approval = release_approval_queue.ReleaseApprovalQueue( release_id=release_id, status='rejected', release_approval_id=release_approval_id, last_updated=datetime.datetime(2017, 6, 10, 0, 0, 0), date_submitted=datetime.datetime(2017, 6, 10, 0, 0, 0) ) db.seed_models(approval) result = release_approval_queue.delete_latest_release_approval_queue(release_id, account_id, account_type) assert result.status == 400 assert result.errors == { 'message': 'Product {} is not checked in'.format(release_id), 'code': 'bad_request' }