Merge pull request #4 from Shchoholiev/feature/SA-51-wishlists-service

Feature/sa 51 wishlists service
This commit is contained in:
Mykhailo Bilodid 2023-10-11 21:08:30 +03:00 committed by GitHub
commit 6b8b2bdeb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 671 additions and 11 deletions

View File

@ -12,10 +12,12 @@ public static class GraphQlExtention
.AddQueryType()
.AddTypeExtension<UsersQuery>()
.AddTypeExtension<RolesQuery>()
.AddTypeExtension<WishlistsQuery>()
.AddMutationType()
.AddTypeExtension<AccessMutation>()
.AddTypeExtension<UsersMutation>()
.AddTypeExtension<RolesMutation>()
.AddTypeExtension<WishlistsMutation>()
.AddAuthorization()
.InitializeOnStartup(keepWarm: true);

View File

@ -0,0 +1,17 @@
using ShoppingAssistantApi.Application.IServices;
using ShoppingAssistantApi.Application.Models.CreateDtos;
using ShoppingAssistantApi.Application.Models.Dtos;
namespace ShoppingAssistantApi.Api.Mutations;
[ExtendObjectType(OperationTypeNames.Mutation)]
public class WishlistsMutation
{
public Task<WishlistDto> StartPersonalWishlist(WishlistCreateDto dto, CancellationToken cancellationToken,
[Service] IWishlistsService wishlistsService)
=> wishlistsService.StartPersonalWishlistAsync(dto, cancellationToken);
public Task<MessageDto> AddMessageToPersonalWishlist(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken,
[Service] IWishlistsService wishlistsService)
=> wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, dto, cancellationToken);
}

View File

@ -0,0 +1,20 @@
using HotChocolate.Authorization;
using ShoppingAssistantApi.Application.IServices;
using ShoppingAssistantApi.Application.Models.Dtos;
using ShoppingAssistantApi.Application.Paging;
namespace ShoppingAssistantApi.Api.Queries;
[ExtendObjectType(OperationTypeNames.Query)]
public class WishlistsQuery
{
[Authorize]
public Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken,
[Service] IWishlistsService wishlistsService)
=> wishlistsService.GetPersonalWishlistsPageAsync(pageNumber, pageSize, cancellationToken);
[Authorize]
public Task<WishlistDto> GetPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken,
[Service] IWishlistsService wishlistsService)
=> wishlistsService.GetPersonalWishlistAsync(wishlistId, cancellationToken);
}

View File

@ -0,0 +1,11 @@
using MongoDB.Bson;
using ShoppingAssistantApi.Domain.Common;
namespace ShoppingAssistantApi.Application.Exceptions;
public class UnAuthorizedException<TEntity> : Exception where TEntity : EntityBase
{
public UnAuthorizedException() { }
public UnAuthorizedException(ObjectId id) : base(String.Format($"Access to object {id} of type {typeof(TEntity).Name} denied.")) { }
}

View File

@ -0,0 +1,5 @@
using ShoppingAssistantApi.Domain.Entities;
namespace ShoppingAssistantApi.Application.IRepositories;
public interface IMessagesRepository : IBaseRepository<Message> { }

View File

@ -0,0 +1,9 @@
using System.Linq.Expressions;
using ShoppingAssistantApi.Domain.Entities;
namespace ShoppingAssistantApi.Application.IRepositories;
public interface IWishlistsRepository : IBaseRepository<Wishlist>
{
public Task<Wishlist> GetWishlistAsync(Expression<Func<Wishlist, bool>> predicate, CancellationToken cancellationToken);
}

View File

@ -0,0 +1,16 @@
using ShoppingAssistantApi.Application.Models.CreateDtos;
using ShoppingAssistantApi.Application.Models.Dtos;
using ShoppingAssistantApi.Application.Paging;
namespace ShoppingAssistantApi.Application.IServices;
public interface IWishlistsService
{
Task<WishlistDto> StartPersonalWishlistAsync(WishlistCreateDto dto, CancellationToken cancellationToken);
Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken);
Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken);
Task<WishlistDto> GetPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken);
}

View File

@ -0,0 +1,15 @@
using AutoMapper;
using ShoppingAssistantApi.Application.Models.CreateDtos;
using ShoppingAssistantApi.Application.Models.Dtos;
using ShoppingAssistantApi.Domain.Entities;
namespace ShoppingAssistantApi.Application.MappingProfiles;
public class MessageProfile : Profile
{
public MessageProfile()
{
CreateMap<Message, MessageDto>().ReverseMap();
CreateMap<MessageCreateDto, Message>().ReverseMap();
}
}

View File

@ -0,0 +1,15 @@
using AutoMapper;
using ShoppingAssistantApi.Application.Models.CreateDtos;
using ShoppingAssistantApi.Application.Models.Dtos;
using ShoppingAssistantApi.Domain.Entities;
namespace ShoppingAssistantApi.Application.MappingProfiles;
public class WishlistProfile : Profile
{
public WishlistProfile()
{
CreateMap<Wishlist, WishlistDto>().ReverseMap();
CreateMap<WishlistCreateDto, Wishlist>().ReverseMap();
}
}

View File

@ -0,0 +1,6 @@
namespace ShoppingAssistantApi.Application.Models.CreateDtos;
public class MessageCreateDto
{
public required string Text { get; set; }
}

View File

@ -0,0 +1,8 @@
namespace ShoppingAssistantApi.Application.Models.CreateDtos;
public class WishlistCreateDto
{
public required string Type { get; set; }
public required string FirstMessageText { get; set; }
}

View File

@ -0,0 +1,12 @@
namespace ShoppingAssistantApi.Application.Models.Dtos;
public class MessageDto
{
public required string Id { get; set; }
public required string Text { get; set; }
public required string Role { get; set; }
public string? CreatedById { get; set; } = null;
}

View File

@ -0,0 +1,12 @@
namespace ShoppingAssistantApi.Application.Models.Dtos;
public class WishlistDto
{
public required string Id { get; set; }
public required string Name { get; set; }
public required string Type { get; set; }
public string CreatedById { get; set; } = null!;
}

View File

@ -0,0 +1,13 @@
using MongoDB.Bson;
using ShoppingAssistantApi.Domain.Common;
namespace ShoppingAssistantApi.Domain.Entities;
public class Message : EntityBase
{
public required string Text { get; set; }
public required string Role { get; set; }
public ObjectId WishlistId { get; set; }
}

View File

@ -0,0 +1,12 @@
using ShoppingAssistantApi.Domain.Common;
namespace ShoppingAssistantApi.Domain.Entities;
public class Wishlist : EntityBase
{
public required string Name { get; set; }
public required string Type { get; set; }
public ICollection<Message>? Messages { get; set; }
}

View File

@ -0,0 +1,7 @@
namespace ShoppingAssistantApi.Domain.Enums;
public enum MessageRoles
{
User = 0,
Application = 1
}

View File

@ -0,0 +1,7 @@
namespace ShoppingAssistantApi.Domain.Enums;
public enum WishlistTypes
{
Product = 0,
Gift = 1
}

View File

@ -14,6 +14,7 @@ public static class ServicesExtention
services.AddScoped<IUserManager, UserManager>();
services.AddScoped<ITokensService, TokensService>();
services.AddScoped<IUsersService, UsersService>();
services.AddScoped<IWishlistsService, WishlistsService>();
return services;
}

View File

@ -0,0 +1,107 @@
using AutoMapper;
using MongoDB.Bson;
using ShoppingAssistantApi.Application.Exceptions;
using ShoppingAssistantApi.Application.GlobalInstances;
using ShoppingAssistantApi.Application.IRepositories;
using ShoppingAssistantApi.Application.IServices;
using ShoppingAssistantApi.Application.Models.CreateDtos;
using ShoppingAssistantApi.Application.Models.Dtos;
using ShoppingAssistantApi.Application.Paging;
using ShoppingAssistantApi.Domain.Entities;
using ShoppingAssistantApi.Domain.Enums;
namespace ShoppingAssistantApi.Infrastructure.Services;
public class WishlistsService : IWishlistsService
{
private readonly IWishlistsRepository _wishlistsRepository;
private readonly IMessagesRepository _messagesRepository;
private readonly IMapper _mapper;
public WishlistsService(IWishlistsRepository wishlistRepository, IMessagesRepository messageRepository, IMapper mapper)
{
_wishlistsRepository = wishlistRepository;
_messagesRepository = messageRepository;
_mapper = mapper;
}
public async Task<WishlistDto> StartPersonalWishlistAsync(WishlistCreateDto dto, CancellationToken cancellationToken)
{
var newWishlist = _mapper.Map<Wishlist>(dto);
if (!Enum.TryParse<WishlistTypes>(newWishlist.Type, true, out var enumValue) ||
!Enum.GetValues<WishlistTypes>().Contains(enumValue))
{
throw new InvalidDataException("Provided type is invalid.");
}
newWishlist.CreatedById = (ObjectId) GlobalUser.Id;
newWishlist.CreatedDateUtc = DateTime.UtcNow;
newWishlist.Name = $"{newWishlist.Type} Search";
var createdWishlist = await _wishlistsRepository.AddAsync(newWishlist, cancellationToken);
var newMessage = new Message
{
Text = dto.FirstMessageText,
Role = MessageRoles.User.ToString(),
WishlistId = createdWishlist.Id
};
var createdMessage = await _messagesRepository.AddAsync(newMessage, cancellationToken);
return _mapper.Map<WishlistDto>(createdWishlist);
}
public async Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken)
{
var newMessage = _mapper.Map<Message>(dto);
if (!ObjectId.TryParse(wishlistId, out var wishlistObjectId))
{
throw new InvalidDataException("Provided id is invalid.");
}
newMessage.WishlistId = wishlistObjectId;
newMessage.Role = MessageRoles.User.ToString();
newMessage.CreatedById = (ObjectId) GlobalUser.Id;
newMessage.CreatedDateUtc = DateTime.UtcNow;
var relatedWishlist = await _wishlistsRepository.GetWishlistAsync(x => x.Id == wishlistObjectId && x.CreatedById == GlobalUser.Id, cancellationToken);
if (relatedWishlist == null)
{
throw new UnAuthorizedException<Wishlist>();
}
var createdMessage = await _messagesRepository.AddAsync(newMessage, cancellationToken);
return _mapper.Map<MessageDto>(createdMessage);
}
public async Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken)
{
var entities = await _wishlistsRepository.GetPageAsync(pageNumber, pageSize, cancellationToken);
var dtos = _mapper.Map<List<WishlistDto>>(entities);
var count = await _wishlistsRepository.GetTotalCountAsync();
return new PagedList<WishlistDto>(dtos, pageNumber, pageSize, count);
}
public async Task<WishlistDto> GetPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken)
{
if (!ObjectId.TryParse(wishlistId, out var wishlistObjectId))
{
throw new InvalidDataException("Provided id is invalid.");
}
var entity = await _wishlistsRepository.GetWishlistAsync(x => x.Id == wishlistObjectId && x.CreatedById == GlobalUser.Id, cancellationToken);
Console.WriteLine(" WISHLIST: " + entity.CreatedById + " " + GlobalUser.Id);
if (entity == null)
{
throw new UnAuthorizedException<Wishlist>();
}
return _mapper.Map<WishlistDto>(entity);
}
}

View File

@ -1,11 +1,15 @@
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Bson;
using MongoDB.Driver;
using ShoppingAssistantApi.Application.GlobalInstances;
using ShoppingAssistantApi.Application.IServices;
using ShoppingAssistantApi.Application.IServices.Identity;
using ShoppingAssistantApi.Application.Models.CreateDtos;
using ShoppingAssistantApi.Application.Models.Dtos;
using ShoppingAssistantApi.Application.Models.Identity;
using ShoppingAssistantApi.Domain.Entities;
using ShoppingAssistantApi.Domain.Enums;
using ShoppingAssistantApi.Persistance.Database;
namespace ShoppingAssistantApi.Persistance.PersistanceExtentions;
@ -19,23 +23,27 @@ public class DbInitialaizer
private readonly ITokensService _tokensService;
private readonly IMongoCollection<User> _userCollection;
private readonly IMongoCollection<Wishlist> _wishlistCollection;
public IEnumerable<RoleDto> Roles { get; set; }
public DbInitialaizer(IServiceProvider serviceProvider)
{
this._usersService = serviceProvider.GetService<IUsersService>();
this._rolesService = serviceProvider.GetService<IRolesService>();
this._userManager = serviceProvider.GetService<IUserManager>();
this._tokensService = serviceProvider.GetService<ITokensService>();
_usersService = serviceProvider.GetService<IUsersService>();
_rolesService = serviceProvider.GetService<IRolesService>();
_userManager = serviceProvider.GetService<IUserManager>();
_tokensService = serviceProvider.GetService<ITokensService>();
_wishlistCollection = serviceProvider.GetService<MongoDbContext>().Db.GetCollection<Wishlist>("Wishlists");
_userCollection = serviceProvider.GetService<MongoDbContext>().Db.GetCollection<User>("Users");
}
public async
Task
InitialaizeDb(CancellationToken cancellationToken)
public async Task InitialaizeDb(CancellationToken cancellationToken)
{
await this.AddRoles(cancellationToken);
await this.AddUsers(cancellationToken);
await AddRoles(cancellationToken);
await AddUsers(cancellationToken);
await AddWishlistsWithMessages(cancellationToken);
}
public async Task AddUsers(CancellationToken cancellationToken)
@ -73,7 +81,7 @@ InitialaizeDb(CancellationToken cancellationToken)
_userManager.AccessGuestAsync(guestModel5, cancellationToken)
);
var guests = await this._usersService.GetUsersPageAsync(1, 4, cancellationToken);
var guests = await _usersService.GetUsersPageAsync(1, 4, cancellationToken);
var guestsResult = guests.Items.ToList();
var user1 = new UserDto
@ -123,7 +131,7 @@ InitialaizeDb(CancellationToken cancellationToken)
RefreshToken = _tokensService.GenerateRefreshToken(),
RefreshTokenExpiryDate = DateTime.Now.AddDays(7),
};
GlobalUser.Id = ObjectId.Parse(user1.Id);
await _userManager.UpdateAsync(user1, cancellationToken);
@ -158,4 +166,51 @@ InitialaizeDb(CancellationToken cancellationToken)
var dto2 = await _rolesService.AddRoleAsync(role2, cancellationToken);
var dto3 = await _rolesService.AddRoleAsync(role3, cancellationToken);
}
public async Task AddWishlistsWithMessages(CancellationToken cancellationToken)
{
var user1 = await (await _userCollection.FindAsync(x => x.Email.Equals("shopping.assistant.team@gmail.com"))).FirstAsync();
var user2 = await (await _userCollection.FindAsync(x => x.Email.Equals("mykhailo.bilodid@nure.ua"))).FirstAsync();
var wishlists = new Wishlist[]
{
new Wishlist
{
Id = ObjectId.Parse("ab79cde6f69abcd3efab65cd"),
Name = "Gaming PC",
Type = WishlistTypes.Product.ToString(),
CreatedById = user1.Id,
Messages = new Message[]
{
new Message
{
Text = "Prompt",
Role = MessageRoles.User.ToString(),
},
new Message
{
Text = "Answer",
Role = MessageRoles.Application.ToString(),
},
}
},
new Wishlist
{
Id = ObjectId.Parse("ab6c2c2d9edf39abcd1ef9ab"),
Name = "Generic Wishlist Name",
Type = WishlistTypes.Product.ToString(),
CreatedById = user2.Id,
Messages = new Message[]
{
new Message
{
Text = "Prompt",
Role = MessageRoles.User.ToString(),
}
}
}
};
await _wishlistCollection.InsertManyAsync(wishlists);
}
}

View File

@ -13,6 +13,8 @@ public static class RepositoriesExtention
services.AddScoped<IRolesRepository, RolesRepository>();
services.AddScoped<IUsersRepository, UsersRepository>();
services.AddScoped<IWishlistsRepository, WishlistsRepository>();
services.AddScoped<IMessagesRepository, MessagesRepository>();
return services;
}

View File

@ -0,0 +1,10 @@
using ShoppingAssistantApi.Application.IRepositories;
using ShoppingAssistantApi.Domain.Entities;
using ShoppingAssistantApi.Persistance.Database;
namespace ShoppingAssistantApi.Persistance.Repositories;
public class MessagesRepository : BaseRepository<Message>, IMessagesRepository
{
public MessagesRepository(MongoDbContext db) : base(db, "Messages") { }
}

View File

@ -0,0 +1,17 @@
using System.Linq.Expressions;
using MongoDB.Driver;
using ShoppingAssistantApi.Application.IRepositories;
using ShoppingAssistantApi.Domain.Entities;
using ShoppingAssistantApi.Persistance.Database;
namespace ShoppingAssistantApi.Persistance.Repositories;
public class WishlistsRepository : BaseRepository<Wishlist>, IWishlistsRepository
{
public WishlistsRepository(MongoDbContext db) : base(db, "Wishlists") { }
public async Task<Wishlist> GetWishlistAsync(Expression<Func<Wishlist, bool>> predicate, CancellationToken cancellationToken)
{
return await (await _collection.FindAsync(predicate)).FirstOrDefaultAsync(cancellationToken);
}
}

View File

@ -0,0 +1,281 @@
using ShoppingAssistantApi.Tests.TestExtentions;
using System.Net.Http.Headers;
using System.Net;
using System.Text;
using Xunit;
using Newtonsoft.Json;
using ShoppingAssistantApi.Domain.Enums;
namespace ShoppingAssistantApi.Tests.Tests;
[Collection("Tests")]
public class WishlistsTests : IClassFixture<TestingFactory<Program>>
{
private readonly HttpClient _httpClient;
private const string WISHLIST_TESTING_USER_EMAIL = "shopping.assistant.team@gmail.com";
private const string WISHLIST_TESTING_USER_PASSWORD = "Yuiop12345";
private const string TESTING_WISHLIST_ID = "ab79cde6f69abcd3efab65cd";
public WishlistsTests(TestingFactory<Program> factory)
{
_httpClient = factory.CreateClient();
factory.InitialaizeData().GetAwaiter().GetResult();
}
[Fact]
public async Task StartPersonalWishlistAsync_ValidWishlistModel_ReturnsNewWishlistModels()
{
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
var user = await UserExtention.GetCurrentUser(_httpClient);
var mutation = new
{
query = "mutation startPersonalWishlist($dto: WishlistCreateDtoInput!) { startPersonalWishlist (dto: $dto) { id, name, type, createdById } }",
variables = new
{
dto = new
{
firstMessageText = "First message",
type = WishlistTypes.Product.ToString()
}
}
};
var jsonPayload = JsonConvert.SerializeObject(mutation);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync("graphql", content);
response.EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var responseString = await response.Content.ReadAsStringAsync();
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
var wishlistId = (string) document.data.startPersonalWishlist.id;
var wishlistCreatedById = (string) document.data.startPersonalWishlist.createdById;
var wishlistType = (string) document.data.startPersonalWishlist.type;
var wishlistName = (string) document.data.startPersonalWishlist.name;
Assert.Equal(user.Id, wishlistCreatedById);
Assert.Equal(WishlistTypes.Product.ToString(), wishlistType);
Assert.Equal($"{WishlistTypes.Product} Search", wishlistName);
}
[Fact]
public async Task GetPersonalWishlistsPage_ValidPageNumberAndSize_ReturnsPage()
{
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
var user = await UserExtention.GetCurrentUser(_httpClient);
var query = new
{
query = "query personalWishlistsPage($pageNumber: Int!, $pageSize: Int!) { personalWishlistsPage(pageNumber: $pageNumber, pageSize: $pageSize) { items { createdById, id, name, type } } }",
variables = new
{
pageNumber = 1,
pageSize = 1
}
};
var jsonPayload = JsonConvert.SerializeObject(query);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync("graphql", content);
response.EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var responseString = await response.Content.ReadAsStringAsync();
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
var personalWishlistsPageItems = Enumerable.ToList(document.data.personalWishlistsPage.items);
var personalWishlistCreatedById = (string) personalWishlistsPageItems[0].createdById;
Assert.NotEmpty(personalWishlistsPageItems);
Assert.Equal(user.Id, personalWishlistCreatedById);
}
[Fact]
public async Task GetPersonalWishlist_ValidWishlistIdOrAuthorizedAccess_ReturnsWishlistDto()
{
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
var user = await UserExtention.GetCurrentUser(_httpClient);
var query = new
{
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
variables = new
{
wishlistId = TESTING_WISHLIST_ID
}
};
var jsonPayload = JsonConvert.SerializeObject(query);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync("graphql", content);
response.EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var responseString = await response.Content.ReadAsStringAsync();
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
var personalWishlistId = (string) document.data.personalWishlist.id;
var personalWishlistName = (string) document.data.personalWishlist.name;
var personalWishlistType = (string) document.data.personalWishlist.type;
var personalWishlistCreatedById = (string) document.data.personalWishlist.createdById;
Assert.Equal(TESTING_WISHLIST_ID, personalWishlistId);
Assert.Equal("Gaming PC", personalWishlistName);
Assert.Equal(WishlistTypes.Product.ToString(), personalWishlistType);
Assert.Equal(user.Id, personalWishlistCreatedById);
}
[Fact]
public async Task AddMessageToPersonalWishlist_ValidMessageModel_ReturnsNewMessageModel()
{
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
var user = await UserExtention.GetCurrentUser(_httpClient);
const string MESSAGE_TEXT = "Second Message";
var mutation = new
{
query = "mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { addMessageToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { role, text, createdById } }",
variables = new
{
wishlistId = TESTING_WISHLIST_ID,
dto = new
{
text = MESSAGE_TEXT
}
}
};
var jsonPayload = JsonConvert.SerializeObject(mutation);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync("graphql", content);
response.EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var responseString = await response.Content.ReadAsStringAsync();
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
var messageRole = (string) document.data.addMessageToPersonalWishlist.role;
var messageText = (string) document.data.addMessageToPersonalWishlist.text;
var messageCreatedById = (string) document.data.addMessageToPersonalWishlist.createdById;
Assert.Equal(MessageRoles.User.ToString(), messageRole);
Assert.Equal(MESSAGE_TEXT, messageText);
Assert.Equal(user.Id, messageCreatedById);
}
[Fact]
public async Task StartPersonalWishlistAsync_InvalidWishlistModel_ReturnsInternalServerError()
{
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
var user = await UserExtention.GetCurrentUser(_httpClient);
var mutation = new
{
query = "mutation startPersonalWishlist($dto: WishlistCreateDtoInput!) { startPersonalWishlist (dto: $dto) { id, name, type, createdById } }",
variables = new
{
dto = new
{
firstMessageText = "First message",
type = "Invalid type" // Invalid Wishlist Type
}
}
};
var jsonPayload = JsonConvert.SerializeObject(mutation);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync("graphql", content);
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
}
[Fact]
public async Task GetPersonalWishlist_InvalidWishlistId_ReturnsInternalServerError()
{
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
var user = await UserExtention.GetCurrentUser(_httpClient);
var query = new
{
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
variables = new
{
wishlistId = "1234567890abcdef12345678" // Invalid wishlistId
}
};
var jsonPayload = JsonConvert.SerializeObject(query);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync("graphql", content);
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
}
[Fact]
public async Task GetPersonalWishlist_UnAuthorizedAccess_ReturnsInternalServerError()
{
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
var user = await UserExtention.GetCurrentUser(_httpClient);
var query = new
{
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
variables = new
{
wishlistId = "ab6c2c2d9edf39abcd1ef9ab" // Other user's wishlist
}
};
var jsonPayload = JsonConvert.SerializeObject(query);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync("graphql", content);
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
}
[Fact]
public async Task AddMessageToPersonalWishlist_InvalidMessageModel_ReturnsInternalServerError()
{
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
var user = await UserExtention.GetCurrentUser(_httpClient);
const string MESSAGE_TEXT = "Second Message";
var mutation = new
{
query = "mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { addMessageToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { role, text, createdById } }",
variables = new
{
wishlistId = "8125jad7g12", // Invalid wishlistId
dto = new
{
text = MESSAGE_TEXT,
}
}
};
var jsonPayload = JsonConvert.SerializeObject(mutation);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync("graphql", content);
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
}
}