File size: 4,398 Bytes
d6f631f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package testutils

import (
	"crypto/rand"
	"log/slog"
	"sync"
	"testing"
	"time"

	"github.com/oklog/ulid/v2"
	"github.com/stretchr/testify/require"
	"go.opentelemetry.io/otel/trace"
	"go.opentelemetry.io/otel/trace/noop"

	"github.com/openmeterio/openmeter/openmeter/customer"
	customeradapter "github.com/openmeterio/openmeter/openmeter/customer/adapter"
	customerservice "github.com/openmeterio/openmeter/openmeter/customer/service"
	entdb "github.com/openmeterio/openmeter/openmeter/ent/db"
	"github.com/openmeterio/openmeter/openmeter/entitlement"
	entitlementpgadapter "github.com/openmeterio/openmeter/openmeter/entitlement/adapter"
	meteradapter "github.com/openmeterio/openmeter/openmeter/meter/mockadapter"
	productcatalogadapter "github.com/openmeterio/openmeter/openmeter/productcatalog/adapter"
	"github.com/openmeterio/openmeter/openmeter/productcatalog/feature"
	"github.com/openmeterio/openmeter/openmeter/subject"
	subjectadapter "github.com/openmeterio/openmeter/openmeter/subject/adapter"
	subjectservice "github.com/openmeterio/openmeter/openmeter/subject/service"
	"github.com/openmeterio/openmeter/openmeter/testutils"
	"github.com/openmeterio/openmeter/openmeter/watermill/eventbus"
)

func NewTestULID(t *testing.T) string {
	t.Helper()

	return ulid.MustNew(ulid.Timestamp(time.Now().UTC()), rand.Reader).String()
}

var NewTestNamespace = NewTestULID

type TestEnv struct {
	Logger             *slog.Logger
	Tracer             trace.Tracer
	SubjectService     subject.Service
	CustomerService    customer.Service
	EntitlementAdapter entitlement.EntitlementRepo
	FeatureService     feature.FeatureConnector

	Client *entdb.Client
	db     *testutils.TestDB
	close  sync.Once
}

func (e *TestEnv) Close(t *testing.T) {
	t.Helper()

	e.close.Do(func() {
		if e.db != nil {
			if err := e.db.EntDriver.Close(); err != nil {
				t.Errorf("failed to close ent driver: %v", err)
			}

			if err := e.db.PGDriver.Close(); err != nil {
				t.Errorf("failed to postgres driver: %v", err)
			}
		}

		if e.Client != nil {
			if err := e.Client.Close(); err != nil {
				t.Errorf("failed to close ent client: %v", err)
			}
		}
	})
}

func NewTestEnv(t *testing.T) *TestEnv {
	t.Helper()

	// Init logger
	logger := testutils.NewDiscardLogger(t)

	tracer := noop.NewTracerProvider().Tracer("test_env")

	// Init database
	db := testutils.InitPostgresDB(t, testutils.PostgresDBStateEntMigrated)
	client := db.EntDriver.Client()

	// Init event publisher
	publisher := eventbus.NewMock(t)

	// Init meter service
	meterAdapter, err := meteradapter.New(nil)
	require.NoErrorf(t, err, "initializing meter adapter must not fail")
	require.NotNilf(t, meterAdapter, "meter adapter must not be nil")

	// Init feature service
	featureAdapter := productcatalogadapter.NewPostgresFeatureRepo(client, logger)
	featureService := feature.NewFeatureConnector(featureAdapter, meterAdapter, publisher)

	// Entitlement Adapter
	entitlementDBAdapter := entitlementpgadapter.NewPostgresEntitlementRepo(client)
	require.NotNilf(t, entitlementDBAdapter, "entitlement adapter must not be nil")

	// Init subject service
	subjectAdapter, err := subjectadapter.New(client)
	require.NoErrorf(t, err, "initializing subject adapter must not fail")
	require.NotNilf(t, subjectAdapter, "subject adapter must not be nil")

	subjectService, err := subjectservice.New(subjectAdapter)
	require.NoErrorf(t, err, "initializing subject service must not fail")
	require.NotNilf(t, subjectService, "subject service must not be nil")

	// Init Customer service
	customerAdapter, err := customeradapter.New(customeradapter.Config{
		Client: client,
		Logger: logger,
	})
	require.NoErrorf(t, err, "initializing customer adapter must not fail")
	require.NotNilf(t, customerAdapter, "customer adapter must not be nil")

	customerService, err := customerservice.New(customerservice.Config{
		Adapter:   customerAdapter,
		Publisher: publisher,
	})
	require.NoErrorf(t, err, "initializing subject service must not fail")
	require.NotNilf(t, customerService, "subject service must not be nil")

	return &TestEnv{
		Logger:             logger,
		Tracer:             tracer,
		FeatureService:     featureService,
		SubjectService:     subjectService,
		CustomerService:    customerService,
		EntitlementAdapter: entitlementDBAdapter,
		Client:             client,
		db:                 db,
		close:              sync.Once{},
	}
}