/**
 * Go SDK for OpenFGA
 *
 * API version: 1.x
 * Website: https://openfga.dev
 * Documentation: https://openfga.dev/docs
 * Support: https://openfga.dev/community
 * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE)
 *
 * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT.
 */

package client_test

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"testing"
	"time"

	"github.com/jarcoal/httpmock"
	"github.com/openfga/go-sdk"
	. "github.com/openfga/go-sdk/client"
)

type TestDefinition struct {
	Name           string
	JsonResponse   string
	ResponseStatus int
	Method         string
	RequestPath    string
}

func TestOpenFgaClient(t *testing.T) {
	fgaClient, err := NewSdkClient(&ClientConfiguration{
		ApiUrl:  "https://api.fga.example",
		StoreId: "01GXSB9YR785C4FYS3C0RTG7B2",
	})
	if err != nil {
		t.Fatalf("%v", err)
	}

	t.Run("Allow client to have no store ID specified", func(t *testing.T) {
		_, err := NewSdkClient(&ClientConfiguration{
			ApiHost: "api.fga.example",
		})
		if err != nil {
			t.Fatalf("Expect no error when store id is not specified but got %v", err)
		}
	})

	t.Run("Allow client to have ApiUrl specified", func(t *testing.T) {
		_, err := NewSdkClient(&ClientConfiguration{
			ApiUrl: "https://api.fga.example",
		})
		if err != nil {
			t.Fatalf("Expect no error when api url is specified but got %v", err)
		}
	})

	t.Run("Ensure that ApiUrl is well formed", func(t *testing.T) {
		urls := []string{
			"api.fga.example",
			"https//api.fga.example",
			"https://api.fga.example:notavalidport",
			"https://https://api.fga.example",
			"notavalidscheme://api.fga.example",
		}
		for _, uri := range urls {
			_, err := NewSdkClient(&ClientConfiguration{
				ApiUrl: uri,
			})
			if err == nil {
				t.Fatalf("Expected an error for invalid uri (%s) but got nil", uri)
			}

			expectedErrorString := fmt.Sprintf("Configuration.ApiUrl (%s) does not form a valid uri", uri)
			if err.Error() != expectedErrorString {
				t.Fatalf("Expected error (%s) but got (%s)", expectedErrorString, err.Error())
			}
		}
	})

	t.Run("Allow client to have empty store ID specified", func(t *testing.T) {
		_, err := NewSdkClient(&ClientConfiguration{
			ApiHost: "api.fga.example",
			StoreId: "",
		})
		if err != nil {
			t.Fatalf("Expect no error when store id is empty but has %v", err)
		}
	})

	t.Run("Validate store ID when specified", func(t *testing.T) {
		_, err := NewSdkClient(&ClientConfiguration{
			ApiHost: "api.fga.example",
			StoreId: "error",
		})
		if err == nil {
			t.Fatalf("Expect invalid store ID to result in error but there is none")
		}
	})

	t.Run("Validate auth model ID when specified", func(t *testing.T) {
		_, err := NewSdkClient(&ClientConfiguration{
			ApiHost:              "api.fga.example",
			StoreId:              "01GXSB9YR785C4FYS3C0RTG7B2",
			AuthorizationModelId: "BadAuthID",
		})
		if err == nil {
			t.Fatalf("Expect invalid auth mode ID to result in error but there is none")
		}
	})

	t.Run("Allow auth model ID to be empty when specified", func(t *testing.T) {
		_, err := NewSdkClient(&ClientConfiguration{
			ApiHost:              "api.fga.example",
			StoreId:              "01GXSB9YR785C4FYS3C0RTG7B2",
			AuthorizationModelId: "",
		})
		if err != nil {
			t.Fatalf("Expect no error when auth model id is empty but has %v", err)
		}
	})

	t.Run("Allow specifying an ApiUrl with a port and a base path", func(t *testing.T) {
		_, err := NewSdkClient(&ClientConfiguration{
			ApiUrl:  "https://api.fga.example:8080/fga",
			StoreId: "01GXSB9YR785C4FYS3C0RTG7B2",
		})
		if err != nil {
			t.Fatalf("Expect no error when auth model id is empty but has %v", err)
		}

		test := TestDefinition{
			Name:           "ListStores",
			JsonResponse:   `{"stores":[]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodGet,
		}

		var expectedResponse openfga.ListStoresResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores", fgaClient.GetConfig().ApiUrl),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		got, err := fgaClient.ListStores(context.Background()).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
		if len(got.Stores) != 0 {
			t.Fatalf("expected stores of length 0, got %v", len(got.Stores))
		}
	})

	/* Stores */
	t.Run("ListStores", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ListStores",
			JsonResponse:   `{"stores":[{"id":"01GXSA8YR785C4FYS3C0RTG7B1","name":"Test Store","created_at":"2023-01-01T23:23:23.000000000Z","updated_at":"2023-01-01T23:23:23.000000000Z"}]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodGet,
		}

		var expectedResponse openfga.ListStoresResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores", fgaClient.GetConfig().ApiUrl),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		options := ClientListStoresOptions{
			PageSize:          openfga.PtrInt32(10),
			ContinuationToken: openfga.PtrString("..."),
		}
		got, err := fgaClient.ListStores(context.Background()).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(got.Stores) != 1 {
			t.Fatalf("%v", err)
		}

		if got.Stores[0].Id != expectedResponse.Stores[0].Id {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, got.Stores[0].Id, expectedResponse.Stores[0].Id)
		}
		// ListStores without options should work
		_, err = fgaClient.ListStores(context.Background()).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("CreateStore", func(t *testing.T) {
		test := TestDefinition{
			Name:           "CreateStore",
			JsonResponse:   `{"id":"01GXSA8YR785C4FYS3C0RTG7B1","name":"Test Store","created_at":"2023-01-01T23:23:23.000000000Z","updated_at":"2023-01-01T23:23:23.000000000Z"}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
		}
		requestBody := ClientCreateStoreRequest{
			Name: "Test Store",
		}

		var expectedResponse openfga.CreateStoreResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores", fgaClient.GetConfig().ApiUrl),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		got, err := fgaClient.CreateStore(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		_, err = got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}
		if got.Name != expectedResponse.Name {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, got.Name, expectedResponse.Name)
		}
		// CreateStore without options should work
		_, err = fgaClient.CreateStore(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("GetStore", func(t *testing.T) {
		test := TestDefinition{
			Name:           "GetStore",
			JsonResponse:   `{"id":"01GXSA8YR785C4FYS3C0RTG7B1","name":"Test Store","created_at":"2023-01-01T23:23:23.000000000Z","updated_at":"2023-01-01T23:23:23.000000000Z"}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodGet,
		}

		var expectedResponse openfga.GetStoreResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient)),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		got, err := fgaClient.GetStore(context.Background()).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if got.Id != expectedResponse.Id {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, got.Id, expectedResponse.Id)
		}
		// GetStore without options should work
		_, err = fgaClient.GetStore(context.Background()).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientGetStoreOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.GetStore(context.Background()).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientGetStoreOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		_, err = fgaClient.GetStore(context.Background()).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

	})

	t.Run("GetStoreAfterSettingStoreId", func(t *testing.T) {
		test := TestDefinition{
			Name:           "GetStoreAfterSettingStoreId",
			JsonResponse:   `{"id":"01GXSA8YR785C4FYS3C0RTG7B1","name":"Test Store","created_at":"2023-01-01T23:23:23.000000000Z","updated_at":"2023-01-01T23:23:23.000000000Z"}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
		}

		requestBody := ClientCreateStoreRequest{
			Name: "Test Store",
		}

		var expectedResponse openfga.CreateStoreResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores", fgaClient.GetConfig().ApiUrl),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		got1, err1 := fgaClient.CreateStore(context.Background()).Body(requestBody).Execute()
		if err1 != nil {
			t.Fatalf("%v", err1)
		}

		_, err = got1.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}
		if got1.Name != expectedResponse.Name {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, got1.Name, expectedResponse.Name)
		}

		storeId := got1.Id
		fgaClient.SetStoreId(storeId)

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(http.MethodGet, fmt.Sprintf("%s/stores/%s", fgaClient.GetConfig().ApiUrl, storeId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		got2, err2 := fgaClient.GetStore(context.Background()).Execute()
		if err2 != nil {
			t.Fatalf("%v", err2)
		}

		if got2.Id != storeId {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, got2.Id, storeId)
		}
	})

	t.Run("DeleteStore", func(t *testing.T) {
		test := TestDefinition{
			Name:           "DeleteStore",
			JsonResponse:   ``,
			ResponseStatus: http.StatusNoContent,
			Method:         http.MethodDelete,
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient)),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, "{}")
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err := fgaClient.DeleteStore(context.Background()).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
		// DeleteStore without options should work
		_, err = fgaClient.DeleteStore(context.Background()).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientDeleteStoreOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.DeleteStore(context.Background()).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientDeleteStoreOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, "{}")
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.DeleteStore(context.Background()).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	/* Authorization Models */
	t.Run("ReadAuthorizationModels", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ReadAuthorizationModels",
			JsonResponse:   `{"authorization_models":[{"id":"01GXSA8YR785C4FYS3C0RTG7B1","schema_version":"1.1","type_definitions":[]}]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodGet,
			RequestPath:    "authorization-models",
		}

		var expectedResponse openfga.ReadAuthorizationModelsResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		options := ClientReadAuthorizationModelsOptions{
			PageSize:          openfga.PtrInt32(10),
			ContinuationToken: openfga.PtrString("..."),
		}
		got, err := fgaClient.ReadAuthorizationModels(context.Background()).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(got.AuthorizationModels) != 1 {
			t.Fatalf("%v", err)
		}

		if got.AuthorizationModels[0].Id != expectedResponse.AuthorizationModels[0].Id {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, got.AuthorizationModels[0].Id, expectedResponse.AuthorizationModels[0].Id)
		}
		// ReadAuthorizationModels without options should work
		_, err = fgaClient.ReadAuthorizationModels(context.Background()).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientReadAuthorizationModelsOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ReadAuthorizationModels(context.Background()).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientReadAuthorizationModelsOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.ReadAuthorizationModels(context.Background()).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("WriteAuthorizationModel", func(t *testing.T) {
		test := TestDefinition{
			Name:           "WriteAuthorizationModel",
			JsonResponse:   `{"authorization_model_id":"01GXSA8YR785C4FYS3C0RTG7B1"}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "authorization-models",
		}
		requestBody := ClientWriteAuthorizationModelRequest{
			SchemaVersion: "1.1",
			TypeDefinitions: []openfga.TypeDefinition{
				{Type: "user", Relations: &map[string]openfga.Userset{}},
				{
					Type: "document",
					Relations: &map[string]openfga.Userset{
						"writer": {
							This: &map[string]interface{}{},
						},
						"viewer": {Union: &openfga.Usersets{
							Child: []openfga.Userset{
								{This: &map[string]interface{}{}},
								{ComputedUserset: &openfga.ObjectRelation{
									Object:   openfga.PtrString(""),
									Relation: openfga.PtrString("writer"),
								}},
							},
						}},
					},
					Metadata: &openfga.Metadata{
						Relations: &map[string]openfga.RelationMetadata{
							"writer": {
								DirectlyRelatedUserTypes: &[]openfga.RelationReference{
									{Type: "user"},
								},
							},
							"viewer": {
								DirectlyRelatedUserTypes: &[]openfga.RelationReference{
									{Type: "user"},
								},
							},
						},
					},
				}},
		}

		var expectedResponse openfga.WriteAuthorizationModelResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		options := ClientWriteAuthorizationModelOptions{}
		got, err := fgaClient.WriteAuthorizationModel(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		_, err = got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if got.GetAuthorizationModelId() != expectedResponse.GetAuthorizationModelId() {
			t.Fatalf("OpenFgaClient.%v() / AuthorizationModelId = %v, want %v", test.Name, got.GetAuthorizationModelId(), expectedResponse.GetAuthorizationModelId())
		}

		// WriteAuthorizationModel without options should work
		_, err = fgaClient.WriteAuthorizationModel(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientWriteAuthorizationModelOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.WriteAuthorizationModel(context.Background()).Body(requestBody).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("%v", err)
		}

		// store can be overridden
		storeOverrideOptions := ClientWriteAuthorizationModelOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.WriteAuthorizationModel(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("WriteAuthorizationModelWithCondition", func(t *testing.T) {
		test := TestDefinition{
			Name:           "WriteAuthorizationModelWithCondition",
			JsonResponse:   `{"authorization_model_id":"01GXSA8YR785C4FYS3C0RTG7B1"}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "authorization-models",
		}
		requestBody := ClientWriteAuthorizationModelRequest{
			SchemaVersion: "1.1",
			TypeDefinitions: []openfga.TypeDefinition{
				{
					Type:      "user",
					Relations: &map[string]openfga.Userset{},
				},
				{
					Type: "document",
					Relations: &map[string]openfga.Userset{
						"writer": {This: &map[string]interface{}{}},
						"viewer": {Union: &openfga.Usersets{
							Child: []openfga.Userset{
								{This: &map[string]interface{}{}},
								{ComputedUserset: &openfga.ObjectRelation{
									Object:   openfga.PtrString(""),
									Relation: openfga.PtrString("writer"),
								}},
							},
						}},
					},
					Metadata: &openfga.Metadata{
						Relations: &map[string]openfga.RelationMetadata{
							"writer": {
								DirectlyRelatedUserTypes: &[]openfga.RelationReference{
									{Type: "user"},
									{Type: "user", Condition: openfga.PtrString("ViewCountLessThan200")},
								},
							},
							"viewer": {
								DirectlyRelatedUserTypes: &[]openfga.RelationReference{
									{Type: "user"},
								},
							},
						},
					},
				},
			},
			Conditions: &map[string]openfga.Condition{
				"ViewCountLessThan200": {
					Name:       "ViewCountLessThan200",
					Expression: "ViewCount < 200",
					Parameters: &map[string]openfga.ConditionParamTypeRef{
						"ViewCount": {
							TypeName: openfga.TYPENAME_INT,
						},
						"Type": {
							TypeName: openfga.TYPENAME_STRING,
						},
						"Name": {
							TypeName: openfga.TYPENAME_STRING,
						},
					},
				},
			},
		}

		var expectedResponse openfga.WriteAuthorizationModelResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(
			test.Method,
			fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"ViewCountLessThan200"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		options := ClientWriteAuthorizationModelOptions{}
		got, err := fgaClient.WriteAuthorizationModel(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		_, err = got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if got.GetAuthorizationModelId() != expectedResponse.GetAuthorizationModelId() {
			t.Fatalf("OpenFgaClient.%v() / AuthorizationModelId = %v, want %v", test.Name, got.GetAuthorizationModelId(), expectedResponse.GetAuthorizationModelId())
		}

		// WriteAuthorizationModel without options should work
		_, err = fgaClient.WriteAuthorizationModel(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("WriteAuthorizationModelWithCondition2", func(t *testing.T) {
		test := TestDefinition{
			Name:           "WriteAuthorizationModelWithCondition2",
			JsonResponse:   `{"authorization_model_id":"01GXSA8YR785C4FYS3C0RTG7B1"}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "authorization-models",
		}

		schemaVersion := "1.1"
		typeDefs := []openfga.TypeDefinition{
			{
				Type:      "user",
				Relations: &map[string]openfga.Userset{},
			},
			{
				Type: "document",
				Relations: &map[string]openfga.Userset{
					"writer": {This: &map[string]interface{}{}},
					"viewer": {Union: &openfga.Usersets{
						Child: []openfga.Userset{
							{This: &map[string]interface{}{}},
							{ComputedUserset: &openfga.ObjectRelation{
								Object:   openfga.PtrString(""),
								Relation: openfga.PtrString("writer"),
							}},
						},
					}},
				},
				Metadata: &openfga.Metadata{
					Relations: &map[string]openfga.RelationMetadata{
						"writer": {
							DirectlyRelatedUserTypes: &[]openfga.RelationReference{
								{Type: "user"},
								{Type: "user", Condition: openfga.PtrString("ViewCountLessThan200")},
							},
						},
						"viewer": {
							DirectlyRelatedUserTypes: &[]openfga.RelationReference{
								{Type: "user"},
							},
						},
					},
				},
			},
		}
		conditions := map[string]openfga.Condition{
			"ViewCountLessThan200": {
				Name:       "ViewCountLessThan200",
				Expression: "ViewCount < 200",
				Parameters: &map[string]openfga.ConditionParamTypeRef{
					"ViewCount": {
						TypeName: openfga.TYPENAME_INT,
					},
					"Type": {
						TypeName: openfga.TYPENAME_STRING,
					},
					"Name": {
						TypeName: openfga.TYPENAME_STRING,
					},
				},
			},
		}
		requestBody := ClientWriteAuthorizationModelRequest{
			SchemaVersion:   schemaVersion,
			TypeDefinitions: typeDefs,
			Conditions:      &conditions,
		}

		var expectedResponse openfga.WriteAuthorizationModelResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(
			test.Method,
			fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"ViewCountLessThan200"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		options := ClientWriteAuthorizationModelOptions{}
		got, err := fgaClient.WriteAuthorizationModel(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		_, err = got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if got.GetAuthorizationModelId() != expectedResponse.GetAuthorizationModelId() {
			t.Fatalf("OpenFgaClient.%v() / AuthorizationModelId = %v, want %v", test.Name, got.GetAuthorizationModelId(), expectedResponse.GetAuthorizationModelId())
		}

		// WriteAuthorizationModel without options should work
		_, err = fgaClient.WriteAuthorizationModel(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ReadAuthorizationModel", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ReadAuthorizationModel",
			JsonResponse:   `{"authorization_model":{"id":"01GXSA8YR785C4FYS3C0RTG7B1","schema_version":"1.1","type_definitions":[{"type":"github-repo", "relations":{"viewer":{"this":{}}}}]}}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodGet,
			RequestPath:    "authorization-models",
		}

		var expectedResponse openfga.ReadAuthorizationModelResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}
		modelId := expectedResponse.AuthorizationModel.Id

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath, modelId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		options := ClientReadAuthorizationModelOptions{
			AuthorizationModelId: openfga.PtrString(modelId),
		}
		got, err := fgaClient.ReadAuthorizationModel(context.Background()).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		responseJson, err := got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if got.AuthorizationModel.Id != modelId {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, string(responseJson), test.JsonResponse)
		}
		// ReadAuthorizationModel without options should not work
		_, err = fgaClient.ReadAuthorizationModel(context.Background()).Execute()
		expectedError := "Required parameter AuthorizationModelId was not provided"
		if err == nil || err.Error() != expectedError {
			t.Fatalf("Expected error:%v, got: %v", expectedError, err)
		}
		// ReadAuthorizationModel with options of empty string should not work
		badOptions := ClientReadAuthorizationModelOptions{
			AuthorizationModelId: openfga.PtrString(""),
		}
		_, err = fgaClient.ReadAuthorizationModel(context.Background()).Options(badOptions).Execute()
		if err == nil || err.Error() != expectedError {
			t.Fatalf("Expected error:%v, got: %v", expectedError, err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientReadAuthorizationModelOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ReadAuthorizationModel(context.Background()).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientReadAuthorizationModelOptions{
			AuthorizationModelId: openfga.PtrString(modelId),
			StoreId:              openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath, modelId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.ReadAuthorizationModel(context.Background()).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ReadLatestAuthorizationModel", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ReadAuthorizationModels",
			JsonResponse:   `{"authorization_models":[{"id":"01GXSA8YR785C4FYS3C0RTG7B1","schema_version":"1.1","type_definitions":[{"type":"github-repo", "relations":{"viewer":{"this":{}}}}]}]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodGet,
			RequestPath:    "authorization-models",
		}

		var expectedResponse openfga.ReadAuthorizationModelsResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}
		modelId := expectedResponse.AuthorizationModels[0].Id

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		options := ClientReadLatestAuthorizationModelOptions{}
		got, err := fgaClient.ReadLatestAuthorizationModel(context.Background()).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		responseJson, err := got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if got.AuthorizationModel.GetId() != modelId {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, string(responseJson), test.JsonResponse)
		}
		// ReadLatestAuthorizationModel without options should work
		_, err = fgaClient.ReadLatestAuthorizationModel(context.Background()).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientReadLatestAuthorizationModelOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ReadLatestAuthorizationModel(context.Background()).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientReadLatestAuthorizationModelOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.ReadLatestAuthorizationModel(context.Background()).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	/* Relationship Tuples */
	t.Run("ReadChanges", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ReadChanges",
			JsonResponse:   `{"changes":[{"tuple_key":{"user":"user:81684243-9356-4421-8fbf-a4f8d36aa31b","relation":"viewer","object":"document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"},"operation":"TUPLE_OPERATION_WRITE","timestamp": "2000-01-01T00:00:00Z"}],"continuation_token":"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ=="}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodGet,
			RequestPath:    "changes",
		}

		var expectedResponse openfga.ReadChangesResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		startTime, err := time.Parse(time.RFC3339, "2022-01-01T00:00:00Z")
		if err != nil {
			t.Fatalf("Failed to parse startTime: %v", err)
		}
		body := ClientReadChangesRequest{
			Type:      "document",
			StartTime: startTime,
		}
		options := ClientReadChangesOptions{ContinuationToken: openfga.PtrString("eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ=="), PageSize: openfga.PtrInt32(25)}
		got, err := fgaClient.ReadChanges(context.Background()).Body(body).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		responseJson, err := got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(got.Changes) != len(expectedResponse.Changes) {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, string(responseJson), test.JsonResponse)
		}
		// ReadChanges without options should work
		_, err = fgaClient.ReadChanges(context.Background()).Body(body).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientReadChangesOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ReadChanges(context.Background()).Body(body).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientReadChangesOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.ReadChanges(context.Background()).Body(body).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("Read", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Read",
			JsonResponse:   `{"tuples":[{"key":{"user":"user:81684243-9356-4421-8fbf-a4f8d36aa31b","relation":"viewer","object":"document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"},"timestamp": "2000-01-01T00:00:00Z"}]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "read",
		}

		requestBody := ClientReadRequest{
			User:     openfga.PtrString("user:81684243-9356-4421-8fbf-a4f8d36aa31b"),
			Relation: openfga.PtrString("viewer"),
			Object:   openfga.PtrString("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"),
		}

		var expectedResponse openfga.ReadResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		options := ClientReadOptions{
			PageSize:          openfga.PtrInt32(10),
			ContinuationToken: openfga.PtrString("eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ=="),
		}
		got, err := fgaClient.Read(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		responseJson, err := got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(got.Tuples) != len(expectedResponse.Tuples) {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, string(responseJson), test.JsonResponse)
		}
		// Read without options should work
		_, err = fgaClient.Read(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientReadOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.Read(context.Background()).Body(requestBody).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientReadOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.Read(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ReadWithConsistency", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Read",
			JsonResponse:   `{"tuples":[{"key":{"user":"user:81684243-9356-4421-8fbf-a4f8d36aa31b","relation":"viewer","object":"document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"},"timestamp": "2000-01-01T00:00:00Z"}]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "read",
		}

		requestBody := ClientReadRequest{
			User:     openfga.PtrString("user:81684243-9356-4421-8fbf-a4f8d36aa31b"),
			Relation: openfga.PtrString("viewer"),
			Object:   openfga.PtrString("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"),
		}

		var expectedResponse openfga.ReadResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"consistency":"MINIMIZE_LATENCY"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		options := ClientReadOptions{
			PageSize:          openfga.PtrInt32(10),
			ContinuationToken: openfga.PtrString("eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ=="),
			Consistency:       openfga.CONSISTENCYPREFERENCE_MINIMIZE_LATENCY.Ptr(),
		}
		_, err := fgaClient.Read(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("Write", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}
		requestBody := ClientWriteRequest{
			Writes: []ClientTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
			Deletes: []ClientTupleKeyWithoutCondition{},
		}
		options := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		var expectedResponse map[string]interface{}
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		data, err := fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(data.Writes) != 1 {
			t.Fatalf("OpenFgaClient.%v() - expected %v Writes, got %v", test.Name, 1, len(data.Writes))
		}

		if len(data.Deletes) != 0 {
			t.Fatalf("OpenFgaClient.%v() - expected %v Deletes, got %v", test.Name, 0, len(data.Deletes))
		}

		for index := 0; index < len(data.Writes); index++ {
			response := data.Writes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			_, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}
		}

		for index := 0; index < len(data.Deletes); index++ {
			response := data.Deletes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			_, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}
		}
		// Write without options should work
		_, err = fgaClient.Write(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// store ID can be overridden
		storeOverrideOptions := ClientWriteOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.Write(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("Write with invalid auth model id", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}
		requestBody := ClientWriteRequest{
			Writes: []ClientTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		options := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
		}

		var expectedResponse map[string]interface{}
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		_, err := fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err == nil {
			t.Fatalf("Expect error due to invalid auth model ID but there is none")
		}
	})

	t.Run("Write with invalid store id", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}
		requestBody := ClientWriteRequest{
			Writes: []ClientTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		options := ClientWriteOptions{
			StoreId: openfga.PtrString("INVALID"),
		}

		var expectedResponse map[string]interface{}
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		_, err := fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err == nil {
			t.Fatalf("Expect error due to invalid store ID but there is none")
		}
	})

	t.Run("WriteNonTransaction", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}
		requestBody := ClientWriteRequest{
			Writes: []ClientTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}, {
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:budget",
			}},
			Deletes: []ClientTupleKeyWithoutCondition{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:planning",
			}},
		}
		const authModelId = "01GAHCE4YVKPQEKZQHT2R89MQV"
		options := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString(authModelId),
			Transaction: &TransactionOptions{
				Disable:             true,
				MaxParallelRequests: 5,
				MaxPerChunk:         1,
			},
		}

		var expectedResponse map[string]interface{}
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		data, err := fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(data.Writes) != 2 {
			t.Fatalf("OpenFgaClient.%v() - expected %v Writes, got %v", test.Name, 2, len(data.Writes))
		}

		if len(data.Deletes) != 1 {
			t.Fatalf("OpenFgaClient.%v() - expected %v Deletes, got %v", test.Name, 1, len(data.Deletes))
		}

		for index := 0; index < len(data.Writes); index++ {
			response := data.Writes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			_, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}
		}

		for index := 0; index < len(data.Deletes); index++ {
			response := data.Deletes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			_, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}
		}

		// store can be overridden
		storeOverrideOptions := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString(authModelId),
			Transaction: &TransactionOptions{
				Disable:             true,
				MaxParallelRequests: 5,
				MaxPerChunk:         1,
			},
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		data, err = fgaClient.Write(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", data)
		}

		for index := 0; index < len(data.Writes); index++ {
			response := data.Writes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
		}
	})

	t.Run("Write with invalid auth", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}
		requestBody := ClientWriteRequest{
			Writes: []ClientTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		options := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				return httpmock.NewStringResponse(http.StatusUnauthorized, ""), nil
			},
		)
		_, err = fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth but there is none")
		}

		if _, ok := err.(openfga.FgaApiAuthenticationError); !ok {
			t.Fatalf("Expected an api auth error")
		}
	})

	t.Run("Write with invalid auth - transaction mode disabled", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}
		requestBody := ClientWriteRequest{
			Writes: []ClientTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		options := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
			Transaction: &TransactionOptions{
				Disable:             true,
				MaxPerChunk:         1,
				MaxParallelRequests: 1,
			},
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				return httpmock.NewStringResponse(http.StatusUnauthorized, ""), nil
			},
		)
		_, err = fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth but there is none")
		}

		if _, ok := err.(openfga.FgaApiAuthenticationError); !ok {
			t.Fatalf("Expected an api auth error")
		}

		requestBody = ClientWriteRequest{
			Deletes: []openfga.TupleKeyWithoutCondition{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}

		// Now tests that deletes returns the error
		_, err = fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth but there is none")
		}

		if _, ok := err.(openfga.FgaApiAuthenticationError); !ok {
			t.Fatalf("Expected an api auth error")
		}
	})

	t.Run("Write with 400 error - transaction mode disabled", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}
		requestBody := ClientWriteRequest{
			Writes: []ClientTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		options := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
			Transaction: &TransactionOptions{
				Disable:             true,
				MaxPerChunk:         1,
				MaxParallelRequests: 1,
			},
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				return httpmock.NewStringResponse(http.StatusBadRequest, ""), nil
			},
		)
		data, err := fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("Expected no error")
		}

		if data.Writes[0].Error == nil {
			t.Fatalf("Expected error to be in writes")
		}

		requestBody = ClientWriteRequest{
			Deletes: []openfga.TupleKeyWithoutCondition{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "viewer",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}

		// Now tests that deletes returns the error
		data, err = fgaClient.Write(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("Expected no error")
		}

		if data.Deletes[0].Error == nil {
			t.Fatalf("Expected error to be in deletes")
		}
	})

	t.Run("WriteTuples", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}
		requestBody := []ClientTupleKey{{
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "viewer",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
		}}
		options := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		var expectedResponse map[string]interface{}
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		data, err := fgaClient.WriteTuples(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(data.Writes) != 1 {
			t.Fatalf("OpenFgaClient.%v() - expected %v Writes, got %v", test.Name, 1, len(data.Writes))
		}

		if len(data.Deletes) != 0 {
			t.Fatalf("OpenFgaClient.%v() - expected %v Deletes, got %v", test.Name, 0, len(data.Deletes))
		}

		for index := 0; index < len(data.Writes); index++ {
			response := data.Writes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			_, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}
		}

		for index := 0; index < len(data.Deletes); index++ {
			response := data.Deletes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			_, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}
		}
		// WriteTuples without options should work
		_, err = fgaClient.WriteTuples(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientWriteOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.WriteTuples(context.Background()).Body(requestBody).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientWriteOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.WriteTuples(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("DeleteTuples", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Write",
			JsonResponse:   `{}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "write",
		}

		requestBody := []ClientTupleKeyWithoutCondition{{
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "viewer",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
		}}
		options := ClientWriteOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		var expectedResponse map[string]interface{}
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		data, err := fgaClient.DeleteTuples(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(data.Writes) != 0 {
			t.Fatalf("OpenFgaClient.%v() - expected no Writes, got %v", test.Name, len(data.Writes))
		}

		if len(data.Deletes) != 1 {
			t.Fatalf("OpenFgaClient.%v() - expected no Deletes, got %v", test.Name, len(data.Deletes))
		}

		for index := 0; index < len(data.Writes); index++ {
			response := data.Writes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			_, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}
		}

		for index := 0; index < len(data.Deletes); index++ {
			response := data.Deletes[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			_, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}
		}
		// DeleteTuples without options should work
		_, err = fgaClient.DeleteTuples(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// invalid store id should result in error
		badStoreOptions := ClientWriteOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.DeleteTuples(context.Background()).Body(requestBody).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientWriteOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.DeleteTuples(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	/* Relationship Queries */
	t.Run("Check", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Check",
			JsonResponse:   `{"allowed":true, "resolution":""}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "check",
		}
		requestBody := ClientCheckRequest{
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "viewer",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}

		options := ClientCheckOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		var expectedResponse openfga.CheckResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		got, err := fgaClient.Check(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		responseJson, err := got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if got.GetAllowed() != *expectedResponse.Allowed {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, string(responseJson), test.JsonResponse)
		}
		// Check without options should work
		_, err = fgaClient.Check(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// check with invalid auth model id should result in error
		badOptions := ClientCheckOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.Check(context.Background()).Body(requestBody).Options(badOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad auth model id but there is none")
		}
		// invalid store id should result in error
		badStoreOptions := ClientCheckOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.Check(context.Background()).Body(requestBody).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with bad store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientCheckOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.Check(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

	})

	t.Run("CheckWithConsistency", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Check",
			JsonResponse:   `{"allowed":true, "resolution":""}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "check",
		}
		requestBody := ClientCheckRequest{
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "viewer",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}

		options := ClientCheckOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
			Consistency:          openfga.CONSISTENCYPREFERENCE_HIGHER_CONSISTENCY.Ptr(),
		}

		var expectedResponse openfga.CheckResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"consistency":"HIGHER_CONSISTENCY"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err := fgaClient.Check(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("BatchCheck", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Check",
			JsonResponse:   `{"allowed":true, "resolution":""}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "check",
		}
		requestBody := ClientBatchCheckBody{{
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "viewer",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}, {
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "admin",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}, {
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "creator",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
		}, {
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "deleter",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
		}}

		const authModelId = "01GAHCE4YVKPQEKZQHT2R89MQV"

		options := ClientBatchCheckOptions{
			AuthorizationModelId: openfga.PtrString(authModelId),
			MaxParallelRequests:  openfga.PtrInt32(5),
		}

		var expectedResponse openfga.CheckResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		got, err := fgaClient.BatchCheck(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if httpmock.GetTotalCallCount() != 4 {
			t.Fatalf("OpenFgaClient.%v() - wanted %v calls to /check, got %v", test.Name, 4, httpmock.GetTotalCallCount())
		}

		if len(*got) != len(requestBody) {
			t.Fatalf("OpenFgaClient.%v() - Response Length = %v, want %v", test.Name, len(*got), len(requestBody))
		}

		for index := 0; index < len(*got); index++ {
			response := (*got)[index]
			if response.Error != nil {
				t.Fatalf("OpenFgaClient.%v()|%d/ %v", test.Name, index, response.Error)
			}
			if response.HttpResponse.StatusCode != test.ResponseStatus {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, response.HttpResponse.StatusCode, test.ResponseStatus)
			}

			responseJson, err := response.MarshalJSON()
			if err != nil {
				t.Fatalf("%v", err)
			}

			if *response.Allowed != *expectedResponse.Allowed {
				t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, string(responseJson), test.JsonResponse)
			}
		}
		// BatchCheck without options should work
		_, err = fgaClient.BatchCheck(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.ZeroCallCounters()
		// BatchCheck with invalid auth model ID should fail
		badOptions := ClientBatchCheckOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
			MaxParallelRequests:  openfga.PtrInt32(5),
		}
		_, err = fgaClient.BatchCheck(context.Background()).Body(requestBody).Options(badOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth model id but there is none")
		}
		// invalid store ID should fail
		badStoreOptions := ClientBatchCheckOptions{
			StoreId:             openfga.PtrString("INVALID"),
			MaxParallelRequests: openfga.PtrInt32(5),
		}
		_, err = fgaClient.BatchCheck(context.Background()).Body(requestBody).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth model id but there is none")
		}

		if httpmock.GetTotalCallCount() != 0 {
			t.Fatalf("Expected no calls to be made")
		}

		httpmock.ZeroCallCounters()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				return httpmock.NewStringResponse(http.StatusUnauthorized, ""), nil
			},
		)
		// BatchCheck with invalid auth should fail
		_, err = fgaClient.BatchCheck(context.Background()).Body(requestBody).Options(options).Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth but there is none")
		}

		// store should be overridden
		storeOverrideOptions := ClientBatchCheckOptions{
			StoreId:             openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
			MaxParallelRequests: openfga.PtrInt32(5),
		}
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		_, err = fgaClient.BatchCheck(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("BatchCheckWithConsistency", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Check",
			JsonResponse:   `{"allowed":true, "resolution":""}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "check",
		}
		requestBody := ClientBatchCheckBody{{
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "viewer",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}, {
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "admin",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}, {
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "creator",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
		}, {
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "deleter",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
		}}

		const authModelId = "01GAHCE4YVKPQEKZQHT2R89MQV"

		options := ClientBatchCheckOptions{
			AuthorizationModelId: openfga.PtrString(authModelId),
			MaxParallelRequests:  openfga.PtrInt32(5),
			Consistency:          openfga.CONSISTENCYPREFERENCE_HIGHER_CONSISTENCY.Ptr(),
		}

		var expectedResponse openfga.CheckResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"consistency":"HIGHER_CONSISTENCY"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		checks, err := fgaClient.BatchCheck(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		for _, check := range *checks {
			if check.Error != nil {
				t.Fatalf("a check failed %v", check.Error)
			}
		}
	})

	t.Run("Expand", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Expand",
			JsonResponse:   `{"tree":{"root":{"name":"document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a#viewer","union":{"nodes":[{"name": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a#viewer","leaf":{"users":{"users":["user:81684243-9356-4421-8fbf-a4f8d36aa31b"]}}}]}}}}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "expand",
		}

		requestBody := ClientExpandRequest{
			Relation: "viewer",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
		}
		options := ClientExpandOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		var expectedResponse openfga.ExpandResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		got, err := fgaClient.Expand(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		_, err = got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}
		// Expand without options should work
		_, err = fgaClient.Expand(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
		// Invalid auth model ID should result in error
		badOptions := ClientExpandOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.Expand(context.Background()).Body(requestBody).Options(badOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error for invalid auth model id but there is none")
		}

		// Invalid auth model ID should result in error
		badStoreOptions := ClientExpandOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.Expand(context.Background()).Body(requestBody).Options(badStoreOptions).Execute()
		if err == nil {
			t.Fatalf("Expect error for invalid auth model id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientExpandOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.Expand(context.Background()).Body(requestBody).Options(storeOverrideOptions).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ExpandWithConsistency", func(t *testing.T) {
		test := TestDefinition{
			Name:           "Expand",
			JsonResponse:   `{"tree":{"root":{"name":"document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a#viewer","union":{"nodes":[{"name": "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a#viewer","leaf":{"users":{"users":["user:81684243-9356-4421-8fbf-a4f8d36aa31b"]}}}]}}}}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "expand",
		}

		requestBody := ClientExpandRequest{
			Relation: "viewer",
			Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
		}
		options := ClientExpandOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
			Consistency:          openfga.CONSISTENCYPREFERENCE_MINIMIZE_LATENCY.Ptr(),
		}

		var expectedResponse openfga.ExpandResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"consistency":"MINIMIZE_LATENCY"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err := fgaClient.Expand(context.Background()).Body(requestBody).Options(options).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ListObjects", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ListObjects",
			JsonResponse:   `{"objects":["document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "list-objects",
		}

		requestBody := ClientListObjectsRequest{
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "can_read",
			Type:     "document",
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "folder:product",
			}, {
				User:     "folder:product",
				Relation: "parent",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		options := ClientListObjectsOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		var expectedResponse openfga.ListObjectsResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		got, err := fgaClient.ListObjects(context.Background()).
			Body(requestBody).
			Options(options).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		responseJson, err := got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(got.Objects) != len(expectedResponse.Objects) || (got.Objects)[0] != (expectedResponse.Objects)[0] {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, string(responseJson), test.JsonResponse)
		}
		// ListObjects without options should work
		_, err = fgaClient.ListObjects(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// Invalid auth model id should result in error
		badOptions := ClientListObjectsOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ListObjects(context.Background()).
			Body(requestBody).
			Options(badOptions).
			Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth model id but there is none")
		}
		// Invalid store id should result in error
		badStoreOptions := ClientListObjectsOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ListObjects(context.Background()).
			Body(requestBody).
			Options(badStoreOptions).
			Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth model id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientListObjectsOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.ListObjects(context.Background()).
			Body(requestBody).
			Options(storeOverrideOptions).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ListObjectsWithConsistency", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ListObjects",
			JsonResponse:   `{"objects":["document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "list-objects",
		}

		requestBody := ClientListObjectsRequest{
			User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Relation: "can_read",
			Type:     "document",
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "folder:product",
			}, {
				User:     "folder:product",
				Relation: "parent",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		options := ClientListObjectsOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
			Consistency:          openfga.CONSISTENCYPREFERENCE_MINIMIZE_LATENCY.Ptr(),
		}

		var expectedResponse openfga.ListObjectsResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"consistency":"MINIMIZE_LATENCY"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err := fgaClient.ListObjects(context.Background()).
			Body(requestBody).
			Options(options).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ListRelations", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ListRelations",
			JsonResponse:   `{"allowed":true, "resolution":""}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "check",
		}

		requestBody := ClientListRelationsRequest{
			User:      "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Object:    "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			Relations: []string{"can_view", "can_edit", "can_delete", "can_rename"},
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		const authModelId = "01GAHCE4YVKPQEKZQHT2R89MQV"
		options := ClientListRelationsOptions{
			AuthorizationModelId: openfga.PtrString(authModelId),
		}

		var expectedResponse openfga.CheckResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"relation":"can_delete"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, openfga.CheckResponse{Allowed: openfga.PtrBool(false)})
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		got, err := fgaClient.ListRelations(context.Background()).
			Body(requestBody).
			Options(options).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if httpmock.GetTotalCallCount() != 4 {
			t.Fatalf("OpenFgaClient.%v() - wanted %v calls to /check, got %v", test.Name, 4, httpmock.GetTotalCallCount())
		}

		_, err = got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(got.Relations) != 3 {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, len(got.Relations), 3)
		}
		// ListRelations without options should work
		_, err = fgaClient.ListRelations(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
		// Invalid auth model ID should result in error
		badOptions := ClientListRelationsOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ListRelations(context.Background()).
			Body(requestBody).
			Options(badOptions).
			Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth model id but there is none")
		}

		// invalid store ID should result in error
		badStoreOptions := ClientListRelationsOptions{
			AuthorizationModelId: openfga.PtrString(authModelId),
			StoreId:              openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ListRelations(context.Background()).
			Body(requestBody).
			Options(badStoreOptions).
			Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid store id but there is none")
		}

		// store can be overridden
		storeOverrideOptions := ClientListRelationsOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			httpmock.BodyContainsString(`"relation":"can_delete"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, openfga.CheckResponse{Allowed: openfga.PtrBool(false)})
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		_, err = fgaClient.ListRelations(context.Background()).
			Body(requestBody).
			Options(storeOverrideOptions).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

	})

	t.Run("ListRelationsWithConsistency", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ListRelations",
			JsonResponse:   `{"allowed":true, "resolution":""}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "check",
		}

		requestBody := ClientListRelationsRequest{
			User:      "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Object:    "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			Relations: []string{"can_view", "can_edit", "can_delete", "can_rename"},
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		const authModelId = "01GAHCE4YVKPQEKZQHT2R89MQV"
		options := ClientListRelationsOptions{
			AuthorizationModelId: openfga.PtrString(authModelId),
			Consistency:          openfga.CONSISTENCYPREFERENCE_HIGHER_CONSISTENCY.Ptr(),
		}

		var expectedResponse openfga.CheckResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"consistency":"HIGHER_CONSISTENCY"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, openfga.CheckResponse{Allowed: openfga.PtrBool(false)})
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		_, err := fgaClient.ListRelations(context.Background()).
			Body(requestBody).
			Options(options).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ListRelationsNoRelationsProvided", func(t *testing.T) {
		test := TestDefinition{
			Name:           "ListRelations",
			JsonResponse:   ``,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "check",
		}

		requestBody := ClientListRelationsRequest{
			User:      "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
			Object:    "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			Relations: []string{},
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
		}
		options := ClientListRelationsOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		_, err := fgaClient.ListRelations(context.Background()).
			Body(requestBody).
			Options(options).
			Execute()

		if err == nil {
			t.Fatalf("OpenFgaClient.%v() - expected an error but received none", test.Name)
		}
	})

	t.Run("ListUsers", func(t *testing.T) {
		test := TestDefinition{
			Name: "ListUsers",
			// A real API would not return all these for the filter provided, these are just for test purposes
			JsonResponse:   `{"users":[{"object":{"id":"81684243-9356-4421-8fbf-a4f8d36aa31b","type":"user"}},{"userset":{"id":"fga","relation":"member","type":"team"}},{"wildcard":{"type":"user"}}]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "list-users",
		}

		requestBody := ClientListUsersRequest{
			Object: openfga.FgaObject{
				Type: "document",
				Id:   "roadmap",
			},
			Relation: "can_read",
			// API does not allow sending multiple filters, done here for testing purposes
			UserFilters: []openfga.UserTypeFilter{{
				Type: "user",
			}, {
				Type:     "team",
				Relation: openfga.PtrString("member"),
			}},
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "folder:product",
			}, {
				User:     "folder:product",
				Relation: "parent",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
			Context: &map[string]interface{}{"ViewCount": 100},
		}
		options := ClientListUsersOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
		}

		var expectedResponse openfga.ListUsersResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		got, err := fgaClient.ListUsers(context.Background()).
			Body(requestBody).
			Options(options).
			Execute()

		_, err = got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(got.Users) != len(expectedResponse.Users) {
			t.Fatalf("OpenFga%v().Execute() = %v, want %v", test.Name, got.GetUsers(), expectedResponse.GetUsers())
		}

		if got.Users[0].GetObject().Type != expectedResponse.Users[0].GetObject().Type || got.Users[0].GetObject().Id != expectedResponse.Users[0].GetObject().Id {
			t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[0], expectedResponse.Users[0], "object: { type: \"user\", id: \"81684243-9356-4421-8fbf-a4f8d36aa31b\" }")
		}

		if got.Users[1].GetUserset().Type != expectedResponse.Users[1].GetUserset().Type || got.Users[1].GetUserset().Id != expectedResponse.Users[1].GetUserset().Id || got.Users[1].GetUserset().Relation != expectedResponse.Users[1].GetUserset().Relation {
			t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[1], expectedResponse.Users[1], "wildcard: { type: \"team\", id: \"fga\", relation: \"member\" }")
		}

		if got.Users[2].GetWildcard().Type != expectedResponse.Users[2].GetWildcard().Type {
			t.Fatalf("OpenFga%v().Execute() = %v, want %v (%v)", test.Name, got.Users[2], expectedResponse.Users[2], "wildcard: { type: \"user\" }")
		}

		// ListUsers without options should work
		_, err = fgaClient.ListUsers(context.Background()).Body(requestBody).Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		// Invalid auth model id should result in error
		badOptions := ClientListUsersOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ListUsers(context.Background()).
			Body(requestBody).
			Options(badOptions).
			Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid auth model id but there is none")
		}
		// Invalid store id should result in error
		badStoreOptions := ClientListUsersOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ListUsers(context.Background()).
			Body(requestBody).
			Options(badStoreOptions).
			Execute()
		if err == nil {
			t.Fatalf("Expect error with invalid store model id but there is none")
		}

		// StoreId can be overridden
		storeOverrideOptions := ClientListUsersOptions{
			StoreId: openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		_, err = fgaClient.ListUsers(context.Background()).
			Body(requestBody).
			Options(storeOverrideOptions).
			Execute()

		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("ListUsersWithConsistency", func(t *testing.T) {
		test := TestDefinition{
			Name: "ListUsers",
			// A real API would not return all these for the filter provided, these are just for test purposes
			JsonResponse:   `{"users":[{"object":{"id":"81684243-9356-4421-8fbf-a4f8d36aa31b","type":"user"}},{"userset":{"id":"fga","relation":"member","type":"team"}},{"wildcard":{"type":"user"}}]}`,
			ResponseStatus: http.StatusOK,
			Method:         http.MethodPost,
			RequestPath:    "list-users",
		}

		requestBody := ClientListUsersRequest{
			Object: openfga.FgaObject{
				Type: "document",
				Id:   "roadmap",
			},
			Relation: "can_read",
			// API does not allow sending multiple filters, done here for testing purposes
			UserFilters: []openfga.UserTypeFilter{{
				Type: "user",
			}, {
				Type:     "team",
				Relation: openfga.PtrString("member"),
			}},
			ContextualTuples: []ClientContextualTupleKey{{
				User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation: "editor",
				Object:   "folder:product",
			}, {
				User:     "folder:product",
				Relation: "parent",
				Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
			}},
			Context: &map[string]interface{}{"ViewCount": 100},
		}
		options := ClientListUsersOptions{
			AuthorizationModelId: openfga.PtrString("01GAHCE4YVKPQEKZQHT2R89MQV"),
			Consistency:          openfga.CONSISTENCYPREFERENCE_MINIMIZE_LATENCY.Ptr(),
		}

		var expectedResponse openfga.ListUsersResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath),
			httpmock.BodyContainsString(`"consistency":"MINIMIZE_LATENCY"`),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)

		_, err := fgaClient.ListUsers(context.Background()).
			Body(requestBody).
			Options(options).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	/* Assertions */
	t.Run("ReadAssertions", func(t *testing.T) {
		modelId := "01GAHCE4YVKPQEKZQHT2R89MQV"
		test := TestDefinition{
			Name:           "ReadAssertions",
			JsonResponse:   fmt.Sprintf(`{"assertions":[{"tuple_key":{"user":"user:anna","relation":"can_view","object":"document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"},"expectation":true}],"authorization_model_id":"%s","context":{"context":"value"},"contextual_tuples":[{"object":"document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a","relation":"can_view","user":"user:81684243-9356-4421-8fbf-a4f8d36aa31b"}]}`, modelId),
			ResponseStatus: http.StatusOK,
			Method:         http.MethodGet,
			RequestPath:    "assertions",
		}

		options := ClientReadAssertionsOptions{
			AuthorizationModelId: openfga.PtrString(modelId),
		}

		var expectedResponse openfga.ReadAssertionsResponse
		if err := json.Unmarshal([]byte(test.JsonResponse), &expectedResponse); err != nil {
			t.Fatalf("%v", err)
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath, modelId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		got, err := fgaClient.ReadAssertions(context.Background()).
			Options(options).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}

		responseJson, err := got.MarshalJSON()
		if err != nil {
			t.Fatalf("%v", err)
		}

		if len(*got.Assertions) != len(*expectedResponse.Assertions) || (*got.Assertions)[0].Expectation != (*expectedResponse.Assertions)[0].Expectation {
			t.Fatalf("OpenFgaClient.%v() = %v, want %v", test.Name, string(responseJson), test.JsonResponse)
		}
		// ReadAssertions without options should work
		_, err = fgaClient.ReadAssertions(context.Background()).Execute()
		expectedError := "Required parameter AuthorizationModelId was not provided"
		if err == nil || err.Error() != expectedError {
			t.Fatalf("Expected error:%v, got: %v", expectedError, err)
		}

		// Invalid auth model id should result in error
		badOptions := ClientReadAssertionsOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ReadAssertions(context.Background()).
			Options(badOptions).
			Execute()
		if err == nil {
			t.Fatalf("Invalid auth model ID should result in error")
		}

		// Invalid store id should result in error
		badStoreOptions := ClientReadAssertionsOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.ReadAssertions(context.Background()).
			Options(badStoreOptions).
			Execute()
		if err == nil {
			t.Fatalf("Invalid store ID should result in error")
		}

		// store can be overriden
		storeOverrideOptions := ClientReadAssertionsOptions{
			AuthorizationModelId: openfga.PtrString(modelId),
			StoreId:              openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath, modelId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse)
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.ReadAssertions(context.Background()).
			Options(storeOverrideOptions).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})

	t.Run("WriteAssertions", func(t *testing.T) {
		modelId := "01GAHCE4YVKPQEKZQHT2R89MQV"
		test := TestDefinition{
			Name:           "WriteAssertions",
			JsonResponse:   "",
			ResponseStatus: http.StatusNoContent,
			Method:         http.MethodPut,
			RequestPath:    "assertions",
		}

		requestBody := ClientWriteAssertionsRequest{
			{
				User:        "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
				Relation:    "can_view",
				Object:      "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
				Expectation: true,
				Context: &map[string]interface{}{
					"context": "value",
				},
				ContextualTuples: []ClientContextualTupleKey{
					{
						User:     "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
						Relation: "can_view",
						Object:   "document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
					},
				},
			},
		}
		options := ClientWriteAssertionsOptions{
			AuthorizationModelId: openfga.PtrString(modelId),
		}

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath, modelId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, "")
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err := fgaClient.WriteAssertions(context.Background()).
			Body(requestBody).
			Options(options).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
		// WriteAssertions without options should work
		_, err = fgaClient.WriteAssertions(context.Background()).Body(requestBody).Execute()
		expectedError := "Required parameter AuthorizationModelId was not provided"
		if err == nil || err.Error() != expectedError {
			t.Fatalf("Expected error:%v, got: %v", expectedError, err)
		}
		badOptions := ClientWriteAssertionsOptions{
			AuthorizationModelId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.WriteAssertions(context.Background()).
			Body(requestBody).
			Options(badOptions).
			Execute()
		if err == nil {
			t.Fatalf("Invalid auth model id should result in error but there is none")
		}

		badStoreOptions := ClientWriteAssertionsOptions{
			StoreId: openfga.PtrString("INVALID"),
		}
		_, err = fgaClient.WriteAssertions(context.Background()).
			Body(requestBody).
			Options(badStoreOptions).
			Execute()
		if err == nil {
			t.Fatalf("Invalid store id should result in error but there is none")
		}

		// store can be overriden
		storeOverrideOptions := ClientWriteAssertionsOptions{
			AuthorizationModelId: openfga.PtrString(modelId),
			StoreId:              openfga.PtrString("7777HCE4YVKPQEKZQHT2R89MQV"),
		}
		httpmock.Reset()
		httpmock.RegisterResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s/%s", fgaClient.GetConfig().ApiUrl, *storeOverrideOptions.StoreId, test.RequestPath, modelId),
			func(req *http.Request) (*http.Response, error) {
				resp, err := httpmock.NewJsonResponse(test.ResponseStatus, "")
				if err != nil {
					return httpmock.NewStringResponse(http.StatusInternalServerError, ""), nil
				}
				return resp, nil
			},
		)
		_, err = fgaClient.WriteAssertions(context.Background()).
			Body(requestBody).
			Options(storeOverrideOptions).
			Execute()
		if err != nil {
			t.Fatalf("%v", err)
		}
	})
}

func getStoreId(t *testing.T, fgaClient *OpenFgaClient) string {
	storeId, err := fgaClient.GetStoreId()
	if err != nil {
		t.Fatalf("%v", err)
	}
	return storeId
}
