...

Source file src/github.com/launchdarkly/go-sdk-common/v3/ldcontext/context_marshaling_test.go

Documentation: github.com/launchdarkly/go-sdk-common/v3/ldcontext

     1  package ldcontext
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  
     7  	"github.com/launchdarkly/go-sdk-common/v3/ldattr"
     8  	"github.com/launchdarkly/go-sdk-common/v3/lderrors"
     9  	"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
    10  	"github.com/launchdarkly/go-test-helpers/v3/jsonhelpers"
    11  
    12  	"github.com/launchdarkly/go-jsonstream/v3/jwriter"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  type contextSerializationParams struct {
    19  	context Context
    20  	json    string
    21  }
    22  
    23  func makeContextMarshalingAndUnmarshalingParams() []contextSerializationParams {
    24  	return []contextSerializationParams{
    25  		{NewWithKind("org", "key1"), `{"kind": "org", "key": "key1"}`},
    26  
    27  		{New("key1b"), `{"kind": "user", "key": "key1b"}`},
    28  
    29  		{NewBuilder("key1c").Kind("org").Build(),
    30  			`{"kind": "org", "key": "key1c"}`},
    31  
    32  		{NewBuilder("key2").Name("my-name").Build(),
    33  			`{"kind": "user", "key": "key2", "name": "my-name"}`},
    34  
    35  		{NewBuilder("key4").Anonymous(true).Build(),
    36  			`{"kind": "user", "key": "key4", "anonymous": true}`},
    37  		{NewBuilder("key5").Anonymous(false).Build(),
    38  			`{"kind": "user", "key": "key5"}`},
    39  
    40  		{NewBuilder("key6").SetBool("attr1", true).Build(),
    41  			`{"kind": "user", "key": "key6", "attr1": true}`},
    42  		{NewBuilder("key6").SetBool("attr1", false).Build(),
    43  			`{"kind": "user", "key": "key6", "attr1": false}`},
    44  		{NewBuilder("key6").SetInt("attr1", 123).Build(),
    45  			`{"kind": "user", "key": "key6", "attr1": 123}`},
    46  		{NewBuilder("key6").SetFloat64("attr1", 1.5).Build(),
    47  			`{"kind": "user", "key": "key6", "attr1": 1.5}`},
    48  		{NewBuilder("key6").SetString("attr1", "xyz").Build(),
    49  			`{"kind": "user", "key": "key6", "attr1": "xyz"}`},
    50  		{NewBuilder("key6").SetValue("attr1", ldvalue.ArrayOf(ldvalue.Int(10), ldvalue.Int(20))).Build(),
    51  			`{"kind": "user", "key": "key6", "attr1": [10, 20]}`},
    52  		{NewBuilder("key6").SetValue("attr1", ldvalue.ObjectBuild().Set("a", ldvalue.Int(1)).Build()).Build(),
    53  			`{"kind": "user", "key": "key6", "attr1": {"a": 1}}`},
    54  
    55  		{NewBuilder("key7").Private("a").PrivateRef(ldattr.NewRef("/b/c")).Build(),
    56  			`{"kind": "user", "key": "key7", "_meta": {"privateAttributes": ["a", "/b/c"]}}`},
    57  
    58  		{NewMulti(NewWithKind("org", "my-org-key"), New("my-user-key")),
    59  			`{"kind": "multi", "org": {"key": "my-org-key"}, "user": {"key": "my-user-key"}}`},
    60  	}
    61  }
    62  
    63  func makeContextMarshalingEventOutputFormatParams() []contextSerializationParams {
    64  	var ret []contextSerializationParams
    65  	for _, p := range makeContextMarshalingAndUnmarshalingParams() {
    66  		transformed := p
    67  		transformed.json = translateRegularContextJSONToEventOutputJSONAndViceVersa(transformed.json)
    68  		ret = append(ret, transformed)
    69  	}
    70  	return ret
    71  }
    72  
    73  func contextMarshalingTests(t *testing.T, marshalFn func(*Context) ([]byte, error)) {
    74  	for _, params := range makeContextMarshalingAndUnmarshalingParams() {
    75  		t.Run(params.json, func(t *testing.T) {
    76  			bytes, err := marshalFn(&params.context)
    77  			assert.NoError(t, err)
    78  			jsonhelpers.AssertEqual(t, params.json, bytes)
    79  		})
    80  	}
    81  
    82  	t.Run("invalid context", func(t *testing.T) {
    83  		c := New("")
    84  		_, err := marshalFn(&c)
    85  		require.Error(t, err)
    86  		assert.Contains(t, err.Error(), lderrors.ErrContextKeyEmpty{}.Error())
    87  		// We compare the error string, rather than checking for equality to errContextKeyEmpty itself, because
    88  		// the JSON marshaller may decorate the error in its own type with additional text.
    89  	})
    90  
    91  	t.Run("uninitialized context", func(t *testing.T) {
    92  		var c Context
    93  		_, err := marshalFn(&c)
    94  		require.Error(t, err)
    95  		assert.Contains(t, err.Error(), lderrors.ErrContextUninitialized{}.Error())
    96  	})
    97  }
    98  
    99  func jsonMarshalTestFn(c *Context) ([]byte, error) {
   100  	return json.Marshal(c)
   101  }
   102  
   103  func jsonStreamMarshalTestFn(c *Context) ([]byte, error) {
   104  	w := jwriter.NewWriter()
   105  	ContextSerialization.MarshalToJSONWriter(&w, c)
   106  	return w.Bytes(), w.Error()
   107  }
   108  
   109  func TestContextJSONMarshal(t *testing.T) {
   110  	contextMarshalingTests(t, jsonMarshalTestFn)
   111  }
   112  
   113  func TestContextWriteToJSONWriter(t *testing.T) {
   114  	contextMarshalingTests(t, jsonStreamMarshalTestFn)
   115  }
   116  
   117  func TestContextMarshalEventOutputFormat(t *testing.T) {
   118  	for _, p := range makeContextMarshalingEventOutputFormatParams() {
   119  		t.Run(p.json, func(t *testing.T) {
   120  			w := jwriter.NewWriter()
   121  			ec := EventOutputContext{Context: p.context}
   122  			ContextSerialization.MarshalToJSONWriterEventOutput(&w, &ec)
   123  			assert.NoError(t, w.Error())
   124  			jsonhelpers.AssertEqual(t, p.json, w.Bytes())
   125  		})
   126  	}
   127  
   128  	t.Run("invalid context", func(t *testing.T) {
   129  		c := New("")
   130  		ec := EventOutputContext{Context: c}
   131  		w := jwriter.NewWriter()
   132  		ContextSerialization.MarshalToJSONWriterEventOutput(&w, &ec)
   133  		require.Error(t, w.Error())
   134  		assert.Contains(t, w.Error().Error(), lderrors.ErrContextKeyEmpty{}.Error())
   135  	})
   136  
   137  	t.Run("uninitialized context", func(t *testing.T) {
   138  		var c Context
   139  		ec := EventOutputContext{Context: c}
   140  		w := jwriter.NewWriter()
   141  		ContextSerialization.MarshalToJSONWriterEventOutput(&w, &ec)
   142  		require.Error(t, w.Error())
   143  		assert.Contains(t, w.Error().Error(), lderrors.ErrContextUninitialized{}.Error())
   144  	})
   145  }
   146  
   147  func TestContextJSONStringIsEquivalentToJSONMarshal(t *testing.T) {
   148  	for _, params := range makeContextMarshalingAndUnmarshalingParams() {
   149  		t.Run(params.json, func(t *testing.T) {
   150  			bytes, err := json.Marshal(&params.context)
   151  			assert.NoError(t, err)
   152  			jsonhelpers.AssertEqual(t, string(bytes), params.context.JSONString())
   153  		})
   154  	}
   155  }
   156  

View as plain text