Skip to content

Commit

Permalink
✅ test(profile): add profile tests
Browse files Browse the repository at this point in the history
Signed-off-by: csc530 <[email protected]>
  • Loading branch information
csc530 committed Dec 19, 2023
1 parent 0e2d78a commit ebe705f
Show file tree
Hide file tree
Showing 7 changed files with 348 additions and 24 deletions.
5 changes: 3 additions & 2 deletions TestResumeBuilder/TestBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
using Microsoft.EntityFrameworkCore;
using resume_builder;
using resume_builder.models;
using Spectre.Console;
Expand All @@ -19,8 +20,7 @@ protected TestBase()
//given
TestApp = new CommandAppTester(new FakeTypeRegistrar());

TestApp.Configure(c =>
{
TestApp.Configure(c => {
Program.AppConfiguration(c);
// c.ConfigureConsole(TestConsole); //? this is what spectre does inside of Run() but only if the config is null but either way it didn't work for me
});
Expand All @@ -31,6 +31,7 @@ protected TestBase()
TestConsole = new TestConsole();
AnsiConsole.Console = TestConsole;
TestDb = new ResumeContext();
TestDb.Database.Migrate();
}

public async ValueTask DisposeAsync()
Expand Down
2 changes: 2 additions & 0 deletions TestResumeBuilder/TestResumeBuilder.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

<ItemGroup>
<PackageReference Include="AutoBogus" Version="2.13.1" />
<PackageReference Include="AutoBogus.Conventions" Version="2.13.1"/>
<PackageReference Include="AutoBogus.FakeItEasy" Version="2.13.1"/>
<PackageReference Include="Bogus" Version="35.0.1" />
<PackageReference Include="CountryData" Version="4.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
Expand Down
2 changes: 1 addition & 1 deletion TestResumeBuilder/commands/InitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public void Init_WithNoArgs_ShouldCreateDb()
//when
var result = TestApp.Run("init");
//then
Assert.True(File.Exists("TestResumeBuilder.db"));
Assert.Equal(0, result.ExitCode);
Assert.True(File.Exists("resume.db"));
TestDb = new ResumeContext();
Assert.True(TestDb.Database.CanConnect());
}
Expand Down
242 changes: 242 additions & 0 deletions TestResumeBuilder/commands/add/AddProfileTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
using resume_builder.cli.commands.add;
using resume_builder.models;
using TestResumeBuilder.data;

namespace TestResumeBuilder.commands.add;

public class AddProfileTest: TestBase
{
private readonly string[] _cmdArgs = { "add", "profile" };

[Fact]
public void AddProfile_WithNoArgs_ShouldSucceed()
{
//when
var result = TestApp.Run(_cmdArgs);
//then
Assert.Equal(0, result.ExitCode);
Assert.NotEmpty(TestDb.Profiles);
}

[Fact]
public void AddProfile_NonInteractive_WithNoArgs_ShouldFail()
{
//when
var result = TestApp.Run("add", "-i", "false", "job");
//then
Assert.Equal(0, result.ExitCode);
Assert.NotEmpty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.AllOptions), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithAllOptions_ShouldSucceed(Profile profile)
{
//given
var firstName = profile.FirstName;
var middleName = profile.MiddleName;
var lastName = profile.LastName;
var email = profile.EmailAddress;
var phone = profile.PhoneNumber;
var website = profile.Website;
var summary = profile.Summary;
var args = CreateCmdOptions(profile);
//when
var result = TestApp.Run(args);
var resultSettings = result.Settings as AddProfileSettings;
//then
Assert.Equal(0, result.ExitCode);
Assert.NotNull(resultSettings);
Assert.Multiple(() => {
Assert.Equal(firstName, resultSettings.FirstName);
Assert.Equal(middleName, resultSettings.MiddleName);
Assert.Equal(lastName, resultSettings.LastName);
Assert.Equal(email, resultSettings.EmailAddress);
Assert.Equal(phone, resultSettings.PhoneNumber);
Assert.Equal(website, resultSettings.Website);
Assert.Equal(summary, resultSettings.Summary);
});
}

[Theory]
[MemberData(nameof(AddProfileTestData.AllOptions), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithAnEmptyFirstname_AndAllOptions_ShouldFail(Profile profile)
{
//given
var args = CreateCmdOptions(string.Empty, profile.LastName, profile.EmailAddress, profile.PhoneNumber,
profile.MiddleName, profile.Website, profile.Summary);
//when
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run(args));
Assert.Empty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.WhiteSpaceStringAndProfile), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithWhitespaceFirstname_AndAllOptions_ShouldFail(string firstName, Profile profile)
{
//given
var args = CreateCmdOptions(firstName, profile.LastName, profile.EmailAddress, profile.PhoneNumber,
profile.MiddleName, profile.Website, profile.Summary);
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run(args));
Assert.Empty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.AllOptions), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithAnEmptyLastname_AndAllOptions_ShouldFail(Profile profile)
{
//given
var args = CreateCmdOptions(profile.FirstName, string.Empty, profile.EmailAddress, profile.PhoneNumber,
profile.MiddleName, profile.Website, profile.Summary);
//when
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run(args));
Assert.Empty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.WhiteSpaceStringAndProfile), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithWhitespaceLastname_AndAllOptions_ShouldFail(string lastname, Profile profile)
{
//given
var args = CreateCmdOptions(profile.FirstName, lastname, profile.EmailAddress, profile.PhoneNumber,
profile.MiddleName, profile.Website, profile.Summary);
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run(args));
Assert.Empty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.AllOptions), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithAnEmptyEmail_AndAllOptions_ShouldFail(Profile profile)
{
//given
var args = CreateCmdOptions(profile.FirstName, profile.LastName, string.Empty, profile.PhoneNumber,
profile.MiddleName, profile.Website, profile.Summary);
//when
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run(args));
Assert.Empty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.WhiteSpaceStringAndProfile), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithWhitespaceEmail_AndAllOptions_ShouldFail(string email, Profile profile)
{
//given
var args = CreateCmdOptions(profile.FirstName, profile.LastName, email, profile.PhoneNumber,
profile.MiddleName, profile.Website, profile.Summary);
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run(args));
Assert.Empty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.InvalidEmails), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithInvalidEmail_ShouldFail(string email, Profile profile)
{
//given
var args = CreateCmdOptions(profile.FirstName, profile.LastName, null, profile.PhoneNumber,
profile.MiddleName, profile.Website, profile.Summary);
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run([..args, "-e", email]));
Assert.Empty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.AllOptions), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithAnEmptyPhoneNumber_AndAllOptions_ShouldFail(Profile profile)
{
//given
var args = CreateCmdOptions(profile.FirstName, profile.LastName, profile.EmailAddress, string.Empty,
profile.MiddleName, profile.Website, profile.Summary);
//when
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run(args));
Assert.Empty(TestDb.Profiles);
}

[Theory]
[MemberData(nameof(AddProfileTestData.WhiteSpaceStringAndProfile), MemberType = typeof(AddProfileTestData))]
public void AddProfile_WithWhitespacePhoneNumber_AndAllOptions_ShouldFail(string phone, Profile profile)
{
//given
var args = CreateCmdOptions(profile.FirstName, profile.LastName, profile.EmailAddress, phone,
profile.MiddleName, profile.Website, profile.Summary);
//then
Assert.ThrowsAny<Exception>(() => TestApp.Run(args));
Assert.Empty(TestDb.Profiles);
}


private string[] CreateCmdOptions(Profile profile)
{
var firstName = profile.FirstName;
var middleName = profile.MiddleName;
var lastName = profile.LastName;
var email = profile.EmailAddress;
var phone = profile.PhoneNumber;
var website = profile.Website;
var summary = profile.Summary;

string[] args = [.._cmdArgs, "-f", firstName, "-l", lastName, "-e", email, "-p", phone];
if(middleName != null)
args = args.Concat(new[] { "-m", middleName }).ToArray();
if(website != null)
args = args.Concat(new[] { "-w", website }).ToArray();
if(summary != null)
args = [.. args, "-s", summary];
return args;
}

private string[] CreateCmdOptions(string? firstName = null, string? lastName = null, string? email = null,
string? phone = null,
string? middleName = null, string? website = null, string? summary = null)
{
var args = _cmdArgs;
if(firstName != null)
args = [..args, "-f", firstName];
if(lastName != null)
args = [..args, "-l", lastName];
if(email != null)
args = [..args, "-e", email];
if(phone != null)
args = [..args, "-p", phone];
if(middleName != null)
args = [..args, "-m", middleName];
if(website != null)
args = [..args, "-w", website];
if(summary != null)
args = [.. args, "-s", summary];
return args;
}
}

internal class AddProfileTestData: ProfileTestData
{
public static TheoryData<string, Profile> InvalidEmails()
{
var data = new TheoryData<string, Profile>();
for(var i = 0; i < TestRepetitions; i++)
data.Add(Faker.Random.String().Replace("@", ""), GetFakeProfile());
return data;
}

public static TheoryData<string, Profile> WhiteSpaceStringAndProfile()
{
var data = new TheoryData<string, Profile>();
foreach(var whitespace in RandomWhiteSpaceString())
data.Add(whitespace, GetFakeProfile());
return data;
}

public static TheoryData<Profile> AllOptions()
{
var data = new TheoryData<Profile>();
for(var i = TestRepetitions - 1; i >= 0; i--)
data.Add(ProfileTestData.GetFakeProfile());
return data;
}
}
22 changes: 22 additions & 0 deletions TestResumeBuilder/data/ProfileTestData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using AutoBogus;
using AutoBogus.Conventions;
using Bogus;
using resume_builder.models;

namespace TestResumeBuilder.data;

internal class ProfileTestData: TestData
{
static public Faker<Profile> BogusProfile = new AutoFaker<Profile>()

Check notice on line 10 in TestResumeBuilder/data/ProfileTestData.cs

View workflow job for this annotation

GitHub Actions / qodana

Adjust modifiers declaration order

Inconsistent modifiers declaration order
.Configure(config => config.WithConventions(conv =>
conv.Email.Aliases("EmailAddress", "emailAddress")))
.RuleFor(profile => profile.MiddleName,
Faker.Random.Word().OrNull(Faker))
//.RuleFor(profile => profile.EmailAddress, (_, profile) => Faker.Internet.Email(profile.FirstName, profile.LastName))
.RuleFor(profile => profile.Summary,
Faker.Lorem.Paragraph().OrNull(Faker));

static public IEnumerable<Profile> InfiniteFakeProfiles => BogusProfile.GenerateForever();

Check notice on line 19 in TestResumeBuilder/data/ProfileTestData.cs

View workflow job for this annotation

GitHub Actions / qodana

Adjust modifiers declaration order

Inconsistent modifiers declaration order
static public List<Profile> GetFakeProfiles(int count = TestRepetitions) => BogusProfile.Generate(count);

Check notice on line 20 in TestResumeBuilder/data/ProfileTestData.cs

View workflow job for this annotation

GitHub Actions / qodana

Adjust modifiers declaration order

Inconsistent modifiers declaration order
static public Profile GetFakeProfile() => BogusProfile.Generate();

Check notice on line 21 in TestResumeBuilder/data/ProfileTestData.cs

View workflow job for this annotation

GitHub Actions / qodana

Adjust modifiers declaration order

Inconsistent modifiers declaration order
}
42 changes: 42 additions & 0 deletions TestResumeBuilder/data/TestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ internal class TestData
{
private protected const int TestRepetitions = 10;

public const string space = " ";
public const string tab = "\t";
public const string newline = "\n";
public const string zeroWidthSpace = "\u200b";
public const string zeroWidthJoiner = "\u200d";
public const string zeroWidthNonJoiner = "\u200c";
public const string zeroWidthNoBreakSpace = "\u200b";
public const string zeroWidthHairSpace = "\u200a";
public const string sixPerEmSpace = "\u2006";
public const string thinSpace = "\u2009";
public const string punctuationSpace = "\u2008";
public const string fourPerEmSpace = "\u2005";
public const string threePerEmSpace = "\u2004";
public const string figureSpace = "\u2007";
public const string enSpace = "\u2002";
public const string emSpace = "\u2003";

public const string braillePatternBlank = "\u2800";


private static Random Random { get; set; } = new();
protected static Faker Faker { get; set; } = new();
Expand Down Expand Up @@ -35,4 +54,27 @@ static private protected int MaxRandomYearsBeforeToday()

public static string Waffle() => WaffleEngine.Text(Random.Next(TestRepetitions), Faker.Random.Bool());
public static string? WaffleOrNull() => Waffle().OrNull(Faker);

//#region white spaces
public static IEnumerable<string> RandomWhiteSpaceString(int count = TestRepetitions)
{
yield return Faker.Random.String2(Random.Next(count), space);
yield return Faker.Random.String2(Random.Next(count), tab);
yield return Faker.Random.String2(Random.Next(count), newline);
yield return Faker.Random.String2(Random.Next(count), zeroWidthSpace);
yield return Faker.Random.String2(Random.Next(count), zeroWidthJoiner);
yield return Faker.Random.String2(Random.Next(count), zeroWidthNonJoiner);
yield return Faker.Random.String2(Random.Next(count), zeroWidthNoBreakSpace);
yield return Faker.Random.String2(Random.Next(count), zeroWidthHairSpace);
yield return Faker.Random.String2(Random.Next(count), sixPerEmSpace);
yield return Faker.Random.String2(Random.Next(count), thinSpace);
yield return Faker.Random.String2(Random.Next(count), punctuationSpace);
yield return Faker.Random.String2(Random.Next(count), fourPerEmSpace);
yield return Faker.Random.String2(Random.Next(count), threePerEmSpace);
yield return Faker.Random.String2(Random.Next(count), figureSpace);
yield return Faker.Random.String2(Random.Next(count), enSpace);
yield return Faker.Random.String2(Random.Next(count), emSpace);
yield return Faker.Random.String2(Random.Next(count), braillePatternBlank);
}
//#endregion
}
Loading

0 comments on commit ebe705f

Please sign in to comment.