mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-06-02 02:28:32 +02:00
DA FSM edits, DA unit test refactor
This commit is contained in:
parent
335b96b2a7
commit
55f84f6d26
3 changed files with 337 additions and 396 deletions
|
@ -585,7 +585,12 @@ class DomainApplication(TimeStampedModel):
|
||||||
|
|
||||||
@transition(
|
@transition(
|
||||||
field="status",
|
field="status",
|
||||||
source=[ApplicationStatus.STARTED, ApplicationStatus.ACTION_NEEDED, ApplicationStatus.WITHDRAWN],
|
source=[
|
||||||
|
ApplicationStatus.STARTED,
|
||||||
|
ApplicationStatus.IN_REVIEW,
|
||||||
|
ApplicationStatus.ACTION_NEEDED,
|
||||||
|
ApplicationStatus.WITHDRAWN,
|
||||||
|
],
|
||||||
target=ApplicationStatus.SUBMITTED,
|
target=ApplicationStatus.SUBMITTED,
|
||||||
)
|
)
|
||||||
def submit(self):
|
def submit(self):
|
||||||
|
@ -613,7 +618,17 @@ class DomainApplication(TimeStampedModel):
|
||||||
"emails/submission_confirmation_subject.txt",
|
"emails/submission_confirmation_subject.txt",
|
||||||
)
|
)
|
||||||
|
|
||||||
@transition(field="status", source=ApplicationStatus.SUBMITTED, target=ApplicationStatus.IN_REVIEW)
|
@transition(
|
||||||
|
field="status",
|
||||||
|
source=[
|
||||||
|
ApplicationStatus.SUBMITTED,
|
||||||
|
ApplicationStatus.ACTION_NEEDED,
|
||||||
|
ApplicationStatus.APPROVED,
|
||||||
|
ApplicationStatus.REJECTED,
|
||||||
|
ApplicationStatus.INELIGIBLE,
|
||||||
|
],
|
||||||
|
target=ApplicationStatus.IN_REVIEW,
|
||||||
|
)
|
||||||
def in_review(self):
|
def in_review(self):
|
||||||
"""Investigate an application that has been submitted.
|
"""Investigate an application that has been submitted.
|
||||||
|
|
||||||
|
@ -627,7 +642,12 @@ class DomainApplication(TimeStampedModel):
|
||||||
|
|
||||||
@transition(
|
@transition(
|
||||||
field="status",
|
field="status",
|
||||||
source=[ApplicationStatus.IN_REVIEW, ApplicationStatus.REJECTED],
|
source=[
|
||||||
|
ApplicationStatus.IN_REVIEW,
|
||||||
|
ApplicationStatus.APPROVED,
|
||||||
|
ApplicationStatus.REJECTED,
|
||||||
|
ApplicationStatus.INELIGIBLE,
|
||||||
|
],
|
||||||
target=ApplicationStatus.ACTION_NEEDED,
|
target=ApplicationStatus.ACTION_NEEDED,
|
||||||
)
|
)
|
||||||
def action_needed(self):
|
def action_needed(self):
|
||||||
|
@ -646,8 +666,8 @@ class DomainApplication(TimeStampedModel):
|
||||||
source=[
|
source=[
|
||||||
ApplicationStatus.SUBMITTED,
|
ApplicationStatus.SUBMITTED,
|
||||||
ApplicationStatus.IN_REVIEW,
|
ApplicationStatus.IN_REVIEW,
|
||||||
|
ApplicationStatus.ACTION_NEEDED,
|
||||||
ApplicationStatus.REJECTED,
|
ApplicationStatus.REJECTED,
|
||||||
ApplicationStatus.INELIGIBLE,
|
|
||||||
],
|
],
|
||||||
target=ApplicationStatus.APPROVED,
|
target=ApplicationStatus.APPROVED,
|
||||||
)
|
)
|
||||||
|
@ -684,7 +704,7 @@ class DomainApplication(TimeStampedModel):
|
||||||
|
|
||||||
@transition(
|
@transition(
|
||||||
field="status",
|
field="status",
|
||||||
source=[ApplicationStatus.SUBMITTED, ApplicationStatus.IN_REVIEW],
|
source=[ApplicationStatus.SUBMITTED, ApplicationStatus.IN_REVIEW, ApplicationStatus.ACTION_NEEDED],
|
||||||
target=ApplicationStatus.WITHDRAWN,
|
target=ApplicationStatus.WITHDRAWN,
|
||||||
)
|
)
|
||||||
def withdraw(self):
|
def withdraw(self):
|
||||||
|
@ -697,7 +717,7 @@ class DomainApplication(TimeStampedModel):
|
||||||
|
|
||||||
@transition(
|
@transition(
|
||||||
field="status",
|
field="status",
|
||||||
source=[ApplicationStatus.IN_REVIEW, ApplicationStatus.APPROVED],
|
source=[ApplicationStatus.IN_REVIEW, ApplicationStatus.ACTION_NEEDED, ApplicationStatus.APPROVED],
|
||||||
target=ApplicationStatus.REJECTED,
|
target=ApplicationStatus.REJECTED,
|
||||||
conditions=[domain_is_not_active],
|
conditions=[domain_is_not_active],
|
||||||
)
|
)
|
||||||
|
@ -707,12 +727,16 @@ class DomainApplication(TimeStampedModel):
|
||||||
As side effects this will delete the domain and domain_information
|
As side effects this will delete the domain and domain_information
|
||||||
(will cascade), and send an email notification."""
|
(will cascade), and send an email notification."""
|
||||||
if self.status == self.ApplicationStatus.APPROVED:
|
if self.status == self.ApplicationStatus.APPROVED:
|
||||||
domain_state = self.approved_domain.state
|
try:
|
||||||
# Only reject if it exists on EPP
|
domain_state = self.approved_domain.state
|
||||||
if domain_state != Domain.State.UNKNOWN:
|
# Only reject if it exists on EPP
|
||||||
self.approved_domain.deletedInEpp()
|
if domain_state != Domain.State.UNKNOWN:
|
||||||
self.approved_domain.delete()
|
self.approved_domain.deletedInEpp()
|
||||||
self.approved_domain = None
|
self.approved_domain.delete()
|
||||||
|
self.approved_domain = None
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(err)
|
||||||
|
logger.error("Can't querry an approved domain while attempting a DA reject()")
|
||||||
|
|
||||||
self._send_status_update_email(
|
self._send_status_update_email(
|
||||||
"action needed",
|
"action needed",
|
||||||
|
@ -722,7 +746,12 @@ class DomainApplication(TimeStampedModel):
|
||||||
|
|
||||||
@transition(
|
@transition(
|
||||||
field="status",
|
field="status",
|
||||||
source=[ApplicationStatus.IN_REVIEW, ApplicationStatus.APPROVED],
|
source=[
|
||||||
|
ApplicationStatus.IN_REVIEW,
|
||||||
|
ApplicationStatus.ACTION_NEEDED,
|
||||||
|
ApplicationStatus.APPROVED,
|
||||||
|
ApplicationStatus.REJECTED,
|
||||||
|
],
|
||||||
target=ApplicationStatus.INELIGIBLE,
|
target=ApplicationStatus.INELIGIBLE,
|
||||||
conditions=[domain_is_not_active],
|
conditions=[domain_is_not_active],
|
||||||
)
|
)
|
||||||
|
@ -736,12 +765,16 @@ class DomainApplication(TimeStampedModel):
|
||||||
and domain_information (will cascade) when they exist."""
|
and domain_information (will cascade) when they exist."""
|
||||||
|
|
||||||
if self.status == self.ApplicationStatus.APPROVED:
|
if self.status == self.ApplicationStatus.APPROVED:
|
||||||
domain_state = self.approved_domain.state
|
try:
|
||||||
# Only reject if it exists on EPP
|
domain_state = self.approved_domain.state
|
||||||
if domain_state != Domain.State.UNKNOWN:
|
# Only reject if it exists on EPP
|
||||||
self.approved_domain.deletedInEpp()
|
if domain_state != Domain.State.UNKNOWN:
|
||||||
self.approved_domain.delete()
|
self.approved_domain.deletedInEpp()
|
||||||
self.approved_domain = None
|
self.approved_domain.delete()
|
||||||
|
self.approved_domain = None
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(err)
|
||||||
|
logger.error("Can't querry an approved domain while attempting a DA reject_with_prejudice()")
|
||||||
|
|
||||||
self.creator.restrict_user()
|
self.creator.restrict_user()
|
||||||
|
|
||||||
|
|
|
@ -462,7 +462,7 @@ def completed_application(
|
||||||
):
|
):
|
||||||
"""A completed domain application."""
|
"""A completed domain application."""
|
||||||
if not user:
|
if not user:
|
||||||
user = get_user_model().objects.create(username="username")
|
user = get_user_model().objects.create(username="username" + str(uuid.uuid4())[:8])
|
||||||
ao, _ = Contact.objects.get_or_create(
|
ao, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
|
|
|
@ -26,20 +26,52 @@ boto3_mocking.clients.register_handler("sesv2", MockSESClient)
|
||||||
# with AWS SES, so mock that out in all of these test cases
|
# with AWS SES, so mock that out in all of these test cases
|
||||||
@boto3_mocking.patching
|
@boto3_mocking.patching
|
||||||
class TestDomainApplication(TestCase):
|
class TestDomainApplication(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.started_application = completed_application(
|
||||||
|
status=DomainApplication.ApplicationStatus.STARTED, name="started.gov"
|
||||||
|
)
|
||||||
|
self.submitted_application = completed_application(
|
||||||
|
status=DomainApplication.ApplicationStatus.SUBMITTED, name="submitted.gov"
|
||||||
|
)
|
||||||
|
self.in_review_application = completed_application(
|
||||||
|
status=DomainApplication.ApplicationStatus.IN_REVIEW, name="in-review.gov"
|
||||||
|
)
|
||||||
|
self.action_needed_application = completed_application(
|
||||||
|
status=DomainApplication.ApplicationStatus.ACTION_NEEDED, name="action-needed.gov"
|
||||||
|
)
|
||||||
|
self.approved_application = completed_application(
|
||||||
|
status=DomainApplication.ApplicationStatus.APPROVED, name="approved.gov"
|
||||||
|
)
|
||||||
|
self.withdrawn_application = completed_application(
|
||||||
|
status=DomainApplication.ApplicationStatus.WITHDRAWN, name="withdrawn.gov"
|
||||||
|
)
|
||||||
|
self.rejected_application = completed_application(
|
||||||
|
status=DomainApplication.ApplicationStatus.REJECTED, name="rejected.gov"
|
||||||
|
)
|
||||||
|
self.ineligible_application = completed_application(
|
||||||
|
status=DomainApplication.ApplicationStatus.INELIGIBLE, name="ineligible.gov"
|
||||||
|
)
|
||||||
|
|
||||||
|
def assertNotRaises(self, exception_type):
|
||||||
|
"""Helper method for testing allowed transitions."""
|
||||||
|
return self.assertRaises(Exception, None, exception_type)
|
||||||
|
|
||||||
def test_empty_create_fails(self):
|
def test_empty_create_fails(self):
|
||||||
"""Can't create a completely empty domain application."""
|
"""Can't create a completely empty domain application.
|
||||||
|
NOTE: something about theexception this test raises messes up with the
|
||||||
|
atomic block in a custom tearDown method for the parent test class."""
|
||||||
with self.assertRaisesRegex(IntegrityError, "creator"):
|
with self.assertRaisesRegex(IntegrityError, "creator"):
|
||||||
DomainApplication.objects.create()
|
DomainApplication.objects.create()
|
||||||
|
|
||||||
def test_minimal_create(self):
|
def test_minimal_create(self):
|
||||||
"""Can create with just a creator."""
|
"""Can create with just a creator."""
|
||||||
user, _ = User.objects.get_or_create()
|
user, _ = User.objects.get_or_create(username="testy")
|
||||||
application = DomainApplication.objects.create(creator=user)
|
application = DomainApplication.objects.create(creator=user)
|
||||||
self.assertEqual(application.status, DomainApplication.ApplicationStatus.STARTED)
|
self.assertEqual(application.status, DomainApplication.ApplicationStatus.STARTED)
|
||||||
|
|
||||||
def test_full_create(self):
|
def test_full_create(self):
|
||||||
"""Can create with all fields."""
|
"""Can create with all fields."""
|
||||||
user, _ = User.objects.get_or_create()
|
user, _ = User.objects.get_or_create(username="testy")
|
||||||
contact = Contact.objects.create()
|
contact = Contact.objects.create()
|
||||||
com_website, _ = Website.objects.get_or_create(website="igorville.com")
|
com_website, _ = Website.objects.get_or_create(website="igorville.com")
|
||||||
gov_website, _ = Website.objects.get_or_create(website="igorville.gov")
|
gov_website, _ = Website.objects.get_or_create(website="igorville.gov")
|
||||||
|
@ -69,7 +101,7 @@ class TestDomainApplication(TestCase):
|
||||||
|
|
||||||
def test_domain_info(self):
|
def test_domain_info(self):
|
||||||
"""Can create domain info with all fields."""
|
"""Can create domain info with all fields."""
|
||||||
user, _ = User.objects.get_or_create()
|
user, _ = User.objects.get_or_create(username="testy")
|
||||||
contact = Contact.objects.create()
|
contact = Contact.objects.create()
|
||||||
domain, _ = Domain.objects.get_or_create(name="igorville.gov")
|
domain, _ = Domain.objects.get_or_create(name="igorville.gov")
|
||||||
information = DomainInformation.objects.create(
|
information = DomainInformation.objects.create(
|
||||||
|
@ -95,14 +127,14 @@ class TestDomainApplication(TestCase):
|
||||||
self.assertEqual(information.id, domain.domain_info.id)
|
self.assertEqual(information.id, domain.domain_info.id)
|
||||||
|
|
||||||
def test_status_fsm_submit_fail(self):
|
def test_status_fsm_submit_fail(self):
|
||||||
user, _ = User.objects.get_or_create()
|
user, _ = User.objects.get_or_create(username="testy")
|
||||||
application = DomainApplication.objects.create(creator=user)
|
application = DomainApplication.objects.create(creator=user)
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
# can't submit an application with a null domain name
|
# can't submit an application with a null domain name
|
||||||
application.submit()
|
application.submit()
|
||||||
|
|
||||||
def test_status_fsm_submit_succeed(self):
|
def test_status_fsm_submit_succeed(self):
|
||||||
user, _ = User.objects.get_or_create()
|
user, _ = User.objects.get_or_create(username="testy")
|
||||||
site = DraftDomain.objects.create(name="igorville.gov")
|
site = DraftDomain.objects.create(name="igorville.gov")
|
||||||
application = DomainApplication.objects.create(creator=user, requested_domain=site)
|
application = DomainApplication.objects.create(creator=user, requested_domain=site)
|
||||||
# no submitter email so this emits a log warning
|
# no submitter email so this emits a log warning
|
||||||
|
@ -112,7 +144,7 @@ class TestDomainApplication(TestCase):
|
||||||
|
|
||||||
def test_submit_sends_email(self):
|
def test_submit_sends_email(self):
|
||||||
"""Create an application and submit it and see if email was sent."""
|
"""Create an application and submit it and see if email was sent."""
|
||||||
user, _ = User.objects.get_or_create()
|
user, _ = User.objects.get_or_create(username="testy")
|
||||||
contact = Contact.objects.create(email="test@test.gov")
|
contact = Contact.objects.create(email="test@test.gov")
|
||||||
domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov")
|
domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov")
|
||||||
application = DomainApplication.objects.create(
|
application = DomainApplication.objects.create(
|
||||||
|
@ -135,320 +167,251 @@ class TestDomainApplication(TestCase):
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_transition_not_allowed_submitted_submitted(self):
|
def test_submit_transition_allowed(self):
|
||||||
"""Create an application with status submitted and call submit
|
"""
|
||||||
against transition rules"""
|
Test that calling submit from allowable statuses does raises TransitionNotAllowed.
|
||||||
|
"""
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.SUBMITTED)
|
test_cases = [
|
||||||
|
(self.started_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
(self.in_review_application, TransitionNotAllowed),
|
||||||
application.submit()
|
(self.action_needed_application, TransitionNotAllowed),
|
||||||
|
(self.withdrawn_application, TransitionNotAllowed),
|
||||||
def test_transition_not_allowed_in_review_submitted(self):
|
]
|
||||||
"""Create an application with status in review and call submit
|
|
||||||
against transition rules"""
|
for application, exception_type in test_cases:
|
||||||
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
try:
|
||||||
|
application.submit()
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
except TransitionNotAllowed:
|
||||||
application.submit()
|
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||||
|
|
||||||
def test_transition_not_allowed_approved_submitted(self):
|
def test_submit_transition_not_allowed(self):
|
||||||
"""Create an application with status approved and call submit
|
"""
|
||||||
against transition rules"""
|
Test that calling submit against transition rules raises TransitionNotAllowed.
|
||||||
|
"""
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
test_cases = [
|
||||||
|
(self.submitted_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
(self.approved_application, TransitionNotAllowed),
|
||||||
application.submit()
|
(self.rejected_application, TransitionNotAllowed),
|
||||||
|
(self.ineligible_application, TransitionNotAllowed),
|
||||||
def test_transition_not_allowed_rejected_submitted(self):
|
]
|
||||||
"""Create an application with status rejected and call submit
|
|
||||||
against transition rules"""
|
for application, exception_type in test_cases:
|
||||||
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.REJECTED)
|
with self.assertRaises(exception_type):
|
||||||
|
application.submit()
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.submit()
|
def test_in_review_transition_allowed(self):
|
||||||
|
"""
|
||||||
def test_transition_not_allowed_ineligible_submitted(self):
|
Test that calling in_review from allowable statuses does raises TransitionNotAllowed.
|
||||||
"""Create an application with status ineligible and call submit
|
"""
|
||||||
against transition rules"""
|
test_cases = [
|
||||||
|
(self.submitted_application, TransitionNotAllowed),
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.INELIGIBLE)
|
(self.action_needed_application, TransitionNotAllowed),
|
||||||
|
(self.approved_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
(self.rejected_application, TransitionNotAllowed),
|
||||||
application.submit()
|
(self.ineligible_application, TransitionNotAllowed),
|
||||||
|
]
|
||||||
def test_transition_not_allowed_started_in_review(self):
|
|
||||||
"""Create an application with status started and call in_review
|
for application, exception_type in test_cases:
|
||||||
against transition rules"""
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
|
try:
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.STARTED)
|
application.in_review()
|
||||||
|
except TransitionNotAllowed:
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||||
application.in_review()
|
|
||||||
|
def test_in_review_transition_not_allowed(self):
|
||||||
def test_transition_not_allowed_in_review_in_review(self):
|
"""
|
||||||
"""Create an application with status in review and call in_review
|
Test that calling in_review against transition rules raises TransitionNotAllowed.
|
||||||
against transition rules"""
|
"""
|
||||||
|
test_cases = [
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
(self.started_application, TransitionNotAllowed),
|
||||||
|
(self.in_review_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
(self.withdrawn_application, TransitionNotAllowed),
|
||||||
application.in_review()
|
]
|
||||||
|
|
||||||
def test_transition_not_allowed_approved_in_review(self):
|
for application, exception_type in test_cases:
|
||||||
"""Create an application with status approved and call in_review
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
against transition rules"""
|
with self.assertRaises(exception_type):
|
||||||
|
application.in_review()
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
|
||||||
|
def test_action_needed_transition_allowed(self):
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
"""
|
||||||
application.in_review()
|
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||||
|
"""
|
||||||
def test_transition_not_allowed_action_needed_in_review(self):
|
test_cases = [
|
||||||
"""Create an application with status action needed and call in_review
|
(self.in_review_application, TransitionNotAllowed),
|
||||||
against transition rules"""
|
(self.approved_application, TransitionNotAllowed),
|
||||||
|
(self.rejected_application, TransitionNotAllowed),
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.ACTION_NEEDED)
|
(self.ineligible_application, TransitionNotAllowed),
|
||||||
|
]
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.in_review()
|
for application, exception_type in test_cases:
|
||||||
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
def test_transition_not_allowed_rejected_in_review(self):
|
try:
|
||||||
"""Create an application with status rejected and call in_review
|
application.action_needed()
|
||||||
against transition rules"""
|
except TransitionNotAllowed:
|
||||||
|
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.REJECTED)
|
|
||||||
|
def test_action_needed_transition_not_allowed(self):
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
"""
|
||||||
application.in_review()
|
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||||
|
"""
|
||||||
def test_transition_not_allowed_withdrawn_in_review(self):
|
test_cases = [
|
||||||
"""Create an application with status withdrawn and call in_review
|
(self.started_application, TransitionNotAllowed),
|
||||||
against transition rules"""
|
(self.submitted_application, TransitionNotAllowed),
|
||||||
|
(self.action_needed_application, TransitionNotAllowed),
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.WITHDRAWN)
|
(self.withdrawn_application, TransitionNotAllowed),
|
||||||
|
]
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.in_review()
|
for application, exception_type in test_cases:
|
||||||
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
def test_transition_not_allowed_ineligible_in_review(self):
|
with self.assertRaises(exception_type):
|
||||||
"""Create an application with status ineligible and call in_review
|
application.action_needed()
|
||||||
against transition rules"""
|
|
||||||
|
def test_approved_transition_allowed(self):
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.INELIGIBLE)
|
"""
|
||||||
|
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
"""
|
||||||
application.in_review()
|
test_cases = [
|
||||||
|
(self.submitted_application, TransitionNotAllowed),
|
||||||
def test_transition_not_allowed_started_action_needed(self):
|
(self.in_review_application, TransitionNotAllowed),
|
||||||
"""Create an application with status started and call action_needed
|
(self.action_needed_application, TransitionNotAllowed),
|
||||||
against transition rules"""
|
(self.rejected_application, TransitionNotAllowed),
|
||||||
|
]
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.STARTED)
|
|
||||||
|
for application, exception_type in test_cases:
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
application.action_needed()
|
try:
|
||||||
|
application.approve()
|
||||||
def test_transition_not_allowed_submitted_action_needed(self):
|
except TransitionNotAllowed:
|
||||||
"""Create an application with status submitted and call action_needed
|
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||||
against transition rules"""
|
|
||||||
|
def test_approved_transition_not_allowed(self):
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.SUBMITTED)
|
"""
|
||||||
|
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
"""
|
||||||
application.action_needed()
|
test_cases = [
|
||||||
|
(self.started_application, TransitionNotAllowed),
|
||||||
def test_transition_not_allowed_action_needed_action_needed(self):
|
(self.approved_application, TransitionNotAllowed),
|
||||||
"""Create an application with status action needed and call action_needed
|
(self.withdrawn_application, TransitionNotAllowed),
|
||||||
against transition rules"""
|
(self.ineligible_application, TransitionNotAllowed),
|
||||||
|
]
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.ACTION_NEEDED)
|
|
||||||
|
for application, exception_type in test_cases:
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
application.action_needed()
|
with self.assertRaises(exception_type):
|
||||||
|
application.approve()
|
||||||
def test_transition_not_allowed_approved_action_needed(self):
|
|
||||||
"""Create an application with status approved and call action_needed
|
def test_withdraw_transition_allowed(self):
|
||||||
against transition rules"""
|
"""
|
||||||
|
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
"""
|
||||||
|
test_cases = [
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
(self.submitted_application, TransitionNotAllowed),
|
||||||
application.action_needed()
|
(self.in_review_application, TransitionNotAllowed),
|
||||||
|
(self.action_needed_application, TransitionNotAllowed),
|
||||||
def test_transition_not_allowed_withdrawn_action_needed(self):
|
]
|
||||||
"""Create an application with status withdrawn and call action_needed
|
|
||||||
against transition rules"""
|
for application, exception_type in test_cases:
|
||||||
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.WITHDRAWN)
|
try:
|
||||||
|
application.withdraw()
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
except TransitionNotAllowed:
|
||||||
application.action_needed()
|
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||||
|
|
||||||
def test_transition_not_allowed_ineligible_action_needed(self):
|
def test_withdraw_transition_not_allowed(self):
|
||||||
"""Create an application with status ineligible and call action_needed
|
"""
|
||||||
against transition rules"""
|
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||||
|
"""
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.INELIGIBLE)
|
test_cases = [
|
||||||
|
(self.started_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
(self.approved_application, TransitionNotAllowed),
|
||||||
application.action_needed()
|
(self.withdrawn_application, TransitionNotAllowed),
|
||||||
|
(self.rejected_application, TransitionNotAllowed),
|
||||||
def test_transition_not_allowed_started_approved(self):
|
(self.ineligible_application, TransitionNotAllowed),
|
||||||
"""Create an application with status started and call approve
|
]
|
||||||
against transition rules"""
|
|
||||||
|
for application, exception_type in test_cases:
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.STARTED)
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
|
with self.assertRaises(exception_type):
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
application.withdraw()
|
||||||
application.approve()
|
|
||||||
|
def test_reject_transition_allowed(self):
|
||||||
def test_transition_not_allowed_approved_approved(self):
|
"""
|
||||||
"""Create an application with status approved and call approve
|
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||||
against transition rules"""
|
"""
|
||||||
|
test_cases = [
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
(self.in_review_application, TransitionNotAllowed),
|
||||||
|
(self.action_needed_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
(self.approved_application, TransitionNotAllowed),
|
||||||
application.approve()
|
]
|
||||||
|
|
||||||
def test_transition_not_allowed_action_needed_approved(self):
|
for application, exception_type in test_cases:
|
||||||
"""Create an application with status action needed and call approve
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
against transition rules"""
|
try:
|
||||||
|
application.reject()
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.ACTION_NEEDED)
|
except TransitionNotAllowed:
|
||||||
|
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.approve()
|
def test_reject_transition_not_allowed(self):
|
||||||
|
"""
|
||||||
def test_transition_not_allowed_withdrawn_approved(self):
|
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||||
"""Create an application with status withdrawn and call approve
|
"""
|
||||||
against transition rules"""
|
test_cases = [
|
||||||
|
(self.started_application, TransitionNotAllowed),
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.WITHDRAWN)
|
(self.submitted_application, TransitionNotAllowed),
|
||||||
|
(self.withdrawn_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
(self.rejected_application, TransitionNotAllowed),
|
||||||
application.approve()
|
(self.ineligible_application, TransitionNotAllowed),
|
||||||
|
]
|
||||||
def test_transition_not_allowed_started_withdrawn(self):
|
|
||||||
"""Create an application with status started and call withdraw
|
for application, exception_type in test_cases:
|
||||||
against transition rules"""
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
|
with self.assertRaises(exception_type):
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.STARTED)
|
application.reject()
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
def test_reject_with_prejudice_transition_allowed(self):
|
||||||
application.withdraw()
|
"""
|
||||||
|
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||||
def test_transition_not_allowed_approved_withdrawn(self):
|
"""
|
||||||
"""Create an application with status approved and call withdraw
|
test_cases = [
|
||||||
against transition rules"""
|
(self.in_review_application, TransitionNotAllowed),
|
||||||
|
(self.action_needed_application, TransitionNotAllowed),
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
(self.approved_application, TransitionNotAllowed),
|
||||||
|
(self.rejected_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
]
|
||||||
application.withdraw()
|
|
||||||
|
for application, exception_type in test_cases:
|
||||||
def test_transition_not_allowed_action_needed_withdrawn(self):
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
"""Create an application with status action needed and call withdraw
|
try:
|
||||||
against transition rules"""
|
application.reject_with_prejudice()
|
||||||
|
except TransitionNotAllowed:
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.ACTION_NEEDED)
|
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
def test_reject_with_prejudice_transition_not_allowed(self):
|
||||||
application.withdraw()
|
"""
|
||||||
|
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||||
def test_transition_not_allowed_rejected_withdrawn(self):
|
"""
|
||||||
"""Create an application with status rejected and call withdraw
|
test_cases = [
|
||||||
against transition rules"""
|
(self.started_application, TransitionNotAllowed),
|
||||||
|
(self.submitted_application, TransitionNotAllowed),
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.REJECTED)
|
(self.withdrawn_application, TransitionNotAllowed),
|
||||||
|
(self.ineligible_application, TransitionNotAllowed),
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
]
|
||||||
application.withdraw()
|
|
||||||
|
for application, exception_type in test_cases:
|
||||||
def test_transition_not_allowed_withdrawn_withdrawn(self):
|
with self.subTest(application=application, exception_type=exception_type):
|
||||||
"""Create an application with status withdrawn and call withdraw
|
with self.assertRaises(exception_type):
|
||||||
against transition rules"""
|
application.reject_with_prejudice()
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.WITHDRAWN)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.withdraw()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_ineligible_withdrawn(self):
|
|
||||||
"""Create an application with status ineligible and call withdraw
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.INELIGIBLE)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.withdraw()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_started_rejected(self):
|
|
||||||
"""Create an application with status started and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.STARTED)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_submitted_rejected(self):
|
|
||||||
"""Create an application with status submitted and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.SUBMITTED)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_action_needed_rejected(self):
|
|
||||||
"""Create an application with status action needed and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.ACTION_NEEDED)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_withdrawn_rejected(self):
|
|
||||||
"""Create an application with status withdrawn and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.WITHDRAWN)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_rejected_rejected(self):
|
|
||||||
"""Create an application with status rejected and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.REJECTED)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_ineligible_rejected(self):
|
|
||||||
"""Create an application with status ineligible and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.INELIGIBLE)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_approved_rejected_when_domain_is_active(self):
|
def test_transition_not_allowed_approved_rejected_when_domain_is_active(self):
|
||||||
"""Create an application with status approved, create a matching domain that
|
"""Create an application with status approved, create a matching domain that
|
||||||
is active, and call reject against transition rules"""
|
is active, and call reject against transition rules"""
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
domain = Domain.objects.create(name=self.approved_application.requested_domain.name)
|
||||||
domain = Domain.objects.create(name=application.requested_domain.name)
|
self.approved_application.approved_domain = domain
|
||||||
application.approved_domain = domain
|
self.approved_application.save()
|
||||||
application.save()
|
|
||||||
|
|
||||||
# Define a custom implementation for is_active
|
# Define a custom implementation for is_active
|
||||||
def custom_is_active(self):
|
def custom_is_active(self):
|
||||||
|
@ -458,70 +421,15 @@ class TestDomainApplication(TestCase):
|
||||||
with patch.object(Domain, "is_active", custom_is_active):
|
with patch.object(Domain, "is_active", custom_is_active):
|
||||||
# Now, when you call is_active on Domain, it will return True
|
# Now, when you call is_active on Domain, it will return True
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
with self.assertRaises(TransitionNotAllowed):
|
||||||
application.reject()
|
self.approved_application.reject()
|
||||||
|
|
||||||
def test_transition_not_allowed_started_ineligible(self):
|
|
||||||
"""Create an application with status started and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.STARTED)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject_with_prejudice()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_submitted_ineligible(self):
|
|
||||||
"""Create an application with status submitted and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.SUBMITTED)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject_with_prejudice()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_action_needed_ineligible(self):
|
|
||||||
"""Create an application with status action needed and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.ACTION_NEEDED)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject_with_prejudice()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_withdrawn_ineligible(self):
|
|
||||||
"""Create an application with status withdrawn and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.WITHDRAWN)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject_with_prejudice()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_rejected_ineligible(self):
|
|
||||||
"""Create an application with status rejected and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.REJECTED)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject_with_prejudice()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_ineligible_ineligible(self):
|
|
||||||
"""Create an application with status ineligible and call reject
|
|
||||||
against transition rules"""
|
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.INELIGIBLE)
|
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
|
||||||
application.reject_with_prejudice()
|
|
||||||
|
|
||||||
def test_transition_not_allowed_approved_ineligible_when_domain_is_active(self):
|
def test_transition_not_allowed_approved_ineligible_when_domain_is_active(self):
|
||||||
"""Create an application with status approved, create a matching domain that
|
"""Create an application with status approved, create a matching domain that
|
||||||
is active, and call reject_with_prejudice against transition rules"""
|
is active, and call reject_with_prejudice against transition rules"""
|
||||||
|
|
||||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
domain = Domain.objects.create(name=self.approved_application.requested_domain.name)
|
||||||
domain = Domain.objects.create(name=application.requested_domain.name)
|
self.approved_application.approved_domain = domain
|
||||||
application.approved_domain = domain
|
self.approved_application.save()
|
||||||
application.save()
|
|
||||||
|
|
||||||
# Define a custom implementation for is_active
|
# Define a custom implementation for is_active
|
||||||
def custom_is_active(self):
|
def custom_is_active(self):
|
||||||
|
@ -531,7 +439,7 @@ class TestDomainApplication(TestCase):
|
||||||
with patch.object(Domain, "is_active", custom_is_active):
|
with patch.object(Domain, "is_active", custom_is_active):
|
||||||
# Now, when you call is_active on Domain, it will return True
|
# Now, when you call is_active on Domain, it will return True
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
with self.assertRaises(TransitionNotAllowed):
|
||||||
application.reject_with_prejudice()
|
self.approved_application.reject_with_prejudice()
|
||||||
|
|
||||||
|
|
||||||
class TestPermissions(TestCase):
|
class TestPermissions(TestCase):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue