diff --git a/HISTORY.rst b/HISTORY.rst index d78952dbf9..9beabfa2b6 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -33,6 +33,7 @@ - Replace document type selection widget with an opened selection list. - Add mailing documentation chapter. - Add roadmap documentation chapter. +- API updates. 2.0.2 (2016-02-09) ================== diff --git a/mayan/apps/metadata/api_views.py b/mayan/apps/metadata/api_views.py index 6dfbf40db2..569a95277d 100644 --- a/mayan/apps/metadata/api_views.py +++ b/mayan/apps/metadata/api_views.py @@ -23,8 +23,9 @@ from .permissions import ( permission_metadata_type_edit, permission_metadata_type_view ) from .serializers import ( - DocumentMetadataSerializer, DocumentTypeNewMetadataTypeSerializer, - MetadataTypeSerializer, DocumentTypeMetadataTypeSerializer + DocumentMetadataSerializer, DocumentNewMetadataSerializer, + DocumentTypeNewMetadataTypeSerializer, MetadataTypeSerializer, + DocumentTypeMetadataTypeSerializer ) @@ -89,15 +90,14 @@ class APIMetadataTypeView(generics.RetrieveUpdateDestroyAPIView): class APIDocumentMetadataListView(generics.ListCreateAPIView): permission_classes = (MayanPermission,) - serializer_class = DocumentMetadataSerializer def get_document(self): - return get_object_or_404(Document, pk=self.kwargs['document_pk']) + return get_object_or_404(Document, pk=self.kwargs['pk']) def get_queryset(self): document = self.get_document() - if self.request == 'GET': + if self.request.method == 'GET': # Make sure the use has the permission to see the metadata for # this document try: @@ -111,7 +111,7 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView): ) else: return document.metadata.all() - elif self.request == 'POST': + elif self.request.method == 'POST': # Make sure the use has the permission to add metadata to this # document try: @@ -126,8 +126,11 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView): else: return document.metadata.all() - def pre_save(self, serializer): - serializer.document = self.get_document() + def get_serializer_class(self): + if self.request.method == 'GET': + return DocumentMetadataSerializer + elif self.request.method == 'POST': + return DocumentNewMetadataSerializer def get(self, *args, **kwargs): """ @@ -135,6 +138,10 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView): """ return super(APIDocumentMetadataListView, self).get(*args, **kwargs) + def perform_create(self, serializer): + serializer.document = self.get_document() + serializer.save() + def post(self, *args, **kwargs): """ Add an existing metadata type and value to the selected document. diff --git a/mayan/apps/metadata/apps.py b/mayan/apps/metadata/apps.py index 8bb0df6364..75b0e38bf7 100644 --- a/mayan/apps/metadata/apps.py +++ b/mayan/apps/metadata/apps.py @@ -66,7 +66,7 @@ class MetadataApp(MayanAppConfig): DocumentTypeMetadataType = self.get_model('DocumentTypeMetadataType') MetadataType = self.get_model('MetadataType') - APIEndPoint(app=self, version_string='1') + APIEndPoint(app=self, version_string='2') Document.add_to_class( 'metadata_value_of', DocumentMetadataHelper.constructor diff --git a/mayan/apps/metadata/serializers.py b/mayan/apps/metadata/serializers.py index cb59e3678a..3dfa602d01 100644 --- a/mayan/apps/metadata/serializers.py +++ b/mayan/apps/metadata/serializers.py @@ -19,6 +19,7 @@ class DocumentMetadataSerializer(serializers.ModelSerializer): class Meta: fields = ('document', 'id', 'metadata_type', 'value',) model = DocumentMetadata + read_only_fields = ('metadata_type',) class DocumentTypeMetadataTypeSerializer(serializers.ModelSerializer): @@ -28,14 +29,31 @@ class DocumentTypeMetadataTypeSerializer(serializers.ModelSerializer): class DocumentNewMetadataSerializer(serializers.Serializer): - metadata_type = serializers.IntegerField( - help_text=_('Primary key of the metadata type to be added.') + metadata_type_pk = serializers.IntegerField( + help_text=_('Primary key of the metadata type to be added.'), + write_only=True ) + + metadata_type = MetadataTypeSerializer(read_only=True) + + pk = serializers.IntegerField( + help_text=_('Primary key of the document metadata type.'), + read_only=True + ) + value = serializers.CharField( max_length=255, help_text=_('Value of the corresponding metadata type instance.') ) + def create(self, validated_data): + metadata_type = MetadataType.objects.get( + pk=validated_data['metadata_type_pk'] + ) + instance = self.document.metadata.create( + metadata_type=metadata_type, value=validated_data['value'] + ) + return instance class DocumentTypeNewMetadataTypeSerializer(serializers.Serializer): metadata_type_pk = serializers.IntegerField( diff --git a/mayan/apps/metadata/tests/test_api.py b/mayan/apps/metadata/tests/test_api.py index 652bd3e70a..da70c338f2 100644 --- a/mayan/apps/metadata/tests/test_api.py +++ b/mayan/apps/metadata/tests/test_api.py @@ -19,6 +19,9 @@ from .literals import ( TEST_METADATA_TYPE_NAME, TEST_METADATA_TYPE_NAME_2 ) +TEST_METADATA_VALUE = 'test value' +TEST_METADATA_VALUE_EDITED = 'test value edited' + class MetadataTypeAPITestCase(APITestCase): def setUp(self): @@ -119,7 +122,9 @@ class DocumentTypeMetadataTypeAPITestCase(APITestCase): self.assertEqual(response.status_code, 201) - document_type_metadata_type = DocumentTypeMetadataType.objects.filter(document_type=self.document_type, required=False).first() + document_type_metadata_type = DocumentTypeMetadataType.objects.filter( + document_type=self.document_type, required=False + ).first() self.assertEqual(response.data['pk'], document_type_metadata_type.pk) @@ -137,26 +142,9 @@ class DocumentTypeMetadataTypeAPITestCase(APITestCase): self.assertEqual(response.status_code, 201) - document_type_metadata_type = DocumentTypeMetadataType.objects.filter(document_type=self.document_type, required=True).first() - - self.assertEqual(response.data['pk'], document_type_metadata_type.pk) - - self.assertEqual( - document_type_metadata_type.metadata_type, self.metadata_type - ) - - - def test_document_type_metadata_type_required_create(self): - response = self.client.post( - reverse( - 'rest_api:documenttyperequiredmetadatatype-list', - args=(self.document_type.pk,) - ), data={'metadata_type_pk': self.metadata_type.pk} - ) - - self.assertEqual(response.status_code, 201) - - document_type_metadata_type = DocumentTypeMetadataType.objects.filter(document_type=self.document_type, required=True).first() + document_type_metadata_type = DocumentTypeMetadataType.objects.filter( + document_type=self.document_type, required=True + ).first() self.assertEqual(response.data['pk'], document_type_metadata_type.pk) @@ -179,3 +167,127 @@ class DocumentTypeMetadataTypeAPITestCase(APITestCase): self.assertEqual(response.status_code, 204) self.assertEqual(self.document_type.metadata.all().count(), 0) + + +class DocumentMetadataAPITestCase(APITestCase): + @override_settings(OCR_AUTO_OCR=False) + def setUp(self): + self.admin_user = get_user_model().objects.create_superuser( + username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL, + password=TEST_ADMIN_PASSWORD + ) + + self.client.login( + username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD + ) + + self.document_type = DocumentType.objects.create( + label=TEST_DOCUMENT_TYPE + ) + + self.metadata_type = MetadataType.objects.create( + label=TEST_METADATA_TYPE_LABEL, name=TEST_METADATA_TYPE_NAME + ) + + self.document_type.metadata.create( + metadata_type=self.metadata_type, required=False + ) + + with open(TEST_SMALL_DOCUMENT_PATH) as file_object: + self.document = self.document_type.new_document( + file_object=file_object, + ) + + def tearDown(self): + self.admin_user.delete() + self.document_type.delete() + + def test_document_metadata_create(self): + response = self.client.post( + reverse( + 'rest_api:documentmetadata-list', + args=(self.document.pk,) + ), data={ + 'metadata_type_pk': self.metadata_type.pk, + 'value': TEST_METADATA_VALUE + } + ) + + document_metadata = DocumentMetadata.objects.get( + document=self.document + ) + + self.assertEqual(response.status_code, 201) + + self.assertEqual(response.data['pk'], document_metadata.pk) + + self.assertEqual(document_metadata.metadata_type, self.metadata_type) + self.assertEqual(document_metadata.value, TEST_METADATA_VALUE) + + def test_document_metadata_list(self): + document_metadata = self.document.metadata.create( + metadata_type=self.metadata_type, value=TEST_METADATA_VALUE + ) + + response = self.client.get( + reverse( + 'rest_api:documentmetadata-list', args=(self.document.pk,) + ) + ) + + self.assertEqual(response.status_code, 200) + + self.assertEqual( + response.data['results'][0]['document'], self.document.pk + ) + self.assertEqual( + response.data['results'][0]['metadata_type'], self.metadata_type.pk + ) + self.assertEqual( + response.data['results'][0]['value'], TEST_METADATA_VALUE + ) + self.assertEqual( + response.data['results'][0]['id'], document_metadata.pk + ) + + def test_document_metadata_edit(self): + document_metadata = self.document.metadata.create( + metadata_type=self.metadata_type, value=TEST_METADATA_VALUE + ) + + response = self.client.put( + reverse( + 'rest_api:documentmetadata-detail', + args=(document_metadata.pk,) + ), data={ + 'value': TEST_METADATA_VALUE_EDITED + } + ) + + self.assertEqual(response.status_code, 200) + + self.assertEqual( + response.data['document'], self.document.pk + ) + self.assertEqual( + response.data['metadata_type'], self.metadata_type.pk + ) + self.assertEqual( + response.data['value'], TEST_METADATA_VALUE_EDITED + ) + + def test_document_metadata_delete(self): + document_metadata = self.document.metadata.create( + metadata_type=self.metadata_type, value=TEST_METADATA_VALUE + ) + + response = self.client.delete( + reverse( + 'rest_api:documentmetadata-detail', + args=(document_metadata.pk,) + ) + ) + + self.assertEqual(response.status_code, 204) + + self.assertEqual(self.document.metadata.all().count(), 0) diff --git a/mayan/apps/metadata/urls.py b/mayan/apps/metadata/urls.py index 79e1505a20..b94acc25a3 100644 --- a/mayan/apps/metadata/urls.py +++ b/mayan/apps/metadata/urls.py @@ -75,11 +75,11 @@ urlpatterns = patterns( api_urls = patterns( '', url( - r'^metadatatypes/$', APIMetadataTypeListView.as_view(), + r'^metadata_types/$', APIMetadataTypeListView.as_view(), name='metadatatype-list' ), url( - r'^metadatatypes/(?P[0-9]+)/$', APIMetadataTypeView.as_view(), + r'^metadata_types/(?P[0-9]+)/$', APIMetadataTypeView.as_view(), name='metadatatype-detail' ), url( @@ -87,16 +87,16 @@ api_urls = patterns( APIDocumentMetadataView.as_view(), name='documentmetadata-detail' ), url( - r'^document/(?P[0-9]+)/metadata/$', + r'^document/(?P\d+)/metadata/$', APIDocumentMetadataListView.as_view(), name='documentmetadata-list' ), url( - r'^document_type/(?P[0-9]+)/metadatatypes/optional/$', + r'^document_type/(?P[0-9]+)/metadata_types/optional/$', APIDocumentTypeMetadataTypeOptionalListView.as_view(), name='documenttypeoptionalmetadatatype-list' ), url( - r'^document_type/(?P[0-9]+)/metadatatypes/required/$', + r'^document_type/(?P[0-9]+)/metadata_types/required/$', APIDocumentTypeMetadataTypeRequiredListView.as_view(), name='documenttyperequiredmetadatatype-list' ),