diff --git a/src/HttpClientInterception/Bundles/BundleItemConverter.cs b/src/HttpClientInterception/Bundles/BundleItemConverter.cs index 5bcb3fb2..c19d8eac 100644 --- a/src/HttpClientInterception/Bundles/BundleItemConverter.cs +++ b/src/HttpClientInterception/Bundles/BundleItemConverter.cs @@ -16,12 +16,10 @@ public static HttpRequestInterceptionBuilder FromItem( IEnumerable> templateValues) { // Override the template values in the JSON with any user-specified values - if (item.TemplateValues?.Count > 0) + foreach (var pair in templateValues) { - foreach (var pair in templateValues) - { - item.TemplateValues[pair.Key] = pair.Value; - } + item.TemplateValues ??= new Dictionary(); + item.TemplateValues[pair.Key] = pair.Value; } ValidateItem(item, out Uri? uri, out Version? version); diff --git a/tests/HttpClientInterception.Tests/Bundles/BundleExtensionsTests.cs b/tests/HttpClientInterception.Tests/Bundles/BundleExtensionsTests.cs index 542bb139..fccd5dba 100644 --- a/tests/HttpClientInterception.Tests/Bundles/BundleExtensionsTests.cs +++ b/tests/HttpClientInterception.Tests/Bundles/BundleExtensionsTests.cs @@ -249,6 +249,32 @@ public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_Templ .ShouldBe(@"[{""id"":123456,""name"":""httpclient-interception"",""full_name"":""justeat/httpclient-interception"",""private"":false,""owner"":{""login"":""justeat"",""id"":1516790}}]"); } + [Fact] + public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_Templated_Json_TemplateValues_Only_Defined_In_Code() + { + // Arrange + var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); + + var templateValues = new Dictionary() + { + ["AvatarUrl"] = "https://avatars.githubusercontent.com/u/1516790?v=4", + ["BlogUrl"] = "https://tech.justeattakeaway.com/", + ["CompanyName"] = "justeat", + ["RepoName"] = "httpclient-interception", + }; + + // Act + options.RegisterBundle(Path.Join("Bundles", "templated-bundle-json-no-parameters.json"), templateValues); + + // Assert + string content = await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat/repos"); + content + .Replace(" ", string.Empty, StringComparison.Ordinal) + .Replace("\n", string.Empty, StringComparison.Ordinal) + .Replace("\r", string.Empty, StringComparison.Ordinal) + .ShouldBe(@"[{""id"":123456,""name"":""httpclient-interception"",""full_name"":""justeat/httpclient-interception"",""private"":false,""owner"":{""login"":""justeat"",""id"":1516790}}]"); + } + [Fact] public static void RegisterBundle_Validates_Parameters() { diff --git a/tests/HttpClientInterception.Tests/Bundles/templated-bundle-json-no-parameters.json b/tests/HttpClientInterception.Tests/Bundles/templated-bundle-json-no-parameters.json new file mode 100644 index 00000000..d08c8672 --- /dev/null +++ b/tests/HttpClientInterception.Tests/Bundles/templated-bundle-json-no-parameters.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://raw.githubusercontent.com/justeat/httpclient-interception/main/src/HttpClientInterception/Bundles/http-request-bundle-schema.json", + "id": "templated-bundle-json-no-parameters", + "comment": "An HTTP request bundle that uses templating for JSON where the parameters are only defined in code.", + "version": 1, + "items": [ + { + "comment": "An HTTP request for a JSON response that uses templating.", + "uri": "https://api.github.com/orgs/${CompanyName}/repos", + "contentFormat": "json", + "contentJson": [ + { + "id": 123456, + "name": "${RepoName}", + "full_name": "${CompanyName}/${RepoName}", + "private": false, + "owner": { + "login": "${CompanyName}", + "id": 1516790 + } + } + ] + } + ] +}