Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚒️ Testing | Setup unit tests #411

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions SSW.Rewards.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SSW.Rewards.iOS", "src\SSW.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SSW.Rewards", "src\SSW.Rewards\SSW.Rewards.csproj", "{B98A315F-FDC2-489E-A8E5-94757CF3DD9F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SSW.Rewards.UnitTests", "tests\SSW.Rewards.UnitTests\SSW.Rewards.UnitTests.csproj", "{1F9C15C2-854D-4581-BF66-B581415987C1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -97,6 +99,24 @@ Global
{B98A315F-FDC2-489E-A8E5-94757CF3DD9F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{B98A315F-FDC2-489E-A8E5-94757CF3DD9F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{B98A315F-FDC2-489E-A8E5-94757CF3DD9F}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Debug|iPhone.Build.0 = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.QA|Any CPU.ActiveCfg = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.QA|Any CPU.Build.0 = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.QA|iPhone.ActiveCfg = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.QA|iPhone.Build.0 = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.QA|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.QA|iPhoneSimulator.Build.0 = Debug|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Release|Any CPU.Build.0 = Release|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Release|iPhone.ActiveCfg = Release|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Release|iPhone.Build.0 = Release|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{1F9C15C2-854D-4581-BF66-B581415987C1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
15 changes: 15 additions & 0 deletions tests/SSW.Rewards.UnitTests/BaseUnitTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Moq.AutoMock;

namespace SSW.Rewards.UnitTests;

public class BaseUnitTest<TSut> where TSut : class
{
public BaseUnitTest()
{
Mocker = new AutoMocker();
Sut = Mocker.CreateInstance<TSut>();
}

public AutoMocker Mocker { get; }
public TSut Sut { get; }
}
38 changes: 38 additions & 0 deletions tests/SSW.Rewards.UnitTests/SSW.Rewards.UnitTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
Copy link
Member Author

@AntPolkanov AntPolkanov Feb 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At that point we cannot target .net5+ because Rg.Plugins package has a dependency on .NET Framework 4.7.2 https://www.nuget.org/packages/Rg.Plugins.Popup . As we are gonna use Xamarin. Mopups (a fork of Rg.Plugins) with MAUI, I will target .net7 after the merge.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes:

<PackageReference Include="Mopups" Version="1.1.0" />

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully this PR will come out of draft tomorrow :)

<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>

<LangVersion>11</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Bogus" Version="34.0.2" />
<PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="Moq.AutoMock" Version="3.5.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<Folder Include="Factories" />
<Folder Include="Sut\Services" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\SSW.Rewards\SSW.Rewards.csproj" />
</ItemGroup>

</Project>
236 changes: 236 additions & 0 deletions tests/SSW.Rewards.UnitTests/Sut/ViewModels/OnBoardingViewModelTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
using SSW.Rewards.ViewModels;
using Xamarin.Forms;

namespace SSW.Rewards.UnitTests;

public class OnBoardingViewModelTests : BaseUnitTest<OnBoardingViewModel>
{
#region Ctor

[Fact]
public void Ctor_ShouldInitializeCommands()
{
// Arrange

// Act

// Assert
Sut.DoActionCommand.Should().NotBeNull();
Sut.Swiped.Should().NotBeNull();
Sut.Skip.Should().NotBeNull();
}

[Fact]
public void Ctor_ShouldInitializePropertiesCollection()
{
// Arrange
var expected = new[]
{
nameof(Sut.SubHeading), nameof(Sut.Content), nameof(Sut.BackgroundColour), nameof(Sut.ButtonText),
nameof(Sut.Points), nameof(Sut.HasPoints)
};

// Act

// Assert
Sut.Properties.Should().BeEquivalentTo(expected);
}

[Fact]
public void Ctor_ShouldInitializeWelcomeCarouselItem()
{
// Arrange

// Act

// Assert
Sut.Items[0].Content.Should().Be("Talk to SSW people, attend their talks and scan their QR codes, and complete other fun achievements to earn points.");
Sut.Items[0].Animation.Should().Be("Sophie.json");
Sut.Items[0].SubHeading.Should().Be("Welcome!");
Sut.Items[0].ButtonText.Should().Be("GET STARTED");
Sut.Items[0].IsAnimation.Should().BeTrue();
}

[Fact]
public void Ctor_ShouldInitializeClaimRewardsCarouselItem()
{
// Arrange

// Act

// Assert
Sut.Items[1].Content.Should().Be("Exchange your points at SSW Events or at SSW booths at developer conferences for awesome rewards.");
Sut.Items[1].Image.Should().Be("test_passed");
Sut.Items[1].SubHeading.Should().Be("Claim Rewards");
Sut.Items[1].ButtonText.Should().Be("NEXT");
Sut.Items[1].IsAnimation.Should().BeFalse();
}

[Fact]
public void Ctor_ShouldInitializeGoogleHubMaxCarouselItem()
{
// Arrange

// Act

// Assert
Sut.Items[2].Content.Should().Be("Get on the leaderboard for a chance to win a Google Hub Max.");
Sut.Items[2].Image.Should().Be("prize_hubmax");
Sut.Items[2].SubHeading.Should().Be("Google Nest Hub Max");
Sut.Items[2].ButtonText.Should().Be("NEXT");
Sut.Items[2].IsAnimation.Should().BeFalse();
}

[Fact]
public void Ctor_ShouldInitializeKeepcupCarouselItem()
{
// Arrange

// Act

// Assert
Sut.Items[3].Content.Should().Be("Earn enough points and you could claim a cool SSW Keepcup.");
Sut.Items[3].Image.Should().Be("v2cups");
Sut.Items[3].SubHeading.Should().Be("SSW Keepcup");
Sut.Items[3].ButtonText.Should().Be("NEXT");
Sut.Items[3].HasPoints.Should().BeTrue();
Sut.Items[3].Points.Should().Be(2000);
Sut.Items[3].IsAnimation.Should().BeFalse();
}

[Fact]
public void Ctor_ShouldInitializeMiBandCarouselItem()
{
// Arrange

// Act

// Assert
Sut.Items[4].Content.Should().Be("Get on the leaderboard and earn a Mi Wrist band. Just like a FitBit, except more functionality and a month's battery life!");
Sut.Items[4].Image.Should().Be("v2band");
Sut.Items[4].SubHeading.Should().Be("Mi Band 6");
Sut.Items[4].ButtonText.Should().Be("NEXT");
Sut.Items[4].HasPoints.Should().BeTrue();
Sut.Items[4].Points.Should().Be(6000);
Sut.Items[4].IsAnimation.Should().BeFalse();
}

[Fact]
public void Ctor_ShouldInitializeSpecificationReviewCarouselItem()
{
// Arrange

// Act

// Assert
Sut.Items[5].Content.Should().Be("SSW Architects will help you successfully implement your project.");
Sut.Items[5].Image.Should().Be("v2consultation");
Sut.Items[5].SubHeading.Should().Be("Half Price Specification Review");
Sut.Items[5].ButtonText.Should().Be("DONE");
Sut.Items[5].HasPoints.Should().BeTrue();
Sut.Items[5].Points.Should().Be(3000);
Sut.Items[5].IsAnimation.Should().BeFalse();
}

[Fact]
public void Ctor_ShouldSetSelectedItemToFirst()
{
// Arrange
var expected = Sut.Items.First();

// Act

// Assert
Sut.SelectedItem.Should().Be(expected);
}

[Fact]
public void Ctor_ShouldSetDetailsFromSelectedItem()
{
// Arrange
var selectedItem = Sut.SelectedItem;

// Act

// Assert
Sut.SubHeading.Should().Be(selectedItem.SubHeading);
Sut.Content.Should().Be(selectedItem.Content);
Sut.ButtonText.Should().Be(selectedItem.ButtonText);
Sut.HasPoints.Should().Be(selectedItem.HasPoints);
Sut.Points.Should().Be(selectedItem.Points);
}

#endregion

#region DoActionCommand

[Fact]
public void DoActionCommand_ShouldCallPopModalAsync_WhenIsLastItemTrue()
{
// Arrange
Sut.Navigation = Mocker.GetMock<INavigation>().Object;
Sut.SelectedItem = Sut.Items.Last();

// Act
Sut.DoActionCommand.Execute(null);

// Assert
Mocker.GetMock<INavigation>().Verify(c => c.PopModalAsync());
}

[Fact]
public void DoActionCommand_ShouldRaiseScrollToRequestedEvent_WhenIsLastItemFalse()
{
// Arrange
var nextSelectedIndex = Sut.Items.IndexOf(Sut.SelectedItem) + 1;

// Act
var raisedEvent = Assert.Raises<int>(handler => Sut.ScrollToRequested += handler, handler => Sut.ScrollToRequested -= handler,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason didn't manage to get it working with FluentAssertions 😕 With Assert it works fine, but if anyone knows how to do that via FluentAssertions - please let me know.

() => Sut.DoActionCommand.Execute(null));

// Assert
raisedEvent.Arguments.Should().Be(nextSelectedIndex);
raisedEvent.Sender.Should().Be(Sut);
}

#endregion

#region SwipedCommand

[Fact]
public void SwipedCommand_ShouldSetDetailsFromSelectedItem()
{
// Arrange
var selectedItem = Sut.Items.Last();
Sut.SelectedItem = selectedItem;

// Act
Sut.Swiped.Execute(null);

// Assert
Sut.SubHeading.Should().Be(selectedItem.SubHeading);
Sut.Content.Should().Be(selectedItem.Content);
Sut.ButtonText.Should().Be(selectedItem.ButtonText);
Sut.HasPoints.Should().Be(selectedItem.HasPoints);
Sut.Points.Should().Be(selectedItem.Points);
}

#endregion

#region SkipCommand

[Fact]
public void SkipCommand_ShouldCallPopModalAsync()
{
// Arrange
Sut.Navigation = Mocker.GetMock<INavigation>().Object;

// Act
Sut.Skip.Execute(null);

// Assert
Mocker.GetMock<INavigation>().Verify(c => c.PopModalAsync());
}

#endregion
}
2 changes: 2 additions & 0 deletions tests/SSW.Rewards.UnitTests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
global using Xunit;
global using FluentAssertions;