Skip to content
Browse files

basics

  • Loading branch information...
1 parent ffe298e commit 3f633b12d941a02eb345a46e8f98752f9b90a05d Tim Iles committed Mar 22, 2012
Showing with 74,511 additions and 0 deletions.
  1. +22 −0 .gitignore
  2. +49 −0 GoCardlessSdk.Net2/GoCardlessSdk.Net2.csproj
  3. +36 −0 GoCardlessSdk.Net2/Properties/AssemblyInfo.cs
  4. +37 −0 GoCardlessSdk.Tests/Api/CancelPreAuthorizationTests.cs
  5. +36 −0 GoCardlessSdk.Tests/Api/CancelSubscriptionTests.cs
  6. +7 −0 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_bills_213.txt
  7. +19 −0 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_bills_VZUG2SC3PRT5EM.txt
  8. +22 −0 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1.txt
  9. +36 −0 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_bills.txt
  10. +42 −0 ...dlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_pre_authorizations.txt
  11. +40 −0 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_subscriptions.txt
  12. +18 −0 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_users.txt
  13. +22 −0 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_pre_authorizations_1234JKH8KLJ.txt
  14. +21 −0 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_subscriptions_AJKH638A99.txt
  15. +19 −0 GoCardlessSdk.Tests/Api/Data/POST gocardless.com_api_v1_bills.txt
  16. +21 −0 GoCardlessSdk.Tests/Api/Data/PUT gocardless.com_api_v1_pre_authorizations_1580_cancel.txt
  17. +20 −0 GoCardlessSdk.Tests/Api/Data/PUT gocardless.com_api_v1_subscriptions_1580_cancel.txt
  18. +44 −0 GoCardlessSdk.Tests/Api/DeepAssertHelper.cs
  19. +22 −0 GoCardlessSdk.Tests/Api/DisposableEventHandler.cs
  20. +45 −0 GoCardlessSdk.Tests/Api/FiddlerSetupFixture.cs
  21. +35 −0 GoCardlessSdk.Tests/Api/GetBillTests.cs
  22. +24 −0 GoCardlessSdk.Tests/Api/GetErrorTests.cs
  23. +55 −0 GoCardlessSdk.Tests/Api/GetMerchantBillTests.cs
  24. +62 −0 GoCardlessSdk.Tests/Api/GetMerchantPreAuthorizationsTests.cs
  25. +61 −0 GoCardlessSdk.Tests/Api/GetMerchantSubscriptionsTests.cs
  26. +39 −0 GoCardlessSdk.Tests/Api/GetMerchantTests.cs
  27. +35 −0 GoCardlessSdk.Tests/Api/GetMerchantUsersTests.cs
  28. +38 −0 GoCardlessSdk.Tests/Api/GetPreAuthorizationTests.cs
  29. +37 −0 GoCardlessSdk.Tests/Api/GetSubscriptionTests.cs
  30. +52 −0 GoCardlessSdk.Tests/Api/PostBillTests.cs
  31. +34 −0 GoCardlessSdk.Tests/Connect/ConnectTests.cs
  32. +134 −0 GoCardlessSdk.Tests/GoCardlessSdk.Tests.csproj
  33. +36 −0 GoCardlessSdk.Tests/Properties/AssemblyInfo.cs
  34. +139 −0 GoCardlessSdk.Tests/UtilsTests.cs
  35. +25 −0 GoCardlessSdk.Tests/WebHooks/Data/test invalid signature.txt
  36. +25 −0 GoCardlessSdk.Tests/WebHooks/Data/test valid signature.txt
  37. +26 −0 GoCardlessSdk.Tests/WebHooks/WebHooksTests.cs
  38. +5,184 −0 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/DotNet4/FiddlerCore4.XML
  39. BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/DotNet4/FiddlerCore4.dll
  40. +5,183 −0 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/FiddlerCore.XML
  41. BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/FiddlerCore.dll
  42. BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/FiddlerCore.pdb
  43. BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/FiddlerCore.shadow
  44. +14 −0 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/License.txt
  45. +111 −0 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/SampleApp/Demo.csproj
  46. +414 −0 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/SampleApp/Program.cs
  47. +36 −0 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/SampleApp/Properties/AssemblyInfo.cs
  48. +335 −0 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/SampleApp/SAZ-DOTNETZIP.cs
  49. +352 −0 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/SampleApp/SAZ-XCEEDZIP.cs
  50. BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/makecert.exe
  51. BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/uninst.exe
  52. +5 −0 GoCardlessSdk.Tests/packages.config
  53. +32 −0 GoCardlessSdk.sln
  54. +54 −0 GoCardlessSdk/AccountDetails.cs
  55. +146 −0 GoCardlessSdk/Api/ApiClient.cs
  56. +23 −0 GoCardlessSdk/Api/BillResponse.cs
  57. +35 −0 GoCardlessSdk/Api/Json/NewtonsoftJsonDeserializer.cs
  58. +17 −0 GoCardlessSdk/Api/Json/UnderscoreToCamelCasePropertyResolver.cs
  59. +58 −0 GoCardlessSdk/Api/MerchantResponse.cs
  60. +50 −0 GoCardlessSdk/Api/PreAuthorizationResponse.cs
  61. +34 −0 GoCardlessSdk/Api/SubscriptionResponse.cs
  62. +13 −0 GoCardlessSdk/Api/UserResponse.cs
  63. +11 −0 GoCardlessSdk/Connect/BillRequest.cs
  64. +11 −0 GoCardlessSdk/Connect/ConfirmResource.cs
  65. +184 −0 GoCardlessSdk/Connect/ConnectClient.cs
  66. +22 −0 GoCardlessSdk/Connect/PreAuthorizationRequest.cs
  67. +20 −0 GoCardlessSdk/Connect/SubscriptionRequest.cs
  68. +15 −0 GoCardlessSdk/Connect/UserRequest.cs
  69. +30 −0 GoCardlessSdk/Exceptions.cs
  70. +68 −0 GoCardlessSdk/GoCardless.cs
  71. +89 −0 GoCardlessSdk/GoCardlessSdk.csproj
  72. +8 −0 GoCardlessSdk/Partners/AuthorizeResponse.cs
  73. +13 −0 GoCardlessSdk/Partners/Merchant.cs
  74. +21 −0 GoCardlessSdk/Partners/MerchantAccessTokenResponse.cs
  75. +42 −0 GoCardlessSdk/Partners/PartnerClient.cs
  76. +7 −0 GoCardlessSdk/Partners/Prepopulated.cs
  77. +9 −0 GoCardlessSdk/Partners/User.cs
  78. +38 −0 GoCardlessSdk/Properties/AssemblyInfo.cs
  79. +200 −0 GoCardlessSdk/Utils.cs
  80. +41 −0 GoCardlessSdk/WebHooks/GoCardlessRequest.cs
  81. +29 −0 GoCardlessSdk/WebHooks/WebHooksClient.cs
  82. +5 −0 GoCardlessSdk/packages.config
  83. BIN packages/NUnit.2.6.0.12054/NUnit.2.6.0.12054.nupkg
  84. BIN packages/NUnit.2.6.0.12054/lib/nunit.framework.dll
  85. +10,845 −0 packages/NUnit.2.6.0.12054/lib/nunit.framework.xml
  86. +15 −0 packages/NUnit.2.6.0.12054/license.txt
  87. BIN packages/Newtonsoft.Json.4.5.1/Newtonsoft.Json.4.5.1.nupkg
  88. BIN packages/Newtonsoft.Json.4.5.1/lib/net20/Newtonsoft.Json.dll
  89. BIN packages/Newtonsoft.Json.4.5.1/lib/net20/Newtonsoft.Json.pdb
  90. +7,938 −0 packages/Newtonsoft.Json.4.5.1/lib/net20/Newtonsoft.Json.xml
  91. BIN packages/Newtonsoft.Json.4.5.1/lib/net35/Newtonsoft.Json.dll
  92. BIN packages/Newtonsoft.Json.4.5.1/lib/net35/Newtonsoft.Json.pdb
  93. +7,069 −0 packages/Newtonsoft.Json.4.5.1/lib/net35/Newtonsoft.Json.xml
  94. BIN packages/Newtonsoft.Json.4.5.1/lib/net40/Newtonsoft.Json.dll
  95. BIN packages/Newtonsoft.Json.4.5.1/lib/net40/Newtonsoft.Json.pdb
  96. +7,320 −0 packages/Newtonsoft.Json.4.5.1/lib/net40/Newtonsoft.Json.xml
  97. BIN packages/Newtonsoft.Json.4.5.1/lib/sl3-wp/Newtonsoft.Json.dll
  98. BIN packages/Newtonsoft.Json.4.5.1/lib/sl3-wp/Newtonsoft.Json.pdb
  99. +6,661 −0 packages/Newtonsoft.Json.4.5.1/lib/sl3-wp/Newtonsoft.Json.xml
  100. BIN packages/Newtonsoft.Json.4.5.1/lib/sl4-windowsphone71/Newtonsoft.Json.dll
  101. BIN packages/Newtonsoft.Json.4.5.1/lib/sl4-windowsphone71/Newtonsoft.Json.pdb
  102. +6,661 −0 packages/Newtonsoft.Json.4.5.1/lib/sl4-windowsphone71/Newtonsoft.Json.xml
  103. BIN packages/Newtonsoft.Json.4.5.1/lib/sl4/Newtonsoft.Json.dll
  104. BIN packages/Newtonsoft.Json.4.5.1/lib/sl4/Newtonsoft.Json.pdb
  105. +6,691 −0 packages/Newtonsoft.Json.4.5.1/lib/sl4/Newtonsoft.Json.xml
  106. BIN packages/Newtonsoft.Json.4.5.1/lib/winrt45/Newtonsoft.Json.dll
  107. BIN packages/Newtonsoft.Json.4.5.1/lib/winrt45/Newtonsoft.Json.pdb
  108. +6,912 −0 packages/Newtonsoft.Json.4.5.1/lib/winrt45/Newtonsoft.Json.xml
  109. BIN packages/RestSharp.102.7/RestSharp.102.7.nupkg
  110. BIN packages/RestSharp.102.7/lib/net35-client/RestSharp.dll
  111. BIN packages/RestSharp.102.7/lib/net35/RestSharp.dll
  112. BIN packages/RestSharp.102.7/lib/sl3-wp/RestSharp.WindowsPhone.dll
  113. BIN packages/RestSharp.102.7/lib/sl4-wp71/RestSharp.WindowsPhone.dll
  114. BIN packages/RestSharp.102.7/lib/sl4/RestSharp.Silverlight.dll
  115. +5 −0 packages/repositories.config
View
22 .gitignore
@@ -0,0 +1,22 @@
+obj
+bin
+Bin
+Bin/*
+bin/*
+deploy
+deploy/*
+_ReSharper.*
+*.csproj.user
+*.resharper.user
+*.ReSharper.user
+*.resharper
+*.suo
+*.cache
+~$*
+*.suo
+*.hbm.xml
+*.orig
+*.user
+Visual Studio 2010/
+*.Publish.xml
+packages/NHibernateProfiler.1.0.0.920/tools/log.txt
View
49 GoCardlessSdk.Net2/GoCardlessSdk.Net2.csproj
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C8AA0C78-ED08-4912-ABB5-921661A8E9C5}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>GoCardlessSdk.Net2</RootNamespace>
+ <AssemblyName>GoCardlessSdk.Net2</AssemblyName>
+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
36 GoCardlessSdk.Net2/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GoCardlessSdk.Net2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("GoCardlessSdk.Net2")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("be1cb8d4-18fd-44c5-bb26-069e578283be")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
View
37 GoCardlessSdk.Tests/Api/CancelPreAuthorizationTests.cs
@@ -0,0 +1,37 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class CancelPreAuthorizationTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new PreAuthorizationResponse
+ {
+ CreatedAt = DateTime.Parse("2011-02-18T15:25:58Z"),
+ Currency = "GBP",
+ Name = "Variable Payments For Tennis Court Rental",
+ Description = "You will be charged according to your monthly usage of the tennis courts",
+ ExpiresAt = null,
+ Id = "1609",
+ IntervalLength = 1,
+ IntervalUnit = "month",
+ MerchantId = "WOQRUJU9OH2HH1",
+ Status = "cancelled",
+ RemainingAmount = 65.0m,
+ UserId = "604",
+ MaxAmount = 70.0m,
+ Uri = "https://gocardless.com/api/v1/pre_authorizations/1609",
+ SubResourceUris =
+ {
+ Bills = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1609"
+ }
+ };
+
+ DeepAssertHelper.AssertDeepEquality(expected, new ApiClient("asdf").CancelPreAuthorization("1580"));
+ }
+ }
+}
View
36 GoCardlessSdk.Tests/Api/CancelSubscriptionTests.cs
@@ -0,0 +1,36 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class CancelSubscriptionTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new SubscriptionResponse
+ {
+ Amount = 44.0m,
+ IntervalLength = 1,
+ IntervalUnit = "month",
+ CreatedAt = DateTimeOffset.Parse("2011-09-12T13:51:30Z"),
+ Currency = "GBP",
+ Name = "London Gym Membership",
+ Description = "Entitles you to use all of the gyms around London",
+ ExpiresAt = null,
+ Id = "1580",
+ MerchantId = "WOQRUJU9OH2HH1",
+ Status = "cancelled",
+ UserId = "638",
+ Uri = "https://gocardless.com/api/v1/subscriptions/1580",
+ SubResourceUris =
+ {
+ Bills = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1580"
+ }
+ };
+
+ DeepAssertHelper.AssertDeepEquality(expected, new ApiClient("asdf").CancelSubscription("1580"));
+ }
+ }
+}
View
7 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_bills_213.txt
@@ -0,0 +1,7 @@
+HTTP/1.1 400
+
+{
+ "amount":[
+ "is not a number"
+ ]
+}
View
19 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_bills_VZUG2SC3PRT5EM.txt
@@ -0,0 +1,19 @@
+HTTP/1.1 200 OK
+
+{
+ "amount": "44.0",
+ "gocardless_fees": "0.44",
+ "partner_fees": "0",
+ "currency": "GBP",
+ "created_at": "2011-11-04T21: 41: 25Z",
+ "description": "Month 2 payment",
+ "id": "VZUG2SC3PRT5EM",
+ "name": "Bill 2 for Subscription description",
+ "paid_at": "2011-11-07T15: 00: 00Z",
+ "status": "paid",
+ "merchant_id": "WOQRUJU9OH2HH1",
+ "user_id": "FIVWCCVEST6S4D",
+ "source_type": "subscription",
+ "source_id": "YH1VEVQHYVB1UT",
+ "uri": "https://gocardless.com/api/v1/bills/VZUG2SC3PRT5EM"
+}
View
22 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1.txt
@@ -0,0 +1,22 @@
+HTTP/1.1 200 OK
+
+{
+ "created_at": "2011-11-18T17:07:09Z",
+ "description": null,
+ "id": "WOQRUJU9OH2HH1",
+ "name": "Tom's Delicious Chicken Shop",
+ "first_name": "Tom",
+ "last_name": "Blomfield",
+ "email": "tom@gocardless.com",
+ "uri": "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1",
+ "balance": "12.00",
+ "pending_balance": "0.00",
+ "next_payout_date": "2011-11-25T17: 07: 09Z",
+ "next_payout_amount": "12.00",
+ "sub_resource_uris": {
+ "users": "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/users",
+ "bills": "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills",
+ "pre_authorizations": "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/pre_authorizations",
+ "subscriptions": "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/subscriptions",
+ }
+}
View
36 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_bills.txt
@@ -0,0 +1,36 @@
+HTTP/1.1 200 OK
+
+[{
+ "amount": "44.0",
+ "gocardless_fees": "0.44",
+ "partner_fees": "0",
+ "currency": "GBP",
+ "created_at": "2011-11-04T21: 41: 25Z",
+ "description": "Month 2 payment",
+ "id": "VZUG2SC3PRT5EM",
+ "name": "Bill 2 for Subscription description",
+ "paid_at": "2011-11-07T15: 00: 00Z",
+ "status": "paid",
+ "merchant_id": "WOQRUJU9OH2HH1",
+ "user_id": "FIVWCCVEST6S4D",
+ "source_type": "subscription",
+ "source_id": "YH1VEVQHYVB1UT",
+ "uri": "https://gocardless.com/api/v1/bills/VZUG2SC3PRT5EM"
+},
+{
+ "amount": "44.0",
+ "gocardless_fees": "0.44",
+ "partner_fees": "0",
+ "currency": "GBP",
+ "created_at": "2011-11-04T21: 41: 25Z",
+ "description": "Month 2 payment",
+ "id": "VZUG2SC3PRT5EN",
+ "name": "Bill 2 for Subscription description",
+ "paid_at": "2011-11-07T15: 00: 00Z",
+ "status": "paid",
+ "merchant_id": "WOQRUJU9OH2HH1",
+ "user_id": "FIVWCCVEST6S4D",
+ "source_type": "subscription",
+ "source_id": "YH1VEVQHYVB1UT",
+ "uri": "https://gocardless.com/api/v1/bills/VZUG2SC3PRT5EM"
+}]
View
42 ....Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_pre_authorizations.txt
@@ -0,0 +1,42 @@
+HTTP/1.1 200 OK
+
+[{
+ "created_at":"2011-02-18T15:25:58Z",
+ "currency":"GBP",
+ "name":"Variable Payments For Tennis Court Rental",
+ "description":"You will be charged according to your monthly usage of the tennis courts",
+ "expires_at":null,
+ "id": "1234JKH8KLJ",
+ "interval_length":1,
+ "interval_unit":"month",
+ "merchant_id": "WOQRUJU9OH2HH1",
+ "status":"active",
+ "remaining_amount": "65.0",
+ "next_interval_start": "2012-02-20T00:00:00Z",
+ "user_id": "834JUH8KLJ",
+ "max_amount":"70.0",
+ "uri":"https://gocardless.com/api/v1/pre_authorizations/1609",
+ "sub_resource_uris":{
+ "bills":"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1609"
+ }
+},
+{
+ "created_at":"2011-02-18T15:25:58Z",
+ "currency":"GBP",
+ "name":"Variable Payments For Tennis Court Rental",
+ "description":"You will be charged according to your monthly usage of the tennis courts",
+ "expires_at":null,
+ "id": "1234JKH8KLJ",
+ "interval_length":1,
+ "interval_unit":"month",
+ "merchant_id": "WOQRUJU9OH2HH2",
+ "status":"active",
+ "remaining_amount": "65.0",
+ "next_interval_start": "2012-02-20T00:00:00Z",
+ "user_id": "834JUH8KLJ",
+ "max_amount":"70.0",
+ "uri":"https://gocardless.com/api/v1/pre_authorizations/1610",
+ "sub_resource_uris":{
+ "bills":"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1610"
+ }
+}]
View
40 ...ssSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_subscriptions.txt
@@ -0,0 +1,40 @@
+HTTP/1.1 200 OK
+
+[{
+ "amount":"44.0",
+ "interval_length":1,
+ "interval_unit":"month",
+ "created_at":"2011-09-12T13:51:30Z",
+ "currency":"GBP",
+ "name":"London Gym Membership",
+ "description":"Entitles you to use all of the gyms around London",
+ "expires_at":null,
+ "next_interval_start":"2011-10-12T13:51:30Z",
+ "id": "AJKH638A99",
+ "merchant_id":"WOQRUJU9OH2HH1",
+ "status":"active",
+ "user_id":"HJEH638AJD",
+ "uri":"https://gocardless.com/api/v1/subscriptions/1580",
+ "sub_resource_uris":{
+ "bills":"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1580"
+ }
+},
+{
+ "amount":"44.0",
+ "interval_length":1,
+ "interval_unit":"month",
+ "created_at":"2011-09-12T13:51:30Z",
+ "currency":"GBP",
+ "name":"London Gym Membership",
+ "description":"Entitles you to use all of the gyms around London",
+ "expires_at":null,
+ "next_interval_start":"2011-10-12T13:51:30Z",
+ "id": "AJKH638A9A",
+ "merchant_id":"WOQRUJU9OH2HH1",
+ "status":"active",
+ "user_id":"HJEH638AJD",
+ "uri":"https://gocardless.com/api/v1/subscriptions/1580",
+ "sub_resource_uris":{
+ "bills":"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1580"
+ }
+}]
View
18 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_users.txt
@@ -0,0 +1,18 @@
+HTTP/1.1 200 OK
+
+[
+ {
+ "created_at":"2011-11-18T17:06:15Z",
+ "email":"customer40@gocardless.com",
+ "id": "JKH8HGKL9H",
+ "first_name":"Frank",
+ "last_name":"Smith"
+ },
+ {
+ "created_at":"2011-11-19T14:16:15Z",
+ "email":"customer41@gocardless.com",
+ "id":"JKH8HGKL9I",
+ "first_name":"James",
+ "last_name":"Dean"
+ }
+]
View
22 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_pre_authorizations_1234JKH8KLJ.txt
@@ -0,0 +1,22 @@
+HTTP/1.1 200 OK
+
+{
+ "created_at":"2011-02-18T15:25:58Z",
+ "currency":"GBP",
+ "name":"Variable Payments For Tennis Court Rental",
+ "description":"You will be charged according to your monthly usage of the tennis courts",
+ "expires_at":null,
+ "id": "1234JKH8KLJ",
+ "interval_length":1,
+ "interval_unit":"month",
+ "merchant_id": "WOQRUJU9OH2HH1",
+ "status":"active",
+ "remaining_amount": "65.0",
+ "next_interval_start": "2012-02-20T00:00:00Z",
+ "user_id": "834JUH8KLJ",
+ "max_amount":"70.0",
+ "uri":"https://gocardless.com/api/v1/pre_authorizations/1610",
+ "sub_resource_uris":{
+ "bills":"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1610"
+ }
+}
View
21 GoCardlessSdk.Tests/Api/Data/GET gocardless.com_api_v1_subscriptions_AJKH638A99.txt
@@ -0,0 +1,21 @@
+HTTP/1.1 200 OK
+
+{
+ "amount":"44.0",
+ "interval_length":1,
+ "interval_unit":"month",
+ "created_at":"2011-09-12T13:51:30Z",
+ "currency":"GBP",
+ "name":"London Gym Membership",
+ "description":"Entitles you to use all of the gyms around London",
+ "expires_at":null,
+ "next_interval_start":"2011-10-12T13:51:30Z",
+ "id": "AJKH638A99",
+ "merchant_id":"WOQRUJU9OH2HH1",
+ "status":"active",
+ "user_id":"HJEH638AJD",
+ "uri":"https://gocardless.com/api/v1/subscriptions/1580",
+ "sub_resource_uris":{
+ "bills":"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1580"
+ }
+}
View
19 GoCardlessSdk.Tests/Api/Data/POST gocardless.com_api_v1_bills.txt
@@ -0,0 +1,19 @@
+HTTP/1.1 201 Created
+
+{
+ "amount": "10.00",
+ "gocardless_fees": "0.10",
+ "partner_fees": "0",
+ "currency": "GBP",
+ "created_at": "2011-11-22T11: 59: 12Z",
+ "description": null,
+ "id": "PWSDXRYSCOKA7Z",
+ "name": null,
+ "status": "pending",
+ "merchant_id": "6UFY9IJWGYBTAP",
+ "user_id": "BWJ2GP659OXPAU",
+ "paid_at": null,
+ "source_type": "pre_authorization",
+ "source_id": "FAZ6FGSMTCOZUG",
+ "uri": "https://gocardless.com/api/v1/bills/PWSDXRYSCOKA7Z"
+}
View
21 GoCardlessSdk.Tests/Api/Data/PUT gocardless.com_api_v1_pre_authorizations_1580_cancel.txt
@@ -0,0 +1,21 @@
+HTTP/1.1 200 OK
+
+{
+ "created_at":"2011-02-18T15:25:58Z",
+ "currency":"GBP",
+ "name":"Variable Payments For Tennis Court Rental",
+ "description":"You will be charged according to your monthly usage of the tennis courts",
+ "expires_at":null,
+ "id":1609,
+ "interval_length":1,
+ "interval_unit":"month",
+ "merchant_id":"WOQRUJU9OH2HH1",
+ "status":"cancelled",
+ "remaining_amount": "65.0",
+ "user_id":604,
+ "max_amount":"70.0",
+ "uri":"https://gocardless.com/api/v1/pre_authorizations/1609",
+ "sub_resource_uris":{
+ "bills":"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1609"
+ }
+}
View
20 GoCardlessSdk.Tests/Api/Data/PUT gocardless.com_api_v1_subscriptions_1580_cancel.txt
@@ -0,0 +1,20 @@
+HTTP/1.1 200 OK
+
+{
+ "amount":"44.0",
+ "interval_length":1,
+ "interval_unit":"month",
+ "created_at":"2011-09-12T13:51:30Z",
+ "currency":"GBP",
+ "name":"London Gym Membership",
+ "description":"Entitles you to use all of the gyms around London",
+ "expires_at":null,
+ "id":1580,
+ "merchant_id":"WOQRUJU9OH2HH1",
+ "status":"cancelled",
+ "user_id":638,
+ "uri":"https://gocardless.com/api/v1/subscriptions/1580",
+ "sub_resource_uris":{
+ "bills":"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1580"
+ }
+}
View
44 GoCardlessSdk.Tests/Api/DeepAssertHelper.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections;
+using System.Linq;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class DeepAssertHelper
+ {
+ public static void AssertIEnumerableDeepEquality(IEnumerable expected, IEnumerable actual, string prefix = "")
+ {
+ var expectedArray = expected.Cast<object>().ToArray();
+ var actualArray = actual.Cast<object>().ToArray();
+ Assert.AreEqual(expectedArray.Length, actualArray.Length, "IEnumerables should be the same length");
+ for (var i = 0; i < expectedArray.Length; i++)
+ {
+ AssertDeepEquality(expectedArray[i], actualArray[i], prefix + "Item[" + i + "].");
+ }
+ }
+
+ public static void AssertDeepEquality(object expected, object actual, string prefix = null)
+ {
+ if (expected == null && actual != null) Assert.Fail("Actual " + prefix + " was not null");
+ if (expected != null && actual == null) Assert.Fail("Actual " + prefix + " was null");
+ if (expected == null) return;
+ foreach (var property in expected.GetType().GetProperties())
+ {
+ var type = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
+ var expectedValue = property.GetValue(expected, null);
+ var actualValue = property.GetValue(actual, null);
+
+ if (type.IsValueType || type == typeof(string))
+ {
+ Assert.AreEqual(expectedValue, actualValue, prefix + property.Name);
+ }
+ else
+ {
+ AssertDeepEquality(expectedValue, actualValue, prefix + property.Name);
+ }
+ }
+
+ }
+ }
+}
View
22 GoCardlessSdk.Tests/Api/DisposableEventHandler.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class DisposableEventHandler<T> : IDisposable
+ {
+ private readonly Action<T> _remove;
+ private readonly T _t;
+
+ public DisposableEventHandler(Action<T> add, Action<T> remove, T t)
+ {
+ _remove = remove;
+ _t = t;
+ add(t);
+ }
+
+ public void Dispose()
+ {
+ _remove(_t);
+ }
+ }
+}
View
45 GoCardlessSdk.Tests/Api/FiddlerSetupFixture.cs
@@ -0,0 +1,45 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Net;
+using Fiddler;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ [SetUpFixture]
+ public class FiddlerSetupFixture
+ {
+ [SetUp]
+ public void StartFiddlerProxy()
+ {
+ GoCardless.Environment = GoCardless.Environments.Test;
+
+ FiddlerApplication.Startup(7883, FiddlerCoreStartupFlags.None | FiddlerCoreStartupFlags.DecryptSSL);
+ WebRequest.DefaultWebProxy = new WebProxy("localhost", 7883);
+
+ FiddlerApplication.BeforeRequest += BeforeRequest;
+ }
+
+ public static void BeforeRequest(Session oS)
+ {
+ var file = oS.url.Replace('/', '_').Split('?').First();
+ var method = oS.HTTPMethodIs("GET") ? "GET"
+ : oS.HTTPMethodIs("POST") ? "POST"
+ : oS.HTTPMethodIs("PUT") ? "PUT" : null;
+ oS.utilCreateResponseAndBypassServer();
+ var lines = File.ReadAllLines("./Api/Data/" + method + " " + file + ".txt");
+ oS.oResponse.headers = Parser.ParseResponse(lines.First());
+ oS.oResponse.headers.Add("Content-Type", "application/json");
+
+ oS.utilSetResponseBody(String.Join(Environment.NewLine, lines.Skip(2).ToArray()));
+ }
+
+ [TearDown]
+ public void StopFiddlerProxy()
+ {
+ FiddlerApplication.BeforeRequest -= BeforeRequest;
+ FiddlerApplication.oProxy.Detach();
+ }
+ }
+}
View
35 GoCardlessSdk.Tests/Api/GetBillTests.cs
@@ -0,0 +1,35 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetBillTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new BillResponse
+ {
+ Amount = 44.0m,
+ GocardlessFees = 0.44m,
+ PartnerFees = 0m,
+ Currency = "GBP",
+ CreatedAt = DateTimeOffset.Parse("2011-11-04T21: 41: 25Z"),
+ Description = "Month 2 payment",
+ Id = "VZUG2SC3PRT5EM",
+ Name = "Bill 2 for Subscription description",
+ PaidAt = DateTimeOffset.Parse("2011-11-07T15: 00: 00Z"),
+ Status = "paid",
+ MerchantId = "WOQRUJU9OH2HH1",
+ UserId = "FIVWCCVEST6S4D",
+ SourceType = "subscription",
+ SourceId = "YH1VEVQHYVB1UT",
+ Uri = "https://gocardless.com/api/v1/bills/VZUG2SC3PRT5EM"
+ };
+ DeepAssertHelper.AssertDeepEquality(expected, new ApiClient("asdf").GetBill("VZUG2SC3PRT5EM"));
+ }
+
+
+ }
+}
View
24 GoCardlessSdk.Tests/Api/GetErrorTests.cs
@@ -0,0 +1,24 @@
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetErrorTests
+ {
+ private static readonly JObject Expected = JObject.FromObject(new { amount = new[] { "is not a number" } });
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ try
+ {
+ new ApiClient("asdf").GetBill("213"); //the document returns a 400
+ Assert.Fail("Should have thrown an error instead of reaching this point");
+ }
+ catch (ApiException ex)
+ {
+ Assert.AreEqual(Expected.ToString(), ex.Content.ToString());
+ }
+ }
+ }
+}
View
55 GoCardlessSdk.Tests/Api/GetMerchantBillTests.cs
@@ -0,0 +1,55 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetMerchantBillTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new[]
+ {
+ new BillResponse
+ {
+ Amount = 44.0m,
+ GocardlessFees = 0.44m,
+ PartnerFees = 0m,
+ Currency = "GBP",
+ CreatedAt = DateTimeOffset.Parse("2011-11-04T21: 41: 25Z"),
+ Description = "Month 2 payment",
+ Id = "VZUG2SC3PRT5EM",
+ Name = "Bill 2 for Subscription description",
+ PaidAt = DateTimeOffset.Parse("2011-11-07T15: 00: 00Z"),
+ Status = "paid",
+ MerchantId = "WOQRUJU9OH2HH1",
+ UserId = "FIVWCCVEST6S4D",
+ SourceType = "subscription",
+ SourceId = "YH1VEVQHYVB1UT",
+ Uri = "https://gocardless.com/api/v1/bills/VZUG2SC3PRT5EM"
+ },
+ new BillResponse
+ {
+ Amount = 44.0m,
+ GocardlessFees = 0.44m,
+ PartnerFees = 0m,
+ Currency = "GBP",
+ CreatedAt = DateTimeOffset.Parse("2011-11-04T21: 41: 25Z"),
+ Description = "Month 2 payment",
+ Id = "VZUG2SC3PRT5EN",
+ Name = "Bill 2 for Subscription description",
+ PaidAt = DateTimeOffset.Parse("2011-11-07T15: 00: 00Z"),
+ Status = "paid",
+ MerchantId = "WOQRUJU9OH2HH1",
+ UserId = "FIVWCCVEST6S4D",
+ SourceType = "subscription",
+ SourceId = "YH1VEVQHYVB1UT",
+ Uri = "https://gocardless.com/api/v1/bills/VZUG2SC3PRT5EM"
+ }
+ };
+ DeepAssertHelper.AssertIEnumerableDeepEquality(expected, new ApiClient("asdf").GetMerchantBills("WOQRUJU9OH2HH1"));
+ }
+
+ }
+}
View
62 GoCardlessSdk.Tests/Api/GetMerchantPreAuthorizationsTests.cs
@@ -0,0 +1,62 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetMerchantPreAuthorizationsTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new[]
+ {
+ new PreAuthorizationResponse
+ {
+ CreatedAt = DateTimeOffset.Parse("2011-02-18T15:25:58Z"),
+ Currency = "GBP",
+ Name = "Variable Payments For Tennis Court Rental",
+ Description = "You will be charged according to your monthly usage of the tennis courts",
+ ExpiresAt = null,
+ Id = "1234JKH8KLJ",
+ IntervalLength = 1,
+ IntervalUnit = "month",
+ MerchantId = "WOQRUJU9OH2HH1",
+ Status = "active",
+ RemainingAmount = 65.0m,
+ NextIntervalStart = DateTimeOffset.Parse("2012-02-20T00:00:00Z"),
+ UserId = "834JUH8KLJ",
+ MaxAmount = 70.0m,
+ Uri = "https://gocardless.com/api/v1/pre_authorizations/1609",
+ SubResourceUris={
+ Bills="https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1609"
+ }
+ },
+ new PreAuthorizationResponse
+ {
+ CreatedAt = DateTimeOffset.Parse("2011-02-18T15:25:58Z"),
+ Currency = "GBP",
+ Name = "Variable Payments For Tennis Court Rental",
+ Description = "You will be charged according to your monthly usage of the tennis courts",
+ ExpiresAt = null,
+ Id = "1234JKH8KLJ",
+ IntervalLength = 1,
+ IntervalUnit = "month",
+ MerchantId = "WOQRUJU9OH2HH2",
+ Status = "active",
+ RemainingAmount = 65.0m,
+ NextIntervalStart = DateTimeOffset.Parse("2012-02-20T00:00:00Z"),
+ UserId = "834JUH8KLJ",
+ MaxAmount = 70.0m,
+ Uri = "https://gocardless.com/api/v1/pre_authorizations/1610",
+ SubResourceUris={
+ Bills="https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1610"
+ }
+ },
+
+ };
+ DeepAssertHelper.AssertIEnumerableDeepEquality(expected, new ApiClient("asdf").GetMerchantPreAuthorizations("WOQRUJU9OH2HH1"));
+ }
+
+ }
+}
View
61 GoCardlessSdk.Tests/Api/GetMerchantSubscriptionsTests.cs
@@ -0,0 +1,61 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetMerchantSubscriptionsTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new[]
+ {
+ new SubscriptionResponse
+ {
+ Amount = 44.0m,
+ IntervalLength = 1,
+ IntervalUnit = "month",
+ CreatedAt = DateTimeOffset.Parse("2011-09-12T13:51:30Z"),
+ Currency = "GBP",
+ Name = "London Gym Membership",
+ Description = "Entitles you to use all of the gyms around London",
+ ExpiresAt = null,
+ NextIntervalStart = DateTimeOffset.Parse("2011-10-12T13:51:30Z"),
+ Id = "AJKH638A99",
+ MerchantId = "WOQRUJU9OH2HH1",
+ Status = "active",
+ UserId = "HJEH638AJD",
+ Uri = "https://gocardless.com/api/v1/subscriptions/1580",
+ SubResourceUris =
+ {
+ Bills = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1580"
+ }
+ }, new SubscriptionResponse
+ {
+ Amount = 44.0m,
+ IntervalLength = 1,
+ IntervalUnit = "month",
+ CreatedAt = DateTimeOffset.Parse("2011-09-12T13:51:30Z"),
+ Currency = "GBP",
+ Name = "London Gym Membership",
+ Description = "Entitles you to use all of the gyms around London",
+ ExpiresAt = null,
+ NextIntervalStart = DateTimeOffset.Parse("2011-10-12T13:51:30Z"),
+ Id = "AJKH638A9A",
+ MerchantId = "WOQRUJU9OH2HH1",
+ Status = "active",
+ UserId = "HJEH638AJD",
+ Uri = "https://gocardless.com/api/v1/subscriptions/1580",
+ SubResourceUris =
+ {
+ Bills = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1580"
+ }
+ }
+
+ };
+ DeepAssertHelper.AssertIEnumerableDeepEquality(expected, new ApiClient("asdf").GetMerchantSubscriptions("WOQRUJU9OH2HH1"));
+ }
+
+ }
+}
View
39 GoCardlessSdk.Tests/Api/GetMerchantTests.cs
@@ -0,0 +1,39 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetMerchantTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new MerchantResponse
+ {
+ CreatedAt = DateTimeOffset.Parse("2011-11-18T17:07:09Z"),
+ Description = null,
+ Id = "WOQRUJU9OH2HH1",
+ Name = "Tom's Delicious Chicken Shop",
+ FirstName = "Tom",
+ LastName = "Blomfield",
+ Email = "tom@gocardless.com",
+ Uri = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1",
+ Balance = 12.00m,
+ PendingBalance = 0.00m,
+ NextPayoutDate = DateTimeOffset.Parse("2011-11-25T17: 07: 09Z"),
+ NextPayoutAmount = 12.00m,
+ SubResourceUris =
+ {
+ Users = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/users",
+ Bills = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills",
+ PreAuthorizations = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/pre_authorizations",
+ Subscriptions = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/subscriptions",
+ }
+ };
+ DeepAssertHelper.AssertDeepEquality(expected, new ApiClient("asdf").GetMerchant("WOQRUJU9OH2HH1"));
+ }
+
+
+ }
+}
View
35 GoCardlessSdk.Tests/Api/GetMerchantUsersTests.cs
@@ -0,0 +1,35 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetMerchantUsersTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new[]
+ {
+ new UserResponse
+ {
+ CreatedAt = DateTimeOffset.Parse("2011-11-18T17:06:15Z"),
+ Email = "customer40@gocardless.com",
+ Id = "JKH8HGKL9H",
+ FirstName = "Frank",
+ LastName = "Smith"
+ },
+ new UserResponse
+ {
+ CreatedAt = DateTimeOffset.Parse("2011-11-19T14:16:15Z"),
+ Email = "customer41@gocardless.com",
+ Id = "JKH8HGKL9I",
+ FirstName = "James",
+ LastName = "Dean"
+ }
+ };
+ DeepAssertHelper.AssertIEnumerableDeepEquality(expected, new ApiClient("asdf").GetMerchantUsers("WOQRUJU9OH2HH1"));
+ }
+
+ }
+}
View
38 GoCardlessSdk.Tests/Api/GetPreAuthorizationTests.cs
@@ -0,0 +1,38 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetPreAuthorizationTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new PreAuthorizationResponse
+ {
+ CreatedAt = DateTimeOffset.Parse("2011-02-18T15:25:58Z"),
+ Currency = "GBP",
+ Name = "Variable Payments For Tennis Court Rental",
+ Description = "You will be charged according to your monthly usage of the tennis courts",
+ ExpiresAt = null,
+ Id = "1234JKH8KLJ",
+ IntervalLength = 1,
+ IntervalUnit = "month",
+ MerchantId = "WOQRUJU9OH2HH1",
+ Status = "active",
+ RemainingAmount = 65.0m,
+ NextIntervalStart = DateTimeOffset.Parse("2012-02-20T00:00:00Z"),
+ UserId = "834JUH8KLJ",
+ MaxAmount = 70.0m,
+ Uri = "https://gocardless.com/api/v1/pre_authorizations/1610",
+ SubResourceUris =
+ {
+ Bills = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1610"
+ }
+ }
+ ;
+ DeepAssertHelper.AssertDeepEquality(expected, new ApiClient("asdf").GetPreAuthorization("1234JKH8KLJ"));
+ }
+ }
+}
View
37 GoCardlessSdk.Tests/Api/GetSubscriptionTests.cs
@@ -0,0 +1,37 @@
+using System;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class GetSubscriptionTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new SubscriptionResponse
+ {
+ Amount = 44.0m,
+ IntervalLength = 1,
+ IntervalUnit = "month",
+ CreatedAt = DateTimeOffset.Parse("2011-09-12T13:51:30Z"),
+ Currency = "GBP",
+ Name = "London Gym Membership",
+ Description = "Entitles you to use all of the gyms around London",
+ ExpiresAt = null,
+ NextIntervalStart = DateTimeOffset.Parse("2011-10-12T13:51:30Z"),
+ Id = "AJKH638A99",
+ MerchantId = "WOQRUJU9OH2HH1",
+ Status = "active",
+ UserId = "HJEH638AJD",
+ Uri = "https://gocardless.com/api/v1/subscriptions/1580",
+ SubResourceUris =
+ {
+ Bills = "https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?source_id=1580"
+ }
+ }
+ ;
+ DeepAssertHelper.AssertDeepEquality(expected, new ApiClient("asdf").GetSubscription("AJKH638A99"));
+ }
+ }
+}
View
52 GoCardlessSdk.Tests/Api/PostBillTests.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Text;
+using GoCardlessSdk.Api;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace GoCardlessSdk.Tests.Api
+{
+ public class PostBillTests
+ {
+ [Test]
+ public void CanFetchAndDeserializeCorrectly()
+ {
+ var expected = new BillResponse
+ {
+ Amount = 10.00m,
+ GocardlessFees = 0.10m,
+ PartnerFees = 0m,
+ Currency = "GBP",
+ CreatedAt = DateTime.Parse("2011-11-22T11: 59: 12Z"),
+ Description = null,
+ Id = "PWSDXRYSCOKA7Z",
+ Name = null,
+ Status = "pending",
+ MerchantId = "6UFY9IJWGYBTAP",
+ UserId = "BWJ2GP659OXPAU",
+ PaidAt = null,
+ SourceType = "pre_authorization",
+ SourceId = "FAZ6FGSMTCOZUG",
+ Uri = "https://gocardless.com/api/v1/bills/PWSDXRYSCOKA7Z"
+ };
+
+ DeepAssertHelper.AssertDeepEquality(expected, new ApiClient("asdf").PostBill(44, "AJKH638A99"));
+ }
+
+ [Test]
+ public void PostsDataCorrectly()
+ {
+
+ var body = null as string;
+ Fiddler.SessionStateHandler inspect = s =>
+ {
+ body = Encoding.UTF8.GetString(s.requestBodyBytes);
+ };
+ Fiddler.FiddlerApplication.BeforeRequest += inspect;
+ new ApiClient("asdf").PostBill(44, "AJKH638A99", "some name", "some description");
+ Fiddler.FiddlerApplication.BeforeRequest -= inspect;
+ var expected = JObject.Parse("{bill: { amount: 44.0, pre_authorization_id: 'AJKH638A99', name: 'some name', description: 'some description' }}");
+ Assert.AreEqual(expected.ToString(), JObject.Parse(body).ToString());
+ }
+ }
+}
View
34 GoCardlessSdk.Tests/Connect/ConnectTests.cs
@@ -0,0 +1,34 @@
+using System;
+using GoCardlessSdk.Connect;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.Connect
+{
+ public class ConnectTests
+ {
+ [Test]
+ public void NewSubscriptionUrl_GeneratesCorrectSignature()
+ {
+ var subscription = new SubscriptionRequest
+ {
+ Amount = 15m,
+ Name="Premium Account",
+ IntervalUnit = "month",
+ IntervalLength = 1,
+ MerchantId = "0190G74E3J",
+ };
+ GoCardless.Environment = GoCardless.Environments.Sandbox;
+ GoCardless.AccountDetails.AppId = "Y9ON6TY6bFamTVNQKq98fPYzb6z4RoHsKy1Fyi1V7LtlT3fgiF5VTfppt9HO3Y8f";
+ GoCardless.AccountDetails.AppSecret = "8ifu76Qi4HMJC1zSNf93WntQzJKpSmce0SwBNTA5HEqQY61aBTH7Nsx4w_HG1vUL";
+ GoCardless.GenerateNonce = () => "Q9gMPVBZixfRiQ9VnRdDyrrMiskqT0ox8IT+HO3ReWMxavlco0Fw8rva+ZcI";
+ GoCardless.GetUtcNow = () => new DateTimeOffset(new DateTime(2012, 03, 21, 08, 55, 56));
+
+ var url = ConnectClient.NewSubscriptionUrl(subscription);
+ var expected =
+ "https://sandbox.gocardless.com/connect/subscriptions/new?client_id=Y9ON6TY6bFamTVNQKq98fPYzb6z4RoHsKy1Fyi1V7LtlT3fgiF5VTfppt9HO3Y8f&nonce=Q9gMPVBZixfRiQ9VnRdDyrrMiskqT0ox8IT%2BHO3ReWMxavlco0Fw8rva%2BZcI&signature=4502dbbd24fe92136948408edf50f627b9cf3c333e7788f803b8a7d94d246799&subscription%5Bamount%5D=15.00&subscription%5Binterval_length%5D=1&subscription%5Binterval_unit%5D=month&subscription%5Bmerchant_id%5D=0190G74E3J&subscription%5Bname%5D=Premium%20Account&timestamp=2012-03-21T08%3A55%3A56Z";
+ Assert.AreEqual(expected, url);
+ }
+
+ // TODO: other endpoints
+ }
+}
View
134 GoCardlessSdk.Tests/GoCardlessSdk.Tests.csproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{5DE0A32E-5920-44CD-8272-1311094D6932}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>GoCardlessSdk.Tests</RootNamespace>
+ <AssemblyName>GoCardlessSdk.Tests</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="FiddlerCore4">
+ <HintPath>libs\FiddlerCoreAPI\DotNet4\FiddlerCore4.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Newtonsoft.Json.4.5.1\lib\net40\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.framework">
+ <HintPath>..\packages\NUnit.2.6.0.12054\lib\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Api\CancelPreAuthorizationTests.cs" />
+ <Compile Include="Api\CancelSubscriptionTests.cs" />
+ <Compile Include="Api\DeepAssertHelper.cs" />
+ <Compile Include="Api\DisposableEventHandler.cs" />
+ <Compile Include="Api\FiddlerSetupFixture.cs" />
+ <Compile Include="Api\GetBillTests.cs" />
+ <Compile Include="Api\GetErrorTests.cs" />
+ <Compile Include="Api\GetMerchantBillTests.cs" />
+ <Compile Include="Api\GetMerchantPreAuthorizationsTests.cs" />
+ <Compile Include="Api\GetMerchantSubscriptionsTests.cs" />
+ <Compile Include="Api\GetMerchantTests.cs" />
+ <Compile Include="Api\GetMerchantUsersTests.cs" />
+ <Compile Include="Api\GetPreAuthorizationTests.cs" />
+ <Compile Include="Api\GetSubscriptionTests.cs" />
+ <Compile Include="Api\PostBillTests.cs" />
+ <Compile Include="Connect\ConnectTests.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="UtilsTests.cs" />
+ <Compile Include="WebHooks\WebHooksTests.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_bills_213.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_bills_VZUG2SC3PRT5EM.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_bills.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_pre_authorizations.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_subscriptions.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_merchants_WOQRUJU9OH2HH1_users.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_pre_authorizations_1234JKH8KLJ.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\GET gocardless.com_api_v1_subscriptions_AJKH638A99.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\POST gocardless.com_api_v1_bills.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\PUT gocardless.com_api_v1_pre_authorizations_1580_cancel.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="Api\Data\PUT gocardless.com_api_v1_subscriptions_1580_cancel.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="WebHooks\Data\test invalid signature.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="WebHooks\Data\test valid signature.txt">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\GoCardlessSdk\GoCardlessSdk.csproj">
+ <Project>{36CDA1FB-4093-41ED-9879-CD18EFCCE80B}</Project>
+ <Name>GoCardlessSdk</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
36 GoCardlessSdk.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GoCardlessSdk.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("GoCardlessSdk.Tests")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("afda068d-db95-43c6-b3ff-f9eab06c3464")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
View
139 GoCardlessSdk.Tests/UtilsTests.cs
@@ -0,0 +1,139 @@
+using System;
+using System.Linq;
+using GoCardlessSdk.Connect;
+using GoCardlessSdk.Partners;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests
+{
+ public class UtilsTests
+ {
+ [Test]
+ public void NonceTest()
+ {
+ Assert.AreNotEqual(Utils.GenerateNonce(), Utils.GenerateNonce());
+ }
+
+ [Test]
+ public void ToUnderscoreCaseTests()
+ {
+ Assert.AreEqual("name", "name".ToUnderscoreCase());
+ Assert.AreEqual("name", "Name".ToUnderscoreCase());
+ Assert.AreEqual("name", "NAME".ToUnderscoreCase());
+ Assert.AreEqual("first_name", "FirstName".ToUnderscoreCase());
+ Assert.AreEqual("date_of_birth", "DateOfBirth".ToUnderscoreCase());
+ }
+
+ [Test]
+ public void ToHashtableTests()
+ {
+ var subscription = new SubscriptionRequest
+ {
+ Amount = 2m,
+ MerchantId = "merchant123",
+ User = new UserRequest
+ {
+ FirstName = "Tim",
+ Email = "blah@timiles.com"
+ }
+ };
+ var subscriptionHash = subscription.ToHashParams();
+ Assert.AreEqual(2m, subscriptionHash["amount"].Single());
+ Assert.AreEqual("merchant123", subscriptionHash["merchant_id"].Single());
+ Assert.AreEqual("Tim", subscriptionHash["user[first_name]"].Single());
+ Assert.AreEqual("blah@timiles.com", subscriptionHash["user[email]"].Single());
+
+ var prepopulated = new Prepopulated
+ {
+ Merchant = new Merchant
+ {
+ Name = "Mike the Merchant",
+ BillingAddress1 = "Flat 1",
+ BillingAddress2 = "200 High St",
+ BillingTown = "Townville",
+ BillingCounty = "Countyshire",
+ BillingPostcode = "AB12 3CD",
+ User = new User
+ {
+ FirstName = "Mike",
+ LastName = "Merchant",
+ Email = "mike@merchants.com",
+ }
+ }
+ };
+ var prepopulatedHash = prepopulated.ToHashParams();
+ Assert.AreEqual("Mike the Merchant", prepopulatedHash["merchant[name]"].Single());
+ Assert.AreEqual("Flat 1", prepopulatedHash["merchant[billing_address1]"].Single());
+ Assert.AreEqual("200 High St", prepopulatedHash["merchant[billing_address2]"].Single());
+ Assert.AreEqual("Townville", prepopulatedHash["merchant[billing_town]"].Single());
+ Assert.AreEqual("Countyshire", prepopulatedHash["merchant[billing_county]"].Single());
+ Assert.AreEqual("AB12 3CD", prepopulatedHash["merchant[billing_postcode]"].Single());
+ Assert.AreEqual("Mike", prepopulatedHash["merchant[user][first_name]"].Single());
+ Assert.AreEqual("Merchant", prepopulatedHash["merchant[user][last_name]"].Single());
+ Assert.AreEqual("mike@merchants.com", prepopulatedHash["merchant[user][email]"].Single());
+ }
+
+ [Test]
+ public void PercentEncodeTests()
+ {
+ Assert.AreEqual("Tim", "Tim".PercentEncode());
+ Assert.AreEqual("Tim%20Iles", "Tim Iles".PercentEncode());
+ Assert.AreEqual("%21%40%A3%24%25%5E%26%2A%28%29%2B%3D%5B%5D%7B%7D%3A%27%40%22%23%3F%3C%3E%2C%60%20",
+ "!@£$%^&*()+=[]{}:'@\"#?<>,` ".PercentEncode());
+ const string allValidChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
+ Assert.AreEqual(allValidChars, allValidChars.PercentEncode());
+ }
+
+ [Test]
+ public void ToQueryStringTests()
+ {
+ Assert.AreEqual("name=Tim", new UserRequest { Name = "Tim" }.ToQueryString());
+
+ var subscription = new SubscriptionRequest
+ {
+ Amount = 2m,
+ StartAt =
+ new DateTimeOffset(new DateTime(2011, 01, 01, 12, 00, 00)),
+ User =
+ new UserRequest
+ {
+ Name = "Tim Iles",
+ FirstName = "Tim",
+ }
+ };
+ Assert.AreEqual(
+ "amount=2.00&interval_length=0&start_at=2011-01-01T12%3A00%3A00Z&user%5Bfirst_name%5D=Tim&user%5Bname%5D=Tim%20Iles",
+ subscription.ToQueryString());
+ }
+
+ class SignatureTestModel
+ {
+ public string Foo { get; set; }
+ public object[] Example { get; set; }
+ }
+ [Test]
+ public void SignatureTest()
+ {
+ /* from API docs: (https://gocardless.com/docs/signature_guide#constructing-the-parameter-array)
+ * irb(main):002:0> to_query(data)
+ * => "example%5B%5D=1&example%5B%5D=a&foo=bar"
+ * irb(main):003:0> secret = '5PUZmVMmukNwiHc7V/TJvFHRQZWZumIpCnfZKrVYGpuAdkCcEfv3LIDSrsJ+xOVH'
+ * => "5PUZmVMmukNwiHc7V/TJvFHRQZWZumIpCnfZKrVYGpuAdkCcEfv3LIDSrsJ+xOVH"
+ * irb(main):004:0> signature(data, secret)
+ * => "5a9447aef2ebd0e12d80d80c836858c6f9c13219f615ef5d135da408bcad453d"
+ */
+
+ var model = new SignatureTestModel
+ {
+ Foo = "bar",
+ Example = new object[] {1, 'a'}
+ };
+ var hash = model.ToHashParams();
+ Assert.AreEqual("example%5B%5D=1&example%5B%5D=a&foo=bar", hash.ToQueryString());
+
+ const string secret = "5PUZmVMmukNwiHc7V/TJvFHRQZWZumIpCnfZKrVYGpuAdkCcEfv3LIDSrsJ+xOVH";
+ Assert.AreEqual("5a9447aef2ebd0e12d80d80c836858c6f9c13219f615ef5d135da408bcad453d",
+ Utils.GetSignatureForParams(hash, secret));
+ }
+ }
+}
View
25 GoCardlessSdk.Tests/WebHooks/Data/test invalid signature.txt
@@ -0,0 +1,25 @@
+{
+ "payload": {
+ "resource_type": "bill",
+ "action": "paid",
+ "bills": [
+ {
+ "id": "AKJ398H8KA",
+ "status": "paid",
+ "source_type": "subscription",
+ "source_id": "KKJ398H8K8",
+ "paid_at": "2011-12-01T12:00:00Z",
+ "uri": "https://gocardless.com/api/v1/bills/AKJ398H8KA"
+ },
+ {
+ "id": "AKJ398H8KB",
+ "status": "paid",
+ "source_type": "subscription",
+ "source_id": "8AKJ398H78",
+ "paid_at": "2011-12-09T12:00:00Z",
+ "uri": "https://gocardless.com/api/v1/bills/AKJ398H8KB"
+ }
+ ],
+ "signature": "blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah"
+ }
+}
View
25 GoCardlessSdk.Tests/WebHooks/Data/test valid signature.txt
@@ -0,0 +1,25 @@
+{
+ "payload": {
+ "resource_type": "bill",
+ "action": "paid",
+ "bills": [
+ {
+ "id": "AKJ398H8KA",
+ "status": "paid",
+ "source_type": "subscription",
+ "source_id": "KKJ398H8K8",
+ "paid_at": "2011-12-01T12:00:00Z",
+ "uri": "https://sandbox.gocardless.com/api/v1/bills/AKJ398H8KA"
+ },
+ {
+ "id": "AKJ398H8KB",
+ "status": "paid",
+ "source_type": "subscription",
+ "source_id": "8AKJ398H78",
+ "paid_at": "2011-12-09T12:00:00Z",
+ "uri": "https://sandbox.gocardless.com/api/v1/bills/AKJ398H8KB"
+ }
+ ],
+ "signature": "27eafb3a2f38bb6fae752ae6cd7a1a7b5a4df660af2a90499748d8f5d1f554ba"
+ }
+}
View
26 GoCardlessSdk.Tests/WebHooks/WebHooksTests.cs
@@ -0,0 +1,26 @@
+using System.IO;
+using GoCardlessSdk.WebHooks;
+using NUnit.Framework;
+
+namespace GoCardlessSdk.Tests.WebHooks
+{
+ public class WebHooksTests
+ {
+ [Test]
+ public void TestInvalidSignature()
+ {
+ var request = File.ReadAllText("./Webhooks/Data/test invalid signature.txt");
+ GoCardless.AccountDetails.AppSecret = "8ifu76Qi4HMJC1zSNf93WntQzJKpSmce0SwBNTA5HEqQY61aBTH7Nsx4w_HG1vUL";
+ Assert.Throws<SignatureException>(() => WebHooksClient.ParseRequest(request));
+ }
+
+ [Test]
+ public void TestValidSignature()
+ {
+ var request = File.ReadAllText("./Webhooks/Data/test valid signature.txt");
+ GoCardless.AccountDetails.AppSecret = "8ifu76Qi4HMJC1zSNf93WntQzJKpSmce0SwBNTA5HEqQY61aBTH7Nsx4w_HG1vUL";
+ Assert.DoesNotThrow(() => WebHooksClient.ParseRequest(request));
+ }
+
+ }
+}
View
5,184 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/DotNet4/FiddlerCore4.XML
5,184 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/DotNet4/FiddlerCore4.dll
Binary file not shown.
View
5,183 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/FiddlerCore.XML
5,183 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/FiddlerCore.dll
Binary file not shown.
View
BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/FiddlerCore.pdb
Binary file not shown.
View
BIN GoCardlessSdk.Tests/libs/FiddlerCoreAPI/FiddlerCore.shadow
Binary file not shown.
View
14 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/License.txt
@@ -0,0 +1,14 @@
+By using this software, you accept these terms. If you do not accept these terms, do not install, build upon, distribute, or use the software.
+
+The software (FiddlerCore) is provided "as is" and you bear the risk of using it. In no event shall I, Eric Lawrence, be liable for any consequential, special, incidental or indirect damages of any kind arising out of the delivery, performance or use of this software. This software was written with care, but no one warrants that the software is error free.
+
+Your sole remedy for any failure or any form of damage caused by this software is a full refund of the fee I have received from you, which in all cases is $0.
+
+You may use any number of copies of the software to design, develop and test your programs that run on a Microsoft Windows operating system. You may copy and distribute the software, in compiled form, to run on a Microsoft Windows operating system. Permission to redistribute FiddlerCore without charge is granted, subject to the following restrictions: You may not: 1> alter any copyright, trademark or patent notice in the software, 2> include the software in malicious, deceptive or unlawful programs.
+
+If you distribute the software, you must 1> require distributors and external end users to agree to terms that protect it at least as much as this agreement, 2> display your valid copyright notice on your programs, 3> indemnify, defend, and hold harmless Eric Lawrence from any claims, including attorneys� fees, related to the distribution or use of your programs or to your modifications to the software.
+
+EXPORT RESTRICTIONS: The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to software. These laws include restrictions on destinations, end users and end use.
+USE RESTRICTIONS: You warrant that your use of this software is legal and does not violate any law or regulation to which you are subject.
+
+FiddlerCore is �2012 Eric Lawrence. All rights reserved.
View
111 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/SampleApp/Demo.csproj
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{B4436616-28A2-4B98-9C39-3DA4AC95537E}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Demo</RootNamespace>
+ <AssemblyName>Demo</AssemblyName>
+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <SccProjectName>SAK</SccProjectName>
+ <SccLocalPath>SAK</SccLocalPath>
+ <SccAuxPath>SAK</SccAuxPath>
+ <SccProvider>SAK</SccProvider>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;NO_SAZ_SUPPORT; NO_USE_XCEED</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>NO_SAZ_SUPPORT; NO_USE_XCEED</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-Plus|AnyCPU' ">
+ <OutputPath>bin\Release-Plus\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="SAZ-XCEEDZIP.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SAZ-DOTNETZIP.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\FiddlerCore\FiddlerCore.csproj">
+ <Project>{75328C63-EC78-4283-9106-23E12EE76B77}</Project>
+ <Name>FiddlerCore</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
414 GoCardlessSdk.Tests/libs/FiddlerCoreAPI/SampleApp/Program.cs
@@ -0,0 +1,414 @@
+/*
+* This demo program shows how to use the FiddlerCore library.
+* By default, it is compiled without support for the SAZ File format.
+* If you want to add SAZ support, define the token SAZ_SUPPORT in the list of
+* Conditional Compilation symbols on the project's BUILD tab.
+*
+* You will need to add either SAZ-DOTNETZIP.cs or SAZXCEEDZIP.cs to your project,
+* depending on which ZIP library you want to use. You must also ensure to set the
+* Fiddler.RequiredVersionAttribute on your assembly, or your transcoders will be
+* ignored.
+*/
+
+using System;
+using Fiddler;
+using System.Collections.Generic;
+using System.Threading;
+using System.Reflection;
+
+namespace Demo
+{
+ class Program
+ {
+ static bool bUpdateTitle = true;
+ static Proxy oSecureEndpoint;
+ static string sSecureEndpointHostname = "localhost";
+ static int iSecureEndpointPort = 7777;
+
+ public static void WriteCommandResponse(string s)
+ {
+ ConsoleColor oldColor = Console.ForegroundColor;
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine(s);
+ Console.ForegroundColor = oldColor;
+ }
+
+ public static void DoQuit()
+ {
+ WriteCommandResponse("Shutting down...");
+ if (null != oSecureEndpoint) oSecureEndpoint.Dispose();
+ Fiddler.FiddlerApplication.Shutdown();
+ Thread.Sleep(500);
+ }
+ private static string Ellipsize(string s, int iLen)
+ {
+ if (s.Length <= iLen) return s;
+ return s.Substring(0, iLen - 3) + "...";
+ }
+
+#if SAZ_SUPPORT
+ private static void ReadSessions(List<Fiddler.Session> oAllSessions)
+ {
+ TranscoderTuple oImporter = FiddlerApplication.oTranscoders.GetImporter("SAZ");
+ if (null != oImporter)
+ {
+ Dictionary<string, object> dictOptions = new Dictionary<string, object>();
+ dictOptions.Add("Filename", Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\ToLoad.saz");
+
+ Session[] oLoaded = FiddlerApplication.DoImport("SAZ", false, dictOptions, null);
+
+ if ((oLoaded != null) && (oLoaded.Length > 0))
+ {
+ oAllSessions.AddRange(oLoaded);
+ WriteCommandResponse("Loaded: " + oLoaded.Length + " sessions.");
+ }
+ }
+ }
+
+ private static void SaveSessionsToDesktop(List<Fiddler.Session> oAllSessions)
+ {
+ bool bSuccess = false;
+ string sFilename = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
+ + @"\" + DateTime.Now.ToString("hh-mm-ss") + ".saz";
+ try
+ {
+ try
+ {
+ Monitor.Enter(oAllSessions);
+ TranscoderTuple oExporter = FiddlerApplication.oTranscoders.GetExporter("SAZ");
+
+ if (null != oExporter)
+ {
+ Dictionary<string, object> dictOptions = new Dictionary<string, object>();
+ dictOptions.Add("Filename", sFilename);
+ // dictOptions.Add("Password", "pencil");
+
+ bSuccess = FiddlerApplication.DoExport("SAZ", oAllSessions.ToArray(), dictOptions, null);
+ }
+ else
+ {
+ Console.WriteLine("Save failed because the SAZ Format Exporter was not available.");
+ }
+ }
+ finally
+ {
+ Monitor.Exit(oAllSessions);
+ }
+
+ WriteCommandResponse( bSuccess ? ("Wrote: " + sFilename) : ("Failed to save: " + sFilename) );
+ }
+ catch (Exception eX)
+ {
+ Console.WriteLine("Save failed: " + eX.Message);
+ }
+ }
+#endif
+
+ private static void WriteSessionList(List<Fiddler.Session> oAllSessions)
+ {
+ ConsoleColor oldColor = Console.ForegroundColor;
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("Session list contains...");
+ try
+ {
+ Monitor.Enter(oAllSessions);
+ foreach (Session oS in oAllSessions)
+ {
+ Console.Write(String.Format("{0} {1} {2}\n{3} {4}\n\n", oS.id, oS.oRequest.headers.HTTPMethod, Ellipsize(oS.fullUrl, 60), oS.responseCode, oS.oResponse.MIMEType));
+ }
+ }
+ finally
+ {
+ Monitor.Exit(oAllSessions);
+ }
+ Console.WriteLine();
+ Console.ForegroundColor = oldColor;
+ }
+
+ static void Main(string[] args)
+ {
+ List<Fiddler.Session> oAllSessions = new List<Fiddler.Session>();
+ #region AttachEventListeners
+ //
+ // It is important to understand that FiddlerCore calls event handlers on session-handling
+ // background threads. If you need to properly synchronize to the UI-thread (say, because
+ // you're adding the sessions to a list view) you must call .Invoke on a delegate on the
+ // window handle.
+ //
+ // If you are writing to a non-threadsafe data structure (e.g. List<t>) you must
+ // use a Monitor or other mechanism to ensure safety.
+ //
+
+ // Simply echo notifications to the console. Because Fiddler.CONFIG.QuietMode=true
+ // by default, we must handle notifying the user ourselves.
+ Fiddler.FiddlerApplication.OnNotification += delegate(object sender, NotificationEventArgs oNEA) { Console.WriteLine("** NotifyUser: " + oNEA.NotifyString); };
+ Fiddler.FiddlerApplication.Log.OnLogString += delegate(object sender, LogEventArgs oLEA) { Console.WriteLine("** LogString: " + oLEA.LogString); };
+
+ Fiddler.FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
+ {
+ // Console.WriteLine("Before request for:\t" + oS.fullUrl);
+ // In order to enable response tampering, buffering mode MUST
+ // be enabled; this allows FiddlerCore to permit modification of
+ // the response in the BeforeResponse handler rather than streaming
+ // the response to the client as the response comes in.
+ oS.bBufferResponse = false;
+ Monitor.Enter(oAllSessions);
+ oAllSessions.Add(oS);
+ Monitor.Exit(oAllSessions);
+
+ /* If the request is going to our secure endpoint, we'll echo back the response.
+
+ Note: This BeforeRequest is getting called for both our main proxy tunnel AND our secure endpoint,
+ so we have to look at which Fiddler port the client connected to (pipeClient.LocalPort) to determine whether this request
+ was sent to secure endpoint, or was merely sent to the main proxy tunnel (e.g. a CONNECT) in order to *reach* the secure endpoint.
+
+ As a result of this, if you run the demo and visit https://localhost:7777 in your browser, you'll see
+
+ Session list contains...
+
+ 1 CONNECT http://localhost:7777
+ 200 <-- CONNECT tunnel sent to the main proxy tunnel, port 8877
+
+ 2 GET https://localhost:7777/
+ 200 text/html <-- GET request decrypted on the main proxy tunnel, port 8877
+
+ 3 GET https://localhost:7777/
+ 200 text/html <-- GET request received by the secure endpoint, port 7777
+ */
+
+ if ((oS.oRequest.pipeClient.LocalPort == iSecureEndpointPort) && (oS.hostname == sSecureEndpointHostname))
+ {
+ oS.utilCreateResponseAndBypassServer();
+ oS.oResponse.headers.HTTPResponseStatus = "200 Ok";
+ oS.oResponse["Content-Type"] = "text/html; charset=UTF-8";
+ oS.oResponse["Cache-Control"] = "private, max-age=0";
+ oS.utilSetResponseBody("<html><body>Request for httpS://"+sSecureEndpointHostname+ ":" + iSecureEndpointPort.ToString() + " received. Your request was:<br /><plaintext>" + oS.oRequest.headers.ToString());
+ }
+ };
+
+ /*
+ // The following event allows you to examine every response buffer read by Fiddler. Note that this isn't useful for the vast majority of
+ // applications because the raw buffer is nearly useless; it's not decompressed, it includes both headers and body bytes, etc.
+ //
+ // This event is only useful for a handful of applications which need access to a raw, unprocessed byte-stream
+ Fiddler.FiddlerApplication.OnReadResponseBuffer += new EventHandler<RawReadEventArgs>(FiddlerApplication_OnReadResponseBuffer);
+ */
+
+ /*
+ Fiddler.FiddlerApplication.BeforeResponse += delegate(Fiddler.Session oS) {
+ // Console.WriteLine("{0}:HTTP {1} for {2}", oS.id, oS.responseCode, oS.fullUrl);
+
+ // Uncomment the following two statements to decompress/unchunk the
+ // HTTP response and subsequently modify any HTTP responses to replace
+ // instances of the word "Microsoft" with "Bayden". You MUST also
+ // set bBufferResponse = true inside the beforeREQUEST method above.
+ //
+ //oS.utilDecodeResponse(); oS.utilReplaceInResponse("Microsoft", "Bayden");
+ };*/
+
+ Fiddler.FiddlerApplication.AfterSessionComplete += delegate(Fiddler.Session oS)
+ {
+ //Console.WriteLine("Finished session:\t" + oS.fullUrl);
+ if (bUpdateTitle)
+ {
+ Console.Title = ("Session list contains: " + oAllSessions.Count.ToString() + " sessions");
+ }
+ };
+
+ // Tell the system console to handle CTRL+C by calling our method that
+ // gracefully shuts down the FiddlerCore.
+ //
+ // Note, this doesn't handle the case where the user closes the window with the close button.
+ // See http://geekswithblogs.net/mrnat/archive/2004/09/23/11594.aspx for info on that...
+ //
+ Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
+ #endregion AttachEventListeners
+
+ string sSAZInfo = "NoSAZ";
+#if SAZ_SUPPORT
+ // If this demo was compiled with a SAZ-Transcoder, then the following lines will load the
+ // Transcoders into the available transcoders. You can load other types of Transcoders from
+ // a different assembly if you'd like, using the ImportTranscoders(string AssemblyPath) overload.
+ // See https://www.fiddler2.com/dl/FiddlerCore-BasicFormats.zip for an example.
+ //
+ if (!FiddlerApplication.oTranscoders.ImportTranscoders(Assembly.GetExecutingAssembly()))
+ {
+ Console.WriteLine("This assembly was not compiled with a SAZ-exporter");
+ }
+ else
+ {
+ sSAZInfo = SAZFormat.GetZipLibraryInfo();
+ }
+#endif
+
+ Console.WriteLine(String.Format("Starting {0} ({1})...", Fiddler.FiddlerApplication.GetVersionString(), sSAZInfo));
+
+ // For the purposes of this demo, we'll forbid connections to HTTPS
+ // sites that use invalid certificates. Change this from the default only
+ // if you know EXACTLY what that implies.
+ Fiddler.CONFIG.IgnoreServerCertErrors = false;
+
+ // ... but you can allow a specific (even invalid) certificate by implementing and assigning a callback...
+ // FiddlerApplication.OverrideServerCertificateValidation += new OverrideCertificatePolicyHandler(FiddlerApplication_OverrideServerCertificateValidation);
+
+ FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true);
+
+ // For forward-compatibility with updated FiddlerCore libraries, it is strongly recommended that you
+ // start with the DEFAULT options and manually disable specific unwanted options.
+ FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;
+ // E.g. uncomment the next line if you don't want FiddlerCore to act as the system proxy
+ // oFCSF = (oFCSF & ~FiddlerCoreStartupFlags.RegisterAsSystemProxy);
+ // or uncomment the next line if you don't want to decrypt SSL traffic.
+ // oFCSF = (oFCSF & ~FiddlerCoreStartupFlags.DecryptSSL);
+ //
+ // NOTE: Because we haven't disabled the option to decrypt HTTPS traffic, makecert.exe
+ // must be present in this executable's folder.
+
+ // NOTE: In the next line, you can pass 0 for the port (instead of 8877) to have FiddlerCore auto-select an available port
+ Fiddler.FiddlerApplication.Startup(8877, oFCSF);
+
+ FiddlerApplication.Log.LogString("Starting with settings: [" + oFCSF + "]");
+ FiddlerApplication.Log.LogString("Using Gateway: " + ((CONFIG.bForwardToGateway) ? "TRUE" : "FALSE"));
+
+ Console.WriteLine("Hit CTRL+C to end session.");
+
+ oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, sSecureEndpointHostname);
+ if (null != oSecureEndpoint)
+ {
+ FiddlerApplication.Log.LogString("Created secure end point listening on port "+ iSecureEndpointPort.ToString() + ", using a HTTPS certificate for '" + sSecureEndpointHostname + "'");
+ }
+
+ bool bDone = false;
+ do
+ {
+ Console.WriteLine("\nEnter a command [C=Clear; L=List; G=Collect Garbage; W=write SAZ; R=read SAZ;\n\tS=Toggle Forgetful Streaming; T=Toggle Title Counter; Q=Quit]:");
+ Console.Write(">");
+ ConsoleKeyInfo cki = Console.ReadKey();
+ Console.WriteLine();
+ switch (cki.KeyChar)
+ {
+ case 'c':
+ Monitor.Enter(oAllSessions);
+ oAllSessions.Clear();
+ Monitor.Exit(oAllSessions);
+ WriteCommandResponse("Clear...");
+ FiddlerApplication.Log.LogString("Cleared session list.");
+ break;
+
+ case 'l':
+ WriteSessionList(oAllSessions);
+ break;
+
+ case 'g':
+ Console.WriteLine("Working Set:\t" + Environment.WorkingSet.ToString("n0"));
+ Console.WriteLine("Begin GC...");
+ GC.Collect();
+ Console.WriteLine("GC Done.\nWorking Set:\t" + Environment.WorkingSet.ToString("n0"));
+ break;
+
+ case 'q':
+ bDone = true;
+ DoQuit();
+ break;
+
+ case 'r':
+#if SAZ_SUPPORT
+ ReadSessions(oAllSessions);
+#else
+ WriteCommandResponse("This demo was compiled without SAZ_SUPPORT defined");
+#endif
+ break;
+
+ case 'w':
+#if SAZ_SUPPORT
+ if (oAllSessions.Count > 0)
+ {
+ SaveSessionsToDesktop(oAllSessions);
+ }
+ else
+ {
+ WriteCommandResponse("No sessions have been captured");
+ }
+#else
+ WriteCommandResponse("This demo was compiled without SAZ_SUPPORT defined");
+#endif
+ break;
+
+ case 't':
+ bUpdateTitle = !bUpdateTitle;
+ Console.Title = (bUpdateTitle) ? "Title bar will update with request count..." :
+ "Title bar update suppressed...";
+ break;
+
+ // Forgetful streaming
+ case 's':
+ bool bForgetful = !FiddlerApplication.Prefs.GetBoolPref("fiddler.network.streaming.ForgetStreamedData", false);
+ FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.ForgetStreamedData", bForgetful);
+ Console.WriteLine( bForgetful ? "FiddlerCore will immediately dump streaming response data." : "FiddlerCore will keep a copy of streamed response data.");
+ break;
+
+ }
+ } while (!bDone);
+ }
+
+ /*
+ /// <summary>
+ /// This callback allows your code to evaluate the certificate for a site and optionally override default validation behavior for that certificate.
+ /// You should not implement this method unless you understand why it is a security risk.
+ /// </summary>
+ /// <param name="sExpectedCN">The CN expected for this session</param>
+ /// <param name="ServerCertificate">The certificate provided by the server</param>
+ /// <param name="ServerCertificateChain">The certificate chain of that certificate</param>
+ /// <param name="sslPolicyErrors">Errors from default validation</param>
+ /// <param name="bTreatCertificateAsValid">TRUE if you want to force the certificate to be valid; FALSE if you want to force the certificate to be invalid</param>
+ /// <returns>TRUE if you want to override default validation; FALSE if bTreatCertificateAsValid should be ignored</returns>
+ static bool FiddlerApplication_OverrideServerCertificateValidation(Session oS, string sExpectedCN, System.Security.Cryptography.X509Certificates.X509Certificate ServerCertificate, System.Security.Cryptography.X509Certificates.X509Chain ServerCertificateChain, System.Net.Security.SslPolicyErrors sslPolicyErrors, out bool bTreatCertificateAsValid)
+ {
+ if (null != ServerCertificate)
+ {
+ Console.WriteLine("Certificate for " + sExpectedCN + " was for site " + ServerCertificate.Subject + " and errors were " + sslPolicyErrors.ToString());
+
+ if (ServerCertificate.Subject.Contains("fiddler2.com"))
+ {
+ Console.WriteLine("Got a certificate for fiddler2.com and we'll say this is also good for, say, fiddlertool.com");
+ bTreatCertificateAsValid = true;
+ return true;
+ }
+ }
+
+ bTreatCertificateAsValid = false;
+ return false;
+ }
+ */
+
+ /*
+ // This event handler is called on every socket read for the HTTP Response. You almost certainly don't want
+ // to sync on this event handler, but the code below shows how you can use it to mess up your HTTP traffic.
+ static void FiddlerApplication_OnReadResponseBuffer(object sender, RawReadEventArgs e)
+ {
+ // NOTE: arrDataBuffer is a fixed-size array. Only bytes 0 to iCountOfBytes should be read/manipulated.
+ //
+ // Just for kicks, lowercase every byte. Note that this will obviously break any binary content.
+ for (int i = 0; i < e.iCountOfBytes; i++)
+ {
+ if ((e.arrDataBuffer[i] > 0x40) && (e.arrDataBuffer[i] < 0x5b))