Ctrl K
ComunidadGuías…

cli/dockercompose/graphql_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package dockercompose //nolint:testpackage

import (
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/nhost/be/services/mimir/model"
)

func expectedGraphql() *Service {
	return &Service{
		Image:   "nhost/graphql-engine:2.12.0",
		Command: nil,
		DependsOn: map[string]DependsOn{
			"postgres": {Condition: "service_healthy"},
		},
		EntryPoint: nil,
		Environment: map[string]string{
			"ENV1":                                                     "VALUE1",
			"ENV2":                                                     "VALUE2",
			"GRAPHITE_WEBHOOK_SECRET":                                  "webhookSecret",
			"HASURA_GRAPHQL_ADMIN_INTERNAL_ERRORS":                     "true",
			"HASURA_GRAPHQL_ADMIN_SECRET":                              "adminSecret",
			"HASURA_GRAPHQL_CONSOLE_ASSETS_DIR":                        "/srv/console-assets",
			"HASURA_GRAPHQL_CORS_DOMAIN":                               "http://*.localhost,http://dev.dashboard.local.nhost.run:1337,http://*.hasura.local.nhost.run:1337,http://*.dashboard.local.nhost.run:1337",
			"HASURA_GRAPHQL_DATABASE_URL":                              "postgres://nhost_hasura@postgres:5432/local",
			"HASURA_GRAPHQL_DEV_MODE":                                  "false",
			"HASURA_GRAPHQL_DISABLE_CORS":                              "false",
			"HASURA_GRAPHQL_ENABLED_APIS":                              "metadata,graphql,config,pgdump",
			"HASURA_GRAPHQL_ENABLED_LOG_TYPES":                         "startup,http-log,webhook-log,websocket-log",
			"HASURA_GRAPHQL_ENABLE_ALLOWLIST":                          "true",
			"HASURA_GRAPHQL_ENABLE_CONSOLE":                            "false",
			"HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS":          "true",
			"HASURA_GRAPHQL_ENABLE_TELEMETRY":                          "false",
			"HASURA_GRAPHQL_EVENTS_HTTP_POOL_SIZE":                     "100",
			"HASURA_GRAPHQL_INFER_FUNCTION_PERMISSIONS":                "true",
			"HASURA_GRAPHQL_JWT_SECRET":                                `{"claims_map":{"x-hasura-allowed-roles":{"path":"$.roles"},"x-hasura-default-role":"viewer","x-hasura-org-id":{"default":"public","path":"$.org"},"x-hasura-user-id":{"path":"$.sub"}},"key":"jwtSecretKey","type":"HS256"}`,
			"HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_BATCH_SIZE":       "100",
			"HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL": "1000",
			"HASURA_GRAPHQL_LOG_LEVEL":                                 "info",
			"HASURA_GRAPHQL_PG_CONNECTIONS":                            "50",
			"HASURA_GRAPHQL_PG_TIMEOUT":                                "180",
			"HASURA_GRAPHQL_STRINGIFY_NUMERIC_TYPES":                   "false",
			"HASURA_GRAPHQL_TX_ISOLATION":                              "read-committed",
			"HASURA_GRAPHQL_UNAUTHORIZED_ROLE":                         "public",
			"HASURA_GRAPHQL_USE_PREPARED_STATEMENTS":                   "true",
			"HASURA_GRAPHQL_WS_READ_COOKIE":                            "false",
			"NHOST_ADMIN_SECRET":                                       "adminSecret",
			"NHOST_AUTH_URL":                                           "http://dev.auth.local.nhost.run:1337/v1",
			"NHOST_FUNCTIONS_URL":                                      "http://dev.functions.local.nhost.run:1337/v1",
			"NHOST_GRAPHQL_URL":                                        "http://dev.graphql.local.nhost.run:1337/v1",
			"NHOST_HASURA_URL":                                         "http://dev.hasura.local.nhost.run:1337",
			"NHOST_JWT_SECRET":                                         `{"claims_map":{"x-hasura-allowed-roles":{"path":"$.roles"},"x-hasura-default-role":"viewer","x-hasura-org-id":{"default":"public","path":"$.org"},"x-hasura-user-id":{"path":"$.sub"}},"key":"jwtSecretKey","type":"HS256"}`,
			"NHOST_REGION":                                             "local",
			"NHOST_STORAGE_URL":                                        "http://dev.storage.local.nhost.run:1337/v1",
			"NHOST_SUBDOMAIN":                                          "dev",
			"NHOST_WEBHOOK_SECRET":                                     "webhookSecret",
		},
		ExtraHosts: []string{
			"host.docker.internal:host-gateway",
		},
		HealthCheck: &HealthCheck{
			Test: []string{
				"CMD-SHELL",
				"curl http://localhost:8080/healthz > /dev/null 2>&1",
			},
			Timeout:     "60s",
			Interval:    "5s",
			StartPeriod: "60s",
		},
		Labels: map[string]string{
			"traefik.enable": "true",
			"traefik.http.middlewares.replace-graphql.replacepathregex.regex":       "/v1(/|$$)(.*)",
			"traefik.http.middlewares.replace-graphql.replacepathregex.replacement": "/v1/graphql$$2",
			"traefik.http.routers.graphql.entrypoints":                              "web",
			"traefik.http.routers.graphql.middlewares":                              "replace-graphql",
			"traefik.http.routers.graphql.rule":                                     "(HostRegexp(`^.+\\.graphql\\.local\\.nhost\\.run$`) || Host(`local.graphql.nhost.run`))&& PathPrefix(`/v1`)",
			"traefik.http.routers.graphql.service":                                  "graphql",
			"traefik.http.routers.graphql.tls":                                      "false",
			"traefik.http.routers.hasura.entrypoints":                               "web",
			"traefik.http.routers.hasura.rule":                                      "(HostRegexp(`^.+\\.hasura\\.local\\.nhost\\.run$`) || Host(`local.hasura.nhost.run`))&& ( PathPrefix(`/v1`) || PathPrefix(`/v2`) || PathPrefix(`/api/`) || PathPrefix(`/console/assets`) )",
			"traefik.http.routers.hasura.service":                                   "hasura",
			"traefik.http.routers.hasura.tls":                                       "false",
			"traefik.http.services.graphql.loadbalancer.server.port":                "8080",
			"traefik.http.services.hasura.loadbalancer.server.port":                 "8080",
		},
		Networks:   networkAliases("hasura-service"),
		Ports:      nil,
		Restart:    "always",
		Volumes:    nil,
		WorkingDir: nil,
	}
}

func expectedGraphqlWithConstellation() *Service {
	svc := expectedGraphql()
	// When constellation is enabled, graphql() must not register the
	// `graphql` router or its rewrite middleware — constellation owns
	// local.graphql.local.nhost.run instead. The hasura router stays
	// byte-for-byte identical.
	delete(svc.Labels, "traefik.http.middlewares.replace-graphql.replacepathregex.regex")
	delete(svc.Labels, "traefik.http.middlewares.replace-graphql.replacepathregex.replacement")
	delete(svc.Labels, "traefik.http.routers.graphql.entrypoints")
	delete(svc.Labels, "traefik.http.routers.graphql.middlewares")
	delete(svc.Labels, "traefik.http.routers.graphql.rule")
	delete(svc.Labels, "traefik.http.routers.graphql.service")
	delete(svc.Labels, "traefik.http.routers.graphql.tls")
	delete(svc.Labels, "traefik.http.services.graphql.loadbalancer.server.port")

	return svc
}

func configWithConstellation() *model.ConfigConfig {
	cfg := getConfig()
	cfg.Experimental = &model.ConfigExperimental{
		Constellation: &model.ConfigConstellation{
			Version:  new("0.0.1"),
			Settings: nil,
		},
	}

	return cfg
}

func TestGraphql(t *testing.T) {
	t.Parallel()

	cases := []struct {
		name     string
		cfg      func() *model.ConfigConfig
		useTlS   bool
		expected func() *Service
	}{
		{
			name:     "success",
			cfg:      getConfig,
			useTlS:   false,
			expected: expectedGraphql,
		},
		{
			name:     "with constellation",
			cfg:      configWithConstellation,
			useTlS:   false,
			expected: expectedGraphqlWithConstellation,
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			got, err := graphql(tc.cfg(), "dev", tc.useTlS, 1337, 0)
			if err != nil {
				t.Errorf("got error: %v", err)
			}

			if diff := cmp.Diff(tc.expected(), got); diff != "" {
				t.Error(diff)
			}
		})
	}
}

func expectedConsole() *Service {
	return &Service{
		Image:     "nhost/graphql-engine:v2.25.0.cli-migrations-v3",
		DependsOn: map[string]DependsOn{"graphql": {Condition: "service_healthy"}},
		Command: []string{
			"bash", "-c",
			`
                hasura-cli \
                    console \
                    --no-browser \
                    --endpoint http://graphql:8080 \
                    --address 0.0.0.0 \
                    --console-port 9695 \
                    --api-port 1337 \
                    --api-host http://dev.hasura.local.nhost.run \
                    --console-hge-endpoint http://dev.hasura.local.nhost.run:1337`,
		},
		EntryPoint: nil,
		Environment: map[string]string{
			"ENV1":                                                     "VALUE1",
			"ENV2":                                                     "VALUE2",
			"GRAPHITE_WEBHOOK_SECRET":                                  "webhookSecret",
			"HOME":                                                     "/tmp",
			"HASURA_GRAPHQL_ADMIN_INTERNAL_ERRORS":                     "true",
			"HASURA_GRAPHQL_ADMIN_SECRET":                              "adminSecret",
			"HASURA_GRAPHQL_CONSOLE_ASSETS_DIR":                        "/srv/console-assets",
			"HASURA_GRAPHQL_CORS_DOMAIN":                               "http://*.localhost,http://dev.dashboard.local.nhost.run:1337,http://*.hasura.local.nhost.run:1337",
			"HASURA_GRAPHQL_DATABASE_URL":                              "postgres://nhost_hasura@postgres:5432/local",
			"HASURA_GRAPHQL_DEV_MODE":                                  "false",
			"HASURA_GRAPHQL_DISABLE_CORS":                              "false",
			"HASURA_GRAPHQL_ENABLED_APIS":                              "metadata,graphql,config,pgdump",
			"HASURA_GRAPHQL_ENABLED_LOG_TYPES":                         "startup,http-log,webhook-log,websocket-log",
			"HASURA_GRAPHQL_ENABLE_ALLOWLIST":                          "true",
			"HASURA_GRAPHQL_ENABLE_CONSOLE":                            "false",
			"HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS":          "true",
			"HASURA_GRAPHQL_ENABLE_TELEMETRY":                          "false",
			"HASURA_GRAPHQL_EVENTS_HTTP_POOL_SIZE":                     "100",
			"HASURA_GRAPHQL_INFER_FUNCTION_PERMISSIONS":                "true",
			"HASURA_GRAPHQL_JWT_SECRET":                                `{"claims_map":{"x-hasura-allowed-roles":{"path":"$.roles"},"x-hasura-default-role":"viewer","x-hasura-org-id":{"default":"public","path":"$.org"},"x-hasura-user-id":{"path":"$.sub"}},"key":"jwtSecretKey","type":"HS256"}`,
			"HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_BATCH_SIZE":       "100",
			"HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL": "1000",
			"HASURA_GRAPHQL_LOG_LEVEL":                                 "info",
			"HASURA_GRAPHQL_PG_CONNECTIONS":                            "50",
			"HASURA_GRAPHQL_PG_TIMEOUT":                                "180",
			"HASURA_GRAPHQL_STRINGIFY_NUMERIC_TYPES":                   "false",
			"HASURA_GRAPHQL_TX_ISOLATION":                              "read-committed",
			"HASURA_GRAPHQL_UNAUTHORIZED_ROLE":                         "public",
			"HASURA_GRAPHQL_USE_PREPARED_STATEMENTS":                   "true",
			"HASURA_GRAPHQL_WS_READ_COOKIE":                            "false",
			"NHOST_ADMIN_SECRET":                                       "adminSecret",
			"NHOST_AUTH_URL":                                           "http://dev.auth.local.nhost.run:1337/v1",
			"NHOST_FUNCTIONS_URL":                                      "http://dev.functions.local.nhost.run:1337/v1",
			"NHOST_GRAPHQL_URL":                                        "http://dev.graphql.local.nhost.run:1337/v1",
			"NHOST_HASURA_URL":                                         "http://dev.hasura.local.nhost.run:1337",
			"NHOST_JWT_SECRET":                                         `{"claims_map":{"x-hasura-allowed-roles":{"path":"$.roles"},"x-hasura-default-role":"viewer","x-hasura-org-id":{"default":"public","path":"$.org"},"x-hasura-user-id":{"path":"$.sub"}},"key":"jwtSecretKey","type":"HS256"}`,
			"NHOST_REGION":                                             "local",
			"NHOST_STORAGE_URL":                                        "http://dev.storage.local.nhost.run:1337/v1",
			"NHOST_SUBDOMAIN":                                          "dev",
			"NHOST_WEBHOOK_SECRET":                                     "webhookSecret",
		},
		ExtraHosts: []string{
			"host.docker.internal:host-gateway",
			"dev.hasura.local.nhost.run:0.0.0.0",
		},
		HealthCheck: &HealthCheck{
			Test: []string{
				"CMD-SHELL",
				"timeout 1s bash -c ':> /dev/tcp/127.0.0.1/9695' || exit 1",
			},
			Timeout:     "60s",
			Interval:    "5s",
			StartPeriod: "60s",
		},
		Labels: map[string]string{
			"traefik.enable": "true",
			"traefik.http.routers.console.entrypoints":               "web",
			"traefik.http.routers.console.rule":                      "(HostRegexp(`^.+\\.hasura\\.local\\.nhost\\.run$`) || Host(`local.hasura.nhost.run`))",
			"traefik.http.routers.console.service":                   "console",
			"traefik.http.routers.console.tls":                       "false",
			"traefik.http.routers.migrate.entrypoints":               "web",
			"traefik.http.routers.migrate.rule":                      "(HostRegexp(`^.+\\.hasura\\.local\\.nhost\\.run$`) || Host(`local.hasura.nhost.run`))&& PathPrefix(`/apis/`)",
			"traefik.http.routers.migrate.service":                   "migrate",
			"traefik.http.routers.migrate.tls":                       "false",
			"traefik.http.services.console.loadbalancer.server.port": "9695",
			"traefik.http.services.migrate.loadbalancer.server.port": "1337",
		},
		Networks: nil,
		Ports:    nil,
		Restart:  "always",
		Volumes: []Volume{
			{Type: "bind", Source: "/path/to/nhost", Target: "/app", ReadOnly: new(false)},
		},
		WorkingDir: new("/app"),
	}
}

func TestConsole(t *testing.T) {
	t.Parallel()

	cases := []struct {
		name     string
		cfg      func() *model.ConfigConfig
		useTlS   bool
		expected func() *Service
	}{
		{
			name: "success",
			cfg: func() *model.ConfigConfig {
				cfg := getConfig()
				cfg.Hasura.Version = new("v2.25.0")

				return cfg
			},
			useTlS:   false,
			expected: expectedConsole,
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			got, err := console(tc.cfg(), "dev", 1337, tc.useTlS, "/path/to/nhost", 0, "")
			if err != nil {
				t.Fatalf("got error: %v", err)
			}

			if diff := cmp.Diff(tc.expected(), got); diff != "" {
				t.Error(diff)
			}
		})
	}
}

func TestConsoleHostUser(t *testing.T) {
	t.Parallel()

	cases := []struct {
		name     string
		hostUser string
		want     *string
	}{
		{
			name:     "set",
			hostUser: "1000:1000",
			want:     new("1000:1000"),
		},
		{
			name:     "unset",
			hostUser: "",
			want:     nil,
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			cfg := getConfig()
			cfg.Hasura.Version = new("v2.25.0")

			got, err := console(
				cfg, "dev", 1337, false, "/path/to/nhost", 0, tc.hostUser,
			)
			if err != nil {
				t.Fatalf("got error: %v", err)
			}

			if diff := cmp.Diff(tc.want, got.User); diff != "" {
				t.Error(diff)
			}
		})
	}
}