Skip to content

Commit

Permalink
Deserialize BT source and add fixture support to stripe-mock
Browse files Browse the repository at this point in the history
  • Loading branch information
remi-stripe committed Jul 23, 2018
1 parent d4141d6 commit 8eb8d8e
Show file tree
Hide file tree
Showing 7 changed files with 325 additions and 3 deletions.
40 changes: 40 additions & 0 deletions src/Stripe.net/Entities/BalanceTransactionSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace Stripe
{
using Newtonsoft.Json;
using Stripe.Infrastructure;

public enum BalanceTransactionSourceType
{
ApplicationFee,
Charge,
Dispute,
Payout,
Refund,
Transfer,
TransferReversal,
Topup,
Unknown,
}

[JsonConverter(typeof(BalanceTransactionSourceConverter))]
public class BalanceTransactionSource : StripeEntityWithId
{
public BalanceTransactionSourceType Type { get; set; }

public StripeApplicationFee ApplicationFee { get; set; }

public StripeCharge Charge { get; set; }

public StripeDispute Dispute { get; set; }

public StripePayout Payout { get; set; }

public StripeRefund Refund { get; set; }

public StripeTransfer Transfer { get; set; }

public StripeTransferReversal TransferReversal { get; set; }

public StripeTopup Topup { get; set; }
}
}
6 changes: 3 additions & 3 deletions src/Stripe.net/Entities/StripeBalanceTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ public class StripeBalanceTransaction : StripeEntityWithId
[JsonProperty("net")]
public int Net { get; set; }

#region Expandable Source
#region Expandable BalanceTransactionSource
public string SourceId { get; set; }

[JsonIgnore]
public StripeSource Source { get; set; }
public BalanceTransactionSource Source { get; set; }

[JsonProperty("source")]
internal object InternalSource
{
set
{
StringOrObject<StripeSource>.Map(value, s => this.SourceId = s, o => this.Source = o);
StringOrObject<BalanceTransactionSource>.Map(value, s => this.SourceId = s, o => this.Source = o);
}
}
#endregion
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
namespace Stripe.Infrastructure
{
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

internal class BalanceTransactionSourceConverter : JsonConverter
{
public override bool CanWrite => false;

public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var incoming = JObject.FromObject(value);

incoming.WriteTo(writer);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var incoming = JObject.Load(reader);

var source = new BalanceTransactionSource
{
Id = incoming.SelectToken("id").ToString()
};

if (incoming.SelectToken("object")?.ToString() == "application_fee")
{
source.Type = BalanceTransactionSourceType.ApplicationFee;
source.ApplicationFee = Mapper<StripeApplicationFee>.MapFromJson(incoming.ToString());
}
else if (incoming.SelectToken("object")?.ToString() == "charge")
{
source.Type = BalanceTransactionSourceType.Charge;
source.Charge = Mapper<StripeCharge>.MapFromJson(incoming.ToString());
}
else if (incoming.SelectToken("object")?.ToString() == "dispute")
{
source.Type = BalanceTransactionSourceType.Dispute;
source.Dispute = Mapper<StripeDispute>.MapFromJson(incoming.ToString());
}
else if (incoming.SelectToken("object")?.ToString() == "payout")
{
source.Type = BalanceTransactionSourceType.Payout;
source.Payout = Mapper<StripePayout>.MapFromJson(incoming.ToString());
}
else if (incoming.SelectToken("object")?.ToString() == "refund")
{
source.Type = BalanceTransactionSourceType.Refund;
source.Refund = Mapper<StripeRefund>.MapFromJson(incoming.ToString());
}
else if (incoming.SelectToken("object")?.ToString() == "transfer")
{
source.Type = BalanceTransactionSourceType.Transfer;
source.Transfer = Mapper<StripeTransfer>.MapFromJson(incoming.ToString());
}
else if (incoming.SelectToken("object")?.ToString() == "transfer_reversal")
{
source.Type = BalanceTransactionSourceType.TransferReversal;
source.TransferReversal = Mapper<StripeTransferReversal>.MapFromJson(incoming.ToString());
}
else if (incoming.SelectToken("object")?.ToString() == "topup")
{
source.Type = BalanceTransactionSourceType.Topup;
source.Topup = Mapper<StripeTopup>.MapFromJson(incoming.ToString());
}
else
{
source.Type = BalanceTransactionSourceType.Unknown;
}

return source;
}
}
}
18 changes: 18 additions & 0 deletions src/StripeTests/BaseStripeTest.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
namespace StripeTests
{
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading;

using Stripe;
Expand Down Expand Up @@ -92,6 +95,21 @@ protected static string GetFixture(string path, string[] expansions)
}
}

/// <summary>
/// Gets a resource file and returns its contents in a string.
/// </summary>
/// <param name="path">Path to the resource file</param>
/// <returns>File contents</returns>
protected static string GetResourceAsString(string path)
{
var fullpath = "StripeTests.Resources." + path;
var json = new StreamReader(
typeof(BaseStripeTest).GetTypeInfo().Assembly.GetManifestResourceStream(fullpath),
Encoding.UTF8).ReadToEnd();

return json;
}

/// <summary>
/// Checks that stripe-mock is running and that it's a recent enough version.
/// </summary>
Expand Down
99 changes: 99 additions & 0 deletions src/StripeTests/Entities/StripeBalanceTransactionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
namespace StripeTests
{
using System;
using System.IO;
using System.Reflection;
using System.Text;

using Newtonsoft.Json;
using Stripe;
using Xunit;

public class StripeBalanceTransactionTest : BaseStripeTest
{
[Fact]
public void Deserialize()
{
string json = GetFixture("/v1/balance/history/txn_123");
var balanceTransaction = Mapper<StripeBalanceTransaction>.MapFromJson(json);
Assert.NotNull(balanceTransaction);
Assert.IsType<StripeBalanceTransaction>(balanceTransaction);
Assert.NotNull(balanceTransaction.Id);
Assert.Equal("balance_transaction", balanceTransaction.Object);
}

[Fact]
public void DeserializeWithExpansions()
{
// We test all balance transaction possible source types to ensure the deserializer
// works as expectes.
var json = GetResourceAsString("api_fixtures.balance_transaction_with_expansion.json");
var balanceTransactions = Mapper<StripeList<StripeBalanceTransaction>>.MapFromJson(json);

Assert.NotNull(balanceTransactions);
Assert.NotNull(balanceTransactions.Data);
Assert.Equal(9, balanceTransactions.Data.Count);

Assert.NotNull(balanceTransactions.Data[0]);
Assert.Equal("balance_transaction", balanceTransactions.Data[0].Object);
Assert.NotNull(balanceTransactions.Data[0].Source);
Assert.Equal(BalanceTransactionSourceType.ApplicationFee, balanceTransactions.Data[0].Source.Type);
Assert.NotNull(balanceTransactions.Data[0].Source.ApplicationFee);
Assert.Equal("application_fee", balanceTransactions.Data[0].Source.ApplicationFee.Object);

Assert.NotNull(balanceTransactions.Data[1]);
Assert.Equal("balance_transaction", balanceTransactions.Data[1].Object);
Assert.NotNull(balanceTransactions.Data[1].Source);
Assert.Equal(BalanceTransactionSourceType.Charge, balanceTransactions.Data[1].Source.Type);
Assert.NotNull(balanceTransactions.Data[1].Source.Charge);
Assert.Equal("charge", balanceTransactions.Data[1].Source.Charge.Object);

Assert.NotNull(balanceTransactions.Data[2]);
Assert.Equal("balance_transaction", balanceTransactions.Data[2].Object);
Assert.NotNull(balanceTransactions.Data[2].Source);
Assert.Equal(BalanceTransactionSourceType.Dispute, balanceTransactions.Data[2].Source.Type);
Assert.NotNull(balanceTransactions.Data[2].Source.Dispute);
Assert.Equal("dispute", balanceTransactions.Data[2].Source.Dispute.Object);

Assert.NotNull(balanceTransactions.Data[3]);
Assert.Equal("balance_transaction", balanceTransactions.Data[3].Object);
Assert.NotNull(balanceTransactions.Data[3].Source);
Assert.Equal(BalanceTransactionSourceType.Payout, balanceTransactions.Data[3].Source.Type);
Assert.NotNull(balanceTransactions.Data[3].Source.Payout);
Assert.Equal("payout", balanceTransactions.Data[3].Source.Payout.Object);

Assert.NotNull(balanceTransactions.Data[4]);
Assert.Equal("balance_transaction", balanceTransactions.Data[4].Object);
Assert.NotNull(balanceTransactions.Data[4].Source);
Assert.Equal(BalanceTransactionSourceType.Refund, balanceTransactions.Data[4].Source.Type);
Assert.NotNull(balanceTransactions.Data[4].Source.Refund);
Assert.Equal("refund", balanceTransactions.Data[4].Source.Refund.Object);

Assert.NotNull(balanceTransactions.Data[5]);
Assert.Equal("balance_transaction", balanceTransactions.Data[5].Object);
Assert.NotNull(balanceTransactions.Data[5].Source);
Assert.Equal(BalanceTransactionSourceType.Transfer, balanceTransactions.Data[5].Source.Type);
Assert.NotNull(balanceTransactions.Data[5].Source.Transfer);
Assert.Equal("transfer", balanceTransactions.Data[5].Source.Transfer.Object);

Assert.NotNull(balanceTransactions.Data[6]);
Assert.Equal("balance_transaction", balanceTransactions.Data[6].Object);
Assert.NotNull(balanceTransactions.Data[6].Source);
Assert.Equal(BalanceTransactionSourceType.TransferReversal, balanceTransactions.Data[6].Source.Type);
Assert.NotNull(balanceTransactions.Data[6].Source.TransferReversal);
Assert.Equal("transfer_reversal", balanceTransactions.Data[6].Source.TransferReversal.Object);

Assert.NotNull(balanceTransactions.Data[7]);
Assert.Equal("balance_transaction", balanceTransactions.Data[7].Object);
Assert.NotNull(balanceTransactions.Data[7].Source);
Assert.Equal(BalanceTransactionSourceType.Topup, balanceTransactions.Data[7].Source.Type);
Assert.NotNull(balanceTransactions.Data[7].Source.Topup);
Assert.Equal("topup", balanceTransactions.Data[7].Source.Topup.Object);

Assert.NotNull(balanceTransactions.Data[8]);
Assert.Equal("balance_transaction", balanceTransactions.Data[8].Object);
Assert.NotNull(balanceTransactions.Data[8].Source);
Assert.Equal(BalanceTransactionSourceType.Unknown, balanceTransactions.Data[8].Source.Type);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"object": "list",
"url": "/v1/balance/history",
"data": [
{
"id": "txn_100",
"object": "balance_transaction",
"source": {
"id": "fee_123",
"object": "application_fee",
},
},
{
"id": "txn_101",
"object": "balance_transaction",
"source": {
"id": "ch_123",
"object": "charge",
},
},
{
"id": "txn_102",
"object": "balance_transaction",
"source": {
"id": "dp_123",
"object": "dispute",
},
},
{
"id": "txn_103",
"object": "balance_transaction",
"source": {
"id": "po_123",
"object": "payout",
},
},
{
"id": "txn_104",
"object": "balance_transaction",
"source": {
"id": "re_123",
"object": "refund",
},
},
{
"id": "txn_105",
"object": "balance_transaction",
"source": {
"id": "tr_123",
"object": "transfer",
},
},
{
"id": "txn_106",
"object": "balance_transaction",
"source": {
"id": "trr_123",
"object": "transfer_reversal",
},
},
{
"id": "txn_107",
"object": "balance_transaction",
"source": {
"id": "tu_123",
"object": "topup",
},
},
{
"id": "txn_108",
"object": "balance_transaction",
"source": {
"id": "random",
"object": "unknown_object",
},
}
]
}


5 changes: 5 additions & 0 deletions src/StripeTests/StripeTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
<ProjectReference Include="..\Stripe.net\Stripe.net.csproj" />
</ItemGroup>

<!-- Include all API fixture files to use in the Test suite -->
<ItemGroup>
<EmbeddedResource Include="Resources\api_fixtures\*.json" />
</ItemGroup>

<PropertyGroup>
<CodeAnalysisRuleSet>..\_stylecop\StyleCopRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
Expand Down

0 comments on commit 8eb8d8e

Please sign in to comment.