diff --git a/.vscode/launch.json b/.vscode/launch.json index f6f9287f..59444ea1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -33,12 +33,12 @@ "args": [] }, { - "name": "BE-DebugTest", + "name": "BE-DebugTestFile", "type": "debugpy", "request": "launch", "cwd": "${workspaceFolder}/rsconcept/backend", "program": "${workspaceFolder}/rsconcept/backend/manage.py", - "args": ["test"], + "args": ["test", "-k", "${fileBasenameNoExtension}"], "django": true }, { diff --git a/rsconcept/backend/apps/rsform/tests/s_views/EndpointTester.py b/rsconcept/backend/apps/rsform/tests/EndpointTester.py similarity index 80% rename from rsconcept/backend/apps/rsform/tests/s_views/EndpointTester.py rename to rsconcept/backend/apps/rsform/tests/EndpointTester.py index 0c4e705f..6f1b94bf 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/EndpointTester.py +++ b/rsconcept/backend/apps/rsform/tests/EndpointTester.py @@ -26,7 +26,16 @@ class EndpointTester(APITestCase): def setUp(self): self.factory = APIRequestFactory() - self.user = User.objects.create(username='UserTest') + self.user = User.objects.create_user( + username='UserTest', + email='blank@test.com', + password='password' + ) + self.user2 = User.objects.create_user( + username='UserTest2', + email='another@test.com', + password='password' + ) self.client = APIClient() self.client.force_authenticate(user=self.user) @@ -77,30 +86,6 @@ class EndpointTester(APITestCase): else: return self.client.delete(self.endpoint) - def assertOK(self, data=None, **kwargs): - response = self.execute(data, **kwargs) - self.assertEqual(response.status_code, status.HTTP_200_OK) - - def assertCreated(self, data=None, **kwargs): - response = self.execute(data, **kwargs) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - - def assertBadData(self, data=None, **kwargs): - response = self.execute(data, **kwargs) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - - def assertForbidden(self, data=None, **kwargs): - response = self.execute(data, **kwargs) - self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - - def assertNotModified(self, data=None, **kwargs): - response = self.execute(data, **kwargs) - self.assertEqual(response.status_code, status.HTTP_304_NOT_MODIFIED) - - def assertNotFound(self, data=None, **kwargs): - response = self.execute(data, **kwargs) - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def execute(self, data=None, **kwargs): if self.method == 'get': return self.get(**kwargs) @@ -114,6 +99,46 @@ class EndpointTester(APITestCase): return self.delete(data, **kwargs) return None + def executeOK(self, data=None, **kwargs): + response = self.execute(data, **kwargs) + self.assertEqual(response.status_code, status.HTTP_200_OK) + return response + + def executeCreated(self, data=None, **kwargs): + response = self.execute(data, **kwargs) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + return response + + def executeAccepted(self, data=None, **kwargs): + response = self.execute(data, **kwargs) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + return response + + def executeNoContent(self, data=None, **kwargs): + response = self.execute(data, **kwargs) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + return response + + def executeBadData(self, data=None, **kwargs): + response = self.execute(data, **kwargs) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + return response + + def executeForbidden(self, data=None, **kwargs): + response = self.execute(data, **kwargs) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + return response + + def executeNotModified(self, data=None, **kwargs): + response = self.execute(data, **kwargs) + self.assertEqual(response.status_code, status.HTTP_304_NOT_MODIFIED) + return response + + def executeNotFound(self, data=None, **kwargs): + response = self.execute(data, **kwargs) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + return response + def _resolve_url(url: str, **kwargs) -> str: if url == '' or len(kwargs) == 0: diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_cctext.py b/rsconcept/backend/apps/rsform/tests/s_views/t_cctext.py index 76cef739..33c91811 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_cctext.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_cctext.py @@ -1,8 +1,7 @@ ''' Testing views ''' from cctext import split_grams -from rest_framework import status -from .EndpointTester import EndpointTester, decl_endpoint +from ..EndpointTester import EndpointTester, decl_endpoint class TestNaturalLanguageViews(EndpointTester): @@ -15,23 +14,20 @@ class TestNaturalLanguageViews(EndpointTester): @decl_endpoint(endpoint='/api/cctext/parse', method='post') def test_parse_text(self): data = {'text': 'синим слонам'} - response = self.execute(data) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data) self._assert_tags(response.data['result'], 'datv,NOUN,plur,anim,masc') @decl_endpoint(endpoint='/api/cctext/inflect', method='post') def test_inflect(self): data = {'text': 'синий слон', 'grams': 'plur,datv'} - response = self.execute(data) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data) self.assertEqual(response.data['result'], 'синим слонам') @decl_endpoint(endpoint='/api/cctext/generate-lexeme', method='post') def test_generate_lexeme(self): data = {'text': 'синий слон'} - response = self.execute(data) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data) self.assertEqual(len(response.data['items']), 12) self.assertEqual(response.data['items'][0]['text'], 'синий слон') diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py b/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py index 098d2741..a19cfc49 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py @@ -1,9 +1,7 @@ ''' Testing API: Constituents. ''' -from rest_framework import status - from apps.rsform.models import Constituenta, CstType, RSForm -from .EndpointTester import EndpointTester, decl_endpoint +from ..EndpointTester import EndpointTester, decl_endpoint class TestConstituentaAPI(EndpointTester): @@ -45,9 +43,8 @@ class TestConstituentaAPI(EndpointTester): @decl_endpoint('/api/constituents/{item}', method='get') def test_retrieve(self): - self.assertNotFound(item=self.invalid_cst) - response = self.execute(item=self.cst1.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + self.executeNotFound(item=self.invalid_cst) + response = self.executeOK(item=self.cst1.pk) self.assertEqual(response.data['alias'], self.cst1.alias) self.assertEqual(response.data['convention'], self.cst1.convention) @@ -55,19 +52,18 @@ class TestConstituentaAPI(EndpointTester): @decl_endpoint('/api/constituents/{item}', method='patch') def test_partial_update(self): data = {'convention': 'tt'} - self.assertForbidden(data, item=self.cst2.pk) + self.executeForbidden(data, item=self.cst2.pk) self.logout() - self.assertForbidden(data, item=self.cst1.pk) + self.executeForbidden(data, item=self.cst1.pk) self.login() - response = self.execute(data, item=self.cst1.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data, item=self.cst1.pk) self.cst1.refresh_from_db() self.assertEqual(response.data['convention'], 'tt') self.assertEqual(self.cst1.convention, 'tt') - self.assertOK(data, item=self.cst1.pk) + self.executeOK(data, item=self.cst1.pk) @decl_endpoint('/api/constituents/{item}', method='patch') @@ -76,8 +72,7 @@ class TestConstituentaAPI(EndpointTester): 'term_raw': 'New term', 'definition_raw': 'New def' } - response = self.execute(data, item=self.cst3.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data, item=self.cst3.pk) self.cst3.refresh_from_db() self.assertEqual(response.data['term_resolved'], 'New term') self.assertEqual(self.cst3.term_resolved, 'New term') @@ -91,8 +86,7 @@ class TestConstituentaAPI(EndpointTester): 'term_raw': '@{X1|nomn,sing}', 'definition_raw': '@{X1|nomn,sing} @{X1|sing,datv}' } - response = self.execute(data, item=self.cst3.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data, item=self.cst3.pk) self.cst3.refresh_from_db() self.assertEqual(self.cst3.term_resolved, self.cst1.term_resolved) self.assertEqual(response.data['term_resolved'], self.cst1.term_resolved) @@ -103,8 +97,7 @@ class TestConstituentaAPI(EndpointTester): @decl_endpoint('/api/constituents/{item}', method='patch') def test_readonly_cst_fields(self): data = {'alias': 'X33', 'order': 10} - response = self.execute(data, item=self.cst1.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data, item=self.cst1.pk) self.assertEqual(response.data['alias'], 'X1') self.assertEqual(response.data['alias'], self.cst1.alias) self.assertEqual(response.data['order'], self.cst1.order) diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_library.py b/rsconcept/backend/apps/rsform/tests/s_views/t_library.py index 302cbdc3..bb99dba3 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_library.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_library.py @@ -9,10 +9,9 @@ from apps.rsform.models import ( RSForm, Subscription ) -from apps.users.models import User +from ..EndpointTester import EndpointTester, decl_endpoint from ..testing_utils import response_contains -from .EndpointTester import EndpointTester, decl_endpoint class TestLibraryViewset(EndpointTester): @@ -20,7 +19,6 @@ class TestLibraryViewset(EndpointTester): def setUp(self): super().setUp() - self.user2 = User.objects.create(username='UserTest2') self.owned = LibraryItem.objects.create( item_type=LibraryItemType.RSFORM, title='Test', @@ -46,25 +44,23 @@ class TestLibraryViewset(EndpointTester): @decl_endpoint('/api/library', method='post') def test_create(self): data = {'title': 'Title'} - response = self.post(data=data) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data) self.assertEqual(response.data['title'], 'Title') self.assertEqual(response.data['owner'], self.user.pk) self.logout() data = {'title': 'Title2'} - self.assertForbidden(data) + self.executeForbidden(data) @decl_endpoint('/api/library/{item}', method='patch') def test_update(self): data = {'id': self.unowned.pk, 'title': 'New title'} - self.assertNotFound(data, item=self.invalid_item) - self.assertForbidden(data, item=self.unowned.pk) + self.executeNotFound(data, item=self.invalid_item) + self.executeForbidden(data, item=self.unowned.pk) data = {'id': self.owned.pk, 'title': 'New title'} - response = self.execute(data, item=self.owned.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data, item=self.owned.pk) self.assertEqual(response.data['title'], 'New title') self.assertEqual(response.data['alias'], self.owned.alias) @@ -74,22 +70,22 @@ class TestLibraryViewset(EndpointTester): time_update = self.owned.time_update data = {'user': self.user.pk} - self.assertNotFound(data, item=self.invalid_item) - self.assertForbidden(data, item=self.unowned.pk) - self.assertOK(data, item=self.owned.pk) + self.executeNotFound(data, item=self.invalid_item) + self.executeForbidden(data, item=self.unowned.pk) + self.executeOK(data, item=self.owned.pk) self.owned.refresh_from_db() self.assertEqual(self.owned.owner, self.user) data = {'user': self.user2.pk} - self.assertOK(data, item=self.owned.pk) + self.executeOK(data, item=self.owned.pk) self.owned.refresh_from_db() self.assertEqual(self.owned.owner, self.user2) self.assertEqual(self.owned.time_update, time_update) - self.assertForbidden(data, item=self.owned.pk) + self.executeForbidden(data, item=self.owned.pk) self.toggle_admin(True) data = {'user': self.user.pk} - self.assertOK(data, item=self.owned.pk) + self.executeOK(data, item=self.owned.pk) self.owned.refresh_from_db() self.assertEqual(self.owned.owner, self.user) @@ -98,22 +94,22 @@ class TestLibraryViewset(EndpointTester): time_update = self.owned.time_update data = {'user': self.invalid_user} - self.assertBadData(data, item=self.owned.pk) + self.executeBadData(data, item=self.owned.pk) data = {'user': self.user.pk} - self.assertNotFound(data, item=self.invalid_item) - self.assertForbidden(data, item=self.unowned.pk) + self.executeNotFound(data, item=self.invalid_item) + self.executeForbidden(data, item=self.unowned.pk) - self.assertOK(data, item=self.owned.pk) + self.executeOK(data, item=self.owned.pk) self.owned.refresh_from_db() self.assertEqual(self.owned.time_update, time_update) self.assertEqual(self.owned.editors(), [self.user]) - self.assertOK(data) + self.executeOK(data) self.assertEqual(self.owned.editors(), [self.user]) data = {'user': self.user2.pk} - self.assertOK(data) + self.executeOK(data) self.assertEqual(set(self.owned.editors()), set([self.user, self.user2])) @@ -122,25 +118,25 @@ class TestLibraryViewset(EndpointTester): time_update = self.owned.time_update data = {'user': self.invalid_user} - self.assertBadData(data, item=self.owned.pk) + self.executeBadData(data, item=self.owned.pk) data = {'user': self.user.pk} - self.assertNotFound(data, item=self.invalid_item) - self.assertForbidden(data, item=self.unowned.pk) + self.executeNotFound(data, item=self.invalid_item) + self.executeForbidden(data, item=self.unowned.pk) - self.assertOK(data, item=self.owned.pk) + self.executeOK(data, item=self.owned.pk) self.owned.refresh_from_db() self.assertEqual(self.owned.time_update, time_update) self.assertEqual(self.owned.editors(), []) Editor.add(item=self.owned, user=self.user) - self.assertOK(data) + self.executeOK(data) self.assertEqual(self.owned.editors(), []) Editor.add(item=self.owned, user=self.user) Editor.add(item=self.owned, user=self.user2) data = {'user': self.user2.pk} - self.assertOK(data) + self.executeOK(data) self.assertEqual(self.owned.editors(), [self.user]) @@ -149,30 +145,30 @@ class TestLibraryViewset(EndpointTester): time_update = self.owned.time_update data = {'users': [self.invalid_user]} - self.assertBadData(data, item=self.owned.pk) + self.executeBadData(data, item=self.owned.pk) data = {'users': [self.user.pk]} - self.assertNotFound(data, item=self.invalid_item) - self.assertForbidden(data, item=self.unowned.pk) + self.executeNotFound(data, item=self.invalid_item) + self.executeForbidden(data, item=self.unowned.pk) - self.assertOK(data, item=self.owned.pk) + self.executeOK(data, item=self.owned.pk) self.owned.refresh_from_db() self.assertEqual(self.owned.time_update, time_update) self.assertEqual(self.owned.editors(), [self.user]) - self.assertOK(data) + self.executeOK(data) self.assertEqual(self.owned.editors(), [self.user]) data = {'users': [self.user2.pk]} - self.assertOK(data) + self.executeOK(data) self.assertEqual(self.owned.editors(), [self.user2]) data = {'users': []} - self.assertOK(data) + self.executeOK(data) self.assertEqual(self.owned.editors(), []) data = {'users': [self.user2.pk, self.user.pk]} - self.assertOK(data) + self.executeOK(data) self.assertEqual(set(self.owned.editors()), set([self.user2, self.user])) @@ -181,7 +177,7 @@ class TestLibraryViewset(EndpointTester): response = self.execute(item=self.owned.pk) self.assertTrue(response.status_code in [status.HTTP_202_ACCEPTED, status.HTTP_204_NO_CONTENT]) - self.assertForbidden(item=self.unowned.pk) + self.executeForbidden(item=self.unowned.pk) self.toggle_admin(True) response = self.execute(item=self.unowned.pk) self.assertTrue(response.status_code in [status.HTTP_202_ACCEPTED, status.HTTP_204_NO_CONTENT]) @@ -189,15 +185,13 @@ class TestLibraryViewset(EndpointTester): @decl_endpoint('/api/library/active', method='get') def test_retrieve_common(self): - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertTrue(response_contains(response, self.common)) self.assertFalse(response_contains(response, self.unowned)) self.assertTrue(response_contains(response, self.owned)) self.logout() - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertTrue(response_contains(response, self.common)) self.assertFalse(response_contains(response, self.unowned)) self.assertFalse(response_contains(response, self.owned)) @@ -206,47 +200,42 @@ class TestLibraryViewset(EndpointTester): @decl_endpoint('/api/library/all', method='get') def test_retrieve_all(self): self.toggle_admin(False) - self.assertForbidden() + self.executeForbidden() self.toggle_admin(True) - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertTrue(response_contains(response, self.common)) self.assertTrue(response_contains(response, self.unowned)) self.assertTrue(response_contains(response, self.owned)) self.logout() - self.assertForbidden() + self.executeForbidden() @decl_endpoint('/api/library/active', method='get') def test_retrieve_subscribed(self): - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertFalse(response_contains(response, self.unowned)) Subscription.subscribe(user=self.user, item=self.unowned) Subscription.subscribe(user=self.user2, item=self.unowned) Subscription.subscribe(user=self.user2, item=self.owned) - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertTrue(response_contains(response, self.unowned)) self.assertEqual(len(response.data), 3) @decl_endpoint('/api/library/{item}/subscribe', method='post') def test_subscriptions(self): - self.assertNotFound(item=self.invalid_item) + self.executeNotFound(item=self.invalid_item) response = self.client.delete(f'/api/library/{self.unowned.pk}/unsubscribe') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertFalse(self.user in self.unowned.subscribers()) - response = self.execute(item=self.unowned.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(item=self.unowned.pk) self.assertTrue(self.user in self.unowned.subscribers()) - response = self.execute(item=self.unowned.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(item=self.unowned.pk) self.assertTrue(self.user in self.unowned.subscribers()) response = self.client.delete(f'/api/library/{self.unowned.pk}/unsubscribe') @@ -256,15 +245,13 @@ class TestLibraryViewset(EndpointTester): @decl_endpoint('/api/library/templates', method='get') def test_retrieve_templates(self): - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertFalse(response_contains(response, self.common)) self.assertFalse(response_contains(response, self.unowned)) self.assertFalse(response_contains(response, self.owned)) LibraryTemplate.objects.create(lib_source=self.unowned) - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertFalse(response_contains(response, self.common)) self.assertTrue(response_contains(response, self.unowned)) self.assertFalse(response_contains(response, self.owned)) @@ -284,12 +271,11 @@ class TestLibraryViewset(EndpointTester): ) data = {'title': 'Title1337'} - self.assertNotFound(data, item=self.invalid_item) - self.assertCreated(data, item=self.unowned.pk) + self.executeNotFound(data, item=self.invalid_item) + self.executeCreated(data, item=self.unowned.pk) data = {'title': 'Title1338'} - response = self.execute(data, item=self.owned.pk) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data, item=self.owned.pk) self.assertEqual(response.data['title'], data['title']) self.assertEqual(len(response.data['items']), 2) self.assertEqual(response.data['items'][0]['alias'], x12.alias) @@ -299,14 +285,12 @@ class TestLibraryViewset(EndpointTester): self.assertEqual(response.data['items'][1]['term_resolved'], d2.term_resolved) data = {'title': 'Title1340', 'items': []} - response = self.execute(data, item=self.owned.pk) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data, item=self.owned.pk) self.assertEqual(response.data['title'], data['title']) self.assertEqual(len(response.data['items']), 0) data = {'title': 'Title1341', 'items': [x12.pk]} - response = self.execute(data, item=self.owned.pk) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data, item=self.owned.pk) self.assertEqual(response.data['title'], data['title']) self.assertEqual(len(response.data['items']), 1) self.assertEqual(response.data['items'][0]['alias'], x12.alias) diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py b/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py index 33faab82..0cd9867f 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py @@ -1,9 +1,7 @@ ''' Testing API: Operations. ''' -from rest_framework import status - from apps.rsform.models import Constituenta, CstType, RSForm -from .EndpointTester import EndpointTester, decl_endpoint +from ..EndpointTester import EndpointTester, decl_endpoint class TestInlineSynthesis(EndpointTester): @@ -26,20 +24,20 @@ class TestInlineSynthesis(EndpointTester): 'items': [], 'substitutions': [] } - self.assertForbidden(data) + self.executeForbidden(data) data['receiver'] = invalid_id - self.assertBadData(data) + self.executeBadData(data) data['receiver'] = self.schema1.item.pk data['source'] = invalid_id - self.assertBadData(data) + self.executeBadData(data) data['source'] = self.schema1.item.pk - self.assertOK(data) + self.executeOK(data) data['items'] = [invalid_id] - self.assertBadData(data) + self.executeBadData(data) def test_inline_synthesis(self): @@ -70,8 +68,7 @@ class TestInlineSynthesis(EndpointTester): } ] } - response = self.execute(data) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data) result = {item['alias']: item for item in response.data['items']} self.assertEqual(len(result), 6) self.assertEqual(result['X2']['term_raw'], ks1_x2.term_raw) diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py b/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py index e0a10b16..3ad506e3 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py @@ -8,8 +8,8 @@ from rest_framework import status from apps.rsform.models import Constituenta, CstType, LibraryItem, LibraryItemType, RSForm +from ..EndpointTester import EndpointTester, decl_endpoint from ..testing_utils import response_contains -from .EndpointTester import EndpointTester, decl_endpoint class TestRSFormViewset(EndpointTester): @@ -39,8 +39,7 @@ class TestRSFormViewset(EndpointTester): @decl_endpoint('/api/rsforms/create-detailed', method='post') def test_create_rsform_json(self): data = {'title': 'Test123', 'comment': '123', 'alias': 'ks1'} - response = self.execute(data) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data) self.assertEqual(response.data['owner'], self.user.pk) self.assertEqual(response.data['title'], 'Test123') self.assertEqual(response.data['alias'], 'ks1') @@ -53,8 +52,7 @@ class TestRSFormViewset(EndpointTester): item_type=LibraryItemType.OPERATIONS_SCHEMA, title='Test3' ) - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertFalse(response_contains(response, non_schema)) self.assertTrue(response_contains(response, self.unowned.item)) self.assertTrue(response_contains(response, self.schema.item)) @@ -70,7 +68,7 @@ class TestRSFormViewset(EndpointTester): def test_contents(self): schema = RSForm.create(title='Title1') schema.insert_new('X1') - self.assertOK(item=schema.item.pk) + self.executeOK(item=schema.item.pk) @decl_endpoint('/api/rsforms/{item}/details', method='get') @@ -87,8 +85,7 @@ class TestRSFormViewset(EndpointTester): term_resolved='люди' ) - response = self.execute(item=schema.item.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(item=schema.item.pk) self.assertEqual(response.data['title'], 'Test') self.assertEqual(len(response.data['items']), 2) self.assertEqual(response.data['items'][0]['id'], x1.pk) @@ -107,15 +104,14 @@ class TestRSFormViewset(EndpointTester): schema = RSForm.create(title='Test') schema.insert_new('X1') data = {'expression': 'X1=X1'} - response = self.execute(data, item=schema.item.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data, item=schema.item.pk) self.assertEqual(response.data['parseResult'], True) self.assertEqual(response.data['syntax'], 'math') self.assertEqual(response.data['astText'], '[=[X1][X1]]') self.assertEqual(response.data['typification'], 'LOGIC') self.assertEqual(response.data['valueClass'], 'value') - self.assertOK(data, item=self.unowned_id) + self.executeOK(data, item=self.unowned_id) @decl_endpoint('/api/rsforms/{item}/resolve', method='post') @@ -127,8 +123,7 @@ class TestRSFormViewset(EndpointTester): ) data = {'text': '@{1|редкий} @{X1|plur,datv}'} - response = self.execute(data, item=schema.item.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data, item=schema.item.pk) self.assertEqual(response.data['input'], '@{1|редкий} @{X1|plur,datv}') self.assertEqual(response.data['output'], 'редким синим слонам') self.assertEqual(len(response.data['refs']), 2) @@ -165,8 +160,7 @@ class TestRSFormViewset(EndpointTester): def test_export_trs(self): schema = RSForm.create(title='Test') schema.insert_new('X1') - response = self.execute(item=schema.item.pk) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(item=schema.item.pk) self.assertEqual(response.headers['Content-Disposition'], 'attachment; filename=Schema.trs') with io.BytesIO(response.content) as stream: with ZipFile(stream, 'r') as zipped_file: @@ -177,13 +171,12 @@ class TestRSFormViewset(EndpointTester): @decl_endpoint('/api/rsforms/{item}/cst-create', method='post') def test_create_constituenta(self): data = {'alias': 'X3', 'cst_type': CstType.BASE} - self.assertForbidden(data, item=self.unowned_id) + self.executeForbidden(data, item=self.unowned_id) self.schema.insert_new('X1') x2 = self.schema.insert_new('X2') - response = self.execute(data, item=self.schema_id) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data, item=self.schema_id) self.assertEqual(response.data['new_cst']['alias'], 'X3') x3 = Constituenta.objects.get(alias=response.data['new_cst']['alias']) self.assertEqual(x3.order, 3) @@ -195,8 +188,7 @@ class TestRSFormViewset(EndpointTester): 'term_raw': 'test', 'term_forms': [{'text': 'form1', 'tags': 'sing,datv'}] } - response = self.execute(data, item=self.schema_id) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data, item=self.schema_id) self.assertEqual(response.data['new_cst']['alias'], data['alias']) x4 = Constituenta.objects.get(alias=response.data['new_cst']['alias']) self.assertEqual(x4.order, 3) @@ -223,14 +215,14 @@ class TestRSFormViewset(EndpointTester): ) data = {'target': x2_2.pk, 'alias': 'D2', 'cst_type': CstType.TERM} - self.assertForbidden(data, item=self.unowned_id) - self.assertBadData(data, item=self.schema_id) + self.executeForbidden(data, item=self.unowned_id) + self.executeBadData(data, item=self.schema_id) data = {'target': x1.pk, 'alias': x1.alias, 'cst_type': CstType.TERM} - self.assertBadData(data, item=self.schema_id) + self.executeBadData(data, item=self.schema_id) data = {'target': x1.pk, 'alias': x3.alias} - self.assertBadData(data, item=self.schema_id) + self.executeBadData(data, item=self.schema_id) d1 = self.schema.insert_new( alias='D1', @@ -242,8 +234,7 @@ class TestRSFormViewset(EndpointTester): self.assertEqual(x1.cst_type, CstType.BASE) data = {'target': x1.pk, 'alias': 'D2', 'cst_type': CstType.TERM} - response = self.execute(data, item=self.schema_id) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data, item=self.schema_id) self.assertEqual(response.data['new_cst']['alias'], 'D2') self.assertEqual(response.data['new_cst']['cst_type'], CstType.TERM) d1.refresh_from_db() @@ -270,14 +261,14 @@ class TestRSFormViewset(EndpointTester): unowned = self.unowned.insert_new('X2') data = {'substitutions': [{'original': x1.pk, 'substitution': unowned.pk, 'transfer_term': True}]} - self.assertForbidden(data, item=self.unowned_id) - self.assertBadData(data, item=self.schema_id) + self.executeForbidden(data, item=self.unowned_id) + self.executeBadData(data, item=self.schema_id) data = {'substitutions': [{'original': unowned.pk, 'substitution': x1.pk, 'transfer_term': True}]} - self.assertBadData(data, item=self.schema_id) + self.executeBadData(data, item=self.schema_id) data = {'substitutions': [{'original': x1.pk, 'substitution': x1.pk, 'transfer_term': True}]} - self.assertBadData(data, item=self.schema_id) + self.executeBadData(data, item=self.schema_id) d1 = self.schema.insert_new( alias='D1', @@ -285,9 +276,7 @@ class TestRSFormViewset(EndpointTester): definition_formal='X1' ) data = {'substitutions': [{'original': x1.pk, 'substitution': x2.pk, 'transfer_term': True}]} - response = self.execute(data, item=self.schema_id) - self.assertEqual(response.status_code, status.HTTP_200_OK) - + response = self.executeOK(data, item=self.schema_id) d1.refresh_from_db() x2.refresh_from_db() self.assertEqual(x2.term_raw, 'Test1') @@ -307,7 +296,7 @@ class TestRSFormViewset(EndpointTester): ) data = {'substitutions': []} - self.assertBadData(data) + self.executeBadData(data) data = {'substitutions': [ { @@ -321,7 +310,7 @@ class TestRSFormViewset(EndpointTester): 'transfer_term': True } ]} - self.assertBadData(data) + self.executeBadData(data) data = {'substitutions': [ { @@ -335,9 +324,7 @@ class TestRSFormViewset(EndpointTester): 'transfer_term': True } ]} - response = self.execute(data, item=self.schema_id) - self.assertEqual(response.status_code, status.HTTP_200_OK) - + response = self.executeOK(data, item=self.schema_id) d3.refresh_from_db() self.assertEqual(d3.definition_formal, r'D1 \ D2') @@ -352,8 +339,7 @@ class TestRSFormViewset(EndpointTester): 'definition_formal': '3', 'definition_raw': '4' } - response = self.execute(data, item=self.schema_id) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data, item=self.schema_id) self.assertEqual(response.data['new_cst']['alias'], 'X3') self.assertEqual(response.data['new_cst']['cst_type'], CstType.BASE) self.assertEqual(response.data['new_cst']['convention'], '1') @@ -369,16 +355,15 @@ class TestRSFormViewset(EndpointTester): self.set_params(item=self.schema_id) data = {'items': [1337]} - self.assertBadData(data) + self.executeBadData(data) x1 = self.schema.insert_new('X1') x2 = self.schema.insert_new('X2') data = {'items': [x1.pk]} - response = self.execute(data) + response = self.executeOK(data) x2.refresh_from_db() self.schema.item.refresh_from_db() - self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['items']), 1) self.assertEqual(self.schema.constituents().count(), 1) self.assertEqual(x2.alias, 'X2') @@ -386,7 +371,7 @@ class TestRSFormViewset(EndpointTester): x3 = self.unowned.insert_new('X1') data = {'items': [x3.pk]} - self.assertBadData(data, item=self.schema_id) + self.executeBadData(data, item=self.schema_id) @decl_endpoint('/api/rsforms/{item}/cst-moveto', method='patch') @@ -394,42 +379,39 @@ class TestRSFormViewset(EndpointTester): self.set_params(item=self.schema_id) data = {'items': [1337], 'move_to': 1} - self.assertBadData(data) + self.executeBadData(data) x1 = self.schema.insert_new('X1') x2 = self.schema.insert_new('X2') data = {'items': [x2.pk], 'move_to': 1} - response = self.execute(data) + response = self.executeOK(data) x1.refresh_from_db() x2.refresh_from_db() - self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['id'], self.schema_id) self.assertEqual(x1.order, 2) self.assertEqual(x2.order, 1) x3 = self.unowned.insert_new('X1') data = {'items': [x3.pk], 'move_to': 1} - self.assertBadData(data) + self.executeBadData(data) @decl_endpoint('/api/rsforms/{item}/reset-aliases', method='patch') def test_reset_aliases(self): self.set_params(item=self.schema_id) - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertEqual(response.data['id'], self.schema_id) x2 = self.schema.insert_new('X2') x1 = self.schema.insert_new('X1') d11 = self.schema.insert_new('D11') - response = self.execute() + response = self.executeOK() x1.refresh_from_db() x2.refresh_from_db() d11.refresh_from_db() - self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(x2.order, 1) self.assertEqual(x2.alias, 'X1') self.assertEqual(x1.order, 2) @@ -437,7 +419,7 @@ class TestRSFormViewset(EndpointTester): self.assertEqual(d11.order, 3) self.assertEqual(d11.alias, 'D1') - self.assertOK() + self.executeOK() @decl_endpoint('/api/rsforms/{item}/load-trs', method='patch') @@ -484,13 +466,12 @@ class TestRSFormViewset(EndpointTester): ) invalid_id = f1.pk + 1337 - self.assertBadData({'target': invalid_id}) - self.assertBadData({'target': x1.pk}) - self.assertBadData({'target': s2.pk}) + self.executeBadData({'target': invalid_id}) + self.executeBadData({'target': x1.pk}) + self.executeBadData({'target': s2.pk}) # Testing simple structure - response = self.execute({'target': s1.pk}) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data={'target': s1.pk}) result = response.data['schema'] items = [item for item in result['items'] if item['id'] in response.data['cst_list']] self.assertEqual(len(items), 2) @@ -501,8 +482,7 @@ class TestRSFormViewset(EndpointTester): # Testing complex structure s3.refresh_from_db() - response = self.execute({'target': s3.pk}) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data={'target': s3.pk}) result = response.data['schema'] items = [item for item in result['items'] if item['id'] in response.data['cst_list']] self.assertEqual(len(items), 8) @@ -511,8 +491,7 @@ class TestRSFormViewset(EndpointTester): # Testing function f1.refresh_from_db() - response = self.execute({'target': f1.pk}) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data={'target': f1.pk}) result = response.data['schema'] items = [item for item in result['items'] if item['id'] in response.data['cst_list']] self.assertEqual(len(items), 2) diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_rslang.py b/rsconcept/backend/apps/rsform/tests/s_views/t_rslang.py index 185586b2..910e852e 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_rslang.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_rslang.py @@ -1,44 +1,37 @@ ''' Testing views ''' -from rest_framework import status -from rest_framework.exceptions import ErrorDetail - -from .EndpointTester import EndpointTester, decl_endpoint +from ..EndpointTester import EndpointTester, decl_endpoint class TestRSLanguageViews(EndpointTester): ''' Test RS language endpoints. ''' - @decl_endpoint('/api/rslang/to-ascii', method='post') def test_convert_to_ascii(self): data = {'data': '1=1'} - self.assertBadData(data) + self.executeBadData(data) data = {'expression': '1=1'} - response = self.execute(data) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data) self.assertEqual(response.data['result'], r'1 \eq 1') @decl_endpoint('/api/rslang/to-math', method='post') def test_convert_to_math(self): data = {'data': r'1 \eq 1'} - self.assertBadData(data) + self.executeBadData(data) data = {'expression': r'1 \eq 1'} - response = self.execute(data) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data) self.assertEqual(response.data['result'], r'1=1') @decl_endpoint('/api/rslang/parse-expression', method='post') def test_parse_expression(self): data = {'data': r'1=1'} - self.assertBadData(data) + self.executeBadData(data) data = {'expression': r'1=1'} - response = self.execute(data) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(data) self.assertEqual(response.data['parseResult'], True) self.assertEqual(response.data['syntax'], 'math') self.assertEqual(response.data['astText'], '[=[1][1]]') diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py b/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py index 62fcef7a..d2b273a7 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py @@ -8,7 +8,7 @@ from rest_framework import status from apps.rsform.models import Constituenta, RSForm -from .EndpointTester import EndpointTester, decl_endpoint +from ..EndpointTester import EndpointTester, decl_endpoint class TestVersionViews(EndpointTester): @@ -31,12 +31,11 @@ class TestVersionViews(EndpointTester): invalid_id = 1338 data = {'version': '1.0.0', 'description': 'test'} - self.assertNotFound(data, schema=invalid_id) - self.assertForbidden(data, schema=self.unowned.pk) - self.assertBadData(invalid_data, schema=self.owned.pk) + self.executeNotFound(data, schema=invalid_id) + self.executeForbidden(data, schema=self.unowned.pk) + self.executeBadData(invalid_data, schema=self.owned.pk) - response = self.execute(data, schema=self.owned.pk) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + response = self.executeCreated(data, schema=self.owned.pk) self.assertTrue('version' in response.data) self.assertTrue('schema' in response.data) self.assertTrue(response.data['version'] in [v['id'] for v in response.data['schema']['versions']]) @@ -47,18 +46,17 @@ class TestVersionViews(EndpointTester): version_id = self._create_version({'version': '1.0.0', 'description': 'test'}) invalid_id = version_id + 1337 - self.assertNotFound(schema=invalid_id, version=invalid_id) - self.assertNotFound(schema=self.owned.pk, version=invalid_id) - self.assertNotFound(schema=invalid_id, version=version_id) - self.assertNotFound(schema=self.unowned.pk, version=version_id) + self.executeNotFound(schema=invalid_id, version=invalid_id) + self.executeNotFound(schema=self.owned.pk, version=invalid_id) + self.executeNotFound(schema=invalid_id, version=version_id) + self.executeNotFound(schema=self.unowned.pk, version=version_id) self.owned.alias = 'NewName' self.owned.save() self.x1.alias = 'X33' self.x1.save() - response = self.execute(schema=self.owned.pk, version=version_id) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(schema=self.owned.pk, version=version_id) self.assertNotEqual(response.data['alias'], self.owned.alias) self.assertNotEqual(response.data['items'][0]['alias'], self.x1.alias) self.assertEqual(response.data['version'], version_id) @@ -70,26 +68,25 @@ class TestVersionViews(EndpointTester): version_id = self._create_version(data) invalid_id = version_id + 1337 - self.assertNotFound(version=invalid_id) + self.executeNotFound(version=invalid_id) self.set_params(version=version_id) self.logout() - response = self.execute() - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK() self.assertEqual(response.data['version'], data['version']) self.assertEqual(response.data['description'], data['description']) self.assertEqual(response.data['item'], self.owned.pk) data = {'version': '1.2.0', 'description': 'test1'} self.method = 'patch' - self.assertForbidden(data) + self.executeForbidden(data) self.method = 'delete' - self.assertForbidden() + self.executeForbidden() self.client.force_authenticate(user=self.user) self.method = 'patch' - self.assertOK(data) + self.executeOK(data) response = self.get() self.assertEqual(response.data['version'], data['version']) self.assertEqual(response.data['description'], data['description']) @@ -113,8 +110,7 @@ class TestVersionViews(EndpointTester): a1.definition_formal = 'X1=X2' a1.save() - response = self.get(schema=self.owned.pk, version=version_id) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(schema=self.owned.pk, version=version_id) loaded_a1 = response.data['items'][1] self.assertEqual(loaded_a1['definition_formal'], 'X1=X1') self.assertEqual(loaded_a1['parse']['status'], 'verified') @@ -123,11 +119,10 @@ class TestVersionViews(EndpointTester): @decl_endpoint('/api/versions/{version}/export-file', method='get') def test_export_version(self): invalid_id = 1338 - self.assertNotFound(version=invalid_id) + self.executeNotFound(version=invalid_id) version_id = self._create_version({'version': '1.0.0', 'description': 'test'}) - response = self.get(version=version_id) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(version=version_id) self.assertEqual( response.headers['Content-Disposition'], f'attachment; filename={self.owned.alias}.trs' @@ -156,10 +151,9 @@ class TestVersionViews(EndpointTester): x3.order = 1 x3.save() - self.assertNotFound(version=invalid_id) + self.executeNotFound(version=invalid_id) - response = self.execute(version=version_id) - self.assertEqual(response.status_code, status.HTTP_200_OK) + response = self.executeOK(version=version_id) x1.refresh_from_db() x2.refresh_from_db() self.assertEqual(len(response.data['items']), 3) diff --git a/rsconcept/backend/apps/users/messages.py b/rsconcept/backend/apps/users/messages.py index a99495fb..a7ea4f94 100644 --- a/rsconcept/backend/apps/users/messages.py +++ b/rsconcept/backend/apps/users/messages.py @@ -8,3 +8,7 @@ def passwordAuthFailed(): def passwordsNotMatch(): return 'Введенные пароли не совпадают' + + +def emailAlreadyTaken(): + return 'Пользователь с данным email уже существует' diff --git a/rsconcept/backend/apps/users/serializers.py b/rsconcept/backend/apps/users/serializers.py index 984804f7..519f74d6 100644 --- a/rsconcept/backend/apps/users/serializers.py +++ b/rsconcept/backend/apps/users/serializers.py @@ -1,4 +1,6 @@ ''' Serializers: User profile and Authorization. ''' +from urllib import request + from django.contrib.auth import authenticate from django.contrib.auth.password_validation import validate_password from rest_framework import serializers @@ -99,6 +101,17 @@ class UserSerializer(serializers.ModelSerializer): 'last_name', ] + def validate(self, attrs): + attrs = super().validate(attrs) + if 'email' in attrs: + maybe_user = models.User.objects.filter(email=attrs['email']) + if maybe_user.exists(): + if maybe_user.count() > 1 or maybe_user.first().pk != self.context['request'].user.pk: + raise serializers.ValidationError({ + 'email': msg.emailAlreadyTaken() + }) + return attrs + class ChangePasswordSerializer(serializers.Serializer): ''' Serializer: Change password. ''' @@ -130,11 +143,17 @@ class SignupSerializer(serializers.ModelSerializer): raise serializers.ValidationError({ 'password': msg.passwordsNotMatch() }) + if models.User.objects.filter(email=attrs['email']).exists(): + raise serializers.ValidationError({ + 'email': msg.emailAlreadyTaken() + }) return attrs def create(self, validated_data): user = models.User.objects.create_user( - validated_data['username'], validated_data['email'], validated_data['password'] + username=validated_data['username'], + email=validated_data['email'], + password=validated_data['password'] ) user.first_name = validated_data['first_name'] user.last_name = validated_data['last_name'] diff --git a/rsconcept/backend/apps/users/tests/t_views.py b/rsconcept/backend/apps/users/tests/t_views.py index 57a4a738..cc7f51b2 100644 --- a/rsconcept/backend/apps/users/tests/t_views.py +++ b/rsconcept/backend/apps/users/tests/t_views.py @@ -1,195 +1,186 @@ -''' Testing views ''' +''' Testing API: users. ''' from rest_framework.test import APIClient, APITestCase -from apps.rsform.models import LibraryItem, LibraryItemType +from apps.rsform.tests.EndpointTester import EndpointTester, decl_endpoint from apps.users.models import User -class TestUserAPIViews(APITestCase): +class TestUserAPIViews(EndpointTester): + ''' Testing Authentication views. ''' + def setUp(self): - self.username = 'UserTest' - self.email = 'test@test.com' - self.password = 'password' - self.user = User.objects.create_user( - self.username, self.email, self.password - ) - self.client = APIClient() + super().setUp() + + @decl_endpoint('/users/api/login', method='post') def test_login(self): - data = {'username': self.username, 'password': self.password} - response = self.client.post( - '/users/api/login', - data=data, format='json' - ) - self.assertEqual(response.status_code, 202) + self.logout() + data = {'username': self.user.username, 'password': 'invalid'} + self.executeBadData(data) + data = {'username': self.user.username, 'password': 'password'} + self.executeAccepted(data) + self.executeAccepted(data) + + + @decl_endpoint('/users/api/logout', method='post') def test_logout(self): - self.assertEqual(self.client.post('/users/api/logout').status_code, 403) + self.logout() + self.executeForbidden() - self.client.force_login(user=self.user) - self.assertEqual(self.client.get('/users/api/logout').status_code, 405) - self.assertEqual(self.client.post('/users/api/logout').status_code, 204) + self.login() + self.executeNoContent() + self.executeNoContent() - self.assertEqual(self.client.post('/users/api/logout').status_code, 403) + @decl_endpoint('/users/api/auth', method='get') def test_auth(self): - LibraryItem.objects.create(item_type=LibraryItemType.RSFORM, title='T1') - item = LibraryItem.objects.create( - item_type=LibraryItemType.RSFORM, - title='Test', - alias='T1', - is_common=True, - owner=self.user - ) - response = self.client.get('/users/api/auth') - self.assertEqual(response.status_code, 200) + response = self.executeOK() + self.assertEqual(response.data['id'], self.user.pk) + self.assertEqual(response.data['username'], self.user.username) + self.assertEqual(response.data['is_staff'], self.user.is_staff) + self.assertEqual(response.data['subscriptions'], []) + + self.logout() + response = self.executeOK() self.assertEqual(response.data['id'], None) self.assertEqual(response.data['username'], '') self.assertEqual(response.data['is_staff'], False) self.assertEqual(response.data['subscriptions'], []) - self.client.force_login(self.user) - response = self.client.get('/users/api/auth') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.data['id'], self.user.pk) - self.assertEqual(response.data['username'], self.user.username) - self.assertEqual(response.data['is_staff'], self.user.is_staff) - self.assertEqual(response.data['subscriptions'], [item.pk]) +class TestUserUserProfileAPIView(EndpointTester): + ''' Testing User profile views. ''' -class TestUserUserProfileAPIView(APITestCase): def setUp(self): - self.username = 'UserTest' - self.email = 'test@test.com' - self.password = 'password' - self.first_name = 'John' - self.user = User.objects.create_user( - self.username, self.email, self.password - ) - self.user.first_name = self.first_name + super().setUp() + self.user.first_name = 'John' + self.user.second_name = 'Smith' self.user.save() - self.client = APIClient() + + @decl_endpoint('/users/api/profile', method='get') def test_read_profile(self): - self.assertEqual(self.client.get('/users/api/profile').status_code, 403) - self.client.force_login(user=self.user) - response = self.client.get('/users/api/profile') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.data['username'], self.username) - self.assertEqual(response.data['email'], self.email) - self.assertEqual(response.data['first_name'], self.first_name) - self.assertEqual(response.data['last_name'], '') + response = self.executeOK() + self.assertEqual(response.data['username'], self.user.username) + self.assertEqual(response.data['email'], self.user.email) + self.assertEqual(response.data['first_name'], self.user.first_name) + self.assertEqual(response.data['last_name'], self.user.last_name) - def test_patch_profile(self): - self.client.force_login(user=self.user) + self.logout() + self.executeForbidden() + + + @decl_endpoint('/users/api/profile', method='patch') + def test_edit_profile(self): data = { 'email': '123@mail.ru', 'first_name': 'firstName', 'last_name': 'lastName', } - response = self.client.patch( - '/users/api/profile', - data=data, format='json' - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.data['email'], '123@mail.ru') - self.assertEqual(response.data['first_name'], 'firstName') - self.assertEqual(response.data['last_name'], 'lastName') - - def test_edit_profile(self): - new_mail = 'newmail@gmail.com' - data = {'email': new_mail} - response = self.client.patch( - '/users/api/profile', - data=data, format='json' - ) - self.assertEqual(response.status_code, 403) - - self.client.force_login(user=self.user) - response = self.client.patch( - '/users/api/profile', - data=data, format='json' - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.data['username'], self.username) - self.assertEqual(response.data['email'], new_mail) - - def test_change_password(self): - newpassword = 'pw2' - data = { - 'old_password': self.password, - 'new_password': newpassword - } - response = self.client.patch( - '/users/api/change-password', - data=data, format='json' - ) - self.assertEqual(response.status_code, 403) - self.assertFalse(self.client.login(username=self.user.username, password=newpassword)) - self.assertTrue(self.client.login(username=self.user.username, password=self.password)) - - invalid = { - 'old_password': 'invalid', - 'new_password': newpassword - } - response = self.client.patch( - '/users/api/change-password', - data=invalid, format='json' - ) - self.assertEqual(response.status_code, 400) - - oldHash = self.user.password - self.client.force_login(user=self.user) - response = self.client.patch( - '/users/api/change-password', - data=data, format='json' - ) + response = self.executeOK(data) + self.user.refresh_from_db() + self.assertEqual(response.data['email'], '123@mail.ru') + self.assertEqual(self.user.email, '123@mail.ru') + self.assertEqual(response.data['first_name'], 'firstName') + self.assertEqual(self.user.first_name, 'firstName') + self.assertEqual(response.data['last_name'], 'lastName') + self.assertEqual(self.user.last_name, 'lastName') + + data = { + 'email': data['email'], + 'first_name': 'new', + 'last_name': 'new2', + } + self.executeOK(data) + + data = {'email': self.user2.email} + self.executeBadData(data) + + self.logout() + self.executeForbidden() + + + @decl_endpoint('/users/api/change-password', method='patch') + def test_change_password(self): + data = { + 'old_password': 'invalid', + 'new_password': 'password2' + } + self.executeBadData(data) + + data = { + 'old_password': 'password', + 'new_password': 'password2' + } + oldHash = self.user.password + response = self.executeNoContent(data) self.user.refresh_from_db() - self.assertEqual(response.status_code, 204) self.assertNotEqual(self.user.password, oldHash) - self.assertTrue(self.client.login(username=self.user.username, password=newpassword)) - self.assertFalse(self.client.login(username=self.user.username, password=self.password)) + self.assertTrue(self.client.login(username=self.user.username, password='password2')) + self.assertFalse(self.client.login(username=self.user.username, password='password')) + self.logout() + self.executeForbidden() + + + @decl_endpoint('/users/api/password-reset', method='post') def test_password_reset_request(self): - data = { - 'email': 'invalid@gmail.com' - } - response = self.client.post( - '/users/api/password-reset', - data=data, format='json' - ) - self.assertEqual(response.status_code, 400) - - data = { - 'email': self.email - } - response = self.client.post( - '/users/api/password-reset', - data=data, format='json' - ) - self.assertEqual(response.status_code, 200) + self.executeBadData({'email': 'invalid@mail.ru'}) + self.executeOK({'email': self.user.email}) + # TODO: check if mail server actually sent email and if reset procedure works -class TestSignupAPIView(APITestCase): +class TestSignupAPIView(EndpointTester): + ''' Testing signup. ''' + def setUp(self): - self.client = APIClient() + super().setUp() + + @decl_endpoint('/users/api/signup', method='post') def test_signup(self): data = { - 'username': 'TestUser', - 'email': 'email@mail.ru', + 'username': 'NewUser', + 'email': 'newMail@mail.ru', + 'password': 'Test@@123', + 'password2': 'Test@@123456', + 'first_name': 'firstName', + 'last_name': 'lastName' + } + self.executeBadData(data) + + data = { + 'username': 'NewUser', + 'email': 'newMail@mail.ru', 'password': 'Test@@123', 'password2': 'Test@@123', 'first_name': 'firstName', - 'last_name': 'lastName', + 'last_name': 'lastName' } - response = self.client.post( - '/users/api/signup', - data=data, format='json' - ) - self.assertEqual(response.status_code, 201) + response = self.executeCreated(data) self.assertTrue('id' in response.data) - self.assertEqual(response.data['username'], 'TestUser') - self.assertEqual(response.data['email'], 'email@mail.ru') - self.assertEqual(response.data['first_name'], 'firstName') - self.assertEqual(response.data['last_name'], 'lastName') + self.assertEqual(response.data['username'], data['username']) + self.assertEqual(response.data['email'], data['email']) + self.assertEqual(response.data['first_name'], data['first_name']) + self.assertEqual(response.data['last_name'], data['last_name']) + + data = { + 'username': 'NewUser', + 'email': 'newMail2@mail.ru', + 'password': 'Test@@123', + 'password2': 'Test@@123', + 'first_name': 'firstName', + 'last_name': 'lastName' + } + self.executeBadData(data) + + data = { + 'username': 'NewUser2', + 'email': self.user.email, + 'password': 'Test@@123', + 'password2': 'Test@@123', + 'first_name': 'firstName', + 'last_name': 'lastName' + } + self.executeBadData(data)