Skip to content

Commit

Permalink
fix Mastercard#257 Creating a validation step when creating an obj so…
Browse files Browse the repository at this point in the history
… we can identify we are not getting a formatted JSON response object

If we get a response as a string or int we are assigning that response
as the id of the obj. We need to set the `id_attribute` to `*`
  • Loading branch information
S3B4SZ17 committed Mar 10, 2024
1 parent af260a3 commit f5fda96
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
31 changes: 30 additions & 1 deletion restapi/api_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,37 @@ func (obj *APIObject) createObject() error {
obj.apiClient.writeReturnsObject, obj.apiClient.createReturnsObject)
}
err = obj.updateState(resultString)

/* Checking if the response is not a normal JSON but probabbly an int or string and the id_attribute is set to '*'
Setting that response value as the ID */
var result interface{}
err = json.Unmarshal([]byte(resultString), &result)
if err != nil {
return fmt.Errorf("internal validation failed; couldnt unmarshal response from API: %s", err)
}

if _, ok := result.(map[string]interface{}); !ok {
/*Check for not json responses like plain strings or ints */
var id string
switch tp := result.(type) {
case string:
id = fmt.Sprintf("%v", result)
case float64:
id = fmt.Sprintf("%.0f", result)
default:
fmt.Printf("api_object.go: Falling default response type is '%T'\n", tp)
}

if obj.idAttribute == "*" {
if obj.debug {
log.Printf("api_object.go: Getting ID from response as id_attribute is set to '*'. Response is '%v'\n", result)
}
obj.id = id
}
}

/* Yet another failsafe. In case something terrible went wrong internally,
bail out so the user at least knows that the ID did not get set. */
bail out so the user at least knows that the ID did not get set. */
if obj.id == "" {
return fmt.Errorf("internal validation failed; object ID is not set, but *may* have been created; this should never happen")
}
Expand Down
47 changes: 47 additions & 0 deletions restapi/api_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,53 @@ func TestAPIObject(t *testing.T) {
}
})

/* Crete an oject with no JSON response, saving int or string as ID */
t.Run("create_object_no_json_response", func(t *testing.T) {
var err error
if testDebug {
log.Printf("api_object_test.go: Testing create_object() with no JSON response")
}

objectOpts := &apiObjectOpts{
path: "/api/objects",
debug: apiObjectDebug,
data: `{
"Test_case": "no_JSON_response",
"Id": "6",
"No_json": true,
"Name": "cat"
}`,
}
// Important to set the new idAttribute to "*" for non JSON responses
client.idAttribute = "*"

object, err := NewAPIObject(client, objectOpts)
if err != nil {
t.Fatalf("api_object_test.go: Failed to create new api_object")
}

err = object.createObject()
if err != nil {
t.Fatalf("api_object_test.go: Failed in create_object() test: %s", err)
}

if object.id != "6" {
t.Errorf("expected populated object id from creation to be %s but got %s", "6", object.id)
}

object.data["Name"] = "dog"
object.updateObject()

if object.data["Name"] != "dog" {
t.Fatalf("api_object_test.go: Failed to update 'Name' field. Expected it to be '%s' but it is '%s'\nFull obj: %+v\n", "dog", object.data["Name"], object)
}

if testDebug {
log.Printf("api_object_test.go: Object created %v", object)
}

})

if testDebug {
log.Println("api_object_test.go: Stopping HTTP server")
}
Expand Down

0 comments on commit f5fda96

Please sign in to comment.