mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 15:42:48 -05:00
PM-18939 refactoring send service to 'cqrs' (#5652)
* PM-18939 refactoring send service to 'cqrs' * PM-18939 fixing import issue with sendValidationService * PM-18939 fixing code based on PR comments * PM-18339 reverting to previous code in test * PM-18939 adding XMLdocs to services * PM-18939 reverting send validation methods * PM-18939 updating code to match main * PM-18939 reverting validateUserCanSaveAsync to match main * PM-18939 fill our param and return sections of XMLdocs * PM-18939 updating XMLdocs based on PR comments * Update src/Core/Tools/SendFeatures/Commands/Interfaces/IAnonymousSendCommand.cs Co-authored-by: ✨ Audrey ✨ <ajensen@bitwarden.com> * Update src/Core/Tools/SendFeatures/Commands/Interfaces/INonAnonymousSendCommand.cs Co-authored-by: ✨ Audrey ✨ <ajensen@bitwarden.com> * Update src/Core/Tools/SendFeatures/Commands/Interfaces/INonAnonymousSendCommand.cs Co-authored-by: ✨ Audrey ✨ <ajensen@bitwarden.com> * Update src/Core/Tools/SendFeatures/Services/Interfaces/ISendStorageService.cs Co-authored-by: ✨ Audrey ✨ <ajensen@bitwarden.com> * PM-18939 adding commits to change tuple to enum type * PM-18939 resetting stream position to 0 when uploading file * PM-18939 updating XMLdocs based on PR comments * PM-18939 updating XMLdocs * PM-18939 removing circular dependency * PM-18939 fixing based on comments * PM-18939 updating method name and documentation --------- Co-authored-by: ✨ Audrey ✨ <ajensen@bitwarden.com>
This commit is contained in:
118
test/Core.Test/Tools/Services/AnonymousSendCommandTests.cs
Normal file
118
test/Core.Test/Tools/Services/AnonymousSendCommandTests.cs
Normal file
@ -0,0 +1,118 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Tools.Entities;
|
||||
using Bit.Core.Tools.Enums;
|
||||
using Bit.Core.Tools.Models.Data;
|
||||
using Bit.Core.Tools.Repositories;
|
||||
using Bit.Core.Tools.SendFeatures.Commands;
|
||||
using Bit.Core.Tools.Services;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Tools.Services;
|
||||
|
||||
public class AnonymousSendCommandTests
|
||||
{
|
||||
private readonly ISendRepository _sendRepository;
|
||||
private readonly ISendFileStorageService _sendFileStorageService;
|
||||
private readonly IPushNotificationService _pushNotificationService;
|
||||
private readonly ISendAuthorizationService _sendAuthorizationService;
|
||||
private readonly AnonymousSendCommand _anonymousSendCommand;
|
||||
|
||||
public AnonymousSendCommandTests()
|
||||
{
|
||||
_sendRepository = Substitute.For<ISendRepository>();
|
||||
_sendFileStorageService = Substitute.For<ISendFileStorageService>();
|
||||
_pushNotificationService = Substitute.For<IPushNotificationService>();
|
||||
_sendAuthorizationService = Substitute.For<ISendAuthorizationService>();
|
||||
|
||||
_anonymousSendCommand = new AnonymousSendCommand(
|
||||
_sendRepository,
|
||||
_sendFileStorageService,
|
||||
_pushNotificationService,
|
||||
_sendAuthorizationService);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSendFileDownloadUrlAsync_Success_ReturnsDownloadUrl()
|
||||
{
|
||||
// Arrange
|
||||
var send = new Send
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Type = SendType.File,
|
||||
AccessCount = 0,
|
||||
Data = JsonSerializer.Serialize(new { Id = "fileId123" })
|
||||
};
|
||||
var fileId = "fileId123";
|
||||
var password = "testPassword";
|
||||
var expectedUrl = "https://example.com/download";
|
||||
|
||||
_sendAuthorizationService
|
||||
.SendCanBeAccessed(send, password)
|
||||
.Returns(SendAccessResult.Granted);
|
||||
|
||||
_sendFileStorageService
|
||||
.GetSendFileDownloadUrlAsync(send, fileId)
|
||||
.Returns(expectedUrl);
|
||||
|
||||
// Act
|
||||
var result =
|
||||
await _anonymousSendCommand.GetSendFileDownloadUrlAsync(send, fileId, password);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedUrl, result.Item1);
|
||||
Assert.Equal(1, send.AccessCount);
|
||||
|
||||
await _sendRepository.Received(1).ReplaceAsync(send);
|
||||
await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSendFileDownloadUrlAsync_AccessDenied_ReturnsNullWithReasons()
|
||||
{
|
||||
// Arrange
|
||||
var send = new Send
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Type = SendType.File,
|
||||
AccessCount = 0
|
||||
};
|
||||
var fileId = "fileId123";
|
||||
var password = "wrongPassword";
|
||||
|
||||
_sendAuthorizationService
|
||||
.SendCanBeAccessed(send, password)
|
||||
.Returns(SendAccessResult.Denied);
|
||||
|
||||
// Act
|
||||
var result =
|
||||
await _anonymousSendCommand.GetSendFileDownloadUrlAsync(send, fileId, password);
|
||||
|
||||
// Assert
|
||||
Assert.Null(result.Item1);
|
||||
Assert.Equal(SendAccessResult.Denied, result.Item2);
|
||||
Assert.Equal(0, send.AccessCount);
|
||||
|
||||
await _sendRepository.DidNotReceiveWithAnyArgs().ReplaceAsync(default);
|
||||
await _pushNotificationService.DidNotReceiveWithAnyArgs().PushSyncSendUpdateAsync(default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSendFileDownloadUrlAsync_NotFileSend_ThrowsBadRequestException()
|
||||
{
|
||||
// Arrange
|
||||
var send = new Send
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Type = SendType.Text
|
||||
};
|
||||
var fileId = "fileId123";
|
||||
var password = "testPassword";
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
_anonymousSendCommand.GetSendFileDownloadUrlAsync(send, fileId, password));
|
||||
}
|
||||
}
|
1111
test/Core.Test/Tools/Services/NonAnonymousSendCommandTests.cs
Normal file
1111
test/Core.Test/Tools/Services/NonAnonymousSendCommandTests.cs
Normal file
File diff suppressed because it is too large
Load Diff
175
test/Core.Test/Tools/Services/SendAuthorizationServiceTests.cs
Normal file
175
test/Core.Test/Tools/Services/SendAuthorizationServiceTests.cs
Normal file
@ -0,0 +1,175 @@
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Tools.Entities;
|
||||
using Bit.Core.Tools.Models.Data;
|
||||
using Bit.Core.Tools.Repositories;
|
||||
using Bit.Core.Tools.Services;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Tools.Services;
|
||||
|
||||
public class SendAuthorizationServiceTests
|
||||
{
|
||||
private readonly ISendRepository _sendRepository;
|
||||
private readonly IPasswordHasher<Bit.Core.Entities.User> _passwordHasher;
|
||||
private readonly IPushNotificationService _pushNotificationService;
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly SendAuthorizationService _sendAuthorizationService;
|
||||
|
||||
public SendAuthorizationServiceTests()
|
||||
{
|
||||
_sendRepository = Substitute.For<ISendRepository>();
|
||||
_passwordHasher = Substitute.For<IPasswordHasher<Bit.Core.Entities.User>>();
|
||||
_pushNotificationService = Substitute.For<IPushNotificationService>();
|
||||
_referenceEventService = Substitute.For<IReferenceEventService>();
|
||||
_currentContext = Substitute.For<ICurrentContext>();
|
||||
|
||||
_sendAuthorizationService = new SendAuthorizationService(
|
||||
_sendRepository,
|
||||
_passwordHasher,
|
||||
_pushNotificationService,
|
||||
_referenceEventService,
|
||||
_currentContext);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void SendCanBeAccessed_Success_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var send = new Send
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserId = Guid.NewGuid(),
|
||||
MaxAccessCount = 10,
|
||||
AccessCount = 5,
|
||||
ExpirationDate = DateTime.UtcNow.AddYears(1),
|
||||
DeletionDate = DateTime.UtcNow.AddYears(1),
|
||||
Disabled = false,
|
||||
Password = "hashedPassword123"
|
||||
};
|
||||
|
||||
const string password = "TEST";
|
||||
|
||||
_passwordHasher
|
||||
.VerifyHashedPassword(Arg.Any<Bit.Core.Entities.User>(), send.Password, password)
|
||||
.Returns(PasswordVerificationResult.Success);
|
||||
|
||||
// Act
|
||||
var result =
|
||||
_sendAuthorizationService.SendCanBeAccessed(send, password);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SendAccessResult.Granted, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SendCanBeAccessed_NullMaxAccess_Success()
|
||||
{
|
||||
// Arrange
|
||||
var send = new Send
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserId = Guid.NewGuid(),
|
||||
MaxAccessCount = null,
|
||||
AccessCount = 5,
|
||||
ExpirationDate = DateTime.UtcNow.AddYears(1),
|
||||
DeletionDate = DateTime.UtcNow.AddYears(1),
|
||||
Disabled = false,
|
||||
Password = "hashedPassword123"
|
||||
};
|
||||
|
||||
const string password = "TEST";
|
||||
|
||||
_passwordHasher
|
||||
.VerifyHashedPassword(Arg.Any<Bit.Core.Entities.User>(), send.Password, password)
|
||||
.Returns(PasswordVerificationResult.Success);
|
||||
|
||||
// Act
|
||||
var result = _sendAuthorizationService.SendCanBeAccessed(send, password);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SendAccessResult.Granted, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SendCanBeAccessed_NullSend_DoesNotGrantAccess()
|
||||
{
|
||||
// Arrange
|
||||
_passwordHasher
|
||||
.VerifyHashedPassword(Arg.Any<Bit.Core.Entities.User>(), "TEST", "TEST")
|
||||
.Returns(PasswordVerificationResult.Success);
|
||||
|
||||
// Act
|
||||
var result =
|
||||
_sendAuthorizationService.SendCanBeAccessed(null, "TEST");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SendAccessResult.Denied, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SendCanBeAccessed_RehashNeeded_RehashesPassword()
|
||||
{
|
||||
// Arrange
|
||||
var now = DateTime.UtcNow;
|
||||
var send = new Send
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserId = Guid.NewGuid(),
|
||||
MaxAccessCount = null,
|
||||
AccessCount = 5,
|
||||
ExpirationDate = now.AddYears(1),
|
||||
DeletionDate = now.AddYears(1),
|
||||
Disabled = false,
|
||||
Password = "TEST"
|
||||
};
|
||||
|
||||
_passwordHasher
|
||||
.VerifyHashedPassword(Arg.Any<Bit.Core.Entities.User>(), "TEST", "TEST")
|
||||
.Returns(PasswordVerificationResult.SuccessRehashNeeded);
|
||||
|
||||
// Act
|
||||
var result =
|
||||
_sendAuthorizationService.SendCanBeAccessed(send, "TEST");
|
||||
|
||||
// Assert
|
||||
_passwordHasher
|
||||
.Received(1)
|
||||
.HashPassword(Arg.Any<Bit.Core.Entities.User>(), "TEST");
|
||||
|
||||
Assert.Equal(SendAccessResult.Granted, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SendCanBeAccessed_VerifyFailed_PasswordInvalidReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var now = DateTime.UtcNow;
|
||||
var send = new Send
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserId = Guid.NewGuid(),
|
||||
MaxAccessCount = null,
|
||||
AccessCount = 5,
|
||||
ExpirationDate = now.AddYears(1),
|
||||
DeletionDate = now.AddYears(1),
|
||||
Disabled = false,
|
||||
Password = "TEST"
|
||||
};
|
||||
|
||||
_passwordHasher
|
||||
.VerifyHashedPassword(Arg.Any<Bit.Core.Entities.User>(), "TEST", "TEST")
|
||||
.Returns(PasswordVerificationResult.Failed);
|
||||
|
||||
// Act
|
||||
var result =
|
||||
_sendAuthorizationService.SendCanBeAccessed(send, "TEST");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SendAccessResult.PasswordInvalid, result);
|
||||
}
|
||||
}
|
@ -1,867 +0,0 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
using Bit.Core.AdminConsole.Services;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.AutoFixture.CurrentContextFixtures;
|
||||
using Bit.Core.Test.Entities;
|
||||
using Bit.Core.Test.Tools.AutoFixture.SendFixtures;
|
||||
using Bit.Core.Tools.Entities;
|
||||
using Bit.Core.Tools.Enums;
|
||||
using Bit.Core.Tools.Models.Data;
|
||||
using Bit.Core.Tools.Repositories;
|
||||
using Bit.Core.Tools.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using NSubstitute;
|
||||
using NSubstitute.ExceptionExtensions;
|
||||
using Xunit;
|
||||
|
||||
using GlobalSettings = Bit.Core.Settings.GlobalSettings;
|
||||
|
||||
namespace Bit.Core.Test.Tools.Services;
|
||||
|
||||
[SutProviderCustomize]
|
||||
[CurrentContextCustomize]
|
||||
[UserSendCustomize]
|
||||
public class SendServiceTests
|
||||
{
|
||||
private void SaveSendAsync_Setup(SendType sendType, bool disableSendPolicyAppliesToUser,
|
||||
SutProvider<SendService> sutProvider, Send send)
|
||||
{
|
||||
send.Id = default;
|
||||
send.Type = sendType;
|
||||
|
||||
sutProvider.GetDependency<IPolicyService>().AnyPoliciesApplicableToUserAsync(
|
||||
Arg.Any<Guid>(), PolicyType.DisableSend).Returns(disableSendPolicyAppliesToUser);
|
||||
}
|
||||
|
||||
// Disable Send policy check
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableSend_Applies_throws(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, disableSendPolicyAppliesToUser: true, sutProvider, send);
|
||||
|
||||
await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.SaveSendAsync(send));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableSend_DoesntApply_success(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, disableSendPolicyAppliesToUser: false, sutProvider, send);
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
// Send Options Policy - Disable Hide Email check
|
||||
|
||||
private void SaveSendAsync_HideEmail_Setup(bool disableHideEmailAppliesToUser,
|
||||
SutProvider<SendService> sutProvider, Send send, Policy policy)
|
||||
{
|
||||
send.HideEmail = true;
|
||||
|
||||
var sendOptions = new SendOptionsPolicyData
|
||||
{
|
||||
DisableHideEmail = disableHideEmailAppliesToUser
|
||||
};
|
||||
policy.Data = JsonSerializer.Serialize(sendOptions, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
});
|
||||
|
||||
sutProvider.GetDependency<IPolicyService>().GetPoliciesApplicableToUserAsync(
|
||||
Arg.Any<Guid>(), PolicyType.SendOptions).Returns(new List<OrganizationUserPolicyDetails>()
|
||||
{
|
||||
new() { PolicyType = policy.Type, PolicyData = policy.Data, OrganizationId = policy.OrganizationId, PolicyEnabled = policy.Enabled }
|
||||
});
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableHideEmail_Applies_throws(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send, Policy policy)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, false, sutProvider, send);
|
||||
SaveSendAsync_HideEmail_Setup(true, sutProvider, send, policy);
|
||||
|
||||
await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.SaveSendAsync(send));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableHideEmail_DoesntApply_success(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, Send send, Policy policy)
|
||||
{
|
||||
SaveSendAsync_Setup(sendType, false, sutProvider, send);
|
||||
SaveSendAsync_HideEmail_Setup(false, sutProvider, send, policy);
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
// Disable Send policy check - vNext
|
||||
private void SaveSendAsync_Setup_vNext(SutProvider<SendService> sutProvider, Send send,
|
||||
DisableSendPolicyRequirement disableSendPolicyRequirement, SendOptionsPolicyRequirement sendOptionsPolicyRequirement)
|
||||
{
|
||||
sutProvider.GetDependency<IPolicyRequirementQuery>().GetAsync<DisableSendPolicyRequirement>(send.UserId!.Value)
|
||||
.Returns(disableSendPolicyRequirement);
|
||||
sutProvider.GetDependency<IPolicyRequirementQuery>().GetAsync<SendOptionsPolicyRequirement>(send.UserId!.Value)
|
||||
.Returns(sendOptionsPolicyRequirement);
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||
|
||||
// Should not be called in these tests
|
||||
sutProvider.GetDependency<IPolicyService>().AnyPoliciesApplicableToUserAsync(
|
||||
Arg.Any<Guid>(), Arg.Any<PolicyType>()).ThrowsAsync<Exception>();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableSend_Applies_Throws_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new DisableSendPolicyRequirement { DisableSend = true }, new SendOptionsPolicyRequirement());
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.SaveSendAsync(send));
|
||||
Assert.Contains("Due to an Enterprise Policy, you are only able to delete an existing Send.",
|
||||
exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableSend_DoesntApply_Success_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new DisableSendPolicyRequirement(), new SendOptionsPolicyRequirement());
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
// Send Options Policy - Disable Hide Email check
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableHideEmail_Applies_Throws_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new DisableSendPolicyRequirement(), new SendOptionsPolicyRequirement { DisableHideEmail = true });
|
||||
send.HideEmail = true;
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.SaveSendAsync(send));
|
||||
Assert.Contains("Due to an Enterprise Policy, you are not allowed to hide your email address from recipients when creating or editing a Send.", exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableHideEmail_Applies_ButEmailNotHidden_Success_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new DisableSendPolicyRequirement(), new SendOptionsPolicyRequirement { DisableHideEmail = true });
|
||||
send.HideEmail = false;
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableHideEmail_DoesntApply_Success_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new DisableSendPolicyRequirement(), new SendOptionsPolicyRequirement());
|
||||
send.HideEmail = true;
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveSendAsync_ExistingSend_Updates(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
send.Id = Guid.NewGuid();
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
Assert.True(send.RevisionDate - now < TimeSpan.FromSeconds(1));
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>()
|
||||
.Received(1)
|
||||
.UpsertAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncSendUpdateAsync(send);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_TextType_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
send.Type = SendType.Text;
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 0)
|
||||
);
|
||||
|
||||
Assert.Contains("not of type \"file\"", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_EmptyFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
send.Type = SendType.File;
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 0)
|
||||
);
|
||||
|
||||
Assert.Contains("no file data", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_UserCannotAccessPremium_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
};
|
||||
|
||||
send.UserId = user.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetByIdAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.CanAccessPremium(user)
|
||||
.Returns(false);
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 1)
|
||||
);
|
||||
|
||||
Assert.Contains("must have premium", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_UserHasUnconfirmedEmail_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
EmailVerified = false,
|
||||
};
|
||||
|
||||
send.UserId = user.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetByIdAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.CanAccessPremium(user)
|
||||
.Returns(true);
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 1)
|
||||
);
|
||||
|
||||
Assert.Contains("must confirm your email", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_UserCanAccessPremium_HasNoStorage_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
EmailVerified = true,
|
||||
Premium = true,
|
||||
MaxStorageGb = null,
|
||||
Storage = 0,
|
||||
};
|
||||
|
||||
send.UserId = user.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetByIdAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.CanAccessPremium(user)
|
||||
.Returns(true);
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 1)
|
||||
);
|
||||
|
||||
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_UserCanAccessPremium_StorageFull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
EmailVerified = true,
|
||||
Premium = true,
|
||||
MaxStorageGb = 2,
|
||||
Storage = 2 * UserTests.Multiplier,
|
||||
};
|
||||
|
||||
send.UserId = user.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetByIdAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.CanAccessPremium(user)
|
||||
.Returns(true);
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 1)
|
||||
);
|
||||
|
||||
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_UserCanAccessPremium_IsNotPremium_IsSelfHosted_GiantFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
EmailVerified = true,
|
||||
Premium = false,
|
||||
};
|
||||
|
||||
send.UserId = user.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetByIdAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.CanAccessPremium(user)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<GlobalSettings>()
|
||||
.SelfHosted = true;
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 11000 * UserTests.Multiplier)
|
||||
);
|
||||
|
||||
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_UserCanAccessPremium_IsNotPremium_IsNotSelfHosted_TwoGigabyteFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
EmailVerified = true,
|
||||
Premium = false,
|
||||
};
|
||||
|
||||
send.UserId = user.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetByIdAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.CanAccessPremium(user)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<GlobalSettings>()
|
||||
.SelfHosted = false;
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 2 * UserTests.Multiplier)
|
||||
);
|
||||
|
||||
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_ThroughOrg_MaxStorageIsNull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var org = new Organization
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
MaxStorageGb = null,
|
||||
};
|
||||
|
||||
send.UserId = null;
|
||||
send.OrganizationId = org.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>()
|
||||
.GetByIdAsync(org.Id)
|
||||
.Returns(org);
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 1)
|
||||
);
|
||||
|
||||
Assert.Contains("organization cannot use file sends", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_ThroughOrg_MaxStorageIsNull_TwoGBFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var org = new Organization
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
MaxStorageGb = null,
|
||||
};
|
||||
|
||||
send.UserId = null;
|
||||
send.OrganizationId = org.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>()
|
||||
.GetByIdAsync(org.Id)
|
||||
.Returns(org);
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 1)
|
||||
);
|
||||
|
||||
Assert.Contains("organization cannot use file sends", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_ThroughOrg_MaxStorageIsOneGB_TwoGBFile_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var org = new Organization
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
MaxStorageGb = 1,
|
||||
};
|
||||
|
||||
send.UserId = null;
|
||||
send.OrganizationId = org.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>()
|
||||
.GetByIdAsync(org.Id)
|
||||
.Returns(org);
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, null, 2 * UserTests.Multiplier)
|
||||
);
|
||||
|
||||
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_HasEnoughStorage_Success(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
EmailVerified = true,
|
||||
MaxStorageGb = 10,
|
||||
};
|
||||
|
||||
var data = new SendFileData
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
send.UserId = user.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
var testUrl = "https://test.com/";
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetByIdAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.CanAccessPremium(user)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ISendFileStorageService>()
|
||||
.GetSendFileUploadUrlAsync(send, Arg.Any<string>())
|
||||
.Returns(testUrl);
|
||||
|
||||
var utcNow = DateTime.UtcNow;
|
||||
|
||||
var url = await sutProvider.Sut.SaveFileSendAsync(send, data, 1 * UserTests.Multiplier);
|
||||
|
||||
Assert.Equal(testUrl, url);
|
||||
Assert.True(send.RevisionDate - utcNow < TimeSpan.FromSeconds(1));
|
||||
|
||||
await sutProvider.GetDependency<ISendFileStorageService>()
|
||||
.Received(1)
|
||||
.GetSendFileUploadUrlAsync(send, Arg.Any<string>());
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>()
|
||||
.Received(1)
|
||||
.UpsertAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncSendUpdateAsync(send);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveFileSendAsync_HasEnoughStorage_SendFileThrows_CleansUp(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
EmailVerified = true,
|
||||
MaxStorageGb = 10,
|
||||
};
|
||||
|
||||
var data = new SendFileData
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
send.UserId = user.Id;
|
||||
send.Type = SendType.File;
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetByIdAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.CanAccessPremium(user)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ISendFileStorageService>()
|
||||
.GetSendFileUploadUrlAsync(send, Arg.Any<string>())
|
||||
.Returns<string>(callInfo => throw new Exception("Problem"));
|
||||
|
||||
var utcNow = DateTime.UtcNow;
|
||||
|
||||
var exception = await Assert.ThrowsAsync<Exception>(() =>
|
||||
sutProvider.Sut.SaveFileSendAsync(send, data, 1 * UserTests.Multiplier)
|
||||
);
|
||||
|
||||
Assert.True(send.RevisionDate - utcNow < TimeSpan.FromSeconds(1));
|
||||
Assert.Equal("Problem", exception.Message);
|
||||
|
||||
await sutProvider.GetDependency<ISendFileStorageService>()
|
||||
.Received(1)
|
||||
.GetSendFileUploadUrlAsync(send, Arg.Any<string>());
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>()
|
||||
.Received(1)
|
||||
.UpsertAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncSendUpdateAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendFileStorageService>()
|
||||
.Received(1)
|
||||
.DeleteFileAsync(send, Arg.Any<string>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task UpdateFileToExistingSendAsync_SendNull_ThrowsBadRequest(SutProvider<SendService> sutProvider)
|
||||
{
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(), null)
|
||||
);
|
||||
|
||||
Assert.Contains("does not have file data", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task UpdateFileToExistingSendAsync_SendDataNull_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
send.Data = null;
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(), send)
|
||||
);
|
||||
|
||||
Assert.Contains("does not have file data", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task UpdateFileToExistingSendAsync_NotFileType_ThrowsBadRequest(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(), send)
|
||||
);
|
||||
|
||||
Assert.Contains("not a file type send", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task UpdateFileToExistingSendAsync_Success(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var fileContents = "Test file content";
|
||||
|
||||
var sendFileData = new SendFileData
|
||||
{
|
||||
Id = "TEST",
|
||||
Size = fileContents.Length,
|
||||
Validated = false,
|
||||
};
|
||||
|
||||
send.Type = SendType.File;
|
||||
send.Data = JsonSerializer.Serialize(sendFileData);
|
||||
|
||||
sutProvider.GetDependency<ISendFileStorageService>()
|
||||
.ValidateFileAsync(send, sendFileData.Id, sendFileData.Size, Arg.Any<long>())
|
||||
.Returns((true, sendFileData.Size));
|
||||
|
||||
await sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(Encoding.UTF8.GetBytes(fileContents)), send);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task UpdateFileToExistingSendAsync_InvalidSize(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var fileContents = "Test file content";
|
||||
|
||||
var sendFileData = new SendFileData
|
||||
{
|
||||
Id = "TEST",
|
||||
Size = fileContents.Length,
|
||||
};
|
||||
|
||||
send.Type = SendType.File;
|
||||
send.Data = JsonSerializer.Serialize(sendFileData);
|
||||
|
||||
sutProvider.GetDependency<ISendFileStorageService>()
|
||||
.ValidateFileAsync(send, sendFileData.Id, sendFileData.Size, Arg.Any<long>())
|
||||
.Returns((false, sendFileData.Size));
|
||||
|
||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(Encoding.UTF8.GetBytes(fileContents)), send)
|
||||
);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void SendCanBeAccessed_Success(SutProvider<SendService> sutProvider, Send send)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
send.MaxAccessCount = 10;
|
||||
send.AccessCount = 5;
|
||||
send.ExpirationDate = now.AddYears(1);
|
||||
send.DeletionDate = now.AddYears(1);
|
||||
send.Disabled = false;
|
||||
|
||||
sutProvider.GetDependency<IPasswordHasher<User>>()
|
||||
.VerifyHashedPassword(Arg.Any<User>(), send.Password, "TEST")
|
||||
.Returns(PasswordVerificationResult.Success);
|
||||
|
||||
var (grant, passwordRequiredError, passwordInvalidError)
|
||||
= sutProvider.Sut.SendCanBeAccessed(send, "TEST");
|
||||
|
||||
Assert.True(grant);
|
||||
Assert.False(passwordRequiredError);
|
||||
Assert.False(passwordInvalidError);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void SendCanBeAccessed_NullMaxAccess_Success(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
send.MaxAccessCount = null;
|
||||
send.AccessCount = 5;
|
||||
send.ExpirationDate = now.AddYears(1);
|
||||
send.DeletionDate = now.AddYears(1);
|
||||
send.Disabled = false;
|
||||
|
||||
sutProvider.GetDependency<IPasswordHasher<User>>()
|
||||
.VerifyHashedPassword(Arg.Any<User>(), send.Password, "TEST")
|
||||
.Returns(PasswordVerificationResult.Success);
|
||||
|
||||
var (grant, passwordRequiredError, passwordInvalidError)
|
||||
= sutProvider.Sut.SendCanBeAccessed(send, "TEST");
|
||||
|
||||
Assert.True(grant);
|
||||
Assert.False(passwordRequiredError);
|
||||
Assert.False(passwordInvalidError);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void SendCanBeAccessed_NullSend_DoesNotGrantAccess(SutProvider<SendService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IPasswordHasher<User>>()
|
||||
.VerifyHashedPassword(Arg.Any<User>(), "TEST", "TEST")
|
||||
.Returns(PasswordVerificationResult.Success);
|
||||
|
||||
var (grant, passwordRequiredError, passwordInvalidError)
|
||||
= sutProvider.Sut.SendCanBeAccessed(null, "TEST");
|
||||
|
||||
Assert.False(grant);
|
||||
Assert.False(passwordRequiredError);
|
||||
Assert.False(passwordInvalidError);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void SendCanBeAccessed_NullPassword_PasswordRequiredErrorReturnsTrue(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
send.MaxAccessCount = null;
|
||||
send.AccessCount = 5;
|
||||
send.ExpirationDate = now.AddYears(1);
|
||||
send.DeletionDate = now.AddYears(1);
|
||||
send.Disabled = false;
|
||||
send.Password = "HASH";
|
||||
|
||||
sutProvider.GetDependency<IPasswordHasher<User>>()
|
||||
.VerifyHashedPassword(Arg.Any<User>(), "TEST", "TEST")
|
||||
.Returns(PasswordVerificationResult.Success);
|
||||
|
||||
var (grant, passwordRequiredError, passwordInvalidError)
|
||||
= sutProvider.Sut.SendCanBeAccessed(send, null);
|
||||
|
||||
Assert.False(grant);
|
||||
Assert.True(passwordRequiredError);
|
||||
Assert.False(passwordInvalidError);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void SendCanBeAccessed_RehashNeeded_RehashesPassword(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
send.MaxAccessCount = null;
|
||||
send.AccessCount = 5;
|
||||
send.ExpirationDate = now.AddYears(1);
|
||||
send.DeletionDate = now.AddYears(1);
|
||||
send.Disabled = false;
|
||||
send.Password = "TEST";
|
||||
|
||||
sutProvider.GetDependency<IPasswordHasher<User>>()
|
||||
.VerifyHashedPassword(Arg.Any<User>(), "TEST", "TEST")
|
||||
.Returns(PasswordVerificationResult.SuccessRehashNeeded);
|
||||
|
||||
var (grant, passwordRequiredError, passwordInvalidError)
|
||||
= sutProvider.Sut.SendCanBeAccessed(send, "TEST");
|
||||
|
||||
sutProvider.GetDependency<IPasswordHasher<User>>()
|
||||
.Received(1)
|
||||
.HashPassword(Arg.Any<User>(), "TEST");
|
||||
|
||||
Assert.True(grant);
|
||||
Assert.False(passwordRequiredError);
|
||||
Assert.False(passwordInvalidError);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void SendCanBeAccessed_VerifyFailed_PasswordInvalidReturnsTrue(SutProvider<SendService> sutProvider,
|
||||
Send send)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
send.MaxAccessCount = null;
|
||||
send.AccessCount = 5;
|
||||
send.ExpirationDate = now.AddYears(1);
|
||||
send.DeletionDate = now.AddYears(1);
|
||||
send.Disabled = false;
|
||||
send.Password = "TEST";
|
||||
|
||||
sutProvider.GetDependency<IPasswordHasher<User>>()
|
||||
.VerifyHashedPassword(Arg.Any<User>(), "TEST", "TEST")
|
||||
.Returns(PasswordVerificationResult.Failed);
|
||||
|
||||
var (grant, passwordRequiredError, passwordInvalidError)
|
||||
= sutProvider.Sut.SendCanBeAccessed(send, "TEST");
|
||||
|
||||
Assert.False(grant);
|
||||
Assert.False(passwordRequiredError);
|
||||
Assert.True(passwordInvalidError);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user