You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Tests.TokenUtils.cs 7.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Xunit;
  5. namespace Discord
  6. {
  7. public class TokenUtilsTests
  8. {
  9. /// <summary>
  10. /// Tests the usage of <see cref="TokenUtils.ValidateToken(TokenType, string)"/>
  11. /// to see that when a null, empty or whitespace-only string is passed as the token,
  12. /// it will throw an ArgumentNullException.
  13. /// </summary>
  14. [Theory]
  15. [InlineData(null)]
  16. [InlineData("")] // string.Empty isn't a constant type
  17. [InlineData(" ")]
  18. [InlineData(" ")]
  19. [InlineData("\t")]
  20. public void TestNullOrWhitespaceToken(string token)
  21. {
  22. // an ArgumentNullException should be thrown, regardless of the TokenType
  23. Assert.Throws<ArgumentNullException>(() => TokenUtils.ValidateToken(TokenType.Bearer, token));
  24. Assert.Throws<ArgumentNullException>(() => TokenUtils.ValidateToken(TokenType.Bot, token));
  25. Assert.Throws<ArgumentNullException>(() => TokenUtils.ValidateToken(TokenType.Webhook, token));
  26. }
  27. /// <summary>
  28. /// Tests the behavior of <see cref="TokenUtils.ValidateToken(TokenType, string)"/>
  29. /// to see that valid Webhook tokens do not throw Exceptions.
  30. /// </summary>
  31. /// <param name="token"></param>
  32. [Theory]
  33. [InlineData("123123123")]
  34. // bot token
  35. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")]
  36. // bearer token taken from discord docs
  37. [InlineData("6qrZcUqja7812RVdnEKjpzOL4CvHBFG")]
  38. // client secret
  39. [InlineData("937it3ow87i4ery69876wqire")]
  40. public void TestWebhookTokenDoesNotThrowExceptions(string token)
  41. {
  42. TokenUtils.ValidateToken(TokenType.Webhook, token);
  43. }
  44. // No tests for invalid webhook token behavior, because there is nothing there yet.
  45. /// <summary>
  46. /// Tests the behavior of <see cref="TokenUtils.ValidateToken(TokenType, string)"/>
  47. /// to see that valid Webhook tokens do not throw Exceptions.
  48. /// </summary>
  49. /// <param name="token"></param>
  50. [Theory]
  51. [InlineData("123123123")]
  52. // bot token
  53. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")]
  54. // bearer token taken from discord docs
  55. [InlineData("6qrZcUqja7812RVdnEKjpzOL4CvHBFG")]
  56. // client secret
  57. [InlineData("937it3ow87i4ery69876wqire")]
  58. public void TestBearerTokenDoesNotThrowExceptions(string token)
  59. {
  60. TokenUtils.ValidateToken(TokenType.Bearer, token);
  61. }
  62. // No tests for invalid bearer token behavior, because there is nothing there yet.
  63. /// <summary>
  64. /// Tests the behavior of <see cref="TokenUtils.ValidateToken(TokenType, string)"/>
  65. /// to see that valid Bot tokens do not throw Exceptions.
  66. /// Valid Bot tokens can be strings of length 58 or above.
  67. /// </summary>
  68. [Theory]
  69. // missing a single character from the end, 58 char. still should be valid
  70. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKW")]
  71. // 59 char token
  72. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")]
  73. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWss")]
  74. public void TestBotTokenDoesNotThrowExceptions(string token)
  75. {
  76. // This example token is pulled from the Discord Docs
  77. // https://discordapp.com/developers/docs/reference#authentication-example-bot-token-authorization-header
  78. // should not throw any exception
  79. TokenUtils.ValidateToken(TokenType.Bot, token);
  80. }
  81. /// <summary>
  82. /// Tests the usage of <see cref="TokenUtils.ValidateToken(TokenType, string)"/> with
  83. /// a Bot token that is invalid.
  84. /// </summary>
  85. [Theory]
  86. [InlineData("This is invalid")]
  87. // bearer token
  88. [InlineData("6qrZcUqja7812RVdnEKjpzOL4CvHBFG")]
  89. // client secret
  90. [InlineData("937it3ow87i4ery69876wqire")]
  91. // 57 char bot token
  92. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kK")]
  93. [InlineData("This is an invalid token, but it passes the check for string length.")]
  94. // valid token, but passed in twice
  95. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWsMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")]
  96. public void TestBotTokenInvalidThrowsArgumentException(string token)
  97. {
  98. Assert.Throws<ArgumentException>(() => TokenUtils.ValidateToken(TokenType.Bot, token));
  99. }
  100. /// <summary>
  101. /// Tests the behavior of <see cref="TokenUtils.ValidateToken(TokenType, string)"/>
  102. /// to see that an <see cref="ArgumentException"/> is thrown when an invalid
  103. /// <see cref="TokenType"/> is supplied as a parameter.
  104. /// </summary>
  105. /// <remarks>
  106. /// The <see cref="TokenType.User"/> type is treated as an invalid <see cref="TokenType"/>.
  107. /// </remarks>
  108. [Theory]
  109. // TokenType.User
  110. [InlineData(0)]
  111. // out of range TokenType
  112. [InlineData(-1)]
  113. [InlineData(4)]
  114. [InlineData(7)]
  115. public void TestUnrecognizedTokenType(int type)
  116. {
  117. Assert.Throws<ArgumentException>(() =>
  118. TokenUtils.ValidateToken((TokenType)type, "MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs"));
  119. }
  120. /// <summary>
  121. /// Checks the <see cref="TokenUtils.CheckBotTokenValidity(string)"/> method for expected output.
  122. /// </summary>
  123. /// <param name="token"> The Bot Token to test.</param>
  124. /// <param name="expected"> The expected result. </param>
  125. [Theory]
  126. // this method only checks the first part of the JWT
  127. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4..", true)]
  128. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kK", true)]
  129. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4. this part is invalid. this part is also invalid", true)]
  130. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.", false)]
  131. [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4", false)]
  132. [InlineData("NDI4NDc3OTQ0MDA5MTk1NTIw.xxxx.xxxxx", true)]
  133. // should not throw an unexpected exception
  134. [InlineData("", false)]
  135. [InlineData(null, false)]
  136. public void TestCheckBotTokenValidity(string token, bool expected)
  137. {
  138. Assert.Equal(expected, TokenUtils.CheckBotTokenValidity(token));
  139. }
  140. [Theory]
  141. // cannot pass a ulong? as a param in InlineData, so have to have a separate param
  142. // indicating if a value is null
  143. [InlineData("NDI4NDc3OTQ0MDA5MTk1NTIw", false, 428477944009195520)]
  144. // should return null w/o throwing other exceptions
  145. [InlineData("", true, 0)]
  146. [InlineData(" ", true, 0)]
  147. [InlineData(null, true, 0)]
  148. [InlineData("these chars aren't allowed @U#)*@#!)*", true, 0)]
  149. public void TestDecodeBase64UserId(string encodedUserId, bool isNull, ulong expectedUserId)
  150. {
  151. var result = TokenUtils.DecodeBase64UserId(encodedUserId);
  152. if (isNull)
  153. Assert.Null(result);
  154. else
  155. Assert.Equal(expectedUserId, result);
  156. }
  157. }
  158. }