Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

AuthenticationServiceTests.cs 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. using AutoMapper;
  2. using Diligent.WebAPI.Business.MappingProfiles;
  3. using Diligent.WebAPI.Business.Services;
  4. using Diligent.WebAPI.Business.Settings;
  5. using Diligent.WebAPI.Contracts.DTOs;
  6. using Diligent.WebAPI.Contracts.DTOs.Auth;
  7. using Diligent.WebAPI.Contracts.Models;
  8. using Diligent.WebAPI.Data.Entities;
  9. using Microsoft.AspNetCore.Identity;
  10. using Microsoft.AspNetCore.WebUtilities;
  11. using Microsoft.EntityFrameworkCore;
  12. using Microsoft.Extensions.Logging;
  13. using Microsoft.Extensions.Options;
  14. using NSubstitute.ReturnsExtensions;
  15. using System.Text;
  16. namespace Diligent.WebAPI.Tests.Services
  17. {
  18. public class AuthenticationServiceTests
  19. {
  20. private readonly List<User> _users;
  21. private readonly List<RefreshToken> _tokens;
  22. private readonly IUserStore<User> _mockStore;
  23. private readonly UserManager<User> _mockUserManager;
  24. private readonly IEmailer _emailer = Substitute.For<IEmailer>();
  25. private readonly IMapper _mapper;
  26. private readonly ILogger<AuthenticationService> _logger = Substitute.For<ILogger<AuthenticationService>>();
  27. private readonly IHttpClientService _httpClient = Substitute.For<IHttpClientService>();
  28. public AuthenticationServiceTests()
  29. {
  30. _mockStore = Substitute.For<IUserStore<User>>();
  31. _mockUserManager = Substitute.For<UserManager<User>>(_mockStore, null, null, null, null, null, null, null, null);
  32. _tokens = new List<RefreshToken>
  33. {
  34. new RefreshToken
  35. {
  36. Id = 1,
  37. CreationDate = DateTime.UtcNow,
  38. ExpiryDate = DateTime.UtcNow.AddDays(5),
  39. UserId = 1,
  40. Invalidated = false,
  41. JwtId = "string",
  42. Used = false,
  43. Token = "refresh"
  44. },
  45. new RefreshToken
  46. {
  47. Id = 2,
  48. CreationDate = DateTime.UtcNow,
  49. ExpiryDate = DateTime.UtcNow.AddDays(5),
  50. UserId = 2,
  51. Invalidated = false,
  52. JwtId = "string",
  53. Used = false,
  54. Token = "refresh"
  55. },
  56. new RefreshToken
  57. {
  58. Id = 3,
  59. CreationDate = DateTime.UtcNow,
  60. ExpiryDate = DateTime.UtcNow.AddDays(5),
  61. UserId = 3,
  62. Invalidated = false,
  63. JwtId = "string",
  64. Used = false,
  65. Token = "refresh"
  66. }
  67. };
  68. _users = new List<User>
  69. {
  70. new User
  71. {
  72. Id = 1,
  73. PasswordHash = "AQAAAAEAACcQAAAAEJnWVhD/qftzqJq5XOUD0BxEBEwhd7vS46HeDD+9cwEsqO9ev9xEORJVjmFMASUGJg==",
  74. FirstName = "User",
  75. LastName = "One",
  76. UserName = "user1",
  77. NormalizedUserName = "USER1",
  78. Email = "user1@dilig.net",
  79. NormalizedEmail = "USER1@DILIG.NET",
  80. EmailConfirmed = false,
  81. IsEnabled = true,
  82. AccessFailedCount = 0,
  83. SecurityStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
  84. ConcurrencyStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
  85. },
  86. new User
  87. {
  88. Id = 2,
  89. PasswordHash = "AQAAAAEAACcQAAAAEJnWVhD/qftzqJq5XOUD0BxEBEwhd7vS46HeDD+9cwEsqO9ev9xEORJVjmFMASUGJg==",
  90. FirstName = "User",
  91. LastName = "Two",
  92. UserName = "user2",
  93. NormalizedUserName = "USER2",
  94. Email = "user2@dilig.net",
  95. NormalizedEmail = "USER2@DILIG.NET",
  96. EmailConfirmed = false,
  97. IsEnabled = true,
  98. AccessFailedCount = 0,
  99. SecurityStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
  100. ConcurrencyStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
  101. },
  102. new User
  103. {
  104. Id = 3,
  105. PasswordHash = "AQAAAAEAACcQAAAAEJnWVhD/qftzqJq5XOUD0BxEBEwhd7vS46HeDD+9cwEsqO9ev9xEORJVjmFMASUGJg==",
  106. FirstName = "User",
  107. LastName = "Three",
  108. UserName = "user3",
  109. NormalizedUserName = "USER3",
  110. Email = "user3@dilig.net",
  111. NormalizedEmail = "USER3@DILIG.NET",
  112. EmailConfirmed = false,
  113. IsEnabled = false,
  114. AccessFailedCount = 0,
  115. SecurityStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
  116. ConcurrencyStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
  117. },
  118. new User
  119. {
  120. Id = 4,
  121. PasswordHash = "AQAAAAEAACcQAAAAEJnWVhD/qftzqJq5XOUD0BxEBEwhd7vS46HeDD+9cwEsqO9ev9xEORJVjmFMASUGJg==",
  122. FirstName = "User",
  123. LastName = "Four",
  124. UserName = "user4",
  125. NormalizedUserName = "USER4",
  126. Email = "user4@dilig.net",
  127. NormalizedEmail = "USER4@DILIG.NET",
  128. EmailConfirmed = false,
  129. IsEnabled = true,
  130. AccessFailedCount = 0,
  131. SecurityStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
  132. ConcurrencyStamp = "2D3XPK2P5MAKO377AWFU3T4ZFFYTSOJX",
  133. }
  134. };
  135. // configure mapper
  136. var configuration = new MapperConfiguration(cfg => cfg.AddProfiles(
  137. new List<Profile>
  138. {
  139. new UserMappingProfile()
  140. }));
  141. _mapper = new Mapper(configuration);
  142. }
  143. [Fact]
  144. public async Task Authenticate_ShouldReturnError_IfInvalidUsername()
  145. {
  146. _mockUserManager.FindByNameAsync(Arg.Any<string>()).ReturnsNull();
  147. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  148. var frontEndSettings = Options.Create(new FrontEndSettings
  149. {
  150. BaseUrl = "some url"
  151. });
  152. var authSettings = Options.Create(new AuthorizationSettings { });
  153. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  154. var result = await service.Authenticate(new Contracts.DTOs.Auth.AuthenticateRequestDto
  155. {
  156. Username = "Any",
  157. Password = "Any"
  158. });
  159. result.Should().BeEquivalentTo(new ServiceResponseDTO<AuthenticateResponseDto>
  160. {
  161. IsError = true,
  162. ErrorMessage = "Username is not valid"
  163. });
  164. }
  165. [Fact]
  166. public async Task Authenticate_ShouldCall_CheckPasswordAsync()
  167. {
  168. _mockUserManager.FindByNameAsync(Arg.Any<string>()).Returns(_users[1]);
  169. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  170. var frontEndSettings = Options.Create(new FrontEndSettings
  171. {
  172. BaseUrl = "some url"
  173. });
  174. var authSettings = Options.Create(new AuthorizationSettings { });
  175. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  176. await service.Authenticate(new Contracts.DTOs.Auth.AuthenticateRequestDto
  177. {
  178. Username = _users[1].Email,
  179. Password = "Any"
  180. });
  181. await _mockUserManager.Received(1).CheckPasswordAsync(_users[1], "Any");
  182. }
  183. [Fact]
  184. public async Task Authenticate_ShouldReturnError_IfUserIsDisabled()
  185. {
  186. _mockUserManager.FindByNameAsync(Arg.Any<string>()).Returns(_users[2]);
  187. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  188. var frontEndSettings = Options.Create(new FrontEndSettings
  189. {
  190. BaseUrl = "some url"
  191. });
  192. var authSettings = Options.Create(new AuthorizationSettings { });
  193. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  194. var result = await service.Authenticate(new Contracts.DTOs.Auth.AuthenticateRequestDto
  195. {
  196. Username = _users[2].Email,
  197. Password = "Any"
  198. });
  199. result.Should().BeEquivalentTo(new ServiceResponseDTO<AuthenticateResponseDto>
  200. {
  201. IsError = true,
  202. ErrorMessage = $"User with email {_users[2].Email} has no permission to log in."
  203. });
  204. }
  205. [Fact]
  206. public async Task Authenticate_ShouldReturnError_IfInvalidPassword()
  207. {
  208. _mockUserManager.FindByNameAsync(Arg.Any<string>()).Returns(_users[1]);
  209. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  210. var frontEndSettings = Options.Create(new FrontEndSettings
  211. {
  212. BaseUrl = "some url"
  213. });
  214. var authSettings = Options.Create(new AuthorizationSettings { });
  215. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  216. var result = await service.Authenticate(new Contracts.DTOs.Auth.AuthenticateRequestDto
  217. {
  218. Username = _users[1].Email,
  219. Password = "Any"
  220. });
  221. result.Should().BeEquivalentTo(new ServiceResponseDTO<AuthenticateResponseDto>
  222. {
  223. IsError = true,
  224. ErrorMessage = $"Password is not correct"
  225. });
  226. }
  227. [Fact]
  228. public async Task Authenticate_ShouldReturnError_IfUserIsLockedOut()
  229. {
  230. _mockUserManager.FindByNameAsync(Arg.Any<string>()).Returns(_users[3]);
  231. _mockUserManager.CheckPasswordAsync(Arg.Any<User>(), Arg.Any<string>()).Returns(true);
  232. _mockUserManager.IsLockedOutAsync(Arg.Any<User>()).Returns(true);
  233. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  234. var frontEndSettings = Options.Create(new FrontEndSettings
  235. {
  236. BaseUrl = "some url"
  237. });
  238. var authSettings = Options.Create(new AuthorizationSettings {
  239. Secret = "S1231251WAS124AS"
  240. });
  241. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  242. var result = await service.Authenticate(new Contracts.DTOs.Auth.AuthenticateRequestDto
  243. {
  244. Username = _users[3].Email,
  245. Password = "Nekasifra123!"
  246. });
  247. result.Should().BeEquivalentTo(new ServiceResponseDTO<AuthenticateResponseDto>
  248. {
  249. IsError = true,
  250. ErrorMessage = "The account is locked out"
  251. });
  252. }
  253. [Fact]
  254. public async Task Authenticate_ShouldGenerateToken_IfCredsAreValid()
  255. {
  256. _mockUserManager.FindByNameAsync(Arg.Any<string>()).Returns(_users[1]);
  257. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  258. var frontEndSettings = Options.Create(new FrontEndSettings
  259. {
  260. BaseUrl = "some url"
  261. });
  262. var authSettings = Options.Create(new AuthorizationSettings { });
  263. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  264. var result = await service.Authenticate(new Contracts.DTOs.Auth.AuthenticateRequestDto
  265. {
  266. Username = _users[1].Email,
  267. Password = "Nekasifra123!"
  268. });
  269. Assert.IsType<ServiceResponseDTO<AuthenticateResponseDto>>(result);
  270. }
  271. [Fact]
  272. public async Task AuthenticateGoogle_ShouldReturnError_IfInvalidApiToken()
  273. {
  274. _httpClient.IsTokenValid(Arg.Any<string>()).Returns(false);
  275. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  276. var frontEndSettings = Options.Create(new FrontEndSettings
  277. {
  278. BaseUrl = "some url"
  279. });
  280. var authSettings = Options.Create(new AuthorizationSettings { });
  281. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  282. var result = await service.Authenticate(new GoogleApiModel
  283. {
  284. Token = "t",
  285. User = new GoogleApiTokenInfo
  286. {
  287. email = "something@dilig.net"
  288. }
  289. });
  290. result.Should().BeEquivalentTo(new ServiceResponseDTO<AuthenticateResponseDto>
  291. {
  292. IsError = true,
  293. ErrorMessage = "Invalid Google Api Token"
  294. });
  295. }
  296. [Fact]
  297. public async Task AuthenticateGoogle_ShouldReturnError_IfUserDoesntExist()
  298. {
  299. _httpClient.IsTokenValid(Arg.Any<string>()).Returns(true);
  300. _mockUserManager.FindByNameAsync(Arg.Any<string>()).ReturnsNull();
  301. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  302. var frontEndSettings = Options.Create(new FrontEndSettings
  303. {
  304. BaseUrl = "some url"
  305. });
  306. var authSettings = Options.Create(new AuthorizationSettings { });
  307. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  308. var result = await service.Authenticate(new GoogleApiModel
  309. {
  310. Token = "t",
  311. User = new GoogleApiTokenInfo
  312. {
  313. email = _users[1].Email,
  314. }
  315. });
  316. result.Should().BeEquivalentTo(new ServiceResponseDTO<AuthenticateResponseDto>
  317. {
  318. IsError = true,
  319. ErrorMessage = $"User with email {_users[1].Email} does not exist in database"
  320. });
  321. }
  322. [Fact]
  323. public async Task AuthenticateGoogle_ShouldReturnError_IfUserIsDisabled()
  324. {
  325. _httpClient.IsTokenValid(Arg.Any<string>()).Returns(true);
  326. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_users[2]);
  327. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  328. var frontEndSettings = Options.Create(new FrontEndSettings
  329. {
  330. BaseUrl = "some url"
  331. });
  332. var authSettings = Options.Create(new AuthorizationSettings { });
  333. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  334. var result = await service.Authenticate(new GoogleApiModel
  335. {
  336. Token = "token",
  337. User = new GoogleApiTokenInfo
  338. {
  339. email = _users[2].Email,
  340. }
  341. });
  342. result.Should().BeEquivalentTo(new ServiceResponseDTO<AuthenticateResponseDto>
  343. {
  344. IsError = true,
  345. ErrorMessage = $"User with email {_users[2].Email} has no permission to log in."
  346. });
  347. }
  348. [Fact]
  349. public async Task AuthenticateGoogle_ShouldGenerateToken()
  350. {
  351. _httpClient.IsTokenValid(Arg.Any<string>()).Returns(true);
  352. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_users[1]);
  353. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  354. var frontEndSettings = Options.Create(new FrontEndSettings
  355. {
  356. BaseUrl = "some url"
  357. });
  358. var authSettings = Options.Create(new AuthorizationSettings
  359. {
  360. Secret = "S1231251WAS124AS"
  361. });
  362. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  363. var result = await service.Authenticate(new GoogleApiModel
  364. {
  365. Token = "token",
  366. User = new GoogleApiTokenInfo
  367. {
  368. email = _users[1].Email
  369. }
  370. });
  371. Assert.IsType<ServiceResponseDTO<AuthenticateResponseDto>>(result);
  372. }
  373. [Fact]
  374. public async Task Register_ShouldReturnError_IfUserNotFound()
  375. {
  376. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).ReturnsNull();
  377. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  378. var frontEndSettings = Options.Create(new FrontEndSettings
  379. {
  380. BaseUrl = "some url"
  381. });
  382. var authSettings = Options.Create(new AuthorizationSettings { });
  383. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  384. var result = await service.Register(new Contracts.DTOs.User.RegisterDTO
  385. {
  386. Token = "token",
  387. LinkedIn = "Link",
  388. Confirm = "Password123!",
  389. Email = _users[1].Email,
  390. Password = "Password123!",
  391. Phone = "123",
  392. Position = "Senior Dev"
  393. });
  394. result.Should().BeEquivalentTo(new ServiceResponseDTO<AuthenticateResponseDto>
  395. {
  396. IsError = true,
  397. ErrorMessage = "User not invited."
  398. });
  399. }
  400. [Fact]
  401. public async Task Register_ShouldCreateUser_IfUserExists()
  402. {
  403. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_users[1]);
  404. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  405. var frontEndSettings = Options.Create(new FrontEndSettings
  406. {
  407. BaseUrl = "some url"
  408. });
  409. var authSettings = Options.Create(new AuthorizationSettings { });
  410. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  411. _mockUserManager.ResetPasswordAsync(Arg.Any<User>(), Arg.Any<string>(), Arg.Any<string>()).Returns(IdentityResult.Success);
  412. var result = await service.Register(new Contracts.DTOs.User.RegisterDTO
  413. {
  414. Token = "token",
  415. LinkedIn = "Link",
  416. Confirm = "Password123!",
  417. Email = _users[1].Email,
  418. Password = "Password123!",
  419. Phone = "123",
  420. Position = "Senior Dev"
  421. });
  422. result.Should().BeEquivalentTo(new ServiceResponseDTO<object>
  423. {
  424. Data = true,
  425. });
  426. }
  427. [Fact]
  428. public async Task Register_ShouldThrowError_IfUnsuccessfulReset()
  429. {
  430. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_users[1]);
  431. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  432. var frontEndSettings = Options.Create(new FrontEndSettings
  433. {
  434. BaseUrl = "some url"
  435. });
  436. var authSettings = Options.Create(new AuthorizationSettings { });
  437. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  438. _mockUserManager.ResetPasswordAsync(Arg.Any<User>(), Arg.Any<string>(), Arg.Any<string>())
  439. .Returns(IdentityResult.Failed(
  440. new IdentityError[] {
  441. new IdentityError {
  442. Description= "Failed"
  443. }
  444. }
  445. ));
  446. var result = await service.Register(new Contracts.DTOs.User.RegisterDTO
  447. {
  448. Token = "token",
  449. LinkedIn = "Link",
  450. Confirm = "Password123!",
  451. Email = _users[1].Email,
  452. Password = "Password123!",
  453. Phone = "123",
  454. Position = "Senior Dev"
  455. });
  456. result.Should().BeEquivalentTo(new ServiceResponseDTO<object>
  457. {
  458. IsError = true,
  459. ErrorMessage = "Failed"
  460. });
  461. }
  462. [Fact]
  463. public async Task PasswordResetAsync_ShouldReturnError_IfUserNotFound()
  464. {
  465. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).ReturnsNull();
  466. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  467. var frontEndSettings = Options.Create(new FrontEndSettings
  468. {
  469. BaseUrl = "some url"
  470. });
  471. var authSettings = Options.Create(new AuthorizationSettings { });
  472. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  473. var result = await service.PasswordResetAsync(
  474. email: _users[1].Email,
  475. code: "code",
  476. password: "Password123!"
  477. );
  478. result.Should().BeEquivalentTo(new ServiceResponseDTO<object>
  479. {
  480. IsError = true,
  481. ErrorMessage = "Email did not find."
  482. });
  483. }
  484. [Fact]
  485. public async Task PasswordResetAsync_ShouldResetToken_IfUserFound()
  486. {
  487. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_users[1]);
  488. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  489. var frontEndSettings = Options.Create(new FrontEndSettings
  490. {
  491. BaseUrl = "some url"
  492. });
  493. _mockUserManager.ResetPasswordAsync(Arg.Any<User>(), Arg.Any<string>(), Arg.Any<string>())
  494. .Returns(IdentityResult.Success);
  495. var authSettings = Options.Create(new AuthorizationSettings { });
  496. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  497. var result = await service.PasswordResetAsync(
  498. email: _users[1].Email,
  499. code: "code",
  500. password: "Password123!"
  501. );
  502. result.Should().BeEquivalentTo(new ServiceResponseDTO<object>
  503. { Data = true }
  504. );
  505. }
  506. [Fact]
  507. public async Task PasswordResetAsync_ShouldReturnError_IfUnsuccessfulReset()
  508. {
  509. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_users[1]);
  510. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  511. var frontEndSettings = Options.Create(new FrontEndSettings
  512. {
  513. BaseUrl = "some url"
  514. });
  515. _mockUserManager.ResetPasswordAsync(Arg.Any<User>(), Arg.Any<string>(), Arg.Any<string>())
  516. .Returns(IdentityResult.Failed(
  517. new IdentityError[] {
  518. new IdentityError {
  519. Description= "Failed"
  520. }
  521. }
  522. ));
  523. var authSettings = Options.Create(new AuthorizationSettings { });
  524. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  525. var result = await service.PasswordResetAsync(
  526. email: _users[1].Email,
  527. code: "code",
  528. password: "Password123!"
  529. );
  530. result.Should().BeEquivalentTo(new ServiceResponseDTO<object>
  531. {
  532. IsError = true,
  533. ErrorMessage = "Failed"
  534. });
  535. }
  536. [Fact]
  537. public async Task GetForgotPasswordUrlAsync_ShouldReturnError_IfUserNotFound()
  538. {
  539. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).ReturnsNull();
  540. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  541. var frontEndSettings = Options.Create(new FrontEndSettings
  542. {
  543. BaseUrl = "some url"
  544. });
  545. var authSettings = Options.Create(new AuthorizationSettings { });
  546. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  547. var result = await service.GetForgotPasswordUrlAsync(_users[1].Email);
  548. result.Should().BeEquivalentTo(new ServiceResponseDTO<object>
  549. {
  550. IsError = true,
  551. ErrorMessage = "Email did not find."
  552. });
  553. }
  554. [Fact]
  555. public async Task GetForgotPasswordUrlAsync_ShouldReturnSuccess_IfUserIsFound()
  556. {
  557. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_users[1]);
  558. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  559. var frontEndSettings = Options.Create(new FrontEndSettings
  560. {
  561. BaseUrl = "some url"
  562. });
  563. var authSettings = Options.Create(new AuthorizationSettings { });
  564. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  565. await service.GetForgotPasswordUrlAsync(_users[1].Email);
  566. await _emailer.ReceivedWithAnyArgs(1)
  567. .SendEmailAndWriteToDbAsync("mail", "reset", "url", true);
  568. }
  569. [Fact]
  570. public async Task GetForgotPasswordUrlAsync_ShouldCallEmailer_IfUserIsFound()
  571. {
  572. _mockUserManager.FindByEmailAsync(Arg.Any<string>()).Returns(_users[1]);
  573. var databaseContext = await Helpers<User>.GetDatabaseContext(_users);
  574. var frontEndSettings = Options.Create(new FrontEndSettings
  575. {
  576. BaseUrl = "some url"
  577. });
  578. var authSettings = Options.Create(new AuthorizationSettings { });
  579. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  580. var result = await service.GetForgotPasswordUrlAsync(_users[1].Email);
  581. result.Should().BeOfType(typeof(ServiceResponseDTO<object>));
  582. }
  583. [Fact]
  584. public async Task UpdateRefreshToken_ShouldUpdate()
  585. {
  586. var databaseContext = await Helpers<User>.GetDatabaseContextWithRelation(_users, _tokens);
  587. var authSettings = Options.Create(new AuthorizationSettings { });
  588. var frontEndSettings = Options.Create(new FrontEndSettings
  589. {
  590. BaseUrl = "some url"
  591. });
  592. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  593. var first = await databaseContext.RefreshTokens.FindAsync(1);
  594. await service.UpdateRefreshToken(first);
  595. databaseContext.Entry(first).Should().NotBeNull();
  596. }
  597. [Fact]
  598. public async Task DeleteRefreshToken_ShouldReturnError_IfTokenDoesNotExist()
  599. {
  600. var databaseContext = await Helpers<User>.GetDatabaseContextWithRelation(_users, _tokens);
  601. var authSettings = Options.Create(new AuthorizationSettings { });
  602. var frontEndSettings = Options.Create(new FrontEndSettings
  603. {
  604. BaseUrl = "some url"
  605. });
  606. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  607. var result = await service.DeleteRefreshToken(1000); // not existing token
  608. result.Should().BeEquivalentTo(new ServiceResponseDTO<string>
  609. {
  610. IsError = true,
  611. ErrorMessage = "There is no refresh token for user"
  612. });
  613. }
  614. [Fact]
  615. public async Task DeleteRefreshToken_ShouldSucceed_IfTokenExists()
  616. {
  617. var databaseContext = await Helpers<User>.GetDatabaseContextWithRelation(_users, _tokens);
  618. var authSettings = Options.Create(new AuthorizationSettings { });
  619. var frontEndSettings = Options.Create(new FrontEndSettings
  620. {
  621. BaseUrl = "some url"
  622. });
  623. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  624. var result = await service.DeleteRefreshToken(1); // not existing token
  625. result.Should().BeEquivalentTo(new ServiceResponseDTO<string>
  626. {
  627. Data = null
  628. });
  629. }
  630. [Fact]
  631. public async Task GetRefreshTokenByUserId_ShouldReturnTokenOrNull()
  632. {
  633. var databaseContext = await Helpers<User>.GetDatabaseContextWithRelation(_users, _tokens);
  634. var authSettings = Options.Create(new AuthorizationSettings { });
  635. var frontEndSettings = Options.Create(new FrontEndSettings
  636. {
  637. BaseUrl = "some url"
  638. });
  639. var service = new AuthenticationService(authSettings, frontEndSettings, _mockUserManager, databaseContext, _emailer, _logger, _httpClient, _mapper);
  640. var result = await service.GetRefreshTokenByUserId(1);
  641. result.Should().BeEquivalentTo(_tokens[0]);
  642. }
  643. }
  644. }