github.com/weaviate/weaviate@v1.24.6/adapters/handlers/graphql/test/helper/mock_resolver.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package helper
    13  
    14  import (
    15  	"context"
    16  	"encoding/json"
    17  	"fmt"
    18  	"sync"
    19  	"testing"
    20  
    21  	"github.com/davecgh/go-spew/spew"
    22  	"github.com/stretchr/testify/assert"
    23  	"github.com/stretchr/testify/mock"
    24  	"github.com/stretchr/testify/require"
    25  	"github.com/tailor-inc/graphql"
    26  	"github.com/tailor-inc/graphql/gqlerrors"
    27  	"github.com/weaviate/weaviate/entities/schema"
    28  )
    29  
    30  type MockResolver struct {
    31  	mock.Mock
    32  	Schema        *schema.Schema
    33  	RootField     *graphql.Field
    34  	RootFieldName string
    35  	RootObject    map[string]interface{}
    36  }
    37  
    38  var schemaBuildLock sync.Mutex
    39  
    40  func (mr *MockResolver) Resolve(query string) *graphql.Result {
    41  	fields := graphql.Fields{}
    42  	fields[mr.RootFieldName] = mr.RootField
    43  	schemaObject := graphql.ObjectConfig{
    44  		Name:        "RootObj",
    45  		Description: "Location of the root query",
    46  		Fields:      fields,
    47  	}
    48  
    49  	schemaBuildLock.Lock() // serialize creation of GraphQL schema.
    50  	schema, err := graphql.NewSchema(graphql.SchemaConfig{
    51  		Query: graphql.NewObject(schemaObject),
    52  	})
    53  	schemaBuildLock.Unlock()
    54  
    55  	if err != nil {
    56  		panic(err)
    57  	}
    58  
    59  	result := graphql.Do(graphql.Params{
    60  		Schema:        schema,
    61  		RequestString: query,
    62  		RootObject:    mr.RootObject,
    63  		Context:       context.Background(),
    64  	})
    65  
    66  	return result
    67  }
    68  
    69  func (mr *MockResolver) AssertResolve(t *testing.T, query string) *GraphQLResult {
    70  	result := mr.Resolve(query)
    71  	if len(result.Errors) > 0 {
    72  		t.Fatalf("Failed to resolve; %s", spew.Sdump(result.Errors))
    73  	}
    74  
    75  	mr.AssertExpectations(t)
    76  	return &GraphQLResult{Result: result.Data}
    77  }
    78  
    79  func (mr *MockResolver) AssertFailToResolve(t *testing.T, query string, errors ...string) {
    80  	result := mr.Resolve(query)
    81  	if len(result.Errors) == 0 {
    82  		t.Fatalf("Expected to not resolve; %#v", result.Errors)
    83  	} else {
    84  		t.Log("Resolve failed, as expected, with error", result.Errors)
    85  	}
    86  	if len(errors) > 0 {
    87  		require.Equal(t, errors[0], result.Errors[0].Error())
    88  	}
    89  }
    90  
    91  func (mr *MockResolver) AssertErrors(t *testing.T, query string, errors []gqlerrors.FormattedError) {
    92  	result := mr.Resolve(query)
    93  	for i, actual := range result.Errors {
    94  		assert.Equal(t, errors[i].Error(), actual.Error(), "should have failed in a specific way, but didnt")
    95  	}
    96  }
    97  
    98  func (mr *MockResolver) AssertJSONResponse(t *testing.T, query string, expectedResponseString string) {
    99  	var expectedResponse map[string]interface{}
   100  	err := json.Unmarshal([]byte(expectedResponseString), &expectedResponse)
   101  	if err != nil {
   102  		t.Fatalf("Could not parse '%s' as json: %v", expectedResponseString, err)
   103  	}
   104  
   105  	response := mr.AssertResolve(t, query)
   106  
   107  	assert.Equal(t, expectedResponse, response)
   108  }
   109  
   110  type GraphQLResult struct {
   111  	Result interface{}
   112  }
   113  
   114  // Drill down in the result
   115  func (g GraphQLResult) Get(paths ...string) *GraphQLResult {
   116  	current := g.Result
   117  	for _, path := range paths {
   118  		var ok bool
   119  		currentAsMap, ok := (current.(map[string]interface{}))
   120  		if !ok {
   121  			panic(fmt.Sprintf("Cannot get element %s in %#v; result: %#v", path, paths, g.Result))
   122  		}
   123  
   124  		current, ok = currentAsMap[path]
   125  		if !ok {
   126  			panic(fmt.Sprintf("Cannot get element %s in %#v; result: %#v", path, paths, g.Result))
   127  		}
   128  	}
   129  
   130  	return &GraphQLResult{
   131  		Result: current,
   132  	}
   133  }