diff --git a/poem/Poem/api/internal_views/metrics.py b/poem/Poem/api/internal_views/metrics.py
index 2074b8148..2aadce9c6 100644
--- a/poem/Poem/api/internal_views/metrics.py
+++ b/poem/Poem/api/internal_views/metrics.py
@@ -46,11 +46,12 @@ def get(self, request, name=None):
if name:
metrics = poem_models.Metric.objects.filter(name=name)
if metrics.count() == 0:
- raise NotFound(status=404,
- detail='Metric not found')
+ raise NotFound(status=404, detail='Metric not found')
else:
metrics = poem_models.Metric.objects.all()
+ profiles4metrics = get_metrics_in_profiles(request.tenant)
+
results = []
for metric in metrics:
if metric.probeversion:
@@ -88,6 +89,8 @@ def get(self, request, name=None):
name=metric.name,
mtype=mt.mtype.name,
tags=[tag.name for tag in mt.tags.all()],
+ profiles=profiles4metrics[metric.name]
+ if metric.name in profiles4metrics else [],
probeversion=metric.probeversion if metric.probeversion else "",
group=group,
description=mt.description,
diff --git a/poem/Poem/api/internal_views/metrictemplates.py b/poem/Poem/api/internal_views/metrictemplates.py
index 41034fcb7..83c0f19cf 100644
--- a/poem/Poem/api/internal_views/metrictemplates.py
+++ b/poem/Poem/api/internal_views/metrictemplates.py
@@ -758,7 +758,10 @@ def get(self, request, name=None):
return Response({
"id": tag.id,
"name": tag.name,
- "metrics": sorted([metric.name for metric in metrics])
+ "metrics": sorted(
+ [{"name": metric.name} for metric in metrics],
+ key=lambda m: m["name"]
+ )
})
except admin_models.MetricTags.DoesNotExist:
@@ -777,7 +780,10 @@ def get(self, request, name=None):
data.append({
"id": tag.id,
"name": tag.name,
- "metrics": sorted([metric.name for metric in metrics])
+ "metrics": sorted(
+ [{"name": metric.name} for metric in metrics],
+ key=lambda m: m["name"]
+ )
})
return Response(data)
@@ -831,14 +837,16 @@ def post(self, request):
if len(missing_metrics) > 0:
if len(missing_metrics) == 1:
- warn_msg = \
- f"{warn_msg}Metric {list(missing_metrics)[0]} " \
+ warn_msg = (
+ f"{warn_msg}Metric {list(missing_metrics)[0]} "
f"does not exist."
+ )
else:
- warn_msg = "{}Metrics {} do not exist.".format(
- warn_msg,
- ", ".join(sorted(list(missing_metrics)))
+ warn_msg = (
+ f"{warn_msg}Metrics "
+ f"{', '.join(sorted(list(missing_metrics)))} "
+ f"do not exist."
)
if warn_msg:
diff --git a/poem/Poem/api/tests/test_metrics.py b/poem/Poem/api/tests/test_metrics.py
index 9fef91a86..bd9843534 100644
--- a/poem/Poem/api/tests/test_metrics.py
+++ b/poem/Poem/api/tests/test_metrics.py
@@ -313,6 +313,11 @@ def mock_db():
content_type=ct
)
+profiles4metrics = {
+ "argo.AMS-Check": ["ARGO_MON", "ARGO_MON_CRITICAL"],
+ "argo.AMSPublisher-Check": ["ARGO_MON_INTERNAL"]
+}
+
class ListAllMetricsAPIViewTests(TenantTestCase):
@factory.django.mute_signals(pre_save)
@@ -424,8 +429,11 @@ def setUp(self):
name="org.apel.APEL-Pub"
)
- def test_get_metric_list(self):
+ @patch("Poem.api.internal_views.metrics.get_metrics_in_profiles")
+ def test_get_metric_list(self, mock_profiles4metrics):
+ mock_profiles4metrics.return_value = profiles4metrics
request = self.factory.get(self.url)
+ request.tenant = self.tenant
force_authenticate(request, user=self.user)
response = self.view(request)
self.assertEqual(
@@ -436,6 +444,7 @@ def test_get_metric_list(self):
'name': 'argo.AMS-Check',
'mtype': 'Active',
'tags': ['test_tag1', 'test_tag2'],
+ "profiles": ["ARGO_MON", "ARGO_MON_CRITICAL"],
'probeversion': 'ams-probe (0.1.7)',
'group': 'EGI',
'description': 'Description of argo.AMS-Check',
@@ -490,6 +499,7 @@ def test_get_metric_list(self):
'name': 'argo.AMSPublisher-Check',
'mtype': 'Active',
'tags': ['test_tag1'],
+ "profiles": ["ARGO_MON_INTERNAL"],
'probeversion': 'ams-publisher-probe (0.1.7)',
'group': 'EUDAT',
'description': '',
@@ -538,6 +548,7 @@ def test_get_metric_list(self):
'name': 'org.apel.APEL-Pub',
'mtype': 'Passive',
'tags': [],
+ "profiles": [],
'probeversion': '',
'group': 'EGI',
'description': '',
@@ -563,8 +574,11 @@ def test_get_metric_list(self):
]
)
- def test_get_metric_by_name(self):
+ @patch("Poem.api.internal_views.metrics.get_metrics_in_profiles")
+ def test_get_metric_by_name(self, mock_profiles4metrics):
+ mock_profiles4metrics.return_value = profiles4metrics
request = self.factory.get(self.url + 'argo.AMS-Check')
+ request.tenant = self.tenant
force_authenticate(request, user=self.user)
response = self.view(request, 'argo.AMS-Check')
self.assertEqual(
@@ -574,6 +588,7 @@ def test_get_metric_by_name(self):
'name': 'argo.AMS-Check',
'mtype': 'Active',
'tags': ['test_tag1', 'test_tag2'],
+ "profiles": ["ARGO_MON", "ARGO_MON_CRITICAL"],
'probeversion': 'ams-probe (0.1.7)',
'group': 'EGI',
'description': 'Description of argo.AMS-Check',
diff --git a/poem/Poem/api/tests/test_metrictemplates.py b/poem/Poem/api/tests/test_metrictemplates.py
index d6a046773..74ae8e4d4 100644
--- a/poem/Poem/api/tests/test_metrictemplates.py
+++ b/poem/Poem/api/tests/test_metrictemplates.py
@@ -10022,17 +10022,25 @@ def test_get_metric_tags_admin_superuser(self):
{
"id": self.tag1.id,
"name": "internal",
- "metrics": ["argo.AMS-Check"]
+ "metrics": [{
+ "name": "argo.AMS-Check"
+ }]
},
{
"id": self.tag3.id,
"name": "test_tag1",
- "metrics": ["argo.AMS-Check", "argo.EGI-Connectors-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"},
+ {"name": "argo.EGI-Connectors-Check"}
+ ]
},
{
"id": self.tag4.id,
"name": "test_tag2",
- "metrics": ["argo.AMS-Check", "org.apel.APEL-Pub"]
+ "metrics": [
+ {"name": "argo.AMS-Check"},
+ {"name": "org.apel.APEL-Pub"}
+ ]
}
]
)
@@ -10052,17 +10060,25 @@ def test_get_metric_tags_admin_regular_user(self):
{
"id": self.tag1.id,
"name": "internal",
- "metrics": ["argo.AMS-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"}
+ ]
},
{
"id": self.tag3.id,
"name": "test_tag1",
- "metrics": ["argo.AMS-Check", "argo.EGI-Connectors-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"},
+ {"name": "argo.EGI-Connectors-Check"}
+ ]
},
{
"id": self.tag4.id,
"name": "test_tag2",
- "metrics": ["argo.AMS-Check", "org.apel.APEL-Pub"]
+ "metrics": [
+ {"name": "argo.AMS-Check"},
+ {"name": "org.apel.APEL-Pub"}
+ ]
}
]
)
@@ -10082,17 +10098,25 @@ def test_get_metric_tags_tenant_superuser(self):
{
"id": self.tag1.id,
"name": "internal",
- "metrics": ["argo.AMS-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"}
+ ]
},
{
"id": self.tag3.id,
"name": "test_tag1",
- "metrics": ["argo.AMS-Check", "argo.EGI-Connectors-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"},
+ {"name": "argo.EGI-Connectors-Check"}
+ ]
},
{
"id": self.tag4.id,
"name": "test_tag2",
- "metrics": ["argo.AMS-Check", "org.apel.APEL-Pub"]
+ "metrics": [
+ {"name": "argo.AMS-Check"},
+ {"name": "org.apel.APEL-Pub"}
+ ]
}
]
)
@@ -10112,17 +10136,25 @@ def test_get_metric_tags_tenant_regular_user(self):
{
"id": self.tag1.id,
"name": "internal",
- "metrics": ["argo.AMS-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"}
+ ]
},
{
"id": self.tag3.id,
"name": "test_tag1",
- "metrics": ["argo.AMS-Check", "argo.EGI-Connectors-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"},
+ {"name": "argo.EGI-Connectors-Check"}
+ ]
},
{
"id": self.tag4.id,
"name": "test_tag2",
- "metrics": ["argo.AMS-Check", "org.apel.APEL-Pub"]
+ "metrics": [
+ {"name": "argo.AMS-Check"},
+ {"name": "org.apel.APEL-Pub"}
+ ]
}
]
)
@@ -10141,7 +10173,9 @@ def test_get_metric_tag_by_name_admin_superuser(self):
{
"id": self.tag1.id,
"name": "internal",
- "metrics": ["argo.AMS-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"}
+ ]
}
)
@@ -10154,7 +10188,9 @@ def test_get_metric_tag_by_name_admin_regular_user(self):
{
"id": self.tag1.id,
"name": "internal",
- "metrics": ["argo.AMS-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"}
+ ]
}
)
@@ -10167,7 +10203,9 @@ def test_get_metric_tag_by_name_tenant_superuser(self):
{
"id": self.tag1.id,
"name": "internal",
- "metrics": ["argo.AMS-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"}
+ ]
}
)
@@ -10180,7 +10218,9 @@ def test_get_metric_tag_by_name_tenant_regular_user(self):
{
"id": self.tag1.id,
"name": "internal",
- "metrics": ["argo.AMS-Check"]
+ "metrics": [
+ {"name": "argo.AMS-Check"}
+ ]
}
)
diff --git a/poem/Poem/frontend/react/MetricTags.js b/poem/Poem/frontend/react/MetricTags.js
index ad586fd93..5f85a7ad0 100644
--- a/poem/Poem/frontend/react/MetricTags.js
+++ b/poem/Poem/frontend/react/MetricTags.js
@@ -1,4 +1,4 @@
-import React, { useState } from "react"
+import React, { useContext, useEffect, useState } from "react"
import { useMutation, useQuery, useQueryClient } from "react-query"
import { Link, useLocation, useParams, useNavigate } from "react-router-dom"
import { fetchMetricTags, fetchMetricTemplates, fetchUserDetails } from "./QueryFunctions"
@@ -31,7 +31,7 @@ import {
} from "reactstrap"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faSearch,faPlus, faTimes } from '@fortawesome/free-solid-svg-icons';
-import { Controller, useForm, useWatch } from "react-hook-form"
+import { Controller, FormProvider, useFieldArray, useForm, useFormContext, useWatch } from "react-hook-form"
import { ErrorMessage } from '@hookform/error-message'
import { yupResolver } from '@hookform/resolvers/yup'
import * as Yup from "yup"
@@ -46,6 +46,9 @@ const validationSchema = Yup.object().shape({
})
+const MetricTagsContext = React.createContext()
+
+
export const MetricTagsList = (props) => {
const location = useLocation();
const publicView = props.publicView
@@ -80,7 +83,7 @@ export const MetricTagsList = (props) => {
:
row.value.map((metric, i) =>
- { metric }
+ { metric.name }
)
}
@@ -120,6 +123,134 @@ export const MetricTagsList = (props) => {
}
+const MetricsList = () => {
+ const context = useContext(MetricTagsContext)
+
+ const { control, getValues, setValue, resetField } = useFormContext()
+
+ const { fields, insert, remove } = useFieldArray({ control, name: "view_metrics4tag" })
+
+ const onRemove = (index) => {
+ let tmp_metrics4tag = [ ...context.metrics4tag ]
+ let origIndex = tmp_metrics4tag.findIndex(e => e.name == getValues(`view_metrics4tag.${index}.name`))
+ tmp_metrics4tag.splice(origIndex, 1)
+ resetField("metrics4tag")
+ setValue("metrics4tag", tmp_metrics4tag)
+ remove(index)
+ }
+
+ const onInsert = (index) => {
+ let tmp_metrics4tag = [ ...context.metrics4tag ]
+ let origIndex = tmp_metrics4tag.findIndex(e => e.name == getValues(`view_metrics4tag.${index}.name`))
+ let new_element = { name: "" }
+ tmp_metrics4tag.splice(origIndex + 1, 0, new_element)
+ resetField("metrics4tag")
+ setValue("metrics4tag", tmp_metrics4tag)
+ insert(index + 1, new_element)
+ }
+
+ return (
+
+
+
+ # |
+ Metric template |
+ {
+ !context.publicView && Actions |
+ }
+
+
+
+
+
+
+ |
+
+
+
+ }
+ />
+ |
+
+ {
+ fields.map((item, index) =>
+
+
+
+ { index + 1 }
+ |
+
+ {
+ context.publicView ?
+ item.name
+ :
+
+ {
+ let origIndex = getValues("metrics4tag").findIndex(met => met.name == getValues(`view_metrics4tag.${index}.name`) )
+ setValue(`metrics4tag.${origIndex}.name`, e.value)
+ setValue(`view_metrics4tag.${index}.name`, e.value)
+ } }
+ options={
+ context.allMetrics.map(
+ met => met.name
+ ).filter(
+ met => !context.metrics4tag.map(met => met.name).includes(met)
+ ).map(
+ option => new Object({ label: option, value: option })
+ )}
+ value={ { label: field.value, value: field.value } }
+ />
+ }
+ />
+ }
+ |
+ {
+ !context.publicView &&
+
+
+
+ |
+ }
+
+
+ )
+ }
+
+
+ )
+}
+
+
const MetricTagsForm = ({
name=undefined,
tag=undefined,
@@ -142,19 +273,41 @@ const MetricTagsForm = ({
const addMutation = useMutation(async (values) => await backend.addObject('/api/v2/internal/metrictags/', values));
const deleteMutation = useMutation(async () => await backend.deleteObject(`/api/v2/internal/metrictags/${name}`))
- const { control, getValues, setValue, handleSubmit, formState: { errors } } = useForm({
+ const default_metrics4tag = tag?.metrics.length > 0 ? tag.metrics : [{ name: "" }]
+
+ const methods = useForm({
defaultValues: {
id: `${tag ? tag.id : ""}`,
name: `${tag ? tag.name : ""}`,
- metrics4tag: tag?.metrics.length > 0 ? tag.metrics : [""],
+ metrics4tag: default_metrics4tag,
+ view_metrics4tag: default_metrics4tag,
searchItem: ""
},
mode: "all",
resolver: yupResolver(validationSchema)
})
+ const { control } = methods
+
const searchItem = useWatch({ control, name: "searchItem" })
const metrics4tag = useWatch({ control, name: "metrics4tag" })
+ const view_metrics4tag = useWatch({ control, name: "view_metrics4tag" })
+
+ useEffect(() => {
+ if (view_metrics4tag.length === 0) {
+ methods.setValue("view_metrics4tag", [{ name: "" }])
+ }
+ }, [view_metrics4tag])
+
+ useEffect(() => {
+ if (metrics4tag.length === 0) {
+ methods.setValue("metrics4tag", [{ name: "" }])
+ }
+ }, [metrics4tag])
+
+ useEffect(() => {
+ methods.setValue("view_metrics4tag", metrics4tag.filter(e => e.name.toLowerCase().includes(searchItem.toLowerCase())))
+ }, [searchItem])
const toggleAreYouSure = () => {
setAreYouSureModal(!areYouSureModal)
@@ -171,11 +324,11 @@ const MetricTagsForm = ({
}
const doChange = () => {
- let formValues = getValues()
+ let formValues = methods.getValues()
const sendValues = new Object({
name: formValues.name,
- metrics: formValues.metrics4tag.filter(met => met !== "")
+ metrics: formValues.metrics4tag.map(met => met.name).filter(met => met !== "")
})
if (addview)
@@ -279,178 +432,79 @@ const MetricTagsForm = ({
}}
toggle={toggleAreYouSure}
>
-
+
+
+ { message }
+
+ }
+ />
+
+
+
+
+
+
+
+
+
+
+ {
+ !publicView &&
+
+ {
+ !addview ?
+
+ :
+
+ }
+
+
+ }
+
+
)
}
diff --git a/poem/Poem/frontend/react/Metrics.js b/poem/Poem/frontend/react/Metrics.js
index 6ace548c4..7be3234f1 100644
--- a/poem/Poem/frontend/react/Metrics.js
+++ b/poem/Poem/frontend/react/Metrics.js
@@ -860,6 +860,7 @@ export const MetricForm =
defaultValues: {
id: initValues.id ? initValues.id : "",
name: initValues.name,
+ profiles: initValues.profiles,
probeversion: initValues.probeversion,
type: initValues.type,
group: initValues.group ? initValues.group: "",
@@ -968,6 +969,25 @@ export const MetricForm =
toggleAreYouSure()
}
+ function onDeleteHandle() {
+ let profiles = getValues("profiles")
+ let name = getValues("name")
+ let msg = ""
+
+ if (resourcename === "metric" && !isHistory && profiles.length > 0) {
+ msg =
+
Metric { name } is part of profile(s): { profiles.join(", ") }
+
ARE YOU SURE you want to delete it?
+
+ } else
+ msg = `Are you sure you want to delete ${resourcename_beautify}?`
+
+ setModalMsg(msg)
+ setModalTitle(`Delete ${resourcename_beautify}`)
+ setModalFlag('delete')
+ toggleAreYouSure()
+ }
+
return (
{
- setModalMsg(`Are you sure you want to delete ${resourcename_beautify}?`)
- setModalTitle(`Delete ${resourcename_beautify}`)
- setModalFlag('delete')
- toggleAreYouSure()
- }}
+ onClick={() => onDeleteHandle()}
>
Delete
@@ -1707,7 +1722,8 @@ export const MetricChange = (props) => {
file_attributes: metric.files,
file_parameters: metric.fileparameter,
probe: probe,
- tags: metric.tags
+ tags: metric.tags,
+ profiles: metric.profiles
}}
isTenantSchema={ true }
groups={ groups }
diff --git a/poem/Poem/frontend/react/__tests__/MetricTags.test.js b/poem/Poem/frontend/react/__tests__/MetricTags.test.js
index 10951d4cd..74d99af23 100644
--- a/poem/Poem/frontend/react/__tests__/MetricTags.test.js
+++ b/poem/Poem/frontend/react/__tests__/MetricTags.test.js
@@ -45,22 +45,27 @@ const mockListTags = [
{
id: "3",
name: "internal",
- metrics: ["argo.AMSPublisher-Check"]
+ metrics: [
+ { "name": "argo.AMSPublisher-Check" }
+ ]
},
{
id: "4",
name: "harmonized",
metrics: [
- "generic.certificate.validity",
- "generic.http.connect",
- "generic.tcp.connect",
+ { "name": "generic.certificate.validity" },
+ { "name": "generic.http.connect" },
+ { "name": "generic.tcp.connect" }
]
},
{
id: "2",
name: "messaging",
- metrics: ["argo.AMS-Check", "argo.AMSPublisher-Check"]
- },
+ metrics: [
+ { "name": "argo.AMS-Check" },
+ { "name": "argo.AMSPublisher-Check" }
+ ]
+ }
]
const mockActiveSession = {
@@ -561,6 +566,49 @@ describe("Test metric tags changeview", () => {
)
})
+ test("Test change metric tags name in filtered view", async () => {
+ mockChangeObject.mockReturnValueOnce(
+ Promise.resolve({ ok: true, status: 201, statusText: "CREATED" })
+ )
+
+ renderChangeView()
+
+ await waitFor(() => {
+ expect(screen.getByRole("button", { name: /save/i })).toBeInTheDocument()
+ })
+
+ fireEvent.change(screen.getByPlaceholderText(/search/i), { target: { value: "connect" } })
+
+ fireEvent.change(screen.getByTestId("name"), { target: { value: "test_tag" } })
+
+ await waitFor(() => {
+ expect(screen.getByTestId("form")).toHaveFormValues({name: "test_tag"})
+ })
+
+ fireEvent.click(screen.getByRole('button', { name: /save/i }));
+ await waitFor(() => {
+ expect(screen.getByRole('dialog', { title: /change/i })).toBeInTheDocument();
+ })
+ fireEvent.click(screen.getByRole('button', { name: /yes/i }));
+
+ await waitFor(() => {
+ expect(mockChangeObject).toHaveBeenCalledWith(
+ "/api/v2/internal/metrictags/",
+ { id: "4", name: "test_tag", metrics: ["generic.certificate.validity", "generic.http.connect", "generic.tcp.connect"] }
+ )
+ })
+
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictemplate")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictemplate")
+ expect(NotificationManager.success).toHaveBeenCalledWith(
+ "Metric tag successfully changed", "Changed", 2000
+ )
+ })
+
test("Test error changing metric tag with error message", async () => {
mockChangeObject.mockImplementationOnce(() => {
throw Error("400 BAD REQUEST: Metric tag with this name already exists.")
@@ -654,10 +702,160 @@ describe("Test metric tags changeview", () => {
expect(screen.getByRole("button", { name: /save/i })).toBeInTheDocument()
})
- await selectEvent.select(screen.getByText("generic.certificate.validity"), "argo.AMS-Check")
+ await waitFor(() => {
+ selectEvent.select(screen.getByText("generic.certificate.validity"), "argo.AMS-Check")
+ })
+
+ fireEvent.click(screen.getByRole('button', { name: /save/i }));
+ await waitFor(() => {
+ expect(screen.getByRole('dialog', { title: /change/i })).toBeInTheDocument();
+ })
+ fireEvent.click(screen.getByRole('button', { name: /yes/i }));
+
+ await waitFor(() => {
+ expect(mockChangeObject).toHaveBeenCalledWith(
+ "/api/v2/internal/metrictags/",
+ { id: "4", name: "harmonized", metrics: ["argo.AMS-Check", "generic.http.connect", "generic.tcp.connect"] }
+ )
+ })
+
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictemplate")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictemplate")
+ expect(NotificationManager.success).toHaveBeenCalledWith(
+ "Metric tag successfully changed", "Changed", 2000
+ )
+ })
+
+ test("Test change metrics for metric tag in filtered view", async () => {
+ mockChangeObject.mockReturnValueOnce(
+ Promise.resolve({ ok: true, status: 201, statusText: "CREATED" })
+ )
+
+ renderChangeView()
+
+ await waitFor(() => {
+ expect(screen.getByRole("button", { name: /save/i })).toBeInTheDocument()
+ })
+
+ fireEvent.change(screen.getByPlaceholderText(/search/i), { target: { value: "connect" } })
+
+ await selectEvent.select(screen.getByText("generic.http.connect"), "argo.AMS-Check")
+
+ fireEvent.click(screen.getByRole('button', { name: /save/i }));
+ await waitFor(() => {
+ expect(screen.getByRole('dialog', { title: /change/i })).toBeInTheDocument();
+ })
+ fireEvent.click(screen.getByRole('button', { name: /yes/i }));
+
+ await waitFor(() => {
+ expect(mockChangeObject).toHaveBeenCalledWith(
+ "/api/v2/internal/metrictags/",
+ { id: "4", name: "harmonized", metrics: ["generic.certificate.validity", "argo.AMS-Check", "generic.tcp.connect"] }
+ )
+ })
+
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictemplate")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictemplate")
+ expect(NotificationManager.success).toHaveBeenCalledWith(
+ "Metric tag successfully changed", "Changed", 2000
+ )
+ })
+
+ test("Test delete metrics from metric tag", async () => {
+ mockChangeObject.mockReturnValueOnce(
+ Promise.resolve({ ok: true, status: 201, statusText: "CREATED" })
+ )
+
+ renderChangeView()
+
+ await waitFor(() => {
+ expect(screen.getByRole("button", { name: /save/i })).toBeInTheDocument()
+ })
fireEvent.click(screen.getByTestId("remove-1"))
+ fireEvent.click(screen.getByRole('button', { name: /save/i }));
+ await waitFor(() => {
+ expect(screen.getByRole('dialog', { title: /change/i })).toBeInTheDocument();
+ })
+ fireEvent.click(screen.getByRole('button', { name: /yes/i }));
+
+ await waitFor(() => {
+ expect(mockChangeObject).toHaveBeenCalledWith(
+ "/api/v2/internal/metrictags/",
+ { id: "4", name: "harmonized", metrics: ["generic.certificate.validity", "generic.tcp.connect"] }
+ )
+ })
+
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictemplate")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictemplate")
+ expect(NotificationManager.success).toHaveBeenCalledWith(
+ "Metric tag successfully changed", "Changed", 2000
+ )
+ })
+
+ test("Test delete metrics from metric tag if filtered view", async () => {
+ mockChangeObject.mockReturnValueOnce(
+ Promise.resolve({ ok: true, status: 201, statusText: "CREATED" })
+ )
+
+ renderChangeView()
+
+ await waitFor(() => {
+ expect(screen.getByRole("button", { name: /save/i })).toBeInTheDocument()
+ })
+
+ fireEvent.change(screen.getByPlaceholderText(/search/i), { target: { value: "connect" } })
+
+ fireEvent.click(screen.getByTestId("remove-0"))
+
+ fireEvent.click(screen.getByRole('button', { name: /save/i }));
+ await waitFor(() => {
+ expect(screen.getByRole('dialog', { title: /change/i })).toBeInTheDocument();
+ })
+ fireEvent.click(screen.getByRole('button', { name: /yes/i }));
+
+ await waitFor(() => {
+ expect(mockChangeObject).toHaveBeenCalledWith(
+ "/api/v2/internal/metrictags/",
+ { id: "4", name: "harmonized", metrics: ["generic.certificate.validity", "generic.tcp.connect"] }
+ )
+ })
+
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictemplate")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictemplate")
+ expect(NotificationManager.success).toHaveBeenCalledWith(
+ "Metric tag successfully changed", "Changed", 2000
+ )
+ })
+
+ test("Test insert new metrics for metric tag", async () => {
+ mockChangeObject.mockReturnValueOnce(
+ Promise.resolve({ ok: true, status: 201, statusText: "CREATED" })
+ )
+
+ renderChangeView()
+
+ await waitFor(() => {
+ expect(screen.getByRole("button", { name: /save/i })).toBeInTheDocument()
+ })
+
fireEvent.click(screen.getByTestId("insert-0"))
const table = within(screen.getByRole("table"))
@@ -675,7 +873,54 @@ describe("Test metric tags changeview", () => {
await waitFor(() => {
expect(mockChangeObject).toHaveBeenCalledWith(
"/api/v2/internal/metrictags/",
- { id: "4", name: "harmonized", metrics: ["argo.AMS-Check", "argo.AMSPublisher-Check", "generic.tcp.connect"] }
+ { id: "4", name: "harmonized", metrics: ["generic.certificate.validity", "argo.AMSPublisher-Check", "generic.http.connect", "generic.tcp.connect"] }
+ )
+ })
+
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("metrictemplate")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictags")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metric")
+ expect(queryClient.invalidateQueries).toHaveBeenCalledWith("public_metrictemplate")
+ expect(NotificationManager.success).toHaveBeenCalledWith(
+ "Metric tag successfully changed", "Changed", 2000
+ )
+ })
+
+ test("Test insert new metrics for metric tag in filtered view", async () => {
+ mockChangeObject.mockReturnValueOnce(
+ Promise.resolve({ ok: true, status: 201, statusText: "CREATED" })
+ )
+
+ renderChangeView()
+
+ await waitFor(() => {
+ expect(screen.getByRole("button", { name: /save/i })).toBeInTheDocument()
+ })
+
+ fireEvent.change(screen.getByPlaceholderText(/search/i), { target: { value: "connect" } })
+
+ fireEvent.click(screen.getByTestId("insert-0"))
+
+ const table = within(screen.getByRole("table"))
+
+ const row2 = table.getAllByRole("row")[3]
+
+ await waitFor(() => {
+ selectEvent.select(within(row2).getByRole("combobox"), "argo.AMSPublisher-Check")
+ })
+
+ fireEvent.click(screen.getByRole('button', { name: /save/i }));
+ await waitFor(() => {
+ expect(screen.getByRole('dialog', { title: /change/i })).toBeInTheDocument();
+ })
+ fireEvent.click(screen.getByRole('button', { name: /yes/i }));
+
+ await waitFor(() => {
+ expect(mockChangeObject).toHaveBeenCalledWith(
+ "/api/v2/internal/metrictags/",
+ { id: "4", name: "harmonized", metrics: ["generic.certificate.validity", "generic.http.connect", "argo.AMSPublisher-Check", "generic.tcp.connect"] }
)
})
@@ -716,7 +961,9 @@ describe("Test metric tags changeview", () => {
const row2 = table.getAllByRole("row")[3]
- await selectEvent.select(within(row2).getByRole("combobox"), "argo.AMSPublisher-Check")
+ await waitFor(() => {
+ selectEvent.select(within(row2).getByRole("combobox"), "argo.AMSPublisher-Check")
+ })
fireEvent.click(screen.getByRole('button', { name: /save/i }));
await waitFor(() => {
@@ -777,7 +1024,9 @@ describe("Test metric tags changeview", () => {
const row2 = table.getAllByRole("row")[3]
- await selectEvent.select(within(row2).getByRole("combobox"), "argo.AMSPublisher-Check")
+ await waitFor(() => {
+ selectEvent.select(within(row2).getByRole("combobox"), "argo.AMSPublisher-Check")
+ })
fireEvent.click(screen.getByRole('button', { name: /save/i }));
await waitFor(() => {
@@ -1018,6 +1267,11 @@ describe("Test metric tags addview", () => {
expect(table.queryByText(/generic/i)).not.toBeInTheDocument()
expect(table.queryByText(/argo/i)).not.toBeInTheDocument()
+ expect(table.queryByText("generic.certificate.validity")).not.toBeInTheDocument()
+ expect(table.queryByText("generic.http.connect")).not.toBeInTheDocument()
+ expect(table.queryByText("generic.tcp.connect")).not.toBeInTheDocument()
+ expect(table.queryByText("argo.AMS-Check")).not.toBeInTheDocument()
+ expect(table.queryByText("argo.AMSPublisher-Check")).not.toBeInTheDocument()
selectEvent.openMenu(input)
expect(table.getByText("generic.certificate.validity")).toBeInTheDocument()
expect(table.getByText("generic.http.connect")).toBeInTheDocument()
@@ -1094,24 +1348,46 @@ describe("Test metric tags addview", () => {
const row1 = table.getAllByRole("row")[2]
const input1 = within(row1).getByRole("combobox")
- await selectEvent.select(input1, "generic.certificate.validity")
+ await waitFor(() => {
+ selectEvent.select(input1, "generic.certificate.validity")
+ })
+
+ await waitFor(() => {
+ expect(table.queryByText("generic.http.connect")).not.toBeInTheDocument()
+ })
fireEvent.click(table.getByTestId("insert-0"))
const row2 = table.getAllByRole("row")[3]
const input2 = within(row2).getByRole("combobox")
- await selectEvent.select(input2, "generic.http.connect")
+ await waitFor(() => {
+ selectEvent.select(input2, "generic.http.connect")
+ })
+
+ await waitFor(() => {
+ expect(table.queryByText("generic.tcp.connect")).not.toBeInTheDocument()
+ })
fireEvent.click(table.getByTestId("insert-1"))
const row3 = table.getAllByRole("row")[4]
const input3 = within(row3).getByRole("combobox")
- await selectEvent.select(input3, "generic.tcp.connect")
+ await waitFor(() => {
+ selectEvent.select(input3, "generic.tcp.connect")
+ })
+
+ await waitFor(() => {
+ expect(table.getByText("generic.tcp.connect")).toBeInTheDocument()
+ })
fireEvent.click(table.getByTestId("remove-1"))
+ await waitFor(() => {
+ expect(table.queryByText("generic.http.connect")).not.toBeInTheDocument()
+ })
+
await selectEvent.select(table.getByText("generic.tcp.connect"), "argo.AMS-Check")
fireEvent.click(screen.getByRole('button', { name: /save/i }));
@@ -1161,13 +1437,25 @@ describe("Test metric tags addview", () => {
const row1 = table.getAllByRole("row")[2]
const input1 = within(row1).getByRole("combobox")
- await selectEvent.select(input1, "generic.tcp.connect")
+ await waitFor(() => {
+ selectEvent.select(input1, "generic.tcp.connect")
+ })
+
+ await waitFor(() => {
+ expect(table.getByText("generic.tcp.connect")).toBeInTheDocument()
+ })
fireEvent.click(table.getByTestId("insert-0"))
const row2 = table.getAllByRole("row")[3]
- await selectEvent.select(within(row2).getByRole("combobox"), "generic.http.connect")
+ await waitFor(() => {
+ selectEvent.select(within(row2).getByRole("combobox"), "generic.http.connect")
+ })
+
+ await waitFor(() => {
+ expect(table.getByText("generic.http.connect")).toBeInTheDocument()
+ })
fireEvent.click(screen.getByRole('button', { name: /save/i }));
await waitFor(() => {
@@ -1225,13 +1513,25 @@ describe("Test metric tags addview", () => {
const row1 = table.getAllByRole("row")[2]
const input1 = within(row1).getByRole("combobox")
- await selectEvent.select(input1, "generic.tcp.connect")
+ await waitFor(() => {
+ selectEvent.select(input1, "generic.tcp.connect")
+ })
+
+ await waitFor(() => {
+ expect(table.getByText("generic.tcp.connect")).toBeInTheDocument()
+ })
fireEvent.click(table.getByTestId("insert-0"))
const row2 = table.getAllByRole("row")[3]
- await selectEvent.select(within(row2).getByRole("combobox"), "generic.http.connect")
+ await waitFor(() => {
+ selectEvent.select(within(row2).getByRole("combobox"), "generic.http.connect")
+ })
+
+ await waitFor(() => {
+ expect(table.getByText("generic.http.connect")).toBeInTheDocument()
+ })
fireEvent.click(screen.getByRole('button', { name: /save/i }));
await waitFor(() => {
diff --git a/poem/Poem/frontend/react/__tests__/Metrics.test.js b/poem/Poem/frontend/react/__tests__/Metrics.test.js
index 65f91871c..08768e7f1 100644
--- a/poem/Poem/frontend/react/__tests__/Metrics.test.js
+++ b/poem/Poem/frontend/react/__tests__/Metrics.test.js
@@ -15,6 +15,7 @@ const mockListOfMetrics = [
name: 'argo.AMS-Check',
mtype: 'Active',
tags: ['test_tag1', 'test_tag2'],
+ profiles: ["ARGO_MON", "TEST_PROFILE"],
probeversion: 'ams-probe (0.1.12)',
group: 'EGI',
description: 'Description of argo.AMS-Check metric',
@@ -44,6 +45,7 @@ const mockListOfMetrics = [
name: 'argo.AMS-Publisher',
mtype: 'Active',
tags: ['internal'],
+ profiles: ["ARGO_MON_INTERNAL"],
probeversion: 'ams-publisher-probe (0.1.12)',
group: 'EGI',
description: '',
@@ -74,6 +76,7 @@ const mockListOfMetrics = [
name: 'org.apel.APEL-Pub',
mtype: 'Passive',
tags: [],
+ profiles: [],
probeversion: '',
group: 'ARGOTEST',
description: '',
@@ -97,6 +100,7 @@ const mockMetric = {
name: 'argo.AMS-Check',
mtype: 'Active',
tags: ['test_tag1', 'test_tag2'],
+ profiles: ["ARGO_MON", "TEST_PROFILE"],
probeversion: 'ams-probe (0.1.12)',
group: 'EGI',
description: 'Description of argo.AMS-Check metric',
@@ -127,6 +131,7 @@ const mockPassiveMetric = {
name: 'org.apel.APEL-Pub',
mtype: 'Passive',
tags: [],
+ profiles: [],
probeversion: '',
group: 'ARGOTEST',
description: '',