|
4 | 4 |
|
5 | 5 | using System;
|
6 | 6 | using System.Collections.Generic;
|
| 7 | +using System.ComponentModel; |
| 8 | +using System.ComponentModel.DataAnnotations; |
| 9 | +using System.IO; |
| 10 | +using System.Text; |
| 11 | +using Microsoft.Extensions.Configuration; |
| 12 | +using Microsoft.Extensions.DependencyInjection; |
| 13 | +using Microsoft.Extensions.Hosting; |
7 | 14 | using Xunit;
|
8 | 15 |
|
9 | 16 | namespace Microsoft.Data.SqlClient.Tests
|
@@ -446,6 +453,159 @@ public void EncryptTryParseInvalidValuesReturnsFalse(string value)
|
446 | 453 | Assert.Null(result);
|
447 | 454 | }
|
448 | 455 |
|
| 456 | + #region SqlConnectionEncryptOptionCoverterTests |
| 457 | + [Fact] |
| 458 | + public void ConnectionStringFromJsonTests() |
| 459 | + { |
| 460 | + UserDbConnectionStringSettings settings = LoadSettingsFromJsonStream<UserDbConnectionStringSettings>("false"); |
| 461 | + Assert.Equal(SqlConnectionEncryptOption.Optional, settings.UserDb.UserComponents.Encrypt); |
| 462 | + |
| 463 | + settings = LoadSettingsFromJsonStream<UserDbConnectionStringSettings>("true"); |
| 464 | + Assert.Equal(SqlConnectionEncryptOption.Mandatory, settings.UserDb.UserComponents.Encrypt); |
| 465 | + |
| 466 | + settings = LoadSettingsFromJsonStream<UserDbConnectionStringSettings>("strict"); |
| 467 | + Assert.Equal(SqlConnectionEncryptOption.Strict, settings.UserDb.UserComponents.Encrypt); |
| 468 | + |
| 469 | + settings = LoadSettingsFromJsonStream<UserDbConnectionStringSettings>("mandatory"); |
| 470 | + Assert.Equal(SqlConnectionEncryptOption.Mandatory, settings.UserDb.UserComponents.Encrypt); |
| 471 | + |
| 472 | + settings = LoadSettingsFromJsonStream<UserDbConnectionStringSettings>("optional"); |
| 473 | + Assert.Equal(SqlConnectionEncryptOption.Optional, settings.UserDb.UserComponents.Encrypt); |
| 474 | + |
| 475 | + settings = LoadSettingsFromJsonStream<UserDbConnectionStringSettings>("yes"); |
| 476 | + Assert.Equal(SqlConnectionEncryptOption.Mandatory, settings.UserDb.UserComponents.Encrypt); |
| 477 | + |
| 478 | + settings = LoadSettingsFromJsonStream<UserDbConnectionStringSettings>("no"); |
| 479 | + Assert.Equal(SqlConnectionEncryptOption.Optional, settings.UserDb.UserComponents.Encrypt); |
| 480 | + } |
| 481 | + |
| 482 | + [Theory] |
| 483 | + [InlineData("absolutely")] |
| 484 | + [InlineData("affirmative")] |
| 485 | + [InlineData("never")] |
| 486 | + [InlineData("always")] |
| 487 | + [InlineData("none")] |
| 488 | + [InlineData(" for sure ")] |
| 489 | + public void ConnectionStringFromJsonThrowsException(string value) |
| 490 | + { |
| 491 | + ExecuteConnectionStringFromJsonThrowsException(value); |
| 492 | + } |
| 493 | + |
| 494 | + [Fact] |
| 495 | + public void SqlConnectionEncryptOptionConverterCanConvertFromTest() |
| 496 | + { |
| 497 | + // Get a converter |
| 498 | + SqlConnectionEncryptOption option = SqlConnectionEncryptOption.Parse("false"); |
| 499 | + TypeConverter converter = TypeDescriptor.GetConverter(option.GetType()); |
| 500 | + // Use the converter to determine if can convert from string data type |
| 501 | + Assert.True(converter.CanConvertFrom(null, typeof(string)), "Expecting to convert from a string type."); |
| 502 | + // Use the same converter to determine if can convert from int or bool data types |
| 503 | + Assert.False(converter.CanConvertFrom(null, typeof(int)), "Not expecting to convert from integer type."); |
| 504 | + Assert.False(converter.CanConvertFrom(null, typeof(bool)), "Not expecting to convert from boolean type."); |
| 505 | + } |
| 506 | + |
| 507 | + [Fact] |
| 508 | + public void SqlConnectionEncryptOptionConverterCanConvertToTest() |
| 509 | + { |
| 510 | + // Get a converter |
| 511 | + SqlConnectionEncryptOption option = SqlConnectionEncryptOption.Parse("false"); |
| 512 | + TypeConverter converter = TypeDescriptor.GetConverter(option.GetType()); |
| 513 | + // Use the converter to check if can convert from stirng |
| 514 | + Assert.True(converter.CanConvertTo(null, typeof(string)), "Expecting to convert to a string type."); |
| 515 | + // Use the same convert to check if can convert to int or bool |
| 516 | + Assert.False(converter.CanConvertTo(null, typeof(int)), "Not expecting to convert from integer type."); |
| 517 | + Assert.False(converter.CanConvertTo(null, typeof(bool)), "Not expecting to convert from boolean type."); |
| 518 | + } |
| 519 | + |
| 520 | + [Fact] |
| 521 | + public void SqlConnectionEncryptOptionConverterConvertFromTest() |
| 522 | + { |
| 523 | + // Create a converter |
| 524 | + SqlConnectionEncryptOption option = SqlConnectionEncryptOption.Parse("false"); |
| 525 | + TypeConverter converter = TypeDescriptor.GetConverter(option.GetType()); |
| 526 | + // Use the converter to convert all possible valid values |
| 527 | + Assert.Equal(SqlConnectionEncryptOption.Parse("false"), converter.ConvertFrom("false")); |
| 528 | + Assert.Equal(SqlConnectionEncryptOption.Parse("true"), converter.ConvertFrom("true")); |
| 529 | + Assert.Equal(SqlConnectionEncryptOption.Parse("strict"), converter.ConvertFrom("strict")); |
| 530 | + Assert.Equal(SqlConnectionEncryptOption.Parse("mandatory"), converter.ConvertFrom("mandatory")); |
| 531 | + Assert.Equal(SqlConnectionEncryptOption.Parse("optional"), converter.ConvertFrom("optional")); |
| 532 | + Assert.Equal(SqlConnectionEncryptOption.Parse("yes"), converter.ConvertFrom("yes")); |
| 533 | + Assert.Equal(SqlConnectionEncryptOption.Parse("no"), converter.ConvertFrom("no")); |
| 534 | + // Use the converter to covert invalid value |
| 535 | + Assert.Throws<ArgumentException>(() => converter.ConvertFrom("affirmative")); |
| 536 | + // Use the same converter to convert from bad data types |
| 537 | + Assert.Throws<ArgumentException>(() => converter.ConvertFrom(1)); |
| 538 | + Assert.Throws<ArgumentException>(() => converter.ConvertFrom(true)); |
| 539 | + } |
| 540 | + |
| 541 | + [Fact] |
| 542 | + public void SqlConnectionEncryptOptionConverterConvertToTest() |
| 543 | + { |
| 544 | + // Get a converter |
| 545 | + SqlConnectionEncryptOption option = SqlConnectionEncryptOption.Parse("false"); |
| 546 | + TypeConverter converter = TypeDescriptor.GetConverter(option.GetType()); |
| 547 | + // Use the converter to convert all possible valid values to string |
| 548 | + Assert.Equal("False", converter.ConvertTo(SqlConnectionEncryptOption.Parse("false"), typeof(string))); |
| 549 | + Assert.Equal("True", converter.ConvertTo(SqlConnectionEncryptOption.Parse("true"), typeof(string))); |
| 550 | + Assert.Equal("Strict", converter.ConvertTo(SqlConnectionEncryptOption.Parse("strict"), typeof(string))); |
| 551 | + Assert.Equal("True", converter.ConvertTo(SqlConnectionEncryptOption.Parse("mandatory"), typeof(string))); |
| 552 | + Assert.Equal("False", converter.ConvertTo(SqlConnectionEncryptOption.Parse("optional"), typeof(string))); |
| 553 | + Assert.Equal("True", converter.ConvertTo(SqlConnectionEncryptOption.Parse("yes"), typeof(string))); |
| 554 | + Assert.Equal("False", converter.ConvertTo(SqlConnectionEncryptOption.Parse("no"), typeof(string))); |
| 555 | + // Use the same converter to try convert to bad data types |
| 556 | + Assert.Throws<ArgumentException>(() => converter.ConvertTo(SqlConnectionEncryptOption.Parse("false"), typeof(int))); |
| 557 | + Assert.Throws<ArgumentException>(() => converter.ConvertTo(SqlConnectionEncryptOption.Parse("false"), typeof(bool))); |
| 558 | + } |
| 559 | + |
| 560 | + internal class UserDbConnectionStringSettings |
| 561 | + { |
| 562 | + [Required] |
| 563 | + public UserSqlConnectionString UserDb { get; set; } |
| 564 | + } |
| 565 | + |
| 566 | + internal class UserSqlConnectionString |
| 567 | + { |
| 568 | + public SqlConnectionStringBuilder UserComponents { get; set; } = new(); |
| 569 | + |
| 570 | + public override string ToString() |
| 571 | + { |
| 572 | + return UserComponents!.ConnectionString; |
| 573 | + } |
| 574 | + } |
| 575 | + |
| 576 | + internal static void ExecuteConnectionStringFromJsonThrowsException(string encryptOption) |
| 577 | + { |
| 578 | + var exception = Assert.Throws<InvalidOperationException>(() => LoadSettingsFromJsonStream<UserDbConnectionStringSettings>(encryptOption)); |
| 579 | + Assert.Contains("Failed to convert configuration", exception.Message, StringComparison.Ordinal); |
| 580 | + } |
| 581 | + |
| 582 | + private static TSettings LoadSettingsFromJsonStream<TSettings>(string encryptOption) where TSettings : class |
| 583 | + { |
| 584 | + TSettings settingsOut = null; |
| 585 | + |
| 586 | + Host.CreateDefaultBuilder() |
| 587 | + .ConfigureAppConfiguration((ctx, configBuilder) => |
| 588 | + { |
| 589 | + // Note: Inside string interpolation, a { should be {{ and a } should be }} |
| 590 | + // First, declare a stringified JSON |
| 591 | + var json = $"{{ \"UserDb\": {{ \"UserComponents\": {{ \"NetworkLibrary\": \"DBMSSOCN\", \"UserID\": \"user\", \"Password\": \"password\", \"DataSource\": \"localhost\", \"InitialCatalog\": \"catalog\", \"Encrypt\": \"{encryptOption}\" }}}}}}"; |
| 592 | + // Load the stringified JSON as a stream into the configuration builder |
| 593 | + configBuilder.AddJsonStream(new MemoryStream(Encoding.ASCII.GetBytes(json))); |
| 594 | + configBuilder.AddEnvironmentVariables(); |
| 595 | + }) |
| 596 | + .ConfigureServices((ctx, services) => |
| 597 | + { |
| 598 | + var configuration = ctx.Configuration; |
| 599 | + services.AddOptions(); |
| 600 | + services.Configure<TSettings>(ctx.Configuration); |
| 601 | + settingsOut = configuration.Get<TSettings>(); |
| 602 | + }) |
| 603 | + .Build(); |
| 604 | + |
| 605 | + return settingsOut; |
| 606 | + } |
| 607 | + #endregion |
| 608 | + |
449 | 609 | internal void ExecuteConnectionStringTests(string connectionString)
|
450 | 610 | {
|
451 | 611 | SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString);
|
|
0 commit comments