1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using Xunit; 6 7 namespace System.Net.Mime.Tests 8 { 9 public class SmtpDateTimeTest 10 { 11 private static readonly DateTime s_validDateStringDateTimeEquivalent = new DateTime(2009, 5, 17, 15, 34, 07, DateTimeKind.Utc); 12 13 private const string UnspecifiedTimeZone = "-0000"; 14 private const string ValidDateStringDateTimeEquivalentString = "Sun, 17 May 2009 15:34:07 +0000"; 15 private const string ValidCompleteDateString = "Sun, 17 May 2009 15:34:07 +0000"; 16 private const string ValidDateStringWithNoDayOfWeek = "17 May 2009 15:34:07 +0000"; 17 private const string ValidDateStringWithKnownShortHandTimeZone = "Sun, 17 May 2009 15:34:07 GMT"; 18 private const string ValidDateStringWithUnknownButValidShortHandTimeZone = "Sun, 17 May 2009 15:34:07 BST"; 19 private const string ValidDateStringWithOnlyTabsAsWhitespace = "Sun,\t17 May\t2009\t15:34:07\tGMT"; 20 private const string ValidDateStringWithMixedTabsAndSpacesAsWhitespace = "Sun,\t17 May\t 2009 \t15:34:07 \t GMT \t "; 21 private const string ValidDateStringWithTrailingWhitespaceAndCommentAfterTimeZone = "Sun,\t17 May\t2009 15:34:07\tGMT\t \"comment\""; 22 private const string InvalidDateStringWithBadDayOfWeek = "Thursday, 17 May 2009 15:34:07 +0000"; 23 private const string InvalidDateStringWithBadDay = "Sun, 37 May 2009 15:34:07 +0000"; 24 private const string InvalidDateStringWithBadMonth = "Sun, 17 Smarch 2009 15:34:07 +0000"; 25 private const string InvalidDateStringWithBadYear = "Sun, 17 May 20099 15:34:07 +0000"; 26 private const string InvalidDateStringWithBadTimeHours = "Sun, 17 May 2009 27:34:07 +0000"; 27 private const string InvalidDateStringWithBadTimeMinutes = "Sun, 17 May 2009 15:88:07 +0000"; 28 private const string InvalidDateStringWithBadTimeSeconds = "Sun, 17 May 2009 15:34:87 +0000"; 29 private const string InvalidDateStringWithInvalidTimeZone = "Sun, 17 May 2009 15:34:07 7M-Gte"; 30 31 [Fact] SmtpDateTime_WithInvalidTimeZone_ShouldParseDateCorrectly()32 public void SmtpDateTime_WithInvalidTimeZone_ShouldParseDateCorrectly() 33 { 34 var smtpDt = new SmtpDateTime(DateTime.Now); 35 string timeZoneOffset; 36 DateTime result = smtpDt.ParseValue(InvalidDateStringWithInvalidTimeZone, out timeZoneOffset); 37 38 Assert.Equal("7M-Gte", timeZoneOffset); 39 Assert.Equal(new DateTime(2009, 5, 17, 15, 34, 07), result); 40 } 41 42 [Theory] 43 [InlineData(InvalidDateStringWithBadTimeSeconds)] 44 [InlineData(InvalidDateStringWithBadTimeMinutes)] 45 [InlineData(InvalidDateStringWithBadTimeHours)] 46 [InlineData(InvalidDateStringWithBadYear)] 47 [InlineData(InvalidDateStringWithBadDay)] 48 [InlineData(InvalidDateStringWithBadMonth)] 49 [InlineData(InvalidDateStringWithBadDayOfWeek)] SmtpDateTime_InvalidInput_ShouldThrowException(string input)50 public void SmtpDateTime_InvalidInput_ShouldThrowException(string input) 51 { 52 var smtpDt = new SmtpDateTime(DateTime.Now); 53 Assert.Throws<FormatException>(() => 54 { 55 string timeZoneOffset; 56 DateTime results = smtpDt.ParseValue(input, out timeZoneOffset); 57 }); 58 } 59 60 [Fact] SmtpDateTime_WithDateThatHasUnspecifiedKind_ShouldSetTimeZoneCorrectly()61 public void SmtpDateTime_WithDateThatHasUnspecifiedKind_ShouldSetTimeZoneCorrectly() 62 { 63 DateTime date = new DateTime(2008, 1, 1, 12, 00, 00, DateTimeKind.Unspecified); 64 var smtpDt = new SmtpDateTime(date); 65 66 Assert.Equal(date, smtpDt.Date); 67 Assert.Equal(DateTimeKind.Unspecified, smtpDt.Date.Kind); 68 } 69 70 [Fact] SmtpDateTime_WithDateThatHasKindSetToLocal_ShouldSetTimeZoneCorrectly()71 public void SmtpDateTime_WithDateThatHasKindSetToLocal_ShouldSetTimeZoneCorrectly() 72 { 73 var date = new DateTime(2008, 1, 1, 12, 00, 00, DateTimeKind.Local); 74 var smtpDt = new SmtpDateTime(date); 75 Assert.Equal(date, smtpDt.Date); 76 } 77 78 [Theory] 79 [InlineData(ValidCompleteDateString, 2009, 5, 17, 15, 34, 7, "GMT", DateTimeKind.Unspecified)] 80 [InlineData(ValidDateStringWithKnownShortHandTimeZone, 2009, 5, 17, 15, 34, 7, "GMT", DateTimeKind.Unspecified)] 81 [InlineData(ValidDateStringWithNoDayOfWeek, 2009, 5, 17, 15, 34, 7, "GMT", DateTimeKind.Unspecified)] 82 [InlineData(ValidDateStringWithOnlyTabsAsWhitespace, 2009, 5, 17, 15, 34, 7, "GMT", DateTimeKind.Unspecified)] 83 [InlineData(ValidDateStringWithTrailingWhitespaceAndCommentAfterTimeZone, 2009, 5, 17, 15, 34, 7, "GMT", DateTimeKind.Unspecified)] 84 [InlineData(ValidDateStringWithMixedTabsAndSpacesAsWhitespace, 2009, 5, 17, 15, 34, 7, "GMT", DateTimeKind.Unspecified)] SmtpDateTime_CreatedFromDateTimeString_ShouldParseCorrectly( string input, int expectedYear, int expectedMonth, int expectedDay, int expectedHour, int expectedMinut, int expectedSecond, string expectedTimeZoneOffset, DateTimeKind expectedKind)85 public void SmtpDateTime_CreatedFromDateTimeString_ShouldParseCorrectly( 86 string input, 87 int expectedYear, int expectedMonth, int expectedDay, 88 int expectedHour, int expectedMinut, int expectedSecond, 89 string expectedTimeZoneOffset, DateTimeKind expectedKind) 90 { 91 var smtpDt = new SmtpDateTime(DateTime.Now); 92 93 string timeZoneOffset; 94 DateTime result = smtpDt.ParseValue(ValidDateStringWithKnownShortHandTimeZone, out timeZoneOffset); 95 96 Assert.Equal(expectedYear, result.Year); 97 Assert.Equal(expectedMonth, result.Month); 98 Assert.Equal(expectedDay, result.Day); 99 Assert.Equal(expectedHour, result.Hour); 100 Assert.Equal(expectedMinut, result.Minute); 101 Assert.Equal(expectedSecond, result.Second); 102 Assert.Equal(expectedTimeZoneOffset, timeZoneOffset); 103 } 104 105 [Fact] SmtpDate_ToString_ShouldOutputCorrectDateString()106 public void SmtpDate_ToString_ShouldOutputCorrectDateString() 107 { 108 var smtpDt = new SmtpDateTime(s_validDateStringDateTimeEquivalent); 109 Assert.Equal(ValidDateStringDateTimeEquivalentString, smtpDt.ToString()); 110 } 111 112 [Fact] SmtpDate_ValidateTimeZoneShortHandValue_WithValidShortHand_ShouldReturnTrue()113 public void SmtpDate_ValidateTimeZoneShortHandValue_WithValidShortHand_ShouldReturnTrue() 114 { 115 var smtpDt = new SmtpDateTime(DateTime.Now); 116 smtpDt.ValidateTimeZoneShortHandValue("GMT"); 117 } 118 119 [Fact] SmtpDate_ValidateTimeZoneShortHandValue_WithInvalidShortHand_ShouldReturnFalse()120 public void SmtpDate_ValidateTimeZoneShortHandValue_WithInvalidShortHand_ShouldReturnFalse() 121 { 122 var smtpDt = new SmtpDateTime(DateTime.Now); 123 Assert.Throws<FormatException>(() => smtpDt.ValidateTimeZoneShortHandValue("7M-GTE")); 124 } 125 126 [Fact] SmtpDate_ValidateTimeZoneOffsetValue_WithValidAndInvalidOffsets_ShouldReturnCorrectly()127 public void SmtpDate_ValidateTimeZoneOffsetValue_WithValidAndInvalidOffsets_ShouldReturnCorrectly() 128 { 129 var smtpDt = new SmtpDateTime(DateTime.Now); 130 131 bool positive; 132 int hours; 133 int minutes; 134 135 smtpDt.ValidateAndGetTimeZoneOffsetValues("+0000", out positive, out hours, out minutes); 136 smtpDt.ValidateAndGetTimeZoneOffsetValues("+9959", out positive, out hours, out minutes); 137 smtpDt.ValidateAndGetTimeZoneOffsetValues("-9959", out positive, out hours, out minutes); 138 smtpDt.ValidateAndGetTimeZoneOffsetValues("+0900", out positive, out hours, out minutes); 139 140 Assert.Throws<FormatException>(() => smtpDt.ValidateAndGetTimeZoneOffsetValues("+0080", out positive, out hours, out minutes)); 141 Assert.Throws<FormatException>(() => smtpDt.ValidateAndGetTimeZoneOffsetValues("+-0045", out positive, out hours, out minutes)); 142 Assert.Throws<FormatException>(() => smtpDt.ValidateAndGetTimeZoneOffsetValues("+10000", out positive, out hours, out minutes)); 143 Assert.Throws<FormatException>(() => smtpDt.ValidateAndGetTimeZoneOffsetValues("-A000", out positive, out hours, out minutes)); 144 } 145 146 [Fact] SmtpDate_WithCompletelyInvalidDateString_ShouldThrowException()147 public void SmtpDate_WithCompletelyInvalidDateString_ShouldThrowException() 148 { 149 Assert.Throws<FormatException>(() => new SmtpDateTime("asdiwefhn m.sdf,m,sdfl\"")); 150 } 151 152 [Fact] SmtpDate_TimeSpanToOffset_ShouldConvertCorrectly()153 public void SmtpDate_TimeSpanToOffset_ShouldConvertCorrectly() 154 { 155 var smtpDt = new SmtpDateTime(DateTime.Now); 156 TimeSpan timeZone = TimeZoneInfo.Utc.GetUtcOffset(DateTime.Now); 157 string timeZoneToString = timeZone.ToString(); 158 string result = smtpDt.TimeSpanToOffset(timeZone); 159 Assert.Equal("+0000", result); 160 } 161 162 [Fact] SmtpDate_TimeSpanToOffset_WithNonGmtOffset_ShouldConvertCorrectly()163 public void SmtpDate_TimeSpanToOffset_WithNonGmtOffset_ShouldConvertCorrectly() 164 { 165 var smtpDt = new SmtpDateTime(DateTime.Now); 166 Assert.Equal("-0800", smtpDt.TimeSpanToOffset(new TimeSpan(-8, 0, 0))); 167 Assert.Equal("-1000", smtpDt.TimeSpanToOffset(new TimeSpan(-10, 0, 0))); 168 Assert.Equal("+1000", smtpDt.TimeSpanToOffset(new TimeSpan(10, 0, 0))); 169 Assert.Equal("+0400", smtpDt.TimeSpanToOffset(new TimeSpan(4, 0, 0))); 170 } 171 172 [Fact] SmtpDate_TryParseTimeZoneString_WithValidShortHand_ShouldReturnCorrectOffset()173 public void SmtpDate_TryParseTimeZoneString_WithValidShortHand_ShouldReturnCorrectOffset() 174 { 175 var smtpDt = new SmtpDateTime(DateTime.Now); 176 TimeSpan span; 177 Assert.True(smtpDt.TryParseTimeZoneString("GMT", out span)); 178 Assert.Equal(TimeSpan.Zero, span); 179 } 180 181 [Fact] SmtpDate_TryParseTimeZoneString_WithUnknownShortHand_ShouldReturnFalse()182 public void SmtpDate_TryParseTimeZoneString_WithUnknownShortHand_ShouldReturnFalse() 183 { 184 var smtpDt = new SmtpDateTime(DateTime.Now); 185 TimeSpan span; 186 Assert.False(smtpDt.TryParseTimeZoneString("ABCD", out span)); 187 } 188 189 [Fact] SmtpDate_TryParseTimeZoneString_WithInvalidShortHand_ShouldThrowException()190 public void SmtpDate_TryParseTimeZoneString_WithInvalidShortHand_ShouldThrowException() 191 { 192 var smtpDt = new SmtpDateTime(DateTime.Now); 193 TimeSpan span; 194 Assert.Throws<FormatException>(() => smtpDt.TryParseTimeZoneString("7mGTE", out span)); 195 } 196 } 197 } 198