public IHttpActionResult Put(Guid ticketId, TicketModel model)
        {
            var newTicket = Mapper.Map<Ticket>(model);
            newTicket.TicketId = ticketId;
            newTicket.ExpectedVersion = _versionQuery.Execute(Envelop(this.Request));

            try
            {
                _updateTicketCmd.Execute(Envelop(newTicket));
            }
            catch (UnauthorizedAccessException)
            {
                return this.Unauthorized();
            }
            catch (ValidationException e)
            {
                return this.BadRequest(e.Message);
            }
            catch (TicketNotFoundException)
            {
                return this.NotFound();
            }
            catch (OptimisticConcurrencyException e)
            {
                return this.ResponseMessage(new HttpResponseMessage(HttpStatusCode.PreconditionFailed)
                {
                    Content = new StringContent(e.Message)
                });
            }

            var ticket = _getTicketQuery.Execute(Envelop(ticketId));
            var response = Mapper.Map<TicketResponseModel>(ticket);

            return new OkResultWithETag<TicketResponseModel>(response, this)
            {
                ETagValue = ticket.Version.ToString()
            };
        }
        public void put_returns_412_precondition_failed_on_version_conflict(
            Guid ticketId,
            TicketModel ticket,
            OptimisticConcurrencyException exception,
            [Frozen]Mock<ICommand<Ticket>> updateCmd,
            TicketsController sut)
        {
            updateCmd.Setup(cmd => cmd.Execute(It.IsAny<Envelope<Ticket>>())).Throws(exception);

            var actual = sut.Put(ticketId, ticket);

            actual.Should().BeOfType<ResponseMessageResult>()
                  .Which.Response.StatusCode.Should().Be(HttpStatusCode.PreconditionFailed);
        }
        public IHttpActionResult Post(TicketModel model)
        {
            var id = Guid.NewGuid();
            var newTicket = Mapper.Map<Ticket>(model);
            newTicket.TicketId = id;

            try
            {
                _addTicketCmd.Execute(Envelop(newTicket));
            }
            catch (ValidationException e)
            {
                return this.BadRequest(e.Message);
            }
            catch(UnauthorizedAccessException)
            {
                return this.Unauthorized();
            }

            var ticket = _getTicketQuery.Execute(Envelop(id));
            var response = Mapper.Map<TicketResponseModel>(ticket);

            var uri = this.Url.Link("GetTicketById", new { ticketId = id });
            return new CreatedResultWithETag<TicketResponseModel>(new Uri(uri), response, this)
            {
                ETagValue = ticket.Version.ToString()
            };
        }
        public void put_returns_403_unauthorized_if_unauthorized(
            Guid ticketId,
            TicketModel ticket,
            [Frozen]Mock<ICommand<Ticket>> updateCmd,
            TicketsController sut)
        {
            updateCmd.Setup(c => c.Execute(It.IsAny<Envelope<Ticket>>()))
                     .Throws<UnauthorizedAccessException>();

            var actual = sut.Put(ticketId, ticket);

            actual.Should().BeOfType<UnauthorizedResult>("because user name query returned nothing");
        }
        public void put_returns_404_notfound_when_ticket_not_found(
            Guid ticketId,
            TicketModel ticket,
            TicketNotFoundException exception,
            [Frozen]Mock<ICommand<Ticket>> updateCmd,
            TicketsController sut)
        {
            updateCmd.Setup(cmd => cmd.Execute(It.IsAny<Envelope<Ticket>>())).Throws(exception);

            var actual = sut.Put(ticketId, ticket);

            actual.Should().BeOfType<NotFoundResult>("because TicketNotFoundException was thrown");
        }
        public void put_returns_400_bad_request_on_validation_error(
            TicketModel ticket,
            Guid ticketId,
            ValidationException exception,
            [Frozen]Mock<ICommand<Ticket>> updateCmd,
            TicketsController sut)
        {
            updateCmd.Setup(cmd => cmd.Execute(It.IsAny<Envelope<Ticket>>())).Throws(exception);

            var actual = sut.Put(ticketId, ticket);

            actual.Should().BeOfType<BadRequestErrorMessageResult>();
        }
        public void put_returns_200_ok_with_correct_etag_on_success(
            Guid ticketId,
            TicketModel ticket,
            TicketDetails ticketDetails,
            [Frozen]Mock<IUserNameQuery> userQuery,
            [Frozen]Mock<IQuery<Guid, TicketDetails>> ticketQuery,
            TicketsController sut)
        {
            ticketQuery.Setup(q => q.Execute(It.IsAny<Envelope<Guid>>())).Returns(ticketDetails);

            var actual = sut.Put(ticketId, ticket);

            actual.Should().BeOfType<OkResultWithETag<TicketResponseModel>>()
                .Which.ETagValue.Should().Be(ticketDetails.Version.ToString());
        }
        public void post_returns_ticket_etag_on_success(
            TicketModel ticket,
            TicketDetails ticketDetails,
            [Frozen]Mock<IQuery<Guid, TicketDetails>> ticketQuery,
            [Frozen]Mock<UrlHelper> url,
            TicketsController sut)
        {
            var createdUri = "http://localhost:8051/api/tickets/123";
            url.Setup(u => u.Link(It.IsAny<string>(), It.IsAny<object>()))
                            .Returns(createdUri);
            ticketQuery.Setup(q => q.Execute(It.IsAny<Envelope<Guid>>())).Returns(ticketDetails);

            var actual = sut.Post(ticket);

            actual.Should().BeOfType<CreatedResultWithETag<TicketResponseModel>>()
                  .Which.ETagValue.Should().Be(ticketDetails.Version.ToString());
        }
        public void post_returns_created_ticket_on_success(
            TicketModel ticket,
            TicketDetails ticketDetails,
            [Frozen]Mock<IQuery<Guid, TicketDetails>> ticketQuery,
            [Frozen]Mock<UrlHelper> url,
            TicketsController sut)
        {
            var createdUri = "http://localhost:8051/api/tickets/123";
            url.Setup(u => u.Link(It.IsAny<string>(), It.IsAny<object>()))
                            .Returns(createdUri);
            ticketQuery.Setup(q => q.Execute(It.IsAny<Envelope<Guid>>())).Returns(ticketDetails);

            var actual = sut.Post(ticket);

            actual.Should().BeOfType<CreatedResultWithETag<TicketResponseModel>>()
                  .Which.Content.ShouldBeEquivalentTo(ticketDetails, options => options.ExcludingMissingMembers());
        }
        public void post_returns_201_created_with_correct_location_on_success(
            TicketModel ticket,
            [Frozen]Mock<UrlHelper> url,
            TicketsController sut)
        {
            var createdUri = "http://localhost:8051/api/tickets/123";
            url.Setup(u => u.Link(It.IsAny<string>(), It.IsAny<object>()))
                            .Returns(createdUri);

            var actual = sut.Post(ticket);

            actual.Should().BeOfType<CreatedResultWithETag<TicketResponseModel>>()
                  .Which.Location.OriginalString.Should().Be(createdUri);
        }