From 85760c6f3a7525dee52c521a61fdcc37aa149afc Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Fri, 10 May 2024 16:05:47 +0200
Subject: [PATCH 01/10] feat: support workspace tags

---
 .../coder_workspace_tags/resource.tf          | 48 +++++++++++++++++++
 provider/examples_test.go                     | 28 ++++++-----
 2 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 examples/resources/coder_workspace_tags/resource.tf

diff --git a/examples/resources/coder_workspace_tags/resource.tf b/examples/resources/coder_workspace_tags/resource.tf
new file mode 100644
index 00000000..5988bac4
--- /dev/null
+++ b/examples/resources/coder_workspace_tags/resource.tf
@@ -0,0 +1,48 @@
+provider "coder" {}
+
+data "coder_parameter" "os_selector" {
+  name = "os_selector"
+  display_name = "Operating System"
+  mutable = false
+
+  default = "osx"
+
+  option {
+    icon  = "/icons/linux.png"
+    name  = "Linux"
+    value = "linux"
+  }
+  option {
+    icon  = "/icons/osx.png"
+    name  = "OSX"
+    value = "osx"
+  }
+  option {
+    icon  = "/icons/windows.png"
+    name  = "Windows"
+    value = "windows"
+  }
+}
+
+data "coder_parameter" "feature_cache_enabled" {
+  name         = "feature_cache_enabled"
+  display_name = "Enable cache?"
+  type    = "bool"
+
+  default = false
+}
+
+data "coder_workspace_tags" "custom_workspace_tags" {
+  tag {
+    name = "cluster"
+    value = "developers"
+  }
+  tag {
+    name = "os"
+    value = "${data.coder_parameter.os_selector}"
+  }
+  tag {
+    name = "cache"
+    value = data.coder_parameter.feature_cache_enabled == "true" ? "nix-with-cache": "no-cache"
+  }
+}
\ No newline at end of file
diff --git a/provider/examples_test.go b/provider/examples_test.go
index 9be7ce02..6fa73d21 100644
--- a/provider/examples_test.go
+++ b/provider/examples_test.go
@@ -14,19 +14,25 @@ import (
 func TestExamples(t *testing.T) {
 	t.Parallel()
 
-	t.Run("coder_parameter", func(t *testing.T) {
-		t.Parallel()
+	for _, testDir := range []string{
+		"coder_parameter",
+		"coder_workspace_tags",
+	} {
+		t.Run(testDir, func(t *testing.T) {
+			testDir := testDir
+			t.Parallel()
 
-		resource.Test(t, resource.TestCase{
-			Providers: map[string]*schema.Provider{
-				"coder": provider.New(),
-			},
-			IsUnitTest: true,
-			Steps: []resource.TestStep{{
-				Config: mustReadFile(t, "../examples/resources/coder_parameter/resource.tf"),
-			}},
+			resource.Test(t, resource.TestCase{
+				Providers: map[string]*schema.Provider{
+					"coder": provider.New(),
+				},
+				IsUnitTest: true,
+				Steps: []resource.TestStep{{
+					Config: mustReadFile(t, "../examples/resources/"+testDir+"/resource.tf"),
+				}},
+			})
 		})
-	})
+	}
 }
 
 func mustReadFile(t *testing.T, path string) string {

From 2601c439e678a05af315c7a03eeb6c49e39c3622 Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Fri, 10 May 2024 16:07:33 +0200
Subject: [PATCH 02/10] fmt

---
 .../resources/coder_workspace_tags/resource.tf   | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/examples/resources/coder_workspace_tags/resource.tf b/examples/resources/coder_workspace_tags/resource.tf
index 5988bac4..ed3e65e8 100644
--- a/examples/resources/coder_workspace_tags/resource.tf
+++ b/examples/resources/coder_workspace_tags/resource.tf
@@ -1,9 +1,9 @@
 provider "coder" {}
 
 data "coder_parameter" "os_selector" {
-  name = "os_selector"
+  name         = "os_selector"
   display_name = "Operating System"
-  mutable = false
+  mutable      = false
 
   default = "osx"
 
@@ -27,22 +27,22 @@ data "coder_parameter" "os_selector" {
 data "coder_parameter" "feature_cache_enabled" {
   name         = "feature_cache_enabled"
   display_name = "Enable cache?"
-  type    = "bool"
+  type         = "bool"
 
   default = false
 }
 
 data "coder_workspace_tags" "custom_workspace_tags" {
   tag {
-    name = "cluster"
+    name  = "cluster"
     value = "developers"
   }
   tag {
-    name = "os"
-    value = "${data.coder_parameter.os_selector}"
+    name  = "os"
+    value = data.coder_parameter.os_selector
   }
   tag {
-    name = "cache"
-    value = data.coder_parameter.feature_cache_enabled == "true" ? "nix-with-cache": "no-cache"
+    name  = "cache"
+    value = data.coder_parameter.feature_cache_enabled == "true" ? "nix-with-cache" : "no-cache"
   }
 }
\ No newline at end of file

From 434b170000d24fcc046fb21b5d2c3ad967163401 Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Tue, 14 May 2024 14:17:52 +0200
Subject: [PATCH 03/10] WIP

---
 .../coder_workspace_tags/resource.tf          | 16 ++++-
 provider/provider.go                          | 11 ++--
 provider/workspace_tags.go                    | 60 +++++++++++++++++++
 3 files changed, 80 insertions(+), 7 deletions(-)
 create mode 100644 provider/workspace_tags.go

diff --git a/examples/resources/coder_workspace_tags/resource.tf b/examples/resources/coder_workspace_tags/resource.tf
index ed3e65e8..ffa7efe4 100644
--- a/examples/resources/coder_workspace_tags/resource.tf
+++ b/examples/resources/coder_workspace_tags/resource.tf
@@ -32,6 +32,14 @@ data "coder_parameter" "feature_cache_enabled" {
   default = false
 }
 
+data "coder_parameter" "feature_debug_enabled" {
+  name         = "feature_debug_enabled"
+  display_name = "Enable debug?"
+  type         = "bool"
+
+  default = true
+}
+
 data "coder_workspace_tags" "custom_workspace_tags" {
   tag {
     name  = "cluster"
@@ -39,10 +47,14 @@ data "coder_workspace_tags" "custom_workspace_tags" {
   }
   tag {
     name  = "os"
-    value = data.coder_parameter.os_selector
+    value = data.coder_parameter.os_selector.value
+  }
+  tag {
+    name  = "debug"
+    value = data.coder_parameter.feature_debug_enabled.value
   }
   tag {
     name  = "cache"
-    value = data.coder_parameter.feature_cache_enabled == "true" ? "nix-with-cache" : "no-cache"
+    value = data.coder_parameter.feature_cache_enabled.value == "true" ? "nix-with-cache" : "no-cache"
   }
 }
\ No newline at end of file
diff --git a/provider/provider.go b/provider/provider.go
index fb262c8c..4ea75ba8 100644
--- a/provider/provider.go
+++ b/provider/provider.go
@@ -68,11 +68,12 @@ func New() *schema.Provider {
 			}, nil
 		},
 		DataSourcesMap: map[string]*schema.Resource{
-			"coder_workspace":     workspaceDataSource(),
-			"coder_provisioner":   provisionerDataSource(),
-			"coder_parameter":     parameterDataSource(),
-			"coder_git_auth":      gitAuthDataSource(),
-			"coder_external_auth": externalAuthDataSource(),
+			"coder_workspace":      workspaceDataSource(),
+			"coder_workspace_tags": workspaceTagDataSource(),
+			"coder_provisioner":    provisionerDataSource(),
+			"coder_parameter":      parameterDataSource(),
+			"coder_git_auth":       gitAuthDataSource(),
+			"coder_external_auth":  externalAuthDataSource(),
 		},
 		ResourcesMap: map[string]*schema.Resource{
 			"coder_agent":          agentResource(),
diff --git a/provider/workspace_tags.go b/provider/workspace_tags.go
new file mode 100644
index 00000000..2f2be6d5
--- /dev/null
+++ b/provider/workspace_tags.go
@@ -0,0 +1,60 @@
+package provider
+
+import (
+	"context"
+	"log"
+
+	"github.com/google/uuid"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+type WorkspaceTags struct {
+	Tag []Tag
+}
+
+type Tag struct {
+	Name  string
+	Value string
+}
+
+func workspaceTagDataSource() *schema.Resource {
+	return &schema.Resource{
+		Description: "Use this data source to configure workspace tags to select provisioners.",
+		ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics {
+			rd.SetId(uuid.NewString())
+			rawConfig := rd.GetRawConfig()
+			rawTags, ok := rawConfig.AsValueMap()["tag"]
+			if !ok {
+				return diag.Errorf("boom")
+			}
+			log.Println(rawTags)
+			return nil
+		},
+		Schema: map[string]*schema.Schema{
+			"tag": {
+				Type:        schema.TypeList,
+				Description: `Each "tag" block defines a workspace tag.`,
+				ForceNew:    true,
+				Optional:    true,
+				MaxItems:    64,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"name": {
+							Type:        schema.TypeString,
+							Description: "The name of the tag.",
+							ForceNew:    true,
+							Required:    true,
+						},
+						"value": {
+							Type:        schema.TypeString,
+							Description: "The value of the tag.",
+							ForceNew:    true,
+							Required:    true,
+						},
+					},
+				},
+			},
+		},
+	}
+}

From 2b879566874f476e9f4ff84077eee841228e8cd1 Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Tue, 14 May 2024 14:57:00 +0200
Subject: [PATCH 04/10] WIP

---
 examples/resources/coder_workspace_tags/resource.tf | 2 +-
 provider/workspace_tags.go                          | 7 -------
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/examples/resources/coder_workspace_tags/resource.tf b/examples/resources/coder_workspace_tags/resource.tf
index ffa7efe4..392d328c 100644
--- a/examples/resources/coder_workspace_tags/resource.tf
+++ b/examples/resources/coder_workspace_tags/resource.tf
@@ -51,7 +51,7 @@ data "coder_workspace_tags" "custom_workspace_tags" {
   }
   tag {
     name  = "debug"
-    value = data.coder_parameter.feature_debug_enabled.value
+    value = "${data.coder_parameter.feature_debug_enabled.value}"
   }
   tag {
     name  = "cache"
diff --git a/provider/workspace_tags.go b/provider/workspace_tags.go
index 2f2be6d5..f1430f49 100644
--- a/provider/workspace_tags.go
+++ b/provider/workspace_tags.go
@@ -2,7 +2,6 @@ package provider
 
 import (
 	"context"
-	"log"
 
 	"github.com/google/uuid"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -23,12 +22,6 @@ func workspaceTagDataSource() *schema.Resource {
 		Description: "Use this data source to configure workspace tags to select provisioners.",
 		ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics {
 			rd.SetId(uuid.NewString())
-			rawConfig := rd.GetRawConfig()
-			rawTags, ok := rawConfig.AsValueMap()["tag"]
-			if !ok {
-				return diag.Errorf("boom")
-			}
-			log.Println(rawTags)
 			return nil
 		},
 		Schema: map[string]*schema.Schema{

From 537e372f28580b2cc61c76c7ac74977823dd79a0 Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Tue, 14 May 2024 15:04:20 +0200
Subject: [PATCH 05/10] unit test

---
 provider/workspace_tags_test.go | 54 +++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 provider/workspace_tags_test.go

diff --git a/provider/workspace_tags_test.go b/provider/workspace_tags_test.go
new file mode 100644
index 00000000..bda2c780
--- /dev/null
+++ b/provider/workspace_tags_test.go
@@ -0,0 +1,54 @@
+package provider_test
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
+	"github.com/stretchr/testify/require"
+
+	"github.com/coder/terraform-provider-coder/provider"
+)
+
+func TestWorkspaceTags(t *testing.T) {
+	resource.Test(t, resource.TestCase{
+		Providers: map[string]*schema.Provider{
+			"coder": provider.New(),
+		},
+		IsUnitTest: true,
+		Steps: []resource.TestStep{{
+			Config: `
+			provider "coder" {
+			}
+			data "coder_parameter" "animal" {
+				name = "animal"
+				type = "string"
+				default = "chris"
+			}
+			data "coder_workspace_tags" "wt" {
+				tag {
+					name = "cat"
+					value = "james"
+				}
+				tag {
+					name = "dog"
+					value = data.coder_parameter.animal.value
+				}
+			}`,
+			Check: func(state *terraform.State) error {
+				require.Len(t, state.Modules, 1)
+				require.Len(t, state.Modules[0].Resources, 2)
+				resource := state.Modules[0].Resources["data.coder_workspace_tags.wt"]
+				require.NotNil(t, resource)
+
+				attribs := resource.Primary.Attributes
+				require.Equal(t, "cat", attribs["tag.0.name"])
+				require.Equal(t, "james", attribs["tag.0.value"])
+				require.Equal(t, "dog", attribs["tag.1.name"])
+				require.Equal(t, "chris", attribs["tag.1.value"])
+				return nil
+			},
+		}},
+	})
+}

From 1d66a392116cac8438d1fdc3760643502e470637 Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Wed, 15 May 2024 11:15:56 +0200
Subject: [PATCH 06/10] Env

---
 provider/examples_test.go  | 47 ++++++++++++++++++++++----------------
 provider/workspace_tags.go |  2 ++
 2 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/provider/examples_test.go b/provider/examples_test.go
index 6fa73d21..e612a1db 100644
--- a/provider/examples_test.go
+++ b/provider/examples_test.go
@@ -2,6 +2,7 @@ package provider_test
 
 import (
 	"os"
+	"path/filepath"
 	"testing"
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -11,28 +12,34 @@ import (
 	"github.com/coder/terraform-provider-coder/provider"
 )
 
-func TestExamples(t *testing.T) {
+func TestExamples_CoderParameter(t *testing.T) {
 	t.Parallel()
 
-	for _, testDir := range []string{
-		"coder_parameter",
-		"coder_workspace_tags",
-	} {
-		t.Run(testDir, func(t *testing.T) {
-			testDir := testDir
-			t.Parallel()
-
-			resource.Test(t, resource.TestCase{
-				Providers: map[string]*schema.Provider{
-					"coder": provider.New(),
-				},
-				IsUnitTest: true,
-				Steps: []resource.TestStep{{
-					Config: mustReadFile(t, "../examples/resources/"+testDir+"/resource.tf"),
-				}},
-			})
-		})
-	}
+	resource.Test(t, resource.TestCase{
+		Providers: map[string]*schema.Provider{
+			"coder": provider.New(),
+		},
+		IsUnitTest: true,
+		Steps: []resource.TestStep{{
+			Config: mustReadFile(t, "../examples/resources/coder_workspace_tags/resource.tf"),
+		}},
+	})
+}
+
+func TestExamples_CoderWorkspaceTags(t *testing.T) {
+	// no parallel as the test calls t.Setenv()
+	workDir := "../examples/resources/coder_workspace_tags"
+	t.Setenv(provider.TerraformWorkDirEnv, workDir)
+
+	resource.Test(t, resource.TestCase{
+		Providers: map[string]*schema.Provider{
+			"coder": provider.New(),
+		},
+		IsUnitTest: true,
+		Steps: []resource.TestStep{{
+			Config: mustReadFile(t, filepath.Join(workDir, "/resource.tf")),
+		}},
+	})
 }
 
 func mustReadFile(t *testing.T, path string) string {
diff --git a/provider/workspace_tags.go b/provider/workspace_tags.go
index f1430f49..1d754ab7 100644
--- a/provider/workspace_tags.go
+++ b/provider/workspace_tags.go
@@ -8,6 +8,8 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 )
 
+const TerraformWorkDirEnv = "CODER_TF_WORK_DIR"
+
 type WorkspaceTags struct {
 	Tag []Tag
 }

From f0f2f342b37178c793f3d5521042c9f632cd9de5 Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Wed, 15 May 2024 12:29:50 +0200
Subject: [PATCH 07/10] just basic data resource

---
 provider/examples_test.go  | 47 ++++++++++++++++----------------------
 provider/workspace_tags.go |  2 --
 2 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/provider/examples_test.go b/provider/examples_test.go
index e612a1db..6fa73d21 100644
--- a/provider/examples_test.go
+++ b/provider/examples_test.go
@@ -2,7 +2,6 @@ package provider_test
 
 import (
 	"os"
-	"path/filepath"
 	"testing"
 
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -12,34 +11,28 @@ import (
 	"github.com/coder/terraform-provider-coder/provider"
 )
 
-func TestExamples_CoderParameter(t *testing.T) {
+func TestExamples(t *testing.T) {
 	t.Parallel()
 
-	resource.Test(t, resource.TestCase{
-		Providers: map[string]*schema.Provider{
-			"coder": provider.New(),
-		},
-		IsUnitTest: true,
-		Steps: []resource.TestStep{{
-			Config: mustReadFile(t, "../examples/resources/coder_workspace_tags/resource.tf"),
-		}},
-	})
-}
-
-func TestExamples_CoderWorkspaceTags(t *testing.T) {
-	// no parallel as the test calls t.Setenv()
-	workDir := "../examples/resources/coder_workspace_tags"
-	t.Setenv(provider.TerraformWorkDirEnv, workDir)
-
-	resource.Test(t, resource.TestCase{
-		Providers: map[string]*schema.Provider{
-			"coder": provider.New(),
-		},
-		IsUnitTest: true,
-		Steps: []resource.TestStep{{
-			Config: mustReadFile(t, filepath.Join(workDir, "/resource.tf")),
-		}},
-	})
+	for _, testDir := range []string{
+		"coder_parameter",
+		"coder_workspace_tags",
+	} {
+		t.Run(testDir, func(t *testing.T) {
+			testDir := testDir
+			t.Parallel()
+
+			resource.Test(t, resource.TestCase{
+				Providers: map[string]*schema.Provider{
+					"coder": provider.New(),
+				},
+				IsUnitTest: true,
+				Steps: []resource.TestStep{{
+					Config: mustReadFile(t, "../examples/resources/"+testDir+"/resource.tf"),
+				}},
+			})
+		})
+	}
 }
 
 func mustReadFile(t *testing.T, path string) string {
diff --git a/provider/workspace_tags.go b/provider/workspace_tags.go
index 1d754ab7..f1430f49 100644
--- a/provider/workspace_tags.go
+++ b/provider/workspace_tags.go
@@ -8,8 +8,6 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
 )
 
-const TerraformWorkDirEnv = "CODER_TF_WORK_DIR"
-
 type WorkspaceTags struct {
 	Tag []Tag
 }

From 98d4df8c73aaeffa9930d4d7e92b033de140ce9a Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Wed, 15 May 2024 12:46:10 +0200
Subject: [PATCH 08/10] fmt

---
 examples/resources/coder_workspace_tags/resource.tf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/resources/coder_workspace_tags/resource.tf b/examples/resources/coder_workspace_tags/resource.tf
index 392d328c..00ad198d 100644
--- a/examples/resources/coder_workspace_tags/resource.tf
+++ b/examples/resources/coder_workspace_tags/resource.tf
@@ -51,7 +51,7 @@ data "coder_workspace_tags" "custom_workspace_tags" {
   }
   tag {
     name  = "debug"
-    value = "${data.coder_parameter.feature_debug_enabled.value}"
+    value = "${data.coder_parameter.feature_debug_enabled.value}+12345"
   }
   tag {
     name  = "cache"

From 9a46f65b745161878254207eb7783b3e8ccac052 Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Wed, 15 May 2024 17:23:15 +0200
Subject: [PATCH 09/10] Tags as map

---
 .../coder_workspace_tags/resource.tf          | 20 +++---------
 provider/workspace_tags.go                    | 31 +++----------------
 2 files changed, 10 insertions(+), 41 deletions(-)

diff --git a/examples/resources/coder_workspace_tags/resource.tf b/examples/resources/coder_workspace_tags/resource.tf
index 00ad198d..6c26b061 100644
--- a/examples/resources/coder_workspace_tags/resource.tf
+++ b/examples/resources/coder_workspace_tags/resource.tf
@@ -41,20 +41,10 @@ data "coder_parameter" "feature_debug_enabled" {
 }
 
 data "coder_workspace_tags" "custom_workspace_tags" {
-  tag {
-    name  = "cluster"
-    value = "developers"
-  }
-  tag {
-    name  = "os"
-    value = data.coder_parameter.os_selector.value
-  }
-  tag {
-    name  = "debug"
-    value = "${data.coder_parameter.feature_debug_enabled.value}+12345"
-  }
-  tag {
-    name  = "cache"
-    value = data.coder_parameter.feature_cache_enabled.value == "true" ? "nix-with-cache" : "no-cache"
+  tags = {
+    "cluster" = "developers"
+    "os"      = data.coder_parameter.os_selector.value
+    "debug"   = "${data.coder_parameter.feature_debug_enabled.value}+12345"
+    "cache"   = data.coder_parameter.feature_cache_enabled.value == "true" ? "nix-with-cache" : "no-cache"
   }
 }
\ No newline at end of file
diff --git a/provider/workspace_tags.go b/provider/workspace_tags.go
index f1430f49..088ff546 100644
--- a/provider/workspace_tags.go
+++ b/provider/workspace_tags.go
@@ -9,12 +9,7 @@ import (
 )
 
 type WorkspaceTags struct {
-	Tag []Tag
-}
-
-type Tag struct {
-	Name  string
-	Value string
+	Tags map[string]string
 }
 
 func workspaceTagDataSource() *schema.Resource {
@@ -25,28 +20,12 @@ func workspaceTagDataSource() *schema.Resource {
 			return nil
 		},
 		Schema: map[string]*schema.Schema{
-			"tag": {
-				Type:        schema.TypeList,
-				Description: `Each "tag" block defines a workspace tag.`,
+			"tags": {
+				Type:        schema.TypeMap,
+				Description: `Key-value map with workspace tags`,
 				ForceNew:    true,
 				Optional:    true,
-				MaxItems:    64,
-				Elem: &schema.Resource{
-					Schema: map[string]*schema.Schema{
-						"name": {
-							Type:        schema.TypeString,
-							Description: "The name of the tag.",
-							ForceNew:    true,
-							Required:    true,
-						},
-						"value": {
-							Type:        schema.TypeString,
-							Description: "The value of the tag.",
-							ForceNew:    true,
-							Required:    true,
-						},
-					},
-				},
+				Elem:        &schema.Schema{Type: schema.TypeString},
 			},
 		},
 	}

From 4aa79df87e1ae247f71888d3713090b3c3738ac0 Mon Sep 17 00:00:00 2001
From: Marcin Tojek <marcin@coder.com>
Date: Wed, 15 May 2024 17:27:41 +0200
Subject: [PATCH 10/10] james and chris

---
 provider/workspace_tags_test.go | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/provider/workspace_tags_test.go b/provider/workspace_tags_test.go
index bda2c780..2d0f1c49 100644
--- a/provider/workspace_tags_test.go
+++ b/provider/workspace_tags_test.go
@@ -27,13 +27,9 @@ func TestWorkspaceTags(t *testing.T) {
 				default = "chris"
 			}
 			data "coder_workspace_tags" "wt" {
-				tag {
-					name = "cat"
-					value = "james"
-				}
-				tag {
-					name = "dog"
-					value = data.coder_parameter.animal.value
+				tags = {
+					"cat" = "james"
+					"dog" = data.coder_parameter.animal.value
 				}
 			}`,
 			Check: func(state *terraform.State) error {
@@ -43,10 +39,8 @@ func TestWorkspaceTags(t *testing.T) {
 				require.NotNil(t, resource)
 
 				attribs := resource.Primary.Attributes
-				require.Equal(t, "cat", attribs["tag.0.name"])
-				require.Equal(t, "james", attribs["tag.0.value"])
-				require.Equal(t, "dog", attribs["tag.1.name"])
-				require.Equal(t, "chris", attribs["tag.1.value"])
+				require.Equal(t, "james", attribs["tags.cat"])
+				require.Equal(t, "chris", attribs["tags.dog"])
 				return nil
 			},
 		}},