This is an automated email from the ASF dual-hosted git repository.

srijeet0406 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 47a9e37bbb Use Topology type parameter for Topology API TestCase 
(#7116)
47a9e37bbb is described below

commit 47a9e37bbbc1f75dc4e7b9005b06bd18531e2a79
Author: Zach Hoffman <[email protected]>
AuthorDate: Fri Oct 7 21:03:48 2022 +0000

    Use Topology type parameter for Topology API TestCase (#7116)
    
    * API and struct-agnistic TestData and TestCase
    
    * Use Topology type parameter for Topology API TestCase
    
    * Use Topology type parameter for Topology API V3TestCase
    
    * Remove unused TO client session type from type constraint
---
 traffic_ops/testing/api/utils/utils.go        |  33 +++
 traffic_ops/testing/api/v3/topologies_test.go | 276 ++++++++++++------------
 traffic_ops/testing/api/v4/topologies_test.go | 300 +++++++++++++-------------
 traffic_ops/testing/api/v5/topologies_test.go | 300 +++++++++++++-------------
 4 files changed, 459 insertions(+), 450 deletions(-)

diff --git a/traffic_ops/testing/api/utils/utils.go 
b/traffic_ops/testing/api/utils/utils.go
index f08e9ce76b..6b72505675 100644
--- a/traffic_ops/testing/api/utils/utils.go
+++ b/traffic_ops/testing/api/utils/utils.go
@@ -116,6 +116,16 @@ type V3TestData struct {
        Expectations   []CkReqFunc
 }
 
+// V3TestDataT represents the data needed for testing the v3 api endpoints.
+type V3TestDataT[B any] struct {
+       EndpointId     func() int
+       ClientSession  *v3client.Session
+       RequestParams  url.Values
+       RequestHeaders http.Header
+       RequestBody    B
+       Expectations   []CkReqFunc
+}
+
 // V4TestData represents the data needed for testing the v4 api endpoints.
 type V4TestData struct {
        EndpointId    func() int
@@ -134,10 +144,31 @@ type V5TestData struct {
        Expectations  []CkReqFunc
 }
 
+type clientSession interface {
+       v4client.Session | v5client.Session
+}
+
+type requestOpts interface {
+       v4client.RequestOptions | v5client.RequestOptions
+}
+
+// TestData represents the data needed for testing the api endpoints.
+type TestData[C clientSession, R requestOpts, B any] struct {
+       EndpointId    func() int
+       ClientSession *C
+       RequestOpts   R
+       RequestBody   B
+       Expectations  []CkReqFunc
+}
+
 // V3TestCase is the type of the V3TestData struct.
 // Uses nested map to represent the method being tested and the test's 
description.
 type V3TestCase map[string]map[string]V3TestData
 
+// V3TestCaseT is the type of the V3TestDataT struct.
+// Uses nested map to represent the method being tested and the test's 
description.
+type V3TestCaseT[B any] map[string]map[string]V3TestDataT[B]
+
 // V4TestCase is the type of the V4TestData struct.
 // Uses nested map to represent the method being tested and the test's 
description.
 type V4TestCase map[string]map[string]V4TestData
@@ -147,6 +178,8 @@ type V4TestCase map[string]map[string]V4TestData
 // Uses nested map to represent the method being tested and the test's 
description.
 type V5TestCase map[string]map[string]V5TestData
 
+type TestCase[C clientSession, R requestOpts, B any] 
map[string]map[string]TestData[C, R, B]
+
 // CkReqFunc defines the reusable signature for all other functions that 
perform checks.
 // Common parameters that are checked include the request's info, response, 
alerts, and errors.
 type CkReqFunc func(*testing.T, toclientlib.ReqInf, interface{}, tc.Alerts, 
error)
diff --git a/traffic_ops/testing/api/v3/topologies_test.go 
b/traffic_ops/testing/api/v3/topologies_test.go
index 5b56b4cdfe..667477940b 100644
--- a/traffic_ops/testing/api/v3/topologies_test.go
+++ b/traffic_ops/testing/api/v3/topologies_test.go
@@ -20,7 +20,6 @@ package v3
  */
 
 import (
-       "encoding/json"
        "net/http"
        "net/url"
        "testing"
@@ -34,7 +33,7 @@ import (
 func TestTopologies(t *testing.T) {
        WithObjs(t, []TCObj{Tenants, Users, Types, CacheGroups, CDNs, 
Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, Servers, 
ServerCapabilities, ServerServerCapabilities, Topologies, ServiceCategories, 
DeliveryServices, DeliveryServicesRequiredCapabilities, 
DeliveryServiceServerAssignments}, func() {
 
-               methodTests := utils.V3TestCase{
+               methodTests := utils.V3TestCaseT[tc.Topology]{
                        "GET": {
                                "OK when VALID REQUEST": {
                                        ClientSession: TOSession,
@@ -44,48 +43,48 @@ func TestTopologies(t *testing.T) {
                        "POST": {
                                "OK when MISSING DESCRIPTION": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-missing-description",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-missing-description",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
                                },
                                "BAD REQUEST when EMPTY NODES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-no-nodes",
-                                               "nodes": 
[]map[string]interface{}{},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-no-nodes",
+                                               Nodes: []tc.TopologyNode{},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when NODE PARENT of ITSELF": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "self-parent",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{0}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "self-parent",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{0}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when TOO MANY PARENTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "too-many-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "too-many-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"secondaryCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"secondaryCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0, 1, 2},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0, 1, 2},
                                                        },
                                                },
                                        },
@@ -93,16 +92,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when EDGE_LOC PARENTS MID_LOC": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "edge-parents-mid",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "edge-parents-mid",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -110,20 +109,20 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLICAL NODES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "cyclical-nodes",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "cyclical-nodes",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{1, 2},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{1, 2},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{2},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{2},
                                                        },
                                                        {
-                                                               "cachegroup": 
"secondaryCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"secondaryCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                },
                                        },
@@ -131,20 +130,20 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLES ACROSS TOPOLOGIES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "cyclical-nodes-tiered",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "cyclical-nodes-tiered",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -152,16 +151,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLICAL NODES BUT EMPTY 
CACHE GROUPS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": 
"cyclical-nodes-nontopology",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: 
"cyclical-nodes-nontopology",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"edge-parent1",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"edge-parent1",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"has-edge-parent1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"has-edge-parent1",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -169,56 +168,56 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when OUT-OF-BOUNDS PARENT INDEX": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "outofbounds",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{7}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "outofbounds",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{7}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP DOESNT EXIST": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-nonexistent-cachegroup",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "doesntexist", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-nonexistent-cachegroup",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "doesntexist", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when MISSING NAME": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "description": "missing name",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Description: "missing name",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when ALREADY EXISTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "mso-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "mso-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP has NO SERVERS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-empty-cg",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "noServers", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-empty-cg",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "noServers", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when DUPLICATE PARENTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": 
"topology-duplicate-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: 
"topology-duplicate-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0, 0},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0, 0},
                                                        },
                                                },
                                        },
@@ -226,16 +225,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when ORG_LOC is CHILD NODE": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-orgloc-child",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-orgloc-child",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"multiOriginCachegroup",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"multiOriginCachegroup",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -243,25 +242,25 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when LEAF NODE is a MID_LOC": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-midloc-leaf",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "parentCachegroup", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-midloc-leaf",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "parentCachegroup", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "WARNING LEVEL ALERT when MID PARENTING EDGE": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"topology-mid-parent",
-                                               "description": "mid parent to 
edge",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name:        
"topology-mid-parent",
+                                               Description: "mid parent to 
edge",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -272,10 +271,10 @@ func TestTopologies(t *testing.T) {
                                "OK when VALID request": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"top-with-no-mids"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"top-with-no-mids-updated",
-                                               "description": "Updating 
fields",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "cachegroup2", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:        
"top-with-no-mids-updated",
+                                               Description: "Updating fields",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "cachegroup2", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
                                                
validateTopologiesUpdateCreateFields(map[string]interface{}{"Name": 
"top-with-no-mids-updated", "Description": "Updating fields"})),
@@ -283,61 +282,61 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when OUT-OF-BOUNDS PARENT INDEX": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"another-topology"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-invalid-parent",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{100}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-invalid-parent",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{100}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP has NO SERVERS": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"another-topology"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-empty-cg",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "noServers", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-empty-cg",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "noServers", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP SERVERS DO NOT 
HAVE REQUIRED CAPABILITIES": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"top-for-ds-req"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "top-for-ds-req",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "top-for-ds-req",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when NODE PARENT of ITSELF": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"another-topology"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "another-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{0}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "another-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{0}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP HAS NO SERVERS IN 
TOPOLOGY CDN": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"top-used-by-cdn1-and-cdn2"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"top-used-by-cdn1-and-cdn2",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cdn1-only", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"top-used-by-cdn1-and-cdn2",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cdn1-only", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when ORG_LOC is CHILD NODE": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"another-topology"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-orgloc-child",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-orgloc-child",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"multiOriginCachegroup",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"multiOriginCachegroup",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -346,26 +345,26 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when LEAF NODE is a MID_LOC": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"another-topology"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"topology-child-midloc",
-                                               "description": "child mid_loc",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "parentCachegroup", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:        
"topology-child-midloc",
+                                               Description: "child mid_loc",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "parentCachegroup", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when DUPLICATE PARENTS": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"another-topology"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-same-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-same-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{0, 0},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{0, 0},
                                                        },
                                                },
                                        },
@@ -374,9 +373,9 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when REMOVING ORG ASSIGNED DS": {
                                        ClientSession: TOSession,
                                        RequestParams: url.Values{"name": 
{"mso-topology"}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "mso-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "topology-edge-cg-01", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "mso-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "topology-edge-cg-01", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
@@ -386,14 +385,7 @@ func TestTopologies(t *testing.T) {
                for method, testCases := range methodTests {
                        t.Run(method, func(t *testing.T) {
                                for name, testCase := range testCases {
-                                       topology := tc.Topology{}
-
-                                       if testCase.RequestBody != nil {
-                                               dat, err := 
json.Marshal(testCase.RequestBody)
-                                               assert.NoError(t, err, "Error 
occurred when marshalling request body: %v", err)
-                                               err = json.Unmarshal(dat, 
&topology)
-                                               assert.NoError(t, err, "Error 
occurred when unmarshalling request body: %v", err)
-                                       }
+                                       topology := testCase.RequestBody
 
                                        switch method {
                                        case "GET", "GET AFTER CHANGES":
diff --git a/traffic_ops/testing/api/v4/topologies_test.go 
b/traffic_ops/testing/api/v4/topologies_test.go
index 9e8850beea..6ccd639e82 100644
--- a/traffic_ops/testing/api/v4/topologies_test.go
+++ b/traffic_ops/testing/api/v4/topologies_test.go
@@ -20,7 +20,6 @@ package v4
  */
 
 import (
-       "encoding/json"
        "net/http"
        "net/url"
        "testing"
@@ -43,7 +42,7 @@ func TestTopologies(t *testing.T) {
                currentTimeRFC := currentTime.Format(time.RFC1123)
                tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
 
-               methodTests := utils.V4TestCase{
+               methodTests := utils.TestCase[client.Session, 
client.RequestOptions, tc.Topology]{
                        "GET": {
                                "NOT MODIFIED when NO CHANGES made": {
                                        ClientSession: TOSession,
@@ -68,48 +67,48 @@ func TestTopologies(t *testing.T) {
                        "POST": {
                                "OK when MISSING DESCRIPTION": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-missing-description",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-missing-description",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
                                },
                                "BAD REQUEST when EMPTY NODES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-no-nodes",
-                                               "nodes": 
[]map[string]interface{}{},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-no-nodes",
+                                               Nodes: []tc.TopologyNode{},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when NODE PARENT of ITSELF": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "self-parent",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{0}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "self-parent",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{0}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when TOO MANY PARENTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "too-many-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "too-many-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"secondaryCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"secondaryCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0, 1, 2},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0, 1, 2},
                                                        },
                                                },
                                        },
@@ -117,16 +116,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when EDGE_LOC PARENTS MID_LOC": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "edge-parents-mid",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "edge-parents-mid",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -134,20 +133,20 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLICAL NODES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "cyclical-nodes",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "cyclical-nodes",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{1, 2},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{1, 2},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{2},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{2},
                                                        },
                                                        {
-                                                               "cachegroup": 
"secondaryCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"secondaryCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                },
                                        },
@@ -155,20 +154,20 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLES ACROSS TOPOLOGIES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "cyclical-nodes-tiered",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "cyclical-nodes-tiered",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -176,16 +175,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLICAL NODES BUT EMPTY 
CACHE GROUPS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": 
"cyclical-nodes-nontopology",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: 
"cyclical-nodes-nontopology",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"edge-parent1",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"edge-parent1",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"has-edge-parent1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"has-edge-parent1",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -193,56 +192,56 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when OUT-OF-BOUNDS PARENT INDEX": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "outofbounds",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{7}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "outofbounds",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{7}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP DOESNT EXIST": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-nonexistent-cachegroup",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "doesntexist", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-nonexistent-cachegroup",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "doesntexist", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when MISSING NAME": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "description": "missing name",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Description: "missing name",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when ALREADY EXISTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "mso-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "mso-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP has NO SERVERS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-empty-cg",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "noServers", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-empty-cg",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "noServers", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when DUPLICATE PARENTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": 
"topology-duplicate-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: 
"topology-duplicate-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0, 0},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0, 0},
                                                        },
                                                },
                                        },
@@ -250,16 +249,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when ORG_LOC is CHILD NODE": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-orgloc-child",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-orgloc-child",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"multiOriginCachegroup",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"multiOriginCachegroup",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -267,25 +266,25 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when LEAF NODE is a MID_LOC": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-midloc-leaf",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "parentCachegroup", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-midloc-leaf",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "parentCachegroup", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "WARNING LEVEL ALERT when MID PARENTING EDGE": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"topology-mid-parent",
-                                               "description": "mid parent to 
edge",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name:        
"topology-mid-parent",
+                                               Description: "mid parent to 
edge",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -293,9 +292,9 @@ func TestTopologies(t *testing.T) {
                                },
                                "FORBIDDEN when READ-ONLY USER": {
                                        ClientSession: readOnlyUserSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-ro",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-ro",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
                                },
@@ -304,10 +303,10 @@ func TestTopologies(t *testing.T) {
                                "OK when VALID request": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"top-with-no-mids"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"top-with-no-mids-updated",
-                                               "description": "Updating 
fields",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "cachegroup2", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:        
"top-with-no-mids-updated",
+                                               Description: "Updating fields",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "cachegroup2", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
                                                
validateTopologiesUpdateCreateFields(map[string]interface{}{"Name": 
"top-with-no-mids-updated", "Description": "Updating fields"})),
@@ -315,61 +314,61 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when OUT-OF-BOUNDS PARENT INDEX": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-invalid-parent",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{100}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-invalid-parent",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{100}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP has NO SERVERS": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-empty-cg",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "noServers", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-empty-cg",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "noServers", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP SERVERS DO NOT 
HAVE REQUIRED CAPABILITIES": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": {"top-for-ds-req"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "top-for-ds-req",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "top-for-ds-req",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when NODE PARENT of ITSELF": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "another-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{0}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "another-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{0}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP HAS NO SERVERS IN 
TOPOLOGY CDN": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"top-used-by-cdn1-and-cdn2"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"top-used-by-cdn1-and-cdn2",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cdn1-only", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"top-used-by-cdn1-and-cdn2",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cdn1-only", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when ORG_LOC is CHILD NODE": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-orgloc-child",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-orgloc-child",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"multiOriginCachegroup",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"multiOriginCachegroup",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -378,26 +377,26 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when LEAF NODE is a MID_LOC": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"topology-child-midloc",
-                                               "description": "child mid_loc",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "parentCachegroup", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:        
"topology-child-midloc",
+                                               Description: "child mid_loc",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "parentCachegroup", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when DUPLICATE PARENTS": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-same-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-same-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{0, 0},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{0, 0},
                                                        },
                                                },
                                        },
@@ -406,18 +405,18 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when REMOVING ORG ASSIGNED DS": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": {"mso-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "mso-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "topology-edge-cg-01", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "mso-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "topology-edge-cg-01", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "FORBIDDEN when READ-ONLY USER": {
                                        ClientSession: readOnlyUserSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-ro",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-ro",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
                                },
@@ -427,9 +426,9 @@ func TestTopologies(t *testing.T) {
                                                QueryParameters: 
url.Values{"name": {"another-topology"}},
                                                Header:          
http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
                                        },
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "another-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "another-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), 
utils.HasStatus(http.StatusPreconditionFailed)),
                                },
@@ -439,9 +438,9 @@ func TestTopologies(t *testing.T) {
                                                QueryParameters: 
url.Values{"name": {"another-topology"}},
                                                Header:          
http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
                                        },
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "another-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "another-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), 
utils.HasStatus(http.StatusPreconditionFailed)),
                                },
@@ -468,14 +467,7 @@ func TestTopologies(t *testing.T) {
                for method, testCases := range methodTests {
                        t.Run(method, func(t *testing.T) {
                                for name, testCase := range testCases {
-                                       topology := tc.Topology{}
-
-                                       if testCase.RequestBody != nil {
-                                               dat, err := 
json.Marshal(testCase.RequestBody)
-                                               assert.NoError(t, err, "Error 
occurred when marshalling request body: %v", err)
-                                               err = json.Unmarshal(dat, 
&topology)
-                                               assert.NoError(t, err, "Error 
occurred when unmarshalling request body: %v", err)
-                                       }
+                                       topology := testCase.RequestBody
 
                                        switch method {
                                        case "GET", "GET AFTER CHANGES":
diff --git a/traffic_ops/testing/api/v5/topologies_test.go 
b/traffic_ops/testing/api/v5/topologies_test.go
index 40fc852d96..ca436999d4 100644
--- a/traffic_ops/testing/api/v5/topologies_test.go
+++ b/traffic_ops/testing/api/v5/topologies_test.go
@@ -20,7 +20,6 @@ package v5
  */
 
 import (
-       "encoding/json"
        "net/http"
        "net/url"
        "testing"
@@ -43,7 +42,7 @@ func TestTopologies(t *testing.T) {
                currentTimeRFC := currentTime.Format(time.RFC1123)
                tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
 
-               methodTests := utils.V5TestCase{
+               methodTests := utils.TestCase[client.Session, 
client.RequestOptions, tc.Topology]{
                        "GET": {
                                "NOT MODIFIED when NO CHANGES made": {
                                        ClientSession: TOSession,
@@ -68,48 +67,48 @@ func TestTopologies(t *testing.T) {
                        "POST": {
                                "OK when MISSING DESCRIPTION": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-missing-description",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-missing-description",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
                                },
                                "BAD REQUEST when EMPTY NODES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-no-nodes",
-                                               "nodes": 
[]map[string]interface{}{},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-no-nodes",
+                                               Nodes: []tc.TopologyNode{},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when NODE PARENT of ITSELF": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "self-parent",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{0}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "self-parent",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{0}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when TOO MANY PARENTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "too-many-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "too-many-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"secondaryCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"secondaryCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0, 1, 2},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0, 1, 2},
                                                        },
                                                },
                                        },
@@ -117,16 +116,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when EDGE_LOC PARENTS MID_LOC": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "edge-parents-mid",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "edge-parents-mid",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -134,20 +133,20 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLICAL NODES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "cyclical-nodes",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "cyclical-nodes",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{1, 2},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{1, 2},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{2},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{2},
                                                        },
                                                        {
-                                                               "cachegroup": 
"secondaryCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"secondaryCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                },
                                        },
@@ -155,20 +154,20 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLES ACROSS TOPOLOGIES": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "cyclical-nodes-tiered",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "cyclical-nodes-tiered",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"parentCachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -176,16 +175,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when CYCLICAL NODES BUT EMPTY 
CACHE GROUPS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": 
"cyclical-nodes-nontopology",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: 
"cyclical-nodes-nontopology",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"edge-parent1",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"edge-parent1",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"has-edge-parent1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"has-edge-parent1",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -193,56 +192,56 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when OUT-OF-BOUNDS PARENT INDEX": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "outofbounds",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{7}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "outofbounds",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{7}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP DOESNT EXIST": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-nonexistent-cachegroup",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "doesntexist", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-nonexistent-cachegroup",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "doesntexist", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when MISSING NAME": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "description": "missing name",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Description: "missing name",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when ALREADY EXISTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "mso-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "mso-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP has NO SERVERS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-empty-cg",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "noServers", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-empty-cg",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "noServers", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when DUPLICATE PARENTS": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": 
"topology-duplicate-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: 
"topology-duplicate-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"parentCachegroup",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"parentCachegroup",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{0, 0},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{0, 0},
                                                        },
                                                },
                                        },
@@ -250,16 +249,16 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when ORG_LOC is CHILD NODE": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-orgloc-child",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-orgloc-child",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"multiOriginCachegroup",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"multiOriginCachegroup",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -267,25 +266,25 @@ func TestTopologies(t *testing.T) {
                                },
                                "BAD REQUEST when LEAF NODE is a MID_LOC": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-midloc-leaf",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "parentCachegroup", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-midloc-leaf",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "parentCachegroup", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "WARNING LEVEL ALERT when MID PARENTING EDGE": {
                                        ClientSession: TOSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"topology-mid-parent",
-                                               "description": "mid parent to 
edge",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name:        
"topology-mid-parent",
+                                               Description: "mid parent to 
edge",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{1},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{1},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{},
                                                        },
                                                },
                                        },
@@ -293,9 +292,9 @@ func TestTopologies(t *testing.T) {
                                },
                                "FORBIDDEN when READ-ONLY USER": {
                                        ClientSession: readOnlyUserSession,
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-ro",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-ro",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
                                },
@@ -304,10 +303,10 @@ func TestTopologies(t *testing.T) {
                                "OK when VALID request": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"top-with-no-mids"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"top-with-no-mids-updated",
-                                               "description": "Updating 
fields",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "cachegroup2", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:        
"top-with-no-mids-updated",
+                                               Description: "Updating fields",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "cachegroup2", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
                                                
validateTopologiesUpdateCreateFields(map[string]interface{}{"Name": 
"top-with-no-mids-updated", "Description": "Updating fields"})),
@@ -315,61 +314,61 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when OUT-OF-BOUNDS PARENT INDEX": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"topology-invalid-parent",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{100}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"topology-invalid-parent",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{100}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP has NO SERVERS": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-empty-cg",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "noServers", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-empty-cg",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "noServers", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP SERVERS DO NOT 
HAVE REQUIRED CAPABILITIES": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": {"top-for-ds-req"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "top-for-ds-req",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "top-for-ds-req",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when NODE PARENT of ITSELF": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "another-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{0}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "another-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{0}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when CACHEGROUP HAS NO SERVERS IN 
TOPOLOGY CDN": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"top-used-by-cdn1-and-cdn2"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  
"top-used-by-cdn1-and-cdn2",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cdn1-only", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  
"top-used-by-cdn1-and-cdn2",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cdn1-only", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when ORG_LOC is CHILD NODE": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-orgloc-child",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-orgloc-child",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"multiOriginCachegroup",
-                                                               "parents":    
[]int{0},
+                                                               Cachegroup: 
"multiOriginCachegroup",
+                                                               Parents:    
[]int{0},
                                                        },
                                                },
                                        },
@@ -378,26 +377,26 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when LEAF NODE is a MID_LOC": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":        
"topology-child-midloc",
-                                               "description": "child mid_loc",
-                                               "nodes":       
[]map[string]interface{}{{"cachegroup": "parentCachegroup", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:        
"topology-child-midloc",
+                                               Description: "child mid_loc",
+                                               Nodes:       
[]tc.TopologyNode{{Cachegroup: "parentCachegroup", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "BAD REQUEST when DUPLICATE PARENTS": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name": "topology-same-parents",
-                                               "nodes": 
[]map[string]interface{}{
+                                       RequestBody: tc.Topology{
+                                               Name: "topology-same-parents",
+                                               Nodes: []tc.TopologyNode{
                                                        {
-                                                               "cachegroup": 
"cachegroup1",
-                                                               "parents":    
[]int{},
+                                                               Cachegroup: 
"cachegroup1",
+                                                               Parents:    
[]int{},
                                                        },
                                                        {
-                                                               "cachegroup": 
"cachegroup2",
-                                                               "parents":    
[]int{0, 0},
+                                                               Cachegroup: 
"cachegroup2",
+                                                               Parents:    
[]int{0, 0},
                                                        },
                                                },
                                        },
@@ -406,18 +405,18 @@ func TestTopologies(t *testing.T) {
                                "BAD REQUEST when REMOVING ORG ASSIGNED DS": {
                                        ClientSession: TOSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": {"mso-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "mso-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "topology-edge-cg-01", "parents": 
[]int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "mso-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "topology-edge-cg-01", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
                                },
                                "FORBIDDEN when READ-ONLY USER": {
                                        ClientSession: readOnlyUserSession,
                                        RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"name": 
{"another-topology"}}},
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "topology-ro",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "topology-ro",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
                                },
@@ -427,9 +426,9 @@ func TestTopologies(t *testing.T) {
                                                QueryParameters: 
url.Values{"name": {"another-topology"}},
                                                Header:          
http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
                                        },
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "another-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "another-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), 
utils.HasStatus(http.StatusPreconditionFailed)),
                                },
@@ -439,9 +438,9 @@ func TestTopologies(t *testing.T) {
                                                QueryParameters: 
url.Values{"name": {"another-topology"}},
                                                Header:          
http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
                                        },
-                                       RequestBody: map[string]interface{}{
-                                               "name":  "another-topology",
-                                               "nodes": 
[]map[string]interface{}{{"cachegroup": "cachegroup1", "parents": []int{}}},
+                                       RequestBody: tc.Topology{
+                                               Name:  "another-topology",
+                                               Nodes: 
[]tc.TopologyNode{{Cachegroup: "cachegroup1", Parents: []int{}}},
                                        },
                                        Expectations: 
utils.CkRequest(utils.HasError(), 
utils.HasStatus(http.StatusPreconditionFailed)),
                                },
@@ -468,14 +467,7 @@ func TestTopologies(t *testing.T) {
                for method, testCases := range methodTests {
                        t.Run(method, func(t *testing.T) {
                                for name, testCase := range testCases {
-                                       topology := tc.Topology{}
-
-                                       if testCase.RequestBody != nil {
-                                               dat, err := 
json.Marshal(testCase.RequestBody)
-                                               assert.NoError(t, err, "Error 
occurred when marshalling request body: %v", err)
-                                               err = json.Unmarshal(dat, 
&topology)
-                                               assert.NoError(t, err, "Error 
occurred when unmarshalling request body: %v", err)
-                                       }
+                                       topology := testCase.RequestBody
 
                                        switch method {
                                        case "GET", "GET AFTER CHANGES":

Reply via email to