diff --git a/designate/api/v1/__init__.py b/designate/api/v1/__init__.py index 9bfd06949..3ec6f31d9 100644 --- a/designate/api/v1/__init__.py +++ b/designate/api/v1/__init__.py @@ -68,6 +68,9 @@ def factory(global_config, **local_conf): # Install custom converters (URL param varidators) app.url_map.converters['uuid'] = UUIDConverter + # disable strict slashes. This allows trailing slashes in the URLS. + app.url_map.strict_slashes = False + # Ensure all error responses are JSON def _json_error(ex): code = ex.code if isinstance(ex, wexceptions.HTTPException) else 500 diff --git a/designate/tests/test_api/test_v1/test_domains.py b/designate/tests/test_api/test_v1/test_domains.py index af9196ca7..ed029e580 100644 --- a/designate/tests/test_api/test_v1/test_domains.py +++ b/designate/tests/test_api/test_v1/test_domains.py @@ -40,6 +40,15 @@ class ApiV1DomainsTest(ApiV1Test): self.assertIn('name', response.json) self.assertEqual(response.json['name'], fixture['name']) + @patch.object(central_service.Service, 'create_domain') + def test_create_domain_trailing_slash(self, mock): + # Create a server + self.create_server() + self.post('domains/', data=self.get_domain_fixture(0)) + + # verify that the central service is called + self.assertTrue(mock.called) + def test_create_domain_junk(self): # Create a server self.create_server() @@ -102,6 +111,13 @@ class ApiV1DomainsTest(ApiV1Test): self.assertIn('domains', response.json) self.assertEqual(2, len(response.json['domains'])) + @patch.object(central_service.Service, 'find_domains') + def test_get_domains_trailing_slash(self, mock): + self.get('domains/') + + # verify that the central service is called + self.assertTrue(mock.called) + @patch.object(central_service.Service, 'find_domains', side_effect=rpc_common.Timeout()) def test_get_domains_timeout(self, _): @@ -156,6 +172,16 @@ class ApiV1DomainsTest(ApiV1Test): self.assertIn('id', response.json) self.assertEqual(response.json['id'], domain['id']) + @patch.object(central_service.Service, 'get_domain') + def test_get_domain_trailing_slash(self, mock): + # Create a domain + domain = self.create_domain() + + self.get('domains/%s/' % domain['id']) + + # verify that the central service is called + self.assertTrue(mock.called) + @patch.object(central_service.Service, 'get_domain', side_effect=rpc_common.Timeout()) def test_get_domain_timeout(self, _): @@ -189,6 +215,18 @@ class ApiV1DomainsTest(ApiV1Test): self.assertIn('email', response.json) self.assertEqual(response.json['email'], 'prefix-%s' % domain['email']) + @patch.object(central_service.Service, 'update_domain') + def test_update_domain_trailing_slash(self, mock): + # Create a domain + domain = self.create_domain() + + data = {'email': 'prefix-%s' % domain['email']} + + self.put('domains/%s/' % domain['id'], data=data) + + # verify that the central service is called + self.assertTrue(mock.called) + def test_update_domain_junk(self): # Create a domain domain = self.create_domain() @@ -258,6 +296,16 @@ class ApiV1DomainsTest(ApiV1Test): # Esnure we can no longer fetch the domain self.get('domains/%s' % domain['id'], status_code=404) + @patch.object(central_service.Service, 'delete_domain') + def test_delete_domain_trailing_slash(self, mock): + # Create a domain + domain = self.create_domain() + + self.delete('domains/%s/' % domain['id']) + + # verify that the central service is called + self.assertTrue(mock.called) + @patch.object(central_service.Service, 'delete_domain', side_effect=rpc_common.Timeout()) def test_delete_domain_timeout(self, _): diff --git a/designate/tests/test_api/test_v1/test_records.py b/designate/tests/test_api/test_v1/test_records.py index bb22e6a78..516f7cd47 100644 --- a/designate/tests/test_api/test_v1/test_records.py +++ b/designate/tests/test_api/test_v1/test_records.py @@ -42,6 +42,15 @@ class ApiV1RecordsTest(ApiV1Test): self.assertIn('name', response.json) self.assertEqual(response.json['name'], fixture['name']) + @patch.object(central_service.Service, 'create_record') + def test_create_record_trailing_slash(self, mock): + # Create a record with a trailing slash + self.post('domains/%s/records/' % self.domain['id'], + data=self.get_record_fixture(self.domain['name'], 0)) + + # verify that the central service is called + self.assertTrue(mock.called) + def test_create_record_junk(self): fixture = self.get_record_fixture(self.domain['name'], 0) @@ -179,6 +188,13 @@ class ApiV1RecordsTest(ApiV1Test): self.assertIn('records', response.json) self.assertEqual(2, len(response.json['records'])) + @patch.object(central_service.Service, 'find_records') + def test_get_records_trailing_slash(self, mock): + self.get('domains/%s/records/' % self.domain['id']) + + # verify that the central service is called + self.assertTrue(mock.called) + @patch.object(central_service.Service, 'find_records', side_effect=rpc_common.Timeout()) def test_get_records_timeout(self, _): @@ -203,6 +219,17 @@ class ApiV1RecordsTest(ApiV1Test): self.assertIn('id', response.json) self.assertEqual(response.json['id'], record['id']) + @patch.object(central_service.Service, 'get_record') + def test_get_record_trailing_slash(self, mock): + # Create a record + record = self.create_record(self.domain) + + self.get('domains/%s/records/%s/' % (self.domain['id'], + record['id'])) + + # verify that the central service is called + self.assertTrue(mock.called) + def test_update_record(self): # Create a record record = self.create_record(self.domain) @@ -219,6 +246,20 @@ class ApiV1RecordsTest(ApiV1Test): self.assertIn('name', response.json) self.assertEqual(response.json['name'], 'prefix-%s' % record['name']) + @patch.object(central_service.Service, 'update_record') + def test_update_record_trailing_slash(self, mock): + # Create a record + record = self.create_record(self.domain) + + data = {'name': 'prefix-%s' % record['name']} + + self.put('domains/%s/records/%s/' % (self.domain['id'], + record['id']), + data=data) + + # verify that the central service is called + self.assertTrue(mock.called) + def test_update_record_junk(self): # Create a record record = self.create_record(self.domain) @@ -292,6 +333,17 @@ class ApiV1RecordsTest(ApiV1Test): record['id']), status_code=404) + @patch.object(central_service.Service, 'delete_record') + def test_delete_record_trailing_slash(self, mock): + # Create a record + record = self.create_record(self.domain) + + self.delete('domains/%s/records/%s/' % (self.domain['id'], + record['id'])) + + # verify that the central service is called + self.assertTrue(mock.called) + @patch.object(central_service.Service, 'delete_record', side_effect=rpc_common.Timeout()) def test_delete_record_timeout(self, _): diff --git a/designate/tests/test_api/test_v1/test_servers.py b/designate/tests/test_api/test_v1/test_servers.py index 66af6f1c5..a2e3c02c1 100644 --- a/designate/tests/test_api/test_v1/test_servers.py +++ b/designate/tests/test_api/test_v1/test_servers.py @@ -37,6 +37,14 @@ class ApiV1ServersTest(ApiV1Test): self.assertIn('name', response.json) self.assertEqual(response.json['name'], fixture['name']) + @patch.object(central_service.Service, 'create_server') + def test_create_server_trailing_slash(self, mock): + # Create a server with a trailing slash + self.post('servers/', data=self.get_server_fixture(0)) + + # verify that the central service is called + self.assertTrue(mock.called) + def test_create_server_junk(self): # Create a server fixture = self.get_server_fixture(0) @@ -85,6 +93,13 @@ class ApiV1ServersTest(ApiV1Test): self.assertIn('servers', response.json) self.assertEqual(2, len(response.json['servers'])) + @patch.object(central_service.Service, 'find_servers') + def test_get_servers_trailing_slash(self, mock): + self.get('servers/') + + # verify that the central service is called + self.assertTrue(mock.called) + @patch.object(central_service.Service, 'find_servers', side_effect=rpc_common.Timeout()) def test_get_servers_timeout(self, _): @@ -99,6 +114,16 @@ class ApiV1ServersTest(ApiV1Test): self.assertIn('id', response.json) self.assertEqual(response.json['id'], server['id']) + @patch.object(central_service.Service, 'get_server') + def test_get_server_trailing_slash(self, mock): + # Create a server + server = self.create_server() + + self.get('servers/%s/' % server['id']) + + # verify that the central service is called + self.assertTrue(mock.called) + @patch.object(central_service.Service, 'get_server', side_effect=rpc_common.Timeout()) def test_get_server_timeout(self, _): @@ -125,6 +150,18 @@ class ApiV1ServersTest(ApiV1Test): self.assertIn('name', response.json) self.assertEqual(response.json['name'], 'test.example.org.') + @patch.object(central_service.Service, 'update_server') + def test_update_server_trailing_slash(self, mock): + # Create a server + server = self.create_server() + + data = {'name': 'test.example.org.'} + + self.put('servers/%s/' % server['id'], data=data) + + # verify that the central service is called + self.assertTrue(mock.called) + def test_update_server_junk(self): # Create a server server = self.create_server() @@ -164,9 +201,19 @@ class ApiV1ServersTest(ApiV1Test): self.delete('servers/%s' % server['id']) - # Esnure we can no longer fetch the server + # Ensure we can no longer fetch the server self.get('servers/%s' % server['id'], status_code=404) + @patch.object(central_service.Service, 'delete_server') + def test_delete_server_trailing_slash(self, mock): + # Create a server + server = self.create_server() + + self.delete('servers/%s/' % server['id']) + + # verify that the central service is called + self.assertTrue(mock.called) + @patch.object(central_service.Service, 'delete_server', side_effect=rpc_common.Timeout()) def test_delete_server_timeout(self, _):