<commit_before>package google

import (
	"fmt"
	"reflect"
	"sort"
	"strings"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"google.golang.org/api/cloudresourcemanager/v1"
)

/*
Tests for `google_project_organization_policy`

These are *not* run in parallel, as they all use the same project
and I end up with 409 Conflict errors from the API when they are
run in parallel.
*/

func TestAccProjectOrganizationPolicy_boolean(t *testing.T) {
	projectId := getTestProjectFromEnv()

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				// Test creation of an enforced boolean policy
				Config: testAccProjectOrganizationPolicy_boolean(projectId, true),
				Check:  testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", true),
			},
			{
				// Test update from enforced to not
				Config: testAccProjectOrganizationPolicy_boolean(projectId, false),
				Check:  testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", false),
			},
			{
				Config:  " ",
				Destroy: true,
			},
			{
				// Test creation of a not enforced boolean policy
				Config: testAccProjectOrganizationPolicy_boolean(projectId, false),
				Check:  testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", false),
			},
			{
				// Test update from not enforced to enforced
				Config: testAccProjectOrganizationPolicy_boolean(projectId, true),
				Check:  testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", true),
			},
		},
	})
}

func TestAccProjectOrganizationPolicy_list_allowAll(t *testing.T) {
	projectId := getTestProjectFromEnv()

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccProjectOrganizationPolicy_list_allowAll(projectId),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyAll("list", "ALLOW"),
			},
		},
	})
}

func TestAccProjectOrganizationPolicy_list_allowSome(t *testing.T) {
	project := getTestProjectFromEnv()
	canonicalProject := canonicalProjectId(project)
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccProjectOrganizationPolicy_list_allowSome(project),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyAllowedValues("list", []string{canonicalProject}),
			},
		},
	})
}

func TestAccProjectOrganizationPolicy_list_denySome(t *testing.T) {
	projectId := getTestProjectFromEnv()
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccProjectOrganizationPolicy_list_denySome(projectId),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyDeniedValues("list", DENIED_ORG_POLICIES),
			},
		},
	})
}

func TestAccProjectOrganizationPolicy_list_update(t *testing.T) {
	projectId := getTestProjectFromEnv()
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccProjectOrganizationPolicy_list_allowAll(projectId),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyAll("list", "ALLOW"),
			},
			{
				Config: testAccProjectOrganizationPolicy_list_denySome(projectId),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyDeniedValues("list", DENIED_ORG_POLICIES),
			},
		},
	})
}

func testAccCheckGoogleProjectOrganizationPolicyDestroy(s *terraform.State) error {
	config := testAccProvider.Meta().(*Config)

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "google_project_organization_policy" {
			continue
		}

		projectId := canonicalProjectId(rs.Primary.Attributes["project"])
		constraint := canonicalOrgPolicyConstraint(rs.Primary.Attributes["constraint"])
		policy, err := config.clientResourceManager.Projects.GetOrgPolicy(projectId, &cloudresourcemanager.GetOrgPolicyRequest{
			Constraint: constraint,
		}).Do()

		if err != nil {
			return err
		}

		if policy.ListPolicy != nil || policy.BooleanPolicy != nil {
			return fmt.Errorf("Org policy with constraint '%s' hasn't been cleared", constraint)
		}
	}
	return nil
}

func testAccCheckGoogleProjectOrganizationBooleanPolicy(n string, enforced bool) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
		if err != nil {
			return err
		}

		if policy.BooleanPolicy.Enforced != enforced {
			return fmt.Errorf("Expected boolean policy enforcement to be '%t', got '%t'", enforced, policy.BooleanPolicy.Enforced)
		}

		return nil
	}
}

func testAccCheckGoogleProjectOrganizationListPolicyAll(n, policyType string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
		if err != nil {
			return err
		}

		if len(policy.ListPolicy.AllowedValues) > 0 || len(policy.ListPolicy.DeniedValues) > 0 {
			return fmt.Errorf("The `values` field shouldn't be set")
		}

		if policy.ListPolicy.AllValues != policyType {
			return fmt.Errorf("The list policy should %s all values", policyType)
		}

		return nil
	}
}

func testAccCheckGoogleProjectOrganizationListPolicyAllowedValues(n string, values []string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
		if err != nil {
			return err<commit_msg>Check that org listpolicy isn't nil.<commit_after>package google

import (
	"fmt"
	"reflect"
	"sort"
	"strings"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"google.golang.org/api/cloudresourcemanager/v1"
)

/*
Tests for `google_project_organization_policy`

These are *not* run in parallel, as they all use the same project
and I end up with 409 Conflict errors from the API when they are
run in parallel.
*/

func TestAccProjectOrganizationPolicy_boolean(t *testing.T) {
	projectId := getTestProjectFromEnv()

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				// Test creation of an enforced boolean policy
				Config: testAccProjectOrganizationPolicy_boolean(projectId, true),
				Check:  testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", true),
			},
			{
				// Test update from enforced to not
				Config: testAccProjectOrganizationPolicy_boolean(projectId, false),
				Check:  testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", false),
			},
			{
				Config:  " ",
				Destroy: true,
			},
			{
				// Test creation of a not enforced boolean policy
				Config: testAccProjectOrganizationPolicy_boolean(projectId, false),
				Check:  testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", false),
			},
			{
				// Test update from not enforced to enforced
				Config: testAccProjectOrganizationPolicy_boolean(projectId, true),
				Check:  testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", true),
			},
		},
	})
}

func TestAccProjectOrganizationPolicy_list_allowAll(t *testing.T) {
	projectId := getTestProjectFromEnv()

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccProjectOrganizationPolicy_list_allowAll(projectId),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyAll("list", "ALLOW"),
			},
		},
	})
}

func TestAccProjectOrganizationPolicy_list_allowSome(t *testing.T) {
	project := getTestProjectFromEnv()
	canonicalProject := canonicalProjectId(project)
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccProjectOrganizationPolicy_list_allowSome(project),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyAllowedValues("list", []string{canonicalProject}),
			},
		},
	})
}

func TestAccProjectOrganizationPolicy_list_denySome(t *testing.T) {
	projectId := getTestProjectFromEnv()
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccProjectOrganizationPolicy_list_denySome(projectId),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyDeniedValues("list", DENIED_ORG_POLICIES),
			},
		},
	})
}

func TestAccProjectOrganizationPolicy_list_update(t *testing.T) {
	projectId := getTestProjectFromEnv()
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccProjectOrganizationPolicy_list_allowAll(projectId),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyAll("list", "ALLOW"),
			},
			{
				Config: testAccProjectOrganizationPolicy_list_denySome(projectId),
				Check:  testAccCheckGoogleProjectOrganizationListPolicyDeniedValues("list", DENIED_ORG_POLICIES),
			},
		},
	})
}

func testAccCheckGoogleProjectOrganizationPolicyDestroy(s *terraform.State) error {
	config := testAccProvider.Meta().(*Config)

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "google_project_organization_policy" {
			continue
		}

		projectId := canonicalProjectId(rs.Primary.Attributes["project"])
		constraint := canonicalOrgPolicyConstraint(rs.Primary.Attributes["constraint"])
		policy, err := config.clientResourceManager.Projects.GetOrgPolicy(projectId, &cloudresourcemanager.GetOrgPolicyRequest{
			Constraint: constraint,
		}).Do()

		if err != nil {
			return err
		}

		if policy.ListPolicy != nil || policy.BooleanPolicy != nil {
			return fmt.Errorf("Org policy with constraint '%s' hasn't been cleared", constraint)
		}
	}
	return nil
}

func testAccCheckGoogleProjectOrganizationBooleanPolicy(n string, enforced bool) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
		if err != nil {
			return err
		}

		if policy.BooleanPolicy.Enforced != enforced {
			return fmt.Errorf("Expected boolean policy enforcement to be '%t', got '%t'", enforced, policy.BooleanPolicy.Enforced)
		}

		return nil
	}
}

func testAccCheckGoogleProjectOrganizationListPolicyAll(n, policyType string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
		if err != nil {
			return err
		}

		if policy.ListPolicy == nil {
			return nil
		}

		if len(policy.ListPolicy.AllowedValues) > 0 || len(policy.ListPolicy.DeniedValues) > 0 {
			return fmt.Errorf("The `values` field shouldn't be set")
		}

		if policy.ListPolicy.AllValues != policyType {
			return fmt.Errorf("The list policy should %s all values", policyType)
		}

		return nil
	}
}

func testAccCheckGoogleProjectOrganizationListPolicyAllowedValues(n string, values []string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
		if err != nil {
			return err
{'fraction_non_alphanumeric': 0.10041666666666667, 'fraction_numerical': 0.001, 'mean_word_length': 5.289832285115304, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5933745', 'n_tokens_mistral': 3995, 'n_tokens_neox': 3560, 'n_words': 713}