87 lines
3.7 KiB
Go
87 lines
3.7 KiB
Go
package runtime_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.sendico.io/tech/sxchnge/product/app/api"
|
|
"git.sendico.io/tech/sxchnge/product/app/profile"
|
|
sharedruntime "git.sendico.io/tech/sxchnge/product/app/runtime"
|
|
"git.sendico.io/tech/sxchnge/product/providers/sendico"
|
|
"git.sendico.io/tech/sxchnge/shared/database"
|
|
sharedmodel "git.sendico.io/tech/sxchnge/shared/model"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/testcontainers/testcontainers-go/modules/mongodb"
|
|
"go.uber.org/zap"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
func TestProfileStartsOnEmptyDatabase(t *testing.T) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
|
defer cancel()
|
|
container, err := mongodb.Run(ctx, "mongo:latest", mongodb.WithReplicaSet("rs"))
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { require.NoError(t, container.Terminate(context.Background())) })
|
|
uri, err := container.ConnectionString(ctx)
|
|
require.NoError(t, err)
|
|
endpoint, err := url.Parse(uri)
|
|
require.NoError(t, err)
|
|
query := endpoint.Query()
|
|
query.Set("directConnection", "true")
|
|
endpoint.RawQuery = query.Encode()
|
|
uri = endpoint.String()
|
|
factory, err := db.NewConnection(zap.NewNop(), &db.Config{Driver: db.Mongo, Settings: sharedmodel.SettingsT{"uri": uri, "database": "sxchnge_runtime"}})
|
|
require.NoError(t, err)
|
|
t.Cleanup(factory.CloseConnection)
|
|
data, err := os.ReadFile("../../config.example.yml")
|
|
require.NoError(t, err)
|
|
var example struct {
|
|
API api.Config `yaml:"api"`
|
|
}
|
|
require.NoError(t, yaml.Unmarshal(data, &example))
|
|
t.Setenv("SXCHNGE_DOMAIN", "localhost")
|
|
t.Setenv("SXCHNGE_API_PROTOCOL", "http")
|
|
t.Setenv("SXCHNGE_API_ENDPOINT", "/api/v1")
|
|
t.Setenv("SXCHNGE_JWT_SECRET", "test-only-signing-key-at-least-32-bytes")
|
|
example.API.Notifications.CAFile = "" // This startup test makes no notification RPCs.
|
|
root, routes := chi.NewRouter(), chi.NewRouter()
|
|
runtime, err := sharedruntime.CreateAPI(ctx, zap.NewNop(), &example.API, factory, root, routes, false, profile.Runtime())
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { require.NoError(t, runtime.Finish(context.Background())) })
|
|
root.Mount("/", routes)
|
|
result := httptest.NewRecorder()
|
|
root.ServeHTTP(result, httptest.NewRequest(http.MethodGet, "/api/v1/health", nil))
|
|
require.Equal(t, http.StatusOK, result.Code)
|
|
// Runtime auth routes are installed even with zero customers and no seed.
|
|
result = httptest.NewRecorder()
|
|
root.ServeHTTP(result, httptest.NewRequest(http.MethodPost, "/api/v1/accounts/login", nil))
|
|
require.Equal(t, http.StatusBadRequest, result.Code)
|
|
// Enabling the adapter validates credentials, composes once, and does not
|
|
// register any provider resource until a customer starts sign-up.
|
|
const source = "507f1f77bcf86cd799439011"
|
|
claims, err := json.Marshal(map[string]any{"id": source, "exp": time.Now().Add(time.Hour).Unix()})
|
|
require.NoError(t, err)
|
|
file := filepath.Join(t.TempDir(), "credential")
|
|
require.NoError(t, os.WriteFile(file, []byte("header."+base64.RawURLEncoding.EncodeToString(claims)+".signature"), 0600))
|
|
example.API.Sendico = &sendico.Config{APIURL: "https://api.example/api/v1", OrganizationID: source, SourceID: source, TokenFile: file}
|
|
dependencies, finish, err := sharedruntime.OpenDependencies(ctx, zap.NewNop(), &example.API, factory)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, dependencies.Auth.Facts)
|
|
require.NoError(t, finish(ctx))
|
|
example.API.Sendico.TokenFile = ""
|
|
_, _, err = sharedruntime.OpenDependencies(ctx, zap.NewNop(), &example.API, factory)
|
|
require.Error(t, err)
|
|
example.API.Notifications = nil
|
|
_, _, err = sharedruntime.OpenDependencies(ctx, zap.NewNop(), &example.API, factory)
|
|
require.Error(t, err)
|
|
}
|