Feature Toggles API: Trigger webhook call when updating (#75254)

* Feature Toggles API: Trigger webhook call when updating

* update status code error check

* lint - handle Close() error

* Rename update webhook config

* fix tests
This commit is contained in:
João Calisto
2023-09-25 19:11:24 +01:00
committed by GitHub
parent 436b0ee48a
commit 7e1b45ba31
6 changed files with 121 additions and 35 deletions

View File

@ -6,6 +6,7 @@ import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"testing"
"github.com/grafana/grafana/pkg/infra/log"
@ -83,10 +84,10 @@ func TestGetFeatureToggles(t *testing.T) {
},
}
settings := setting.FeatureMgmtSettings{
HiddenToggles: map[string]struct{}{"toggle1": {}},
ReadOnlyToggles: map[string]struct{}{"toggle2": {}},
AllowEditing: true,
UpdateControllerUrl: "bogus",
HiddenToggles: map[string]struct{}{"toggle1": {}},
ReadOnlyToggles: map[string]struct{}{"toggle2": {}},
AllowEditing: true,
UpdateWebhook: "bogus",
}
result := runGetScenario(t, features, settings, readPermissions, http.StatusOK)
@ -132,8 +133,8 @@ func TestGetFeatureToggles(t *testing.T) {
t.Run("only public preview and GA are writeable by default", func(t *testing.T) {
settings := setting.FeatureMgmtSettings{
AllowEditing: true,
UpdateControllerUrl: "bogus",
AllowEditing: true,
UpdateWebhook: "bogus",
}
result := runGetScenario(t, features, settings, readPermissions, http.StatusOK)
assert.Len(t, result, 3)
@ -151,8 +152,8 @@ func TestGetFeatureToggles(t *testing.T) {
t.Run("all toggles are read-only when server is misconfigured", func(t *testing.T) {
settings := setting.FeatureMgmtSettings{
AllowEditing: false,
UpdateControllerUrl: "",
AllowEditing: false,
UpdateWebhook: "",
}
result := runGetScenario(t, features, settings, readPermissions, http.StatusOK)
assert.Len(t, result, 3)
@ -216,8 +217,8 @@ func TestSetFeatureToggles(t *testing.T) {
}
s := setting.FeatureMgmtSettings{
AllowEditing: true,
UpdateControllerUrl: "random",
AllowEditing: true,
UpdateWebhook: "random",
}
res := runSetScenario(t, features, updates, s, writePermissions, http.StatusBadRequest)
defer func() { require.NoError(t, res.Body.Close()) }()
@ -243,8 +244,8 @@ func TestSetFeatureToggles(t *testing.T) {
}
s := setting.FeatureMgmtSettings{
AllowEditing: true,
UpdateControllerUrl: "random",
AllowEditing: true,
UpdateWebhook: "random",
ReadOnlyToggles: map[string]struct{}{
"toggle3": {},
},
@ -290,7 +291,7 @@ func TestSetFeatureToggles(t *testing.T) {
})
})
t.Run("succeeds with all conditions met", func(t *testing.T) {
t.Run("when all conditions met", func(t *testing.T) {
features := []*featuremgmt.FeatureFlag{
{
Name: featuremgmt.FlagFeatureToggleAdminPage,
@ -316,8 +317,9 @@ func TestSetFeatureToggles(t *testing.T) {
}
s := setting.FeatureMgmtSettings{
AllowEditing: true,
UpdateControllerUrl: "random",
AllowEditing: true,
UpdateWebhook: "random",
UpdateWebhookToken: "token",
ReadOnlyToggles: map[string]struct{}{
"toggle3": {},
},
@ -332,11 +334,34 @@ func TestSetFeatureToggles(t *testing.T) {
Enabled: false,
},
}
// TODO: check for success status after the handler is fully implemented
res := runSetScenario(t, features, updates, s, writePermissions, http.StatusNotImplemented)
defer func() { require.NoError(t, res.Body.Close()) }()
p := readBody(t, res.Body)
assert.Equal(t, "UpdateFeatureToggle is unimplemented", p["message"])
t.Run("fail when webhook request is not successful", func(t *testing.T) {
webhookServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
}))
defer webhookServer.Close()
s.UpdateWebhook = webhookServer.URL
res := runSetScenario(t, features, updates, s, writePermissions, http.StatusBadRequest)
defer func() { require.NoError(t, res.Body.Close()) }()
assert.Equal(t, http.StatusBadRequest, res.StatusCode)
})
t.Run("succeed when webhook request is successul", func(t *testing.T) {
webhookServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "Bearer "+s.UpdateWebhookToken, r.Header.Get("Authorization"))
var req UpdatePayload
require.NoError(t, json.NewDecoder(r.Body).Decode(&req))
assert.Equal(t, "true", req.FeatureToggles["toggle4"])
assert.Equal(t, "false", req.FeatureToggles["toggle5"])
w.WriteHeader(http.StatusOK)
}))
defer webhookServer.Close()
s.UpdateWebhook = webhookServer.URL
res := runSetScenario(t, features, updates, s, writePermissions, http.StatusOK)
defer func() { require.NoError(t, res.Body.Close()) }()
assert.Equal(t, http.StatusOK, res.StatusCode)
})
})
}