mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-22 04:19:26 +02:00
Merge branch 'main' into sspj/draft-test-cases
This commit is contained in:
commit
12d3f5bdb7
32 changed files with 513 additions and 374 deletions
|
@ -1,14 +1,11 @@
|
|||
{
|
||||
"defaults": {
|
||||
"concurrency": 1,
|
||||
"timeout": 30000,
|
||||
"hideElements": "a[href='/whoami/']"
|
||||
|
||||
"timeout": 30000
|
||||
},
|
||||
"urls": [
|
||||
"http://localhost:8080/",
|
||||
"http://localhost:8080/health/",
|
||||
"http://localhost:8080/whoami/",
|
||||
"http://localhost:8080/register/",
|
||||
"http://localhost:8080/register/organization/",
|
||||
"http://localhost:8080/register/org_federal/",
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import logging
|
||||
from django.contrib import admin, messages
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.http.response import HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
|
||||
from . import models
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AuditedAdmin(admin.ModelAdmin):
|
||||
|
||||
|
@ -78,13 +80,37 @@ class DomainAdmin(AuditedAdmin):
|
|||
return super().response_change(request, obj)
|
||||
|
||||
|
||||
class DomainApplicationAdmin(AuditedAdmin):
|
||||
|
||||
"""Customize the applications listing view."""
|
||||
|
||||
# Trigger action when a fieldset is changed
|
||||
def save_model(self, request, obj, form, change):
|
||||
if change: # Check if the application is being edited
|
||||
# Get the original application from the database
|
||||
original_obj = models.DomainApplication.objects.get(pk=obj.pk)
|
||||
|
||||
if (
|
||||
obj.status != original_obj.status
|
||||
and obj.status == models.DomainApplication.INVESTIGATING
|
||||
):
|
||||
# This is a transition annotated method in model which will throw an
|
||||
# error if the condition is violated. To make this work, we need to
|
||||
# call it on the original object which has the right status value,
|
||||
# but pass the current object which contains the up-to-date data
|
||||
# for the email.
|
||||
original_obj.in_review(obj)
|
||||
|
||||
super().save_model(request, obj, form, change)
|
||||
|
||||
|
||||
admin.site.register(models.User, MyUserAdmin)
|
||||
admin.site.register(models.UserDomainRole, AuditedAdmin)
|
||||
admin.site.register(models.Contact, AuditedAdmin)
|
||||
admin.site.register(models.DomainInvitation, AuditedAdmin)
|
||||
admin.site.register(models.DomainApplication, AuditedAdmin)
|
||||
admin.site.register(models.DomainInformation, AuditedAdmin)
|
||||
admin.site.register(models.Domain, DomainAdmin)
|
||||
admin.site.register(models.Host, MyHostAdmin)
|
||||
admin.site.register(models.Nameserver, MyHostAdmin)
|
||||
admin.site.register(models.Website, AuditedAdmin)
|
||||
admin.site.register(models.DomainApplication, DomainApplicationAdmin)
|
||||
|
|
|
@ -564,15 +564,13 @@ SECURE_SSL_REDIRECT = True
|
|||
# web server configurations.
|
||||
ALLOWED_HOSTS = [
|
||||
"getgov-stable.app.cloud.gov",
|
||||
"getgov-staging.app.cloud.gov",
|
||||
"getgov-gd.app.cloud.gov",
|
||||
"getgov-rb.app.cloud.gov",
|
||||
"getgov-ko.app.cloud.gov",
|
||||
"getgov-ab.app.cloud.gov",
|
||||
"getgov-bl.app.cloud.gov",
|
||||
"getgov-rjm.app.cloud.gov",
|
||||
"getgov-jon.app.cloud.gov",
|
||||
"getgov-mr.app.cloud.gov",
|
||||
"getgov-sspj.app.cloud.gov",
|
||||
"getgov-nmb.app.cloud.gov",
|
||||
"getgov-ik.app.cloud.gov",
|
||||
"get.gov",
|
||||
]
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ for step, view in [
|
|||
|
||||
urlpatterns = [
|
||||
path("", views.index, name="home"),
|
||||
path("whoami/", views.whoami, name="whoami"),
|
||||
path("admin/", admin.site.urls),
|
||||
path(
|
||||
"application/<id>/edit/",
|
||||
|
|
|
@ -24,31 +24,6 @@ class UserFixture:
|
|||
"""
|
||||
|
||||
ADMINS = [
|
||||
{
|
||||
"username": "c4a0e101-73b4-4d7d-9e5e-7f19a726a0fa",
|
||||
"first_name": "Seamus",
|
||||
"last_name": "Johnston",
|
||||
},
|
||||
{
|
||||
"username": "d4c3bd84-dc3a-48bc-a3c3-f53111df2ec6",
|
||||
"first_name": "Igor",
|
||||
"last_name": "",
|
||||
},
|
||||
{
|
||||
"username": "ee80bfe0-49ad-456d-8d82-e2b608a66517",
|
||||
"first_name": "Logan",
|
||||
"last_name": "",
|
||||
},
|
||||
{
|
||||
"username": "2ffe71b0-cea4-4097-8fb6-7a35b901dd70",
|
||||
"first_name": "Neil",
|
||||
"last_name": "Martinsen-Burrell",
|
||||
},
|
||||
{
|
||||
"username": "7185e6cd-d3c8-4adc-90a3-ceddba71d24f",
|
||||
"first_name": "Jon",
|
||||
"last_name": "Roberts",
|
||||
},
|
||||
{
|
||||
"username": "5f283494-31bd-49b5-b024-a7e7cae00848",
|
||||
"first_name": "Rachid",
|
||||
|
@ -59,11 +34,6 @@ class UserFixture:
|
|||
"first_name": "Alysia",
|
||||
"last_name": "Broddrick",
|
||||
},
|
||||
{
|
||||
"username": "55a3bc26-cd1d-4a5c-a8c0-7e1f561ef7f4",
|
||||
"first_name": "Michelle",
|
||||
"last_name": "Rago",
|
||||
},
|
||||
{
|
||||
"username": "8f8e7293-17f7-4716-889b-1990241cbd39",
|
||||
"first_name": "Katherine",
|
||||
|
|
|
@ -490,9 +490,38 @@ class DomainApplication(TimeStampedModel):
|
|||
self.submitter.email,
|
||||
context={"application": self},
|
||||
)
|
||||
logger.info(
|
||||
f"Submission confirmation email sent to: {self.submitter.email}"
|
||||
)
|
||||
except EmailSendingError:
|
||||
logger.warning("Failed to send confirmation email", exc_info=True)
|
||||
|
||||
def _send_in_review_email(self):
|
||||
"""Send an email that this application is now in review.
|
||||
|
||||
The email goes to the email address that the submitter gave as their
|
||||
contact information. If there is not submitter information, then do
|
||||
nothing.
|
||||
"""
|
||||
if self.submitter is None or self.submitter.email is None:
|
||||
logger.warning(
|
||||
"Cannot send status change (in review) email,"
|
||||
"no submitter email address."
|
||||
)
|
||||
return
|
||||
try:
|
||||
send_templated_email(
|
||||
"emails/status_change_in_review.txt",
|
||||
"emails/status_change_in_review_subject.txt",
|
||||
self.submitter.email,
|
||||
context={"application": self},
|
||||
)
|
||||
logging.info(f"In review email sent to: {self.submitter.email}")
|
||||
except EmailSendingError:
|
||||
logger.warning(
|
||||
"Failed to send status change (in review) email", exc_info=True
|
||||
)
|
||||
|
||||
@transition(field="status", source=[STARTED, WITHDRAWN], target=SUBMITTED)
|
||||
def submit(self):
|
||||
"""Submit an application that is started."""
|
||||
|
@ -541,6 +570,19 @@ class DomainApplication(TimeStampedModel):
|
|||
user=self.creator, domain=created_domain, role=UserDomainRole.Roles.ADMIN
|
||||
)
|
||||
|
||||
@transition(field="status", source=SUBMITTED, target=INVESTIGATING)
|
||||
def in_review(self, updated_domain_application):
|
||||
"""Investigate an application that has been submitted.
|
||||
|
||||
This method is called in admin.py on the original application
|
||||
which has the correct status value, but is passed the changed
|
||||
application which has the up-to-date data that we'll use
|
||||
in the email."""
|
||||
|
||||
# When an application is moved to in review, we need to send a
|
||||
# confirmation email. This is a side-effect of the state transition
|
||||
updated_domain_application._send_in_review_email()
|
||||
|
||||
@transition(field="status", source=[SUBMITTED, INVESTIGATING], target=WITHDRAWN)
|
||||
def withdraw(self):
|
||||
"""Withdraw an application that has been submitted."""
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
<ul class="usa-nav__primary usa-accordion">
|
||||
<li class="usa-nav__primary-item">
|
||||
{% if user.is_authenticated %}
|
||||
<a href="{% url 'whoami' %}"><span>{{ user.email }}</span></a>
|
||||
<span>{{ user.email }}</span>
|
||||
</li>
|
||||
<li class="usa-nav__primary-item display-flex flex-align-center">
|
||||
<span class="text-base"> | </span>
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
SUMMARY OF YOUR DOMAIN REQUEST
|
||||
|
||||
Type of organization:
|
||||
{{ application.get_organization_type_display }}
|
||||
|
||||
Organization name and mailing address:
|
||||
{% spaceless %}{{ application.organization_name }}
|
||||
{{ application.address_line1 }}{% if application.address_line2 %}
|
||||
{{ application.address_line2 }}{% endif %}
|
||||
{{ application.city }}, {{ application.state_territory }}
|
||||
{{ application.zipcode }}{% if application.urbanization %}
|
||||
{{ application.urbanization }}{% endif %}{% endspaceless %}
|
||||
{% if application.type_of_work %}{# if block makes one newline if it's false #}
|
||||
Type of work:
|
||||
{% spaceless %}{{ application.type_of_work }}{% endspaceless %}
|
||||
{% endif %}
|
||||
Authorizing official:
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=application.authorizing_official %}{% endspaceless %}
|
||||
{% if application.current_websites.exists %}{# if block makes a newline #}
|
||||
Current website for your organization: {% for site in application.current_websites.all %}
|
||||
{% spaceless %}{{ site.website }}{% endspaceless %}
|
||||
{% endfor %}{% endif %}
|
||||
.gov domain:
|
||||
{{ application.requested_domain.name }}
|
||||
{% for site in application.alternative_domains.all %}{% spaceless %}{{ site.website }}{% endspaceless %}
|
||||
{% endfor %}
|
||||
Purpose of your domain:
|
||||
{{ application.purpose }}
|
||||
|
||||
Your contact information:
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=application.submitter %}{% endspaceless %}
|
||||
{% if application.other_contacts.all %}
|
||||
Other employees from your organization:
|
||||
{% for other in application.other_contacts.all %}
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=other %}{% endspaceless %}
|
||||
{% endfor %}{% endif %}{% if application.anything_else %}
|
||||
Anything else we should know?
|
||||
{{ application.anything_else }}
|
||||
{% endif %}
|
43
src/registrar/templates/emails/status_change_in_review.txt
Normal file
43
src/registrar/templates/emails/status_change_in_review.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
Hi {{ application.submitter.first_name }}.
|
||||
|
||||
Your .gov domain request is being reviewed.
|
||||
|
||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ application.updated_at|date }}
|
||||
REQUEST #: {{ application.id }}
|
||||
STATUS: In review
|
||||
|
||||
|
||||
NEED TO MAKE CHANGES?
|
||||
|
||||
If you need to change your request you have to first withdraw it. Once you
|
||||
withdraw the request you can edit it and submit it again. Changing your request
|
||||
might add to the wait time. Learn more about withdrawing your request.
|
||||
<https://get.gov/help/domain-requests/#withdraw-your-domain-request>.
|
||||
|
||||
|
||||
NEXT STEPS
|
||||
|
||||
- We’re reviewing your request. This usually takes 20 business days.
|
||||
|
||||
- You can check the status of your request at any time.
|
||||
<https://registrar.get.gov/application/{{ application.id }}>
|
||||
|
||||
- We’ll email you with questions or when we complete our review.
|
||||
|
||||
|
||||
THANK YOU
|
||||
|
||||
.Gov helps the public identify official, trusted information. Thank you for
|
||||
requesting a .gov domain.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
{% include 'emails/includes/application_summary.txt' %}
|
||||
----------------------------------------------------------------
|
||||
|
||||
The .gov team
|
||||
Contact us: <https://get.gov/contact/>
|
||||
Visit <https://get.gov>
|
||||
{% endautoescape %}
|
|
@ -0,0 +1 @@
|
|||
Your .gov domain request is being reviewed
|
|
@ -33,45 +33,7 @@ requesting a .gov domain.
|
|||
|
||||
----------------------------------------------------------------
|
||||
|
||||
SUMMARY OF YOUR DOMAIN REQUEST
|
||||
|
||||
Type of organization:
|
||||
{{ application.get_organization_type_display }}
|
||||
|
||||
Organization name and mailing address:
|
||||
{% spaceless %}{{ application.organization_name }}
|
||||
{{ application.address_line1 }}{% if application.address_line2 %}
|
||||
{{ application.address_line2 }}{% endif %}
|
||||
{{ application.city }}, {{ application.state_territory }}
|
||||
{{ application.zipcode }}{% if application.urbanization %}
|
||||
{{ application.urbanization }}{% endif %}{% endspaceless %}
|
||||
{% if application.type_of_work %}{# if block makes one newline if it's false #}
|
||||
Type of work:
|
||||
{% spaceless %}{{ application.type_of_work }}{% endspaceless %}
|
||||
{% endif %}
|
||||
Authorizing official:
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=application.authorizing_official %}{% endspaceless %}
|
||||
{% if application.current_websites.exists %}{# if block makes a newline #}
|
||||
Current website for your organization: {% for site in application.current_websites.all %}
|
||||
{% spaceless %}{{ site.website }}{% endspaceless %}
|
||||
{% endfor %}{% endif %}
|
||||
.gov domain:
|
||||
{{ application.requested_domain.name }}
|
||||
{% for site in application.alternative_domains.all %}{% spaceless %}{{ site.website }}{% endspaceless %}
|
||||
{% endfor %}
|
||||
Purpose of your domain:
|
||||
{{ application.purpose }}
|
||||
|
||||
Your contact information:
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=application.submitter %}{% endspaceless %}
|
||||
{% if application.other_contacts.all %}
|
||||
Other employees from your organization:
|
||||
{% for other in application.other_contacts.all %}
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=other %}{% endspaceless %}
|
||||
{% endfor %}{% endif %}{% if application.anything_else %}
|
||||
Anything else we should know?
|
||||
{{ application.anything_else }}
|
||||
{% endif %}
|
||||
{% include 'emails/includes/application_summary.txt' %}
|
||||
----------------------------------------------------------------
|
||||
|
||||
The .gov team
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<p>Domain requests from state legislatures and courts must be authorized by an agency’s <strong>Chief Information Officer</strong> or <strong>highest-ranking executive</strong>.</p>
|
||||
|
||||
{% elif organization_type == 'tribal' %}
|
||||
<p>Domain requests from federally-recognized tribal governments must be authorized by the leader of the tribe, as recognized by the <a href="https://www.bia.gov/service/tribal-leaders-directory" class="usa-link">Bureau of Indian Affairs.</a></p>
|
||||
<p>Domain requests from state-recognized tribal governments must be authorized by the leader of the tribe, as determined by the state’s tribal recognition initiative.</p>
|
||||
<p><strong>Domain requests from federally-recognized tribal governments must be authorized by the leader of the tribe</strong>, as recognized by the <a href="https://www.bia.gov/service/tribal-leaders-directory" class="usa-link">Bureau of Indian Affairs.</a></p>
|
||||
<p><strong>Domain requests from state-recognized tribal governments must be authorized by the leader of the tribe</strong>, as determined by the state’s tribal recognition initiative.</p>
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %} Hello {% endblock %}
|
||||
{% block content %}
|
||||
<main id="main-content" class="grid-container">
|
||||
<p> Hello {{ user.last_name|default:"No last name given" }}, {{ user.first_name|default:"No first name given" }} <{{ user.email }}>! </p>
|
||||
|
||||
<p><a href="{% url 'logout' %}">Click here to log out</a></p>
|
||||
</main>
|
||||
{% endblock %}
|
|
@ -8,6 +8,8 @@ from typing import List, Dict
|
|||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model, login
|
||||
|
||||
from registrar.models import Contact, DraftDomain, Website, DomainApplication
|
||||
|
||||
|
||||
def get_handlers():
|
||||
"""Obtain pointers to all StreamHandlers."""
|
||||
|
@ -84,3 +86,74 @@ class MockSESClient(Mock):
|
|||
|
||||
def send_email(self, *args, **kwargs):
|
||||
self.EMAILS_SENT.append({"args": args, "kwargs": kwargs})
|
||||
|
||||
|
||||
def completed_application(
|
||||
has_other_contacts=True,
|
||||
has_current_website=True,
|
||||
has_alternative_gov_domain=True,
|
||||
has_type_of_work=True,
|
||||
has_anything_else=True,
|
||||
status=DomainApplication.STARTED,
|
||||
user=False,
|
||||
):
|
||||
"""A completed domain application."""
|
||||
if not user:
|
||||
user = get_user_model().objects.create(username="username")
|
||||
ao, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy",
|
||||
last_name="Tester",
|
||||
title="Chief Tester",
|
||||
email="testy@town.com",
|
||||
phone="(555) 555 5555",
|
||||
)
|
||||
domain, _ = DraftDomain.objects.get_or_create(name="city.gov")
|
||||
alt, _ = Website.objects.get_or_create(website="city1.gov")
|
||||
current, _ = Website.objects.get_or_create(website="city.com")
|
||||
you, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy you",
|
||||
last_name="Tester you",
|
||||
title="Admin Tester",
|
||||
email="mayor@igorville.gov",
|
||||
phone="(555) 555 5556",
|
||||
)
|
||||
other, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy2",
|
||||
last_name="Tester2",
|
||||
title="Another Tester",
|
||||
email="testy2@town.com",
|
||||
phone="(555) 555 5557",
|
||||
)
|
||||
domain_application_kwargs = dict(
|
||||
organization_type="federal",
|
||||
federal_type="executive",
|
||||
purpose="Purpose of the site",
|
||||
is_policy_acknowledged=True,
|
||||
organization_name="Testorg",
|
||||
address_line1="address 1",
|
||||
address_line2="address 2",
|
||||
state_territory="NY",
|
||||
zipcode="10002",
|
||||
authorizing_official=ao,
|
||||
requested_domain=domain,
|
||||
submitter=you,
|
||||
creator=user,
|
||||
status=status,
|
||||
)
|
||||
if has_type_of_work:
|
||||
domain_application_kwargs["type_of_work"] = "e-Government"
|
||||
if has_anything_else:
|
||||
domain_application_kwargs["anything_else"] = "There is more"
|
||||
|
||||
application, _ = DomainApplication.objects.get_or_create(
|
||||
**domain_application_kwargs
|
||||
)
|
||||
|
||||
if has_other_contacts:
|
||||
application.other_contacts.add(other)
|
||||
if has_current_website:
|
||||
application.current_websites.add(current)
|
||||
if has_alternative_gov_domain:
|
||||
application.alternative_domains.add(alt)
|
||||
|
||||
return application
|
||||
|
|
64
src/registrar/tests/test_admin.py
Normal file
64
src/registrar/tests/test_admin.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
from django.test import TestCase, RequestFactory
|
||||
from django.contrib.admin.sites import AdminSite
|
||||
from registrar.admin import DomainApplicationAdmin
|
||||
from registrar.models import DomainApplication, User
|
||||
from .common import completed_application
|
||||
|
||||
from django.conf import settings
|
||||
from unittest.mock import MagicMock
|
||||
import boto3_mocking # type: ignore
|
||||
|
||||
|
||||
class TestDomainApplicationAdmin(TestCase):
|
||||
def setUp(self):
|
||||
self.site = AdminSite()
|
||||
self.factory = RequestFactory()
|
||||
|
||||
@boto3_mocking.patching
|
||||
def test_save_model_sends_email_on_property_change(self):
|
||||
# make sure there is no user with this email
|
||||
EMAIL = "mayor@igorville.gov"
|
||||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client_instance = mock_client.return_value
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", mock_client):
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainApplication.SUBMITTED)
|
||||
|
||||
# Create a mock request
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domainapplication/{}/change/".format(application.pk)
|
||||
)
|
||||
|
||||
# Create an instance of the model admin
|
||||
model_admin = DomainApplicationAdmin(DomainApplication, self.site)
|
||||
|
||||
# Modify the application's property
|
||||
application.status = DomainApplication.INVESTIGATING
|
||||
|
||||
# Use the model admin's save_model method
|
||||
model_admin.save_model(request, application, form=None, change=True)
|
||||
|
||||
# Access the arguments passed to send_email
|
||||
call_args = mock_client_instance.send_email.call_args
|
||||
args, kwargs = call_args
|
||||
|
||||
# Retrieve the email details from the arguments
|
||||
from_email = kwargs.get("FromEmailAddress")
|
||||
to_email = kwargs["Destination"]["ToAddresses"][0]
|
||||
email_content = kwargs["Content"]
|
||||
email_body = email_content["Simple"]["Body"]["Text"]["Data"]
|
||||
|
||||
# Assert or perform other checks on the email details
|
||||
expected_string = "Your .gov domain request is being reviewed"
|
||||
self.assertEqual(from_email, settings.DEFAULT_FROM_EMAIL)
|
||||
self.assertEqual(to_email, EMAIL)
|
||||
self.assertIn(expected_string, email_body)
|
||||
|
||||
# Perform assertions on the mock call itself
|
||||
mock_client_instance.send_email.assert_called_once()
|
||||
|
||||
# Cleanup
|
||||
application.delete()
|
|
@ -2,82 +2,14 @@
|
|||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase
|
||||
from .common import completed_application
|
||||
|
||||
from registrar.models import Contact, DraftDomain, Website, DomainApplication
|
||||
|
||||
import boto3_mocking # type: ignore
|
||||
|
||||
|
||||
class TestEmails(TestCase):
|
||||
def _completed_application(
|
||||
self,
|
||||
has_other_contacts=True,
|
||||
has_current_website=True,
|
||||
has_alternative_gov_domain=True,
|
||||
has_type_of_work=True,
|
||||
has_anything_else=True,
|
||||
):
|
||||
"""A completed domain application."""
|
||||
user = get_user_model().objects.create(username="username")
|
||||
ao, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy",
|
||||
last_name="Tester",
|
||||
title="Chief Tester",
|
||||
email="testy@town.com",
|
||||
phone="(555) 555 5555",
|
||||
)
|
||||
domain, _ = DraftDomain.objects.get_or_create(name="city.gov")
|
||||
alt, _ = Website.objects.get_or_create(website="city1.gov")
|
||||
current, _ = Website.objects.get_or_create(website="city.com")
|
||||
you, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy you",
|
||||
last_name="Tester you",
|
||||
title="Admin Tester",
|
||||
email="testy-admin@town.com",
|
||||
phone="(555) 555 5556",
|
||||
)
|
||||
other, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy2",
|
||||
last_name="Tester2",
|
||||
title="Another Tester",
|
||||
email="testy2@town.com",
|
||||
phone="(555) 555 5557",
|
||||
)
|
||||
domain_application_kwargs = dict(
|
||||
organization_type="federal",
|
||||
federal_type="executive",
|
||||
purpose="Purpose of the site",
|
||||
is_policy_acknowledged=True,
|
||||
organization_name="Testorg",
|
||||
address_line1="address 1",
|
||||
address_line2="address 2",
|
||||
state_territory="NY",
|
||||
zipcode="10002",
|
||||
authorizing_official=ao,
|
||||
requested_domain=domain,
|
||||
submitter=you,
|
||||
creator=user,
|
||||
)
|
||||
if has_type_of_work:
|
||||
domain_application_kwargs["type_of_work"] = "e-Government"
|
||||
if has_anything_else:
|
||||
domain_application_kwargs["anything_else"] = "There is more"
|
||||
|
||||
application, _ = DomainApplication.objects.get_or_create(
|
||||
**domain_application_kwargs
|
||||
)
|
||||
|
||||
if has_other_contacts:
|
||||
application.other_contacts.add(other)
|
||||
if has_current_website:
|
||||
application.current_websites.add(current)
|
||||
if has_alternative_gov_domain:
|
||||
application.alternative_domains.add(alt)
|
||||
|
||||
return application
|
||||
|
||||
def setUp(self):
|
||||
self.mock_client_class = MagicMock()
|
||||
self.mock_client = self.mock_client_class.return_value
|
||||
|
@ -85,7 +17,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation(self):
|
||||
"""Submission confirmation email works."""
|
||||
application = self._completed_application()
|
||||
application = completed_application()
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
|
@ -122,7 +54,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_current_website_spacing(self):
|
||||
"""Test line spacing without current_website."""
|
||||
application = self._completed_application(has_current_website=False)
|
||||
application = completed_application(has_current_website=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -134,7 +66,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_current_website_spacing(self):
|
||||
"""Test line spacing with current_website."""
|
||||
application = self._completed_application(has_current_website=True)
|
||||
application = completed_application(has_current_website=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -147,7 +79,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_other_contacts_spacing(self):
|
||||
"""Test line spacing with other contacts."""
|
||||
application = self._completed_application(has_other_contacts=True)
|
||||
application = completed_application(has_other_contacts=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -160,7 +92,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_other_contacts_spacing(self):
|
||||
"""Test line spacing without other contacts."""
|
||||
application = self._completed_application(has_other_contacts=False)
|
||||
application = completed_application(has_other_contacts=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -172,7 +104,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_alternative_govdomain_spacing(self):
|
||||
"""Test line spacing with alternative .gov domain."""
|
||||
application = self._completed_application(has_alternative_gov_domain=True)
|
||||
application = completed_application(has_alternative_gov_domain=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -184,7 +116,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_alternative_govdomain_spacing(self):
|
||||
"""Test line spacing without alternative .gov domain."""
|
||||
application = self._completed_application(has_alternative_gov_domain=False)
|
||||
application = completed_application(has_alternative_gov_domain=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -196,7 +128,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_type_of_work_spacing(self):
|
||||
"""Test line spacing with type of work."""
|
||||
application = self._completed_application(has_type_of_work=True)
|
||||
application = completed_application(has_type_of_work=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -208,7 +140,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_type_of_work_spacing(self):
|
||||
"""Test line spacing without type of work."""
|
||||
application = self._completed_application(has_type_of_work=False)
|
||||
application = completed_application(has_type_of_work=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -220,7 +152,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_anything_else_spacing(self):
|
||||
"""Test line spacing with anything else."""
|
||||
application = self._completed_application(has_anything_else=True)
|
||||
application = completed_application(has_anything_else=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
@ -231,7 +163,7 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_anything_else_spacing(self):
|
||||
"""Test line spacing without anything else."""
|
||||
application = self._completed_application(has_anything_else=False)
|
||||
application = completed_application(has_anything_else=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
application.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.conf import settings
|
|||
from django.test import Client, TestCase
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth import get_user_model
|
||||
from .common import completed_application
|
||||
|
||||
from django_webtest import WebTest # type: ignore
|
||||
import boto3_mocking # type: ignore
|
||||
|
@ -39,12 +40,6 @@ class TestViews(TestCase):
|
|||
response = self.client.get("/")
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def test_whoami_page_no_user(self):
|
||||
"""Whoami page not accessible without a logged-in user."""
|
||||
response = self.client.get("/whoami/")
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertIn("?next=/whoami/", response.headers["Location"])
|
||||
|
||||
def test_application_form_not_logged_in(self):
|
||||
"""Application form not accessible without a logged-in user."""
|
||||
response = self.client.get("/register/")
|
||||
|
@ -99,13 +94,6 @@ class LoggedInTests(TestWithUser):
|
|||
# clean up
|
||||
role.delete()
|
||||
|
||||
def test_whoami_page(self):
|
||||
"""User information appears on the whoami page."""
|
||||
response = self.client.get("/whoami/")
|
||||
self.assertContains(response, self.user.first_name)
|
||||
self.assertContains(response, self.user.last_name)
|
||||
self.assertContains(response, self.user.email)
|
||||
|
||||
def test_application_form_view(self):
|
||||
response = self.client.get("/register/", follow=True)
|
||||
self.assertContains(
|
||||
|
@ -1407,85 +1395,18 @@ class TestApplicationStatus(TestWithUser, WebTest):
|
|||
self.app.set_user(self.user.username)
|
||||
self.client.force_login(self.user)
|
||||
|
||||
def _completed_application(
|
||||
self,
|
||||
has_other_contacts=True,
|
||||
has_current_website=True,
|
||||
has_alternative_gov_domain=True,
|
||||
has_type_of_work=True,
|
||||
has_anything_else=True,
|
||||
):
|
||||
"""A completed domain application."""
|
||||
ao, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy",
|
||||
last_name="Tester",
|
||||
title="Chief Tester",
|
||||
email="testy@town.com",
|
||||
phone="(555) 555 5555",
|
||||
)
|
||||
domain, _ = DraftDomain.objects.get_or_create(name="citystatus.gov")
|
||||
alt, _ = Website.objects.get_or_create(website="city1.gov")
|
||||
current, _ = Website.objects.get_or_create(website="city.com")
|
||||
you, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy you",
|
||||
last_name="Tester you",
|
||||
title="Admin Tester",
|
||||
email="testy-admin@town.com",
|
||||
phone="(555) 555 5556",
|
||||
)
|
||||
other, _ = Contact.objects.get_or_create(
|
||||
first_name="Testy2",
|
||||
last_name="Tester2",
|
||||
title="Another Tester",
|
||||
email="testy2@town.com",
|
||||
phone="(555) 555 5557",
|
||||
)
|
||||
domain_application_kwargs = dict(
|
||||
organization_type="federal",
|
||||
federal_type="executive",
|
||||
purpose="Purpose of the site",
|
||||
is_policy_acknowledged=True,
|
||||
organization_name="Testorg",
|
||||
address_line1="address 1",
|
||||
address_line2="address 2",
|
||||
state_territory="NY",
|
||||
zipcode="10002",
|
||||
authorizing_official=ao,
|
||||
requested_domain=domain,
|
||||
submitter=you,
|
||||
creator=self.user,
|
||||
)
|
||||
if has_type_of_work:
|
||||
domain_application_kwargs["type_of_work"] = "e-Government"
|
||||
if has_anything_else:
|
||||
domain_application_kwargs["anything_else"] = "There is more"
|
||||
|
||||
application, _ = DomainApplication.objects.get_or_create(
|
||||
**domain_application_kwargs
|
||||
)
|
||||
|
||||
application.status = DomainApplication.SUBMITTED
|
||||
application.save()
|
||||
|
||||
if has_other_contacts:
|
||||
application.other_contacts.add(other)
|
||||
if has_current_website:
|
||||
application.current_websites.add(current)
|
||||
if has_alternative_gov_domain:
|
||||
application.alternative_domains.add(alt)
|
||||
|
||||
return application
|
||||
|
||||
def test_application_status(self):
|
||||
"""Checking application status page"""
|
||||
application = self._completed_application()
|
||||
application = completed_application(
|
||||
status=DomainApplication.SUBMITTED, user=self.user
|
||||
)
|
||||
application.save()
|
||||
|
||||
home_page = self.app.get("/")
|
||||
self.assertContains(home_page, "citystatus.gov")
|
||||
self.assertContains(home_page, "city.gov")
|
||||
# click the "Manage" link
|
||||
detail_page = home_page.click("Manage")
|
||||
self.assertContains(detail_page, "citystatus.gov")
|
||||
self.assertContains(detail_page, "city.gov")
|
||||
self.assertContains(detail_page, "Chief Tester")
|
||||
self.assertContains(detail_page, "testy@town.com")
|
||||
self.assertContains(detail_page, "Admin Tester")
|
||||
|
@ -1493,14 +1414,16 @@ class TestApplicationStatus(TestWithUser, WebTest):
|
|||
|
||||
def test_application_withdraw(self):
|
||||
"""Checking application status page"""
|
||||
application = self._completed_application()
|
||||
application = completed_application(
|
||||
status=DomainApplication.SUBMITTED, user=self.user
|
||||
)
|
||||
application.save()
|
||||
|
||||
home_page = self.app.get("/")
|
||||
self.assertContains(home_page, "citystatus.gov")
|
||||
self.assertContains(home_page, "city.gov")
|
||||
# click the "Manage" link
|
||||
detail_page = home_page.click("Manage")
|
||||
self.assertContains(detail_page, "citystatus.gov")
|
||||
self.assertContains(detail_page, "city.gov")
|
||||
self.assertContains(detail_page, "Chief Tester")
|
||||
self.assertContains(detail_page, "testy@town.com")
|
||||
self.assertContains(detail_page, "Admin Tester")
|
||||
|
@ -1522,7 +1445,9 @@ class TestApplicationStatus(TestWithUser, WebTest):
|
|||
|
||||
def test_application_status_no_permissions(self):
|
||||
"""Can't access applications without being the creator."""
|
||||
application = self._completed_application()
|
||||
application = completed_application(
|
||||
status=DomainApplication.SUBMITTED, user=self.user
|
||||
)
|
||||
other_user = User()
|
||||
other_user.save()
|
||||
application.creator = other_user
|
||||
|
|
|
@ -12,4 +12,3 @@ from .domain import (
|
|||
)
|
||||
from .health import *
|
||||
from .index import *
|
||||
from .whoami import *
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
from django.shortcuts import render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
|
||||
@login_required
|
||||
def whoami(request):
|
||||
"""This is the first page someone goes to after logging in."""
|
||||
return render(request, "whoami.html")
|
Loading…
Add table
Add a link
Reference in a new issue