Exemple #1
0
        public async Task CanApproveNewFeatures()
        {
            var client  = new LeanwareTestClient(_factory);
            var feature = (await client.Create <Feature>()).Received;
            var stories = new List <Story>();

            for (int i = 0; i < 5; i++)
            {
                var story = (await client.Create <Story>(new { FeatureId = feature.Id })).Received;
                stories.Add(story);
            }

            var response = await client.Post(path : $"api/features/{feature.Id}/approve");

            response.EnsureSuccessStatusCode();

            feature = await client.Get <Feature>(feature.ReadPath);

            feature.Status.Should().Be("Approved");

            foreach (var s in stories)
            {
                var story = await client.Get <Story>(s.ReadPath);

                story.Status.Should().Be("Approved");
            }

            // Only New feature can be approved, otherwise HTTP 400 BadRequest should be returned
            response = await client.Post(path : $"api/features/{feature.Id}/approve");

            response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
        }
Exemple #2
0
        public async Task CanFilterFeaturesByTags()
        {
            var client = new LeanwareTestClient(_factory);

            var testTag = $"{Guid.NewGuid().ToString().Split('-')[1]}{Guid.NewGuid().ToString().Split('-')[1]}";

            var features       = new List <Feature>();
            var taggedFeatures = new List <Feature>();

            for (int i = 0; i < 10; i++)
            {
                features.Add((await client.Create <Feature>()).Received);
            }

            for (int i = 0; i < 5; i++)
            {
                var tag = features[i].Tags.First();

                taggedFeatures.Add(features[i]);

                await client.Update <Feature>(features[i].UpdatePath, new { Tags = new List <string> {
                                                                                testTag
                                                                            } });
            }

            var filteredFeatures = await client.Get <List <Feature> >($"api/features?tag={testTag}");

            filteredFeatures.Select(ff => ff.Id).Should().BeEquivalentTo(taggedFeatures.Select(tf => tf.Id));
        }
Exemple #3
0
        public async Task CanCollectLogs()
        {
            var client = new LeanwareTestClient(_factory);

            var feature = (await client.Create <Feature>()).Received;

            var story = (await client.Create <Story>(new { FeatureId = feature.Id })).Received;

            await client.Post(path : $"api/features/{feature.Id}/approve");

            await client.Post(path : $"api/stories/{story.Id}/start");

            await client.Post(path : $"api/stories/{story.Id}/finish");

            var storyUpdate = new { Title = RandomTitle("S") };

            await client.Update <Story>(story.UpdatePath, storyUpdate);

            var logs = await client.Get <List <string> >(path : $"api/logs");

            var assertedLogs = new[] {
                $"Feature #{feature.Id} has been created",
                $"Story #{story.Id} has been added to feature #{feature.Id}",
                $"Feature #{feature.Id} has been approved",
                $"Story #{story.Id} has been started",
                $"Story #{story.Id} has been finished",
                $"Feature #{feature.Id} has been finished",
                $"Story #{story.Id} has been updated"
            };

            foreach (var al in assertedLogs)
            {
                logs.Should().Contain(al);
            }
        }
Exemple #4
0
        public async Task CanEnforceWipLimit()
        {
            const int wipLimit = 2;

            var client = new LeanwareTestClient(_factory);

            var stories = new List <Story>();

            for (int i = 0; i < wipLimit + 1; i++)
            {
                var feature = (await client.Create <Feature>()).Received;
                var story   = (await client.Create <Story>(new { FeatureId = feature.Id })).Received;
                stories.Add(story);
                await client.Post(path : $"api/features/{feature.Id}/approve");
            }

            for (int i = 0; i < wipLimit; i++)
            {
                await client.Post(path : $"api/stories/{stories[i].Id}/start");

                var story = await client.Get <Story>(stories[0].ReadPath);

                story.Status.Should().Be("Implementing");
            }

            var response = await client.Post(path : $"api/stories/{stories[wipLimit].Id}/start");

            response.StatusCode.Should().Be(HttpStatusCode.BadRequest, $"only {wipLimit} features can be in progress at the same time");
        }
Exemple #5
0
        public async Task CanDeleteTags()
        {
            var client = new LeanwareTestClient(_factory);

            var feature = (await client.Create <Feature>()).Received;

            var tag = feature.Tags.First();

            await client.Delete($"api/tags/{tag}");

            feature = await client.Get <Feature>(feature.ReadPath);

            feature.Tags.Should().NotContain(tag);
        }
Exemple #6
0
        public async Task CannotChangeFeatureStatus()
        {
            var client = new LeanwareTestClient(_factory);

            var feature = (await client.Create <Feature>()).Received;

            var directUpdate = new { Status = "Approved" };

            var updateResponse = await client.Patch(feature.UpdatePath, directUpdate);

            feature = await client.Get <Feature>(feature.ReadPath);

            feature.Status.Should().Be("New");
        }
Exemple #7
0
        public async Task CanRenameTags()
        {
            var client = new LeanwareTestClient(_factory);

            var feature = (await client.Create <Feature>()).Received;

            var tag    = feature.Tags.First();
            var newTag = string.Join("", tag.Reverse());

            await client.Post(path : $"api/tags/{tag}/renameTo/{newTag}");

            feature = await client.Get <Feature>(feature.ReadPath);

            feature.Tags.Should().Contain(newTag);
        }
Exemple #8
0
        public async Task CanImplementStories()
        {
            var client = new LeanwareTestClient(_factory);

            var feature = (await client.Create <Feature>()).Received;
            var stories = new List <Story>();

            for (int i = 0; i < 5; i++)
            {
                var s = (await client.Create <Story>(new { FeatureId = feature.Id })).Received;
                stories.Add(s);
            }

            var response = await client.Post(path : $"api/stories/{stories[0].Id}/start");

            response.StatusCode.Should().Be(HttpStatusCode.BadRequest, "only approved stories can be implemented");

            await client.Post(path : $"api/features/{feature.Id}/approve");

            response = await client.Post(path : $"api/stories/{stories[0].Id}/finish");

            response.StatusCode.Should().Be(HttpStatusCode.BadRequest, "story cannot be finished without being started first");

            response = await client.Post(path : $"api/stories/{stories[0].Id}/start");

            response.EnsureSuccessStatusCode();

            feature = await client.Get <Feature>(feature.ReadPath);

            feature.Status.Should().Be("Implementing");

            var story = await client.Get <Story>(stories[0].ReadPath);

            story.Status.Should().Be("Implementing");

            response = await client.Post(path : $"api/stories/{story.Id}/finish");

            response.EnsureSuccessStatusCode();

            feature = await client.Get <Feature>(feature.ReadPath);

            feature.Status.Should().Be("Implementing");

            story = await client.Get <Story>(story.ReadPath);

            story.Status.Should().Be("Implemented");

            for (int i = 1; i < stories.Count; i++)
            {
                await client.Post(path : $"api/stories/{stories[i].Id}/start");

                await client.Post(path : $"api/stories/{stories[i].Id}/finish");
            }

            feature = await client.Get <Feature>(feature.ReadPath);

            feature.Status.Should().Be("Implemented", "when all stories are implemented, feature is automatically set to implemented too");

            var additionalStory = (await client.Create <Story>(new { FeatureId = feature.Id })).Received;

            additionalStory.Status.Should().Be("Approved", "when new story is added to implemented feature, it is considered approved by default");

            feature = await client.Get <Feature>(feature.ReadPath);

            feature.Status.Should().Be("ChangeRequested");
        }
Exemple #9
0
        public async Task CanCrudStoriesAndFeatures()
        {
            // Given CRUD client
            var client = new LeanwareTestClient(_factory);

            // When I create new feature
            var createFeatureResult = await client.Create <Feature>();

            // Then created feature should have valid ID and title
            var createdFeature = createFeatureResult.Received;

            createdFeature.Id.Should().BeGreaterThan(0);
            createdFeature.Status.Should().Be("New");
            createdFeature.Title.Should().Be(createFeatureResult.Sent.Title);

            // When I update feature
            var featureUpdate = new { Tags = RandomTags };

            // Then updated feature should have new title
            var featureUpdateResult = await client.Update <Feature>(createdFeature.UpdatePath, featureUpdate);

            featureUpdateResult.Received.Title.Should().Be(createdFeature.Title);
            featureUpdateResult.Received.Tags.Should().Contain(featureUpdate.Tags);

            // When I create story
            var createStoryResult = await client.Create <Story>(new { FeatureId = createdFeature.Id });

            // Then I created story should have valid ID and title
            var createdStory = createStoryResult.Received;

            createdStory.Id.Should().BeGreaterThan(0);

            createdStory.Title.Should().Be(createStoryResult.Sent.Title);

            createdStory.Status.Should().Be("New");

            createdStory.FeatureId.Should().Be(createdFeature.Id);

            // When I update story
            var storyUpdate = new { Title = RandomTitle("S") };

            // Then updated story should have new title
            var storyUpdateResult = await client.Update <Story>(createdStory.UpdatePath, storyUpdate);

            storyUpdateResult.Received.Title.Should().Be(storyUpdate.Title);

            // When I delete story
            await client.Delete(createdStory.DeletePath);

            // Then getting story should return 404
            var deletedStory = await client.Get(createdStory.ReadPath);

            deletedStory.StatusCode.Should().Be(HttpStatusCode.NotFound);

            // When I delete feature
            await client.Delete(createdFeature.DeletePath);

            // Then getting feature should return 404
            var deletedFeature = await client.Get(createdFeature.ReadPath);

            deletedFeature.StatusCode.Should().Be(HttpStatusCode.NotFound);
        }
Exemple #10
0
        public async Task CanCrudStoriesAndFeatures()
        {
            var client = new LeanwareTestClient(_factory);

            var featureTitle = RandomFeatureTitle;
            var feature      = new
            {
                Id    = 0,
                Title = featureTitle,
                Tags  = RandomFeatureTags
            };

            feature = await client.PostSelf("api/features", feature);

            feature.Id.Should().BeGreaterThan(0);
            feature.Title.Should().Be(featureTitle);

            var featurePath = $"api/features/{feature.Id}";

            var updatedFeature = new
            {
                Title = $"{featureTitle} and {featureTitle}"
            };

            await client.Patch(featurePath, updatedFeature);

            feature = await client.Get(featurePath, feature);

            feature.Title.Should().Be($"{featureTitle} and {featureTitle}");

            var storyTitle = RandomStoryTitle;

            var story = new
            {
                Id          = 0,
                Title       = storyTitle,
                Description = nameof(CanCrudStoriesAndFeatures),
                Tags        = RandomStoryTags,
                FeatureId   = feature.Id
            };

            story = await client.PostSelf("api/stories", story);

            story.Id.Should().BeGreaterThan(0);

            var storyPath = $"api/stories/{story.Id}";

            story.Title.Should().Be(storyTitle);

            var updatedStory = new
            {
                Title = $"{storyTitle} and {storyTitle}"
            };

            await client.Patch(storyPath, updatedStory);

            story = await client.Get(storyPath, story);

            story.Title.Should().Be($"{storyTitle} and {storyTitle}");

            await client.Delete(storyPath);

            var deletedStory = await client.Get(storyPath);

            deletedStory.StatusCode.Should().Be(HttpStatusCode.NotFound);

            await client.Delete(featurePath);

            var deletedFeature = await client.Get(featurePath);

            deletedFeature.StatusCode.Should().Be(HttpStatusCode.NotFound);
        }