Skip to content

Commit 0f222b4

Browse files
authored
fix: GoFeatureFlagUser class was not serialized. (#33)
* fix: GoFeatureFlagUser class was not serialized. System.Text.Json does not serialize private members of a class. Since the class `GoFeatureFlagUser` had the following private members: ``` private string Key { get; set; } private bool Anonymous { get; set; } private Dictionary<string, object> Custom { get; set; } ``` When it was serialized as the User in GOFeatureFlagRequest, the Json that was returned was `{ "user": {}, ...` instead of `{ "user": { "key: : ...` This commit fixes this issue by making the property public and adding a test. * updates documents The name of the package was wrong it should be ***OpenFeature.Contrib.GOFeatureFlag*** and not *OpenFeature.Contrib.Providers.GOFeatureFlag* Signed-off-by: Eric Holton <[email protected]> * chore: fix white space Signed-off-by: Eric Holton <[email protected]> * chore: fix white space Signed-off-by: Eric Holton <[email protected]> --------- Signed-off-by: Eric Holton <[email protected]>
1 parent 370ea41 commit 0f222b4

File tree

4 files changed

+102
-61
lines changed

4 files changed

+102
-61
lines changed

src/OpenFeature.Contrib.Providers.GOFeatureFlag/GoFeatureFlagProvider.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,9 @@ public override async Task<ResolutionDetails<Value>> ResolveStructureValue(strin
244244
private async Task<GoFeatureFlagResponse> CallApi<T>(string flagKey, T defaultValue,
245245
EvaluationContext context = null)
246246
{
247-
var user = GoFeatureFlagUser.FromEvaluationContext(context);
248247
var request = new GOFeatureFlagRequest<T>
249248
{
250-
User = user,
249+
User = context,
251250
DefaultValue = defaultValue
252251
};
253252
var goffRequest = JsonSerializer.Serialize(request, _serializerOptions);
Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,65 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
3-
using OpenFeature.Contrib.Providers.GOFeatureFlag.exception;
4-
using OpenFeature.Model;
5-
6-
namespace OpenFeature.Contrib.Providers.GOFeatureFlag
7-
{
8-
/// <summary>
9-
/// GOFeatureFlagUser is the representation of a User inside GO Feature Flag.
10-
/// </summary>
11-
public class GoFeatureFlagUser
12-
{
13-
private const string AnonymousField = "anonymous";
14-
private const string KeyField = "targetingKey";
15-
private string Key { get; set; }
16-
private bool Anonymous { get; set; }
17-
private Dictionary<string, object> Custom { get; set; }
18-
19-
/**
20-
* FromEvaluationContext convert the evaluation context into a GOFeatureFlagUser Object.
21-
*/
22-
public static GoFeatureFlagUser FromEvaluationContext(EvaluationContext ctx)
23-
{
24-
try
25-
{
26-
if (ctx is null)
27-
throw new InvalidEvaluationContext("GO Feature Flag need an Evaluation context to work.");
28-
if (!ctx.GetValue(KeyField).IsString)
29-
throw new InvalidTargetingKey("targetingKey field MUST be a string.");
30-
}
31-
catch (KeyNotFoundException e)
32-
{
33-
throw new InvalidTargetingKey("targetingKey field is mandatory.", e);
34-
}
35-
36-
var anonymous = ctx.ContainsKey(AnonymousField) && ctx.GetValue(AnonymousField).IsBoolean
37-
? ctx.GetValue(AnonymousField).AsBoolean
38-
: false;
39-
40-
var custom = ctx.AsDictionary().ToDictionary(x => x.Key, x => x.Value.AsObject);
41-
custom.Remove(AnonymousField);
42-
custom.Remove(KeyField);
43-
44-
return new GoFeatureFlagUser
45-
{
46-
Key = ctx.GetValue("targetingKey").AsString,
47-
Anonymous = anonymous.Value,
48-
Custom = custom
49-
};
50-
}
51-
}
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
4+
using OpenFeature.Contrib.Providers.GOFeatureFlag.exception;
5+
using OpenFeature.Model;
6+
7+
namespace OpenFeature.Contrib.Providers.GOFeatureFlag
8+
{
9+
/// <summary>
10+
/// GOFeatureFlagUser is the representation of a User inside GO Feature Flag.
11+
/// </summary>
12+
public class GoFeatureFlagUser
13+
{
14+
private const string AnonymousField = "anonymous";
15+
private const string KeyField = "targetingKey";
16+
17+
/// <summary>
18+
/// The targeting key for the user.
19+
/// </summary>
20+
public string Key { get; private set; }
21+
22+
/// <summary>
23+
/// Is the user Anonymous.
24+
/// </summary>
25+
public bool Anonymous { get; private set; }
26+
27+
/// <summary>
28+
/// Additional Custom Data to pass to GO Feature Flag.
29+
/// </summary>
30+
public Dictionary<string, object> Custom { get; private set; }
31+
32+
/**
33+
* Convert the evaluation context into a GOFeatureFlagUser Object.
34+
*/
35+
public static implicit operator GoFeatureFlagUser(EvaluationContext ctx)
36+
{
37+
try
38+
{
39+
if (ctx is null)
40+
throw new InvalidEvaluationContext("GO Feature Flag need an Evaluation context to work.");
41+
if (!ctx.GetValue(KeyField).IsString)
42+
throw new InvalidTargetingKey("targetingKey field MUST be a string.");
43+
}
44+
catch (KeyNotFoundException e)
45+
{
46+
throw new InvalidTargetingKey("targetingKey field is mandatory.", e);
47+
}
48+
49+
var anonymous = ctx.ContainsKey(AnonymousField) && ctx.GetValue(AnonymousField).IsBoolean
50+
? ctx.GetValue(AnonymousField).AsBoolean
51+
: false;
52+
53+
var custom = ctx.AsDictionary().ToDictionary(x => x.Key, x => x.Value.AsObject);
54+
custom.Remove(AnonymousField);
55+
custom.Remove(KeyField);
56+
57+
return new GoFeatureFlagUser
58+
{
59+
Key = ctx.GetValue("targetingKey").AsString,
60+
Anonymous = anonymous.Value,
61+
Custom = custom
62+
};
63+
}
64+
}
5265
}

src/OpenFeature.Contrib.Providers.GOFeatureFlag/README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,32 @@ The first things we will do is install the **Open Feature SDK** and the **GO Fea
1515

1616
### .NET Cli
1717
```shell
18-
dotnet add package OpenFeature.Contrib.Providers.GOFeatureFlag
18+
dotnet add package OpenFeature.Contrib.GOFeatureFlag
1919
```
2020
### Package Manager
2121

2222
```shell
23-
NuGet\Install-Package OpenFeature.Contrib.Providers.GOFeatureFlag
23+
NuGet\Install-Package OpenFeature.Contrib.GOFeatureFlag
2424
```
2525
### Package Reference
2626

2727
```xml
28-
<PackageReference Include="OpenFeature.Contrib.Providers.GOFeatureFlag" />
28+
<PackageReference Include="OpenFeature.Contrib.GOFeatureFlag" />
2929
```
3030
### Packet cli
3131

3232
```shell
33-
paket add OpenFeature.Contrib.Providers.GOFeatureFlag
33+
paket add OpenFeature.Contrib.GOFeatureFlag
3434
```
3535

3636
### Cake
3737

3838
```shell
39-
// Install OpenFeature.Contrib.Providers.GOFeatureFlag as a Cake Addin
40-
#addin nuget:?package=OpenFeature.Contrib.Providers.GOFeatureFlag
39+
// Install OpenFeature.Contrib.GOFeatureFlag as a Cake Addin
40+
#addin nuget:?package=OpenFeature.Contrib.GOFeatureFlag
4141

42-
// Install OpenFeature.Contrib.Providers.GOFeatureFlag as a Cake Tool
43-
#tool nuget:?package=OpenFeature.Contrib.Providers.GOFeatureFlag
42+
// Install OpenFeature.Contrib.GOFeatureFlag as a Cake Tool
43+
#tool nuget:?package=OpenFeature.Contrib.GOFeatureFlag
4444
```
4545

4646
## Initialize your Open Feature client
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System.Text.Json;
2+
3+
using OpenFeature.Model;
4+
5+
using Xunit;
6+
7+
namespace OpenFeature.Contrib.Providers.GOFeatureFlag.Test;
8+
9+
public class GoFeatureFlagUserTest
10+
{
11+
[Fact]
12+
public void GoFeatureFlagUserSerializesCorrectly()
13+
{
14+
var userContext = EvaluationContext.Builder()
15+
.Set("targetingKey", "1d1b9238-2591-4a47-94cf-d2bc080892f1")
16+
.Set("firstname", "john")
17+
.Set("lastname", "doe")
18+
.Set("email", "[email protected]")
19+
.Set("admin", true)
20+
.Set("anonymous", false)
21+
.Build();
22+
23+
GoFeatureFlagUser user = userContext;
24+
25+
var userAsString = JsonSerializer.Serialize(user, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
26+
27+
Assert.Contains("{\"key\":\"1d1b9238-2591-4a47-94cf-d2bc080892f1\",\"anonymous\":false,\"custom\":{", userAsString);
28+
}
29+
}

0 commit comments

Comments
 (0)