public async Task ProcessAddItemEventAsync_DoesNotAddItemWhenUserIdDoesNotMatch()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakecategoryid", Name = "fakename", UserId = "fakeuserid1"
            });
            var service        = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);
            var eventToProcess = new EventGridEvent
            {
                Subject   = "fakeuserid2/fakeitemid",
                EventType = EventTypes.Audio.AudioCreated,
                Data      = new AudioCreatedEventData
                {
                    Category          = "fakecategoryid",
                    TranscriptPreview = "newpreview"
                }
            };

            // act
            await service.ProcessAddItemEventAsync(eventToProcess, "fakeuserid2");

            // assert
            var itemsCollection = fakeCategoriesRepository.CategoryDocuments.Single().Items;

            Assert.Equal(0, itemsCollection.Count);
        }
        public async Task UpdateCategorySynonyms_PublishesCategorySynonymsUpdatedEventToEventGrid()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", Name = "fakename", UserId = "fakeuserid"
            });
            var mockEventGridPublisherService = new Mock <IEventGridPublisherService>();
            var mockSynonymService            = new Mock <ISynonymService>();

            mockSynonymService
            .Setup(m => m.GetSynonymsAsync("fakename"))
            .ReturnsAsync(new[] { "a", "b" });
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, mockSynonymService.Object, mockEventGridPublisherService.Object);

            // act
            await service.UpdateCategorySynonymsAsync("fakeid", "fakeuserid");

            // assert
            mockEventGridPublisherService.Verify(m =>
                                                 m.PostEventGridEventAsync(EventTypes.Categories.CategorySynonymsUpdated,
                                                                           "fakeuserid/fakeid",
                                                                           It.Is <CategorySynonymsUpdatedEventData>(c => c.Synonyms.Contains("a") && c.Synonyms.Contains("b"))),
                                                 Times.Once);
        }
        public async Task ProcessUpdateItemEventAsync_UpdatesAudioItem()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakecategoryid", Name = "fakename", UserId = "fakeuserid", Items = new List <CategoryItem> {
                    new CategoryItem {
                        Id = "fakeitemid", Type = ItemType.Audio, Preview = "oldpreview"
                    }
                }
            });
            var service        = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);
            var eventToProcess = new EventGridEvent
            {
                Subject   = "fakeuserid/fakeitemid",
                EventType = EventTypes.Audio.AudioTranscriptUpdated,
                Data      = new AudioTranscriptUpdatedEventData
                {
                    TranscriptPreview = "newpreview"
                }
            };

            // act
            await service.ProcessUpdateItemEventAsync(eventToProcess, "fakeuserid");

            // assert
            var itemsCollection = fakeCategoriesRepository.CategoryDocuments.Single().Items;

            Assert.Equal("newpreview", itemsCollection.Single().Preview);
        }
        public async Task UpdateCategoryImage_PublishesCategoryImageUpdatedEventToEventGrid()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", Name = "fakename", UserId = "fakeuserid"
            });
            var mockEventGridPublisherService = new Mock <IEventGridPublisherService>();
            var mockImageSearchService        = new Mock <IImageSearchService>();

            mockImageSearchService
            .Setup(m => m.FindImageUrlAsync("fakename"))
            .ReturnsAsync("http://fake/imageurl.jpg");
            var service = new CategoriesService(fakeCategoriesRepository, mockImageSearchService.Object, new Mock <ISynonymService>().Object, mockEventGridPublisherService.Object);

            // act
            await service.UpdateCategoryImageAsync("fakeid", "fakeuserid");

            // assert
            mockEventGridPublisherService.Verify(m =>
                                                 m.PostEventGridEventAsync(EventTypes.Categories.CategoryImageUpdated,
                                                                           "fakeuserid/fakeid",
                                                                           It.Is <CategoryImageUpdatedEventData>(c => c.ImageUrl == "http://fake/imageurl.jpg")),
                                                 Times.Once);
        }
        public async Task ProcessUpdateItemEventAsync_PublishesCategoryItemsUpdatedEventToEventGrid()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakecategoryid", Name = "fakename", UserId = "fakeuserid", Items = new List <CategoryItem> {
                    new CategoryItem {
                        Id = "fakeitemid", Type = ItemType.Text, Preview = "oldpreview"
                    }
                }
            });
            var mockEventGridPublisherService = new Mock <IEventGridPublisherService>();
            var service        = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, mockEventGridPublisherService.Object);
            var eventToProcess = new EventGridEvent
            {
                Subject   = "fakeuserid/fakeitemid",
                EventType = EventTypes.Text.TextUpdated,
                Data      = new TextUpdatedEventData
                {
                    Preview = "newpreview"
                }
            };

            // act
            await service.ProcessUpdateItemEventAsync(eventToProcess, "fakeuserid");

            // assert
            mockEventGridPublisherService.Verify(m =>
                                                 m.PostEventGridEventAsync(EventTypes.Categories.CategoryItemsUpdated,
                                                                           "fakeuserid/fakecategoryid",
                                                                           It.IsAny <CategoryItemsUpdatedEventData>()),
                                                 Times.Once);
        }
        public async Task ListCategories_ReturnsIds()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid1", Name = "fakename1", UserId = "fakeuserid"
            });
            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid2", Name = "fakename2", UserId = "fakeuserid"
            });
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);

            // act
            var result = await service.ListCategoriesAsync("fakeuserid");

            // assert
            Assert.Equal(2, result.Count);
            var comparer = new CategorySummaryComparer();

            Assert.Contains(new CategorySummary {
                Id = "fakeid1", Name = "fakename1"
            }, result, comparer);
            Assert.Contains(new CategorySummary {
                Id = "fakeid2", Name = "fakename2"
            }, result, comparer);
        }
        public async Task ProcessAddItemEventAsync_AddsAudioItem()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakecategoryid", Name = "fakename", UserId = "fakeuserid"
            });
            var service        = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);
            var eventToProcess = new EventGridEvent
            {
                Subject   = "fakeuserid/fakeitemid",
                EventType = EventTypes.Audio.AudioCreated,
                Data      = new AudioCreatedEventData
                {
                    Category          = "fakecategoryid",
                    TranscriptPreview = "faketranscript"
                }
            };

            // act
            await service.ProcessAddItemEventAsync(eventToProcess, "fakeuserid");

            // assert
            var itemsCollection = fakeCategoriesRepository.CategoryDocuments.Single().Items;

            Assert.Equal(1, itemsCollection.Count);
            Assert.Contains(new CategoryItem {
                Id = "fakeitemid", Preview = "faketranscript", Type = ItemType.Audio
            }, itemsCollection, new CategoryItemComparer());
        }
        public async Task ProcessDeleteItemEventAsync_DeletesTextItem()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakecategoryid", Name = "fakename", UserId = "fakeuserid", Items = new List <CategoryItem> {
                    new CategoryItem {
                        Id = "fakeitemid", Type = ItemType.Text
                    }
                }
            });
            var service        = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);
            var eventToProcess = new EventGridEvent
            {
                Subject   = "fakeuserid/fakeitemid",
                EventType = EventTypes.Text.TextDeleted,
                Data      = new TextDeletedEventData()
            };

            // act
            await service.ProcessDeleteItemEventAsync(eventToProcess, "fakeuserid");

            // assert
            Assert.Empty(fakeCategoriesRepository.CategoryDocuments.Single().Items);
        }
        public async Task AddCategory_AddsDocumentToRepository()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);

            // act
            await service.AddCategoryAsync("name", "fakeuserid");

            // assert
            Assert.Equal(1, fakeCategoriesRepository.CategoryDocuments.Count);
            Assert.Contains(fakeCategoriesRepository.CategoryDocuments, d => d.Name == "name" && d.UserId == "fakeuserid");
        }
        public async Task DeleteCategory_ReturnsSuccess()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", UserId = "fakeuserid"
            });
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);

            // act
            var result = await service.DeleteCategoryAsync("fakeid", "fakeuserid");

            // assert
            Assert.Equal(DeleteCategoryResult.Success, result);
        }
        public async Task GetCategory_IncorrectUserId_ReturnsNull()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", Name = "fakename", UserId = "fakeuserid2"
            });
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);

            // act
            var result = await service.GetCategoryAsync("fakeid", "fakeuserid");

            // assert
            Assert.Null(result);
        }
        public async Task UpdateCategory_UpdatesDocumentInRepository()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", Name = "oldname", UserId = "fakeuserid"
            });
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);

            // act
            await service.UpdateCategoryAsync("fakeid", "fakeuserid", "newname");

            // assert
            Assert.Equal("newname", fakeCategoriesRepository.CategoryDocuments.Single().Name);
        }
        public async Task DeleteCategory_DeletesDocumentFromRepository()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", UserId = "fakeuserid"
            });
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);

            // act
            await service.DeleteCategoryAsync("fakeid", "fakeuserid");

            // assert
            Assert.Empty(fakeCategoriesRepository.CategoryDocuments);
        }
        public async Task UpdateCategorySynonyms_UserIdIncorrect_DoesNotUpdateCategoryDocumentWithSynonyms()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", Name = "fakename", UserId = "fakeuserid1"
            });
            var mockSynonymService = new Mock <ISynonymService>();

            mockSynonymService
            .Setup(m => m.GetSynonymsAsync("fakename"))
            .ReturnsAsync(new[] { "a", "b" });
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, mockSynonymService.Object, new Mock <IEventGridPublisherService>().Object);

            // act
            await service.UpdateCategorySynonymsAsync("fakeid", "fakeuserid2");

            // assert
            Assert.Empty(fakeCategoriesRepository.CategoryDocuments.Single().Synonyms);
        }
        public async Task UpdateCategoryImage_UserIdIncorrect_DoesNotUpdateCategoryDocumentWithImageUrl()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", Name = "fakename", UserId = "fakeuserid1"
            });
            var mockImageSearchService = new Mock <IImageSearchService>();

            mockImageSearchService
            .Setup(m => m.FindImageUrlAsync("fakename"))
            .ReturnsAsync("http://fake/imageurl.jpg");
            var service = new CategoriesService(fakeCategoriesRepository, mockImageSearchService.Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);

            // act
            await service.UpdateCategoryImageAsync("fakeid", "fakeuserid2");

            // assert
            Assert.Null(fakeCategoriesRepository.CategoryDocuments.Single().ImageUrl);
        }
        public async Task UpdateCategorySynonyms_SynonymsNotFound_ReturnsFalse()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", Name = "fakename", UserId = "fakeuserid"
            });
            var mockSynonymService = new Mock <ISynonymService>();

            mockSynonymService
            .Setup(m => m.GetSynonymsAsync("fakename"))
            .ReturnsAsync((string[])null);
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, mockSynonymService.Object, new Mock <IEventGridPublisherService>().Object);

            // act
            var result = await service.UpdateCategorySynonymsAsync("fakeid", "fakeuserid");

            // assert
            Assert.False(result);
        }
        public async Task UpdateCategory_PublishesCategoryNameUpdatedEventToEventGrid()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakeid", UserId = "fakeuserid"
            });
            var mockEventGridPublisherService = new Mock <IEventGridPublisherService>();
            var service = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, mockEventGridPublisherService.Object);

            // act
            await service.UpdateCategoryAsync("fakeid", "fakeuserid", "newname");

            // assert
            mockEventGridPublisherService.Verify(m =>
                                                 m.PostEventGridEventAsync(EventTypes.Categories.CategoryNameUpdated,
                                                                           "fakeuserid/fakeid",
                                                                           It.Is <CategoryNameUpdatedEventData>(d => d.Name == "newname")),
                                                 Times.Once);
        }
        public async Task ProcessAddItemEventAsync_ThrowsWhenCategoryNotProvided()
        {
            // arrange
            var fakeCategoriesRepository = new FakeCategoriesRepository();

            fakeCategoriesRepository.CategoryDocuments.Add(new CategoryDocument {
                Id = "fakecategoryid", Name = "fakename", UserId = "fakeuserid"
            });
            var service        = new CategoriesService(fakeCategoriesRepository, new Mock <IImageSearchService>().Object, new Mock <ISynonymService>().Object, new Mock <IEventGridPublisherService>().Object);
            var eventToProcess = new EventGridEvent
            {
                Subject   = "fakeuserid/fakeitemid",
                EventType = EventTypes.Audio.AudioCreated,
                Data      = new AudioCreatedEventData
                {
                    TranscriptPreview = "faketranscript"
                }
            };

            // act and assert
            await Assert.ThrowsAsync <InvalidOperationException>(() => service.ProcessAddItemEventAsync(eventToProcess, "fakeuserid"));
        }