public async Task Save_should_update_an_existing_product()
        {
            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenAsyncSession())
                {
                    // Arrange
                    var fixture = new Fixture();
                    var product = fixture.Build<Product>()
                        .With(c => c.Id, "Products-1")
                        .With(c => c.Name, "Mediums")
                        .Create();
                    await SaveEntity(product, session);

                    // Act
                    var dto = new ProductDto {Id = "Products-1", Name = "Updated name"};
                    var service = GetProductsService(session);
                    var model = await service.Save(dto);
                    model.Message.Should().Be("Atualizou tipo Updated name");
                }

                using (var session = store.OpenAsyncSession())
                {
                    var actual = await session.LoadAsync<Product>("Products-1");
                    actual.Name.Should().Be("Updated name");
                }
            }
        }
        public async Task Save_should_save_a_product_to_the_db()
        {
            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenAsyncSession())
                {
                    var dto = new ProductDto
                    {
                        Id = default(string),
                        Name = "Mediums",
                        Count = "110/130",
                        Type = ProductType.DomesticGrade
                    };

                    // Act
                    var service = GetProductsService(session);
                    var model = await service.Save(dto);

                    // Assert
                    model.Success.Should().BeTrue();
                    model.Message.Should().Be("Criou tipo Mediums");

                    var actual = await session.LoadAsync<Product>("Products-1");
                    actual.Name.Should().Be("Mediums");
                    actual.Count.Should().Be("110/130");
                    actual.Type.Should().Be(ProductType.DomesticGrade);
                }
            }
        }
        public async Task<BaseUpdateModel<ProductDto>> Save(ProductDto dto)
        {
            var entity = dto.Id.IsNullOrEmpty() ? new Product() : await Session.LoadAsync<Product>(dto.Id);

            SetUpdateText(dto);

            UpdateAuditInfo(entity);
            Mapper.Map(dto, entity);

            await Session.StoreAsync(entity);
            await Session.SaveChangesAsync();

            dto.Id = entity.Id;

            return new BaseUpdateModel<ProductDto>(dto, $"{UpdateText} tipo {entity.Name}", true);
        }
        public async Task<ProductDto> GetById(string id)
        {
            if (id.IsNullOrEmpty()) throw new ArgumentNullException(nameof(id));

            var entity = await Session.LoadAsync<Product>(id);

            if (entity == null)
                throw new NotFoundException($"Não existe um produto com Id {id.FromRavenId()}");

            var dto = new ProductDto
            {
                Id = entity.Id,
                Name = entity.Name,
                Count = entity.Count,
                Type = entity.Type
            };

            return dto;
        }