Fix testhelper.deepDiffEqual (#374)

* Fix deepdiff comparison with maps

* Fix RemainingKeys function

* Fix unit tests

* Another fix of RemainingKeys

* RemainingKeys cleanup

* Simplifying RemainingKeys

* Revert continue on invalid. Fix broken tests

Related-PROD: PROD-28126

Change-Id: Ifc5afaf1278c7cff3a89b23a1fd1876aac1dff34
diff --git a/internal/util.go b/internal/util.go
index f7e10d2..8efb283 100644
--- a/internal/util.go
+++ b/internal/util.go
@@ -2,23 +2,31 @@
 
 import (
 	"reflect"
+	"strings"
 )
 
-// RemainingKeys will inspect a struct and compare it to a map. Any key that
-// is not defined in a JSON tag of the struct will be added to the extras map
-// and returned.
+// RemainingKeys will inspect a struct and compare it to a map. Any struct
+// field that does not have a JSON tag that matches a key in the map or
+// a matching lower-case field in the map will be returned as an extra.
 //
 // This is useful for determining the extra fields returned in response bodies
 // for resources that can contain an arbitrary or dynamic number of fields.
 func RemainingKeys(s interface{}, m map[string]interface{}) (extras map[string]interface{}) {
 	extras = make(map[string]interface{})
+	for k, v := range m {
+		extras[k] = v
+	}
+
 	valueOf := reflect.ValueOf(s)
 	typeOf := reflect.TypeOf(s)
 	for i := 0; i < valueOf.NumField(); i++ {
 		field := typeOf.Field(i)
-		tagValue := field.Tag.Get("json")
-		if _, ok := m[tagValue]; !ok {
-			extras[tagValue] = m[tagValue]
+
+		lowerField := strings.ToLower(field.Name)
+		delete(extras, lowerField)
+
+		if tagValue := field.Tag.Get("json"); tagValue != "" && tagValue != "-" {
+			delete(extras, tagValue)
 		}
 	}