Ctrl K
ComunidadGuías…

tests/single_namespace_test.go

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

Archivo original ↗Preguntar a KiBot
package main

import (
	"net/http"
	"testing"

	"github.com/shellhub-io/shellhub/pkg/api/authorizer"
	"github.com/shellhub-io/shellhub/pkg/api/requests"
	"github.com/shellhub-io/shellhub/pkg/models"
	"github.com/shellhub-io/shellhub/pkg/uuid"
	"github.com/shellhub-io/shellhub/tests/environment"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

// TestSingleNamespaceInstance sets a community instance up through the API, which binds the
// instance to the namespace the setup creates. A bound instance holds that namespace alone, so an
// account belongs to it or to nothing.
func TestSingleNamespaceInstance(t *testing.T) {
	t.Parallel()

	compose := environment.New(t, run).Up(t.Context())
	t.Cleanup(compose.Down)

	const (
		boundUsername  = "bound"
		boundNamespace = "boundspace"
	)

	setup := new(models.UserAuthResponse)
	resp, err := compose.Anonymous(t.Context()).
		SetBody(&requests.Setup{
			Name:      boundUsername,
			Username:  boundUsername,
			Email:     boundUsername + "@ossystems.com.br",
			Password:  ShellHubPassword,
			Namespace: boundNamespace,
		}).
		SetResult(setup).
		Post("/api/setup")
	require.NoError(t, err)
	require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())
	require.NotNil(t, setup.Tenant)

	tenant := *setup.Tenant

	t.Run("the API offers no route to create a namespace", func(t *testing.T) {
		resp, err := asBearer(t, compose, setup.Token).
			SetBody(map[string]string{"name": "secondspace"}).
			Post("/api/namespaces")
		require.NoError(t, err)
		assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode(), resp.String())
	})

	t.Run("the admin CLI refuses a second namespace", func(t *testing.T) {
		err := compose.CreateNamespace(t.Context(), boundUsername, "secondspace", uuid.Generate())
		require.ErrorContains(t, err, "this instance does not support multi-tenancy")

		namespaces := []models.Namespace{}
		resp, err := asBearer(t, compose, setup.Token).SetResult(&namespaces).Get("/api/namespaces")
		require.NoError(t, err)
		require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())
		require.Len(t, namespaces, 1)
		assert.Equal(t, boundNamespace, namespaces[0].Name)
	})

	t.Run("removing a member deletes their account, which belongs to no other namespace", func(t *testing.T) {
		const orphanUsername = "orphan"
		compose.NewUser(t, orphanUsername, "orphan@ossystems.com.br", ShellHubPassword)
		compose.NewMember(t, orphanUsername, boundNamespace, string(authorizer.RoleObserver))
		orphan := compose.AuthUser(t, orphanUsername, ShellHubPassword)

		resp, err := asBearer(t, compose, setup.Token).Delete("/api/namespaces/" + tenant + "/members/" + orphan.ID)
		require.NoError(t, err)
		require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())

		resp, err = compose.Anonymous(t.Context()).
			SetBody(map[string]string{"username": orphanUsername, "password": ShellHubPassword}).
			Post("/api/login")
		require.NoError(t, err)
		assert.Equal(t, http.StatusUnauthorized, resp.StatusCode(), "the removed member's account still signs in: %s", resp.String())
	})
}