Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions SampleWebApp.Api.Tests/Fixtures/AutoMapperFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using AutoMapper;
using SampleWebApp.Core.Mapping;

namespace SampleWebApp.Api.Tests.Fixtures
{
public class AutoMapperFixture
{
public IMapper Mapper { get; }

public AutoMapperFixture()
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
});

Mapper = config.CreateMapper();
}
}
}
109 changes: 109 additions & 0 deletions SampleWebApp.Api.Tests/Fixtures/TestDbContextFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using Microsoft.EntityFrameworkCore;
using SampleWebApp.Api.Data;
using SampleWebApp.Core.Entities;

namespace SampleWebApp.Api.Tests.Fixtures
{
public class TestDbContextFixture : IDisposable
{
public SampleWebAppDbContext Context { get; private set; }

public TestDbContextFixture()
{
var options = new DbContextOptionsBuilder<SampleWebAppDbContext>()
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;

Context = new SampleWebAppDbContext(options);
SeedData();
}

private void SeedData()
{
var blog1 = new Blog
{
BlogId = 1,
Name = "Tech Blog",
EmailAddress = "tech@example.com"
};

var blog2 = new Blog
{
BlogId = 2,
Name = "Science Blog",
EmailAddress = "science@example.com"
};

var tag1 = new Tag
{
TagId = 1,
Name = "Programming",
Slug = "programming"
};

var tag2 = new Tag
{
TagId = 2,
Name = "Web Development",
Slug = "web-development"
};

var tag3 = new Tag
{
TagId = 3,
Name = "Science",
Slug = "science"
};

var post1 = new Post
{
PostId = 1,
Title = "Introduction to C#",
Content = "This is a post about C# programming.",
BlogId = 1,
Blogger = blog1,
LastUpdated = DateTime.UtcNow.AddDays(-1),
Tags = new List<Tag> { tag1, tag2 }
};

var post2 = new Post
{
PostId = 2,
Title = "ASP.NET Core Basics",
Content = "Learn the basics of ASP.NET Core.",
BlogId = 1,
Blogger = blog1,
LastUpdated = DateTime.UtcNow,
Tags = new List<Tag> { tag1, tag2 }
};

var post3 = new Post
{
PostId = 3,
Title = "Physics Fundamentals",
Content = "Understanding the basics of physics.",
BlogId = 2,
Blogger = blog2,
LastUpdated = DateTime.UtcNow.AddDays(-2),
Tags = new List<Tag> { tag3 }
};

blog1.Posts = new List<Post> { post1, post2 };
blog2.Posts = new List<Post> { post3 };

tag1.Posts = new List<Post> { post1, post2 };
tag2.Posts = new List<Post> { post1, post2 };
tag3.Posts = new List<Post> { post3 };

Context.Blogs.AddRange(blog1, blog2);
Context.Tags.AddRange(tag1, tag2, tag3);
Context.Posts.AddRange(post1, post2, post3);
Context.SaveChanges();
}

public void Dispose()
{
Context.Dispose();
}
}
}
73 changes: 73 additions & 0 deletions SampleWebApp.Api.Tests/Handlers/Blogs/GetBlogByIdHandlerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using FluentAssertions;
using SampleWebApp.Api.Tests.Fixtures;
using SampleWebApp.Core.Handlers.Blogs.Queries;
using Xunit;

namespace SampleWebApp.Api.Tests.Handlers.Blogs
{
public class GetBlogByIdHandlerTests : IDisposable
{
private readonly TestDbContextFixture _dbFixture;
private readonly AutoMapperFixture _mapperFixture;
private readonly GetBlogByIdHandler _handler;

public GetBlogByIdHandlerTests()
{
_dbFixture = new TestDbContextFixture();
_mapperFixture = new AutoMapperFixture();
_handler = new GetBlogByIdHandler(_dbFixture.Context, _mapperFixture.Mapper);
}

[Fact]
public async Task Handle_WithValidId_ShouldReturnBlog()
{
var query = new GetBlogByIdQuery { BlogId = 1 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result!.BlogId.Should().Be(1);
result.Name.Should().Be("Tech Blog");
}

[Fact]
public async Task Handle_WithInvalidId_ShouldReturnNull()
{
var query = new GetBlogByIdQuery { BlogId = 999 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().BeNull();
}

[Fact]
public async Task Handle_ShouldIncludePostsCount()
{
var query = new GetBlogByIdQuery { BlogId = 1 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result!.PostsCount.Should().Be(2);
}

[Fact]
public async Task Handle_ShouldMapAllProperties()
{
var query = new GetBlogByIdQuery { BlogId = 2 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result!.BlogId.Should().Be(2);
result.Name.Should().Be("Science Blog");
result.EmailAddress.Should().Be("science@example.com");
result.PostsCount.Should().Be(1);
}

public void Dispose()
{
_dbFixture.Dispose();
}
}
}
75 changes: 75 additions & 0 deletions SampleWebApp.Api.Tests/Handlers/Blogs/GetBlogsHandlerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using FluentAssertions;
using SampleWebApp.Api.Tests.Fixtures;
using SampleWebApp.Core.Handlers.Blogs.Queries;
using Xunit;

namespace SampleWebApp.Api.Tests.Handlers.Blogs
{
public class GetBlogsHandlerTests : IDisposable
{
private readonly TestDbContextFixture _dbFixture;
private readonly AutoMapperFixture _mapperFixture;
private readonly GetBlogsHandler _handler;

public GetBlogsHandlerTests()
{
_dbFixture = new TestDbContextFixture();
_mapperFixture = new AutoMapperFixture();
_handler = new GetBlogsHandler(_dbFixture.Context, _mapperFixture.Mapper);
}

[Fact]
public async Task Handle_ShouldReturnAllBlogs()
{
var query = new GetBlogsQuery();

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result.Should().HaveCount(2);
}

[Fact]
public async Task Handle_ShouldReturnBlogsOrderedByNameDescending()
{
var query = new GetBlogsQuery();

var result = await _handler.Handle(query, CancellationToken.None);
var blogList = result.ToList();

blogList[0].Name.Should().Be("Tech Blog");
blogList[1].Name.Should().Be("Science Blog");
}

[Fact]
public async Task Handle_ShouldIncludePostsCount()
{
var query = new GetBlogsQuery();

var result = await _handler.Handle(query, CancellationToken.None);
var techBlog = result.First(b => b.Name == "Tech Blog");
var scienceBlog = result.First(b => b.Name == "Science Blog");

techBlog.PostsCount.Should().Be(2);
scienceBlog.PostsCount.Should().Be(1);
}

[Fact]
public async Task Handle_ShouldMapAllProperties()
{
var query = new GetBlogsQuery();

var result = await _handler.Handle(query, CancellationToken.None);
var techBlog = result.First(b => b.Name == "Tech Blog");

techBlog.BlogId.Should().Be(1);
techBlog.Name.Should().Be("Tech Blog");
techBlog.EmailAddress.Should().Be("tech@example.com");
}

public void Dispose()
{
_dbFixture.Dispose();
}
}
}
116 changes: 116 additions & 0 deletions SampleWebApp.Api.Tests/Handlers/Posts/GetPostByIdHandlerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using FluentAssertions;
using SampleWebApp.Api.Tests.Fixtures;
using SampleWebApp.Core.Handlers.Posts.Queries;
using Xunit;

namespace SampleWebApp.Api.Tests.Handlers.Posts
{
public class GetPostByIdHandlerTests : IDisposable
{
private readonly TestDbContextFixture _dbFixture;
private readonly AutoMapperFixture _mapperFixture;
private readonly GetPostByIdHandler _handler;

public GetPostByIdHandlerTests()
{
_dbFixture = new TestDbContextFixture();
_mapperFixture = new AutoMapperFixture();
_handler = new GetPostByIdHandler(_dbFixture.Context, _mapperFixture.Mapper);
}

[Fact]
public async Task Handle_WithValidId_ShouldReturnPost()
{
var query = new GetPostByIdQuery { PostId = 1 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result!.PostId.Should().Be(1);
result.Title.Should().Be("Introduction to C#");
}

[Fact]
public async Task Handle_WithInvalidId_ShouldReturnNull()
{
var query = new GetPostByIdQuery { PostId = 999 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().BeNull();
}

[Fact]
public async Task Handle_ShouldIncludeBloggerName()
{
var query = new GetPostByIdQuery { PostId = 1 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result!.BloggerName.Should().Be("Tech Blog");
}

[Fact]
public async Task Handle_ShouldIncludeTags()
{
var query = new GetPostByIdQuery { PostId = 1 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result!.Tags.Should().HaveCount(2);
result.Tags.Select(t => t.Name).Should().Contain("Programming");
result.Tags.Select(t => t.Name).Should().Contain("Web Development");
}

[Fact]
public async Task Handle_ShouldMapAllProperties()
{
var query = new GetPostByIdQuery { PostId = 1 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result!.PostId.Should().Be(1);
result.Title.Should().Be("Introduction to C#");
result.Content.Should().Be("This is a post about C# programming.");
result.BloggerName.Should().Be("Tech Blog");
result.BlogId.Should().Be(1);
result.LastUpdated.Should().NotBe(default);
}

[Fact]
public async Task Handle_ShouldReturnDetailedTagInfo()
{
var query = new GetPostByIdQuery { PostId = 1 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
var programmingTag = result!.Tags.First(t => t.Name == "Programming");
programmingTag.TagId.Should().Be(1);
programmingTag.Slug.Should().Be("programming");
}

[Fact]
public async Task Handle_WithDifferentPost_ShouldReturnCorrectData()
{
var query = new GetPostByIdQuery { PostId = 3 };

var result = await _handler.Handle(query, CancellationToken.None);

result.Should().NotBeNull();
result!.PostId.Should().Be(3);
result.Title.Should().Be("Physics Fundamentals");
result.BloggerName.Should().Be("Science Blog");
result.Tags.Should().HaveCount(1);
result.Tags.First().Name.Should().Be("Science");
}

public void Dispose()
{
_dbFixture.Dispose();
}
}
}
Loading