-
Notifications
You must be signed in to change notification settings - Fork 18
/
ldclient_test.go
112 lines (89 loc) · 4.11 KB
/
ldclient_test.go
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
package ldclient
import (
"errors"
"testing"
"time"
"github.com/launchdarkly/go-server-sdk/v7/internal/datastore"
"github.com/launchdarkly/go-server-sdk/v7/internal/sharedtest/mocks"
"github.com/launchdarkly/go-sdk-common/v3/lduser"
ldevents "github.com/launchdarkly/go-sdk-events/v3"
"github.com/launchdarkly/go-server-sdk/v7/internal/sharedtest"
"github.com/launchdarkly/go-server-sdk/v7/ldcomponents"
"github.com/launchdarkly/go-server-sdk/v7/subsystems"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const testSdkKey = "test-sdk-key"
func TestErrorFromComponentFactoryStopsClientCreation(t *testing.T) {
fakeError := errors.New("sorry")
doTest := func(name string, config Config, expectedError error) {
t.Run(name, func(t *testing.T) {
client, err := MakeCustomClient(testSdkKey, config, 0)
assert.Nil(t, client)
require.Error(t, err)
assert.Equal(t, expectedError.Error(), err.Error())
})
}
doTest("DataSource", Config{DataSource: mocks.ComponentConfigurerThatReturnsError[subsystems.DataSource]{Err: fakeError}}, fakeError)
doTest("DataStore", Config{DataStore: mocks.ComponentConfigurerThatReturnsError[subsystems.DataStore]{Err: fakeError}}, fakeError)
doTest("Events", Config{Events: mocks.ComponentConfigurerThatReturnsError[ldevents.EventProcessor]{Err: fakeError}}, fakeError)
doTest("HTTP", Config{HTTP: ldcomponents.HTTPConfiguration().CACert([]byte{1})}, errors.New("invalid CA certificate data"))
}
func TestSecureModeHash(t *testing.T) {
expected := "aa747c502a898200f9e4fa21bac68136f886a0e27aec70ba06daf2e2a5cb5597"
key := "Message"
config := Config{Offline: true}
client, _ := MakeCustomClient("secret", config, 0*time.Second)
hash := client.SecureModeHash(lduser.NewUser(key))
assert.Equal(t, expected, hash)
}
func TestMakeCustomClientWithFailedInitialization(t *testing.T) {
client, err := MakeCustomClient(testSdkKey, Config{
Logging: ldcomponents.Logging().Loggers(sharedtest.NewTestLoggers()),
DataSource: mocks.DataSourceThatNeverInitializes(),
Events: ldcomponents.NoEvents(),
}, time.Second)
assert.NotNil(t, client)
assert.Equal(t, err, ErrInitializationFailed)
}
func TestInvalidCharacterInSDKKey(t *testing.T) {
badKey := "my-bad-key\n"
_, err := MakeClient(badKey, time.Minute)
assert.Error(t, err)
assert.NotContains(t, err.Error(), "my-bad-key") // message shouldn't include the key value
_, err = MakeCustomClient(badKey, Config{}, time.Minute)
assert.Error(t, err)
assert.NotContains(t, err.Error(), "my-bad-key")
}
func makeTestClient() *LDClient {
return makeTestClientWithConfig(nil)
}
func makeTestClientWithConfig(modConfig func(*Config)) *LDClient {
return makeTestClientWithConfigAndStore(modConfig, func(store subsystems.DataStore) {})
}
// makeTestClientWithConfigAndStore is a variant of makeTestClientWithConfig, which allows you to also pre-populate the
// client's in-memory data store with some test data. The second argument is a callback that provides you access to the
// store; then you can call Upsert/Init to inject data.
func makeTestClientWithConfigAndStore(modConfig func(*Config), populate func(store subsystems.DataStore)) *LDClient {
config := Config{
Offline: false,
DataStore: populateStore(populate),
DataSource: mocks.DataSourceThatIsAlwaysInitialized(),
Events: mocks.SingleComponentConfigurer[ldevents.EventProcessor]{Instance: &mocks.CapturingEventProcessor{}},
Logging: ldcomponents.Logging().Loggers(sharedtest.NewTestLoggers()),
}
if modConfig != nil {
modConfig(&config)
}
client, _ := MakeCustomClient(testSdkKey, config, time.Duration(0))
return client
}
// The populateStore type exist so that we can implement the ComponentConfigurer interface
// on it. When the SDK configures the data store, we can hook in additional logic to populate the store
// via the callback provided in makeTestClientWithConfigAndStore.
type populateStore func(store subsystems.DataStore)
func (populate populateStore) Build(context subsystems.ClientContext) (subsystems.DataStore, error) {
inMemory := datastore.NewInMemoryDataStore(context.GetLogging().Loggers)
populate(inMemory)
return inMemory, nil
}