''' Testing views ''' import os import io from zipfile import ZipFile from rest_framework.test import APITestCase, APIRequestFactory, APIClient from rest_framework.exceptions import ErrorDetail from cctext import ReferenceType, split_grams from apps.users.models import User from apps.rsform.models import ( Syntax, RSForm, Constituenta, CstType, LibraryItem, LibraryItemType, Subscription, LibraryTemplate ) from apps.rsform.views import ( convert_to_ascii, convert_to_math, parse_expression, inflect, parse_text, generate_lexeme ) def _response_contains(response, item: LibraryItem) -> bool: return any(x for x in response.data if x['id'] == item.pk) class TestConstituentaAPI(APITestCase): ''' Testing Constituenta view. ''' def setUp(self): self.factory = APIRequestFactory() self.user = User.objects.create(username='UserTest') self.client = APIClient() self.client.force_authenticate(user=self.user) self.rsform_owned = RSForm.create(title='Test', alias='T1', owner=self.user) self.rsform_unowned = RSForm.create(title='Test2', alias='T2') self.cst1 = Constituenta.objects.create( alias='X1', schema=self.rsform_owned.item, order=1, convention='Test', term_raw='Test1', term_resolved='Test1R', term_forms=[{'text':'form1', 'tags':'sing,datv'}]) self.cst2 = Constituenta.objects.create( alias='X2', schema=self.rsform_unowned.item, order=1, convention='Test1', term_raw='Test2', term_resolved='Test2R') self.cst3 = Constituenta.objects.create( alias='X3', schema=self.rsform_owned.item, order=2, term_raw='Test3', term_resolved='Test3', definition_raw='Test1', definition_resolved='Test2') def test_retrieve(self): response = self.client.get(f'/api/constituents/{self.cst1.id}') self.assertEqual(response.status_code, 200) self.assertEqual(response.data['alias'], self.cst1.alias) self.assertEqual(response.data['convention'], self.cst1.convention) def test_partial_update(self): data = {'convention': 'tt'} response = self.client.patch( f'/api/constituents/{self.cst2.id}', data=data, format='json' ) self.assertEqual(response.status_code, 403) self.client.logout() response = self.client.patch( f'/api/constituents/{self.cst1.id}', data=data, format='json' ) self.assertEqual(response.status_code, 403) self.client.force_authenticate(user=self.user) response = self.client.patch( f'/api/constituents/{self.cst1.id}', data=data, format='json' ) self.assertEqual(response.status_code, 200) self.cst1.refresh_from_db() self.assertEqual(response.data['convention'], 'tt') self.assertEqual(self.cst1.convention, 'tt') response = self.client.patch( f'/api/constituents/{self.cst1.id}', data=data, format='json' ) self.assertEqual(response.status_code, 200) def test_update_resolved_norefs(self): data = { 'term_raw': 'New term', 'definition_raw': 'New def' } response = self.client.patch(f'/api/constituents/{self.cst3.id}', data, format='json') self.assertEqual(response.status_code, 200) self.cst3.refresh_from_db() self.assertEqual(response.data['term_resolved'], 'New term') self.assertEqual(self.cst3.term_resolved, 'New term') self.assertEqual(response.data['definition_resolved'], 'New def') self.assertEqual(self.cst3.definition_resolved, 'New def') def test_update_resolved_refs(self): data = { 'term_raw': '@{X1|nomn,sing}', 'definition_raw': '@{X1|nomn,sing} @{X1|sing,datv}' } response = self.client.patch( f'/api/constituents/{self.cst3.id}', data=data, format='json' ) self.assertEqual(response.status_code, 200) 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) self.assertEqual(self.cst3.definition_resolved, f'{self.cst1.term_resolved} form1') self.assertEqual(response.data['definition_resolved'], f'{self.cst1.term_resolved} form1') def test_readonly_cst_fields(self): data = {'alias': 'X33', 'order': 10} response = self.client.patch( f'/api/constituents/{self.cst1.id}', data=data, format='json' ) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['alias'], 'X1') self.assertEqual(response.data['alias'], self.cst1.alias) self.assertEqual(response.data['order'], self.cst1.order) class TestLibraryViewset(APITestCase): ''' Testing Library view. ''' def setUp(self): self.factory = APIRequestFactory() self.user = User.objects.create(username='UserTest') self.client = APIClient() self.client.force_authenticate(user=self.user) self.owned = LibraryItem.objects.create( item_type=LibraryItemType.RSFORM, title='Test', alias='T1', owner=self.user ) self.unowned = LibraryItem.objects.create( item_type=LibraryItemType.RSFORM, title='Test2', alias='T2' ) self.common = LibraryItem.objects.create( item_type=LibraryItemType.RSFORM, title='Test3', alias='T3', is_common=True ) def test_create_anonymous(self): self.client.logout() data = {'title': 'Title'} response = self.client.post('/api/library', data=data, format='json') self.assertEqual(response.status_code, 403) def test_create_populate_user(self): data = {'title': 'Title'} response = self.client.post('/api/library', data=data, format='json') self.assertEqual(response.status_code, 201) self.assertEqual(response.data['title'], 'Title') self.assertEqual(response.data['owner'], self.user.id) def test_update(self): data = {'id': self.owned.id, 'title': 'New title'} response = self.client.patch( f'/api/library/{self.owned.id}', data=data, format='json' ) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['title'], 'New title') self.assertEqual(response.data['alias'], self.owned.alias) def test_update_unowned(self): data = {'id': self.unowned.id, 'title': 'New title'} response = self.client.patch( f'/api/library/{self.unowned.id}', data=data, format='json' ) self.assertEqual(response.status_code, 403) def test_destroy(self): response = self.client.delete(f'/api/library/{self.owned.id}') self.assertTrue(response.status_code in [202, 204]) def test_destroy_admin_override(self): response = self.client.delete(f'/api/library/{self.unowned.id}') self.assertEqual(response.status_code, 403) self.user.is_staff = True self.user.save() response = self.client.delete(f'/api/library/{self.unowned.id}') self.assertTrue(response.status_code in [202, 204]) def test_claim(self): response = self.client.post(f'/api/library/{self.owned.id}/claim') self.assertEqual(response.status_code, 403) self.owned.is_common = True self.owned.save() response = self.client.post(f'/api/library/{self.owned.id}/claim') self.assertEqual(response.status_code, 304) response = self.client.post(f'/api/library/{self.unowned.id}/claim') self.assertEqual(response.status_code, 403) self.assertFalse(self.user in self.unowned.subscribers()) self.unowned.is_common = True self.unowned.save() response = self.client.post(f'/api/library/{self.unowned.id}/claim') self.assertEqual(response.status_code, 200) self.unowned.refresh_from_db() self.assertEqual(self.unowned.owner, self.user) self.assertEqual(self.unowned.owner, self.user) self.assertTrue(self.user in self.unowned.subscribers()) def test_claim_anonymous(self): self.client.logout() response = self.client.post(f'/api/library/{self.owned.id}/claim') self.assertEqual(response.status_code, 403) def test_retrieve_common(self): self.client.logout() response = self.client.get('/api/library/active') self.assertEqual(response.status_code, 200) self.assertTrue(_response_contains(response, self.common)) self.assertFalse(_response_contains(response, self.unowned)) self.assertFalse(_response_contains(response, self.owned)) def test_retrieve_owned(self): response = self.client.get('/api/library/active') self.assertEqual(response.status_code, 200) self.assertTrue(_response_contains(response, self.common)) self.assertFalse(_response_contains(response, self.unowned)) self.assertTrue(_response_contains(response, self.owned)) def test_retrieve_subscribed(self): response = self.client.get('/api/library/active') self.assertEqual(response.status_code, 200) self.assertFalse(_response_contains(response, self.unowned)) user2 = User.objects.create(username='UserTest2') Subscription.subscribe(user=self.user, item=self.unowned) Subscription.subscribe(user=user2, item=self.unowned) Subscription.subscribe(user=user2, item=self.owned) response = self.client.get('/api/library/active') self.assertEqual(response.status_code, 200) self.assertTrue(_response_contains(response, self.unowned)) self.assertEqual(len(response.data), 3) def test_subscriptions(self): response = self.client.delete(f'/api/library/{self.unowned.id}/unsubscribe') self.assertEqual(response.status_code, 204) self.assertFalse(self.user in self.unowned.subscribers()) response = self.client.post(f'/api/library/{self.unowned.id}/subscribe') self.assertEqual(response.status_code, 204) self.assertTrue(self.user in self.unowned.subscribers()) response = self.client.post(f'/api/library/{self.unowned.id}/subscribe') self.assertEqual(response.status_code, 204) self.assertTrue(self.user in self.unowned.subscribers()) response = self.client.delete(f'/api/library/{self.unowned.id}/unsubscribe') self.assertEqual(response.status_code, 204) self.assertFalse(self.user in self.unowned.subscribers()) def test_retrieve_templates(self): response = self.client.get('/api/library/templates') self.assertEqual(response.status_code, 200) 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.client.get('/api/library/templates') self.assertEqual(response.status_code, 200) self.assertFalse(_response_contains(response, self.common)) self.assertTrue(_response_contains(response, self.unowned)) self.assertFalse(_response_contains(response, self.owned)) class TestRSFormViewset(APITestCase): ''' Testing RSForm view. ''' def setUp(self): self.factory = APIRequestFactory() self.user = User.objects.create(username='UserTest') self.client = APIClient() self.client.force_authenticate(user=self.user) self.owned = RSForm.create(title='Test', alias='T1', owner=self.user) self.unowned = RSForm.create(title='Test2', alias='T2') def test_list(self): non_schema = LibraryItem.objects.create( item_type=LibraryItemType.OPERATIONS_SCHEMA, title='Test3' ) response = self.client.get('/api/rsforms') self.assertEqual(response.status_code, 200) self.assertFalse(_response_contains(response, non_schema)) self.assertTrue(_response_contains(response, self.unowned.item)) self.assertTrue(_response_contains(response, self.owned.item)) response = self.client.get('/api/library') self.assertEqual(response.status_code, 200) self.assertTrue(_response_contains(response, non_schema)) self.assertTrue(_response_contains(response, self.unowned.item)) self.assertTrue(_response_contains(response, self.owned.item)) def test_contents(self): schema = RSForm.create(title='Title1') schema.insert_last(alias='X1', insert_type=CstType.BASE) response = self.client.get(f'/api/rsforms/{schema.item.id}/contents') self.assertEqual(response.status_code, 200) def test_details(self): schema = RSForm.create(title='Test', owner=self.user) x1 = schema.insert_at(1, 'X1', CstType.BASE) x2 = schema.insert_at(2, 'X2', CstType.BASE) x1.term_raw = 'человек' x1.term_resolved = 'человек' x2.term_raw = '@{X1|plur}' x2.term_resolved = 'люди' x1.save() x2.save() response = self.client.get(f'/api/rsforms/{schema.item.id}/details') self.assertEqual(response.status_code, 200) self.assertEqual(response.data['title'], 'Test') self.assertEqual(len(response.data['items']), 2) self.assertEqual(response.data['items'][0]['id'], x1.id) self.assertEqual(response.data['items'][0]['parse']['status'], 'verified') self.assertEqual(response.data['items'][0]['term_raw'], x1.term_raw) self.assertEqual(response.data['items'][0]['term_resolved'], x1.term_resolved) self.assertEqual(response.data['items'][1]['id'], x2.id) self.assertEqual(response.data['items'][1]['term_raw'], x2.term_raw) self.assertEqual(response.data['items'][1]['term_resolved'], x2.term_resolved) self.assertEqual(response.data['subscribers'], [self.user.pk]) def test_check(self): schema = RSForm.create(title='Test') schema.insert_at(1, 'X1', CstType.BASE) data = {'expression': 'X1=X1'} response = self.client.post( f'/api/rsforms/{schema.item.id}/check', data=data, format='json' ) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['parseResult'], True) self.assertEqual(response.data['syntax'], Syntax.MATH) self.assertEqual(response.data['astText'], '[=[X1][X1]]') self.assertEqual(response.data['typification'], 'LOGIC') self.assertEqual(response.data['valueClass'], 'value') response = self.client.post( f'/api/rsforms/{self.unowned.item.id}/check', data=data, format='json' ) self.assertEqual(response.status_code, 200) def test_resolve(self): schema = RSForm.create(title='Test') x1 = schema.insert_at(1, 'X1', CstType.BASE) x1.term_resolved = 'синий слон' x1.save() data = {'text': '@{1|редкий} @{X1|plur,datv}'} response = self.client.post( f'/api/rsforms/{schema.item.id}/resolve', data=data, format='json' ) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['input'], '@{1|редкий} @{X1|plur,datv}') self.assertEqual(response.data['output'], 'редким синим слонам') self.assertEqual(len(response.data['refs']), 2) self.assertEqual(response.data['refs'][0]['type'], ReferenceType.syntactic.value) self.assertEqual(response.data['refs'][0]['resolved'], 'редким') self.assertEqual(response.data['refs'][0]['data']['offset'], 1) self.assertEqual(response.data['refs'][0]['data']['nominal'], 'редкий') self.assertEqual(response.data['refs'][0]['pos_input']['start'], 0) self.assertEqual(response.data['refs'][0]['pos_input']['finish'], 11) self.assertEqual(response.data['refs'][0]['pos_output']['start'], 0) self.assertEqual(response.data['refs'][0]['pos_output']['finish'], 6) self.assertEqual(response.data['refs'][1]['type'], ReferenceType.entity.value) self.assertEqual(response.data['refs'][1]['resolved'], 'синим слонам') self.assertEqual(response.data['refs'][1]['data']['entity'], 'X1') self.assertEqual(response.data['refs'][1]['data']['form'], 'plur,datv') self.assertEqual(response.data['refs'][1]['pos_input']['start'], 12) self.assertEqual(response.data['refs'][1]['pos_input']['finish'], 27) self.assertEqual(response.data['refs'][1]['pos_output']['start'], 7) self.assertEqual(response.data['refs'][1]['pos_output']['finish'], 19) def test_import_trs(self): work_dir = os.path.dirname(os.path.abspath(__file__)) with open(f'{work_dir}/data/sample-rsform.trs', 'rb') as file: data = {'file': file} response = self.client.post('/api/rsforms/import-trs', data=data, format='multipart') self.assertEqual(response.status_code, 201) self.assertEqual(response.data['owner'], self.user.pk) self.assertTrue(response.data['title'] != '') def test_export_trs(self): schema = RSForm.create(title='Test') schema.insert_at(1, 'X1', CstType.BASE) response = self.client.get(f'/api/rsforms/{schema.item.id}/export-trs') self.assertEqual(response.status_code, 200) self.assertEqual(response.headers['Content-Disposition'], 'attachment; filename=Schema.trs') with io.BytesIO(response.content) as stream: with ZipFile(stream, 'r') as zipped_file: self.assertIsNone(zipped_file.testzip()) self.assertIn('document.json', zipped_file.namelist()) def test_create_constituenta(self): data = {'alias': 'X3', 'cst_type': 'basic'} response = self.client.post( f'/api/rsforms/{self.unowned.item.id}/cst-create', data=data, format='json' ) self.assertEqual(response.status_code, 403) item = self.owned.item Constituenta.objects.create(schema=item, alias='X1', cst_type='basic', order=1) x2 = Constituenta.objects.create(schema=item, alias='X2', cst_type='basic', order=2) response = self.client.post( f'/api/rsforms/{item.id}/cst-create', data=data, format='json' ) self.assertEqual(response.status_code, 201) self.assertEqual(response.data['new_cst']['alias'], 'X3') x3 = Constituenta.objects.get(alias=response.data['new_cst']['alias']) self.assertEqual(x3.order, 3) data = { 'alias': 'X4', 'cst_type': 'basic', 'insert_after': x2.id, 'term_raw': 'test', 'term_forms': [{'text':'form1', 'tags':'sing,datv'}] } response = self.client.post( f'/api/rsforms/{item.id}/cst-create', data=data, format='json' ) self.assertEqual(response.status_code, 201) self.assertEqual(response.data['new_cst']['alias'], data['alias']) x4 = Constituenta.objects.get(alias=response.data['new_cst']['alias']) self.assertEqual(x4.order, 3) self.assertEqual(x4.term_raw, data['term_raw']) self.assertEqual(x4.term_forms, data['term_forms']) def test_rename_constituenta(self): cst1 = Constituenta.objects.create( alias='X1', schema=self.owned.item, order=1, convention='Test', term_raw='Test1', term_resolved='Test1', term_forms=[{'text':'form1', 'tags':'sing,datv'}] ) cst2 = Constituenta.objects.create( alias='X2', schema=self.unowned.item, order=1, convention='Test1', term_raw='Test2', term_resolved='Test2' ) cst3 = Constituenta.objects.create( alias='X3', schema=self.owned.item, order=2, term_raw='Test3', term_resolved='Test3', definition_raw='Test1', definition_resolved='Test2' ) data = {'alias': 'D2', 'cst_type': 'term', 'id': cst2.pk} response = self.client.patch( f'/api/rsforms/{self.unowned.item.id}/cst-rename', data=data, format='json' ) self.assertEqual(response.status_code, 403) response = self.client.patch( f'/api/rsforms/{self.owned.item.id}/cst-rename', data=data, format='json' ) self.assertEqual(response.status_code, 400) data = {'alias': cst1.alias, 'cst_type': 'term', 'id': cst1.pk} response = self.client.patch( f'/api/rsforms/{self.owned.item.id}/cst-rename', data=data, format='json' ) self.assertEqual(response.status_code, 400) data = {'alias': cst3.alias, 'id': cst1.pk} response = self.client.patch( f'/api/rsforms/{self.owned.item.id}/cst-rename', data=data, format='json' ) self.assertEqual(response.status_code, 400) data = {'alias': 'D2', 'cst_type': 'term', 'id': cst1.pk} item = self.owned.item d1 = Constituenta.objects.create(schema=item, alias='D1', cst_type='term', order=4) d1.term_raw = '@{X1|plur}' d1.definition_formal = 'X1' d1.save() self.assertEqual(d1.order, 4) self.assertEqual(cst1.order, 1) self.assertEqual(cst1.alias, 'X1') self.assertEqual(cst1.cst_type, CstType.BASE) response = self.client.patch( f'/api/rsforms/{item.id}/cst-rename', data=data, format='json' ) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['new_cst']['alias'], 'D2') self.assertEqual(response.data['new_cst']['cst_type'], 'term') d1.refresh_from_db() cst1.refresh_from_db() self.assertEqual(d1.order, 4) self.assertEqual(d1.term_resolved, '') self.assertEqual(d1.term_raw, '@{D2|plur}') self.assertEqual(cst1.order, 1) self.assertEqual(cst1.alias, 'D2') self.assertEqual(cst1.cst_type, CstType.TERM) def test_create_constituenta_data(self): data = { 'alias': 'X3', 'cst_type': 'basic', 'convention': '1', 'term_raw': '2', 'definition_formal': '3', 'definition_raw': '4' } item = self.owned.item response = self.client.post( f'/api/rsforms/{item.id}/cst-create', data=data, format='json' ) self.assertEqual(response.status_code, 201) self.assertEqual(response.data['new_cst']['alias'], 'X3') self.assertEqual(response.data['new_cst']['cst_type'], 'basic') self.assertEqual(response.data['new_cst']['convention'], '1') self.assertEqual(response.data['new_cst']['term_raw'], '2') self.assertEqual(response.data['new_cst']['term_resolved'], '2') self.assertEqual(response.data['new_cst']['definition_formal'], '3') self.assertEqual(response.data['new_cst']['definition_raw'], '4') self.assertEqual(response.data['new_cst']['definition_resolved'], '4') def test_delete_constituenta(self): schema = self.owned data = {'items': [1337]} response = self.client.patch( f'/api/rsforms/{schema.item.id}/cst-multidelete', data=data, format='json' ) self.assertEqual(response.status_code, 400) x1 = Constituenta.objects.create(schema=schema.item, alias='X1', cst_type='basic', order=1) x2 = Constituenta.objects.create(schema=schema.item, alias='X2', cst_type='basic', order=2) data = {'items': [x1.id]} response = self.client.patch( f'/api/rsforms/{schema.item.id}/cst-multidelete', data=data, format='json' ) x2.refresh_from_db() schema.item.refresh_from_db() self.assertEqual(response.status_code, 202) self.assertEqual(len(response.data['items']), 1) self.assertEqual(schema.constituents().count(), 1) self.assertEqual(x2.alias, 'X2') self.assertEqual(x2.order, 1) x3 = Constituenta.objects.create(schema=self.unowned.item, alias='X1', cst_type='basic', order=1) data = {'items': [x3.id]} response = self.client.patch( f'/api/rsforms/{schema.item.id}/cst-multidelete', data=data, format='json' ) self.assertEqual(response.status_code, 400) def test_move_constituenta(self): item = self.owned.item data = {'items': [1337], 'move_to': 1} response = self.client.patch( f'/api/rsforms/{item.id}/cst-moveto', data=data, format='json' ) self.assertEqual(response.status_code, 400) x1 = Constituenta.objects.create(schema=item, alias='X1', cst_type='basic', order=1) x2 = Constituenta.objects.create(schema=item, alias='X2', cst_type='basic', order=2) data = {'items': [x2.id], 'move_to': 1} response = self.client.patch( f'/api/rsforms/{item.id}/cst-moveto', data=data, format='json' ) x1.refresh_from_db() x2.refresh_from_db() self.assertEqual(response.status_code, 200) self.assertEqual(response.data['id'], item.id) self.assertEqual(x1.order, 2) self.assertEqual(x2.order, 1) x3 = Constituenta.objects.create(schema=self.unowned.item, alias='X1', cst_type='basic', order=1) data = {'items': [x3.id], 'move_to': 1} response = self.client.patch( f'/api/rsforms/{item.id}/cst-moveto', data=data, format='json' ) self.assertEqual(response.status_code, 400) def test_reset_aliases(self): item = self.owned.item response = self.client.patch(f'/api/rsforms/{item.id}/reset-aliases') self.assertEqual(response.status_code, 200) self.assertEqual(response.data['id'], item.id) x2 = Constituenta.objects.create(schema=item, alias='X2', cst_type='basic', order=1) x1 = Constituenta.objects.create(schema=item, alias='X1', cst_type='basic', order=2) d11 = Constituenta.objects.create(schema=item, alias='D11', cst_type='term', order=3) response = self.client.patch(f'/api/rsforms/{item.id}/reset-aliases') x1.refresh_from_db() x2.refresh_from_db() d11.refresh_from_db() self.assertEqual(response.status_code, 200) self.assertEqual(x2.order, 1) self.assertEqual(x2.alias, 'X1') self.assertEqual(x1.order, 2) self.assertEqual(x1.alias, 'X2') self.assertEqual(d11.order, 3) self.assertEqual(d11.alias, 'D1') response = self.client.patch(f'/api/rsforms/{item.id}/reset-aliases') self.assertEqual(response.status_code, 200) def test_load_trs(self): schema = self.owned schema.item.title = 'Testt11' schema.item.save() x1 = Constituenta.objects.create(schema=schema.item, alias='X1', cst_type='basic', order=1) work_dir = os.path.dirname(os.path.abspath(__file__)) with open(f'{work_dir}/data/sample-rsform.trs', 'rb') as file: data = {'file': file, 'load_metadata': False} response = self.client.patch( f'/api/rsforms/{schema.item.id}/load-trs', data=data, format='multipart' ) schema.item.refresh_from_db() self.assertEqual(response.status_code, 200) self.assertEqual(schema.item.title, 'Testt11') self.assertEqual(len(response.data['items']), 25) self.assertEqual(schema.constituents().count(), 25) self.assertFalse(Constituenta.objects.filter(pk=x1.id).exists()) def test_clone(self): item = self.owned.item item.title = 'Testt11' item.save() x1 = Constituenta.objects.create(schema=item, alias='X12', cst_type='basic', order=1) d1 = Constituenta.objects.create(schema=item, alias='D2', cst_type='term', order=1) x1.term_raw = 'человек' x1.term_resolved = 'человек' d1.term_raw = '@{X12|plur}' d1.term_resolved = 'люди' x1.save() d1.save() data = {'title': 'Title'} response = self.client.post( f'/api/library/{item.id}/clone', data=data, format='json' ) self.assertEqual(response.status_code, 201) self.assertEqual(response.data['title'], 'Title') self.assertEqual(response.data['items'][0]['alias'], x1.alias) self.assertEqual(response.data['items'][0]['term_raw'], x1.term_raw) self.assertEqual(response.data['items'][0]['term_resolved'], x1.term_resolved) self.assertEqual(response.data['items'][1]['term_raw'], d1.term_raw) self.assertEqual(response.data['items'][1]['term_resolved'], d1.term_resolved) class TestRSLanguageViews(APITestCase): def setUp(self): self.factory = APIRequestFactory() self.user = User.objects.create(username='UserTest') self.client = APIClient() self.client.force_authenticate(user=self.user) def test_create_rsform(self): work_dir = os.path.dirname(os.path.abspath(__file__)) with open(f'{work_dir}/data/sample-rsform.trs', 'rb') as file: data = {'file': file, 'title': 'Test123', 'comment': '123', 'alias': 'ks1'} response = self.client.post( '/api/rsforms/create-detailed', data=data, format='multipart' ) self.assertEqual(response.status_code, 201) self.assertEqual(response.data['owner'], self.user.pk) self.assertEqual(response.data['title'], 'Test123') self.assertEqual(response.data['alias'], 'ks1') self.assertEqual(response.data['comment'], '123') def test_create_rsform_fallback(self): data = {'title': 'Test123', 'comment': '123', 'alias': 'ks1'} response = self.client.post( '/api/rsforms/create-detailed', data=data, format='json' ) self.assertEqual(response.status_code, 201) self.assertEqual(response.data['owner'], self.user.pk) self.assertEqual(response.data['title'], 'Test123') self.assertEqual(response.data['alias'], 'ks1') self.assertEqual(response.data['comment'], '123') def test_convert_to_ascii(self): data = {'expression': '1=1'} request = self.factory.post( '/api/rslang/to-ascii', data=data, format='json' ) response = convert_to_ascii(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['result'], r'1 \eq 1') def test_convert_to_ascii_missing_data(self): data = {'data': '1=1'} request = self.factory.post( '/api/rslang/to-ascii', data=data, format='json' ) response = convert_to_ascii(request) self.assertEqual(response.status_code, 400) self.assertIsInstance(response.data['expression'][0], ErrorDetail) def test_convert_to_math(self): data = {'expression': r'1 \eq 1'} request = self.factory.post( '/api/rslang/to-math', data=data, format='json' ) response = convert_to_math(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['result'], r'1=1') def test_convert_to_math_missing_data(self): data = {'data': r'1 \eq 1'} request = self.factory.post( '/api/rslang/to-math', data=data, format='json' ) response = convert_to_math(request) self.assertEqual(response.status_code, 400) self.assertIsInstance(response.data['expression'][0], ErrorDetail) def test_parse_expression(self): data = {'expression': r'1=1'} request = self.factory.post( '/api/rslang/parse-expression', data=data, format='json' ) response = parse_expression(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['parseResult'], True) self.assertEqual(response.data['syntax'], Syntax.MATH) self.assertEqual(response.data['astText'], '[=[1][1]]') def test_parse_expression_missing_data(self): data = {'data': r'1=1'} request = self.factory.post( '/api/rslang/parse-expression', data=data, format='json' ) response = parse_expression(request) self.assertEqual(response.status_code, 400) self.assertIsInstance(response.data['expression'][0], ErrorDetail) class TestNaturalLanguageViews(APITestCase): def setUp(self): self.factory = APIRequestFactory() self.client = APIClient() def _assert_tags(self, actual: str, expected: str): self.assertEqual(set(split_grams(actual)), set(split_grams(expected))) def test_parse_text(self): data = {'text': 'синим слонам'} request = self.factory.post( '/api/cctext/parse', data=data, format='json' ) response = parse_text(request) self.assertEqual(response.status_code, 200) self._assert_tags(response.data['result'], 'datv,NOUN,plur,anim,masc') def test_inflect(self): data = {'text': 'синий слон', 'grams': 'plur,datv'} request = self.factory.post( '/api/cctext/inflect', data=data, format='json' ) response = inflect(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['result'], 'синим слонам') def test_generate_lexeme(self): data = {'text': 'синий слон'} request = self.factory.post( '/api/cctext/generate-lexeme', data=data, format='json' ) response = generate_lexeme(request) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data['items']), 12) self.assertEqual(response.data['items'][0]['text'], 'синий слон')