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

Next release #19

Merged
merged 19 commits into from
Apr 2, 2024
Merged
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
29 changes: 21 additions & 8 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true

# C# files
[*.cs]
[*]
indent_style = space

[*.css]
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

#### Core EditorConfig Options ####
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj,props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct,json}]
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

# Indentation and spacing
[*.{razor,cshtml,html}]
charset = utf-8-bom
indent_size = 4
indent_style = space
tab_width = 4
end_of_line = crlf
insert_final_newline = true
trim_trailing_whitespace = true

# New line preferences
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
end_of_line = crlf
insert_final_newline = false
insert_final_newline = true
trim_trailing_whitespace = true

#### .NET Coding Conventions ####

Expand Down
32 changes: 32 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: Bug report
about: Report a bug
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Platform**
- Device: [e.g. Pixel 8]
- OS Version: [e.g. Android 14]
- JournalApp Version [e.g. v7.0.43]

**Additional context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest a new feature
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear description of what you want to happen.

**Describe alternatives you've considered**
Any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
<TargetPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.19041.0</TargetPlatformVersion>
</PropertyGroup>

</Project>
</Project>
130 changes: 128 additions & 2 deletions JournalApp.Tests/CalendarTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,133 @@
namespace JournalApp.Tests;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;

public class CalendarTests
namespace JournalApp.Tests;

public class CalendarTests : JaTestContext
{
public override async Task InitializeAsync()
{
await base.InitializeAsync();

AddDbContext();

var dbf = Services.GetService<IDbContextFactory<AppDbContext>>();
var appDbSeeder = new AppDbSeeder(new NullLogger<AppDbSeeder>(), dbf);

var dates = new DateOnly(2023, 01, 01).DatesTo(new(2024, 01, 01));
appDbSeeder.SeedDays(dates);
}

[Fact]
public void SwitchYear()
{
var cut = RenderComponent<CalendarPage>(p =>
p.Add(x => x.OpenToDateString, "20000101")
);

cut.WaitForAssertion(() => cut.Find(".calendar-view"));

// Back.
var year = cut.Instance.SelectedYear;
cut.Find(".switcher .previous-button").Click();
cut.Instance.SelectedYear.Should().Be(year - 1);

// Next.
year = cut.Instance.SelectedYear;
cut.Find(".switcher .next-button").Click();
cut.Instance.SelectedYear.Should().Be(year + 1);

// Current.
cut.Instance.SelectedYear.Should().NotBe(DateTime.Now.Year);
cut.Find(".year-button").Click();
cut.Instance.SelectedYear.Should().Be(DateTime.Now.Year);

// Can't go further.
year = cut.Instance.SelectedYear;
cut.Find(".switcher .next-button").HasAttribute("disabled").Should().BeTrue();
cut.Find(".switcher .next-button").Click();
cut.Instance.SelectedYear.Should().Be(year);
}

[Fact]
public async Task CalendarViewMoodBlockCount()
{
var cut = RenderComponent<CalendarPage>(p =>
p.Add(x => x.OpenToDateString, "20230101")
);
cut.Instance.SelectedYear.Should().Be(2023);

// Wait for calendar to load.
cut.WaitForAssertion(() => cut.Find(".calendar-view"));
cut.FindAll(".calendar-month").Count.Should().Be(12);

var db = Services.GetService<AppDbContext>();
var calendarService = Services.GetService<CalendarService>();
var gridYear = await calendarService.CreateGridYear(cut.Instance.SelectedYear);
var filledDays = gridYear.GridMonths.Sum(m => m.GridDays.Count(d => d.Emoji != null)); // Random seeding skips some days and grid days include offsets.

// 2023, fully filled out leap year.
cut.FindAll(".calendar-view .mood-block-container > .mood-block-filled").Count.Should().Be(filledDays);

cut.Find(".switcher .previous-button").Click();
cut.Instance.SelectedYear.Should().Be(2022);

// 2022, none filled.
cut.FindAll(".calendar-view .mood-block-container > .mood-block-filled").Count.Should().Be(0);
}

[Fact(Skip = "Stub")]
public async Task CannotSeeIntoFuture() { }

[Fact]
public void CalendarViewRespectsFirstDay()
{
var _culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
_culture.DateTimeFormat.FirstDayOfWeek = DayOfWeek.Wednesday;
Thread.CurrentThread.CurrentCulture = _culture;

var cut = RenderComponent<CalendarPage>(p =>
p.Add(x => x.OpenToDateString, "20230101")
);
cut.Instance.SelectedYear.Should().Be(2023);

// Wait for calendar to load.
cut.WaitForAssertion(() => cut.Find(".calendar-view"));

var weekHeaders = cut.FindAll(".mood-blocks-week > .mood-block-container");
weekHeaders[0].TextContent.Should().Be("We");
weekHeaders[1].TextContent.Should().Be("Th");
weekHeaders[2].TextContent.Should().Be("Fr");
weekHeaders[3].TextContent.Should().Be("Sa");
weekHeaders[4].TextContent.Should().Be("Su");
weekHeaders[5].TextContent.Should().Be("Mo");
weekHeaders[6].TextContent.Should().Be("Tu");
}

[Fact(Skip = "Can't find dialog")]
public void ChangePalette()
{
var cut = RenderComponent<CalendarPage>(p =>
p.Add(x => x.OpenToDateString, "20230101")
);

var preferenceService = Services.GetService<PreferenceService>();
var initialColor = preferenceService.PrimaryColor;

cut.Find(".pick-palette").Click();

// Click a color.
var overlay = cut.WaitForElement(".color-picker .mud-dialog-content .mud-picker-color-overlay-black .mud-picker-color-overlay");
overlay.Click(new MouseEventArgs { OffsetX = 235, OffsetY = 18 });

// Close dialog.
cut.Find(".mud-dialog-container .mud-overlay-dialog").Click();
cut.FindAll(".mud-overlay-dialog").Count.Should().Be(0);

// Color should have changed.
preferenceService.PrimaryColor.Should().NotBe(initialColor);
}

[Fact]
[Description("Are the number of years, and months in the grid correct?")]
public void YearsAndMonths()
Expand Down
49 changes: 49 additions & 0 deletions JournalApp.Tests/Data/InMemoryPreferences.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
namespace JournalApp.Tests.Data;

public sealed class InMemoryPreferences : IPreferences
{
private readonly Dictionary<string, object> Dict = [];

public void Clear(string sharedName = null)
{
if (sharedName != null)
throw new NotImplementedException();

Dict.Clear();
}

public bool ContainsKey(string key, string sharedName = null)
{
if (sharedName != null)
throw new NotImplementedException();

return Dict.ContainsKey(key);
}

public T Get<T>(string key, T defaultValue, string sharedName = null)
{
if (sharedName != null)
throw new NotImplementedException();

if (Dict.TryGetValue(key, out var value))
return (T)value;

return defaultValue;
}

public void Remove(string key, string sharedName = null)
{
if (sharedName != null)
throw new NotImplementedException();

Dict.Remove(key);
}

public void Set<T>(string key, T value, string sharedName = null)
{
if (sharedName != null)
throw new NotImplementedException();

Dict[key] = value;
}
}
Loading