public IHttpActionResult PostAd(CreateAdBindingModel model)
        {
            var userId = this.UserIdProvider.GetUserId();

            if (userId == null)
            {
                return this.BadRequest("Invalid session token.");
            }
            if (model == null)
            {
                return this.BadRequest("Invalid input data");
            }
            if (!this.ModelState.IsValid)
            {
                return this.BadRequest(ModelState);
            }

            var categories = new List<Category>();
            if (model.Categories == null)
            {
                return this.BadRequest("You must insert categories");
            }
            if (!model.Categories.Any() || model.Categories.Count() > 3)
            {
                return this.BadRequest("The categories count must be between 1-3");
            }
            foreach (var categorie in model.Categories)
            {
                var categorieToAdd = this.Data.Categories.All().FirstOrDefault(c=>c.Id.ToString()==categorie);
                if (categorieToAdd == null)
                {
                    return this.BadRequest("Invalid categories id ");
                }
                categories.Add(categorieToAdd);
            }
           
            if (!this.Data.AdTypes.All().Any(a => a.Id.ToString() == model.TypeId))
            {
                return this.BadRequest("invalid type id .");
            }

            Ad newAd = new Ad()
            {
                Name = model.Name,
                Categories = categories,
                PostedOn = DateTime.Now,
                Description = model.Description,
                OwnerId = userId,
                Price = model.Price,
                Status = AdStatus.Open,
                TypeId = Convert.ToInt32(model.TypeId)
            };

            this.Data.Ads.Add(newAd);
            this.Data.SaveChanges();
            return this.Ok(this.Data.Ads.All().Where(a=>a.Id==newAd.Id).Select(AdsViewModel.Create));
        }
        public IHttpActionResult CreateAd(CreateAdBindingModel model)
        {
            if (model == null)
            {
                return this.BadRequest("Model cannot be null");
            }

            if (!this.ModelState.IsValid)
            {
                return this.BadRequest(this.ModelState);
            }

            var currentUserId = this.UserIdProvider.GetUserId();    // Check if id is correct
            var adType = this.Data.AdTypes.Find(model.TypeId);
            if (adType == null)
            {
                return this.BadRequest("AdType with such id does not exists");
            }

            var ad = new Ad
                     {
                         Name = model.Name,
                         Description = model.Description,
                         Price = model.Price,
                         PostedOn = DateTime.Now,
                         Status = AdStatus.Open,
                         TypeId = adType.Id,
                         OwnerId = currentUserId
                     };

            if (model.Categories.Count() > 3 || model.Categories == null)
            {
                return this.BadRequest("Categories must be in range [1..3]");
            }

            foreach (var categoryId in model.Categories)
            {
                var category = this.Data.Categories.All().FirstOrDefault(c => c.Id == categoryId);
                if (category == null)
                {
                    return this.BadRequest("Invalid category id.");
                }

                ad.Categories.Add(category);
            }

            this.Data.Ads.Add(ad);
            this.Data.SaveChanges();
            var result =
                this.Data.Ads.All().Where(a => a.Id == ad.Id).Select(AllAdsViewModel.Create).FirstOrDefault();

            return this.Ok(result);
        }
        public IHttpActionResult CreateAd(CreateAdBindingModel model)
        {
            if (!this.ModelState.IsValid)
            {
                return this.BadRequest(this.ModelState);
            }

            if (model == null)
            {
                return this.BadRequest("No data provided.");
            }

            if (model.Categories.Count() < 1 || model.Categories.Count() > 3)
            {
                return this.BadRequest("Too few or too many categories. Must be between 1 and 3.");
            }

            var ad = new Ad
            {
                Name = model.Name,
                Description = model.Description,
                Price = model.Price,
                PostedOn = DateTime.Now.AddDays(-5),
                Status = AdStatus.Open,
                OwnerId = this.User.Identity.GetUserId(),
                TypeId = model.TypeId
            };

            foreach (var categoryId in model.Categories)
            {
                var category = this.Data.Categories.Find(categoryId);
                if (category == null)
                {
                    return this.BadRequest("Invalid category id.");
                }

                ad.Categories.Add(category);
            }            
           
            this.Data.Ads.Add(ad);
            this.Data.SaveChanges();

            var userId = this.User.Identity.GetUserId();
            var result = this.Data.Ads
                .Where(a => a.Id == ad.Id)
                .Select(a => AdViewModel.Create)
                .FirstOrDefault();

            return this.Ok(result);
        }
        public IHttpActionResult CreateAd(CreateAdBindingModel model)
        {
            var userId = this.UserId;

            if (userId == null) return this.NotFound();

            if (model == null) return this.BadRequest("No data sent");

            if (!this.ModelState.IsValid) return this.BadRequest(this.ModelState);

            if (model.Categories == null || model.Categories.Count() > 3)
            {
                return this.BadRequest("Categories should be atleast 1 and no more than 3");
            }

            if (model.Categories.Select(cat => this.Data.Categories.All().FirstOrDefault(c => c.Id == cat)).Any(category => category == null))
            {
                return this.BadRequest("Categories do not exist");
            }

            if (this.Data.AdTypes.All().FirstOrDefault(t => t.Id == model.TypeId) == null)
            {
                return this.BadRequest("Unknown or missing type of ad");
            }

            ICollection<Category> categories = new HashSet<Category>();

            foreach (var cat in model.Categories)
            {
                categories.Add(this.Data.Categories.Find(cat));
            }

            var ad = new Ad()
            {
                Name = model.Name,
                Description = model.Description,
                TypeId = model.TypeId,
                Price = model.Price,
                Categories = categories,
                OwnerId = userId.GetUserId(),
                PostedOn = DateTime.Now,
                Status = AdStatus.Open
            };

            this.Data.Ads.Add(ad);
            this.Data.SaveChanges();

            return this.Ok(ad.Id);
        }
 public IHttpActionResult CreateAd(CreateAdBindingModel model)
 {
     var userId = this.UserIdProvider.GetUserId();
     var owner = this.Data.Users.Find(userId);
     if (!this.ModelState.IsValid)
     {
         return this.BadRequest(this.ModelState);
     }
     var ad = new Ad()
     {
         Name=model.Name,
         Description=model.Description,
         Type = this.Data.AdTypes.Find(model.TypeId),
         Price = model.Price,
         PostedOn = DateTime.Now,
         Owner = owner,
         Categories= new HashSet<Category>()
     };
     if (model.Categories == null)
     {
         return this.BadRequest("You should enter at least one category!");
     }
     foreach (var id in model.Categories)
     {
         var category = this.Data.Categories.Find(id);
         if (category==null)
         {
             return NotFound();
         }
         ad.Categories.Add(category);
     }
     
     if (ad.Categories.Count > 3)
     {
         return this.BadRequest("The number of categories should not exceed 3!");
     }
     this.Data.Ads.Add(ad);
     this.Data.SaveChanges();
     var result = this.Data.Ads.All()
         .Where(a => a.Id == ad.Id)
         .Select(AdViewModel.Create)
         .FirstOrDefault();
     return this.Ok(result);
 }
        public IHttpActionResult CreateAd(CreateAdBindingModel model)
        {
            string userId = this.UserIdProvider.GetUserId();
            if (userId == null)
            {
                return this.Unauthorized();
            }

            if (model == null)
            {
                return this.BadRequest("Ad model cannot be null.");
            }

            if (!this.ModelState.IsValid)
            {
                return this.BadRequest(this.ModelState);
            }

            var newAd = new Ad
            {
                Name = model.Name,
                Description = model.Description,
                TypeId = model.TypeId,
                Price = model.Price,
                PostedOn = DateTime.Now,
                OwnerId = userId
            };

            foreach (var categoryId in model.Categories)
            {
                var category = this.Data.Categories.Find(categoryId);
                newAd.Categories.Add(category);
            }

            this.Data.Ads.Add(newAd);
            this.Data.SaveChanges();
            var adInDb = this.Data.Ads.All()
                .Where(a => a.Id == newAd.Id)
                .Select(AdViewModel.Create)
                .FirstOrDefault();

            return this.Ok(adInDb);
        }
        public IHttpActionResult CreateAd(CreateAdBindingModel model)
        {
            var userId = this.User.Identity.GetUserId();

            if (model == null)
            {
                return this.BadRequest("Model cannot be null (no data in request)");
            }

            if (!this.ModelState.IsValid)
            {
                return this.BadRequest(this.ModelState);
            }

            var adType = this.Data.AdTypes
                .FirstOrDefault(at => at.Name == model.Type);

            if (adType == null)
            {
                return this.BadRequest("Type is invalid");
            }

            var ad = new Ad()
            {
                Name = model.Name,
                Description = model.Description,
                Price = model.Price,
                Type = adType,
                PostedOn = DateTime.Now,
                Status = AdStatus.Open,
                OwnerId = this.User.Identity.GetUserId()
            };

            this.Data.Ads.Add(ad);
            this.Data.SaveChanges();

            var data = this.Data.Ads
                .Where(a => a.Id == ad.Id)
                .Select(AdViewModel.Create)
                .FirstOrDefault();

            return this.Ok(data);
        }
        public void CreateAd_Should_Succesfully_Add_To_Repository()
        {
            var ads = new List<Ad>();

            var fakeUser = this.mocks.UserRepositoryMock.Object.All().FirstOrDefault();
            if (fakeUser == null)
            {
                Assert.Fail("Cannot perform test - no users available!");
            }
            this.mocks.AdRepositoryMock
                .Setup(r => r.Add(It.IsAny<Ad>()))
                .Callback((Ad ad) =>
                {
                    ad.Owner = fakeUser;
                    ads.Add(ad);
                });

            var mockContext = new Mock<IOnlineShopData>();
            mockContext.Setup(m => m.Ads).Returns(this.mocks.AdRepositoryMock.Object);
            mockContext.Setup(m => m.AdTypes).Returns(this.mocks.AdTypeRepositoryMock.Object);
            mockContext.Setup(m => m.Categories).Returns(this.mocks.CategoryRepositoryMock.Object);
            mockContext.Setup(m => m.Users).Returns(this.mocks.UserRepositoryMock.Object);

            var mockIdProvider = new Mock<IUserIdProvider>();
            mockIdProvider.Setup(m => m.GetUserId()).Returns(fakeUser.Id);

            var adsController = new AdsController(mockContext.Object,mockIdProvider.Object);
            this.SetupController(adsController);

            var randomName = Guid.NewGuid().ToString();
            var newAd = new CreateAdBindingModel()
            {
                Name = randomName,
                Categories = new[] {"0", "2"},
                Price = 300,
                Description = "none",
                TypeId = 1.ToString()
            };

            var response = adsController.PostAd(newAd).ExecuteAsync(CancellationToken.None).Result;

            mockContext.Verify(c=>c.SaveChanges(),Times.Once);

            Assert.AreEqual(response.StatusCode,HttpStatusCode.OK);
            Assert.AreEqual(ads.Count,1);
            Assert.AreEqual(newAd.Name,ads[0].Name);

        }
        public void CreateAd_ShouldAddNewlyCreatedAd()
        {
            var ads = new List<Ad>();

            var fakeUser = this.mockContainer.UserRepositoryMock.Object.All().FirstOrDefault();
            if (fakeUser == null)
            {
                Assert.Fail("Cannot perform test - no users available.");
            }

            this.mockContainer.AdRepositoryMock
                .Setup(r => r.Add(It.IsAny<Ad>()))
                .Callback((Ad ad) =>
                {
                    ad.Owner = fakeUser;
                    ads.Add(ad);
                });

            var fakeCat = mockContainer.CategoryRepositoryMock.Object.All();
            var fakeAdTypes = mockContainer.AdTypeRepositoryMock.Object.All();
            var fakeUsers = mockContainer.UserRepositoryMock.Object.All();

            var mockContext = new Mock<IOnlineShopData>();
            mockContext.Setup(r => r.Ads.All()).Returns(ads.AsQueryable());
            mockContext.Setup(r => r.Ads.Add(It.IsAny<Ad>())).Callback((Ad ad) => ads.Add(ad));

            mockContext.Setup(r => r.Categories.All()).Returns(fakeCat.AsQueryable());
            mockContext.Setup(r => r.AdTypes.All()).Returns(fakeAdTypes.AsQueryable());
            mockContext.Setup(r => r.Users.All()).Returns(fakeUsers.AsQueryable());

            var mockIdProvider = new Mock<IUserIdProvider>();
            mockIdProvider.Setup(r => r.GetUserId()).Returns(fakeUser.Id);

            var adsController = new AdsController(mockContext.Object, mockIdProvider.Object);
            this.SetupController(adsController);

            var randomName = Guid.NewGuid().ToString();
            var newAd = new CreateAdBindingModel()
            {
                Name = randomName,
                Price = 555,
                TypeId = 1,
                Description = "Testing testing",
                Categories = new[] { 1, 2, 3 }
            };

            var response = adsController.CreateAd(newAd).ExecuteAsync(CancellationToken.None).Result;
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

            mockContext.Verify(c => c.SaveChanges(), Times.Once);

            Assert.AreEqual(1, ads.Count);
            Assert.AreEqual(randomName, ads.First().Name);
        }
        public void CreateAd_Should_Successfully_Add_To_Repository()
        {
            var ads = new List<Ad>();
            var fakeUser = this.mocks.UserRepositoryMock.Object.All().FirstOrDefault();
            if (fakeUser == null)
            {
                Assert.Fail("Cannot perform test - no users available.");
            }
            this.mocks.AdRepositoryMock
                .Setup(r => r.Add(It.IsAny<Ad>()))
                .Callback((Ad ad) =>
                {
                    ad.Owner = fakeUser;
                    ads.Add(ad);
                });
            var mockContext = new Mock<IOnlineShopData>();
            mockContext.Setup(c => c.Ads).Returns(this.mocks.AdRepositoryMock.Object);
            var fakeCategories = this.mocks.CategoryRepositoryMock.Object.All();
            mockContext.Setup(c => c.Categories.All()).Returns(fakeCategories);
            mockContext.Setup(c => c.Categories.Find(It.IsAny<int>()))
                .Returns((int id) => fakeCategories.FirstOrDefault(c => c.Id == id));
            var fakeUsers = this.mocks.UserRepositoryMock.Object.All();
            mockContext.Setup(c => c.Users).Returns(this.mocks.UserRepositoryMock.Object);
            var fakeAdTypes = this.mocks.AdTypeRepositoryMock.Object.All();
            mockContext.Setup(c => c.AdTypes).Returns(this.mocks.AdTypeRepositoryMock.Object);

            var mockIdProvider = new Mock<IUserIdProvider>();
            mockIdProvider.Setup(ip => ip.GetUserId()).Returns(fakeUser.Id);

            var adsController = new AdsController(mockContext.Object, mockIdProvider.Object);
            adsController.Request = new HttpRequestMessage();
            adsController.Configuration = new HttpConfiguration();

            var randomName = Guid.NewGuid().ToString();
            var newAd = new CreateAdBindingModel()
            {
                Name = randomName,
                Price = 999,
                TypeId = 1,
                Description = "Nothing to say",
                Categories = new[] {1, 2} 
            };
            var response = adsController.CreateAd(newAd).ExecuteAsync(CancellationToken.None).Result;
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
            mockContext.Verify(c=>c.SaveChanges(), Times.Once);
            Assert.AreEqual(1, ads.Count);
            Assert.AreEqual(newAd.Name, ads[0].Name);
        }
        public void CreateAd_WithCorrectData_ShouldSuccessfullyAddAdInRepository()
        {
            // Arrange
            var ads = new List<Ad>();

            // Act
            var mockContext = new Mock<IOnlineShopData>();
            var fakeAds = this.mockContainer.AdRepositoryMock.Object.All();
            var fakeAdTypes = this.mockContainer.AdTypeRepositoryMock.Object.All();
            var fakeCategories = this.mockContainer.CategoryRepositoryMock.Object.All();
            var fakeUsers = this.mockContainer.ApplicationUserRepositoryMock.Object.All();

            mockContext.Setup(r => r.Ads).Returns(this.mockContainer.AdRepositoryMock.Object);
            mockContext.Setup(r => r.AdTypes).Returns(this.mockContainer.AdTypeRepositoryMock.Object);
            mockContext.Setup(r => r.Categories).Returns(this.mockContainer.CategoryRepositoryMock.Object);
            mockContext.Setup(r => r.ApplicationUsers).Returns(this.mockContainer.ApplicationUserRepositoryMock.Object);
            var fakeUser = this.mockContainer.ApplicationUserRepositoryMock.Object.All().FirstOrDefault();
            var mockIdProvider = new Mock<IUserIdProvider>();
            if (fakeUser == null)
            {
                Assert.Fail("Cannot perform test no users available.");
            }

            mockIdProvider.Setup(r => r.GetUserId()).Returns(fakeUser.Id);

            var adsController = new AdsController(mockContext.Object, mockIdProvider.Object);
            this.SetupController(adsController);
            this.mockContainer.AdRepositoryMock.Setup(r => r.Add(It.IsAny<Ad>()))
                .Callback((Ad ad) =>
                {
                   // ad.Id = 10;   // Uncomment if id is required in the test
                    ad.Owner = fakeUser;
                    ads.Add(ad);
                });
            var randomName = Guid.NewGuid().ToString();
            var newAd = new CreateAdBindingModel()
                        {
                            Name = randomName,
                            Price = 555,
                            TypeId = 1,
                            Description = "Put description here",
                            Categories = new[] { 1, 2 }
                        };

            var httpResponse = adsController.CreateAd(newAd).ExecuteAsync(CancellationToken.None).Result;

            // Assert
            mockContext.Verify(c => c.SaveChanges(), Times.Once);
            Assert.AreEqual(1, ads.Count);
            Assert.AreEqual(ads[0].Name, newAd.Name);
        }