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