...

Source file src/edge-infra.dev/pkg/edge/api/graphqlhelpers/helpers_test.go

Documentation: edge-infra.dev/pkg/edge/api/graphqlhelpers

     1  package graphqlhelpers
     2  
     3  import (
     4  	"bytes"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/99designs/gqlgen/graphql"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/vektah/gqlparser/v2/ast"
    11  	"github.com/vektah/gqlparser/v2/formatter"
    12  	"github.com/vektah/gqlparser/v2/gqlerror"
    13  )
    14  
    15  func TestGetOperation(t *testing.T) {
    16  	queryOp := ast.Query
    17  	mutationOp := ast.Mutation
    18  	subscriptionOp := ast.Subscription
    19  	testCases := []struct {
    20  		title string
    21  		rctx  *graphql.OperationContext
    22  		op    *ast.Operation
    23  	}{
    24  		{
    25  			title: "Test Case One - Empty Context",
    26  			rctx:  &graphql.OperationContext{},
    27  			op:    nil,
    28  		},
    29  		{
    30  			title: "Test Case Two - Nil Context",
    31  			rctx:  nil,
    32  			op:    nil,
    33  		},
    34  		{
    35  			title: "Test Case Three - Query Context",
    36  			rctx: &graphql.OperationContext{
    37  				Operation: &ast.OperationDefinition{
    38  					Operation: ast.Query,
    39  					Name:      "GetUsersQuery",
    40  				},
    41  			},
    42  			op: &queryOp,
    43  		},
    44  		{
    45  			title: "Test Case Four - Mutation Context",
    46  			rctx: &graphql.OperationContext{
    47  				Operation: &ast.OperationDefinition{
    48  					Operation: ast.Mutation,
    49  					Name:      "LoginUserMutation",
    50  				},
    51  			},
    52  			op: &mutationOp,
    53  		},
    54  		{
    55  			title: "Test Case Five - Subscription Context",
    56  			rctx: &graphql.OperationContext{
    57  				Operation: &ast.OperationDefinition{
    58  					Operation: ast.Subscription,
    59  					Name:      "GetPollsSubscription",
    60  				},
    61  			},
    62  			op: &subscriptionOp,
    63  		},
    64  	}
    65  	for _, testCase := range testCases {
    66  		t.Run(testCase.title, func(t *testing.T) {
    67  			op := GetOperation(testCase.rctx)
    68  			assert.Equal(t, testCase.op, op)
    69  		})
    70  	}
    71  }
    72  
    73  func TestGetRawQuery(t *testing.T) {
    74  	queryOp := ast.Query
    75  	mutationOp := ast.Mutation
    76  	testCases := []struct {
    77  		title string
    78  		rctx  *graphql.OperationContext
    79  		op    *ast.Operation
    80  	}{
    81  		{
    82  			title: "Test Case One - Query Raw Query",
    83  			rctx: &graphql.OperationContext{
    84  				Operation: &ast.OperationDefinition{
    85  					Operation: ast.Query,
    86  					Name:      "GetUsersQuery",
    87  				},
    88  				RawQuery: `
    89  				query GetUsersQuery {
    90  					users {
    91  					  email
    92  					  username
    93  					  fullName
    94  					  familyName
    95  					  givenName
    96  					  status
    97  					}
    98  				}
    99  				`,
   100  			},
   101  			op: &queryOp,
   102  		},
   103  		{
   104  			title: "Test Case Two - Mutation Raw Query",
   105  			rctx: &graphql.OperationContext{
   106  				Operation: &ast.OperationDefinition{
   107  					Operation: ast.Mutation,
   108  					Name:      "LoginUserMutation",
   109  				},
   110  				RawQuery: `
   111  				mutation MyMutation {
   112  					login(organization: "test-org", password: "123456", username: "test") {
   113  					  firstName
   114  					  fullName
   115  					  roles
   116  					  organization
   117  					  credentialsExpired
   118  					  sessionTime
   119  					  token
   120  					}
   121  				}				  
   122  				`,
   123  			},
   124  			op: &mutationOp,
   125  		},
   126  	}
   127  	for _, testCase := range testCases {
   128  		t.Run(testCase.title, func(t *testing.T) {
   129  			query := GetRawQuery(testCase.rctx)
   130  			assert.Equal(t, testCase.rctx.RawQuery, query)
   131  		})
   132  	}
   133  }
   134  
   135  func TestGetResponseStatus(t *testing.T) {
   136  	testCases := []struct {
   137  		title  string
   138  		resp   *graphql.Response
   139  		status string
   140  	}{
   141  		{
   142  			title:  "Test Case One - Nil Response",
   143  			resp:   nil,
   144  			status: "Unknown",
   145  		},
   146  		{
   147  			title:  "Test Case Two - Empty Response",
   148  			resp:   &graphql.Response{},
   149  			status: "Success",
   150  		},
   151  		{
   152  			title: "Test Case Three - Errors and No Data Response",
   153  			resp: &graphql.Response{
   154  				Errors: gqlerror.List{
   155  					&gqlerror.Error{
   156  						Message: "error no rows found for banners",
   157  					},
   158  					&gqlerror.Error{
   159  						Message: "error no rows found for clusters",
   160  					},
   161  				},
   162  				Data: []byte("null"),
   163  			},
   164  			status: "Failure",
   165  		},
   166  		{
   167  			title: "Test Case Four - Errors and Data Response",
   168  			resp: &graphql.Response{
   169  				Errors: gqlerror.List{
   170  					&gqlerror.Error{
   171  						Message: "error no rows found for banners",
   172  					},
   173  					&gqlerror.Error{
   174  						Message: "error no rows found for clusters",
   175  					},
   176  				},
   177  				Data: []byte("hello"),
   178  			},
   179  			status: "Partial Failure",
   180  		},
   181  		{
   182  			title: "Test Case Five - Data and No Error Response",
   183  			resp: &graphql.Response{
   184  				Data: []byte("hello"),
   185  			},
   186  			status: "Success",
   187  		},
   188  	}
   189  	for _, testCase := range testCases {
   190  		t.Run(testCase.title, func(t *testing.T) {
   191  			status := GetResponseStatus(testCase.resp)
   192  			assert.Equal(t, testCase.status, status)
   193  		})
   194  	}
   195  }
   196  
   197  func TestUpdateQueryWithVariables(t *testing.T) {
   198  	testcases := []struct {
   199  		title      string
   200  		variables  map[string]interface{}
   201  		rawquery   string
   202  		expected   string
   203  		queryNames []string
   204  	}{
   205  		{
   206  			title:    "Test Case 1 - String Variables",
   207  			rawquery: "mutation login($username: String!, $password: String!, $organization: String!) {\n  login(username: $username, password: $password, organization: $organization) {\n    fullName\n    firstName\n    credentialsExpired\n    token\n    __typename\n  }\n}\n",
   208  			expected: `{"organization":"\"test-org\"","password":"\"123456\"","username":"\"test-user\""}`,
   209  			variables: map[string]interface{}{
   210  				"USERNAME":     "test-user",
   211  				"PASSWORD":     "123456",
   212  				"ORGANIZATION": "test-org",
   213  			},
   214  			queryNames: []string{
   215  				"login",
   216  			},
   217  		},
   218  		{
   219  			title:    "Test Case 2 - Object Variables",
   220  			rawquery: "mutation createLabel($newLabel: LabelInput!) {\n  createLabel(newLabel: $newLabel)\n}\n",
   221  			expected: `{"newLabel":"{color:\"#000\",visible:true,editable:true,unique:false,bannerEdgeId:\"4ba7b765-68e2-453e-a2f5-787dca9b30f7\",description:\"\",type:\"\",key:\"test\"}"}`,
   222  			variables: map[string]interface{}{
   223  				"NEWLABEL": map[string]interface{}{
   224  					"key":          "test",
   225  					"color":        "#000",
   226  					"visible":      true,
   227  					"editable":     true,
   228  					"unique":       false,
   229  					"bannerEdgeId": "4ba7b765-68e2-453e-a2f5-787dca9b30f7",
   230  					"description":  "",
   231  					"type":         "",
   232  				},
   233  			},
   234  			queryNames: []string{
   235  				"createLabel",
   236  			},
   237  		},
   238  		{
   239  			title:    "Test Case 3 - Array Variables",
   240  			rawquery: "mutation assignUserRoles($roles: RoleInput!) {\n  assignUserRoles(roles: $roles)\n}\n",
   241  			expected: `{"roles":"[\"EDGE_ORG_ADMIN\",\"EDGE_BANNER_ADMIN\"]"}`,
   242  			variables: map[string]interface{}{
   243  				"ROLES": []string{
   244  					"EDGE_ORG_ADMIN",
   245  					"EDGE_BANNER_ADMIN",
   246  				},
   247  			},
   248  			queryNames: []string{
   249  				"assignUserRoles",
   250  			},
   251  		},
   252  		{
   253  			title:    "Test Case 4 - Object Variables with Sub List",
   254  			rawquery: "mutation createLabel($newLabel: LabelInput!) {\n  createLabel(newLabel: $newLabel)\n}\n",
   255  			expected: `{"newLabel":"{unique:false,bannerEdgeId:\"4ba7b765-68e2-453e-a2f5-787dca9b30f7\",description:\"\",parent:{labelEdgeId:\"4ba7b765-68e2-453e-a2f5-787dca9b32B1\"},key:\"test\",color:\"#000\",visible:true,editable:true}"}`,
   256  			variables: map[string]interface{}{
   257  				"NEWLABEL": map[string]interface{}{
   258  					"key":          "test",
   259  					"color":        "#000",
   260  					"visible":      true,
   261  					"editable":     true,
   262  					"unique":       false,
   263  					"bannerEdgeId": "4ba7b765-68e2-453e-a2f5-787dca9b30f7",
   264  					"description":  "",
   265  					"parent": map[string]interface{}{
   266  						"labelEdgeId": "4ba7b765-68e2-453e-a2f5-787dca9b32B1",
   267  					},
   268  				},
   269  			},
   270  			queryNames: []string{
   271  				"createLabel",
   272  			},
   273  		},
   274  		{
   275  			title:    "Test Case 5 - Multiple Variable Types",
   276  			rawquery: "mutation user($username: String!, $age: String!, $nickname: String, $roles: RoleInput, $pins: PinInput, $extra: ExtraInput) {\n  user(username: $username, age: $age, nickname: $nickname, roles: $roles, pins: $pins, extra: $extra) {\n    fullName\n    firstName\n    credentialsExpired\n    token\n    __typename\n  }\n}\n",
   277  			expected: `{"age":"10","extra":"[1,\"hello\",2.4,{one:\"two\",two:3},[1,2,3],[\"hello\",[23,43],[\"Colors\",[\"Yellow\",\"Red\",\"Blue\"]]]]","nickname":"nickname","pins":"[20,30,40]","roles":"[\"EDGE_ORG_ADMIN\",\"EDGE_BANNER_ADMIN\"]","username":"\"test-user\""}`,
   278  			variables: map[string]interface{}{
   279  				"USERNAME": "test-user",
   280  				"AGE":      10,
   281  				"NICKNAME": nil,
   282  				"ROLES": []string{
   283  					"EDGE_ORG_ADMIN",
   284  					"EDGE_BANNER_ADMIN",
   285  				},
   286  				"PINS": []int{
   287  					20,
   288  					30,
   289  					40,
   290  				},
   291  				"EXTRA": []any{
   292  					1,
   293  					"hello",
   294  					2.4,
   295  					nil,
   296  					map[string]interface{}{
   297  						"one": "two",
   298  						"two": 3,
   299  					},
   300  					[]int{
   301  						1,
   302  						2,
   303  						3,
   304  					},
   305  					[]any{
   306  						"hello",
   307  						[]int{
   308  							23,
   309  							43,
   310  						},
   311  						[]any{
   312  							"Colors",
   313  							[]string{
   314  								"Yellow",
   315  								"Red",
   316  								"Blue",
   317  							},
   318  						},
   319  					},
   320  				},
   321  			},
   322  			queryNames: []string{
   323  				"user",
   324  			},
   325  		},
   326  	}
   327  	for _, testcase := range testcases {
   328  		t.Run(testcase.title, func(t *testing.T) {
   329  			schema, err := ParseQuery(testcase.rawquery)
   330  			assert.NoError(t, err)
   331  			UpdateQueryWithVariables(schema, testcase.variables)
   332  			buf := bytes.NewBuffer(nil)
   333  			formatter.NewFormatter(buf).FormatQueryDocument(schema)
   334  			updatedschema, err := ParseQuery(buf.String())
   335  			assert.NoError(t, err)
   336  			queryNames := GetQueryNames(updatedschema)
   337  			assert.Equal(t, testcase.queryNames, queryNames)
   338  			params := GetParams(nil, updatedschema)
   339  			for k := range params {
   340  				_, exists := testcase.variables[strings.ToUpper(k)]
   341  				assert.True(t, exists)
   342  			}
   343  		})
   344  	}
   345  }
   346  

View as plain text