# What this PR does **Cleanup label typing:** 1. LabelParam -> two separate types LabekKey and LabelValue 2. LabelData -> renamed to LabelPair. 3. LabelKeyData -> renamed to LabelOption Data is not giving any info about what this type represents. 4. Remove LabelsData and LabelsKeysData types. They are just list of types listed above and with new naming it feels obsolete. 5. ValueData removed. LabelPair is used instead. 6. Rework AlertGroupCustomLabel to use LabelKey type for key to make type system more consistent. Name model type AlertGroupCustomLabel**DB** and api type AlertGroupCustomLabel**API** to clearly distinguish them. **Split update_labels_cache into two tasks** update_label_option_cache and update_label_pairs_cache. Original task was expecting array of LabelsData (now it's LabelPair) OR one LabelKeyData ( now it's LabelOption). I believe having one function with two sp different argument types makes it more complicated for understanding. **Make OnCall backend support prescribed labels**. OnCall will sync and store "prescribed" field for key and values, so Label dropdown able to disable editing for certain labels. ## Which issue(s) this PR fixes ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --------- Co-authored-by: Maxim Mordasov <maxim.mordasov@grafana.com> Co-authored-by: Yulya Artyukhina <Ferril.darkdiver@gmail.com>
141 lines
5.9 KiB
Python
141 lines
5.9 KiB
Python
import pytest
|
|
|
|
from apps.alerts.models import AlertReceiveChannel
|
|
from apps.labels.models import (
|
|
AlertReceiveChannelAssociatedLabel,
|
|
AssociatedLabel,
|
|
LabelValueCache,
|
|
WebhookAssociatedLabel,
|
|
)
|
|
from apps.labels.utils import get_associating_label_model, is_labels_feature_enabled
|
|
from apps.webhooks.models import Webhook
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_labels_feature_flag(mock_is_labels_feature_enabled_for_org, make_organization, settings):
|
|
organization = make_organization()
|
|
# returns True if feature flag is enabled
|
|
assert settings.FEATURE_LABELS_ENABLED_FOR_ALL
|
|
assert organization.id not in settings.FEATURE_LABELS_ENABLED_PER_ORG
|
|
assert is_labels_feature_enabled(organization)
|
|
|
|
mock_is_labels_feature_enabled_for_org(organization.id)
|
|
# returns True if feature flag is disabled and organization is in the feature list
|
|
assert not settings.FEATURE_LABELS_ENABLED_FOR_ALL
|
|
assert organization.id in settings.FEATURE_LABELS_ENABLED_PER_ORG
|
|
assert is_labels_feature_enabled(organization)
|
|
|
|
mock_is_labels_feature_enabled_for_org(12345)
|
|
# returns False if feature flag is disabled and organization is not in the feature list
|
|
assert organization.org_id not in settings.FEATURE_LABELS_ENABLED_PER_ORG
|
|
|
|
assert not is_labels_feature_enabled(organization)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_labels_feature_flag_when_plugin_is_disabled(
|
|
mock_is_labels_feature_enabled_for_org, make_organization, settings
|
|
):
|
|
organization = make_organization()
|
|
organization.is_grafana_labels_enabled = False
|
|
# returns False if feature flag is enabled, but plugin is disabled
|
|
assert settings.FEATURE_LABELS_ENABLED_FOR_ALL
|
|
assert organization.id not in settings.FEATURE_LABELS_ENABLED_PER_ORG
|
|
assert is_labels_feature_enabled(organization) is False
|
|
|
|
mock_is_labels_feature_enabled_for_org(organization.id)
|
|
# returns False if feature flag is disabled, organization is in the feature list, , but plugin is disabled
|
|
assert not settings.FEATURE_LABELS_ENABLED_FOR_ALL
|
|
assert organization.id in settings.FEATURE_LABELS_ENABLED_PER_ORG
|
|
assert is_labels_feature_enabled(organization) is False
|
|
|
|
assert not is_labels_feature_enabled(organization)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_label_associate_new_label(make_organization, make_alert_receive_channel):
|
|
organization = make_organization()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
label_key_id = "testkeyid"
|
|
label_value_id = "testvalueid"
|
|
labels_data = [
|
|
{
|
|
"key": {"id": label_key_id, "name": "testkey", "prescribed": False},
|
|
"value": {"id": label_value_id, "name": "testvalue", "prescribed": False},
|
|
}
|
|
]
|
|
|
|
assert not alert_receive_channel.labels.exists()
|
|
assert not LabelValueCache.objects.filter(key_id=label_key_id, id=label_value_id).exists()
|
|
|
|
AssociatedLabel.update_association(labels_data, alert_receive_channel, organization)
|
|
assert len(alert_receive_channel.labels.all()) == 1
|
|
assert alert_receive_channel.labels.get(key_id=label_key_id, value_id=label_value_id)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_label_associate_existing_label(make_label_key_and_value, make_organization, make_alert_receive_channel):
|
|
organization = make_organization()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
label_key, label_value = make_label_key_and_value(organization)
|
|
labels_data = [
|
|
{
|
|
"key": {"id": label_key.id, "name": label_key.name, "prescribed": False},
|
|
"value": {"id": label_value.id, "name": label_value.name, "prescribed": False},
|
|
}
|
|
]
|
|
assert not alert_receive_channel.labels.exists()
|
|
AssociatedLabel.update_association(labels_data, alert_receive_channel, organization)
|
|
assert len(alert_receive_channel.labels.all()) == 1
|
|
assert alert_receive_channel.labels.filter(key=label_key, value=label_value).exists()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_label_update_association_by_removing_label(
|
|
make_integration_label_association, make_organization, make_alert_receive_channel
|
|
):
|
|
organization = make_organization()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
label_association_1 = make_integration_label_association(organization, alert_receive_channel)
|
|
label_association_2 = make_integration_label_association(organization, alert_receive_channel)
|
|
labels_data = [
|
|
{
|
|
"key": {"id": label_association_1.key_id, "name": label_association_1.key.name, "prescribed": False},
|
|
"value": {"id": label_association_1.value_id, "name": label_association_1.value.name, "prescribed": False},
|
|
}
|
|
]
|
|
|
|
assert len(alert_receive_channel.labels.all()) == 2
|
|
assert alert_receive_channel.labels.filter(
|
|
key=label_association_1.key_id, value=label_association_1.value_id
|
|
).exists()
|
|
assert alert_receive_channel.labels.filter(
|
|
key=label_association_2.key_id, value=label_association_2.value_id
|
|
).exists()
|
|
|
|
# update labels association by removing label_association_2
|
|
AssociatedLabel.update_association(labels_data, alert_receive_channel, organization)
|
|
assert len(alert_receive_channel.labels.all()) == 1
|
|
assert alert_receive_channel.labels.filter(
|
|
key=label_association_1.key_id, value=label_association_1.value_id
|
|
).exists()
|
|
assert not alert_receive_channel.labels.filter(
|
|
key=label_association_2.key_id, value=label_association_2.value_id
|
|
).exists()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_get_associating_label_model():
|
|
model_name = AlertReceiveChannel.__name__
|
|
expected_result = AlertReceiveChannelAssociatedLabel
|
|
result = get_associating_label_model(model_name)
|
|
assert result == expected_result
|
|
|
|
model_name = Webhook.__name__
|
|
expected_result = WebhookAssociatedLabel
|
|
result = get_associating_label_model(model_name)
|
|
assert result == expected_result
|
|
|
|
wrong_model_name = "SomeModel"
|
|
with pytest.raises(LookupError):
|
|
get_associating_label_model(wrong_model_name)
|