Skip to content

Commit

Permalink
Replace pattern placeholders when generating urls (#426)
Browse files Browse the repository at this point in the history
  • Loading branch information
pakrym-stripe authored Jun 13, 2023
1 parent fb3f682 commit 378bd51
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
8 changes: 6 additions & 2 deletions server/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,10 +454,14 @@ func (g *DataGenerator) maybeDereference(schema *spec.Schema, context string) (*

func (g *DataGenerator) generateURLForListableResource(schema *spec.Schema, params *GenerateParams) string {
var val string
const regexPlaceholder = "[^/]+"
if strings.HasPrefix(schema.Pattern, "^") {
// Many listable resources have a URL pattern of the form "^/v1/whatevers";
// we cut off the "^" to leave the URL.
// Many listable resources have a URL pattern of the form "^/v1/tax/calculations/[^/]+/line_items";
// we cut off the "^" to leave the URL and replace placeholders with ids.
val = schema.Pattern[1:]
if strings.Index(val, regexPlaceholder) != -1 {
val = strings.Replace(val, regexPlaceholder, "id_123", 1)
}
} else if params.example != nil {
// If an example was provided, we can assume it has the correct format
example := params.example.value.(map[string]interface{})
Expand Down
59 changes: 59 additions & 0 deletions server/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
)

var listSchema *spec.Schema
var listSchemaWithPlaceholder *spec.Schema
var searchResultSchema *spec.Schema
var verbose bool

Expand Down Expand Up @@ -41,6 +42,30 @@ func init() {
},
}

listSchemaWithPlaceholder = &spec.Schema{
Type: "object",
Properties: map[string]*spec.Schema{
"data": {
Items: &spec.Schema{
Ref: "#/components/schemas/charge",
},
},
"has_more": {
Type: "boolean",
},
"object": {
Enum: []interface{}{"list"},
},
"total_count": {
Type: "integer",
},
"url": {
Type: "string",
Pattern: "^/v1/charges/[^/]+/nested_list",
},
},
}

searchResultSchema = &spec.Schema{
Type: "object",
Properties: map[string]*spec.Schema{
Expand Down Expand Up @@ -339,6 +364,40 @@ func TestGenerateResponseData(t *testing.T) {
data.(map[string]interface{})["customer"])
}

// injected ID in list url
{
generator := DataGenerator{
testSpec.Components.Schemas,
&spec.Fixtures{
Resources: map[spec.ResourceID]interface{}{
spec.ResourceID("charge"): map[string]interface{}{"id": "ch_123"},
spec.ResourceID("with_charges_list"): map[string]interface{}{
"charges_list": map[string]interface{}{
"url": "/v1/charges",
},
},
},
},
verbose,
}
data, err := generator.Generate(&GenerateParams{
Schema: &spec.Schema{
Type: "object",
Properties: map[string]*spec.Schema{
"charges_list": listSchemaWithPlaceholder,
},
XResourceID: "with_charges_list",
},
})
assert.Nil(t, err)
chargesList := data.(map[string]interface{})["charges_list"]
assert.Equal(t, "list", chargesList.(map[string]interface{})["object"])
assert.Equal(t, "/v1/charges/id_123/nested_list", chargesList.(map[string]interface{})["url"])
assert.Equal(t,
testFixtures.Resources["charge"].(map[string]interface{})["id"],
chargesList.(map[string]interface{})["data"].([]interface{})[0].(map[string]interface{})["id"])
}

// injected secondary ID
{
generator := DataGenerator{testSpec.Components.Schemas, &spec.Fixtures{
Expand Down

0 comments on commit 378bd51

Please sign in to comment.