Allow webhook modification by API for advanced webhook (#4175)
# What this PR does Enables the API to perform updates on the advanced webhooks created via the UI ## Which issue(s) this PR closes Closes #3958 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes.
This commit is contained in:
parent
cb613deedb
commit
6f3f4e3f14
6 changed files with 50 additions and 5 deletions
|
|
@ -5,6 +5,7 @@ from rest_framework.validators import UniqueTogetherValidator
|
|||
|
||||
from apps.webhooks.models import Webhook, WebhookResponse
|
||||
from apps.webhooks.models.webhook import PUBLIC_WEBHOOK_HTTP_METHODS, WEBHOOK_FIELD_PLACEHOLDER
|
||||
from apps.webhooks.presets.preset_options import WebhookPresetOptions
|
||||
from common.api_helpers.custom_fields import IntegrationFilteredByOrganizationField, TeamPrimaryKeyRelatedField
|
||||
from common.api_helpers.exceptions import BadRequest
|
||||
from common.api_helpers.utils import CurrentOrganizationDefault, CurrentTeamDefault, CurrentUserDefault
|
||||
|
|
@ -158,7 +159,13 @@ class WebhookCreateSerializer(serializers.ModelSerializer):
|
|||
raise serializers.ValidationError(PRESET_VALIDATION_MESSAGE)
|
||||
|
||||
def validate(self, data):
|
||||
if self.instance and self.instance.preset:
|
||||
if (
|
||||
self.instance
|
||||
and self.instance.preset
|
||||
and WebhookPresetOptions.ADVANCED_PRESET_META_DATA
|
||||
and WebhookPresetOptions.ADVANCED_PRESET_META_DATA.id
|
||||
and self.instance.preset != WebhookPresetOptions.ADVANCED_PRESET_META_DATA.id
|
||||
):
|
||||
raise serializers.ValidationError(PRESET_VALIDATION_MESSAGE)
|
||||
return data
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from rest_framework.test import APIClient
|
|||
|
||||
from apps.public_api.serializers.webhooks import PRESET_VALIDATION_MESSAGE
|
||||
from apps.webhooks.models import Webhook
|
||||
from apps.webhooks.tests.test_webhook_presets import TEST_WEBHOOK_PRESET_ID
|
||||
from apps.webhooks.tests.test_webhook_presets import ADVANCED_WEBHOOK_PRESET_ID, TEST_WEBHOOK_PRESET_ID
|
||||
|
||||
|
||||
def _get_expected_result(webhook):
|
||||
|
|
@ -437,3 +437,23 @@ def test_webhook_block_preset_update(
|
|||
response = client.put(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
assert response.json()["non_field_errors"][0] == PRESET_VALIDATION_MESSAGE
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_webhook_advanced_preset_update(
|
||||
make_organization_and_user_with_token,
|
||||
make_custom_webhook,
|
||||
webhook_preset_api_setup,
|
||||
):
|
||||
organization, user, token = make_organization_and_user_with_token()
|
||||
client = APIClient()
|
||||
webhook = make_custom_webhook(organization=organization, preset=ADVANCED_WEBHOOK_PRESET_ID)
|
||||
webhook.refresh_from_db()
|
||||
|
||||
url = reverse("api-public:webhooks-detail", kwargs={"pk": webhook.public_primary_key})
|
||||
data = {
|
||||
"name": "Test rename preset webhook",
|
||||
}
|
||||
response = client.put(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["name"] == data["name"]
|
||||
|
|
|
|||
|
|
@ -9,11 +9,14 @@ from apps.webhooks.models import Webhook
|
|||
|
||||
class WebhookPresetOptions:
|
||||
WEBHOOK_PRESETS = {}
|
||||
ADVANCED_PRESET_META_DATA = {}
|
||||
for webhook_preset_config in settings.INSTALLED_WEBHOOK_PRESETS:
|
||||
module_path, class_name = webhook_preset_config.rsplit(".", 1)
|
||||
module = import_module(module_path)
|
||||
preset = getattr(module, class_name)()
|
||||
WEBHOOK_PRESETS[preset.metadata.id] = preset
|
||||
if webhook_preset_config == settings.ADVANCED_WEBHOOK_PRESET:
|
||||
ADVANCED_PRESET_META_DATA = preset.metadata
|
||||
|
||||
WEBHOOK_PRESET_CHOICES = [webhook_preset.metadata for webhook_preset in WEBHOOK_PRESETS.values()]
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import pytest
|
|||
|
||||
from apps.webhooks.models import Webhook
|
||||
from apps.webhooks.models.webhook import WEBHOOK_FIELD_PLACEHOLDER
|
||||
from apps.webhooks.presets.advanced import AdvancedWebhookPreset
|
||||
from apps.webhooks.presets.preset import WebhookPreset, WebhookPresetMetadata
|
||||
from apps.webhooks.tasks.trigger_webhook import make_request
|
||||
from apps.webhooks.tests.test_trigger_webhook import MockResponse
|
||||
|
|
@ -20,6 +21,7 @@ TEST_WEBHOOK_AUTHORIZATION_HEADER = "Test Auth header 12345"
|
|||
TEST_WEBHOOK_MASK_HEADER = "X-Secret-Header"
|
||||
TEST_WEBHOOK_MASK_HEADER_VALUE = "abc123"
|
||||
INVALID_PRESET_ID = "invalid_preset_id"
|
||||
ADVANCED_WEBHOOK_PRESET_ID = "advanced_webhook"
|
||||
|
||||
|
||||
class TestWebhookPreset(WebhookPreset):
|
||||
|
|
@ -47,6 +49,10 @@ class TestWebhookPreset(WebhookPreset):
|
|||
return [TEST_WEBHOOK_MASK_HEADER]
|
||||
|
||||
|
||||
class TestAdvancedWebhookPreset(AdvancedWebhookPreset):
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_webhook_from_preset(make_organization, webhook_preset_api_setup, make_custom_webhook):
|
||||
organization = make_organization()
|
||||
|
|
|
|||
|
|
@ -103,7 +103,12 @@ from apps.user_management.models.user import User, listen_for_user_model_save
|
|||
from apps.user_management.tests.factories import OrganizationFactory, RegionFactory, TeamFactory, UserFactory
|
||||
from apps.webhooks.presets.preset_options import WebhookPresetOptions
|
||||
from apps.webhooks.tests.factories import CustomWebhookFactory, WebhookResponseFactory
|
||||
from apps.webhooks.tests.test_webhook_presets import TEST_WEBHOOK_PRESET_ID, TestWebhookPreset
|
||||
from apps.webhooks.tests.test_webhook_presets import (
|
||||
ADVANCED_WEBHOOK_PRESET_ID,
|
||||
TEST_WEBHOOK_PRESET_ID,
|
||||
TestAdvancedWebhookPreset,
|
||||
TestWebhookPreset,
|
||||
)
|
||||
|
||||
register(OrganizationFactory)
|
||||
register(UserFactory)
|
||||
|
|
@ -987,7 +992,10 @@ def shift_swap_request_setup(
|
|||
|
||||
@pytest.fixture()
|
||||
def webhook_preset_api_setup():
|
||||
WebhookPresetOptions.WEBHOOK_PRESETS = {TEST_WEBHOOK_PRESET_ID: TestWebhookPreset()}
|
||||
WebhookPresetOptions.WEBHOOK_PRESETS = {
|
||||
TEST_WEBHOOK_PRESET_ID: TestWebhookPreset(),
|
||||
ADVANCED_WEBHOOK_PRESET_ID: TestAdvancedWebhookPreset(),
|
||||
}
|
||||
WebhookPresetOptions.WEBHOOK_PRESET_CHOICES = [
|
||||
preset.metadata for preset in WebhookPresetOptions.WEBHOOK_PRESETS.values()
|
||||
]
|
||||
|
|
|
|||
|
|
@ -837,9 +837,10 @@ INSTALLED_ONCALL_INTEGRATIONS = [
|
|||
"config_integrations.direct_paging",
|
||||
]
|
||||
|
||||
ADVANCED_WEBHOOK_PRESET = "apps.webhooks.presets.advanced.AdvancedWebhookPreset"
|
||||
INSTALLED_WEBHOOK_PRESETS = [
|
||||
"apps.webhooks.presets.simple.SimpleWebhookPreset",
|
||||
"apps.webhooks.presets.advanced.AdvancedWebhookPreset",
|
||||
ADVANCED_WEBHOOK_PRESET,
|
||||
]
|
||||
|
||||
if IS_OPEN_SOURCE:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue