public async Task CreateCategoryProvidesCategoryToStoreTest()
        {
            var expected = Model.Create <NewCategory>();

            var store = Substitute.For <ICategoryStore>();
            var cache = Substitute.For <ICategoryCache>();

            var sut = new CategoryCommand(store, cache);

            using (var tokenSource = new CancellationTokenSource())
            {
                await sut.CreateCategory(expected, tokenSource.Token).ConfigureAwait(false);

                await store.Received(1).StoreCategory(Arg.Any <Category>(), tokenSource.Token).ConfigureAwait(false);

                await store.Received().StoreCategory(
                    Arg.Is <Category>(x => x.Group == expected.Group),
                    tokenSource.Token).ConfigureAwait(false);

                await store.Received().StoreCategory(Arg.Is <Category>(x => x.Name == expected.Name), tokenSource.Token)
                .ConfigureAwait(false);

                await store.Received().StoreCategory(Arg.Is <Category>(x => x.LinkCount == 0), tokenSource.Token)
                .ConfigureAwait(false);

                await store.Received().StoreCategory(Arg.Is <Category>(x => x.Reviewed), tokenSource.Token)
                .ConfigureAwait(false);

                await store.Received().StoreCategory(Arg.Is <Category>(x => x.Visible), tokenSource.Token)
                .ConfigureAwait(false);

                cache.Received().RemoveCategories();
                cache.Received().RemoveCategory(expected.Group, expected.Name);
            }
        }
        public void CreateCategoryThrowsExceptionWithNullCategoryTest()
        {
            var store = Substitute.For <ICategoryStore>();
            var cache = Substitute.For <ICategoryCache>();

            var sut = new CategoryCommand(store, cache);

            Func <Task> action = async() => await sut.CreateCategory(null, CancellationToken.None)
                                 .ConfigureAwait(false);

            action.Should().Throw <ArgumentNullException>();
        }
        public async Task CreateCategorySetsLinkCountToZeroWhenNoExistingCategoryTest()
        {
            var expected = Model.Create <NewCategory>();

            var store = Substitute.For <ICategoryStore>();
            var cache = Substitute.For <ICategoryCache>();

            var sut = new CategoryCommand(store, cache);

            using (var tokenSource = new CancellationTokenSource())
            {
                await sut.CreateCategory(expected, tokenSource.Token).ConfigureAwait(false);

                await store.Received().StoreCategory(Arg.Is <Category>(x => x.LinkCount == 0), tokenSource.Token)
                .ConfigureAwait(false);
            }
        }
        public async Task CreateCategoryPreservesExistingLinkCountWhenCategoryAlreadyExistsTest()
        {
            var expected = Model.Create <NewCategory>();
            var category = Model.Create <Category>().Set(x => x.Group = expected.Group).Set(x => x.Name = expected.Name);

            var store = Substitute.For <ICategoryStore>();
            var cache = Substitute.For <ICategoryCache>();

            var sut = new CategoryCommand(store, cache);

            using (var tokenSource = new CancellationTokenSource())
            {
                store.GetCategory(expected.Group, expected.Name, tokenSource.Token).Returns(category);

                await sut.CreateCategory(expected, tokenSource.Token).ConfigureAwait(false);

                await store.Received(1).StoreCategory(Arg.Any <Category>(), tokenSource.Token).ConfigureAwait(false);

                await store.Received().StoreCategory(
                    Arg.Is <Category>(x => x.Group == expected.Group),
                    tokenSource.Token).ConfigureAwait(false);

                await store.Received().StoreCategory(Arg.Is <Category>(x => x.Name == expected.Name), tokenSource.Token)
                .ConfigureAwait(false);

                await store.Received().StoreCategory(
                    Arg.Is <Category>(x => x.LinkCount == category.LinkCount),
                    tokenSource.Token).ConfigureAwait(false);

                await store.Received().StoreCategory(Arg.Is <Category>(x => x.Reviewed), tokenSource.Token)
                .ConfigureAwait(false);

                await store.Received().StoreCategory(Arg.Is <Category>(x => x.Visible), tokenSource.Token)
                .ConfigureAwait(false);

                cache.Received().RemoveCategories();
            }
        }