diff --git a/test/Core.Test/Models/Business/TaxInfoTests.cs b/test/Core.Test/Models/Business/TaxInfoTests.cs new file mode 100644 index 0000000000..0dc1c0a38e --- /dev/null +++ b/test/Core.Test/Models/Business/TaxInfoTests.cs @@ -0,0 +1,80 @@ +using Bit.Core.Models.Business; +using Xunit; + +namespace Bit.Core.Test.Models.Business +{ + public class TaxInfoTests + { + // PH = Placeholder + [Theory] + [InlineData(null, null, null, null)] + [InlineData("", "", null, null)] + [InlineData("PH", "", null, null)] + [InlineData("", "PH", null, null)] + [InlineData("AE", "PH", null, "ae_trn")] + [InlineData("AU", "PH", null, "au_abn")] + [InlineData("BR", "PH", null, "br_cnpj")] + // [InlineData("CA", "PH", "bec", "ca_qst")] // This test will fail, I believe this is a bug + [InlineData("CA", "PH", null, "ca_bn")] + [InlineData("CL", "PH", null, "cl_tin")] + [InlineData("AT", "PH", null, "eu_vat")] + [InlineData("BE", "PH", null, "eu_vat")] + [InlineData("BG", "PH", null, "eu_vat")] + [InlineData("CY", "PH", null, "eu_vat")] + [InlineData("CZ", "PH", null, "eu_vat")] + [InlineData("DE", "PH", null, "eu_vat")] + [InlineData("DK", "PH", null, "eu_vat")] + [InlineData("EE", "PH", null, "eu_vat")] + [InlineData("ES", "PH", null, "eu_vat")] + [InlineData("FI", "PH", null, "eu_vat")] + [InlineData("FR", "PH", null, "eu_vat")] + [InlineData("GB", "PH", null, "eu_vat")] + [InlineData("GR", "PH", null, "eu_vat")] + [InlineData("HR", "PH", null, "eu_vat")] + [InlineData("HU", "PH", null, "eu_vat")] + [InlineData("IE", "PH", null, "eu_vat")] + [InlineData("IT", "PH", null, "eu_vat")] + [InlineData("LT", "PH", null, "eu_vat")] + [InlineData("LU", "PH", null, "eu_vat")] + [InlineData("LV", "PH", null, "eu_vat")] + [InlineData("MT", "PH", null, "eu_vat")] + [InlineData("NL", "PH", null, "eu_vat")] + [InlineData("PL", "PH", null, "eu_vat")] + [InlineData("PT", "PH", null, "eu_vat")] + [InlineData("RO", "PH", null, "eu_vat")] + [InlineData("SE", "PH", null, "eu_vat")] + [InlineData("SI", "PH", null, "eu_vat")] + [InlineData("SK", "PH", null, "eu_vat")] + [InlineData("HK", "PH", null, "hk_br")] + [InlineData("IN", "PH", null, "in_gst")] + [InlineData("JP", "PH", null, "jp_cn")] + [InlineData("KR", "PH", null, "kr_brn")] + [InlineData("LI", "PH", null, "li_uid")] + [InlineData("MX", "PH", null, "mx_rfc")] + [InlineData("MY", "PH", null, "my_sst")] + [InlineData("NO", "PH", null, "no_vat")] + [InlineData("NZ", "PH", null, "nz_gst")] + [InlineData("RU", "PH", null, "ru_inn")] + [InlineData("SA", "PH", null, "sa_vat")] + [InlineData("SG", "PH", null, "sg_gst")] + [InlineData("TH", "PH", null, "th_vat")] + [InlineData("TW", "PH", null, "tw_vat")] + [InlineData("US", "PH", null, "us_ein")] + [InlineData("ZA", "PH", null, "za_vat")] + [InlineData("ABCDEF", "PH", null, null)] + public void GetTaxIdType_Success(string billingAddressCountry, + string taxIdNumber, + string billingAddressState, + string expectedTaxIdType) + { + var taxInfo = new TaxInfo + { + BillingAddressCountry = billingAddressCountry, + TaxIdNumber = taxIdNumber, + BillingAddressState = billingAddressState, + }; + + Assert.Equal(expectedTaxIdType, taxInfo.TaxIdType); + } + } +} diff --git a/test/Core.Test/Models/Tables/UserTests.cs b/test/Core.Test/Models/Tables/UserTests.cs new file mode 100644 index 0000000000..05a34c00f4 --- /dev/null +++ b/test/Core.Test/Models/Tables/UserTests.cs @@ -0,0 +1,43 @@ +using Bit.Core.Models.Table; +using Xunit; + +namespace Bit.Core.Test.Models.Tables +{ + public class UserTests + { + // KB MB GB + public const long Multiplier = 1024 * 1024 * 1024; + + [Fact] + public void StorageBytesRemaining_HasMax_DoesNotHaveStorage_ReturnsMaxAsBytes() + { + short maxStorageGb = 1; + + var user = new User + { + MaxStorageGb = maxStorageGb, + Storage = null, + }; + + var bytesRemaining = user.StorageBytesRemaining(); + + Assert.Equal(bytesRemaining, maxStorageGb * Multiplier); + } + + [Theory] + [InlineData(2, 1 * Multiplier, 1 * Multiplier)] + + public void StorageBytesRemaining_HasMax_HasStorage_ReturnRemainingStorage(short maxStorageGb, long storageBytes, long expectedRemainingBytes) + { + var user = new User + { + MaxStorageGb = maxStorageGb, + Storage = storageBytes, + }; + + var bytesRemaining = user.StorageBytesRemaining(); + + Assert.Equal(expectedRemainingBytes, bytesRemaining); + } + } +} diff --git a/test/Core.Test/Services/SendServiceTests.cs b/test/Core.Test/Services/SendServiceTests.cs index 28fb68b0e5..6a1b65e9ff 100644 --- a/test/Core.Test/Services/SendServiceTests.cs +++ b/test/Core.Test/Services/SendServiceTests.cs @@ -102,5 +102,664 @@ namespace Bit.Core.Test.Services await sutProvider.GetDependency().Received(1).CreateAsync(send); } + + [Theory] + [InlineUserSendAutoData] + [InlineUserSendAutoData] + public async void SaveSendAsync_ExistingSend_Updates(SutProvider 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() + .Received(1) + .UpsertAsync(send); + + await sutProvider.GetDependency() + .Received(1) + .PushSyncSendUpdateAsync(send); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_TextType_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + send.Type = SendType.Text; + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 0) + ); + + Assert.Contains("not of type \"file\"", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_EmptyFile_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + send.Type = SendType.File; + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 0) + ); + + Assert.Contains("no file data", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_UserCannotAccessPremium_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + var user = new User + { + Id = Guid.NewGuid(), + }; + + send.UserId = user.Id; + send.Type = SendType.File; + + sutProvider.GetDependency() + .GetByIdAsync(user.Id) + .Returns(user); + + sutProvider.GetDependency() + .CanAccessPremium(user) + .Returns(false); + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 1) + ); + + Assert.Contains("must have premium", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_UserHasUnconfirmedEmail_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + var user = new User + { + Id = Guid.NewGuid(), + EmailVerified = false, + }; + + send.UserId = user.Id; + send.Type = SendType.File; + + sutProvider.GetDependency() + .GetByIdAsync(user.Id) + .Returns(user); + + sutProvider.GetDependency() + .CanAccessPremium(user) + .Returns(true); + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 1) + ); + + Assert.Contains("must confirm your email", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_UserCanAccessPremium_HasNoStorage_ThrowsBadRequest(SutProvider 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() + .GetByIdAsync(user.Id) + .Returns(user); + + sutProvider.GetDependency() + .CanAccessPremium(user) + .Returns(true); + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 1) + ); + + Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_UserCanAccessPremium_StorageFull_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + var user = new User + { + Id = Guid.NewGuid(), + EmailVerified = true, + Premium = true, + MaxStorageGb = 2, + Storage = 2 * Models.Tables.UserTests.Multiplier, + }; + + send.UserId = user.Id; + send.Type = SendType.File; + + sutProvider.GetDependency() + .GetByIdAsync(user.Id) + .Returns(user); + + sutProvider.GetDependency() + .CanAccessPremium(user) + .Returns(true); + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 1) + ); + + Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_UserCanAccessPremium_IsNotPremium_IsSelfHosted_GiantFile_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + var user = new User + { + Id = Guid.NewGuid(), + EmailVerified = true, + Premium = false, + }; + + send.UserId = user.Id; + send.Type = SendType.File; + + sutProvider.GetDependency() + .GetByIdAsync(user.Id) + .Returns(user); + + sutProvider.GetDependency() + .CanAccessPremium(user) + .Returns(true); + + sutProvider.GetDependency() + .SelfHosted = true; + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 11000 * Models.Tables.UserTests.Multiplier) + ); + + Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_UserCanAccessPremium_IsNotPremium_IsNotSelfHosted_TwoGigabyteFile_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + var user = new User + { + Id = Guid.NewGuid(), + EmailVerified = true, + Premium = false, + }; + + send.UserId = user.Id; + send.Type = SendType.File; + + sutProvider.GetDependency() + .GetByIdAsync(user.Id) + .Returns(user); + + sutProvider.GetDependency() + .CanAccessPremium(user) + .Returns(true); + + sutProvider.GetDependency() + .SelfHosted = false; + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 2 * Models.Tables.UserTests.Multiplier) + ); + + Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_ThroughOrg_MaxStorageIsNull_ThrowsBadRequest(SutProvider 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() + .GetByIdAsync(org.Id) + .Returns(org); + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 1) + ); + + Assert.Contains("organization cannot use file sends", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_ThroughOrg_MaxStorageIsNull_TwoGBFile_ThrowsBadRequest(SutProvider 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() + .GetByIdAsync(org.Id) + .Returns(org); + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 1) + ); + + Assert.Contains("organization cannot use file sends", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_ThroughOrg_MaxStorageIsOneGB_TwoGBFile_ThrowsBadRequest(SutProvider 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() + .GetByIdAsync(org.Id) + .Returns(org); + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, null, 2 * Models.Tables.UserTests.Multiplier) + ); + + Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_HasEnouphStorage_Success(SutProvider 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() + .GetByIdAsync(user.Id) + .Returns(user); + + sutProvider.GetDependency() + .CanAccessPremium(user) + .Returns(true); + + sutProvider.GetDependency() + .GetSendFileUploadUrlAsync(send, Arg.Any()) + .Returns(testUrl); + + var utcNow = DateTime.UtcNow; + + var url = await sutProvider.Sut.SaveFileSendAsync(send, data, 1 * Models.Tables.UserTests.Multiplier); + + Assert.Equal(testUrl, url); + Assert.True(send.RevisionDate - utcNow < TimeSpan.FromSeconds(1)); + + await sutProvider.GetDependency() + .Received(1) + .GetSendFileUploadUrlAsync(send, Arg.Any()); + + await sutProvider.GetDependency() + .Received(1) + .UpsertAsync(send); + + await sutProvider.GetDependency() + .Received(1) + .PushSyncSendUpdateAsync(send); + } + + [Theory] + [InlineUserSendAutoData] + public async void SaveFileSendAsync_HasEnouphStorage_SendFileThrows_CleansUp(SutProvider 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() + .GetByIdAsync(user.Id) + .Returns(user); + + sutProvider.GetDependency() + .CanAccessPremium(user) + .Returns(true); + + sutProvider.GetDependency() + .GetSendFileUploadUrlAsync(send, Arg.Any()) + .Returns(callInfo => throw new Exception("Problem")); + + var utcNow = DateTime.UtcNow; + + var exception = await Assert.ThrowsAsync(() => + sutProvider.Sut.SaveFileSendAsync(send, data, 1 * Models.Tables.UserTests.Multiplier) + ); + + Assert.True(send.RevisionDate - utcNow < TimeSpan.FromSeconds(1)); + Assert.Equal("Problem", exception.Message); + + await sutProvider.GetDependency() + .Received(1) + .GetSendFileUploadUrlAsync(send, Arg.Any()); + + await sutProvider.GetDependency() + .Received(1) + .UpsertAsync(send); + + await sutProvider.GetDependency() + .Received(1) + .PushSyncSendUpdateAsync(send); + + await sutProvider.GetDependency() + .Received(1) + .DeleteFileAsync(send, Arg.Any()); + } + + [Theory] + [InlineUserSendAutoData] + public async void UpdateFileToExistingSendAsync_SendNull_ThrowsBadRequest(SutProvider sutProvider) + { + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(), null) + ); + + Assert.Contains("does not have file data", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void UpdateFileToExistingSendAsync_SendDataNull_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + send.Data = null; + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(), send) + ); + + Assert.Contains("does not have file data", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void UpdateFileToExistingSendAsync_NotFileType_ThrowsBadRequest(SutProvider sutProvider, + Send send) + { + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(), send) + ); + + Assert.Contains("not a file type send", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public async void UpdateFileToExistingSendAsync_Success(SutProvider sutProvider, + Send send) + { + var fileContents = "Test file content"; + + var sendFileData = new SendFileData + { + Id = "TEST", + Size = fileContents.Length, + }; + + send.Type = SendType.File; + send.Data = JsonConvert.SerializeObject(sendFileData); + + sutProvider.GetDependency() + .ValidateFileAsync(send, sendFileData.Id, sendFileData.Size, Arg.Any()) + .Returns((true, sendFileData.Size)); + + await sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(Encoding.UTF8.GetBytes(fileContents)), send); + } + + [Theory] + [InlineUserSendAutoData] + public async void UpdateFileToExistingSendAsync_InvalidSize(SutProvider sutProvider, + Send send) + { + var fileContents = "Test file content"; + + var sendFileData = new SendFileData + { + Id = "TEST", + Size = fileContents.Length, + }; + + send.Type = SendType.File; + send.Data = JsonConvert.SerializeObject(sendFileData); + + sutProvider.GetDependency() + .ValidateFileAsync(send, sendFileData.Id, sendFileData.Size, Arg.Any()) + .Returns((false, sendFileData.Size)); + + var badRequest = await Assert.ThrowsAsync(() => + sutProvider.Sut.UploadFileToExistingSendAsync(new MemoryStream(Encoding.UTF8.GetBytes(fileContents)), send) + ); + + Assert.Contains("does not match", badRequest.Message, StringComparison.InvariantCultureIgnoreCase); + } + + [Theory] + [InlineUserSendAutoData] + public void SendCanBeAccessed_Success(SutProvider 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>() + .VerifyHashedPassword(Arg.Any(), 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] + [InlineUserSendAutoData] + public void SendCanBeAccessed_NullMaxAccess_Success(SutProvider 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>() + .VerifyHashedPassword(Arg.Any(), 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] + [InlineUserSendAutoData] + public void SendCanBeAccessed_NullSend_DoesNotGrantAccess(SutProvider sutProvider) + { + sutProvider.GetDependency>() + .VerifyHashedPassword(Arg.Any(), "TEST", "TEST") + .Returns(PasswordVerificationResult.Success); + + var (grant, passwordRequiredError, passwordInvalidError) + = sutProvider.Sut.SendCanBeAccessed(null, "TEST"); + + Assert.False(grant); + Assert.False(passwordRequiredError); + Assert.False(passwordInvalidError); + } + + [Theory] + [InlineUserSendAutoData] + public void SendCanBeAccessed_NullPassword_PasswordRequiredErrorReturnsTrue(SutProvider 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>() + .VerifyHashedPassword(Arg.Any(), "TEST", "TEST") + .Returns(PasswordVerificationResult.Success); + + var (grant, passwordRequiredError, passwordInvalidError) + = sutProvider.Sut.SendCanBeAccessed(send, null); + + Assert.False(grant); + Assert.True(passwordRequiredError); + Assert.False(passwordInvalidError); + } + + [Theory] + [InlineUserSendAutoData] + public void SendCanBeAccessed_RehashNeeded_RehashesPassword(SutProvider 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>() + .VerifyHashedPassword(Arg.Any(), "TEST", "TEST") + .Returns(PasswordVerificationResult.SuccessRehashNeeded); + + var (grant, passwordRequiredError, passwordInvalidError) + = sutProvider.Sut.SendCanBeAccessed(send, "TEST"); + + sutProvider.GetDependency>() + .Received(1) + .HashPassword(Arg.Any(), "TEST"); + + Assert.True(grant); + Assert.False(passwordRequiredError); + Assert.False(passwordInvalidError); + } + + [Theory] + [InlineUserSendAutoData] + public void SendCanBeAccessed_VerifyFailed_PasswordInvalidReturnsTrue(SutProvider 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>() + .VerifyHashedPassword(Arg.Any(), "TEST", "TEST") + .Returns(PasswordVerificationResult.Failed); + + var (grant, passwordRequiredError, passwordInvalidError) + = sutProvider.Sut.SendCanBeAccessed(send, "TEST"); + + Assert.False(grant); + Assert.False(passwordRequiredError); + Assert.True(passwordInvalidError); + } } } diff --git a/test/Icons.Test/Services/IconFetchingServiceTests.cs b/test/Icons.Test/Services/IconFetchingServiceTests.cs new file mode 100644 index 0000000000..c1a6b702ef --- /dev/null +++ b/test/Icons.Test/Services/IconFetchingServiceTests.cs @@ -0,0 +1,53 @@ +using System.Threading.Tasks; +using Bit.Icons.Services; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Xunit; + +namespace Bit.Icons.Test.Services +{ + public class IconFetchingServiceTests + { + [Theory] + [InlineData("www.google.com")] // https site + [InlineData("neverssl.com")] // http site + [InlineData("ameritrade.com")] + [InlineData("icloud.com")] + [InlineData("bofa.com")] + public async Task GetIconAsync_Success(string domain) + { + var sut = new IconFetchingService(GetLogger()); + var result = await sut.GetIconAsync(domain); + + Assert.NotNull(result); + Assert.NotNull(result.Icon); + } + + [Theory] + [InlineData("1.1.1.1")] + [InlineData("")] + [InlineData("localhost")] + public async Task GetIconAsync_ReturnsNull(string domain) + { + var sut = new IconFetchingService(GetLogger()); + var result = await sut.GetIconAsync(domain); + + Assert.Null(result); + } + + private static ILogger GetLogger() + { + var services = new ServiceCollection(); + services.AddLogging(b => + { + b.ClearProviders(); + b.AddDebug(); + }); + + var provider = services.BuildServiceProvider(); + + return provider.GetRequiredService>(); + } + } +}