Skip to content

Commit c527654

Browse files
committed
provider/heroku: add acctest covering orgs; fixup issues
Switching up ResourceData interaction to not reach into the internal dot-notation nesting.
1 parent 81779aa commit c527654

2 files changed

Lines changed: 146 additions & 34 deletions

File tree

builtin/providers/heroku/resource_heroku_app.go

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
"github.com/hashicorp/terraform/helper/schema"
1010
)
1111

12+
// herokuApplication is a value type used to hold the details of an
13+
// application. We use this for common storage of values needed for the
14+
// heroku.App and heroku.OrganizationApp types
1215
type herokuApplication struct {
1316
Name string
1417
Region string
@@ -134,10 +137,9 @@ func resourceHerokuApp() *schema.Resource {
134137
},
135138

136139
"organization": &schema.Schema{
137-
Description: "Name of Organization to create application in. Leave blank for personal apps.",
138-
Type: schema.TypeList,
139-
Optional: true,
140-
ForceNew: true,
140+
Type: schema.TypeList,
141+
Optional: true,
142+
ForceNew: true,
141143
Elem: &schema.Resource{
142144
Schema: map[string]*schema.Schema{
143145
"name": &schema.Schema{
@@ -162,21 +164,16 @@ func resourceHerokuApp() *schema.Resource {
162164
}
163165

164166
func isOrganizationApp(d *schema.ResourceData) bool {
165-
_, ok := d.GetOk("organization.0.name")
166-
return ok
167+
v := d.Get("organization").([]interface{})
168+
return len(v) > 0 && v[0] != nil
167169
}
168170

169171
func switchHerokuAppCreate(d *schema.ResourceData, meta interface{}) error {
170-
orgCount := d.Get("organization.#").(int)
171-
if orgCount > 1 {
172-
return fmt.Errorf("Error Creating Heroku App: Only 1 Heroku Organization is permitted")
173-
}
174-
175172
if isOrganizationApp(d) {
176173
return resourceHerokuOrgAppCreate(d, meta)
177-
} else {
178-
return resourceHerokuAppCreate(d, meta)
179174
}
175+
176+
return resourceHerokuAppCreate(d, meta)
180177
}
181178

182179
func resourceHerokuAppCreate(d *schema.ResourceData, meta interface{}) error {
@@ -225,19 +222,25 @@ func resourceHerokuOrgAppCreate(d *schema.ResourceData, meta interface{}) error
225222
// Build up our creation options
226223
opts := heroku.OrganizationAppCreateOpts{}
227224

228-
if v := d.Get("organization.0.name"); v != nil {
225+
v := d.Get("organization").([]interface{})
226+
if len(v) > 1 {
227+
return fmt.Errorf("Error Creating Heroku App: Only 1 Heroku Organization is permitted")
228+
}
229+
orgDetails := v[0].(map[string]interface{})
230+
231+
if v := orgDetails["name"]; v != nil {
229232
vs := v.(string)
230233
log.Printf("[DEBUG] Organization name: %s", vs)
231234
opts.Organization = &vs
232235
}
233236

234-
if v := d.Get("organization.0.personal"); v != nil {
237+
if v := orgDetails["personal"]; v != nil {
235238
vs := v.(bool)
236239
log.Printf("[DEBUG] Organization Personal: %t", vs)
237240
opts.Personal = &vs
238241
}
239242

240-
if v := d.Get("organization.0.locked"); v != nil {
243+
if v := orgDetails["locked"]; v != nil {
241244
vs := v.(bool)
242245
log.Printf("[DEBUG] Organization locked: %t", vs)
243246
opts.Locked = &vs
@@ -289,7 +292,8 @@ func resourceHerokuAppRead(d *schema.ResourceData, meta interface{}) error {
289292
}
290293
}
291294

292-
_, organizationApp := d.GetOk("organization.0.name")
295+
organizationApp := isOrganizationApp(d)
296+
293297
// Only set the config_vars that we have set in the configuration.
294298
// The "all_config_vars" field has all of them.
295299
app, err := resourceHerokuAppRetrieve(d.Id(), organizationApp, client)
@@ -315,10 +319,15 @@ func resourceHerokuAppRead(d *schema.ResourceData, meta interface{}) error {
315319
d.Set("config_vars", configVarsValue)
316320
d.Set("all_config_vars", app.Vars)
317321
if organizationApp {
318-
d.Set("organization.#", "1")
319-
d.Set("organization.0.name", app.App.OrganizationName)
320-
d.Set("organization.0.locked", app.App.Locked)
321-
d.Set("organization.0.private", false)
322+
orgDetails := map[string]interface{}{
323+
"name": app.App.OrganizationName,
324+
"locked": app.App.Locked,
325+
"private": false,
326+
}
327+
err := d.Set("organization", []interface{}{orgDetails})
328+
if err != nil {
329+
return err
330+
}
322331
}
323332

324333
// We know that the hostname on heroku will be the name+herokuapp.com

builtin/providers/heroku/resource_heroku_app_test.go

Lines changed: 116 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package heroku
22

33
import (
44
"fmt"
5+
"os"
56
"testing"
67

78
"github.com/cyberdelia/heroku-go/v3"
@@ -102,6 +103,31 @@ func TestAccHerokuApp_NukeVars(t *testing.T) {
102103
})
103104
}
104105

106+
func TestAccHerokuApp_Organization(t *testing.T) {
107+
var app heroku.OrganizationApp
108+
org := os.Getenv("HEROKU_ORGANIZATION")
109+
110+
resource.Test(t, resource.TestCase{
111+
PreCheck: func() {
112+
testAccPreCheck(t)
113+
if org == "" {
114+
t.Skip("HEROKU_ORGANIZATION is not set; skipping test.")
115+
}
116+
},
117+
Providers: testAccProviders,
118+
CheckDestroy: testAccCheckHerokuAppDestroy,
119+
Steps: []resource.TestStep{
120+
resource.TestStep{
121+
Config: fmt.Sprintf(testAccCheckHerokuAppConfig_organization, org),
122+
Check: resource.ComposeTestCheckFunc(
123+
testAccCheckHerokuAppExistsOrg("heroku_app.foobar", &app),
124+
testAccCheckHerokuAppAttributesOrg(&app, org),
125+
),
126+
},
127+
},
128+
})
129+
}
130+
105131
func testAccCheckHerokuAppDestroy(s *terraform.State) error {
106132
client := testAccProvider.Meta().(*heroku.Service)
107133

@@ -197,6 +223,39 @@ func testAccCheckHerokuAppAttributesNoVars(app *heroku.App) resource.TestCheckFu
197223
}
198224
}
199225

226+
func testAccCheckHerokuAppAttributesOrg(app *heroku.OrganizationApp, org string) resource.TestCheckFunc {
227+
return func(s *terraform.State) error {
228+
client := testAccProvider.Meta().(*heroku.Service)
229+
230+
if app.Region.Name != "us" {
231+
return fmt.Errorf("Bad region: %s", app.Region.Name)
232+
}
233+
234+
if app.Stack.Name != "cedar-14" {
235+
return fmt.Errorf("Bad stack: %s", app.Stack.Name)
236+
}
237+
238+
if app.Name != "terraform-test-app" {
239+
return fmt.Errorf("Bad name: %s", app.Name)
240+
}
241+
242+
if app.Organization == nil || app.Organization.Name != org {
243+
return fmt.Errorf("Bad org: %v", app.Organization)
244+
}
245+
246+
vars, err := client.ConfigVarInfo(app.Name)
247+
if err != nil {
248+
return err
249+
}
250+
251+
if vars["FOO"] != "bar" {
252+
return fmt.Errorf("Bad config vars: %v", vars)
253+
}
254+
255+
return nil
256+
}
257+
}
258+
200259
func testAccCheckHerokuAppExists(n string, app *heroku.App) resource.TestCheckFunc {
201260
return func(s *terraform.State) error {
202261
rs, ok := s.RootModule().Resources[n]
@@ -227,29 +286,73 @@ func testAccCheckHerokuAppExists(n string, app *heroku.App) resource.TestCheckFu
227286
}
228287
}
229288

289+
func testAccCheckHerokuAppExistsOrg(n string, app *heroku.OrganizationApp) resource.TestCheckFunc {
290+
return func(s *terraform.State) error {
291+
rs, ok := s.RootModule().Resources[n]
292+
293+
if !ok {
294+
return fmt.Errorf("Not found: %s", n)
295+
}
296+
297+
if rs.Primary.ID == "" {
298+
return fmt.Errorf("No App Name is set")
299+
}
300+
301+
client := testAccProvider.Meta().(*heroku.Service)
302+
303+
foundApp, err := client.OrganizationAppInfo(rs.Primary.ID)
304+
305+
if err != nil {
306+
return err
307+
}
308+
309+
if foundApp.Name != rs.Primary.ID {
310+
return fmt.Errorf("App not found")
311+
}
312+
313+
*app = *foundApp
314+
315+
return nil
316+
}
317+
}
318+
230319
const testAccCheckHerokuAppConfig_basic = `
231320
resource "heroku_app" "foobar" {
232-
name = "terraform-test-app"
233-
region = "us"
321+
name = "terraform-test-app"
322+
region = "us"
234323
235-
config_vars {
236-
FOO = "bar"
237-
}
324+
config_vars {
325+
FOO = "bar"
326+
}
238327
}`
239328

240329
const testAccCheckHerokuAppConfig_updated = `
241330
resource "heroku_app" "foobar" {
242-
name = "terraform-test-renamed"
243-
region = "us"
331+
name = "terraform-test-renamed"
332+
region = "us"
244333
245-
config_vars {
246-
FOO = "bing"
247-
BAZ = "bar"
248-
}
334+
config_vars {
335+
FOO = "bing"
336+
BAZ = "bar"
337+
}
249338
}`
250339

251340
const testAccCheckHerokuAppConfig_no_vars = `
252341
resource "heroku_app" "foobar" {
253-
name = "terraform-test-app"
254-
region = "us"
342+
name = "terraform-test-app"
343+
region = "us"
344+
}`
345+
346+
const testAccCheckHerokuAppConfig_organization = `
347+
resource "heroku_app" "foobar" {
348+
name = "terraform-test-app"
349+
region = "us"
350+
351+
organization {
352+
name = "%s"
353+
}
354+
355+
config_vars {
356+
FOO = "bar"
357+
}
255358
}`

0 commit comments

Comments
 (0)