summaryrefslogtreecommitdiff
path: root/src/mailman/rest/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/rest/tests')
-rw-r--r--src/mailman/rest/tests/test_bans.py5
-rw-r--r--src/mailman/rest/tests/test_domains.py222
-rw-r--r--src/mailman/rest/tests/test_listconf.py23
-rw-r--r--src/mailman/rest/tests/test_lists.py232
-rw-r--r--src/mailman/rest/tests/test_root.py211
-rw-r--r--src/mailman/rest/tests/test_systemconf.py1
6 files changed, 688 insertions, 6 deletions
diff --git a/src/mailman/rest/tests/test_bans.py b/src/mailman/rest/tests/test_bans.py
index fc096fa1b..b83bf8aef 100644
--- a/src/mailman/rest/tests/test_bans.py
+++ b/src/mailman/rest/tests/test_bans.py
@@ -81,3 +81,8 @@ class TestBans(unittest.TestCase):
self.assertEqual(cm.exception.code, 404)
self.assertEqual(cm.exception.reason,
b'Email is not banned: banned@example.com')
+
+ def test_ban_missing_mailing_list(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.0/lists/bee.example.com/bans')
+ self.assertEqual(cm.exception.code, 404)
diff --git a/src/mailman/rest/tests/test_domains.py b/src/mailman/rest/tests/test_domains.py
index e98f75b53..41723b07c 100644
--- a/src/mailman/rest/tests/test_domains.py
+++ b/src/mailman/rest/tests/test_domains.py
@@ -23,6 +23,7 @@ from mailman.app.lifecycle import create_list
from mailman.database.transaction import transaction
from mailman.interfaces.domain import IDomainManager
from mailman.interfaces.listmanager import IListManager
+from mailman.interfaces.template import ITemplateManager
from mailman.testing.helpers import call_api
from mailman.testing.layers import RESTLayer
from urllib.error import HTTPError
@@ -41,7 +42,6 @@ class TestDomains(unittest.TestCase):
data = dict(
mail_host='example.org',
description='Example domain',
- base_url='http://example.org',
owner=['someone@example.com', 'secondowner@example.com'],
)
content, response = call_api(
@@ -163,3 +163,223 @@ class TestDomainOwners(unittest.TestCase):
'owner': 'dave@example.com',
}, method='DELETE')
self.assertEqual(cm.exception.code, 400)
+
+
+class TestDomainTemplates(unittest.TestCase):
+ """Test /domains/<mail-host>/uris"""
+
+ layer = RESTLayer
+
+ def test_no_templates_for_api_30(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.0/domains/example.com/uris')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_no_templates_for_missing_list(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.1/domains/example.org/uris')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_path_too_long(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.1/domains/example.com/uris'
+ '/foo/bar')
+ self.assertEqual(cm.exception.code, 400)
+
+ def test_get_unknown_uri(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.1/domains/example.com/uris'
+ '/not:a:template')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_get_all_uris(self):
+ manager = getUtility(ITemplateManager)
+ with transaction():
+ manager.set(
+ 'list:user:notice:welcome', 'example.com',
+ 'http://example.com/welcome')
+ manager.set(
+ 'list:user:notice:goodbye', 'example.com',
+ 'http://example.com/goodbye',
+ 'a user', 'the password',
+ )
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris')
+ self.assertEqual(response.status, 200)
+ self.assertEqual(resource['start'], 0)
+ self.assertEqual(resource['total_size'], 2)
+ self.assertEqual(
+ resource['self_link'],
+ 'http://localhost:9001/3.1/domains/example.com/uris')
+ self.assertEqual(resource['entries'], [
+ {'http_etag': '"e877ff896db0f2e280660ac16b9401f7925a53b9"',
+ 'name': 'list:user:notice:goodbye',
+ 'password': 'the password',
+ 'self_link': ('http://localhost:9001/3.1/domains/example.com'
+ '/uris/list:user:notice:goodbye'),
+ 'uri': 'http://example.com/goodbye',
+ 'username': 'a user',
+ },
+ {'http_etag': '"8dac25601c3419e98e2c05df1d962a2252b67ce6"',
+ 'name': 'list:user:notice:welcome',
+ 'self_link': ('http://localhost:9001/3.1/domains/example.com'
+ '/uris/list:user:notice:welcome'),
+ 'uri': 'http://example.com/welcome',
+ }])
+
+ def test_patch_uris(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ }, method='PATCH')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:user:notice:welcome', 'example.com')
+ self.assertEqual(template.uri, 'http://example.org/welcome')
+ self.assertIsNone(template.username)
+ self.assertEqual(template.password, '')
+ template = manager.raw('list:user:notice:goodbye', 'example.com')
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertIsNone(template.username)
+ self.assertEqual(template.password, '')
+
+ def test_patch_uris_with_credentials(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'password': 'some password',
+ 'username': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:user:notice:welcome', 'example.com')
+ self.assertEqual(template.uri, 'http://example.org/welcome')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', 'example.com')
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+
+ def test_patch_uris_with_partial_credentials(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'username': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(cm.exception.code, 400)
+
+ def test_put_all_uris(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris', {
+ 'domain:admin:notice:new-list': '',
+ 'list:admin:action:post': '',
+ 'list:admin:action:subscribe': '',
+ 'list:admin:action:unsubscribe': '',
+ 'list:admin:notice:subscribe': '',
+ 'list:admin:notice:unrecognized': '',
+ 'list:admin:notice:unsubscribe': '',
+ 'list:member:digest:footer': '',
+ 'list:member:digest:header': '',
+ 'list:member:digest:masthead': '',
+ 'list:member:regular:footer': 'http://example.org/footer',
+ 'list:member:regular:header': 'http://example.org/header',
+ 'list:user:action:confirm': '',
+ 'list:user:action:unsubscribe': '',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'list:user:notice:hold': '',
+ 'list:user:notice:no-more-today': '',
+ 'list:user:notice:post': '',
+ 'list:user:notice:probe': '',
+ 'list:user:notice:refuse': '',
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'password': 'some password',
+ 'username': 'anne.person',
+ }, method='PUT')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:member:digest:footer', 'example.com')
+ self.assertIsNone(template)
+ template = manager.raw('list:member:digest:header', 'example.com')
+ self.assertIsNone(template)
+ template = manager.raw('list:member:regular:footer', 'example.com')
+ self.assertEqual(template.uri, 'http://example.org/footer')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:member:regular:header', 'example.com')
+ self.assertEqual(template.uri, 'http://example.org/header')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', 'example.com')
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', 'example.com')
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+
+ def test_delete_all_uris(self):
+ manager = getUtility(ITemplateManager)
+ with transaction():
+ manager.set(
+ 'list:user:notice:welcome', 'example.com',
+ 'http://example.com/welcome')
+ manager.set(
+ 'list:user:notice:goodbye', 'example.com',
+ 'http://example.com/goodbye',
+ 'a user', 'the password',
+ )
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris',
+ method='DELETE')
+ self.assertEqual(response.status, 204)
+ self.assertIsNone(
+ manager.raw('list:user:notice:welcome', 'example.com'))
+ self.assertIsNone(
+ manager.raw('list:user:notice:goodbye', 'example.com'))
+
+ def test_get_a_url(self):
+ with transaction():
+ getUtility(ITemplateManager).set(
+ 'list:user:notice:welcome', 'example.com',
+ 'http://example.com/welcome')
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris'
+ '/list:user:notice:welcome')
+ self.assertEqual(response.status, 200)
+ self.assertEqual(resource, {
+ 'http_etag': '"8884a0b3d675b4cb9899a7825daac9db88b70bed"',
+ 'self_link': ('http://localhost:9001/3.1/domains/example.com'
+ '/uris/list:user:notice:welcome'),
+ 'uri': 'http://example.com/welcome',
+ })
+
+ def test_get_a_bad_url(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris'
+ '/list:user:notice:notemplate')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_get_unset_url(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris'
+ '/list:user:notice:welcome')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_patch_url_with_too_many_parameters(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/domains/example.com/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'secret': 'some password',
+ 'person': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(cm.exception.code, 400)
diff --git a/src/mailman/rest/tests/test_listconf.py b/src/mailman/rest/tests/test_listconf.py
index b5d8c49f6..9bc3486be 100644
--- a/src/mailman/rest/tests/test_listconf.py
+++ b/src/mailman/rest/tests/test_listconf.py
@@ -24,9 +24,11 @@ from mailman.database.transaction import transaction
from mailman.interfaces.digests import DigestFrequency
from mailman.interfaces.mailinglist import (
IAcceptableAliasSet, SubscriptionPolicy)
+from mailman.interfaces.template import ITemplateManager
from mailman.testing.helpers import call_api
from mailman.testing.layers import RESTLayer
from urllib.error import HTTPError
+from zope.component import getUtility
# The representation of the listconf resource as a dictionary. This is used
# when PUTting to the list's configuration resource.
@@ -373,7 +375,9 @@ class TestConfiguration(unittest.TestCase):
def test_get_goodbye_message_uri(self):
with transaction():
- self._mlist.goodbye_message_uri = 'mailman:///goodbye.txt'
+ getUtility(ITemplateManager).set(
+ 'user:ack:goodbye', self._mlist.list_id,
+ 'mailman:///goodbye.txt')
resource, response = call_api(
'http://localhost:9001/3.0/lists/ant.example.com/config'
'/goodbye_message_uri')
@@ -387,7 +391,9 @@ class TestConfiguration(unittest.TestCase):
'PATCH')
self.assertEqual(response.status, 204)
self.assertEqual(
- self._mlist.goodbye_message_uri, 'mailman:///salutation.txt')
+ getUtility(ITemplateManager).raw(
+ 'user:ack:goodbye', self._mlist.list_id).uri,
+ 'mailman:///salutation.txt')
def test_patch_goodbye_message_uri(self):
resource, response = call_api(
@@ -397,11 +403,17 @@ class TestConfiguration(unittest.TestCase):
'PATCH')
self.assertEqual(response.status, 204)
self.assertEqual(
- self._mlist.goodbye_message_uri, 'mailman:///salutation.txt')
+ getUtility(ITemplateManager).raw(
+ 'user:ack:goodbye', self._mlist.list_id).uri,
+ 'mailman:///salutation.txt')
def test_put_goodbye_message_uri(self):
+ manager = getUtility(ITemplateManager)
with transaction():
- self._mlist.goodbye_message_uri = 'mailman:///somefile.txt'
+ manager.set(
+ 'user:ack:goodbye',
+ self._mlist.list_id,
+ 'mailman:///somefile.txt')
resource, response = call_api(
'http://localhost:9001/3.0/lists/ant.example.com/config'
'/goodbye_message_uri',
@@ -409,7 +421,8 @@ class TestConfiguration(unittest.TestCase):
'PUT')
self.assertEqual(response.status, 204)
self.assertEqual(
- self._mlist.goodbye_message_uri, 'mailman:///salutation.txt')
+ manager.raw('user:ack:goodbye', self._mlist.list_id).uri,
+ 'mailman:///salutation.txt')
def test_advertised(self):
# GL issue #220 claimed advertised was read-only.
diff --git a/src/mailman/rest/tests/test_lists.py b/src/mailman/rest/tests/test_lists.py
index 891afa889..787009855 100644
--- a/src/mailman/rest/tests/test_lists.py
+++ b/src/mailman/rest/tests/test_lists.py
@@ -27,6 +27,7 @@ from mailman.interfaces.digests import DigestFrequency
from mailman.interfaces.listmanager import IListManager
from mailman.interfaces.mailinglist import IAcceptableAliasSet
from mailman.interfaces.member import DeliveryMode
+from mailman.interfaces.template import ITemplateManager
from mailman.interfaces.usermanager import IUserManager
from mailman.model.mailinglist import AcceptableAlias
from mailman.runners.digest import DigestRunner
@@ -545,3 +546,234 @@ Subject: message 1
items = get_queue_messages('virgin')
self.assertEqual(len(items), 1)
self.assertEqual(items[0].msg['subject'], 'Ant Digest, Vol 8, Issue 1')
+
+
+class TestListTemplates(unittest.TestCase):
+ """Test /lists/<list-id>/uris"""
+
+ layer = RESTLayer
+
+ def setUp(self):
+ with transaction():
+ self._mlist = create_list('ant@example.com')
+
+ def test_no_templates_for_api_30(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.0/lists/ant.example.com/uris')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_no_templates_for_missing_list(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.1/lists/bee.example.com/uris')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_path_too_long(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.1/lists/ant.example.com/uris'
+ '/foo/bar')
+ self.assertEqual(cm.exception.code, 400)
+
+ def test_get_unknown_uri(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.1/lists/ant.example.com/uris'
+ '/not:a:template')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_get_all_uris(self):
+ manager = getUtility(ITemplateManager)
+ with transaction():
+ manager.set(
+ 'list:user:notice:welcome', 'ant.example.com',
+ 'http://example.com/welcome')
+ manager.set(
+ 'list:user:notice:goodbye', 'ant.example.com',
+ 'http://example.com/goodbye',
+ 'a user', 'the password',
+ )
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris')
+ self.assertEqual(response.status, 200)
+ self.assertEqual(resource['start'], 0)
+ self.assertEqual(resource['total_size'], 2)
+ self.assertEqual(
+ resource['self_link'],
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris')
+ self.assertEqual(resource['entries'], [
+ {'http_etag': '"6612187ed6604ce54a57405fd66742557391ed4a"',
+ 'name': 'list:user:notice:goodbye',
+ 'password': 'the password',
+ 'self_link': ('http://localhost:9001/3.1/lists/ant.example.com'
+ '/uris/list:user:notice:goodbye'),
+ 'uri': 'http://example.com/goodbye',
+ 'username': 'a user',
+ },
+ {'http_etag': '"cb1ab5eee2242143d2984edd0487532915ad3a8e"',
+ 'name': 'list:user:notice:welcome',
+ 'self_link': ('http://localhost:9001/3.1/lists/ant.example.com'
+ '/uris/list:user:notice:welcome'),
+ 'uri': 'http://example.com/welcome',
+ }])
+
+ def test_patch_uris(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ }, method='PATCH')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:user:notice:welcome', 'ant.example.com')
+ self.assertEqual(template.uri, 'http://example.org/welcome')
+ self.assertIsNone(template.username)
+ self.assertEqual(template.password, '')
+ template = manager.raw('list:user:notice:goodbye', 'ant.example.com')
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertIsNone(template.username)
+ self.assertEqual(template.password, '')
+
+ def test_patch_uris_with_credentials(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'password': 'some password',
+ 'username': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:user:notice:welcome', 'ant.example.com')
+ self.assertEqual(template.uri, 'http://example.org/welcome')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', 'ant.example.com')
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+
+ def test_patch_uris_with_partial_credentials(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'username': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(cm.exception.code, 400)
+
+ def test_put_all_uris(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris', {
+ 'list:admin:action:post': '',
+ 'list:admin:action:subscribe': '',
+ 'list:admin:action:unsubscribe': '',
+ 'list:admin:notice:subscribe': '',
+ 'list:admin:notice:unrecognized': '',
+ 'list:admin:notice:unsubscribe': '',
+ 'list:member:digest:footer': '',
+ 'list:member:digest:header': '',
+ 'list:member:digest:masthead': '',
+ 'list:member:regular:footer': 'http://example.org/footer',
+ 'list:member:regular:header': 'http://example.org/header',
+ 'list:user:action:confirm': '',
+ 'list:user:action:unsubscribe': '',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'list:user:notice:hold': '',
+ 'list:user:notice:no-more-today': '',
+ 'list:user:notice:post': '',
+ 'list:user:notice:probe': '',
+ 'list:user:notice:refuse': '',
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'password': 'some password',
+ 'username': 'anne.person',
+ }, method='PUT')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:member:digest:footer', 'ant.example.com')
+ self.assertIsNone(template)
+ template = manager.raw('list:member:digest:header', 'ant.example.com')
+ self.assertIsNone(template)
+ template = manager.raw('list:member:regular:footer', 'ant.example.com')
+ self.assertEqual(template.uri, 'http://example.org/footer')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:member:regular:header', 'ant.example.com')
+ self.assertEqual(template.uri, 'http://example.org/header')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', 'ant.example.com')
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', 'ant.example.com')
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+
+ def test_delete_all_uris(self):
+ manager = getUtility(ITemplateManager)
+ with transaction():
+ manager.set(
+ 'list:user:notice:welcome', 'ant.example.com',
+ 'http://example.com/welcome')
+ manager.set(
+ 'list:user:notice:goodbye', 'ant.example.com',
+ 'http://example.com/goodbye',
+ 'a user', 'the password',
+ )
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris',
+ method='DELETE')
+ self.assertEqual(response.status, 204)
+ self.assertIsNone(
+ manager.raw('list:user:notice:welcome', 'ant.example.com'))
+ self.assertIsNone(
+ manager.raw('list:user:notice:goodbye', 'ant.example.com'))
+
+ def test_get_a_url(self):
+ with transaction():
+ getUtility(ITemplateManager).set(
+ 'list:user:notice:welcome', 'ant.example.com',
+ 'http://example.com/welcome')
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris'
+ '/list:user:notice:welcome')
+ self.assertEqual(response.status, 200)
+ self.assertEqual(resource, {
+ 'http_etag': '"36f8bef800cfd278f097c61c5892a34c0650f4aa"',
+ 'self_link': ('http://localhost:9001/3.1/lists/ant.example.com'
+ '/uris/list:user:notice:welcome'),
+ 'uri': 'http://example.com/welcome',
+ })
+
+ def test_get_a_bad_url(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris'
+ '/list:user:notice:notemplate')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_get_unset_url(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris'
+ '/list:user:notice:welcome')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_patch_url_with_too_many_parameters(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/lists/ant.example.com/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'secret': 'some password',
+ 'person': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(cm.exception.code, 400)
+
+ def test_deprecated_resources(self):
+ # This resource does not exist with API 3.0.
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.0/templates/ant@example.com'
+ '/footer/en')
+ self.assertEqual(cm.exception.code, 404)
diff --git a/src/mailman/rest/tests/test_root.py b/src/mailman/rest/tests/test_root.py
index 1e0ff6f28..840212825 100644
--- a/src/mailman/rest/tests/test_root.py
+++ b/src/mailman/rest/tests/test_root.py
@@ -25,9 +25,12 @@ from base64 import b64encode
from httplib2 import Http
from mailman.config import config
from mailman.core.system import system
+from mailman.database.transaction import transaction
+from mailman.interfaces.template import ITemplateManager
from mailman.testing.helpers import call_api
from mailman.testing.layers import RESTLayer
from urllib.error import HTTPError
+from zope.component import getUtility
class TestRoot(unittest.TestCase):
@@ -167,3 +170,211 @@ class TestRoot(unittest.TestCase):
'chains': ['chain_1', 'chain_2']
}, method='PUT')
self.assertEqual(cm.exception.code, 405)
+
+
+class TestSiteTemplates(unittest.TestCase):
+ """Test /uris"""
+
+ layer = RESTLayer
+
+ def test_no_templates_for_api_30(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.0/uris')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_path_too_long(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.1/uris/foo/bar')
+ self.assertEqual(cm.exception.code, 400)
+
+ def test_get_unknown_uri(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api('http://localhost:9001/3.1/uris/not:a:template')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_get_all_uris(self):
+ manager = getUtility(ITemplateManager)
+ with transaction():
+ manager.set(
+ 'list:user:notice:welcome', None,
+ 'http://example.com/welcome')
+ manager.set(
+ 'list:user:notice:goodbye', None,
+ 'http://example.com/goodbye',
+ 'a user', 'the password',
+ )
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/uris')
+ self.assertEqual(response.status, 200)
+ self.assertEqual(resource['start'], 0)
+ self.assertEqual(resource['total_size'], 2)
+ self.assertEqual(
+ resource['self_link'],
+ 'http://localhost:9001/3.1/uris')
+ self.assertEqual(resource['entries'], [
+ {'http_etag': '"063fd6635a6035a4b7e939a304fcbd16571aa662"',
+ 'name': 'list:user:notice:goodbye',
+ 'password': 'the password',
+ 'self_link': ('http://localhost:9001/3.1'
+ '/uris/list:user:notice:goodbye'),
+ 'uri': 'http://example.com/goodbye',
+ 'username': 'a user',
+ },
+ {'http_etag': '"5c4ec63b2a0a50f96483ec85b94b80ee092af792"',
+ 'name': 'list:user:notice:welcome',
+ 'self_link': ('http://localhost:9001/3.1'
+ '/uris/list:user:notice:welcome'),
+ 'uri': 'http://example.com/welcome',
+ }])
+
+ def test_patch_uris(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ }, method='PATCH')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:user:notice:welcome', None)
+ self.assertEqual(template.uri, 'http://example.org/welcome')
+ self.assertIsNone(template.username)
+ self.assertEqual(template.password, '')
+ template = manager.raw('list:user:notice:goodbye', None)
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertIsNone(template.username)
+ self.assertEqual(template.password, '')
+
+ def test_patch_uris_with_credentials(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'password': 'some password',
+ 'username': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:user:notice:welcome', None)
+ self.assertEqual(template.uri, 'http://example.org/welcome')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', None)
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+
+ def test_patch_uris_with_partial_credentials(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'username': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(cm.exception.code, 400)
+
+ def test_put_all_uris(self):
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/uris', {
+ 'domain:admin:notice:new-list': '',
+ 'list:admin:action:post': '',
+ 'list:admin:action:subscribe': '',
+ 'list:admin:action:unsubscribe': '',
+ 'list:admin:notice:subscribe': '',
+ 'list:admin:notice:unrecognized': '',
+ 'list:admin:notice:unsubscribe': '',
+ 'list:member:digest:footer': '',
+ 'list:member:digest:header': '',
+ 'list:member:digest:masthead': '',
+ 'list:member:regular:footer': 'http://example.org/footer',
+ 'list:member:regular:header': 'http://example.org/header',
+ 'list:user:action:confirm': '',
+ 'list:user:action:unsubscribe': '',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'list:user:notice:hold': '',
+ 'list:user:notice:no-more-today': '',
+ 'list:user:notice:post': '',
+ 'list:user:notice:probe': '',
+ 'list:user:notice:refuse': '',
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'password': 'some password',
+ 'username': 'anne.person',
+ }, method='PUT')
+ self.assertEqual(response.status, 204)
+ manager = getUtility(ITemplateManager)
+ template = manager.raw('list:member:digest:footer', None)
+ self.assertIsNone(template)
+ template = manager.raw('list:member:digest:header', None)
+ self.assertIsNone(template)
+ template = manager.raw('list:member:regular:footer', None)
+ self.assertEqual(template.uri, 'http://example.org/footer')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:member:regular:header', None)
+ self.assertEqual(template.uri, 'http://example.org/header')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', None)
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+ template = manager.raw('list:user:notice:goodbye', None)
+ self.assertEqual(template.uri, 'http://example.org/goodbye')
+ self.assertEqual(template.username, 'anne.person')
+ self.assertEqual(template.password, 'some password')
+
+ def test_delete_all_uris(self):
+ manager = getUtility(ITemplateManager)
+ with transaction():
+ manager.set(
+ 'list:user:notice:welcome', None,
+ 'http://example.com/welcome')
+ manager.set(
+ 'list:user:notice:goodbye', None,
+ 'http://example.com/goodbye',
+ 'a user', 'the password',
+ )
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/uris',
+ method='DELETE')
+ self.assertEqual(response.status, 204)
+ self.assertIsNone(manager.raw('list:user:notice:welcome', None))
+ self.assertIsNone(manager.raw('list:user:notice:goodbye', None))
+
+ def test_get_a_url(self):
+ with transaction():
+ getUtility(ITemplateManager).set(
+ 'list:user:notice:welcome', None,
+ 'http://example.com/welcome')
+ resource, response = call_api(
+ 'http://localhost:9001/3.1/uris/list:user:notice:welcome')
+ self.assertEqual(response.status, 200)
+ self.assertEqual(resource, {
+ 'http_etag': '"86e360d83197561d50826ad6d15e9c30923b82d6"',
+ 'self_link': ('http://localhost:9001/3.1'
+ '/uris/list:user:notice:welcome'),
+ 'uri': 'http://example.com/welcome',
+ })
+
+ def test_get_a_bad_url(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/uris/list:user:notice:notemplate')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_get_unset_url(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/uris/list:user:notice:welcome')
+ self.assertEqual(cm.exception.code, 404)
+
+ def test_patch_url_with_too_many_parameters(self):
+ with self.assertRaises(HTTPError) as cm:
+ call_api(
+ 'http://localhost:9001/3.1/uris', {
+ 'list:user:notice:welcome': 'http://example.org/welcome',
+ 'list:user:notice:goodbye': 'http://example.org/goodbye',
+ 'secret': 'some password',
+ 'person': 'anne.person',
+ }, method='PATCH')
+ self.assertEqual(cm.exception.code, 400)
diff --git a/src/mailman/rest/tests/test_systemconf.py b/src/mailman/rest/tests/test_systemconf.py
index 9335480bf..e76c082df 100644
--- a/src/mailman/rest/tests/test_systemconf.py
+++ b/src/mailman/rest/tests/test_systemconf.py
@@ -37,6 +37,7 @@ class TestSystemConfiguration(unittest.TestCase):
self.assertIn('http_etag', json)
del json['http_etag']
self.assertEqual(json, dict(
+ cache_life='7d',
default_language='en',
email_commands_max_lines='10',
filtered_messages_are_preservable='no',