diff --git a/BussinessLogick/ArticalBussinessLogick.cs b/BussinessLogick/ArticalBussinessLogick.cs new file mode 100644 index 0000000..42868b9 --- /dev/null +++ b/BussinessLogick/ArticalBussinessLogick.cs @@ -0,0 +1,107 @@ +using ClassLibrary1; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace BussinessLogick; + +internal class ArticalBussinessLogick(IArticleStorageContract articleStorageContract, ILogger logger) : IArticleBusinessLogicContract +{ + private readonly ILogger _logger = logger; + private readonly IArticleStorageContract _articleStorageContract = articleStorageContract; + + public List
GetAllArticles() + { + _logger.LogInformation("Get all articles"); + var articles = _articleStorageContract.GetList() ?? throw new NullListException(); + return articles; + } + + public Article GetArticleByData(string data) + { + _logger.LogInformation("Get article by data: {data}", data); + if (data.IsEmpty()) + throw new ArgumentException(nameof(data)); + + if (data.IsGuid()) + { + var article = _articleStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data); + return article; + } + else + { + var article = _articleStorageContract.GetElementByTitle(data) ?? throw new ElementNotFoundException(data); + return article; + } + } + + public void InsertArticle(Article article) + { + _logger.LogInformation("Insert article: {json}", JsonSerializer.Serialize(article)); + ArgumentNullException.ThrowIfNull(article); + article.Validate(); + + var existingById = _articleStorageContract.GetElementById(article.Id); + if (existingById != null) + throw new ElementNotFoundException($"Article with Id {article.Id} already exists"); + + var existingByTitle = _articleStorageContract.GetElementByTitle(article.Title); + if (existingByTitle != null) + throw new ElementNotFoundException($"Article with Title {article.Title} already exists"); + + try + { + _articleStorageContract.AddElement(article); + } + catch (Exception ex) + { + throw new ElementNotFoundException("Error adding article to storage"); + } + } + + public void UpdateArticle(Article article) + { + _logger.LogInformation("Update article: {json}", JsonSerializer.Serialize(article)); + ArgumentNullException.ThrowIfNull(article); + article.Validate(); + + var existing = _articleStorageContract.GetElementById(article.Id) ?? throw new ElementNotFoundException(article.Id); + + var existingByTitle = _articleStorageContract.GetElementByTitle(article.Title); + if (existingByTitle != null && existingByTitle.Id != article.Id) + throw new ElementNotFoundException($"Article with Title {article.Title} already exists"); + + try + { + _articleStorageContract.UpdElement(article); + } + catch (Exception ex) + { + throw new ElementNotFoundException("Error updating article in storage"); + } + } + + public void DeleteArticle(string id) + { + _logger.LogInformation("Delete article by id: {id}", id); + if (id.IsEmpty()) + throw new ArgumentException(nameof(id)); + if (!id.IsGuid()) + throw new ValidationException("Id is not a unique identifier"); + + var existing = _articleStorageContract.GetElementById(id) ?? throw new ElementNotFoundException(id); + + try + { + _articleStorageContract.DelElement(id); + } + catch (Exception ex) + { + throw new ElementNotFoundException("Error deleting article from storage"); + } + } +} \ No newline at end of file diff --git a/BussinessLogick/AuthorBusinessLogic.cs b/BussinessLogick/AuthorBusinessLogic.cs new file mode 100644 index 0000000..3e3ea6b --- /dev/null +++ b/BussinessLogick/AuthorBusinessLogic.cs @@ -0,0 +1,113 @@ +using ClassLibrary1; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace BussinessLogick; + +internal class AuthorBusinessLogic(IAuthorStorageContract authorStorageContract, ILogger logger) : IAuthorBusinessLogicContract +{ + private readonly ILogger _logger = logger; + private readonly IAuthorStorageContract _authorStorageContract = authorStorageContract; + + public List GetAllAuthors() + { + _logger.LogInformation("Get all authors"); + var authors = _authorStorageContract.GetList() ?? throw new NullListException(); + return authors; + } + + public Author GetAuthorByData(string data) + { + _logger.LogInformation("Get author by data: {data}", data); + if (data.IsEmpty()) + throw new ArgumentException(nameof(data)); + + if (data.IsGuid()) + { + var author = _authorStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data); + return author; + } + else if (Regex.IsMatch(data, @"^([a-zA-Z0-9._%-]+)@([a-zA-Z0-9.-]+)\.([a-zA-Z]{2,})$")) + { + var author = _authorStorageContract.GetElementByEmail(data) ?? throw new ElementNotFoundException(data); + return author; + } + else + { + var author = _authorStorageContract.GetElementByFIO(data) ?? throw new ElementNotFoundException(data); + return author; + } + } + + public void InsertAuthor(Author author) + { + _logger.LogInformation("Insert author: {json}", JsonSerializer.Serialize(author)); + ArgumentNullException.ThrowIfNull(author); + author.Validate(); + + var existingById = _authorStorageContract.GetElementById(author.Id); + if (existingById != null) + throw new ElementNotFoundException($"Author with Id {author.Id} already exists"); + + var existingByEmail = _authorStorageContract.GetElementByEmail(author.Email); + if (existingByEmail != null) + throw new ElementNotFoundException($"Author with Email {author.Email} already exists"); + + try + { + _authorStorageContract.AddElement(author); + } + catch (Exception ex) + { + throw new ElementNotFoundException("Error adding author to storage"); + } + } + + public void UpdateAuthor(Author author) + { + _logger.LogInformation("Update author: {json}", JsonSerializer.Serialize(author)); + ArgumentNullException.ThrowIfNull(author); + author.Validate(); + + var existing = _authorStorageContract.GetElementById(author.Id) ?? throw new ElementNotFoundException(author.Id); + + var existingByEmail = _authorStorageContract.GetElementByEmail(author.Email); + if (existingByEmail != null && existingByEmail.Id != author.Id) + throw new ElementNotFoundException($"Author with Email {author.Email} already exists"); + + try + { + _authorStorageContract.UpdElement(author); + } + catch (Exception ex) + { + throw new ElementNotFoundException("Error updating author in storage"); + } + } + + public void DeleteAuthor(string id) + { + _logger.LogInformation("Delete author by id: {id}", id); + if (id.IsEmpty()) + throw new ArgumentException(nameof(id)); + if (!id.IsGuid()) + throw new ValidationException("Id is not a unique identifier"); + + var existing = _authorStorageContract.GetElementById(id) ?? throw new ElementNotFoundException(id); + + try + { + _authorStorageContract.DelElement(id); + } + catch (Exception ex) + { + throw new ElementNotFoundException("Error deleting author from storage"); + } + } +} diff --git a/BussinessLogick/BussinessLogick.csproj b/BussinessLogick/BussinessLogick.csproj new file mode 100644 index 0000000..db194c1 --- /dev/null +++ b/BussinessLogick/BussinessLogick.csproj @@ -0,0 +1,22 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/ClassLibrary1.sln b/ClassLibrary1.sln index 54b8ecb..b5d50b9 100644 --- a/ClassLibrary1.sln +++ b/ClassLibrary1.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibra EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{8FC911A3-5BFF-4FFC-A8EE-B38E44B572FB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BussinessLogick", "BussinessLogick\BussinessLogick.csproj", "{D098214E-146D-4B68-9EF7-89F5DB610CB7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {8FC911A3-5BFF-4FFC-A8EE-B38E44B572FB}.Debug|Any CPU.Build.0 = Debug|Any CPU {8FC911A3-5BFF-4FFC-A8EE-B38E44B572FB}.Release|Any CPU.ActiveCfg = Release|Any CPU {8FC911A3-5BFF-4FFC-A8EE-B38E44B572FB}.Release|Any CPU.Build.0 = Release|Any CPU + {D098214E-146D-4B68-9EF7-89F5DB610CB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D098214E-146D-4B68-9EF7-89F5DB610CB7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D098214E-146D-4B68-9EF7-89F5DB610CB7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D098214E-146D-4B68-9EF7-89F5DB610CB7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ClassLibrary1/Article.cs b/ClassLibrary1/Article.cs index 197048e..12c9c08 100644 --- a/ClassLibrary1/Article.cs +++ b/ClassLibrary1/Article.cs @@ -20,12 +20,9 @@ namespace ClassLibrary1 throw new ValidationException("Id is Guid"); if (Title.IsEmpty()) throw new ValidationException("Field Id is empty"); - if (!Title.IsGuid()) - throw new ValidationException("Id is Guid"); if (Tema.IsEmpty()) throw new ValidationException("Field Id is empty"); - if (!Tema.IsGuid()) - throw new ValidationException("Id is Guid"); + } } } diff --git a/ClassLibrary1/Author.cs b/ClassLibrary1/Author.cs index af85817..e148be0 100644 --- a/ClassLibrary1/Author.cs +++ b/ClassLibrary1/Author.cs @@ -24,16 +24,12 @@ namespace ClassLibrary1 throw new ValidationException("The value in the field Id is not a unique identifier"); if (FIO.IsEmpty()) throw new ValidationException("Field FIO is empty"); - if (!FIO.IsGuid()) - throw new ValidationException("Field FIO is guid"); if (ArticleId.IsEmpty()) throw new ValidationException("Field ArticleId is empty"); if (!ArticleId.IsGuid()) throw new ValidationException("The value in the field ArticleId is not a unique identifier"); if (Work.IsEmpty()) throw new ValidationException("Field ArticleId is empty"); - if (!Work.IsGuid()) - throw new ValidationException("The value in the field ArticleId is not a unique identifier"); if (BirthDate.Date > DateTime.Now.AddYears(-16).Date) throw new ValidationException($"Minors cannot be hired (BirthDate = {BirthDate.ToShortDateString()})"); if (Email.IsEmpty()) diff --git a/ClassLibrary1/ElementNotFoundException.cs b/ClassLibrary1/ElementNotFoundException.cs new file mode 100644 index 0000000..4250b87 --- /dev/null +++ b/ClassLibrary1/ElementNotFoundException.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary1; + +public class ElementNotFoundException : Exception +{ + public string Value { get; private set; } + public ElementNotFoundException(string value) : base($"Element not found at value = {value}") + { + Value = value; + } +} diff --git a/ClassLibrary1/IArticleBusinessLogicContract.cs b/ClassLibrary1/IArticleBusinessLogicContract.cs new file mode 100644 index 0000000..f16695e --- /dev/null +++ b/ClassLibrary1/IArticleBusinessLogicContract.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary1; + +public interface IArticleBusinessLogicContract +{ + List
GetAllArticles(); + Article GetArticleByData(string data); + void InsertArticle(Article article); + void UpdateArticle(Article article); + void DeleteArticle(string id); +} diff --git a/ClassLibrary1/IArticleStorageContract.cs b/ClassLibrary1/IArticleStorageContract.cs new file mode 100644 index 0000000..465fe95 --- /dev/null +++ b/ClassLibrary1/IArticleStorageContract.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary1; + +public interface IArticleStorageContract +{ + List
GetList(); + Article? GetElementById(string id); + Article? GetElementByTitle(string title); + void AddElement(Article article); + void UpdElement(Article article); + void DelElement(string id); +} diff --git a/ClassLibrary1/IAuthorBusinessLogicContract.cs b/ClassLibrary1/IAuthorBusinessLogicContract.cs new file mode 100644 index 0000000..3b83a73 --- /dev/null +++ b/ClassLibrary1/IAuthorBusinessLogicContract.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary1; + +public interface IAuthorBusinessLogicContract +{ + List GetAllAuthors(); + Author GetAuthorByData(string data); + void InsertAuthor(Author author); + void UpdateAuthor(Author author); + void DeleteAuthor(string id); +} diff --git a/ClassLibrary1/IAuthorStorageContract.cs b/ClassLibrary1/IAuthorStorageContract.cs new file mode 100644 index 0000000..555c6e6 --- /dev/null +++ b/ClassLibrary1/IAuthorStorageContract.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary1; + +public interface IAuthorStorageContract +{ + List GetList(); + Author? GetElementById(string id); + Author? GetElementByFIO(string fio); + Author? GetElementByEmail(string email); + void AddElement(Author author); + void UpdElement(Author author); + void DelElement(string id); +} diff --git a/ClassLibrary1/NullListException.cs b/ClassLibrary1/NullListException.cs new file mode 100644 index 0000000..35858e8 --- /dev/null +++ b/ClassLibrary1/NullListException.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary1; + +public class NullListException : Exception +{ + public NullListException() : base("The returned list is null") { } +} diff --git a/Test/ArticleTests.cs b/Test/ArticleTests.cs index 80337f2..7a8cebe 100644 --- a/Test/ArticleTests.cs +++ b/Test/ArticleTests.cs @@ -38,12 +38,7 @@ internal class ArticleTests Assert.That(() => article.Validate(), Throws.TypeOf()); } - [Test] - public void TitleIsNotGuidTest() - { - var article = CreateArticle(Guid.NewGuid().ToString(), "not-a-guid", Guid.NewGuid().ToString(), DateTime.UtcNow.AddDays(-1)); - Assert.That(() => article.Validate(), Throws.TypeOf()); - } + [Test] public void TemaIsNullOrEmptyTest() @@ -55,12 +50,7 @@ internal class ArticleTests Assert.That(() => article.Validate(), Throws.TypeOf()); } - [Test] - public void TemaIsNotGuidTest() - { - var article = CreateArticle(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "not-a-guid", DateTime.UtcNow.AddDays(-1)); - Assert.That(() => article.Validate(), Throws.TypeOf()); - } + @@ -68,8 +58,8 @@ internal class ArticleTests public void AllFieldsAreCorrectTest() { var id = Guid.NewGuid().ToString(); - var title = Guid.NewGuid().ToString(); // Title должен быть GUID согласно текущей валидации - var tema = Guid.NewGuid().ToString(); // Tema должен быть GUID согласно текущей валидации + var title = Guid.NewGuid().ToString(); + var tema = Guid.NewGuid().ToString(); var dateCreat = DateTime.UtcNow.AddDays(-1); var article = CreateArticle(id, title, tema, dateCreat); diff --git a/Test/AuthorBussinessTest.cs b/Test/AuthorBussinessTest.cs new file mode 100644 index 0000000..ba15dba --- /dev/null +++ b/Test/AuthorBussinessTest.cs @@ -0,0 +1,355 @@ +using ClassLibrary1; +using Moq; +using BussinessLogick; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Test; +[TestFixture] +internal class AuthorBussinessTest +{ + private AuthorBusinessLogic _authorBusinessLogic; + private Mock _authorStorageContract; + private Mock _loggerMock; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + _authorStorageContract = new Mock(); + _loggerMock = new Mock(); + _authorBusinessLogic = new AuthorBusinessLogic(_authorStorageContract.Object, _loggerMock.Object); + } + + [SetUp] + public void SetUp() + { + _authorStorageContract.Reset(); + } + + // Тесты для GetAllAuthors + [Test] + public void GetAllAuthors_ReturnListOfRecords_Test() + { + // Arrange + var authorsList = new List + { + new Author(Guid.NewGuid().ToString(), "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()), + new Author(Guid.NewGuid().ToString(), "Author 2", "author2@example.com", DateTime.Now.AddYears(-25), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()) + }; + _authorStorageContract.Setup(x => x.GetList()).Returns(authorsList); + + // Act + var result = _authorBusinessLogic.GetAllAuthors(); + + // Assert + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.EquivalentTo(authorsList)); + _authorStorageContract.Verify(x => x.GetList(), Times.Once()); + } + + [Test] + public void GetAllAuthors_ReturnEmptyList_Test() + { + // Arrange + _authorStorageContract.Setup(x => x.GetList()).Returns(new List()); + + // Act + var result = _authorBusinessLogic.GetAllAuthors(); + + // Assert + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.Empty); + _authorStorageContract.Verify(x => x.GetList(), Times.Once()); + } + + [Test] + public void GetAllAuthors_ReturnNull_ThrowException_Test() + { + // Arrange + _authorStorageContract.Setup(x => x.GetList()).Returns((List)null); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.GetAllAuthors()); + _authorStorageContract.Verify(x => x.GetList(), Times.Once()); + } + + + + // Тесты для GetAuthorByData + [Test] + public void GetAuthorByData_GetById_ReturnRecord_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var author = new Author(id, "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementById(id)).Returns(author); + + // Act + var result = _authorBusinessLogic.GetAuthorByData(id); + + // Assert + Assert.That(result, Is.Not.Null); + Assert.That(result.Id, Is.EqualTo(id)); + _authorStorageContract.Verify(x => x.GetElementById(id), Times.Once()); + } + + [Test] + public void GetAuthorByData_GetByEmail_ReturnRecord_Test() + { + // Arrange + var email = "author1@example.com"; + var author = new Author(Guid.NewGuid().ToString(), "Author 1", email, DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementByEmail(email)).Returns(author); + + // Act + var result = _authorBusinessLogic.GetAuthorByData(email); + + // Assert + Assert.That(result, Is.Not.Null); + Assert.That(result.Email, Is.EqualTo(email)); + _authorStorageContract.Verify(x => x.GetElementByEmail(email), Times.Once()); + } + + [Test] + public void GetAuthorByData_GetByFIO_ReturnRecord_Test() + { + // Arrange + var fio = "Author 1"; + var author = new Author(Guid.NewGuid().ToString(), fio, "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementByFIO(fio)).Returns(author); + + // Act + var result = _authorBusinessLogic.GetAuthorByData(fio); + + // Assert + Assert.That(result, Is.Not.Null); + Assert.That(result.FIO, Is.EqualTo(fio)); + _authorStorageContract.Verify(x => x.GetElementByFIO(fio), Times.Once()); + } + + [Test] + public void GetAuthorByData_EmptyData_ThrowException_Test() + { + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.GetAuthorByData(null)); + Assert.Throws(() => _authorBusinessLogic.GetAuthorByData(string.Empty)); + _authorStorageContract.Verify(x => x.GetElementById(It.IsAny()), Times.Never()); + _authorStorageContract.Verify(x => x.GetElementByEmail(It.IsAny()), Times.Never()); + _authorStorageContract.Verify(x => x.GetElementByFIO(It.IsAny()), Times.Never()); + } + + [Test] + public void GetAuthorByData_GetById_NotFound_ThrowException_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + _authorStorageContract.Setup(x => x.GetElementById(id)).Returns((Author)null); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.GetAuthorByData(id)); + _authorStorageContract.Verify(x => x.GetElementById(id), Times.Once()); + } + + [Test] + public void GetAuthorByData_GetByEmail_NotFound_ThrowException_Test() + { + // Arrange + var email = "author1@example.com"; + _authorStorageContract.Setup(x => x.GetElementByEmail(email)).Returns((Author)null); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.GetAuthorByData(email)); + _authorStorageContract.Verify(x => x.GetElementByEmail(email), Times.Once()); + } + + [Test] + public void GetAuthorByData_GetByFIO_NotFound_ThrowException_Test() + { + // Arrange + var fio = "Author 1"; + _authorStorageContract.Setup(x => x.GetElementByFIO(fio)).Returns((Author)null); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.GetAuthorByData(fio)); + _authorStorageContract.Verify(x => x.GetElementByFIO(fio), Times.Once()); + } + + // Тесты для InsertAuthor + [Test] + public void InsertAuthor_ValidAuthor_Success_Test() + { + // Arrange + var author = new Author(Guid.NewGuid().ToString(), "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementById(author.Id)).Returns((Author)null); + _authorStorageContract.Setup(x => x.GetElementByEmail(author.Email)).Returns((Author)null); + + // Act + _authorBusinessLogic.InsertAuthor(author); + + // Assert + _authorStorageContract.Verify(x => x.AddElement(author), Times.Once()); + } + + [Test] + public void InsertAuthor_DuplicateId_ThrowException_Test() + { + // Arrange + var author = new Author(Guid.NewGuid().ToString(), "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementById(author.Id)).Returns(author); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.InsertAuthor(author)); + _authorStorageContract.Verify(x => x.AddElement(It.IsAny()), Times.Never()); + } + + [Test] + public void InsertAuthor_DuplicateEmail_ThrowException_Test() + { + // Arrange + var author = new Author(Guid.NewGuid().ToString(), "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementById(author.Id)).Returns((Author)null); + _authorStorageContract.Setup(x => x.GetElementByEmail(author.Email)).Returns(author); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.InsertAuthor(author)); + _authorStorageContract.Verify(x => x.AddElement(It.IsAny()), Times.Never()); + } + + [Test] + public void InsertAuthor_NullAuthor_ThrowException_Test() + { + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.InsertAuthor(null)); + _authorStorageContract.Verify(x => x.AddElement(It.IsAny()), Times.Never()); + } + + [Test] + public void InsertAuthor_InvalidAuthor_ThrowException_Test() + { + // Arrange + var author = new Author("", "Author 1", "invalid_email", DateTime.Now.AddYears(-10), "", ""); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.InsertAuthor(author)); + _authorStorageContract.Verify(x => x.AddElement(It.IsAny()), Times.Never()); + } + + + + // Тесты для UpdateAuthor + [Test] + public void UpdateAuthor_ValidAuthor_Success_Test() + { + // Arrange + var author = new Author(Guid.NewGuid().ToString(), "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementById(author.Id)).Returns(author); + _authorStorageContract.Setup(x => x.GetElementByEmail(author.Email)).Returns((Author)null); + + // Act + _authorBusinessLogic.UpdateAuthor(author); + + // Assert + _authorStorageContract.Verify(x => x.UpdElement(author), Times.Once()); + } + + [Test] + public void UpdateAuthor_NonExistingAuthor_ThrowException_Test() + { + // Arrange + var author = new Author(Guid.NewGuid().ToString(), "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementById(author.Id)).Returns((Author)null); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.UpdateAuthor(author)); + _authorStorageContract.Verify(x => x.UpdElement(It.IsAny()), Times.Never()); + } + + [Test] + public void UpdateAuthor_DuplicateEmail_ThrowException_Test() + { + // Arrange + var author = new Author(Guid.NewGuid().ToString(), "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + var existingAuthor = new Author(Guid.NewGuid().ToString(), "Author 2", "author1@example.com", DateTime.Now.AddYears(-25), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementById(author.Id)).Returns(author); + _authorStorageContract.Setup(x => x.GetElementByEmail(author.Email)).Returns(existingAuthor); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.UpdateAuthor(author)); + _authorStorageContract.Verify(x => x.UpdElement(It.IsAny()), Times.Never()); + } + + [Test] + public void UpdateAuthor_NullAuthor_ThrowException_Test() + { + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.UpdateAuthor(null)); + _authorStorageContract.Verify(x => x.UpdElement(It.IsAny()), Times.Never()); + } + + [Test] + public void UpdateAuthor_InvalidAuthor_ThrowException_Test() + { + // Arrange + var author = new Author("", "Author 1", "invalid_email", DateTime.Now.AddYears(-10), "", ""); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.UpdateAuthor(author)); + _authorStorageContract.Verify(x => x.UpdElement(It.IsAny()), Times.Never()); + } + + + + // Тесты для DeleteAuthor + [Test] + public void DeleteAuthor_ValidId_Success_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var author = new Author(id, "Author 1", "author1@example.com", DateTime.Now.AddYears(-30), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); + _authorStorageContract.Setup(x => x.GetElementById(id)).Returns(author); + + // Act + _authorBusinessLogic.DeleteAuthor(id); + + // Assert + _authorStorageContract.Verify(x => x.DelElement(id), Times.Once()); + } + + [Test] + public void DeleteAuthor_NonExistingId_ThrowException_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + _authorStorageContract.Setup(x => x.GetElementById(id)).Returns((Author)null); + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.DeleteAuthor(id)); + _authorStorageContract.Verify(x => x.DelElement(It.IsAny()), Times.Never()); + } + + [Test] + public void DeleteAuthor_EmptyId_ThrowException_Test() + { + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.DeleteAuthor(null)); + Assert.Throws(() => _authorBusinessLogic.DeleteAuthor(string.Empty)); + _authorStorageContract.Verify(x => x.DelElement(It.IsAny()), Times.Never()); + } + + [Test] + public void DeleteAuthor_InvalidId_ThrowException_Test() + { + // Arrange + var invalidId = "not-a-guid"; + + // Act & Assert + Assert.Throws(() => _authorBusinessLogic.DeleteAuthor(invalidId)); + _authorStorageContract.Verify(x => x.DelElement(It.IsAny()), Times.Never()); + } + + +} diff --git a/Test/AuthorTests.cs b/Test/AuthorTests.cs index 41dfdf2..83d49f5 100644 --- a/Test/AuthorTests.cs +++ b/Test/AuthorTests.cs @@ -37,12 +37,7 @@ internal class AuthorTests Assert.That(() => author.Validate(), Throws.TypeOf()); } - [Test] - public void FIOIsNotGuidTest() - { - var author = CreateAuthor(Guid.NewGuid().ToString(), "not-a-guid", "test@example.com", DateTime.UtcNow.AddYears(-20), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); - Assert.That(() => author.Validate(), Throws.TypeOf()); - } + [Test] public void ArticleIdIsNullOrEmptyTest() @@ -71,12 +66,7 @@ internal class AuthorTests Assert.That(() => author.Validate(), Throws.TypeOf()); } - [Test] - public void WorkIsNotGuidTest() - { - var author = CreateAuthor(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", DateTime.UtcNow.AddYears(-20), "not-a-guid", Guid.NewGuid().ToString()); - Assert.That(() => author.Validate(), Throws.TypeOf()); - } + [Test] public void EmailIsNullOrEmptyTest() diff --git a/Test/Test.csproj b/Test/Test.csproj index e1c8bbe..3754224 100644 --- a/Test/Test.csproj +++ b/Test/Test.csproj @@ -11,6 +11,7 @@ + @@ -18,6 +19,7 @@ +