diff --git a/Snowflake.Data.Tests/Mock/MockLoginStoringRestRequester.cs b/Snowflake.Data.Tests/Mock/MockLoginStoringRestRequester.cs new file mode 100644 index 000000000..a17dfd9e2 --- /dev/null +++ b/Snowflake.Data.Tests/Mock/MockLoginStoringRestRequester.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Snowflake.Data.Core; + +namespace Snowflake.Data.Tests.Mock +{ + class MockLoginStoringRestRequester: IMockRestRequester + { + internal List LoginRequests { get; } = new(); + + public T Get(IRestRequest request) + { + return Task.Run(async () => await (GetAsync(request, CancellationToken.None)).ConfigureAwait(false)).Result; + } + + public Task GetAsync(IRestRequest request, CancellationToken cancellationToken) + { + return Task.FromResult((T)(object)null); + } + + public Task GetAsync(IRestRequest request, CancellationToken cancellationToken) + { + return Task.FromResult(null); + } + + public HttpResponseMessage Get(IRestRequest request) + { + return null; + } + + public T Post(IRestRequest postRequest) + { + return Task.Run(async () => await (PostAsync(postRequest, CancellationToken.None)).ConfigureAwait(false)).Result; + } + + public Task PostAsync(IRestRequest postRequest, CancellationToken cancellationToken) + { + SFRestRequest sfRequest = (SFRestRequest)postRequest; + if (sfRequest.jsonBody is LoginRequest) + { + LoginRequests.Add((LoginRequest) sfRequest.jsonBody); + LoginResponse authnResponse = new LoginResponse + { + data = new LoginResponseData() + { + token = "session_token", + masterToken = "master_token", + authResponseSessionInfo = new SessionInfo(), + nameValueParameter = new List() + }, + success = true + }; + + // login request return success + return Task.FromResult((T)(object)authnResponse); + } + throw new NotImplementedException(); + } + + public void setHttpClient(HttpClient httpClient) + { + // Nothing to do + } + } +} diff --git a/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs b/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs index fa5eafbd1..a1f795026 100644 --- a/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs +++ b/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs @@ -2,8 +2,10 @@ * Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved. */ +using Newtonsoft.Json; using Snowflake.Data.Core; using NUnit.Framework; +using Snowflake.Data.Tests.Mock; namespace Snowflake.Data.Tests.UnitTests { @@ -123,5 +125,28 @@ public void TestSessionPropertyQuotationSafeUpdateOnServerResponse(string sessio else Assert.AreEqual(sessionInitialValue, changedSessionValue); } + + [Test] + public void TestHandlePasswordWithQuotations() + { + // arrange + MockLoginStoringRestRequester restRequester = new MockLoginStoringRestRequester(); + SFSession sfSession = new SFSession("account=test;user=test;password=test\"with'quotations{}", null, restRequester); + + // act + sfSession.Open(); + + // assert + Assert.AreEqual(1, restRequester.LoginRequests.Count); + var loginRequest = restRequester.LoginRequests[0]; + Assert.AreEqual("test\"with'quotations{}", loginRequest.data.password); + + // act + var json = JsonConvert.SerializeObject(loginRequest, JsonUtils.JsonSettings); + var deserializedLoginRequest = (LoginRequest) JsonConvert.DeserializeObject(json, typeof(LoginRequest)); + + // assert + Assert.AreEqual(loginRequest.data.password, deserializedLoginRequest.data.password); + } } }