|
3 | 3 | package action_test |
4 | 4 |
|
5 | 5 | import ( |
| 6 | + "context" |
6 | 7 | "fmt" |
| 8 | + "strings" |
7 | 9 | "testing" |
8 | 10 |
|
9 | 11 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" |
10 | 12 | "github.com/hashicorp/terraform-plugin-testing/terraform" |
| 13 | + ory "github.com/ory/client-go" |
11 | 14 |
|
12 | 15 | "github.com/ory/terraform-provider-ory/internal/acctest" |
13 | 16 | "github.com/ory/terraform-provider-ory/internal/testutil" |
14 | 17 | ) |
15 | 18 |
|
| 19 | +// cleanupDanglingWebhook removes a specific webhook left behind by a previous |
| 20 | +// failed test run. Only the matching webhook is removed; other hooks at the |
| 21 | +// same path are preserved. hookPath must be a full JSON Patch path ending in |
| 22 | +// "/hooks" (e.g. "/services/identity/config/selfservice/flows/registration/after/password/hooks"). |
| 23 | +func cleanupDanglingWebhook(t *testing.T, hookPath, webhookURL string) { |
| 24 | + t.Helper() |
| 25 | + |
| 26 | + c, err := acctest.GetOryClient() |
| 27 | + if err != nil { |
| 28 | + t.Logf("Warning: could not create client for cleanup: %v", err) |
| 29 | + return |
| 30 | + } |
| 31 | + |
| 32 | + project := acctest.GetTestProject(t) |
| 33 | + ctx := context.Background() |
| 34 | + |
| 35 | + p, err := c.GetProject(ctx, project.ID) |
| 36 | + if err != nil { |
| 37 | + t.Logf("Warning: could not get project for cleanup: %v", err) |
| 38 | + return |
| 39 | + } |
| 40 | + |
| 41 | + configMap := p.Services.Identity.Config |
| 42 | + if configMap == nil { |
| 43 | + return |
| 44 | + } |
| 45 | + |
| 46 | + // Derive navigation segments from hookPath. |
| 47 | + // e.g. "/services/identity/config/selfservice/flows/registration/after/password/hooks" |
| 48 | + // → strip prefix "/services/identity/config/" and suffix "/hooks" |
| 49 | + // → segments: ["selfservice", "flows", "registration", "after", "password"] |
| 50 | + trimmed := strings.TrimPrefix(hookPath, "/services/identity/config/") |
| 51 | + trimmed = strings.TrimSuffix(trimmed, "/hooks") |
| 52 | + segments := strings.Split(trimmed, "/") |
| 53 | + |
| 54 | + var current interface{} = configMap |
| 55 | + for _, seg := range segments { |
| 56 | + m, ok := current.(map[string]interface{}) |
| 57 | + if !ok { |
| 58 | + return |
| 59 | + } |
| 60 | + current = m[seg] |
| 61 | + if current == nil { |
| 62 | + return |
| 63 | + } |
| 64 | + } |
| 65 | + |
| 66 | + hooksSlice, ok := current.(map[string]interface{})["hooks"].([]interface{}) |
| 67 | + if !ok || len(hooksSlice) == 0 { |
| 68 | + return |
| 69 | + } |
| 70 | + |
| 71 | + // Build a new hooks list without the dangling test webhook. |
| 72 | + filtered := make([]interface{}, 0, len(hooksSlice)) |
| 73 | + found := false |
| 74 | + for _, h := range hooksSlice { |
| 75 | + hm, _ := h.(map[string]interface{}) |
| 76 | + if hm["hook"] == "web_hook" { |
| 77 | + cfg, _ := hm["config"].(map[string]interface{}) |
| 78 | + if url, _ := cfg["url"].(string); url == webhookURL { |
| 79 | + found = true |
| 80 | + continue // skip the dangling webhook |
| 81 | + } |
| 82 | + } |
| 83 | + filtered = append(filtered, h) |
| 84 | + } |
| 85 | + |
| 86 | + if !found { |
| 87 | + return |
| 88 | + } |
| 89 | + |
| 90 | + t.Logf("Cleaning up dangling webhook at %s: %s", hookPath, webhookURL) |
| 91 | + patches := []ory.JsonPatch{{ |
| 92 | + Op: "replace", |
| 93 | + Path: hookPath, |
| 94 | + Value: filtered, |
| 95 | + }} |
| 96 | + _, err = c.PatchProject(ctx, project.ID, patches) |
| 97 | + if err != nil { |
| 98 | + t.Logf("Warning: failed to clean up dangling webhook: %v", err) |
| 99 | + } |
| 100 | +} |
| 101 | + |
16 | 102 | func TestAccActionResource_basic(t *testing.T) { |
| 103 | + webhookURL := testutil.ExampleWebhookURL + "/user-registered" |
| 104 | + hookPath := "/services/identity/config/selfservice/flows/registration/after/password/hooks" |
| 105 | + |
17 | 106 | resource.Test(t, resource.TestCase{ |
18 | | - PreCheck: func() { acctest.AccPreCheck(t) }, |
| 107 | + PreCheck: func() { |
| 108 | + acctest.AccPreCheck(t) |
| 109 | + cleanupDanglingWebhook(t, hookPath, webhookURL) |
| 110 | + }, |
19 | 111 | ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories(), |
20 | 112 | Steps: []resource.TestStep{ |
21 | 113 | // Create and Read |
|
0 commit comments