public void After_registering_contact__aggregate_contains_ContactOccured_event()
        {
            var school          = new SchoolAggregate(SchoolId.New);
            var registeringUser = new ApplicationUser()
            {
                Id = Guid.NewGuid()
            };

            school.RegisterSchool(
                NodaTime.SystemClock.Instance.GetCurrentInstant() - NodaTime.Duration.FromDays(2),
                new RegisterSchool.Command()
            {
                Name        = "I Liceum Ogólnokształcące",
                City        = "Gdańsk",
                Address     = "Wały Piastowskie 6",
                ContactData = new[] {
                    new ContactData()
                    {
                        Name         = "sekretariat",
                        EmailAddress = EmailAddress.Parse("*****@*****.**"),
                        PhoneNumber  = PhoneNumber.Parse("58 301-67-34")
                    },
                }
            },
                registeringUser);

            var command = new RecordContact.Command()
            {
                SchoolId             = school.Id.GetGuid(),
                ContactTimestamp     = NodaTime.SystemClock.Instance.GetCurrentInstant() - NodaTime.Duration.FromDays(1),
                CommunicationChannel = CommunicationChannelType.OutgoingEmail,
                EmailAddress         = EmailAddress.Parse("*****@*****.**"),
                PhoneNumber          = null,
                ContactPersonName    = "Andrzej Strzelba",
                Content         = "treść",
                AdditionalNotes = "notatka"
            };
            var result = school.RecordContact(command, registeringUser, NodaTime.SystemClock.Instance.GetCurrentInstant());

            Assert.True(result.IsSuccess);

            var uncommittedEvent = Assert.Single(school.UncommittedEvents, @event => @event.AggregateEvent is ContactOccured);
            var @event           = Assert.IsType <ContactOccured>(uncommittedEvent.AggregateEvent);

            Assert.Equal(registeringUser.Id, @event.RecordingUserId);
            Assert.Equal(command.ContactTimestamp, @event.ContactTimestamp);
            Assert.Equal(CommunicationChannelType.OutgoingEmail, @event.CommunicationChannel);
            Assert.Equal(command.EmailAddress, @event.EmailAddress);
            Assert.Equal(command.PhoneNumber, @event.PhoneNumber);
            Assert.Equal("Andrzej Strzelba", @event.ContactPersonName);
            Assert.Equal("treść", @event.Content);
            Assert.Equal("notatka", @event.AdditionalNotes);
        }
        public void Command_must_be_executed_on_aggregate_with_matching_SchoolId()
        {
            var school        = new SchoolAggregate(SchoolId.New);
            var recordingUser = new ApplicationUser();

            var command = new RecordContact.Command()
            {
                SchoolId = SchoolId.New.GetGuid()
            };

            Assert.Throws <AggregateMismatchException>(() =>
                                                       school.RecordContact(command, recordingUser, NodaTime.SystemClock.Instance.GetCurrentInstant()));
        }
        public void Request_Timestamp_cannot_be_later_than_current_timestamp()
        {
            var school          = new SchoolAggregate(SchoolId.New);
            var registeringUser = new ApplicationUser()
            {
                Id = Guid.NewGuid()
            };

            school.RegisterSchool(
                NodaTime.SystemClock.Instance.GetCurrentInstant() - NodaTime.Duration.FromDays(1),
                new RegisterSchool.Command()
            {
                Name        = "I Liceum Ogólnokształcące",
                City        = "Gdańsk",
                Address     = "Wały Piastowskie 6",
                ContactData = new[] {
                    new ContactData()
                    {
                        Name         = "sekretariat",
                        EmailAddress = EmailAddress.Parse("*****@*****.**"),
                        PhoneNumber  = PhoneNumber.Parse("58 301-67-34")
                    },
                }
            },
                registeringUser);

            var command = new RecordContact.Command()
            {
                SchoolId             = school.Id.GetGuid(),
                ContactTimestamp     = NodaTime.SystemClock.Instance.GetCurrentInstant() + NodaTime.Duration.FromDays(1),
                CommunicationChannel = CommunicationChannelType.OutgoingEmail,
                EmailAddress         = EmailAddress.Parse("*****@*****.**"),
                ContactPersonName    = "Andrzej Strzelba",
                Content = "treść"
            };
            var result = school.RecordContact(command, new ApplicationUser()
            {
                Id = Guid.NewGuid()
            }, NodaTime.SystemClock.Instance.GetCurrentInstant());

            Assert.False(result.IsSuccess);
            var error = Assert.IsType <Error.DomainError>(result.Error);

            Assert.Equal(RecordContact_Messages.Contact_timestamp_cannot_be_later_than_current_timestamp, error.Message);
        }
        public void If_CommunicationChannel_is_IncomingEmail__EmailAddress_must_be_provided()
        {
            var school        = new SchoolAggregate(SchoolId.New);
            var recordingUser = new ApplicationUser();

            var command = new RecordContact.Command()
            {
                SchoolId             = school.Id.GetGuid(),
                ContactTimestamp     = NodaTime.SystemClock.Instance.GetCurrentInstant() - NodaTime.Duration.FromDays(1),
                CommunicationChannel = CommunicationChannelType.IncomingEmail,
                ContactPersonName    = "Andrzej Strzelba",
                Content = "treść"
            };
            var result = school.RecordContact(command, recordingUser, NodaTime.SystemClock.Instance.GetCurrentInstant());

            Assert.False(result.IsSuccess);
            var error = Assert.IsType <Error.ValidationFailed>(result.Error);

            Assert.Contains(RecordContact_Messages.EmailAddress_cannot_be_empty_when_CommunicationChannel_is_IncomingEmail_or_OutgoingEmail,
                            error.Failures[nameof(command.EmailAddress)]);
        }
        public void Request_must_contain__SchoolId_Timestamp_CommunicationChannel_and_Content()
        {
            var school        = new SchoolAggregate(SchoolId.With(Guid.Empty));
            var recordingUser = new ApplicationUser();

            var command = new RecordContact.Command()
            {
                ContactPersonName = "   ",
                Content           = "   "
            };
            var result = school.RecordContact(command, recordingUser, NodaTime.SystemClock.Instance.GetCurrentInstant());

            Assert.False(result.IsSuccess);
            var error = Assert.IsType <Error.ValidationFailed>(result.Error);

            Assert.Contains(RecordContact_Messages.SchoolId_cannot_be_empty, error.Failures[nameof(command.SchoolId)]);
            Assert.Contains(RecordContact_Messages.Timestamp_cannot_be_empty, error.Failures[nameof(command.ContactTimestamp)]);
            Assert.Contains(RecordContact_Messages.CommunicationChannel_cannot_be_empty, error.Failures[nameof(command.CommunicationChannel)]);
            Assert.Contains(RecordContact_Messages.ContactPersonName_cannot_be_empty, error.Failures[nameof(command.ContactPersonName)]);
            Assert.Contains(RecordContact_Messages.Content_cannot_be_empty, error.Failures[nameof(command.Content)]);
        }
        public void SchoolId_must_point_to_existing_school()
        {
            var school        = new SchoolAggregate(SchoolId.New);
            var recordingUser = new ApplicationUser();

            var command = new RecordContact.Command()
            {
                SchoolId             = school.Id.GetGuid(),
                ContactTimestamp     = NodaTime.SystemClock.Instance.GetCurrentInstant() - NodaTime.Duration.FromDays(1),
                CommunicationChannel = CommunicationChannelType.OutgoingEmail,
                EmailAddress         = EmailAddress.Parse("*****@*****.**"),
                ContactPersonName    = "Andrzej Strzelba",
                Content = "treść"
            };
            var result = school.RecordContact(command, recordingUser, NodaTime.SystemClock.Instance.GetCurrentInstant());

            Assert.False(result.IsSuccess);
            var error = Assert.IsType <Error.ResourceNotFound>(result.Error);

            Assert.Equal(Messages.School_not_found, error.Message);
        }