terraform-provider-towerops/internal/provider/organization_resource_test.go
Graham McIntire 70c7a5cfbb
feat: allow setting organization name via Terraform
- Make 'name' field optional and computed in organization resource
- Include name in Create and Update operations when provided
- Name can only be changed by organization owners (enforced by API)
- Matches API capability to update organization name
- Backwards compatible: name remains optional

Example usage:
  resource "towerops_organization" "main" {
    name      = "My Organization"
    use_sites = true
  }
2026-03-10 13:32:56 -05:00

139 lines
3.7 KiB
Go

package provider
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"sync"
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)
func TestAccOrganizationResource_basic(t *testing.T) {
var mu sync.Mutex
currentUseSites := false
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
switch {
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/organization":
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"data": Organization{
ID: "org-123",
Name: "Test ISP",
Slug: "test-isp",
UseSites: currentUseSites,
},
})
case r.Method == http.MethodPatch && r.URL.Path == "/api/v1/organization":
var body map[string]Organization
json.NewDecoder(r.Body).Decode(&body)
currentUseSites = body["organization"].UseSites
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"data": Organization{
ID: "org-123",
Name: "Test ISP",
Slug: "test-isp",
UseSites: currentUseSites,
},
})
default:
w.WriteHeader(http.StatusNotFound)
}
}))
defer server.Close()
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
Steps: []resource.TestStep{
{
Config: testAccOrganizationResourceConfig(server.URL, true),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("towerops_organization.settings", "use_sites", "true"),
resource.TestCheckResourceAttr("towerops_organization.settings", "name", "Test ISP"),
resource.TestCheckResourceAttr("towerops_organization.settings", "slug", "test-isp"),
),
},
},
})
}
func TestAccOrganizationResource_update(t *testing.T) {
var mu sync.Mutex
currentUseSites := false
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
switch {
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/organization":
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"data": Organization{
ID: "org-123",
Name: "Test ISP",
Slug: "test-isp",
UseSites: currentUseSites,
},
})
case r.Method == http.MethodPatch && r.URL.Path == "/api/v1/organization":
var body map[string]Organization
json.NewDecoder(r.Body).Decode(&body)
currentUseSites = body["organization"].UseSites
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"data": Organization{
ID: "org-123",
Name: "Test ISP",
Slug: "test-isp",
UseSites: currentUseSites,
},
})
default:
w.WriteHeader(http.StatusNotFound)
}
}))
defer server.Close()
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
Steps: []resource.TestStep{
{
Config: testAccOrganizationResourceConfig(server.URL, true),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("towerops_organization.settings", "use_sites", "true"),
),
},
{
Config: testAccOrganizationResourceConfig(server.URL, false),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("towerops_organization.settings", "use_sites", "false"),
),
},
},
})
}
func testAccOrganizationResourceConfig(apiURL string, useSites bool) string {
return fmt.Sprintf(`
provider "towerops" {
token = "test-token"
api_url = %q
}
resource "towerops_organization" "settings" {
use_sites = %t
}
`, apiURL, useSites)
}