mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-30 01:10:04 +02:00
Sketch test cases for Domain integration
This also includes an illustration of how action buttons could be integrated into the admin portal.
This commit is contained in:
parent
78a9c50561
commit
cabe516f9f
5 changed files with 507 additions and 92 deletions
|
@ -1,4 +1,4 @@
|
|||
from django.contrib import admin
|
||||
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
|
||||
|
@ -50,13 +50,40 @@ class MyHostAdmin(AuditedAdmin):
|
|||
inlines = [HostIPInline]
|
||||
|
||||
|
||||
class DomainAdmin(AuditedAdmin):
|
||||
|
||||
"""Custom domain admin class to add extra buttons."""
|
||||
|
||||
change_form_template = "django/admin/domain_change_form.html"
|
||||
readonly_fields = ["state"]
|
||||
|
||||
def response_change(self, request, obj):
|
||||
if "_place_client_hold" in request.POST:
|
||||
try:
|
||||
obj.place_client_hold()
|
||||
except Exception as err:
|
||||
self.message_user(request, err, messages.ERROR)
|
||||
else:
|
||||
self.message_user(
|
||||
request,
|
||||
(
|
||||
"%s is in client hold. This domain is no longer accessible on"
|
||||
" the public internet."
|
||||
)
|
||||
% obj.name,
|
||||
)
|
||||
return HttpResponseRedirect(".")
|
||||
|
||||
return super().response_change(request, obj)
|
||||
|
||||
|
||||
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, 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)
|
||||
|
|
|
@ -267,7 +267,7 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
|
||||
def place_client_hold(self):
|
||||
"""This domain should not be active."""
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError("This is not implemented yet.")
|
||||
|
||||
def remove_client_hold(self):
|
||||
"""This domain is okay to be active."""
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{% extends 'admin/change_form.html' %}
|
||||
|
||||
{% block field_sets %}
|
||||
<div class="submit-row">
|
||||
<input type="submit" value="Place hold" name="_place_client_hold">
|
||||
</div>
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
|
@ -12,7 +12,6 @@ from registrar.models import (
|
|||
DomainInvitation,
|
||||
UserDomainRole,
|
||||
)
|
||||
from unittest import skip
|
||||
|
||||
import boto3_mocking # type: ignore
|
||||
from .common import MockSESClient, less_console_noise
|
||||
|
@ -213,55 +212,3 @@ class TestInvitations(TestCase):
|
|||
"""A new user's first_login callback retrieves their invitations."""
|
||||
self.user.first_login()
|
||||
self.assertTrue(UserDomainRole.objects.get(user=self.user, domain=self.domain))
|
||||
|
||||
|
||||
@skip("Not implemented yet.")
|
||||
class TestDomainApplicationLifeCycle(TestCase):
|
||||
def test_application_approval(self):
|
||||
# DomainApplication is created
|
||||
# test: Domain is created and is inactive
|
||||
# analyst approves DomainApplication
|
||||
# test: Domain is activated
|
||||
pass
|
||||
|
||||
def test_application_rejection(self):
|
||||
# DomainApplication is created
|
||||
# test: Domain is created and is inactive
|
||||
# analyst rejects DomainApplication
|
||||
# test: Domain remains inactive
|
||||
pass
|
||||
|
||||
def test_application_deleted_before_approval(self):
|
||||
# DomainApplication is created
|
||||
# test: Domain is created and is inactive
|
||||
# admin deletes DomainApplication
|
||||
# test: Domain is deleted; Hosts, HostIps and Nameservers are deleted
|
||||
pass
|
||||
|
||||
def test_application_deleted_following_approval(self):
|
||||
# DomainApplication is created
|
||||
# test: Domain is created and is inactive
|
||||
# analyst approves DomainApplication
|
||||
# admin deletes DomainApplication
|
||||
# test: DomainApplication foreign key field on Domain is set to null
|
||||
pass
|
||||
|
||||
def test_application_approval_with_conflicting_name(self):
|
||||
# DomainApplication #1 is created
|
||||
# test: Domain #1 is created and is inactive
|
||||
# analyst approves DomainApplication #1
|
||||
# test: Domain #1 is activated
|
||||
# DomainApplication #2 is created, with the same domain name string
|
||||
# test: Domain #2 is created and is inactive
|
||||
# analyst approves DomainApplication #2
|
||||
# test: error is raised
|
||||
# test: DomainApplication #1 remains approved
|
||||
# test: Domain #1 remains active
|
||||
# test: DomainApplication #2 remains in investigating
|
||||
# test: Domain #2 remains inactive
|
||||
pass
|
||||
|
||||
def test_application_approval_with_network_errors(self):
|
||||
# TODO: scenario wherein application is approved,
|
||||
# but attempts to contact the registry to activate the domain fail
|
||||
pass
|
||||
|
|
|
@ -1,54 +1,487 @@
|
|||
"""
|
||||
Feature being tested: Registry Integration
|
||||
|
||||
This file tests the various ways in which the registrar interacts with the registry.
|
||||
"""
|
||||
from django.test import TestCase
|
||||
from django.db.utils import IntegrityError
|
||||
|
||||
from registrar.models import (
|
||||
DomainApplication,
|
||||
User,
|
||||
Domain,
|
||||
)
|
||||
from unittest import skip
|
||||
|
||||
|
||||
class TestDomain(TestCase):
|
||||
def test_empty_create_fails(self):
|
||||
class TestDomainCreation(TestCase):
|
||||
"""Rule: An approved domain application must result in a domain"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Background:
|
||||
Given that a valid domain application exists
|
||||
"""
|
||||
pass
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_approved_application_creates_domain_locally(self):
|
||||
"""
|
||||
Scenario: Analyst approves a domain application
|
||||
When the DomainApplication transitions to approved
|
||||
Then a Domain exists in the database with the same `name`
|
||||
But a domain object does not exist in the registry
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_accessing_domain_properties_creates_domain_in_registry(self):
|
||||
"""
|
||||
Scenario: A registrant checks the status of a newly approved domain
|
||||
Given that no domain object exists in the registry
|
||||
When `domain.is_active()` is called
|
||||
Then Domain sends `commands.CreateDomain` to the registry
|
||||
And `domain.state` is set to `CREATED`
|
||||
And `domain.is_active()` returns False
|
||||
"""
|
||||
raise
|
||||
|
||||
def test_empty_domain_creation(self):
|
||||
"""Can't create a completely empty domain."""
|
||||
with self.assertRaisesRegex(IntegrityError, "name"):
|
||||
Domain.objects.create()
|
||||
|
||||
def test_minimal_create(self):
|
||||
def test_minimal_creation(self):
|
||||
"""Can create with just a name."""
|
||||
Domain.objects.create(name="igorville.gov")
|
||||
# this assertion will not work -- for now, the fact that the
|
||||
# above command didn't error out is proof enough
|
||||
# self.assertEquals(domain.state, Domain.State.DRAFTED)
|
||||
|
||||
@skip("cannot activate a domain without mock registry")
|
||||
def test_get_status(self):
|
||||
"""Returns proper status based on `state`."""
|
||||
domain = Domain.objects.create(name="igorville.gov")
|
||||
domain.save()
|
||||
self.assertEqual(None, domain.status)
|
||||
domain.activate()
|
||||
domain.save()
|
||||
self.assertIn("ok", domain.status)
|
||||
def test_duplicate_creation(self):
|
||||
"""Can't create domain if name is not unique."""
|
||||
Domain.objects.create(name="igorville.gov")
|
||||
with self.assertRaisesRegex(IntegrityError, "name"):
|
||||
Domain.objects.create(name="igorville.gov")
|
||||
|
||||
@skip("cannot activate a domain without mock registry")
|
||||
def test_fsm_activate_fail_unique(self):
|
||||
"""Can't activate domain if name is not unique."""
|
||||
d1, _ = Domain.objects.get_or_create(name="igorville.gov")
|
||||
d2, _ = Domain.objects.get_or_create(name="igorville.gov")
|
||||
d1.activate()
|
||||
d1.save()
|
||||
with self.assertRaises(ValueError):
|
||||
d2.activate()
|
||||
|
||||
@skip("cannot activate a domain without mock registry")
|
||||
def test_fsm_activate_fail_unapproved(self):
|
||||
"""Can't activate domain if application isn't approved."""
|
||||
d1, _ = Domain.objects.get_or_create(name="igorville.gov")
|
||||
user, _ = User.objects.get_or_create()
|
||||
application = DomainApplication.objects.create(creator=user)
|
||||
d1.domain_application = application
|
||||
d1.save()
|
||||
with self.assertRaises(ValueError):
|
||||
d1.activate()
|
||||
class TestRegistrantContacts(TestCase):
|
||||
"""Rule: Registrants may modify their WHOIS data"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Background:
|
||||
Given the registrant is logged in
|
||||
And the registrant is the admin on a domain
|
||||
"""
|
||||
pass
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_no_security_email(self):
|
||||
"""
|
||||
Scenario: Registrant declines to add a security contact email
|
||||
Given the domain exists in the registry
|
||||
Then the domain has a valid security contact with CISA defaults
|
||||
And disclose flags are set to keep the email address hidden
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_adds_security_email(self):
|
||||
"""
|
||||
Scenario: Registrant adds a security contact email
|
||||
When `domain.security_contact` is set equal to a PublicContact with the
|
||||
chosen security contact email
|
||||
Then Domain sends `commands.CreateContact` to the registry
|
||||
And Domain sends `commands.UpdateDomain` to the registry with the newly
|
||||
created contact of type 'security'
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_security_email_is_idempotent(self):
|
||||
"""
|
||||
Scenario: Registrant adds a security contact email twice, due to a UI glitch
|
||||
When `commands.CreateContact` and `commands.UpdateDomain` are sent
|
||||
to the registry twice with identical data
|
||||
Then no errors are raised in Domain
|
||||
"""
|
||||
# implementation note: this requires seeing what happens when these are actually
|
||||
# sent like this, and then implementing appropriate mocks for any errors the
|
||||
# registry normally sends in this case
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_deletes_security_email(self):
|
||||
"""
|
||||
Scenario: Registrant clears out an existing security contact email
|
||||
Given a domain exists in the registry with a user-added security email
|
||||
When `domain.security_contact` is set equal to a PublicContact with an empty
|
||||
security contact email
|
||||
Then Domain sends `commands.UpdateDomain` and `commands.DeleteContact`
|
||||
to the registry
|
||||
And the domain has a valid security contact with CISA defaults
|
||||
And disclose flags are set to keep the email address hidden
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_updates_security_email(self):
|
||||
"""
|
||||
Scenario: Registrant replaces one valid security contact email with another
|
||||
Given a domain exists in the registry with a user-added security email
|
||||
When `domain.security_contact` is set equal to a PublicContact with a new
|
||||
security contact email
|
||||
Then Domain sends `commands.UpdateContact` to the registry
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_update_is_unsuccessful(self):
|
||||
"""
|
||||
Scenario: An update to the security contact is unsuccessful
|
||||
When an error is returned from epplibwrapper
|
||||
Then a user-friendly error message is returned for displaying on the web
|
||||
"""
|
||||
raise
|
||||
|
||||
|
||||
class TestRegistrantNameservers(TestCase):
|
||||
"""Rule: Registrants may modify their nameservers"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Background:
|
||||
Given the registrant is logged in
|
||||
And the registrant is the admin on a domain
|
||||
"""
|
||||
pass
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_adds_one_nameserver(self):
|
||||
"""
|
||||
Scenario: Registrant adds a single nameserver
|
||||
Given the domain has zero nameservers
|
||||
When `domain.nameservers` is set to an array of length 1
|
||||
Then `commands.CreateHost` and `commands.UpdateDomain` is sent
|
||||
to the registry
|
||||
And `domain.is_active` returns False
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_adds_two_nameservers(self):
|
||||
"""
|
||||
Scenario: Registrant adds 2 or more nameservers, thereby activating the domain
|
||||
Given the domain has zero nameservers
|
||||
When `domain.nameservers` is set to an array of length 2
|
||||
Then `commands.CreateHost` and `commands.UpdateDomain` is sent
|
||||
to the registry
|
||||
And `domain.is_active` returns True
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_adds_too_many_nameservers(self):
|
||||
"""
|
||||
Scenario: Registrant adds 14 or more nameservers
|
||||
Given the domain has zero nameservers
|
||||
When `domain.nameservers` is set to an array of length 14
|
||||
Then Domain raises a user-friendly error
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_removes_some_nameservers(self):
|
||||
"""
|
||||
Scenario: Registrant removes some nameservers, while keeping at least 2
|
||||
Given the domain has 3 nameservers
|
||||
When `domain.nameservers` is set to an array containing nameserver #1 and #2
|
||||
Then `commands.UpdateDomain` and `commands.DeleteHost` is sent
|
||||
to the registry
|
||||
And `domain.is_active` returns True
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_removes_too_many_nameservers(self):
|
||||
"""
|
||||
Scenario: Registrant removes some nameservers, bringing the total to less than 2
|
||||
Given the domain has 3 nameservers
|
||||
When `domain.nameservers` is set to an array containing nameserver #1
|
||||
Then `commands.UpdateDomain` and `commands.DeleteHost` is sent
|
||||
to the registry
|
||||
And `domain.is_active` returns False
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_replaces_nameservers(self):
|
||||
"""
|
||||
Scenario: Registrant simultaneously adds and removes some nameservers
|
||||
Given the domain has 3 nameservers
|
||||
When `domain.nameservers` is set to an array containing nameserver #1 plus
|
||||
two new nameservers
|
||||
Then `commands.CreateHost` is sent to create #4 and #5
|
||||
And `commands.UpdateDomain` is sent to add #4 and #5 plus remove #2 and #3
|
||||
And `commands.DeleteHost` is sent to delete #2 and #3
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_cannot_add_subordinate_without_ip(self):
|
||||
"""
|
||||
Scenario: Registrant adds a nameserver which is a subdomain of their .gov
|
||||
Given the domain exists in the registry
|
||||
When `domain.nameservers` is set to an array containing an entry
|
||||
with a subdomain of the domain and no IP addresses
|
||||
Then Domain raises a user-friendly error
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_updates_ips(self):
|
||||
"""
|
||||
Scenario: Registrant changes IP addresses for a nameserver
|
||||
Given the domain exists in the registry
|
||||
And has a subordinate nameserver
|
||||
When `domain.nameservers` is set to an array containing that nameserver
|
||||
with a different IP address(es)
|
||||
Then `commands.UpdateHost` is sent to the registry
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_cannot_add_non_subordinate_with_ip(self):
|
||||
"""
|
||||
Scenario: Registrant adds a nameserver which is NOT a subdomain of their .gov
|
||||
Given the domain exists in the registry
|
||||
When `domain.nameservers` is set to an array containing an entry
|
||||
which is not a subdomain of the domain and has IP addresses
|
||||
Then Domain raises a user-friendly error
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_nameservers_are_idempotent(self):
|
||||
"""
|
||||
Scenario: Registrant adds a set of nameservers twice, due to a UI glitch
|
||||
When `commands.CreateHost` and `commands.UpdateDomain` are sent
|
||||
to the registry twice with identical data
|
||||
Then no errors are raised in Domain
|
||||
"""
|
||||
# implementation note: this requires seeing what happens when these are actually
|
||||
# sent like this, and then implementing appropriate mocks for any errors the
|
||||
# registry normally sends in this case
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_update_is_unsuccessful(self):
|
||||
"""
|
||||
Scenario: An update to the nameservers is unsuccessful
|
||||
When an error is returned from epplibwrapper
|
||||
Then a user-friendly error message is returned for displaying on the web
|
||||
"""
|
||||
raise
|
||||
|
||||
|
||||
class TestRegistrantDNSSEC(TestCase):
|
||||
"""Rule: Registrants may modify their secure DNS data"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Background:
|
||||
Given the registrant is logged in
|
||||
And the registrant is the admin on a domain
|
||||
"""
|
||||
pass
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_adds_dns_data(self):
|
||||
"""
|
||||
Scenario: Registrant adds DNS data
|
||||
...
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_dnssec_is_idempotent(self):
|
||||
"""
|
||||
Scenario: Registrant adds DNS data twice, due to a UI glitch
|
||||
...
|
||||
"""
|
||||
# implementation note: this requires seeing what happens when these are actually
|
||||
# sent like this, and then implementing appropriate mocks for any errors the
|
||||
# registry normally sends in this case
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_update_is_unsuccessful(self):
|
||||
"""
|
||||
Scenario: An update to the security contact is unsuccessful
|
||||
When an error is returned from epplibwrapper
|
||||
Then a user-friendly error message is returned for displaying on the web
|
||||
"""
|
||||
raise
|
||||
|
||||
|
||||
class TestAnalystClientHold(TestCase):
|
||||
"""Rule: Analysts may suspend or restore a domain by using client hold"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Background:
|
||||
Given the analyst is logged in
|
||||
And a domain exists in the registry
|
||||
"""
|
||||
pass
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_places_client_hold(self):
|
||||
"""
|
||||
Scenario: Analyst takes a domain off the internet
|
||||
When `domain.place_client_hold()` is called
|
||||
Then `CLIENT_HOLD` is added to the domain's statuses
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_places_client_hold_idempotent(self):
|
||||
"""
|
||||
Scenario: Analyst tries to place client hold twice
|
||||
Given `CLIENT_HOLD` is already in the domain's statuses
|
||||
When `domain.place_client_hold()` is called
|
||||
Then Domain returns normally (without error)
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_removes_client_hold(self):
|
||||
"""
|
||||
Scenario: Analyst restores a suspended domain
|
||||
Given `CLIENT_HOLD` is in the domain's statuses
|
||||
When `domain.remove_client_hold()` is called
|
||||
Then `CLIENT_HOLD` is no longer in the domain's statuses
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_removes_client_hold_idempotent(self):
|
||||
"""
|
||||
Scenario: Analyst tries to remove client hold twice
|
||||
Given `CLIENT_HOLD` is not in the domain's statuses
|
||||
When `domain.remove_client_hold()` is called
|
||||
Then Domain returns normally (without error)
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_update_is_unsuccessful(self):
|
||||
"""
|
||||
Scenario: An update to place or remove client hold is unsuccessful
|
||||
When an error is returned from epplibwrapper
|
||||
Then a user-friendly error message is returned for displaying on the web
|
||||
"""
|
||||
raise
|
||||
|
||||
|
||||
class TestAnalystLock(TestCase):
|
||||
"""Rule: Analysts may lock or unlock a domain to prevent or allow updates"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Background:
|
||||
Given the analyst is logged in
|
||||
And a domain exists in the registry
|
||||
"""
|
||||
pass
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_locks_domain(self):
|
||||
"""
|
||||
Scenario: Analyst locks a domain to prevent edits or deletion
|
||||
When `domain.lock()` is called
|
||||
Then `CLIENT_DELETE_PROHIBITED` is added to the domain's statuses
|
||||
And `CLIENT_TRANSFER_PROHIBITED` is added to the domain's statuses
|
||||
And `CLIENT_UPDATE_PROHIBITED` is added to the domain's statuses
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_locks_domain_idempotent(self):
|
||||
"""
|
||||
Scenario: Analyst tries to lock a domain twice
|
||||
Given `CLIENT_*_PROHIBITED` is already in the domain's statuses
|
||||
When `domain.lock()` is called
|
||||
Then Domain returns normally (without error)
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_removes_client_hold(self):
|
||||
"""
|
||||
Scenario: Analyst unlocks a domain to allow deletion or edits
|
||||
Given `CLIENT_*_PROHIBITED` is in the domain's statuses
|
||||
When `domain.unlock()` is called
|
||||
Then `CLIENT_DELETE_PROHIBITED` is no longer in the domain's statuses
|
||||
And `CLIENT_TRANSFER_PROHIBITED` is no longer in the domain's statuses
|
||||
And `CLIENT_UPDATE_PROHIBITED` is no longer in the domain's statuses
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_removes_client_hold_idempotent(self):
|
||||
"""
|
||||
Scenario: Analyst tries to unlock a domain twice
|
||||
Given `CLIENT_*_PROHIBITED` is not in the domain's statuses
|
||||
When `domain.unlock()` is called
|
||||
Then Domain returns normally (without error)
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_update_is_unsuccessful(self):
|
||||
"""
|
||||
Scenario: An update to lock or unlock a domain is unsuccessful
|
||||
When an error is returned from epplibwrapper
|
||||
Then a user-friendly error message is returned for displaying on the web
|
||||
"""
|
||||
raise
|
||||
|
||||
|
||||
class TestAnalystDelete(TestCase):
|
||||
"""Rule: Analysts may delete a domain"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Background:
|
||||
Given the analyst is logged in
|
||||
And a domain exists in the registry
|
||||
"""
|
||||
pass
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_deletes_domain(self):
|
||||
"""
|
||||
Scenario: Analyst permanently deletes a domain
|
||||
When `domain.delete()` is called
|
||||
Then `commands.DeleteDomain` is sent to the registry
|
||||
And `state` is set to `DELETED`
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_analyst_deletes_domain_idempotent(self):
|
||||
"""
|
||||
Scenario: Analyst tries to delete an already deleted domain
|
||||
Given `state` is already `DELETED`
|
||||
When `domain.delete()` is called
|
||||
Then `commands.DeleteDomain` is sent to the registry
|
||||
And Domain returns normally (without error)
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_deletion_is_unsuccessful(self):
|
||||
"""
|
||||
Scenario: Domain deletion is unsuccessful
|
||||
When an error is returned from epplibwrapper
|
||||
Then a user-friendly error message is returned for displaying on the web
|
||||
And `state` is not set to `DELETED`
|
||||
"""
|
||||
raise
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue