mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-24 19:48:36 +02:00
merge
This commit is contained in:
commit
dcda5d026a
23 changed files with 270 additions and 136 deletions
|
@ -29,7 +29,7 @@ DOMAIN_API_MESSAGES = {
|
||||||
"unavailable": mark_safe( # nosec
|
"unavailable": mark_safe( # nosec
|
||||||
"That domain isn’t available. "
|
"That domain isn’t available. "
|
||||||
"<a class='usa-link' href='{}' target='_blank'>"
|
"<a class='usa-link' href='{}' target='_blank'>"
|
||||||
"Read more about choosing your .gov domain.</a>".format(public_site_url("domains/choosing"))
|
"Read more about choosing your .gov domain</a>.".format(public_site_url("domains/choosing"))
|
||||||
),
|
),
|
||||||
"invalid": "Enter a domain using only letters, numbers, or hyphens (though we don't recommend using hyphens).",
|
"invalid": "Enter a domain using only letters, numbers, or hyphens (though we don't recommend using hyphens).",
|
||||||
"success": "That domain is available! We’ll try to give you the domain you want, \
|
"success": "That domain is available! We’ll try to give you the domain you want, \
|
||||||
|
|
|
@ -51,7 +51,7 @@ class ViewsTest(TestCase):
|
||||||
# assert
|
# assert
|
||||||
self.assertEqual(response.status_code, 500)
|
self.assertEqual(response.status_code, 500)
|
||||||
self.assertTemplateUsed(response, "500.html")
|
self.assertTemplateUsed(response, "500.html")
|
||||||
self.assertIn("server error", response.content.decode("utf-8"))
|
self.assertIn("Server error", response.content.decode("utf-8"))
|
||||||
|
|
||||||
def test_login_callback_reads_next(self, mock_client):
|
def test_login_callback_reads_next(self, mock_client):
|
||||||
# setup
|
# setup
|
||||||
|
|
|
@ -1251,7 +1251,7 @@ admin.site.register(models.DomainInformation, DomainInformationAdmin)
|
||||||
admin.site.register(models.Domain, DomainAdmin)
|
admin.site.register(models.Domain, DomainAdmin)
|
||||||
admin.site.register(models.DraftDomain, DraftDomainAdmin)
|
admin.site.register(models.DraftDomain, DraftDomainAdmin)
|
||||||
# Host and HostIP removed from django admin because changes in admin
|
# Host and HostIP removed from django admin because changes in admin
|
||||||
# do not propogate to registry and logic not applied
|
# do not propagate to registry and logic not applied
|
||||||
# admin.site.register(models.Host, MyHostAdmin)
|
# admin.site.register(models.Host, MyHostAdmin)
|
||||||
admin.site.register(models.Website, WebsiteAdmin)
|
admin.site.register(models.Website, WebsiteAdmin)
|
||||||
admin.site.register(models.PublicContact, AuditedAdmin)
|
admin.site.register(models.PublicContact, AuditedAdmin)
|
||||||
|
|
|
@ -345,30 +345,6 @@ function markForm(e, formLabel){
|
||||||
|
|
||||||
// Set display to 'none'
|
// Set display to 'none'
|
||||||
formToRemove.style.display = 'none';
|
formToRemove.style.display = 'none';
|
||||||
|
|
||||||
//
|
|
||||||
// This next block is a hack to fix a page jump when a fielset is set to display none at the start of the formset but still takes
|
|
||||||
// a bit of space in the DOM, causing the content to jump down a bit
|
|
||||||
//
|
|
||||||
// Get the first hidden fieldset
|
|
||||||
const hiddenFieldset = document.querySelector('.repeatable-form[style="display: none;"]');
|
|
||||||
let targetFieldset = null;
|
|
||||||
// If that first hidden fieldset does not have any sibling out of all the previous siblings that's visible, get the next visible fieldset
|
|
||||||
if (hiddenFieldset && !hiddenFieldset.previousElementSibling.matches('.repeatable-form:not([style="display: none;"])')) {
|
|
||||||
let currentSibling = hiddenFieldset.nextElementSibling;
|
|
||||||
// Iterate through siblings until a visible fieldset is found
|
|
||||||
while (currentSibling) {
|
|
||||||
if (currentSibling.matches(':not([style="display: none;"])')) {
|
|
||||||
targetFieldset = currentSibling;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentSibling = currentSibling.nextElementSibling;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (targetFieldset) {
|
|
||||||
// Account for the space the hidden fieldsets at the top of the formset are occupying in the DOM
|
|
||||||
targetFieldset.querySelector('h2').style.marginTop = '1rem';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update h2s on the visible forms only. We won't worry about the forms' identifiers
|
// Update h2s on the visible forms only. We won't worry about the forms' identifiers
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
.sr-only {
|
.sr-only {
|
||||||
@include sr-only;
|
@include sr-only;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clear-both {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
|
|
|
@ -31,3 +31,10 @@
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
legend.float-left-tablet + button.float-right-tablet {
|
||||||
|
margin-top: .5rem;
|
||||||
|
@include at-media('tablet') {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ from registrar.utility import errors
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class RegistrarForm(forms.Form):
|
class RegistrarForm(forms.Form):
|
||||||
"""
|
"""
|
||||||
A common set of methods and configuration.
|
A common set of methods and configuration.
|
||||||
|
@ -94,14 +95,14 @@ class RegistrarFormSet(forms.BaseFormSet):
|
||||||
Hint: Subclass should call `self._to_database(...)`.
|
Hint: Subclass should call `self._to_database(...)`.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def test_if_more_than_one_join(self, db_obj, rel, related_name):
|
def test_if_more_than_one_join(self, db_obj, rel, related_name):
|
||||||
"""Helper for finding whether an object is joined more than once."""
|
"""Helper for finding whether an object is joined more than once."""
|
||||||
# threshold is the number of related objects that are acceptable
|
# threshold is the number of related objects that are acceptable
|
||||||
# when determining if related objects exist. threshold is 0 for most
|
# when determining if related objects exist. threshold is 0 for most
|
||||||
# relationships. if the relationship is related_name, we know that
|
# relationships. if the relationship is related_name, we know that
|
||||||
# there is already exactly 1 acceptable relationship (the one we are
|
# there is already exactly 1 acceptable relationship (the one we are
|
||||||
# attempting to delete), so the threshold is 1
|
# attempting to delete), so the threshold is 1
|
||||||
threshold = 1 if rel == related_name else 0
|
threshold = 1 if rel == related_name else 0
|
||||||
|
|
||||||
# Raise a KeyError if rel is not a defined field on the db_obj model
|
# Raise a KeyError if rel is not a defined field on the db_obj model
|
||||||
|
@ -305,7 +306,7 @@ class OrganizationContactForm(RegistrarForm):
|
||||||
validators=[
|
validators=[
|
||||||
RegexValidator(
|
RegexValidator(
|
||||||
"^[0-9]{5}(?:-[0-9]{4})?$|^$",
|
"^[0-9]{5}(?:-[0-9]{4})?$|^$",
|
||||||
message="Enter a zip code in the required format, like 12345 or 12345-6789.",
|
message="Enter a zip code in the form of 12345 or 12345-6789.",
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -396,7 +397,7 @@ class CurrentSitesForm(RegistrarForm):
|
||||||
required=False,
|
required=False,
|
||||||
label="Public website",
|
label="Public website",
|
||||||
error_messages={
|
error_messages={
|
||||||
"invalid": ("Enter your organization’s current website in the required format, like www.city.com.")
|
"invalid": ("Enter your organization's current website in the required format, like example.com.")
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -590,7 +591,7 @@ class YourContactForm(RegistrarForm):
|
||||||
)
|
)
|
||||||
phone = PhoneNumberField(
|
phone = PhoneNumberField(
|
||||||
label="Phone",
|
label="Phone",
|
||||||
error_messages={"required": "Enter your phone number."},
|
error_messages={"invalid": "Enter a valid 10-digit phone number.", "required": "Enter your phone number."},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -640,12 +641,15 @@ class OtherContactsForm(RegistrarForm):
|
||||||
label="Email",
|
label="Email",
|
||||||
error_messages={
|
error_messages={
|
||||||
"required": ("Enter an email address in the required format, like name@example.com."),
|
"required": ("Enter an email address in the required format, like name@example.com."),
|
||||||
"invalid": ("Enter an email address in the required format, like name@example.com.")
|
"invalid": ("Enter an email address in the required format, like name@example.com."),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
phone = PhoneNumberField(
|
phone = PhoneNumberField(
|
||||||
label="Phone",
|
label="Phone",
|
||||||
error_messages={"required": "Enter a phone number for this contact."},
|
error_messages={
|
||||||
|
"invalid": "Enter a valid 10-digit phone number.",
|
||||||
|
"required": "Enter a phone number for this contact.",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -659,7 +663,7 @@ class OtherContactsForm(RegistrarForm):
|
||||||
"""
|
"""
|
||||||
self.form_data_marked_for_deletion = False
|
self.form_data_marked_for_deletion = False
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.empty_permitted=False
|
self.empty_permitted = False
|
||||||
|
|
||||||
def mark_form_for_deletion(self):
|
def mark_form_for_deletion(self):
|
||||||
self.form_data_marked_for_deletion = True
|
self.form_data_marked_for_deletion = True
|
||||||
|
@ -668,11 +672,11 @@ class OtherContactsForm(RegistrarForm):
|
||||||
"""
|
"""
|
||||||
This method overrides the default behavior for forms.
|
This method overrides the default behavior for forms.
|
||||||
This cleans the form after field validation has already taken place.
|
This cleans the form after field validation has already taken place.
|
||||||
In this override, allow for a form which is deleted by user or marked for
|
In this override, allow for a form which is deleted by user or marked for
|
||||||
deletion by formset to be considered valid even though certain required fields have
|
deletion by formset to be considered valid even though certain required fields have
|
||||||
not passed field validation
|
not passed field validation
|
||||||
"""
|
"""
|
||||||
if self.form_data_marked_for_deletion or self.cleaned_data["DELETE"]:
|
if self.form_data_marked_for_deletion or self.cleaned_data.get("DELETE"):
|
||||||
# clear any errors raised by the form fields
|
# clear any errors raised by the form fields
|
||||||
# (before this clean() method is run, each field
|
# (before this clean() method is run, each field
|
||||||
# performs its own clean, which could result in
|
# performs its own clean, which could result in
|
||||||
|
@ -694,9 +698,9 @@ class OtherContactsForm(RegistrarForm):
|
||||||
class BaseOtherContactsFormSet(RegistrarFormSet):
|
class BaseOtherContactsFormSet(RegistrarFormSet):
|
||||||
"""
|
"""
|
||||||
FormSet for Other Contacts
|
FormSet for Other Contacts
|
||||||
|
|
||||||
There are two conditions by which a form in the formset can be marked for deletion.
|
There are two conditions by which a form in the formset can be marked for deletion.
|
||||||
One is if the user clicks 'DELETE' button, and this is submitted in the form. The
|
One is if the user clicks 'DELETE' button, and this is submitted in the form. The
|
||||||
other is if the YesNo form, which is submitted with this formset, is set to No; in
|
other is if the YesNo form, which is submitted with this formset, is set to No; in
|
||||||
this case, all forms in formset are marked for deletion. Both of these conditions
|
this case, all forms in formset are marked for deletion. Both of these conditions
|
||||||
must co-exist.
|
must co-exist.
|
||||||
|
@ -705,6 +709,7 @@ class BaseOtherContactsFormSet(RegistrarFormSet):
|
||||||
tested and handled; this is configured with REVERSE_JOINS, which is an array of
|
tested and handled; this is configured with REVERSE_JOINS, which is an array of
|
||||||
strings representing the relationships between contact model and other models.
|
strings representing the relationships between contact model and other models.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
JOIN = "other_contacts"
|
JOIN = "other_contacts"
|
||||||
REVERSE_JOINS = [
|
REVERSE_JOINS = [
|
||||||
"user",
|
"user",
|
||||||
|
@ -718,7 +723,7 @@ class BaseOtherContactsFormSet(RegistrarFormSet):
|
||||||
|
|
||||||
def get_deletion_widget(self):
|
def get_deletion_widget(self):
|
||||||
return forms.HiddenInput(attrs={"class": "deletion"})
|
return forms.HiddenInput(attrs={"class": "deletion"})
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Override __init__ for RegistrarFormSet.
|
Override __init__ for RegistrarFormSet.
|
||||||
|
@ -737,14 +742,14 @@ class BaseOtherContactsFormSet(RegistrarFormSet):
|
||||||
Implements should_delete method from BaseFormSet.
|
Implements should_delete method from BaseFormSet.
|
||||||
"""
|
"""
|
||||||
return self.formset_data_marked_for_deletion or cleaned.get("DELETE", False)
|
return self.formset_data_marked_for_deletion or cleaned.get("DELETE", False)
|
||||||
|
|
||||||
def pre_create(self, db_obj, cleaned):
|
def pre_create(self, db_obj, cleaned):
|
||||||
"""Code to run before an item in the formset is created in the database."""
|
"""Code to run before an item in the formset is created in the database."""
|
||||||
# remove DELETE from cleaned
|
# remove DELETE from cleaned
|
||||||
if "DELETE" in cleaned:
|
if "DELETE" in cleaned:
|
||||||
cleaned.pop('DELETE')
|
cleaned.pop("DELETE")
|
||||||
return cleaned
|
return cleaned
|
||||||
|
|
||||||
def to_database(self, obj: DomainApplication):
|
def to_database(self, obj: DomainApplication):
|
||||||
self._to_database(obj, self.JOIN, self.REVERSE_JOINS, self.should_delete, self.pre_update, self.pre_create)
|
self._to_database(obj, self.JOIN, self.REVERSE_JOINS, self.should_delete, self.pre_update, self.pre_create)
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ class DomainNameserverForm(forms.Form):
|
||||||
# add custom error messages
|
# add custom error messages
|
||||||
self.fields["server"].error_messages.update(
|
self.fields["server"].error_messages.update(
|
||||||
{
|
{
|
||||||
"required": "A minimum of 2 name servers are required.",
|
"required": "At least two name servers are required.",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
<div class="grid-row grow-gap">
|
<div class="grid-row grow-gap">
|
||||||
<div class="tablet:grid-col-6 usa-prose margin-bottom-3">
|
<div class="tablet:grid-col-6 usa-prose margin-bottom-3">
|
||||||
<h1>
|
<h1>
|
||||||
{% translate "You do not have the right permissions to view this page." %}
|
{% translate "You're not authorized to view this page." %}
|
||||||
</h1>
|
</h1>
|
||||||
<h2>
|
<h2>
|
||||||
{% translate "Status 403" %}
|
{% translate "403 error" %}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p>
|
<p>
|
||||||
You must be an authorized user and need to be signed in to view this page.
|
You must be an authorized user and need to be signed in to view this page.
|
||||||
<a href="{% url 'login' %}"> Try logging in again</a>.
|
<a href="{% url 'login' %}"> Try signing in again</a>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If you'd like help with this error <a class="usa-link" rel="noopener noreferrer" target="_blank" href="{% public_site_url 'contact' %}">contact us</a>.
|
If you'd like help with this error <a class="usa-link" rel="noopener noreferrer" target="_blank" href="{% public_site_url 'contact' %}">contact us</a>.
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
<div class="grid-row grid-gap">
|
<div class="grid-row grid-gap">
|
||||||
<div class="tablet:grid-col-6 usa-prose margin-bottom-3">
|
<div class="tablet:grid-col-6 usa-prose margin-bottom-3">
|
||||||
<h1>
|
<h1>
|
||||||
{% translate "We're having some trouble" %}
|
{% translate "We're having some trouble." %}
|
||||||
</h1>
|
</h1>
|
||||||
<h2>
|
<h2>
|
||||||
{% translate "Status 500 – server error" %}
|
{% translate "500 error" %}
|
||||||
</h2>
|
</h2>
|
||||||
{% if friendly_message %}
|
{% if friendly_message %}
|
||||||
<p>{{ friendly_message }}</p>
|
<p>{{ friendly_message }}</p>
|
||||||
|
|
|
@ -34,31 +34,26 @@
|
||||||
{{ forms.1.management_form }}
|
{{ forms.1.management_form }}
|
||||||
{# forms.1 is a formset and this iterates over its forms #}
|
{# forms.1 is a formset and this iterates over its forms #}
|
||||||
{% for form in forms.1.forms %}
|
{% for form in forms.1.forms %}
|
||||||
<fieldset class="usa-fieldset repeatable-form">
|
<fieldset class="usa-fieldset repeatable-form padding-y-1">
|
||||||
|
|
||||||
<div class="grid-row grid-gap-2 flex-end">
|
<legend class="float-left-tablet">
|
||||||
|
<h2 class="margin-top-1">Organization contact {{ forloop.counter }}</h2>
|
||||||
|
</legend>
|
||||||
|
|
||||||
<div class="tablet:grid-col-8">
|
<button type="button" class="usa-button usa-button--unstyled display-block float-right-tablet delete-record margin-bottom-2">
|
||||||
<legend>
|
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
||||||
<h2>Organization contact {{ forloop.counter }}</h2>
|
<use xlink:href="{%static 'img/sprite.svg'%}#delete"></use>
|
||||||
</legend>
|
</svg><span class="margin-left-05">Delete</span>
|
||||||
</div>
|
</button>
|
||||||
|
|
||||||
<div class="tablet:grid-col-4">
|
|
||||||
<button type="button" class="usa-button usa-button--unstyled display-block float-right-tablet delete-record margin-bottom-2">
|
|
||||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
|
||||||
<use xlink:href="{%static 'img/sprite.svg'%}#delete"></use>
|
|
||||||
</svg><span class="margin-left-05">Delete</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if forms.1.can_delete %}
|
{% if forms.1.can_delete %}
|
||||||
{{ form.DELETE }}
|
{{ form.DELETE }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% input_with_errors form.first_name %}
|
<div class="padding-top-1 clear-both">
|
||||||
|
{% input_with_errors form.first_name %}
|
||||||
|
</div>
|
||||||
|
|
||||||
{% input_with_errors form.middle_name %}
|
{% input_with_errors form.middle_name %}
|
||||||
|
|
||||||
|
@ -71,11 +66,11 @@
|
||||||
affecting the margin of this block. The wrapper div is a
|
affecting the margin of this block. The wrapper div is a
|
||||||
temporary workaround. {% endcomment %}
|
temporary workaround. {% endcomment %}
|
||||||
<div class="margin-top-3">
|
<div class="margin-top-3">
|
||||||
{% input_with_errors form.email %}
|
{% input_with_errors form.email %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% with add_class="usa-input--medium" %}
|
{% with add_class="usa-input--medium" %}
|
||||||
{% input_with_errors form.phone %}
|
{% input_with_errors form.phone %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -89,12 +84,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="no-other-employees">
|
<div id="no-other-employees">
|
||||||
{% include "includes/required_fields.html" %}
|
|
||||||
<fieldset class="usa-fieldset margin-top-2">
|
<fieldset class="usa-fieldset margin-top-2">
|
||||||
<legend>
|
<legend>
|
||||||
<h2>No other employees from your organization?</h2>
|
<h2>No other employees from your organization?</h2>
|
||||||
</legend>
|
</legend>
|
||||||
{% with attr_maxlength=1000 %}
|
{% with attr_maxlength=1000 add_label_class="usa-sr-only" %}
|
||||||
{% input_with_errors forms.2.no_other_contacts_rationale %}
|
{% input_with_errors forms.2.no_other_contacts_rationale %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -114,7 +114,7 @@
|
||||||
aria-describedby="Your DNSSEC records will be deleted from the registry."
|
aria-describedby="Your DNSSEC records will be deleted from the registry."
|
||||||
data-force-action
|
data-force-action
|
||||||
>
|
>
|
||||||
{% include 'includes/modal.html' with cancel_button_resets_ds_form=True modal_heading="Warning: You are about to remove all DS records on your domain" modal_description="To fully disable DNSSEC: In addition to removing your DS records here you’ll also need to delete the DS records at your DNS host. To avoid causing your domain to appear offline you should wait to delete your DS records at your DNS host until the Time to Live (TTL) expires. This is often less than 24 hours, but confirm with your provider." modal_button=modal_button|safe %}
|
{% include 'includes/modal.html' with cancel_button_resets_ds_form=True modal_heading="Warning: You are about to remove all DS records on your domain." modal_description="To fully disable DNSSEC: In addition to removing your DS records here, you’ll need to delete the DS records at your DNS host. To avoid causing your domain to appear offline, you should wait to delete your DS records at your DNS host until the Time to Live (TTL) expires. This is often less than 24 hours, but confirm with your provider." modal_button=modal_button|safe %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %} {# domain_content #}
|
{% endblock %} {# domain_content #}
|
||||||
|
|
|
@ -4,7 +4,7 @@ Hi {{ application.submitter.first_name }}.
|
||||||
We've identified an action needed to complete the review of your .gov domain request.
|
We've identified an action needed to complete the review of your .gov domain request.
|
||||||
|
|
||||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||||
REQUEST RECEIVED ON: {{ application.updated_at|date }}
|
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||||
REQUEST #: {{ application.id }}
|
REQUEST #: {{ application.id }}
|
||||||
STATUS: Action needed
|
STATUS: Action needed
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ Hi {{ application.submitter.first_name }}.
|
||||||
Congratulations! Your .gov domain request has been approved.
|
Congratulations! Your .gov domain request has been approved.
|
||||||
|
|
||||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||||
REQUEST RECEIVED ON: {{ application.updated_at|date }}
|
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||||
REQUEST #: {{ application.id }}
|
REQUEST #: {{ application.id }}
|
||||||
STATUS: In review
|
STATUS: In review
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ Hi {{ application.submitter.first_name }}.
|
||||||
Your .gov domain request is being reviewed.
|
Your .gov domain request is being reviewed.
|
||||||
|
|
||||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||||
REQUEST RECEIVED ON: {{ application.updated_at|date }}
|
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||||
REQUEST #: {{ application.id }}
|
REQUEST #: {{ application.id }}
|
||||||
STATUS: In review
|
STATUS: In review
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ Hi {{ application.submitter.first_name }}.
|
||||||
Your .gov domain request has been rejected.
|
Your .gov domain request has been rejected.
|
||||||
|
|
||||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||||
REQUEST RECEIVED ON: {{ application.updated_at|date }}
|
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||||
REQUEST #: {{ application.id }}
|
REQUEST #: {{ application.id }}
|
||||||
STATUS: Rejected
|
STATUS: Rejected
|
||||||
|
|
||||||
|
@ -29,4 +29,4 @@ requesting a .gov domain.
|
||||||
The .gov team
|
The .gov team
|
||||||
Contact us: <https://get.gov/contact/>
|
Contact us: <https://get.gov/contact/>
|
||||||
Visit <https://get.gov>
|
Visit <https://get.gov>
|
||||||
{% endautoescape %}
|
{% endautoescape %}
|
||||||
|
|
|
@ -4,7 +4,7 @@ Hi {{ application.submitter.first_name }}.
|
||||||
We received your .gov domain request.
|
We received your .gov domain request.
|
||||||
|
|
||||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||||
REQUEST RECEIVED ON: {{ application.updated_at|date }}
|
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||||
REQUEST #: {{ application.id }}
|
REQUEST #: {{ application.id }}
|
||||||
STATUS: Received
|
STATUS: Received
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class TestFormValidation(MockEppLib):
|
||||||
form = OrganizationContactForm(data={"zipcode": "nah"})
|
form = OrganizationContactForm(data={"zipcode": "nah"})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
form.errors["zipcode"],
|
form.errors["zipcode"],
|
||||||
["Enter a zip code in the required format, like 12345 or 12345-6789."],
|
["Enter a zip code in the form of 12345 or 12345-6789."],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_org_contact_zip_valid(self):
|
def test_org_contact_zip_valid(self):
|
||||||
|
@ -42,7 +42,7 @@ class TestFormValidation(MockEppLib):
|
||||||
form = CurrentSitesForm(data={"website": "nah"})
|
form = CurrentSitesForm(data={"website": "nah"})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
form.errors["website"],
|
form.errors["website"],
|
||||||
["Enter your organization’s current website in the required format, like www.city.com."],
|
["Enter your organization's current website in the required format, like example.com."],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_website_valid(self):
|
def test_website_valid(self):
|
||||||
|
@ -207,7 +207,7 @@ class TestFormValidation(MockEppLib):
|
||||||
def test_your_contact_phone_invalid(self):
|
def test_your_contact_phone_invalid(self):
|
||||||
"""Must be a valid phone number."""
|
"""Must be a valid phone number."""
|
||||||
form = YourContactForm(data={"phone": "boss@boss"})
|
form = YourContactForm(data={"phone": "boss@boss"})
|
||||||
self.assertTrue(form.errors["phone"][0].startswith("Enter a valid phone number "))
|
self.assertTrue(form.errors["phone"][0].startswith("Enter a valid 10-digit phone number."))
|
||||||
|
|
||||||
def test_other_contact_email_invalid(self):
|
def test_other_contact_email_invalid(self):
|
||||||
"""must be a valid email address."""
|
"""must be a valid email address."""
|
||||||
|
@ -220,7 +220,7 @@ class TestFormValidation(MockEppLib):
|
||||||
def test_other_contact_phone_invalid(self):
|
def test_other_contact_phone_invalid(self):
|
||||||
"""Must be a valid phone number."""
|
"""Must be a valid phone number."""
|
||||||
form = OtherContactsForm(data={"phone": "super@boss"})
|
form = OtherContactsForm(data={"phone": "super@boss"})
|
||||||
self.assertTrue(form.errors["phone"][0].startswith("Enter a valid phone number "))
|
self.assertTrue(form.errors["phone"][0].startswith("Enter a valid 10-digit phone number."))
|
||||||
|
|
||||||
def test_requirements_form_blank(self):
|
def test_requirements_form_blank(self):
|
||||||
"""Requirements box unchecked is an error."""
|
"""Requirements box unchecked is an error."""
|
||||||
|
|
|
@ -10,7 +10,7 @@ class TestNameserverError(TestCase):
|
||||||
def test_with_no_ip(self):
|
def test_with_no_ip(self):
|
||||||
"""Test NameserverError when no ip address is passed"""
|
"""Test NameserverError when no ip address is passed"""
|
||||||
nameserver = "nameserver val"
|
nameserver = "nameserver val"
|
||||||
expected = "Using your domain for a name server requires an IP address"
|
expected = "Using your domain for a name server requires an IP address."
|
||||||
|
|
||||||
nsException = NameserverError(code=nsErrorCodes.MISSING_IP, nameserver=nameserver)
|
nsException = NameserverError(code=nsErrorCodes.MISSING_IP, nameserver=nameserver)
|
||||||
self.assertEqual(nsException.message, expected)
|
self.assertEqual(nsException.message, expected)
|
||||||
|
@ -20,7 +20,7 @@ class TestNameserverError(TestCase):
|
||||||
"""Test NameserverError when no ip address
|
"""Test NameserverError when no ip address
|
||||||
and no nameserver is passed"""
|
and no nameserver is passed"""
|
||||||
nameserver = "nameserver val"
|
nameserver = "nameserver val"
|
||||||
expected = "Too many hosts provided, you may not have more than 13 nameservers."
|
expected = "You can't have more than 13 nameservers."
|
||||||
|
|
||||||
nsException = NameserverError(code=nsErrorCodes.TOO_MANY_HOSTS, nameserver=nameserver)
|
nsException = NameserverError(code=nsErrorCodes.TOO_MANY_HOSTS, nameserver=nameserver)
|
||||||
self.assertEqual(nsException.message, expected)
|
self.assertEqual(nsException.message, expected)
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.conf import settings
|
||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from .common import MockEppLib, MockSESClient, completed_application, create_user # type: ignore
|
from .common import MockEppLib, MockSESClient, completed_application, create_user # type: ignore
|
||||||
from django_webtest import WebTest # type: ignore
|
from django_webtest import WebTest # type: ignore
|
||||||
import boto3_mocking # type: ignore
|
import boto3_mocking # type: ignore
|
||||||
|
@ -957,7 +958,7 @@ class DomainApplicationTests(TestWithUser, WebTest):
|
||||||
def test_submitting_no_other_contacts_rationale_removes_reference_other_contacts_when_joined(self):
|
def test_submitting_no_other_contacts_rationale_removes_reference_other_contacts_when_joined(self):
|
||||||
"""When a user submits the Other Contacts form with no other contacts selected, the application's
|
"""When a user submits the Other Contacts form with no other contacts selected, the application's
|
||||||
other contacts references get removed for other contacts that exist and are joined to other objects"""
|
other contacts references get removed for other contacts that exist and are joined to other objects"""
|
||||||
# Populate the databse with a domain application that
|
# Populate the database with a domain application that
|
||||||
# has 1 "other contact" assigned to it
|
# has 1 "other contact" assigned to it
|
||||||
# We'll do it from scratch so we can reuse the other contact
|
# We'll do it from scratch so we can reuse the other contact
|
||||||
ao, _ = Contact.objects.get_or_create(
|
ao, _ = Contact.objects.get_or_create(
|
||||||
|
@ -1079,31 +1080,115 @@ class DomainApplicationTests(TestWithUser, WebTest):
|
||||||
# Assert that it is returned, ie the contacts form is required
|
# Assert that it is returned, ie the contacts form is required
|
||||||
self.assertContains(response, "Enter the first name / given name of this contact.")
|
self.assertContains(response, "Enter the first name / given name of this contact.")
|
||||||
|
|
||||||
@skip("Repurpose when working on ticket 903")
|
def test_delete_other_contact(self):
|
||||||
def test_application_delete_other_contact(self):
|
"""Other contacts can be deleted after being saved to database.
|
||||||
"""Other contacts can be deleted after being saved to database."""
|
|
||||||
# Populate the databse with a domain application that
|
This formset uses the DJANGO DELETE widget. We'll test that by setting 2 contacts on an application,
|
||||||
# has 1 "other contact" assigned to it
|
loading the form and marking one contact up for deletion."""
|
||||||
|
# Populate the database with a domain application that
|
||||||
|
# has 2 "other contact" assigned to it
|
||||||
|
# We'll do it from scratch so we can reuse the other contact
|
||||||
ao, _ = Contact.objects.get_or_create(
|
ao, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
email="testy@town.com",
|
email="testy@town.com",
|
||||||
phone="(555) 555 5555",
|
phone="(201) 555 5555",
|
||||||
)
|
)
|
||||||
you, _ = Contact.objects.get_or_create(
|
you, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy you",
|
first_name="Testy you",
|
||||||
last_name="Tester you",
|
last_name="Tester you",
|
||||||
title="Admin Tester",
|
title="Admin Tester",
|
||||||
email="testy-admin@town.com",
|
email="testy-admin@town.com",
|
||||||
phone="(555) 555 5556",
|
phone="(201) 555 5556",
|
||||||
)
|
)
|
||||||
other, _ = Contact.objects.get_or_create(
|
other, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy2",
|
first_name="Testy2",
|
||||||
last_name="Tester2",
|
last_name="Tester2",
|
||||||
title="Another Tester",
|
title="Another Tester",
|
||||||
email="testy2@town.com",
|
email="testy2@town.com",
|
||||||
phone="(555) 555 5557",
|
phone="(201) 555 5557",
|
||||||
|
)
|
||||||
|
other2, _ = Contact.objects.get_or_create(
|
||||||
|
first_name="Testy3",
|
||||||
|
last_name="Tester3",
|
||||||
|
title="Another Tester",
|
||||||
|
email="testy3@town.com",
|
||||||
|
phone="(201) 555 5557",
|
||||||
|
)
|
||||||
|
application, _ = DomainApplication.objects.get_or_create(
|
||||||
|
organization_type="federal",
|
||||||
|
federal_type="executive",
|
||||||
|
purpose="Purpose of the site",
|
||||||
|
anything_else="No",
|
||||||
|
is_policy_acknowledged=True,
|
||||||
|
organization_name="Testorg",
|
||||||
|
address_line1="address 1",
|
||||||
|
state_territory="NY",
|
||||||
|
zipcode="10002",
|
||||||
|
authorizing_official=ao,
|
||||||
|
submitter=you,
|
||||||
|
creator=self.user,
|
||||||
|
status="started",
|
||||||
|
)
|
||||||
|
application.other_contacts.add(other)
|
||||||
|
application.other_contacts.add(other2)
|
||||||
|
|
||||||
|
# prime the form by visiting /edit
|
||||||
|
self.app.get(reverse("edit-application", kwargs={"id": application.pk}))
|
||||||
|
# django-webtest does not handle cookie-based sessions well because it keeps
|
||||||
|
# resetting the session key on each new request, thus destroying the concept
|
||||||
|
# of a "session". We are going to do it manually, saving the session ID here
|
||||||
|
# and then setting the cookie on each request.
|
||||||
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
|
other_contacts_page = self.app.get(reverse("application:other_contacts"))
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
|
other_contacts_form = other_contacts_page.forms[0]
|
||||||
|
|
||||||
|
# Minimal check to ensure the form is loaded with both other contacts
|
||||||
|
self.assertEqual(other_contacts_form["other_contacts-0-first_name"].value, "Testy2")
|
||||||
|
self.assertEqual(other_contacts_form["other_contacts-1-first_name"].value, "Testy3")
|
||||||
|
|
||||||
|
# Mark the first dude for deletion
|
||||||
|
other_contacts_form.set("other_contacts-0-DELETE", "on")
|
||||||
|
|
||||||
|
# Submit the form
|
||||||
|
other_contacts_form.submit()
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
|
# Verify that the first dude was deleted
|
||||||
|
application = DomainApplication.objects.get()
|
||||||
|
self.assertEqual(application.other_contacts.count(), 1)
|
||||||
|
self.assertEqual(application.other_contacts.first().first_name, "Testy3")
|
||||||
|
|
||||||
|
def test_delete_other_contact_does_not_allow_zero_contacts(self):
|
||||||
|
"""Delete Other Contact does not allow submission with zero contacts."""
|
||||||
|
# Populate the database with a domain application that
|
||||||
|
# has 1 "other contact" assigned to it
|
||||||
|
# We'll do it from scratch so we can reuse the other contact
|
||||||
|
ao, _ = Contact.objects.get_or_create(
|
||||||
|
first_name="Testy",
|
||||||
|
last_name="Tester",
|
||||||
|
title="Chief Tester",
|
||||||
|
email="testy@town.com",
|
||||||
|
phone="(201) 555 5555",
|
||||||
|
)
|
||||||
|
you, _ = Contact.objects.get_or_create(
|
||||||
|
first_name="Testy you",
|
||||||
|
last_name="Tester you",
|
||||||
|
title="Admin Tester",
|
||||||
|
email="testy-admin@town.com",
|
||||||
|
phone="(201) 555 5556",
|
||||||
|
)
|
||||||
|
other, _ = Contact.objects.get_or_create(
|
||||||
|
first_name="Testy2",
|
||||||
|
last_name="Tester2",
|
||||||
|
title="Another Tester",
|
||||||
|
email="testy2@town.com",
|
||||||
|
phone="(201) 555 5557",
|
||||||
)
|
)
|
||||||
application, _ = DomainApplication.objects.get_or_create(
|
application, _ = DomainApplication.objects.get_or_create(
|
||||||
organization_type="federal",
|
organization_type="federal",
|
||||||
|
@ -1136,35 +1221,97 @@ class DomainApplicationTests(TestWithUser, WebTest):
|
||||||
|
|
||||||
other_contacts_form = other_contacts_page.forms[0]
|
other_contacts_form = other_contacts_page.forms[0]
|
||||||
|
|
||||||
# Minimal check to ensure the form is loaded with data (if this part of
|
# Minimal check to ensure the form is loaded
|
||||||
# the application doesn't work, we should be equipped with other unit
|
|
||||||
# tests to flag it)
|
|
||||||
self.assertEqual(other_contacts_form["other_contacts-0-first_name"].value, "Testy2")
|
self.assertEqual(other_contacts_form["other_contacts-0-first_name"].value, "Testy2")
|
||||||
|
|
||||||
# clear the form
|
# Mark the first dude for deletion
|
||||||
other_contacts_form["other_contacts-0-first_name"] = ""
|
other_contacts_form.set("other_contacts-0-DELETE", "on")
|
||||||
other_contacts_form["other_contacts-0-middle_name"] = ""
|
|
||||||
other_contacts_form["other_contacts-0-last_name"] = ""
|
|
||||||
other_contacts_form["other_contacts-0-title"] = ""
|
|
||||||
other_contacts_form["other_contacts-0-email"] = ""
|
|
||||||
other_contacts_form["other_contacts-0-phone"] = ""
|
|
||||||
|
|
||||||
# Submit the now empty form
|
# Submit the form
|
||||||
result = other_contacts_form.submit()
|
other_contacts_form.submit()
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
# Verify that the contact we saved earlier has been removed from the database
|
# Verify that the contact was not deleted
|
||||||
application = DomainApplication.objects.get() # There are no contacts anymore
|
application = DomainApplication.objects.get()
|
||||||
self.assertEqual(
|
self.assertEqual(application.other_contacts.count(), 1)
|
||||||
application.other_contacts.count(),
|
self.assertEqual(application.other_contacts.first().first_name, "Testy2")
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify that on submit, user is advanced to "no contacts" page
|
def test_delete_other_contact_sets_visible_empty_form_as_required_after_failed_submit(self):
|
||||||
no_contacts_page = result.follow()
|
"""When you:
|
||||||
expected_url_slug = str(Step.NO_OTHER_CONTACTS)
|
1. add an empty contact,
|
||||||
actual_url_slug = no_contacts_page.request.path.split("/")[-2]
|
2. delete existing contacts,
|
||||||
self.assertEqual(expected_url_slug, actual_url_slug)
|
3. then submit,
|
||||||
|
The forms on page reload shows all the required fields and their errors."""
|
||||||
|
|
||||||
|
# Populate the database with a domain application that
|
||||||
|
# has 1 "other contact" assigned to it
|
||||||
|
# We'll do it from scratch so we can reuse the other contact
|
||||||
|
ao, _ = Contact.objects.get_or_create(
|
||||||
|
first_name="Testy",
|
||||||
|
last_name="Tester",
|
||||||
|
title="Chief Tester",
|
||||||
|
email="testy@town.com",
|
||||||
|
phone="(201) 555 5555",
|
||||||
|
)
|
||||||
|
you, _ = Contact.objects.get_or_create(
|
||||||
|
first_name="Testy you",
|
||||||
|
last_name="Tester you",
|
||||||
|
title="Admin Tester",
|
||||||
|
email="testy-admin@town.com",
|
||||||
|
phone="(201) 555 5556",
|
||||||
|
)
|
||||||
|
other, _ = Contact.objects.get_or_create(
|
||||||
|
first_name="Testy2",
|
||||||
|
last_name="Tester2",
|
||||||
|
title="Another Tester",
|
||||||
|
email="testy2@town.com",
|
||||||
|
phone="(201) 555 5557",
|
||||||
|
)
|
||||||
|
application, _ = DomainApplication.objects.get_or_create(
|
||||||
|
organization_type="federal",
|
||||||
|
federal_type="executive",
|
||||||
|
purpose="Purpose of the site",
|
||||||
|
anything_else="No",
|
||||||
|
is_policy_acknowledged=True,
|
||||||
|
organization_name="Testorg",
|
||||||
|
address_line1="address 1",
|
||||||
|
state_territory="NY",
|
||||||
|
zipcode="10002",
|
||||||
|
authorizing_official=ao,
|
||||||
|
submitter=you,
|
||||||
|
creator=self.user,
|
||||||
|
status="started",
|
||||||
|
)
|
||||||
|
application.other_contacts.add(other)
|
||||||
|
|
||||||
|
# prime the form by visiting /edit
|
||||||
|
self.app.get(reverse("edit-application", kwargs={"id": application.pk}))
|
||||||
|
# django-webtest does not handle cookie-based sessions well because it keeps
|
||||||
|
# resetting the session key on each new request, thus destroying the concept
|
||||||
|
# of a "session". We are going to do it manually, saving the session ID here
|
||||||
|
# and then setting the cookie on each request.
|
||||||
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
|
other_contacts_page = self.app.get(reverse("application:other_contacts"))
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
|
other_contacts_form = other_contacts_page.forms[0]
|
||||||
|
|
||||||
|
# Minimal check to ensure the form is loaded
|
||||||
|
self.assertEqual(other_contacts_form["other_contacts-0-first_name"].value, "Testy2")
|
||||||
|
|
||||||
|
# Set total forms to 2 indicating an additional formset was added.
|
||||||
|
# Submit no data though for the second formset.
|
||||||
|
# Set the first formset to be deleted.
|
||||||
|
other_contacts_form["other_contacts-TOTAL_FORMS"] = "2"
|
||||||
|
other_contacts_form.set("other_contacts-0-DELETE", "on")
|
||||||
|
|
||||||
|
response = other_contacts_form.submit()
|
||||||
|
|
||||||
|
# Assert that the response presents errors to the user, including to
|
||||||
|
# Enter the first name ...
|
||||||
|
self.assertContains(response, "Enter the first name / given name of this contact.")
|
||||||
|
|
||||||
def test_application_about_your_organiztion_interstate(self):
|
def test_application_about_your_organiztion_interstate(self):
|
||||||
"""Special districts have to answer an additional question."""
|
"""Special districts have to answer an additional question."""
|
||||||
|
@ -2227,7 +2374,7 @@ class TestDomainNameservers(TestDomainOverview):
|
||||||
# the required field. form requires a minimum of 2 name servers
|
# the required field. form requires a minimum of 2 name servers
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
result,
|
result,
|
||||||
"A minimum of 2 name servers are required.",
|
"At least two name servers are required.",
|
||||||
count=2,
|
count=2,
|
||||||
status_code=200,
|
status_code=200,
|
||||||
)
|
)
|
||||||
|
@ -2468,7 +2615,7 @@ class TestDomainNameservers(TestDomainOverview):
|
||||||
# once around each required field.
|
# once around each required field.
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
result,
|
result,
|
||||||
"A minimum of 2 name servers are required.",
|
"At least two name servers are required.",
|
||||||
count=4,
|
count=4,
|
||||||
status_code=200,
|
status_code=200,
|
||||||
)
|
)
|
||||||
|
|
|
@ -44,8 +44,8 @@ class GenericError(Exception):
|
||||||
|
|
||||||
_error_mapping = {
|
_error_mapping = {
|
||||||
GenericErrorCodes.CANNOT_CONTACT_REGISTRY: (
|
GenericErrorCodes.CANNOT_CONTACT_REGISTRY: (
|
||||||
"We’re experiencing a system connection error. Please wait a few minutes "
|
"We’re experiencing a system error. Please wait a few minutes "
|
||||||
"and try again. If you continue to receive this error after a few tries, "
|
"and try again. If you continue to get this error, "
|
||||||
"contact help@get.gov."
|
"contact help@get.gov."
|
||||||
),
|
),
|
||||||
GenericErrorCodes.GENERIC_ERROR: ("Value entered was wrong."),
|
GenericErrorCodes.GENERIC_ERROR: ("Value entered was wrong."),
|
||||||
|
@ -97,13 +97,15 @@ class NameserverError(Exception):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_error_mapping = {
|
_error_mapping = {
|
||||||
NameserverErrorCodes.MISSING_IP: ("Using your domain for a name server requires an IP address"),
|
NameserverErrorCodes.MISSING_IP: ("Using your domain for a name server requires an IP address."),
|
||||||
NameserverErrorCodes.GLUE_RECORD_NOT_ALLOWED: ("Name server address does not match domain name"),
|
NameserverErrorCodes.GLUE_RECORD_NOT_ALLOWED: ("Name server address does not match domain name"),
|
||||||
NameserverErrorCodes.INVALID_IP: ("{}: Enter an IP address in the required format."),
|
NameserverErrorCodes.INVALID_IP: ("{}: Enter an IP address in the required format."),
|
||||||
NameserverErrorCodes.TOO_MANY_HOSTS: ("Too many hosts provided, you may not have more than 13 nameservers."),
|
NameserverErrorCodes.TOO_MANY_HOSTS: ("You can't have more than 13 nameservers."),
|
||||||
NameserverErrorCodes.MISSING_HOST: ("Name server must be provided to enter IP address."),
|
NameserverErrorCodes.MISSING_HOST: ("You must provide a name server to enter an IP address."),
|
||||||
NameserverErrorCodes.INVALID_HOST: ("Enter a name server in the required format, like ns1.example.com"),
|
NameserverErrorCodes.INVALID_HOST: ("Enter a name server in the required format, like ns1.example.com"),
|
||||||
NameserverErrorCodes.DUPLICATE_HOST: ("Remove duplicate entry"),
|
NameserverErrorCodes.DUPLICATE_HOST: (
|
||||||
|
"You already entered this name server address. Name server addresses must be unique."
|
||||||
|
),
|
||||||
NameserverErrorCodes.BAD_DATA: (
|
NameserverErrorCodes.BAD_DATA: (
|
||||||
"There’s something wrong with the name server information you provided. "
|
"There’s something wrong with the name server information you provided. "
|
||||||
"If you need help email us at help@get.gov."
|
"If you need help email us at help@get.gov."
|
||||||
|
@ -156,8 +158,8 @@ class DsDataError(Exception):
|
||||||
),
|
),
|
||||||
DsDataErrorCodes.INVALID_DIGEST_SHA1: ("SHA-1 digest must be exactly 40 characters."),
|
DsDataErrorCodes.INVALID_DIGEST_SHA1: ("SHA-1 digest must be exactly 40 characters."),
|
||||||
DsDataErrorCodes.INVALID_DIGEST_SHA256: ("SHA-256 digest must be exactly 64 characters."),
|
DsDataErrorCodes.INVALID_DIGEST_SHA256: ("SHA-256 digest must be exactly 64 characters."),
|
||||||
DsDataErrorCodes.INVALID_DIGEST_CHARS: ("Digest must contain only alphanumeric characters [0-9,a-f]."),
|
DsDataErrorCodes.INVALID_DIGEST_CHARS: ("Digest must contain only alphanumeric characters (0-9, a-f)."),
|
||||||
DsDataErrorCodes.INVALID_KEYTAG_SIZE: ("Key tag must be less than 65535"),
|
DsDataErrorCodes.INVALID_KEYTAG_SIZE: ("Key tag must be less than 65535."),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, code=None, **kwargs):
|
def __init__(self, *args, code=None, **kwargs):
|
||||||
|
@ -187,7 +189,7 @@ class SecurityEmailError(Exception):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_error_mapping = {
|
_error_mapping = {
|
||||||
SecurityEmailErrorCodes.BAD_DATA: ("Enter an email address in the required format, like name@example.com.")
|
SecurityEmailErrorCodes.BAD_DATA: ("Enter an email address in the required format, " "like name@example.com."),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, code=None, **kwargs):
|
def __init__(self, *args, code=None, **kwargs):
|
||||||
|
|
|
@ -486,7 +486,7 @@ class YourContact(ApplicationWizard):
|
||||||
class OtherContacts(ApplicationWizard):
|
class OtherContacts(ApplicationWizard):
|
||||||
template_name = "application_other_contacts.html"
|
template_name = "application_other_contacts.html"
|
||||||
forms = [forms.OtherContactsYesNoForm, forms.OtherContactsFormSet, forms.NoOtherContactsForm]
|
forms = [forms.OtherContactsYesNoForm, forms.OtherContactsFormSet, forms.NoOtherContactsForm]
|
||||||
|
|
||||||
def is_valid(self, forms: list) -> bool:
|
def is_valid(self, forms: list) -> bool:
|
||||||
"""Overrides default behavior defined in ApplicationWizard.
|
"""Overrides default behavior defined in ApplicationWizard.
|
||||||
Depending on value in other_contacts_yes_no_form, marks forms in
|
Depending on value in other_contacts_yes_no_form, marks forms in
|
||||||
|
@ -500,9 +500,9 @@ class OtherContacts(ApplicationWizard):
|
||||||
# set all the required other_contact fields as necessary since new forms
|
# set all the required other_contact fields as necessary since new forms
|
||||||
# were added through javascript
|
# were added through javascript
|
||||||
for form in forms[1].forms:
|
for form in forms[1].forms:
|
||||||
for _, field in form.fields.items():
|
for field_item, field in form.fields.items():
|
||||||
if field.required:
|
if field.required:
|
||||||
field.widget.attrs['required'] = 'required'
|
field.widget.attrs["required"] = "required"
|
||||||
|
|
||||||
all_forms_valid = True
|
all_forms_valid = True
|
||||||
# test first for yes_no_form validity
|
# test first for yes_no_form validity
|
||||||
|
|
|
@ -196,7 +196,7 @@ class DomainOrgNameAddressView(DomainFormBaseView):
|
||||||
"""The form is valid, save the organization name and mailing address."""
|
"""The form is valid, save the organization name and mailing address."""
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
messages.success(self.request, "The organization information has been updated.")
|
messages.success(self.request, "The organization information for this domain has been updated.")
|
||||||
|
|
||||||
# superclass has the redirect
|
# superclass has the redirect
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
@ -348,9 +348,8 @@ class DomainNameserversView(DomainFormBaseView):
|
||||||
messages.success(
|
messages.success(
|
||||||
self.request,
|
self.request,
|
||||||
"The name servers for this domain have been updated. "
|
"The name servers for this domain have been updated. "
|
||||||
"Keep in mind that DNS changes may take some time to "
|
"Note that DNS changes could take anywhere from a few minutes to "
|
||||||
"propagate across the internet. It can take anywhere "
|
"48 hours to propagate across the internet.",
|
||||||
"from a few minutes to 48 hours for your changes to take place.",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# superclass has the redirect
|
# superclass has the redirect
|
||||||
|
@ -549,7 +548,7 @@ class DomainYourContactInformationView(DomainFormBaseView):
|
||||||
# Post to DB using values from the form
|
# Post to DB using values from the form
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
messages.success(self.request, "Your contact information for this domain has been updated.")
|
messages.success(self.request, "Your contact information has been updated.")
|
||||||
|
|
||||||
# superclass has the redirect
|
# superclass has the redirect
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
@ -686,7 +685,7 @@ class DomainAddUserView(DomainFormBaseView):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if add_success:
|
if add_success:
|
||||||
messages.success(self.request, f"Invited {email} to this domain.")
|
messages.success(self.request, f"{email} has been invited to this domain.")
|
||||||
|
|
||||||
def _make_invitation(self, email_address: str, requester: User):
|
def _make_invitation(self, email_address: str, requester: User):
|
||||||
"""Make a Domain invitation for this email and redirect with a message."""
|
"""Make a Domain invitation for this email and redirect with a message."""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue