示例#1
0
    public static async Task SeedSampleData(SurveyContext context)
    {
        var testOwner = new User(NonEmptyString.Create("Test User"), NonEmptyString.Create("*****@*****.**"), NonEmptyString.Create("test-id"));

        var survey1 = new Survey(testOwner, NonEmptyString.Create("Test Topic 1"), 10, NonEmptyString.Create("Testers"));
        var survey2 = new Survey(testOwner, NonEmptyString.Create("Test Topic 2"), 20, NonEmptyString.Create("More Testers"));
        var survey3 = new Survey(testOwner, NonEmptyString.Create("Test Topic 3"), 30, NonEmptyString.Create("Even More Testers"));

        survey1.AddSurveyOption(NonEmptyString.Create("Test Option 1"));

        survey2.AddSurveyOption(NonEmptyString.Create("Test Option 2"));
        survey2.AddSurveyOption(NonEmptyString.Create("Test Option 3"));

        survey3.AddSurveyOption(NonEmptyString.Create("Test Option 4"));
        survey3.AddSurveyOption(NonEmptyString.Create("Test Option 5"));
        survey3.AddSurveyOption(NonEmptyString.Create("Test Option 6"));

        await context.Users.AddAsync(testOwner);

        await context.Surveys.AddRangeAsync(new List <Survey> {
            survey1, survey2, survey3
        });

        await context.SaveChangesAsync();
    }
    public async Task <Result <SurveyModel, Error> > Handle(CreateSurveyCommand request,
                                                            CancellationToken cancellationToken)
    {
        try
        {
            var userInfo = await _userService.GetUserInfo(cancellationToken);

            var surveyOwner =
                await _surveyContext.Users.FirstAsync(user => user.ExternalUserId == userInfo.Id,
                                                      cancellationToken);

            var survey = new Survey(surveyOwner, NonEmptyString.Create(request.SurveyTopic),
                                    request.NumberOfRespondents, NonEmptyString.Create(request.RespondentType));

            survey.AddSurveyOptions(request.SurveyOptions.Select(option =>
                                                                 new SurveyOption(NonEmptyString.Create(option.OptionText), option.PreferredNumberOfVotes)));

            survey.CalculateOutcome();

            await _surveyContext.Surveys.AddAsync(survey, cancellationToken);

            await _surveyContext.SaveChangesAsync(cancellationToken);

            return(_mapper.Map <SurveyModel>(survey));
        }
        catch (SurveyDomainException e)
        {
            return(new Error("survey.domain.exception", e.Message));
        }
    }
示例#3
0
        public override void Configure(EntityTypeBuilder <SurveyOption> builder)
        {
            const string tableName    = "SurveyOption";
            var          sequenceName = $"{tableName}Seq";

            builder
            .ToTable(tableName, SurveyContext.DefaultSchema);

            builder
            .HasKey(o => o.Id);

            builder
            .Property(o => o.Id)
            .UseHiLo(sequenceName, SurveyContext.DefaultSchema);

            builder
            .Ignore(b => b.DomainEvents);

            builder
            .Property(o => o.OptionText)
            .HasMaxLength(250)
            .IsRequired()
            .HasConversion(domainValue => domainValue.Value, databaseValue => NonEmptyString.Create(databaseValue));

            builder
            .Property(o => o.NumberOfVotes)
            .IsRequired();

            builder
            .Property(o => o.PreferredNumberOfVotes);

            base.Configure(builder);
        }
        public void Should_Not_Be_Able_To_Create_Survey_With_No_Respondent_Type()
        {
            const string topic = "To be, or not to be?";
            const int    numberOfRespondents = 1;
            const string respondentType      = "";

            Assert.ThrowsAny <Exception>(() => new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType)));
        }
        public void Should_Not_Be_Able_To_Calculate_Results_Of_Survey_With_No_Options()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            var survey = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType));

            Assert.Throws <SurveyDomainException>(() => survey.CalculateOutcome());
        }
        public void Valid_returns_Some()
        {
            // version 1
            NonEmptyString.Create("a").Match(
                () => false,
                _ => true);

            // version 2
            NonEmptyString.Create("a").Should().BeEqualToNonEmptyString("a");
        }
        public void Valid_has_correct_content()
        {
            // version 1
            NonEmptyString.Create("a").Match(
                () => "a".Should().Be("b"),
                x => x.ToString().Should().Be("a"));

            // version 2
            NonEmptyString.Create("").Should().BeNone();
        }
示例#8
0
        public void NonEmptyStringValidatesCorrectly(string value, bool isSuccess)
        {
            Assert.AreEqual(isSuccess, NonEmptyString.Create(value).IsSuccess);

            var exceptionConstraint = isSuccess.Match <IConstraint>(
                t => Throws.Nothing,
                f => Throws.TypeOf <ArgumentException>()
                );

            Assert.That(() => NonEmptyString.CreateUnsafe(value), exceptionConstraint);
        }
        public void Should_Be_Able_To_Create_Survey()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1;
            const string respondentType      = "Developers";

            var survey = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType));

            Assert.Equal(topic, survey.Topic);
            Assert.Equal(numberOfRespondents, survey.NumberOfRespondents);
            Assert.Equal(respondentType, survey.RespondentType);
        }
示例#10
0
        public void Should_Not_Be_Able_To_Add_Empty_Options_To_Survey()
        {
            const string topic = "To be, or not to be?";
            const int    numberOfRespondents = 2;
            const string respondentType      = "Writers";

            Assert.ThrowsAny <Exception>(() =>
            {
                var survey = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType));

                survey.AddSurveyOption(NonEmptyString.Create(""));
            });
        }
        public static Contact CreateSampleContact(int id, string firstName, string lastName, DateTime?dob = null, string twitter = null)
        {
            var optId        = Id.Create(id);
            var optFirstName = NonEmptyString.Create(firstName);
            var optLastName  = NonEmptyString.Create(lastName);
            var optDob       = dob != null?Some(new DateOfBirth(dob.Value)) : None;

            var optTwitterHandle = twitter != null?NonEmptyString.Create(twitter) : None;

            var validContact = Contact.CreateValidContact(optId, optFirstName, optLastName, optDob, optTwitterHandle);

            return(validContact.Match(_ => null, x => x));
        }
示例#12
0
        public void GivenValidSurveyDetail_WhenCreatingSurvey_ThenValidSurveyIsCreated()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1;
            const string respondentType      = "Developers";

            var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                    NonEmptyString.Create(respondentType));

            survey.Topic.Value.Should().Be(topic);
            survey.NumberOfRespondents.Should().Be(numberOfRespondents);
            survey.RespondentType.Value.Should().Be(respondentType);
        }
示例#13
0
        public void GivenNoUser_WhenCreatingSurvey_ThenExceptionShouldBeThrown()
        {
            const string topic = "";
            const int    numberOfRespondents = 1;
            const string respondentType      = "Developers";

            Action act = () =>
            {
                _ = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents,
                               NonEmptyString.Create(respondentType));
            };

            act.Should().Throw <Exception>();
        }
示例#14
0
        public void GivenNoRespondentType_WhenCreatingSurvey_ThenExceptionShouldBeThrown()
        {
            const string topic = "To be, or not to be?";
            const int    numberOfRespondents = 1;
            const string respondentType      = "";

            Action act = () =>
            {
                _ = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                               NonEmptyString.Create(respondentType));
            };

            act.Should().Throw <Exception>();
        }
示例#15
0
        public void Should_Not_Be_Able_To_Add_Preferred_Number_Of_Votes_If_Total_Exceeds_Respondents()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            var survey = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"), 500);

            Assert.Throws <SurveyDomainException>(() =>
            {
                survey.AddSurveyOption(NonEmptyString.Create("Spaces"), 501);
            });
        }
示例#16
0
        GivenSurveyWithOptionsWhereCombinedPreferredNumberOfVotesExceedTotalRespondents_WhenAddingOptionToSurvey_ThenSurveyDomainExceptionShouldBeThrown()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                    NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"), 500);

            Action act = () => { survey.AddSurveyOption(NonEmptyString.Create("Spaces"), 501); };

            act.Should().ThrowExactly <SurveyDomainException>();
        }
示例#17
0
        public void Should_Be_Able_To_Calculate_Results_Of_Survey_With_One_Sided_Outcome()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            var survey = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"));
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"));

            survey.CalculateOneSidedOutcome();

            Assert.Equal(numberOfRespondents, survey.Options.Max(option => option.NumberOfVotes));
        }
示例#18
0
        public void Should_Be_Able_To_Add_Options_To_Survey()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1;
            const string respondentType      = "Developers";

            var survey = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"));
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"));

            Assert.Equal(2, survey.Options.Count);
            Assert.Equal("Tabs", survey.Options.First().OptionText);
            Assert.Equal("Spaces", survey.Options.Last().OptionText);
        }
示例#19
0
        public void GivenSurveyWithOptions_WhenCalculatingOneSidedOutcome_ThenOneOptionShouldReceiveAllVotes()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                    NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"));
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"));

            survey.CalculateOneSidedOutcome();

            survey.Options.Max(option => option.NumberOfVotes).Should().Be(numberOfRespondents);
        }
示例#20
0
        public void Creating_Survey_Should_Add_SurveyCreated_Event_To_DomainEvents()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1;
            const string respondentType      = "Developers";

            var survey = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"));
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"));


            var surveyCreatedEvent = survey.DomainEvents.First() as SurveyCreatedDomainEvent;

            Assert.True(surveyCreatedEvent?.Survey == survey);
        }
示例#21
0
        public void Should_Be_Able_To_Calculate_Results_Of_Survey_With_Fixed_Outcome()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            var survey = new Survey(null, NonEmptyString.Create(topic), numberOfRespondents, NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"), 600);
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"), 400);

            survey.CalculateOutcome();

            Assert.Equal(600, survey.Options.First().NumberOfVotes);
            Assert.Equal(400, survey.Options.Last().NumberOfVotes);
        }
示例#22
0
        public void GivenSurveyWithNoOption_WhenCalculatingOutcome_ThenSurveyDomainExceptionShouldBeThrown()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            Action act = () =>
            {
                var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                        NonEmptyString.Create(respondentType));

                survey.CalculateOutcome();
            };

            act.Should().ThrowExactly <SurveyDomainException>();
        }
示例#23
0
        public void Contact_creation(int id, string firstName, string lastName, string expectedMessage, bool isValid)
        {
            // Arrange
            var optId            = Id.Create(id);
            var optFirstName     = NonEmptyString.Create(firstName);
            var optLastName      = NonEmptyString.Create(lastName);
            var optDob           = None;
            var optTwitterHandle = None;

            // Act
            var validContact = Contact.CreateValidContact(optId, optFirstName, optLastName, optDob, optTwitterHandle);

            // Assert
            validContact.IsValid.Should().Be(isValid);
            validContact.ToString().Should().Be(expectedMessage);
        }
示例#24
0
        public void GivenEmptyOption_WhenAddingOptionToSurvey_ThenExceptionShouldBeThrown()
        {
            const string topic = "To be, or not to be?";
            const int    numberOfRespondents = 2;
            const string respondentType      = "Writers";

            Action act = () =>
            {
                var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                        NonEmptyString.Create(respondentType));

                survey.AddSurveyOption(NonEmptyString.Create(""));
            };

            act.Should().Throw <Exception>();
        }
示例#25
0
        public void GivenValidOption_WhenAddingOptionToSurvey_ShouldAddOptionToSurveyOptionsList()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1;
            const string respondentType      = "Developers";

            var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                    NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"));
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"));

            survey.Options.Count.Should().Be(2);
            survey.Options.First().OptionText.Value.Should().Be("Tabs");
            survey.Options.Last().OptionText.Value.Should().Be("Spaces");
        }
        public override void Configure(EntityTypeBuilder <User> builder)
        {
            const string tableName    = "User";
            var          sequenceName = $"{tableName}Seq";

            builder
            .ToTable(tableName, SurveyContext.DefaultSchema);

            builder
            .HasKey(u => u.Id);

            builder
            .Property(u => u.Id)
            .UseHiLo(sequenceName, SurveyContext.DefaultSchema);

            builder
            .Ignore(u => u.DomainEvents);

            builder
            .Property(u => u.DisplayName)
            .HasMaxLength(250)
            .IsRequired()
            .HasConversion(domainValue => domainValue.Value, databaseValue => NonEmptyString.Create(databaseValue));

            builder
            .Property(u => u.EmailAddress)
            .HasMaxLength(250)
            .IsRequired()
            .HasConversion(domainValue => domainValue.Value, databaseValue => NonEmptyString.Create(databaseValue));

            builder
            .Property(u => u.ExternalUserId)
            .HasMaxLength(250)
            .IsRequired()
            .HasConversion(domainValue => domainValue.Value, databaseValue => NonEmptyString.Create(databaseValue));

            builder
            .HasIndex(u => u.ExternalUserId)
            .IsUnique();

            builder
            .HasMany(u => u.OwnedSurveys)
            .WithOne(s => s.Owner)
            .IsRequired();

            base.Configure(builder);
        }
        public override void Configure(EntityTypeBuilder <Survey> builder)
        {
            const string tableName      = "Survey";
            var          sequenceName   = $"{tableName}Seq";
            var          foreignKeyName = $"{tableName}Id";

            builder
            .ToTable(tableName, SurveyContext.DefaultSchema);

            builder
            .HasKey(s => s.Id);

            builder
            .Property(s => s.Id)
            .UseHiLo(sequenceName, SurveyContext.DefaultSchema);

            builder
            .Ignore(s => s.DomainEvents);

            builder
            .Property(s => s.Topic)
            .HasMaxLength(250)
            .IsRequired()
            .HasConversion(domainValue => domainValue.Value, databaseValue => NonEmptyString.Create(databaseValue));

            builder
            .Property(s => s.RespondentType)
            .HasMaxLength(250)
            .IsRequired()
            .HasConversion(domainValue => domainValue.Value, databaseValue => NonEmptyString.Create(databaseValue));

            builder
            .Property(s => s.NumberOfRespondents)
            .IsRequired();

            builder
            .HasMany(s => s.Options)
            .WithOne()
            .HasForeignKey(foreignKeyName)
            .IsRequired();

            var navigation = builder.Metadata.FindNavigation(nameof(Survey.Options));

            navigation.SetPropertyAccessMode(PropertyAccessMode.Field);

            base.Configure(builder);
        }
示例#28
0
        GivenSurveyWithOptionsHavingPreferredNumberOfVotes_WhenCalculatingOutcome_ThenEachOptionShouldHaveExpectedPreferredNumberOfVotes()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                    NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"), 600);
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"), 400);

            survey.CalculateOutcome();

            survey.Options.First().NumberOfVotes.Should().Be(600);
            survey.Options.Last().NumberOfVotes.Should().Be(400);
        }
示例#29
0
        public void GivenSurveyWithOptions_WhenCalculatingOutcome_ThenOptionNumberOfVotesShouldBeDistributedEvenly()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1000;
            const string respondentType      = "Developers";

            var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                    NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"));
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"));

            survey.CalculateOutcome();

            survey.Options.Sum(option => option.NumberOfVotes).Should().Be(numberOfRespondents);
            survey.Options.All(option => option.NumberOfVotes > 0).Should().BeTrue();
        }
示例#30
0
        GivenValidSurveyDetail_WhenCreatingSurvey_ThenValidSurveyIsCreatedWithSurveyCreatedEventAddedToDomainEvents()
        {
            const string topic = "Tabs or spaces?";
            const int    numberOfRespondents = 1;
            const string respondentType      = "Developers";

            var survey = new Survey(_testUser, NonEmptyString.Create(topic), numberOfRespondents,
                                    NonEmptyString.Create(respondentType));

            survey.AddSurveyOption(NonEmptyString.Create("Tabs"));
            survey.AddSurveyOption(NonEmptyString.Create("Spaces"));

            survey.DomainEvents.Should().AllBeOfType <SurveyCreatedDomainEvent>();

            var surveyCreatedEvent = (SurveyCreatedDomainEvent)survey.DomainEvents.First();

            surveyCreatedEvent.Survey.Should().Be(survey);
        }