diff --git a/serializers/jsonapi/CustomTextFieldSerializer.ts b/serializers/jsonapi/CustomTextFieldSerializer.ts index 93db4e32b23d9ddfb0e5a5e0a1bf390ebf5bcaac..cda282cc3b7250579051220642822efcc2d2a975 100644 --- a/serializers/jsonapi/CustomTextFieldSerializer.ts +++ b/serializers/jsonapi/CustomTextFieldSerializer.ts @@ -3,7 +3,7 @@ * Web client of the Sensor Management System software developed within * the Helmholtz DataHub Initiative by GFZ and UFZ. * - * Copyright (C) 2020 + * Copyright (C) 2020, 2021 * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) * - Helmholtz Centre Potsdam - GFZ German Research Centre for @@ -35,9 +35,7 @@ import { IJsonApiNestedElement, IJsonApiObject, IJsonApiObjectList, - IJsonApiTypeId, - IJsonApiTypeIdAttributes, - IJsonApiTypeIdDataListDict + IJsonApiTypeIdAttributes } from '@/serializers/jsonapi/JsonApiTypes' export class CustomTextFieldSerializer { @@ -92,14 +90,6 @@ export class CustomTextFieldSerializer { return jsonApiObjectList.data.map(this.convertJsonApiDataToModel) } - convertModelListToJsonApiRelationshipObject (customFields: ICustomTextField[]): IJsonApiTypeIdDataListDict { - return { - customfields: { - data: this.convertModelListToTupleListWithIdAndType(customFields) - } - } - } - convertModelToJsonApiData (customField: ICustomTextField, deviceId: string): IJsonApiDataWithOptionalId { const data: any = { type: 'customfield', @@ -121,17 +111,4 @@ export class CustomTextFieldSerializer { } return data } - - convertModelListToTupleListWithIdAndType (customFields: ICustomTextField[]): IJsonApiTypeId[] { - const result: IJsonApiTypeId[] = [] - for (const field of customFields) { - if (field.id !== null) { - result.push({ - id: field.id, - type: 'customfield' - }) - } - } - return result - } } diff --git a/serializers/jsonapi/DeviceAttachmentSerializer.ts b/serializers/jsonapi/DeviceAttachmentSerializer.ts new file mode 100644 index 0000000000000000000000000000000000000000..de70c753ea76784a1eeedf31957101280c479296 --- /dev/null +++ b/serializers/jsonapi/DeviceAttachmentSerializer.ts @@ -0,0 +1,78 @@ +/** + * @license + * Web client of the Sensor Management System software developed within + * the Helmholtz DataHub Initiative by GFZ and UFZ. + * + * Copyright (C) 2021 + * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) + * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) + * - Helmholtz Centre Potsdam - GFZ German Research Centre for + * Geosciences (GFZ, https://www.gfz-potsdam.de) + * + * Parts of this program were developed within the context of the + * following publicly funded projects or measures: + * - Helmholtz Earth and Environment DataHub + * (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095) + * + * Licensed under the HEESIL, Version 1.0 or - as soon they will be + * approved by the "Community" - subsequent versions of the HEESIL + * (the "Licence"). + * + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://gitext.gfz-potsdam.de/software/heesil + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the Licence for the specific language governing + * permissions and limitations under the Licence. + */ +import { Attachment } from '@/models/Attachment' +import { IJsonApiObject, IJsonApiDataWithOptionalId, IJsonApiTypeIdAttributes, IJsonApiObjectList } from '@/serializers/jsonapi/JsonApiTypes' + +export class DeviceAttachmentSerializer { + convertJsonApiObjectToModel (jsonApiObject: IJsonApiObject): Attachment { + const data = jsonApiObject.data + return this.convertJsonApiDataToModel(data) + } + + convertJsonApiObjectListToModelList (jsonApiObjectList: IJsonApiObjectList): Attachment[] { + return jsonApiObjectList.data.map(this.convertJsonApiDataToModel) + } + + convertJsonApiDataToModel (jsonApiData: IJsonApiTypeIdAttributes): Attachment { + const attribues = jsonApiData.attributes + + const newEntry = new Attachment() + + newEntry.id = jsonApiData.id.toString() + newEntry.url = attribues.url || '' + newEntry.label = attribues.label || '' + + return newEntry + } + + convertModelToJsonApiData (attachment: Attachment, deviceId: string): IJsonApiDataWithOptionalId { + const data: any = { + type: 'device_attachment', + attributes: { + url: attachment.url, + label: attachment.label + }, + relationships: { + device: { + data: { + type: 'device', + id: deviceId + } + } + } + } + if (attachment.id) { + data.id = attachment.id + } + return data + } +} diff --git a/serializers/jsonapi/DevicePropertySerializer.ts b/serializers/jsonapi/DevicePropertySerializer.ts index d5171bdfc8c05921e2881b4aee0d1eb30c509efd..67123eec55c25be26812bb9fcccd334a55e0762c 100644 --- a/serializers/jsonapi/DevicePropertySerializer.ts +++ b/serializers/jsonapi/DevicePropertySerializer.ts @@ -3,7 +3,7 @@ * Web client of the Sensor Management System software developed within * the Helmholtz DataHub Initiative by GFZ and UFZ. * - * Copyright (C) 2020 + * Copyright (C) 2020, 2021 * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) * - Helmholtz Centre Potsdam - GFZ German Research Centre for @@ -32,7 +32,7 @@ import { DeviceProperty } from '@/models/DeviceProperty' import { MeasuringRange } from '@/models/MeasuringRange' -import { IJsonApiNestedElement, IJsonApiTypeIdAttributes, IJsonApiObjectList } from '@/serializers/jsonapi/JsonApiTypes' +import { IJsonApiNestedElement, IJsonApiObject, IJsonApiObjectList, IJsonApiTypeIdAttributes, IJsonApiDataWithOptionalId } from '@/serializers/jsonapi/JsonApiTypes' export class DevicePropertySerializer { convertJsonApiElementToModel (property: IJsonApiNestedElement): DeviceProperty { @@ -99,35 +99,73 @@ export class DevicePropertySerializer { return result } - convertJsonApiDataToModel (jsonApiData: IJsonApiTypeIdAttributes): DeviceProperty { - const attributes = jsonApiData.attributes + convertJsonApiObjectToModel (jsonApiObject: IJsonApiObject): DeviceProperty { + const data = jsonApiObject.data + return this.convertJsonApiDataToModel(data) + } - const newEntry = new DeviceProperty() + convertJsonApiObjectListToModelList (jsonApiObjectList: IJsonApiObjectList): DeviceProperty[] { + return jsonApiObjectList.data.map(this.convertJsonApiDataToModel) + } - newEntry.id = jsonApiData.id.toString() - newEntry.measuringRange = new MeasuringRange( - attributes.measuring_range_min, - attributes.measuring_range_max + convertJsonApiDataToModel (jsonApiData: IJsonApiTypeIdAttributes): DeviceProperty { + const result = new DeviceProperty() + result.id = jsonApiData.id.toString() + result.measuringRange = new MeasuringRange( + jsonApiData.attributes.measuring_range_min || null, + jsonApiData.attributes.measuring_range_max || null ) - newEntry.failureValue = attributes.failure_value - newEntry.accuracy = attributes.accuracy - newEntry.resolution = attributes.resolution - newEntry.label = attributes.label || '' - newEntry.unitUri = attributes.unit_uri || '' - newEntry.unitName = attributes.unit_name || '' - newEntry.compartmentUri = attributes.compartment_uri || '' - newEntry.compartmentName = attributes.compartment_name || '' - newEntry.propertyUri = attributes.property_uri || '' - newEntry.propertyName = attributes.property_name || '' - newEntry.samplingMediaUri = attributes.sampling_media_uri || '' - newEntry.samplingMediaName = attributes.sampling_media_name || '' - newEntry.resolutionUnitUri = attributes.resolution_unit_uri || '' - newEntry.resolutionUnitName = attributes.resolution_unit_name || '' + result.failureValue = jsonApiData.attributes.failure_value || null + result.accuracy = jsonApiData.attributes.accuracy || null + result.resolution = jsonApiData.attributes.resolution || null + result.label = jsonApiData.attributes.label || '' + result.unitUri = jsonApiData.attributes.unit_uri || '' + result.unitName = jsonApiData.attributes.unit_name || '' + result.compartmentUri = jsonApiData.attributes.compartment_uri || '' + result.compartmentName = jsonApiData.attributes.compartment_name || '' + result.propertyUri = jsonApiData.attributes.property_uri || '' + result.propertyName = jsonApiData.attributes.property_name || '' + result.samplingMediaUri = jsonApiData.attributes.sampling_media_uri || '' + result.samplingMediaName = jsonApiData.attributes.sampling_media_name || '' + result.resolutionUnitUri = jsonApiData.attributes.resolution_unit_uri || '' + result.resolutionUnitName = jsonApiData.attributes.resolution_unit_name || '' - return newEntry + return result } - convertJsonApiObjectListToModelList (jsonApiObjectList: IJsonApiObjectList): DeviceProperty[] { - return jsonApiObjectList.data.map(this.convertJsonApiDataToModel) + convertModelToJsonApiData (deviceProperty: DeviceProperty, deviceId: string): IJsonApiDataWithOptionalId { + const data: any = { + type: 'device_property', + attributes: { + measuring_range_min: deviceProperty.measuringRange.min, + measuring_range_max: deviceProperty.measuringRange.max, + failure_value: deviceProperty.failureValue, + accuracy: deviceProperty.accuracy, + resolution: deviceProperty.resolution, + label: deviceProperty.label, + unit_uri: deviceProperty.unitUri, + unit_name: deviceProperty.unitName, + compartment_uri: deviceProperty.compartmentUri, + compartment_name: deviceProperty.compartmentName, + property_uri: deviceProperty.propertyUri, + property_name: deviceProperty.propertyName, + sampling_media_uri: deviceProperty.samplingMediaUri, + sampling_media_name: deviceProperty.samplingMediaName, + resolution_unit_uri: deviceProperty.resolutionUnitUri, + resolution_unit_name: deviceProperty.resolutionUnitName + }, + relationships: { + device: { + data: { + type: 'device', + id: deviceId + } + } + } + } + if (deviceProperty.id) { + data.id = deviceProperty.id + } + return data } } diff --git a/serializers/jsonapi/PlatformAttachmentSerializer.ts b/serializers/jsonapi/PlatformAttachmentSerializer.ts new file mode 100644 index 0000000000000000000000000000000000000000..4f6d772e00f496018ffffadeb19f0d566cb809cf --- /dev/null +++ b/serializers/jsonapi/PlatformAttachmentSerializer.ts @@ -0,0 +1,79 @@ +/** + * @license + * Web client of the Sensor Management System software developed within + * the Helmholtz DataHub Initiative by GFZ and UFZ. + * + * Copyright (C) 2021 + * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) + * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) + * - Helmholtz Centre Potsdam - GFZ German Research Centre for + * Geosciences (GFZ, https://www.gfz-potsdam.de) + * + * Parts of this program were developed within the context of the + * following publicly funded projects or measures: + * - Helmholtz Earth and Environment DataHub + * (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095) + * + * Licensed under the HEESIL, Version 1.0 or - as soon they will be + * approved by the "Community" - subsequent versions of the HEESIL + * (the "Licence"). + * + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://gitext.gfz-potsdam.de/software/heesil + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the Licence for the specific language governing + * permissions and limitations under the Licence. + */ + +import { Attachment } from '@/models/Attachment' +import { IJsonApiObject, IJsonApiDataWithOptionalId, IJsonApiTypeIdAttributes, IJsonApiObjectList } from '@/serializers/jsonapi/JsonApiTypes' + +export class PlatformAttachmentSerializer { + convertJsonApiObjectToModel (jsonApiObject: IJsonApiObject): Attachment { + const data = jsonApiObject.data + return this.convertJsonApiDataToModel(data) + } + + convertJsonApiObjectListToModelList (jsonApiObjectList: IJsonApiObjectList): Attachment[] { + return jsonApiObjectList.data.map(this.convertJsonApiDataToModel) + } + + convertJsonApiDataToModel (jsonApiData: IJsonApiTypeIdAttributes): Attachment { + const attribues = jsonApiData.attributes + + const newEntry = new Attachment() + + newEntry.id = jsonApiData.id.toString() + newEntry.url = attribues.url || '' + newEntry.label = attribues.label || '' + + return newEntry + } + + convertModelToJsonApiData (attachment: Attachment, platformId: string): IJsonApiDataWithOptionalId { + const data: any = { + type: 'platform_attachment', + attributes: { + url: attachment.url, + label: attachment.label + }, + relationships: { + platform: { + data: { + type: 'platform', + id: platformId + } + } + } + } + if (attachment.id) { + data.id = attachment.id + } + return data + } +} diff --git a/services/Api.ts b/services/Api.ts index cea629b700d4a6a46685e61aabf3d942eb470e60..2ba69c48a03819d1c7ca08f1a40b617f498f6860 100644 --- a/services/Api.ts +++ b/services/Api.ts @@ -3,7 +3,7 @@ * Web client of the Sensor Management System software developed within * the Helmholtz DataHub Initiative by GFZ and UFZ. * - * Copyright (C) 2020 + * Copyright (C) 2020, 2021 * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) * - Helmholtz Centre Potsdam - GFZ German Research Centre for @@ -33,10 +33,13 @@ import axios, { AxiosInstance, AxiosRequestConfig } from 'axios' import { ContactApi } from '@/services/sms/ContactApi' import { DeviceApi } from '@/services/sms/DeviceApi' +import { DevicePropertyApi } from '@/services/sms/DevicePropertyApi' import { PlatformApi } from '@/services/sms/PlatformApi' import { ConfigurationApi } from '@/services/sms/ConfigurationApi' import { ConfigurationStatusApi } from '@/services/sms/ConfigurationStatusApi' import { CustomfieldsApi } from '@/services/sms/CustomfieldsApi' +import { DeviceAttachmentApi } from '@/services/sms/DeviceAttachmentApi' +import { PlatformAttachmentApi } from '@/services/sms/PlatformAttachmentApi' import { CompartmentApi } from '@/services/cv/CompartmentApi' import { DeviceTypeApi } from '@/services/cv/DeviceTypeApi' @@ -60,6 +63,9 @@ export class Api { private readonly _configurationApi: ConfigurationApi private readonly _configurationStatesApi: ConfigurationStatusApi private readonly _customfieldsApi: CustomfieldsApi + private readonly _deviceAttachmentApi: DeviceAttachmentApi + private readonly _platformAttachmentApi: PlatformAttachmentApi + private readonly _devicePropertyApi: DevicePropertyApi private readonly _manufacturerApi: ManufacturerApi private readonly _platformTypeApi: PlatformTypeApi @@ -105,6 +111,18 @@ export class Api { this.createAxios(smsBaseUrl, '/customfields', smsConfig, getIdToken) ) + this._deviceAttachmentApi = new DeviceAttachmentApi( + this.createAxios(smsBaseUrl, '/device-attachments', smsConfig, getIdToken) + ) + + this._platformAttachmentApi = new PlatformAttachmentApi( + this.createAxios(smsBaseUrl, '/platform-attachments', smsConfig, getIdToken) + ) + + this._devicePropertyApi = new DevicePropertyApi( + this.createAxios(smsBaseUrl, '/device-properties', smsConfig, getIdToken) + ) + // and here we can set settings for all the cv api calls const cvConfig: AxiosRequestConfig = { headers: { @@ -189,6 +207,18 @@ export class Api { return this._customfieldsApi } + get deviceAttachments (): DeviceAttachmentApi { + return this._deviceAttachmentApi + } + + get platformAttachments (): PlatformAttachmentApi { + return this._platformAttachmentApi + } + + get deviceProperties (): DevicePropertyApi { + return this._devicePropertyApi + } + get contacts (): ContactApi { return this._contactApi } diff --git a/services/sms/ConfigurationApi.ts b/services/sms/ConfigurationApi.ts index d55c0669d98d63481226d65efb06b812d1b27df6..535e7c99fae814438305ed47b8e2e02d56a12f49 100644 --- a/services/sms/ConfigurationApi.ts +++ b/services/sms/ConfigurationApi.ts @@ -3,7 +3,7 @@ * Web client of the Sensor Management System software developed within * the Helmholtz DataHub Initiative by GFZ and UFZ. * - * Copyright (C) 2020 + * Copyright (C) 2020, 2021 * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) * - Helmholtz Centre Potsdam - GFZ German Research Centre for @@ -34,6 +34,8 @@ import { AxiosInstance, Method } from 'axios' import { Configuration } from '@/models/Configuration' +import { Contact } from '@/models/Contact' +import { DynamicLocation } from '@/models/Location' import { Project } from '@/models/Project' // eslint-disable-next-line @@ -49,7 +51,8 @@ import { configurationWithMetaToConfigurationByAddingDummyObjects, configurationWithMetaToConfigurationByThrowingErrorOnMissing } from '@/serializers/jsonapi/ConfigurationSerializer' -import { DynamicLocation } from '@/models/Location' + +import { ContactSerializer } from '@/serializers/jsonapi/ContactSerializer' interface IRelationshipData { id: string @@ -174,6 +177,36 @@ export class ConfigurationApi { newSearchBuilder (): ConfigurationSearchBuilder { return new ConfigurationSearchBuilder(this.axiosApi, this.serializer) } + + findRelatedContacts (configurationId: string): Promise<Contact[]> { + const url = configurationId + '/contacts' + const params = { + 'page[size]': 10000 + } + return this.axiosApi.get(url, { params }).then((rawServerResponse) => { + return new ContactSerializer().convertJsonApiObjectListToModelList(rawServerResponse.data) + }) + } + + removeContact (configurationId: string, contactId: string): Promise<void> { + const url = configurationId + '/relationships/contacts' + const params = { + data: [{ + type: 'contact', + id: contactId + }] + } + return this.axiosApi.delete(url, { data: params }) + } + + addContact (configurationId: string, contactId: string): Promise<void> { + const url = configurationId + '/relationships/contacts' + const data = [{ + type: 'contact', + id: contactId + }] + return this.axiosApi.post(url, { data }) + } } export class ConfigurationSearchBuilder { diff --git a/services/sms/CustomfieldsApi.ts b/services/sms/CustomfieldsApi.ts index 8a2179b52880565d1de08a997434d7a405e55d66..4c27722733f7966845264c374cfa21bd9a17af63 100644 --- a/services/sms/CustomfieldsApi.ts +++ b/services/sms/CustomfieldsApi.ts @@ -3,7 +3,7 @@ * Web client of the Sensor Management System software developed within * the Helmholtz DataHub Initiative by GFZ and UFZ. * - * Copyright (C) 2020 + * Copyright (C) 2021 * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) * - Helmholtz Centre Potsdam - GFZ German Research Centre for @@ -59,9 +59,8 @@ export class CustomfieldsApi { add (deviceId: string, field: CustomTextField): Promise<CustomTextField> { const url = '' const data: any = this.serializer.convertModelToJsonApiData(field, deviceId) - return this.axiosApi.post(url, { data }).then((rawResponse) => { - const rawData = rawResponse.data - return this.serializer.convertJsonApiObjectToModel(rawData) + return this.axiosApi.post(url, { data }).then((serverResponse) => { + return this.serializer.convertJsonApiObjectToModel(serverResponse.data) }) } @@ -74,10 +73,9 @@ export class CustomfieldsApi { } }).then((fieldId) => { const data: any = this.serializer.convertModelToJsonApiData(field, deviceId) - return this.axiosApi.patch(fieldId, { data }) - }).then((rawResponse) => { - const rawData = rawResponse.data - return this.serializer.convertJsonApiObjectToModel(rawData) + return this.axiosApi.patch(fieldId, { data }).then((serverResponse) => { + return this.serializer.convertJsonApiObjectToModel(serverResponse.data) + }) }) } } diff --git a/services/sms/DeviceApi.ts b/services/sms/DeviceApi.ts index a0225569d92987be7cc6469b384792339e4b981d..e32ac0b8756531da3a14c35706f63464dab3f861 100644 --- a/services/sms/DeviceApi.ts +++ b/services/sms/DeviceApi.ts @@ -3,7 +3,7 @@ * Web client of the Sensor Management System software developed within * the Helmholtz DataHub Initiative by GFZ and UFZ. * - * Copyright (C) 2020 + * Copyright (C) 2020, 2021 * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) * - Helmholtz Centre Potsdam - GFZ German Research Centre for @@ -31,6 +31,7 @@ */ import { AxiosInstance, Method } from 'axios' +import { Attachment } from '@/models/Attachment' import { Contact } from '@/models/Contact' import { CustomTextField } from '@/models/CustomTextField' import { Device } from '@/models/Device' @@ -41,6 +42,7 @@ import { Status } from '@/models/Status' import { ContactSerializer } from '@/serializers/jsonapi/ContactSerializer' import { CustomTextFieldSerializer } from '@/serializers/jsonapi/CustomTextFieldSerializer' +import { DeviceAttachmentSerializer } from '@/serializers/jsonapi/DeviceAttachmentSerializer' import { DevicePropertySerializer } from '@/serializers/jsonapi/DevicePropertySerializer' import { IFlaskJSONAPIFilter } from '@/utils/JSONApiInterfaces' @@ -150,6 +152,16 @@ export class DeviceApi { }) } + findRelatedDeviceAttachments (deviceId: string): Promise<Attachment[]> { + const url = deviceId + '/device-attachments' + const params = { + 'page[size]': 10000 + } + return this.axiosApi.get(url, { params }).then((rawServerResponse) => { + return new DeviceAttachmentSerializer().convertJsonApiObjectListToModelList(rawServerResponse.data) + }) + } + findRelatedDeviceProperties (deviceId: string): Promise<DeviceProperty[]> { const url = deviceId + '/device-properties' const params = { diff --git a/services/sms/DeviceAttachmentApi.ts b/services/sms/DeviceAttachmentApi.ts new file mode 100644 index 0000000000000000000000000000000000000000..fc21052045fadb0103760ee6448475202d1a34c3 --- /dev/null +++ b/services/sms/DeviceAttachmentApi.ts @@ -0,0 +1,79 @@ +/** + * @license + * Web client of the Sensor Management System software developed within + * the Helmholtz DataHub Initiative by GFZ and UFZ. + * + * Copyright (C) 2021 + * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) + * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) + * - Helmholtz Centre Potsdam - GFZ German Research Centre for + * Geosciences (GFZ, https://www.gfz-potsdam.de) + * + * Parts of this program were developed within the context of the + * following publicly funded projects or measures: + * - Helmholtz Earth and Environment DataHub + * (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095) + * + * Licensed under the HEESIL, Version 1.0 or - as soon they will be + * approved by the "Community" - subsequent versions of the HEESIL + * (the "Licence"). + * + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://gitext.gfz-potsdam.de/software/heesil + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the Licence for the specific language governing + * permissions and limitations under the Licence. + */ +import { AxiosInstance } from 'axios' + +import { Attachment } from '@/models/Attachment' +import { DeviceAttachmentSerializer } from '@/serializers/jsonapi/DeviceAttachmentSerializer' + +export class DeviceAttachmentApi { + private axiosApi: AxiosInstance + private serializer: DeviceAttachmentSerializer + + constructor (axiosInstance: AxiosInstance) { + this.axiosApi = axiosInstance + this.serializer = new DeviceAttachmentSerializer() + } + + findById (id: string): Promise<Attachment> { + return this.axiosApi.get(id).then((rawRespmse) => { + const rawData = rawRespmse.data + return this.serializer.convertJsonApiObjectToModel(rawData) + }) + } + + deleteById (id: string): Promise<void> { + return this.axiosApi.delete<string, void>(id) + } + + add (deviceId: string, attachment: Attachment): Promise<Attachment> { + const url = '' + const data = this.serializer.convertModelToJsonApiData(attachment, deviceId) + return this.axiosApi.post(url, { data }).then((serverResponse) => { + return this.serializer.convertJsonApiObjectToModel(serverResponse.data) + }) + } + + update (deviceId: string, attachment: Attachment): Promise<Attachment> { + return new Promise<string>((resolve, reject) => { + if (attachment.id) { + resolve(attachment.id) + } else { + reject(new Error('no id for the Attachment')) + } + }).then((attachmentId) => { + const data = this.serializer.convertModelToJsonApiData(attachment, deviceId) + return this.axiosApi.patch(attachmentId, { data }).then((serverResponse) => { + return this.serializer.convertJsonApiObjectToModel(serverResponse.data) + }) + }) + } +} diff --git a/services/sms/DevicePropertyApi.ts b/services/sms/DevicePropertyApi.ts new file mode 100644 index 0000000000000000000000000000000000000000..5254beb5f8e6be32596ea61f7d6b508cd8f3d717 --- /dev/null +++ b/services/sms/DevicePropertyApi.ts @@ -0,0 +1,79 @@ +/** + * @license + * Web client of the Sensor Management System software developed within + * the Helmholtz DataHub Initiative by GFZ and UFZ. + * + * Copyright (C) 2021 + * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) + * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) + * - Helmholtz Centre Potsdam - GFZ German Research Centre for + * Geosciences (GFZ, https://www.gfz-potsdam.de) + * + * Parts of this program were developed within the context of the + * following publicly funded projects or measures: + * - Helmholtz Earth and Environment DataHub + * (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095) + * + * Licensed under the HEESIL, Version 1.0 or - as soon they will be + * approved by the "Community" - subsequent versions of the HEESIL + * (the "Licence"). + * + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://gitext.gfz-potsdam.de/software/heesil + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the Licence for the specific language governing + * permissions and limitations under the Licence. + */ +import { AxiosInstance } from 'axios' + +import { DeviceProperty } from '@/models/DeviceProperty' +import { DevicePropertySerializer } from '@/serializers/jsonapi/DevicePropertySerializer' + +export class DevicePropertyApi { + private axiosApi: AxiosInstance + private serializer: DevicePropertySerializer + + constructor (axiosInstance: AxiosInstance) { + this.axiosApi = axiosInstance + this.serializer = new DevicePropertySerializer() + } + + findById (id: string): Promise<DeviceProperty> { + return this.axiosApi.get(id).then((rawRespmse) => { + const rawData = rawRespmse.data + return this.serializer.convertJsonApiObjectToModel(rawData) + }) + } + + deleteById (id: string): Promise<void> { + return this.axiosApi.delete<string, void>(id) + } + + add (deviceId: string, deviceProperty: DeviceProperty): Promise<DeviceProperty> { + const url = '' + const data = this.serializer.convertModelToJsonApiData(deviceProperty, deviceId) + return this.axiosApi.post(url, { data }).then((serverResponse) => { + return this.serializer.convertJsonApiObjectToModel(serverResponse.data) + }) + } + + update (deviceId: string, deviceProperty: DeviceProperty) : Promise<DeviceProperty> { + return new Promise<string>((resolve, reject) => { + if (deviceProperty.id) { + resolve(deviceProperty.id) + } else { + reject(new Error('no id for the Attachment')) + } + }).then((devicePropertyId) => { + const data = this.serializer.convertModelToJsonApiData(deviceProperty, deviceId) + return this.axiosApi.patch(devicePropertyId, { data }).then((serverResponse) => { + return this.serializer.convertJsonApiObjectToModel(serverResponse.data) + }) + }) + } +} diff --git a/services/sms/PlatformApi.ts b/services/sms/PlatformApi.ts index 27842a866427361076e2f0b7aed89b99385e712c..df258d04822dea4be4cee546f2acb3f7b7d89efc 100644 --- a/services/sms/PlatformApi.ts +++ b/services/sms/PlatformApi.ts @@ -3,7 +3,7 @@ * Web client of the Sensor Management System software developed within * the Helmholtz DataHub Initiative by GFZ and UFZ. * - * Copyright (C) 2020 + * Copyright (C) 2020, 2021 * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) * - Helmholtz Centre Potsdam - GFZ German Research Centre for @@ -31,16 +31,21 @@ */ import { AxiosInstance, Method } from 'axios' +import { Attachment } from '@/models/Attachment' +import { Contact } from '@/models/Contact' import { Platform } from '@/models/Platform' import { PlatformType } from '@/models/PlatformType' import { Manufacturer } from '@/models/Manufacturer' import { Status } from '@/models/Status' +import { ContactSerializer } from '@/serializers/jsonapi/ContactSerializer' + import { PlatformSerializer, platformWithMetaToPlatformByThrowingErrorOnMissing, platformWithMetaToPlatformByAddingDummyObjects } from '@/serializers/jsonapi/PlatformSerializer' +import { PlatformAttachmentSerializer } from '@/serializers/jsonapi/PlatformAttachmentSerializer' import { IFlaskJSONAPIFilter } from '@/utils/JSONApiInterfaces' @@ -102,6 +107,46 @@ export class PlatformApi { newSearchBuilder (): PlatformSearchBuilder { return new PlatformSearchBuilder(this.axiosApi, this.serializer) } + + findRelatedContacts (platformId: string): Promise<Contact[]> { + const url = platformId + '/contacts' + const params = { + 'page[size]': 10000 + } + return this.axiosApi.get(url, { params }).then((rawServerResponse) => { + return new ContactSerializer().convertJsonApiObjectListToModelList(rawServerResponse.data) + }) + } + + findRelatedDeviceAttachments (deviceId: string): Promise<Attachment[]> { + const url = deviceId + '/device-attachments' + const params = { + 'page[size]': 10000 + } + return this.axiosApi.get(url, { params }).then((rawServerResponse) => { + return new PlatformAttachmentSerializer().convertJsonApiObjectListToModelList(rawServerResponse.data) + }) + } + + removeContact (platformId: string, contactId: string): Promise<void> { + const url = platformId + '/relationships/contacts' + const params = { + data: [{ + type: 'contact', + id: contactId + }] + } + return this.axiosApi.delete(url, { data: params }) + } + + addContact (platformId: string, contactId: string): Promise<void> { + const url = platformId + '/relationships/contacts' + const data = [{ + type: 'contact', + id: contactId + }] + return this.axiosApi.post(url, { data }) + } } export class PlatformSearchBuilder { diff --git a/services/sms/PlatformAttachmentApi.ts b/services/sms/PlatformAttachmentApi.ts new file mode 100644 index 0000000000000000000000000000000000000000..7f0ab0391ef589370a005f6b8f736e062b1867b1 --- /dev/null +++ b/services/sms/PlatformAttachmentApi.ts @@ -0,0 +1,79 @@ +/** + * @license + * Web client of the Sensor Management System software developed within + * the Helmholtz DataHub Initiative by GFZ and UFZ. + * + * Copyright (C) 2021 + * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) + * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) + * - Helmholtz Centre Potsdam - GFZ German Research Centre for + * Geosciences (GFZ, https://www.gfz-potsdam.de) + * + * Parts of this program were developed within the context of the + * following publicly funded projects or measures: + * - Helmholtz Earth and Environment DataHub + * (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095) + * + * Licensed under the HEESIL, Version 1.0 or - as soon they will be + * approved by the "Community" - subsequent versions of the HEESIL + * (the "Licence"). + * + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://gitext.gfz-potsdam.de/software/heesil + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the Licence for the specific language governing + * permissions and limitations under the Licence. + */ +import { AxiosInstance } from 'axios' + +import { Attachment } from '@/models/Attachment' +import { PlatformAttachmentSerializer } from '@/serializers/jsonapi/PlatformAttachmentSerializer' + +export class PlatformAttachmentApi { + private axiosApi: AxiosInstance + private serializer: PlatformAttachmentSerializer + + constructor (axiosInstance: AxiosInstance) { + this.axiosApi = axiosInstance + this.serializer = new PlatformAttachmentSerializer() + } + + findById (id: string): Promise<Attachment> { + return this.axiosApi.get(id).then((rawRespmse) => { + const rawData = rawRespmse.data + return this.serializer.convertJsonApiObjectToModel(rawData) + }) + } + + deleteById (id: string): Promise<void> { + return this.axiosApi.delete<string, void>(id) + } + + add (platformId: string, attachment: Attachment) : Promise<Attachment> { + const url = '' + const data = this.serializer.convertModelToJsonApiData(attachment, platformId) + return this.axiosApi.post(url, { data }).then((serverResponse) => { + return this.serializer.convertJsonApiObjectToModel(serverResponse.data) + }) + } + + update (platformId: string, attachment: Attachment) : Promise<Attachment> { + return new Promise<string>((resolve, reject) => { + if (attachment.id) { + resolve(attachment.id) + } else { + reject(new Error('no id for the Attachment')) + } + }).then((attachmentId) => { + const data = this.serializer.convertModelToJsonApiData(attachment, platformId) + return this.axiosApi.patch(attachmentId, { data }).then((serverResponse) => { + return this.serializer.convertJsonApiObjectToModel(serverResponse.data) + }) + }) + } +} diff --git a/test/serializers/jsonapi/CustomTextFieldSerializer.test.ts b/test/serializers/jsonapi/CustomTextFieldSerializer.test.ts index 27ced3b6254aaad8606e5a4e1f0423904dd09ebb..80f4221a316c7549a589cabcf25deab628acedc3 100644 --- a/test/serializers/jsonapi/CustomTextFieldSerializer.test.ts +++ b/test/serializers/jsonapi/CustomTextFieldSerializer.test.ts @@ -33,6 +33,10 @@ import { CustomTextField } from '@/models/CustomTextField' import { CustomTextFieldSerializer } from '@/serializers/jsonapi/CustomTextFieldSerializer' +import { + IJsonApiObjectList +} from '@/serializers/jsonapi/JsonApiTypes' + describe('CustomTextFieldSerializer', () => { describe('#convertNestedJsonApiToModelList', () => { it('should convert a list of entries to models', () => { @@ -148,5 +152,128 @@ describe('CustomTextFieldSerializer', () => { expect(deviceData).toHaveProperty('type') expect(deviceData.type).toEqual('device') }) + it('should also be possible if there is no id yet', () => { + const customfield = CustomTextField.createFromObject({ + id: null, + key: 'some key', + value: 'test test test' + }) + const serializer = new CustomTextFieldSerializer() + const deviceId = '456' + + const jsonApiPayload = serializer.convertModelToJsonApiData(customfield, deviceId) + + expect(jsonApiPayload).not.toHaveProperty('id') + expect(jsonApiPayload).toHaveProperty('type') + expect(jsonApiPayload.type).toEqual('customfield') + expect(jsonApiPayload).toHaveProperty('attributes') + expect(jsonApiPayload.attributes).toHaveProperty('key') + expect(jsonApiPayload.attributes.key).toEqual('some key') + expect(jsonApiPayload.attributes).toHaveProperty('value') + expect(jsonApiPayload.attributes.value).toEqual('test test test') + expect(jsonApiPayload).toHaveProperty('relationships') + expect(jsonApiPayload.relationships).toHaveProperty('device') + expect(jsonApiPayload.relationships.device).toHaveProperty('data') + const deviceData: any = jsonApiPayload.relationships.device.data + expect(deviceData).toHaveProperty('id') + expect(deviceData.id).toEqual('456') + expect(deviceData).toHaveProperty('type') + expect(deviceData.type).toEqual('device') + }) + }) + describe('#convertJsonApiDataToModel', () => { + it('should convert an example payload to a model', () => { + const data = { + id: '123', + type: 'customfield', + attributes: { + key: 'institute', + value: 'GFZ' + } + } + + const serializer = new CustomTextFieldSerializer() + const model = serializer.convertJsonApiDataToModel(data) + + expect(model.id).toEqual('123') + expect(model.key).toEqual('institute') + expect(model.value).toEqual('GFZ') + }) + it('should also convert missing values to empty strings', () => { + const data = { + id: '123', + type: 'customfield', + attributes: { + } + } + + const serializer = new CustomTextFieldSerializer() + const model = serializer.convertJsonApiDataToModel(data) + + expect(model.id).toEqual('123') + expect(model.key).toEqual('') + expect(model.value).toEqual('') + }) + }) + describe('#convertJsonApiObjectListToModelList', () => { + it('should convert two paylods to customTextField models', () => { + const data: IJsonApiObjectList = { + data: [ + { + id: '123', + type: 'customfield', + attributes: { + key: 'Website GFZ', + value: 'www.gfz-potsdam.de' + }, + relationships: {} + }, { + id: '124', + type: 'customfield', + attributes: { + key: 'Website UFZ', + value: 'www.ufz.de' + }, + relationships: {} + } + ], + included: [] + } + + const serializer = new CustomTextFieldSerializer() + const models = serializer.convertJsonApiObjectListToModelList(data) + + expect(models.length).toEqual(2) + expect(models[0].id).toEqual('123') + expect(models[0].key).toEqual('Website GFZ') + expect(models[0].value).toEqual('www.gfz-potsdam.de') + + expect(models[1].id).toEqual('124') + expect(models[1].key).toEqual('Website UFZ') + expect(models[1].value).toEqual('www.ufz.de') + }) + }) + describe('#convertJsonApiObjectToModel', () => { + it('should convert an example payload to a model', () => { + const data = { + data: { + id: '123', + type: 'customfield', + attributes: { + key: 'institute', + value: 'GFZ' + }, + relationships: {} + }, + included: [] + } + + const serializer = new CustomTextFieldSerializer() + const model = serializer.convertJsonApiObjectToModel(data) + + expect(model.id).toEqual('123') + expect(model.key).toEqual('institute') + expect(model.value).toEqual('GFZ') + }) }) }) diff --git a/test/serializers/jsonapi/DeviceAttachmentSerializer.test.ts b/test/serializers/jsonapi/DeviceAttachmentSerializer.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..e1c2fdc61214e5044af25f13f58105c9ec68bf6f --- /dev/null +++ b/test/serializers/jsonapi/DeviceAttachmentSerializer.test.ts @@ -0,0 +1,171 @@ +/** + * @license + * Web client of the Sensor Management System software developed within + * the Helmholtz DataHub Initiative by GFZ and UFZ. + * + * Copyright (C) 2021 + * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) + * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) + * - Helmholtz Centre Potsdam - GFZ German Research Centre for + * Geosciences (GFZ, https://www.gfz-potsdam.de) + * + * Parts of this program were developed within the context of the + * following publicly funded projects or measures: + * - Helmholtz Earth and Environment DataHub + * (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095) + * + * Licensed under the HEESIL, Version 1.0 or - as soon they will be + * approved by the "Community" - subsequent versions of the HEESIL + * (the "Licence"). + * + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://gitext.gfz-potsdam.de/software/heesil + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the Licence for the specific language governing + * permissions and limitations under the Licence. + */ + +import { Attachment } from '@/models/Attachment' +import { DeviceAttachmentSerializer } from '@/serializers/jsonapi/DeviceAttachmentSerializer' + +describe('DeviceAttachmetnSerializer', () => { + describe('#convertJsonApiObjectListToModelList', () => { + it('should create a list of attachments', () => { + const data = { + data: [{ + id: '123', + type: 'device_attachment', + attributes: { + url: 'https://www.gfz-potsdam.de', + label: 'GFZ Homepage' + }, + relationships: {} + }, { + id: '456', + type: 'device_attachment', + attributes: { + url: 'https://www.ufz.de', + label: 'UFZ Homepage' + }, + relationships: {} + }], + included: [] + } + const serializer = new DeviceAttachmentSerializer() + const models = serializer.convertJsonApiObjectListToModelList(data) + + expect(models.length).toEqual(2) + expect(models[0].id).toEqual('123') + expect(models[0].url).toEqual('https://www.gfz-potsdam.de') + expect(models[0].label).toEqual('GFZ Homepage') + expect(models[1].id).toEqual('456') + expect(models[1].url).toEqual('https://www.ufz.de') + expect(models[1].label).toEqual('UFZ Homepage') + }) + }) + describe('#convertJsonApiObjectToModel', () => { + it('should create the model from the json:api object', () => { + const data = { + data: { + id: '123', + type: 'device_attachment', + attributes: { + url: 'https://www.gfz-potsdam.de', + label: 'GFZ Homepage' + }, + relationships: {} + }, + included: [] + } + + const serializer = new DeviceAttachmentSerializer() + const model = serializer.convertJsonApiObjectToModel(data) + + expect(model.id).toEqual('123') + expect(model.url).toEqual('https://www.gfz-potsdam.de') + expect(model.label).toEqual('GFZ Homepage') + }) + it('should also fill the attributes with empty strings if missing', () => { + const data = { + data: { + id: '123', + type: 'device_attachment', + attributes: {}, + relationships: {} + }, + included: [] + } + + const serializer = new DeviceAttachmentSerializer() + const model = serializer.convertJsonApiObjectToModel(data) + + expect(model.id).toEqual('123') + expect(model.url).toEqual('') + expect(model.label).toEqual('') + }) + }) + describe('#convertModelToJsonApiData', () => { + it('should convert an attachment to a json:api payload', () => { + const attachment = Attachment.createFromObject({ + id: '123', + url: 'https://www.ufz.de', + label: 'UFZ Homepage' + }) + const serializer = new DeviceAttachmentSerializer() + const deviceId = '456' + + const jsonApiPayload = serializer.convertModelToJsonApiData(attachment, deviceId) + + expect(jsonApiPayload).toHaveProperty('id') + expect(jsonApiPayload.id).toEqual('123') + expect(jsonApiPayload).toHaveProperty('type') + expect(jsonApiPayload.type).toEqual('device_attachment') + expect(jsonApiPayload).toHaveProperty('attributes') + expect(jsonApiPayload.attributes).toHaveProperty('url') + expect(jsonApiPayload.attributes.url).toEqual('https://www.ufz.de') + expect(jsonApiPayload.attributes).toHaveProperty('label') + expect(jsonApiPayload.attributes.label).toEqual('UFZ Homepage') + expect(jsonApiPayload).toHaveProperty('relationships') + expect(jsonApiPayload.relationships).toHaveProperty('device') + expect(jsonApiPayload.relationships.device).toHaveProperty('data') + const deviceData: any = jsonApiPayload.relationships.device.data + expect(deviceData).toHaveProperty('id') + expect(deviceData.id).toEqual('456') + expect(deviceData).toHaveProperty('type') + expect(deviceData.type).toEqual('device') + }) + it('should also work if we don\'t have an id yet', () => { + const attachment = Attachment.createFromObject({ + id: null, + url: 'https://www.ufz.de', + label: 'UFZ Homepage' + }) + const serializer = new DeviceAttachmentSerializer() + const deviceId = '456' + + const jsonApiPayload = serializer.convertModelToJsonApiData(attachment, deviceId) + + expect(jsonApiPayload).not.toHaveProperty('id') + expect(jsonApiPayload).toHaveProperty('type') + expect(jsonApiPayload.type).toEqual('device_attachment') + expect(jsonApiPayload).toHaveProperty('attributes') + expect(jsonApiPayload.attributes).toHaveProperty('url') + expect(jsonApiPayload.attributes.url).toEqual('https://www.ufz.de') + expect(jsonApiPayload.attributes).toHaveProperty('label') + expect(jsonApiPayload.attributes.label).toEqual('UFZ Homepage') + expect(jsonApiPayload).toHaveProperty('relationships') + expect(jsonApiPayload.relationships).toHaveProperty('device') + expect(jsonApiPayload.relationships.device).toHaveProperty('data') + const deviceData: any = jsonApiPayload.relationships.device.data + expect(deviceData).toHaveProperty('id') + expect(deviceData.id).toEqual('456') + expect(deviceData).toHaveProperty('type') + expect(deviceData.type).toEqual('device') + }) + }) +}) diff --git a/test/serializers/jsonapi/DevicePropertySerializer.test.ts b/test/serializers/jsonapi/DevicePropertySerializer.test.ts index 55410c34b037fa93db43224190b6069dcf59c1a9..f44ddd267720e91ce7884261b0e8f3b04c162735 100644 --- a/test/serializers/jsonapi/DevicePropertySerializer.test.ts +++ b/test/serializers/jsonapi/DevicePropertySerializer.test.ts @@ -3,7 +3,7 @@ * Web client of the Sensor Management System software developed within * the Helmholtz DataHub Initiative by GFZ and UFZ. * - * Copyright (C) 2020 + * Copyright (C) 2020, 2021 * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) * - Helmholtz Centre Potsdam - GFZ German Research Centre for @@ -270,4 +270,326 @@ describe('DevicePropertySerializer', () => { }) }) }) + describe('#convertJsonApiObjectListToModelList', () => { + it('should create a list of device properties', () => { + const data = { + data: [{ + id: '123', + type: 'device_property', + attributes: { + compartment_name: 'Climate', + unit_uri: 'abc', + sampling_media_name: 'Other', + compartment_uri: 'variabletype/Climate', + property_name: 'Water vapor concentration', + accuracy: 0.1, + measuring_range_min: 10, + measuring_range_max: -10, + label: 'water vapor', + property_uri: 'variablename/Water%20vapor%20concentration', + unit_name: '%', + failure_value: -234, + sampling_media_uri: 'medium/Other', + resolution: 0.001, + resolution_unit_uri: 'http://foo/unit/1', + resolution_unit_name: 'mm' + }, + relationships: {} + }, { + id: '456', + type: 'device_property', + attributes: { + compartment_name: 'Resources', + unit_uri: 'xyz', + sampling_media_name: 'ether', + compartment_uri: 'variabletype/Resources', + property_name: 'abc', + accuracy: -2.9, + measuring_range_min: 100, + measuring_range_max: -100, + label: 'abc - prop', + property_uri: 'variablename/abc', + unit_name: 'n', + failure_value: -999, + sampling_media_uri: 'medium/ether', + resolution: 0.008, + resolution_unit_uri: 'http://foo/unit/100', + resolution_unit_name: '°C' + }, + relationships: {} + }], + included: [] + } + const serializer = new DevicePropertySerializer() + const models = serializer.convertJsonApiObjectListToModelList(data) + + expect(models.length).toEqual(2) + expect(models[0].id).toEqual('123') + expect(models[0].compartmentName).toEqual('Climate') + expect(models[0].unitUri).toEqual('abc') + expect(models[0].samplingMediaName).toEqual('Other') + expect(models[0].compartmentUri).toEqual('variabletype/Climate') + expect(models[0].propertyName).toEqual('Water vapor concentration') + expect(models[0].accuracy).toEqual(0.1) + // I know it is the wrong ordering + expect(models[0].measuringRange.min).toEqual(10) + expect(models[0].measuringRange.max).toEqual(-10) + expect(models[0].label).toEqual('water vapor') + expect(models[0].propertyUri).toEqual('variablename/Water%20vapor%20concentration') + expect(models[0].unitName).toEqual('%') + expect(models[0].failureValue).toEqual(-234) + expect(models[0].samplingMediaUri).toEqual('medium/Other') + expect(models[0].resolution).toEqual(0.001) + expect(models[0].resolutionUnitUri).toEqual('http://foo/unit/1') + expect(models[0].resolutionUnitName).toEqual('mm') + + expect(models[1].id).toEqual('456') + expect(models[1].compartmentName).toEqual('Resources') + expect(models[1].unitUri).toEqual('xyz') + expect(models[1].samplingMediaName).toEqual('ether') + expect(models[1].compartmentUri).toEqual('variabletype/Resources') + expect(models[1].propertyName).toEqual('abc') + expect(models[1].accuracy).toEqual(-2.9) + expect(models[1].measuringRange.min).toEqual(100) + expect(models[1].measuringRange.max).toEqual(-100) + expect(models[1].label).toEqual('abc - prop') + expect(models[1].propertyUri).toEqual('variablename/abc') + expect(models[1].unitName).toEqual('n') + expect(models[1].failureValue).toEqual(-999) + expect(models[1].samplingMediaUri).toEqual('medium/ether') + expect(models[1].resolution).toEqual(0.008) + expect(models[1].resolutionUnitUri).toEqual('http://foo/unit/100') + expect(models[1].resolutionUnitName).toEqual('°C') + }) + }) + describe('#convertJsonApiObjectToModel', () => { + it('should create the model from the json:api object', () => { + const data = { + data: { + id: '123', + type: 'device_property', + attributes: { + compartment_name: 'Climate', + unit_uri: 'abc', + sampling_media_name: 'Other', + compartment_uri: 'variabletype/Climate', + property_name: 'Water vapor concentration', + accuracy: 0.1, + measuring_range_min: 10, + measuring_range_max: -10, + label: 'water vapor', + property_uri: 'variablename/Water%20vapor%20concentration', + unit_name: '%', + failure_value: -234, + sampling_media_uri: 'medium/Other', + resolution: 0.001, + resolution_unit_uri: 'http://foo/unit/1', + resolution_unit_name: 'mm' + }, + relationships: {} + }, + included: [] + } + const serializer = new DevicePropertySerializer() + const model = serializer.convertJsonApiObjectToModel(data) + + expect(model.id).toEqual('123') + expect(model.compartmentName).toEqual('Climate') + expect(model.unitUri).toEqual('abc') + expect(model.samplingMediaName).toEqual('Other') + expect(model.compartmentUri).toEqual('variabletype/Climate') + expect(model.propertyName).toEqual('Water vapor concentration') + expect(model.accuracy).toEqual(0.1) + expect(model.measuringRange.min).toEqual(10) + expect(model.measuringRange.max).toEqual(-10) + expect(model.label).toEqual('water vapor') + expect(model.propertyUri).toEqual('variablename/Water%20vapor%20concentration') + expect(model.unitName).toEqual('%') + expect(model.failureValue).toEqual(-234) + expect(model.samplingMediaUri).toEqual('medium/Other') + expect(model.resolution).toEqual(0.001) + expect(model.resolutionUnitUri).toEqual('http://foo/unit/1') + expect(model.resolutionUnitName).toEqual('mm') + }) + it('should also fill the attributes with empty strings if missing', () => { + const data = { + data: { + id: '123', + type: 'device_property', + attributes: {}, + relationships: {} + }, + included: [] + } + const serializer = new DevicePropertySerializer() + const model = serializer.convertJsonApiObjectToModel(data) + + expect(model.id).toEqual('123') + expect(model.compartmentName).toEqual('') + expect(model.unitUri).toEqual('') + expect(model.samplingMediaName).toEqual('') + expect(model.compartmentUri).toEqual('') + expect(model.propertyName).toEqual('') + expect(model.accuracy).toEqual(null) + expect(model.measuringRange.min).toEqual(null) + expect(model.measuringRange.max).toEqual(null) + expect(model.label).toEqual('') + expect(model.propertyUri).toEqual('') + expect(model.unitName).toEqual('') + expect(model.failureValue).toEqual(null) + expect(model.samplingMediaUri).toEqual('') + expect(model.resolution).toEqual(null) + expect(model.resolutionUnitUri).toEqual('') + expect(model.resolutionUnitName).toEqual('') + }) + }) + describe('#convertModelToJsonApiData', () => { + it('should convert device prooperty to a json:api payload', () => { + const deviceProperty = DeviceProperty.createFromObject({ + id: '123', + compartmentName: 'Climate', + unitUri: 'abc', + samplingMediaName: 'Other', + compartmentUri: 'variabletype/Climate', + propertyName: 'Water vapor concentration', + accuracy: 0.1, + measuringRange: MeasuringRange.createFromObject({ + min: 10, + max: -10 + }), + label: 'water vapor', + propertyUri: 'variablename/Water%20vapor%20concentration', + unitName: '%', + failureValue: -234, + samplingMediaUri: 'medium/Other', + resolution: 0.001, + resolutionUnitUri: 'http://foo/unit/1', + resolutionUnitName: 'mm' + }) + const serializer = new DevicePropertySerializer() + const deviceId = '456' + + const jsonApiPayload = serializer.convertModelToJsonApiData(deviceProperty, deviceId) + + expect(jsonApiPayload).toHaveProperty('id') + expect(jsonApiPayload.id).toEqual('123') + expect(jsonApiPayload).toHaveProperty('type') + expect(jsonApiPayload.type).toEqual('device_property') + expect(jsonApiPayload).toHaveProperty('attributes') + expect(jsonApiPayload.attributes).toHaveProperty('compartment_name') + expect(jsonApiPayload.attributes.compartment_name).toEqual('Climate') + expect(jsonApiPayload.attributes).toHaveProperty('unit_uri') + expect(jsonApiPayload.attributes.unit_uri).toEqual('abc') + expect(jsonApiPayload.attributes).toHaveProperty('sampling_media_name') + expect(jsonApiPayload.attributes.sampling_media_name).toEqual('Other') + expect(jsonApiPayload.attributes).toHaveProperty('compartment_uri') + expect(jsonApiPayload.attributes.compartment_uri).toEqual('variabletype/Climate') + expect(jsonApiPayload.attributes).toHaveProperty('property_name') + expect(jsonApiPayload.attributes.property_name).toEqual('Water vapor concentration') + expect(jsonApiPayload.attributes).toHaveProperty('accuracy') + expect(jsonApiPayload.attributes.accuracy).toEqual(0.1) + expect(jsonApiPayload.attributes).toHaveProperty('measuring_range_min') + expect(jsonApiPayload.attributes.measuring_range_min).toEqual(10) + expect(jsonApiPayload.attributes).toHaveProperty('measuring_range_max') + expect(jsonApiPayload.attributes.measuring_range_max).toEqual(-10) + expect(jsonApiPayload.attributes).toHaveProperty('label') + expect(jsonApiPayload.attributes.label).toEqual('water vapor') + expect(jsonApiPayload.attributes).toHaveProperty('property_uri') + expect(jsonApiPayload.attributes.property_uri).toEqual('variablename/Water%20vapor%20concentration') + expect(jsonApiPayload.attributes).toHaveProperty('unit_name') + expect(jsonApiPayload.attributes.unit_name).toEqual('%') + expect(jsonApiPayload.attributes).toHaveProperty('failure_value') + expect(jsonApiPayload.attributes.failure_value).toEqual(-234) + expect(jsonApiPayload.attributes).toHaveProperty('sampling_media_uri') + expect(jsonApiPayload.attributes.sampling_media_uri).toEqual('medium/Other') + expect(jsonApiPayload.attributes).toHaveProperty('resolution') + expect(jsonApiPayload.attributes.resolution).toEqual(0.001) + expect(jsonApiPayload.attributes).toHaveProperty('resolution_unit_uri') + expect(jsonApiPayload.attributes.resolution_unit_uri).toEqual('http://foo/unit/1') + expect(jsonApiPayload.attributes).toHaveProperty('resolution_unit_name') + expect(jsonApiPayload.attributes.resolution_unit_name).toEqual('mm') + + expect(jsonApiPayload).toHaveProperty('relationships') + expect(jsonApiPayload.relationships).toHaveProperty('device') + expect(jsonApiPayload.relationships.device).toHaveProperty('data') + const deviceData: any = jsonApiPayload.relationships.device.data + expect(deviceData).toHaveProperty('id') + expect(deviceData.id).toEqual('456') + expect(deviceData).toHaveProperty('type') + expect(deviceData.type).toEqual('device') + }) + it('should also work if we don\'t have an id yet', () => { + const deviceProperty = DeviceProperty.createFromObject({ + id: null, + compartmentName: 'Climate', + unitUri: 'abc', + samplingMediaName: 'Other', + compartmentUri: 'variabletype/Climate', + propertyName: 'Water vapor concentration', + accuracy: 0.1, + measuringRange: MeasuringRange.createFromObject({ + min: 10, + max: -10 + }), + label: 'water vapor', + propertyUri: 'variablename/Water%20vapor%20concentration', + unitName: '%', + failureValue: -234, + samplingMediaUri: 'medium/Other', + resolution: 0.001, + resolutionUnitUri: 'http://foo/unit/1', + resolutionUnitName: 'mm' + }) + const serializer = new DevicePropertySerializer() + const deviceId = '456' + + const jsonApiPayload = serializer.convertModelToJsonApiData(deviceProperty, deviceId) + + expect(jsonApiPayload).not.toHaveProperty('id') + expect(jsonApiPayload).toHaveProperty('type') + expect(jsonApiPayload.type).toEqual('device_property') + expect(jsonApiPayload).toHaveProperty('attributes') + expect(jsonApiPayload.attributes).toHaveProperty('compartment_name') + expect(jsonApiPayload.attributes.compartment_name).toEqual('Climate') + expect(jsonApiPayload.attributes).toHaveProperty('unit_uri') + expect(jsonApiPayload.attributes.unit_uri).toEqual('abc') + expect(jsonApiPayload.attributes).toHaveProperty('sampling_media_name') + expect(jsonApiPayload.attributes.sampling_media_name).toEqual('Other') + expect(jsonApiPayload.attributes).toHaveProperty('compartment_uri') + expect(jsonApiPayload.attributes.compartment_uri).toEqual('variabletype/Climate') + expect(jsonApiPayload.attributes).toHaveProperty('property_name') + expect(jsonApiPayload.attributes.property_name).toEqual('Water vapor concentration') + expect(jsonApiPayload.attributes).toHaveProperty('accuracy') + expect(jsonApiPayload.attributes.accuracy).toEqual(0.1) + expect(jsonApiPayload.attributes).toHaveProperty('measuring_range_min') + expect(jsonApiPayload.attributes.measuring_range_min).toEqual(10) + expect(jsonApiPayload.attributes).toHaveProperty('measuring_range_max') + expect(jsonApiPayload.attributes.measuring_range_max).toEqual(-10) + expect(jsonApiPayload.attributes).toHaveProperty('label') + expect(jsonApiPayload.attributes.label).toEqual('water vapor') + expect(jsonApiPayload.attributes).toHaveProperty('property_uri') + expect(jsonApiPayload.attributes.property_uri).toEqual('variablename/Water%20vapor%20concentration') + expect(jsonApiPayload.attributes).toHaveProperty('unit_name') + expect(jsonApiPayload.attributes.unit_name).toEqual('%') + expect(jsonApiPayload.attributes).toHaveProperty('failure_value') + expect(jsonApiPayload.attributes.failure_value).toEqual(-234) + expect(jsonApiPayload.attributes).toHaveProperty('sampling_media_uri') + expect(jsonApiPayload.attributes.sampling_media_uri).toEqual('medium/Other') + expect(jsonApiPayload.attributes).toHaveProperty('resolution') + expect(jsonApiPayload.attributes.resolution).toEqual(0.001) + expect(jsonApiPayload.attributes).toHaveProperty('resolution_unit_uri') + expect(jsonApiPayload.attributes.resolution_unit_uri).toEqual('http://foo/unit/1') + expect(jsonApiPayload.attributes).toHaveProperty('resolution_unit_name') + expect(jsonApiPayload.attributes.resolution_unit_name).toEqual('mm') + + expect(jsonApiPayload).toHaveProperty('relationships') + expect(jsonApiPayload.relationships).toHaveProperty('device') + expect(jsonApiPayload.relationships.device).toHaveProperty('data') + const deviceData: any = jsonApiPayload.relationships.device.data + expect(deviceData).toHaveProperty('id') + expect(deviceData.id).toEqual('456') + expect(deviceData).toHaveProperty('type') + expect(deviceData.type).toEqual('device') + }) + }) }) diff --git a/test/serializers/jsonapi/PlatformAttachmentSerializer.test.ts b/test/serializers/jsonapi/PlatformAttachmentSerializer.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..e41f5f3e487c6f69eeae8273428762837e6d6032 --- /dev/null +++ b/test/serializers/jsonapi/PlatformAttachmentSerializer.test.ts @@ -0,0 +1,171 @@ +/** + * @license + * Web client of the Sensor Management System software developed within + * the Helmholtz DataHub Initiative by GFZ and UFZ. + * + * Copyright (C) 2021 + * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de) + * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de) + * - Helmholtz Centre Potsdam - GFZ German Research Centre for + * Geosciences (GFZ, https://www.gfz-potsdam.de) + * + * Parts of this program were developed within the context of the + * following publicly funded projects or measures: + * - Helmholtz Earth and Environment DataHub + * (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095) + * + * Licensed under the HEESIL, Version 1.0 or - as soon they will be + * approved by the "Community" - subsequent versions of the HEESIL + * (the "Licence"). + * + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://gitext.gfz-potsdam.de/software/heesil + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the Licence for the specific language governing + * permissions and limitations under the Licence. + */ + +import { Attachment } from '@/models/Attachment' +import { PlatformAttachmentSerializer } from '@/serializers/jsonapi/PlatformAttachmentSerializer' + +describe('PlatformAttachmentSerializer', () => { + describe('#convertJsonApiObjectListToModelList', () => { + it('should create a list of attachments', () => { + const data = { + data: [{ + id: '123', + type: 'platform_attachment', + attributes: { + url: 'https://www.gfz-potsdam.de', + label: 'GFZ Homepage' + }, + relationships: {} + }, { + id: '456', + type: 'platform_attachment', + attributes: { + url: 'https://www.ufz.de', + label: 'UFZ Homepage' + }, + relationships: {} + }], + included: [] + } + const serializer = new PlatformAttachmentSerializer() + const models = serializer.convertJsonApiObjectListToModelList(data) + + expect(models.length).toEqual(2) + expect(models[0].id).toEqual('123') + expect(models[0].url).toEqual('https://www.gfz-potsdam.de') + expect(models[0].label).toEqual('GFZ Homepage') + expect(models[1].id).toEqual('456') + expect(models[1].url).toEqual('https://www.ufz.de') + expect(models[1].label).toEqual('UFZ Homepage') + }) + }) + describe('#convertJsonApiObjectToModel', () => { + it('should create the model from the json:api object', () => { + const data = { + data: { + id: '123', + type: 'platform_attachment', + attributes: { + url: 'https://www.gfz-potsdam.de', + label: 'GFZ Homepage' + }, + relationships: {} + }, + included: [] + } + + const serializer = new PlatformAttachmentSerializer() + const model = serializer.convertJsonApiObjectToModel(data) + + expect(model.id).toEqual('123') + expect(model.url).toEqual('https://www.gfz-potsdam.de') + expect(model.label).toEqual('GFZ Homepage') + }) + it('should also fill the attributes with empty strings if missing', () => { + const data = { + data: { + id: '123', + type: 'device_attachment', + attributes: {}, + relationships: {} + }, + included: [] + } + + const serializer = new PlatformAttachmentSerializer() + const model = serializer.convertJsonApiObjectToModel(data) + + expect(model.id).toEqual('123') + expect(model.url).toEqual('') + expect(model.label).toEqual('') + }) + }) + describe('#convertModelToJsonApiData', () => { + it('should convert an attachment to a json:api payload', () => { + const attachment = Attachment.createFromObject({ + id: '123', + url: 'https://www.ufz.de', + label: 'UFZ Homepage' + }) + const serializer = new PlatformAttachmentSerializer() + const platformId = '456' + + const jsonApiPayload = serializer.convertModelToJsonApiData(attachment, platformId) + + expect(jsonApiPayload).toHaveProperty('id') + expect(jsonApiPayload.id).toEqual('123') + expect(jsonApiPayload).toHaveProperty('type') + expect(jsonApiPayload.type).toEqual('platform_attachment') + expect(jsonApiPayload).toHaveProperty('attributes') + expect(jsonApiPayload.attributes).toHaveProperty('url') + expect(jsonApiPayload.attributes.url).toEqual('https://www.ufz.de') + expect(jsonApiPayload.attributes).toHaveProperty('label') + expect(jsonApiPayload.attributes.label).toEqual('UFZ Homepage') + expect(jsonApiPayload).toHaveProperty('relationships') + expect(jsonApiPayload.relationships).toHaveProperty('platform') + expect(jsonApiPayload.relationships.platform).toHaveProperty('data') + const platformData: any = jsonApiPayload.relationships.platform.data + expect(platformData).toHaveProperty('id') + expect(platformData.id).toEqual('456') + expect(platformData).toHaveProperty('type') + expect(platformData.type).toEqual('platform') + }) + it('should also work if we don\'t have an id yet', () => { + const attachment = Attachment.createFromObject({ + id: null, + url: 'https://www.ufz.de', + label: 'UFZ Homepage' + }) + const serializer = new PlatformAttachmentSerializer() + const platformId = '456' + + const jsonApiPayload = serializer.convertModelToJsonApiData(attachment, platformId) + + expect(jsonApiPayload).not.toHaveProperty('id') + expect(jsonApiPayload).toHaveProperty('type') + expect(jsonApiPayload.type).toEqual('platform_attachment') + expect(jsonApiPayload).toHaveProperty('attributes') + expect(jsonApiPayload.attributes).toHaveProperty('url') + expect(jsonApiPayload.attributes.url).toEqual('https://www.ufz.de') + expect(jsonApiPayload.attributes).toHaveProperty('label') + expect(jsonApiPayload.attributes.label).toEqual('UFZ Homepage') + expect(jsonApiPayload).toHaveProperty('relationships') + expect(jsonApiPayload.relationships).toHaveProperty('platform') + expect(jsonApiPayload.relationships.platform).toHaveProperty('data') + const platformData: any = jsonApiPayload.relationships.platform.data + expect(platformData).toHaveProperty('id') + expect(platformData.id).toEqual('456') + expect(platformData).toHaveProperty('type') + expect(platformData.type).toEqual('platform') + }) + }) +})