Skip to content

Commit

Permalink
Fix handling of null values with AnyOf (#1661)
Browse files Browse the repository at this point in the history
  • Loading branch information
ob-stripe authored Jun 12, 2019
1 parent 93bc5ad commit a62936b
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 2 deletions.
28 changes: 27 additions & 1 deletion src/Stripe.net/Infrastructure/FormEncoding/FormEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private static List<KeyValuePair<string, object>> FlattenParamsValue(object valu
break;

case IAnyOf anyOf:
flatParams = FlattenParamsValue(anyOf.Value, keyPrefix);
flatParams = FlattenParamsAnyOf(anyOf, keyPrefix);
break;

case INestedOptions options:
Expand Down Expand Up @@ -144,6 +144,32 @@ private static List<KeyValuePair<string, object>> FlattenParamsValue(object valu
return flatParams;
}

/// <summary>
/// Returns a list of parameters for a given <see cref="IAnyOf"/> instance.
/// </summary>
/// <param name="anyOf">The instance for which to create the list of parameters.</param>
/// <param name="keyPrefix">The key under which new keys should be nested, if any.</param>
/// <returns>The list of parameters.</returns>
private static List<KeyValuePair<string, object>> FlattenParamsAnyOf(
IAnyOf anyOf,
string keyPrefix)
{
List<KeyValuePair<string, object>> flatParams = new List<KeyValuePair<string, object>>();

// If the value contained within the `AnyOf` instance is null, we don't encode it in the
// request. We do this to mimic the behavior of regular (non-`AnyOf`) properties in
// options classes, which are skipped by the encoder when they have a null value
// because it's the default value (cf. FlattenParamsOptions).
if (anyOf.Value == null)
{
return flatParams;
}

flatParams.AddRange(FlattenParamsValue(anyOf.Value, keyPrefix));

return flatParams;
}

/// <summary>
/// Returns a list of parameters for a given options class. If a key prefix is provided, the
/// keys for the new parameters will be nested under the key prefix. E.g. if the key prefix
Expand Down
24 changes: 24 additions & 0 deletions src/StripeTests/Infrastructure/FormEncoding/FormEncoderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,30 @@ public void CreateQueryString()
},
want = "any_of[foo]=bar"
},
new
{
data = new TestOptions
{
AnyOf = null, // AnyOf itself is null
},
want = string.Empty
},
new
{
data = new TestOptions
{
AnyOf = (string)null, // AnyOf is not null but AnyOf.Value is null
},
want = string.Empty
},
new
{
data = new TestOptions
{
AnyOf = (Dictionary<string, string>)null, // same as above, AnyOf.Value is null
},
want = string.Empty
},

// Array
new
Expand Down
94 changes: 94 additions & 0 deletions src/StripeTests/Services/Charges/ChargeCreateOptionsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
namespace StripeTests
{
using System;
using Stripe;
using Stripe.Infrastructure.FormEncoding;
using Xunit;

public class ChargeCreateOptionsTest : BaseStripeTest
{
[Fact]
public void Serialize()
{
var testCases = new[]
{
// No data
new
{
data = new ChargeCreateOptions { },
want = string.Empty
},

// Source is a non-null, non-empty string
new
{
data = new ChargeCreateOptions
{
Source = "tok_visa",
},
want = "source=tok_visa"
},

// Source is a non-null, empty string
new
{
data = new ChargeCreateOptions
{
Source = string.Empty,
},
want = "source="
},

// Source is a null string
new
{
data = new ChargeCreateOptions
{
Source = (string)null,
},
want = string.Empty
},

// Source is a non-null CardCreateNestedOptions
new
{
data = new ChargeCreateOptions
{
Source = new CardCreateNestedOptions
{
Number = "4242424242424242",
ExpMonth = 1,
ExpYear = 2030,
},
},
want = "source[object]=card&source[exp_month]=1&source[exp_year]=2030&source[number]=4242424242424242"
},

// Source is a null CardCreateNestedOptions
new
{
data = new ChargeCreateOptions
{
Source = (CardCreateNestedOptions)null,
},
want = string.Empty
},

// Source is null
new
{
data = new ChargeCreateOptions
{
Source = null,
},
want = string.Empty
},
};

foreach (var testCase in testCases)
{
Assert.Equal(testCase.want, FormEncoder.CreateQueryString(testCase.data));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void SerializeDateTimeNull()
Created = (DateTime?)null,
};

Assert.Equal("created=", FormEncoder.CreateQueryString(options));
Assert.Equal(string.Empty, FormEncoder.CreateQueryString(options));
}

[Fact]
Expand Down

0 comments on commit a62936b

Please sign in to comment.