Skip to content

Fix tests#147

Open
glittle wants to merge 7 commits intomainfrom
fix-tests
Open

Fix tests#147
glittle wants to merge 7 commits intomainfrom
fix-tests

Conversation

@glittle
Copy link
Copy Markdown
Owner

@glittle glittle commented Apr 13, 2026

This pull request introduces several important improvements and refactorings across the backend and integration tests. The most significant changes include a refactor of the Result entity's section code handling to use a strongly-typed enumeration, improvements to test reliability and diagnostics, and consistent updates to API endpoint usage in tests.

Domain Model Improvements

  • Refactored the Result entity to use a new strongly-typed ResultSection enum for the section code, replacing the previous string-based approach. This includes a new ResultSectionEnum helper for code-string conversions and updates to EF Core model configuration to handle enum-string mapping. (Backend.Domain/Entities/Result.cs, Backend.Domain/Enumerations/ResultSection.cs, Backend.Domain/Context/MainDbContext.cs) [1] [2] [3]

Testing Infrastructure Enhancements

  • Changed the integration test database to use an in-memory provider instead of SQLite, ensuring a fresh and isolated database for each test run. Added configuration to prevent automatic migrations and improved diagnostics with additional logging during test setup. (Backend.Tests/IntegrationTests/CustomWebApplicationFactory.cs) [1] [2] [3]

Integration Test Improvements

  • Updated API endpoint calls in tests to match new or renamed controller routes (e.g., /getMyElections, /electionDetails, /results/{electionGuid}/calculate). Also improved test assertions by providing more detailed error messages when HTTP status codes do not match expectations. (Backend.Tests/IntegrationTests/ElectionsControllerTests.cs, Backend.Tests/IntegrationTests/ResultsControllerTests.cs) [1] [2] [3] [4] [5]

  • Added additional logging in test base classes to help diagnose test failures, including logging the client base address and login request/response details. (Backend.Tests/IntegrationTests/IntegrationTestBase.cs) [1] [2]

These changes enhance type safety in the domain model, improve test reliability and diagnostics, and ensure that integration tests accurately reflect the current API surface.

Copilot AI review requested due to automatic review settings April 13, 2026 00:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates both backend and frontend to align with recent API contract changes and to stabilize/repair automated tests, including refactoring “result section” handling from string codes to a strongly-typed enum.

Changes:

  • Backend: replace Result.Section string with ResultSection enum (SectionCode) and update controllers/DTOs/services accordingly.
  • Testing: improve diagnostics and refactor integration test hosting/database setup for better isolation and reliability.
  • Frontend: update generated API types/transformers and adjust services/stores/pages/tests to match new response shapes and routes; add/adjust i18n keys.

Reviewed changes

Copilot reviewed 118 out of 119 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
frontend/src/vite-env.d.ts Adds Vitest global typings.
frontend/src/utils/searchStrategies.ts Tightens TS null-safety and string access.
frontend/src/test/setup.ts Adds i18n instance to test setup exports.
frontend/src/stores/tellerStore.ts Aligns pagination fields with updated response shape.
frontend/src/stores/peopleStore.ts Adds non-null assertion for cache update.
frontend/src/stores/peopleStore.test.ts Updates tests for stricter nullability.
frontend/src/stores/electionStore.ts Broadens election list typing and adjusts update handling.
frontend/src/stores/electionStore.test.ts Updates mocks/DTO fields to match updated API/types.
frontend/src/stores/ballotStore_backup.ts Adjusts vote creation handling in backup store file.
frontend/src/stores/authStore.ts Updates /auth/me handling to match SDK response shape.
frontend/src/stores/authStore.test.ts Updates mocks and register payload expectations.
frontend/src/stores/auditLogStore.ts Aligns pagination fields with updated response shape.
frontend/src/stores/tests/peopleStore.spec.ts Updates tests for stricter nullability.
frontend/src/services/voteService.ts Aligns vote list extraction with SDK response shape.
frontend/src/services/resultService.ts Updates result endpoints (partial) to match backend route changes.
frontend/src/services/peopleService.ts Switches to generated SDK endpoints and adjusts return shapes.
frontend/src/services/electionService.ts Switches to updated elections endpoints and adjusts request/response typing.
frontend/src/services/computerService.ts Aligns computer list extraction with SDK response shape.
frontend/src/services/ballotService.ts Adds statusCode casting and adjusts ballot list extraction.
frontend/src/services/api.ts Adjusts i18n typing usage in interceptor.
frontend/src/pages/voting/VoterBallotPage.vue Renames notification helpers; tightens input typing.
frontend/src/pages/voting/VoterAuthPage.vue Updates public auth config handling and GIS guard.
frontend/src/pages/TellerJoinPage.vue Template/i18n key updates and formatting cleanup.
frontend/src/pages/results/MonitoringDashboardPage.vue Uses window.setInterval for clearer typing.
frontend/src/pages/RegisterPage.vue Adds displayName field to registration UI/payload.
frontend/src/pages/people/PeopleImportPage.vue Avoids unused header variable in v-for.
frontend/src/pages/LoginPage.vue Updates public auth config handling; template formatting and i18n key changes.
frontend/src/pages/GoogleCallbackPage.vue Updates /auth/me handling to match SDK response shape.
frontend/src/pages/frontdesk/FrontDeskPage.vue Simplifies row class helper signature.
frontend/src/pages/elections/ElectionDetailPage.vue Switches teller access toggle call to tellerService.
frontend/src/pages/DashboardPage.vue Casts election type for convenor access under union typing.
frontend/src/pages/ballots/tests/BallotEntryPage.spec.ts Updates test ballot/vote DTOs with additional required fields.
frontend/src/locales/zh/tally.json Updates tally section translation keys.
frontend/src/locales/zh/common.json Adds common.goHome.
frontend/src/locales/vi/tally.json Updates tally section translation keys.
frontend/src/locales/vi/common.json Adds common.goHome.
frontend/src/locales/sw/tally.json Updates tally section translation keys.
frontend/src/locales/sw/common.json Adds common.goHome.
frontend/src/locales/ru/tally.json Updates tally section translation keys.
frontend/src/locales/ru/common.json Adds common.goHome; adjusts common.open.
frontend/src/locales/pt/tally.json Updates tally section translation keys.
frontend/src/locales/pt/common.json Adds common.goHome.
frontend/src/locales/ko/tally.json Updates tally section translation keys.
frontend/src/locales/ko/common.json Adds common.goHome.
frontend/src/locales/hi/tally.json Updates tally section translation keys.
frontend/src/locales/hi/common.json Adds common.goHome.
frontend/src/locales/fr/tally.json Updates tally section translation keys.
frontend/src/locales/fr/common.json Adds common.goHome.
frontend/src/locales/fi/tally.json Updates tally section translation keys.
frontend/src/locales/fi/common.json Adds common.goHome.
frontend/src/locales/fa/tally.json Updates tally section translation keys.
frontend/src/locales/fa/common.json Adds common.goHome.
frontend/src/locales/es/tally.json Updates tally section translation keys.
frontend/src/locales/es/common.json Adds common.goHome.
frontend/src/locales/en/voting.json Adds a new voting ballot label key.
frontend/src/locales/en/tally.json Updates tally section translation keys.
frontend/src/locales/en/common.json Adds common.goHome.
frontend/src/locales/en/ballots.json Adds new ballot UI/help strings.
frontend/src/locales/en/auth.json Adds displayName strings.
frontend/src/locales/ar/tally.json Updates tally section translation keys.
frontend/src/locales/ar/common.json Adds common.goHome.
frontend/src/composables/useApiErrorHandler.ts Adjusts i18n typing usage.
frontend/src/composables/tests/usePersonSearch.spec.ts Updates tests for stricter nullability.
frontend/src/components/version.ts Adjusts i18n typing usage for month name lookup.
frontend/src/components/people/PeopleTable.vue Fixes selection identity to use personGuid; widens checkbox change typing.
frontend/src/components/common/ErrorBoundary.test.ts Fixes router test route record shape; adds non-null assertion.
frontend/src/components/charts/BarChart.vue Adds non-null assertion for color lookup.
frontend/src/components/ballots/VoteFormDialog.vue Aligns candidate typing and removes explicit statusCode from create vote DTO.
frontend/src/components/ballots/InlineBallotEntry.vue Import/order cleanup; fixes translation key used for “names on ballot”; null-safety.
frontend/src/components/ballots/tests/VoteEntryRow.spec.ts Removes VoteEntryRow unit test file.
frontend/src/components/ballots/tests/InlineBallotEntry.spec.ts Updates stubbing strategy and vote DTOs for new required fields.
frontend/src/components/AppHeader.vue Removes unused computed for selected location.
frontend/src/components/AppHeader.test.ts Adds route component stubs and loosens VM typing for direct calls.
frontend/src/api/gen/configService/types.gen.ts Updates generated types (Result section enum and renamed endpoints).
frontend/src/api/gen/configService/transformers.gen.ts Updates generated transformers to match renamed endpoints/types.
frontend/src/api/gen/configService/schemas.gen.ts Updates generated schemas (sectionCode enum, endpoint renames).
frontend/src/api/config.ts Adjusts i18n typing usage in auth redirect handling.
frontend/simple.test.ts Removes placeholder test file.
frontend/package.json Changes tsc script to use project build mode.
frontend/openApi/tallyj.json Updates OpenAPI paths and schema fields to match backend changes.
backend/test-results-api.ps1 Updates parts of manual results API test script for new routes.
backend/Services/TallyService.cs Updates tally/report logic to use ResultSection enum.
backend/Services/TallyJv2ElectionImportService.cs Parses legacy section codes into ResultSection.
backend/Services/ReportService.cs Updates report DTO mapping to SectionCode.
backend/Services/ReportExportService.cs Exports section codes using helper conversion.
backend/Services/PublicService.cs Updates section filtering to enum-based logic.
backend/Services/JsonElectionImportExportService.cs Updates JSON export/import mapping for section handling.
backend/Services/ElectionImportExportBase.cs Updates JSON model to use ResultSection type for section.
backend/Services/Analyzers/ElectionAnalyzerSingleName.cs Uses enum section assignment for generated results.
backend/Services/Analyzers/ElectionAnalyzerNormal.cs Uses enum section assignment for generated results.
backend/Services/Analyzers/ElectionAnalyzerBase.cs Converts tie/section logic to enum comparisons.
backend/Services/AdvancedReportingService.cs Updates filtering to enum section comparisons.
backend/Program.cs Adds additional startup diagnostics and testing MVC configuration.
backend/EF/Data/DbSeeder.cs Updates seeded results to use SectionCode.
backend/DTOs/Results/TieManagementDto.cs Converts tie DTO section to enum.
backend/DTOs/Results/TieInfoDto.cs Converts tie info DTO section to enum.
backend/DTOs/Results/TallyResultDto.cs Converts candidate result DTO section to enum.
backend/DTOs/Results/ReportDto.cs Converts report DTO sections to enum.
backend/DTOs/Results/PresentationDto.cs Converts presentation tie DTO section to enum.
backend/DTOs/Reports/ReportDtos.cs Converts report DTO sections to enum.
backend/Controllers/ResultsController.cs Updates routes and filters to enum-based section handling.
backend/Controllers/ElectionsController.cs Renames routes (getMyElections, electionDetails).
backend/Controllers/AuthController.cs Adds controller instantiation console output.
Backend.Tests/UnitTests/TallyServiceTests.cs Updates unit tests for enum section handling and vote setup changes.
Backend.Tests/UnitTests/ReportServiceTests.cs Updates unit tests for enum section handling and helper signatures.
Backend.Tests/UnitTests/ReportExportServiceTests.cs Updates unit tests to use enum section fields.
Backend.Tests/UnitTests/ElectionAnalyzerSingleNameTests.cs Updates assertions to enum section fields.
Backend.Tests/UnitTests/ElectionAnalyzerNormalTests.cs Updates assertions to enum section fields.
Backend.Tests/IntegrationTests/VoterAuthenticationFlowTests.cs Improves diagnostics on failures and asserts expected statuses.
Backend.Tests/IntegrationTests/ResultsControllerTests.cs Updates routes and improves failure diagnostics.
Backend.Tests/IntegrationTests/IntegrationTestBase.cs Adds extra diagnostic logging for login/client setup.
Backend.Tests/IntegrationTests/ElectionsControllerTests.cs Updates routes and improves failure diagnostics.
Backend.Tests/IntegrationTests/CustomWebApplicationFactory.cs Switches integration DB to EF InMemory and disables migrations/seeding.
Backend.Tests/IntegrationTests/AuthWorkflowIntegrationTests.cs Updates protected endpoint route usage.
Backend.Domain/Enumerations/ResultSection.cs Adds ResultSection enum + helper conversion utilities.
Backend.Domain/Entities/Result.cs Replaces section string with enum SectionCode mapped to Section column.
Backend.Domain/Context/MainDbContext.cs Adds enum-string conversion for Result.SectionCode in EF model config.
Comments suppressed due to low confidence (1)

frontend/src/pages/elections/ElectionDetailPage.vue:129

  • After toggling teller access, the local election state isn’t updated (and the store’s SignalR update handler doesn’t update isTellerAccessOpen). This means the UI can remain stale and subsequent toggles may keep sending the same newState. Update the store/current election state (or refetch election details) after a successful toggleTellerAccess call.

Comment thread frontend/src/services/resultService.ts Outdated
Comment on lines 78 to 82
async getTieDetails(electionGuid: string): Promise<TieDetailsDto[]> {
const response = await api.get<TieDetailsDto[]>(
`/api/results/election/${electionGuid}/ties`,
`/api/results/${electionGuid}/ties`,
);
return response.data;
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

getTieDetails calls /api/results/${electionGuid}/ties, but the backend expects GET /api/Results/{electionGuid}/{tieBreakGroup}/ties (tieBreakGroup is required). Either change this method signature to accept tieBreakGroup and hit the correct route, or remove it and use the ties list returned by getResults plus a dedicated call for details.

Copilot uses AI. Check for mistakes.
Comment on lines 43 to +47
async getByLocation(locationGuid: string): Promise<BallotDto[]> {
const response = await getApiBallotsByElectionGuidBallots({
path: { electionGuid: locationGuid },
});
return (response.data?.data?.items ?? []) as BallotDto[];
return (response.data?.items ?? []) as BallotDto[];
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

getByLocation passes locationGuid into the API path parameter named electionGuid, so this will query the wrong resource and likely 404/return incorrect ballots. If you need ballots by location, use the correct endpoint (or change this method to accept both electionGuid and locationGuid and call the location-specific API).

Copilot uses AI. Check for mistakes.
Comment on lines 45 to 50
# Step 4: Get Results
Write-Host "=== Step 4: GET /api/results/election/$electionGuid ===" -ForegroundColor Cyan
Write-Host "=== Step 4: GET /api/results/$electionGuid ===" -ForegroundColor Cyan
try {
$results = Invoke-RestMethod -Uri "$baseUrl/api/results/election/$electionGuid" -Method Get -Headers $headers
$results = Invoke-RestMethod -Uri "$baseUrl/api/results/$electionGuid" -Method Get -Headers $headers
Write-Host "✓ Get results successful" -ForegroundColor Green
Write-Host "Candidates in results: $($results.results.Count)" -ForegroundColor Gray
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

This script still uses stale Results API routes and response fields. GET /api/results/$electionGuid no longer exists (it should be /api/results/$electionGuid/results), and results now expose sectionCode (enum strings) rather than section codes. Update the endpoints/field names so the script actually exercises the current API.

Copilot uses AI. Check for mistakes.
Comment thread backend/Program.cs Outdated

Log.Information("Starting up in {SiteType} mode ({SiteMode}) on machine {MachineName}", siteType, siteMode, machineName);
Log.Information("isTesting: {IsTesting}, isDevelopment: {IsDevelopment}", isTesting, isDevelopment);
Log.Information("Assemblies loaded: {Assemblies}", string.Join(", ", AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetName().Name)));
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

Logging the full list of loaded assemblies on every startup (Assemblies loaded: ...) can create very large log entries and adds noise in production. Consider gating this behind isDevelopment/isTesting or lowering the level (e.g., Debug) to avoid operational log volume issues.

Suggested change
Log.Information("Assemblies loaded: {Assemblies}", string.Join(", ", AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetName().Name)));
if (isDevelopment || isTesting)
{
Log.Debug("Assemblies loaded: {Assemblies}", string.Join(", ", AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetName().Name)));
}

Copilot uses AI. Check for mistakes.
using Backend.EF.Data;
using Backend.Application.Services.Auth;
using MimeKit;
using Microsoft.AspNetCore.Builder;
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

Microsoft.AspNetCore.Builder is imported but not used, which will generate an IDE/compiler warning. Remove the unused using to keep the test project clean (and avoid warnings-as-errors issues).

Suggested change
using Microsoft.AspNetCore.Builder;

Copilot uses AI. Check for mistakes.
Comment on lines 4 to 7
"auth.logout": "Logout",
"auth.displayName": "Display Name",
"auth.displayNamePlaceholder": "Enter your display name",
"auth.email": "Email",
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

New translation keys were added here, but they only exist in en. The repo’s locale validation enforces key parity across locales, so builds/tests will fail until auth.displayName and auth.displayNamePlaceholder are added to the other locale files (even if temporarily copied from English).

Copilot uses AI. Check for mistakes.
Comment on lines 150 to 154
"voting.ballot.notOpen": "Online voting is not currently open for this election.",
"voting.ballot.duplicateError": "You have selected the same candidate multiple times. Please review your ballot.",
"voting.ballot.electionNotFound": "Election not found",
"voting.ballot.namesOnBallot": "Names on the Ballot",
"voting.ballot.submit": "Submit Ballot",
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

voting.ballot.namesOnBallot was added only in en. If validate:i18n is enabled, this will fail until the same key is added to all other locales (or the UI uses an existing key shared across locales).

Copilot uses AI. Check for mistakes.
Comment on lines 3 to 40
@@ -32,6 +33,10 @@
"ballots.positionRequired": "Position is required",
"ballots.saveBallot": "Save Ballot",
"ballots.saveError": "Failed to save ballot",
"ballots.saveSuccess": "Ballot saved successfully",
"ballots.searchPerson": "Search for a person...",
"ballots.searchPlaceholder": "Search for a person...",
"ballots.searchHelp": "Use ↑ ↓ keys to move in the list. Press Enter to add.",
"ballots.status": "Status",
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

Several new ballot-related translation keys were added only in en (e.g., ballots.ballotNum, ballots.saveSuccess, ballots.searchPerson, ballots.searchPlaceholder, ballots.searchHelp). Locale validation will fail until these keys are added to the other locales as well.

Copilot uses AI. Check for mistakes.
Comment on lines 113 to 121
if (currentBallot.value?.ballotGuid === dto.ballotGuid) {
currentBallot.value.votes.push(vote);
currentBallot.value.votes.push(vote.vote);
currentBallot.value.voteCount = currentBallot.value.votes.length;
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

This file appears to be a backup/duplicate store implementation (*_backup.ts) but is still committed and being modified. Keeping backup code in src/ increases maintenance burden and risks accidental imports. Consider deleting it, moving it outside src/, or adding a clear comment + ensuring it’s excluded from builds.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 205 out of 206 changed files in this pull request and generated 5 comments.

Comment on lines 92 to 96
async getTieDetails(electionGuid: string): Promise<TieDetailsDto[]> {
const response = await api.get<TieDetailsDto[]>(
`/api/results/election/${electionGuid}/ties`,
`/api/results/${electionGuid}/ties`,
);
return response.data;
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

getTieDetails() is using a hard-coded axios route and a response type that doesn’t match the API. The backend route is GET /api/results/{electionGuid}/{tieBreakGroup}/ties and returns a single TieDetailsDto, not an array. Update this method to accept tieBreakGroup, call the generated SDK endpoint (getApiResultsByElectionGuidByTieBreakGroupTies), and return the correct type.

Copilot uses AI. Check for mistakes.
Comment on lines 2 to 6
"ballots.addBallot": "Add Ballot",
"ballots.addNewPerson": "Add New Person",
"ballots.addVote": "Add Vote",
"ballots.ballotNum": "Ballot #{code}",
"ballots.cacheLoadError": "Failed to load candidates",
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

New translation keys were added here (e.g. ballots.ballotNum, ballots.saveSuccess, ballots.searchHelp, etc.) but they don’t exist in the other locale ballots.json files (es/fr/…); validate:i18n will fail due to missing keys. Add these keys to every locale (even if untranslated) or avoid introducing new keys until all locales are updated.

Copilot uses AI. Check for mistakes.
Comment thread backend/Program.cs
Comment on lines 38 to +54
@@ -53,6 +51,7 @@ void AddLogging(WebApplicationBuilder builder)

void ConfigureServices(WebApplicationBuilder builder)
{
Log.Information("ConfigureServices called");
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

These Log.Information(...) statements were added unconditionally to startup and will increase noise in production logs (and may leak environment details like isTesting). Consider gating them behind isDevelopment/isTesting, lowering to Debug, or removing after diagnosing the test discovery issue.

Copilot uses AI. Check for mistakes.
entity.Property(e => e.SectionCode)
.HasConversion(
v => ResultSectionEnum.ToCodeString(v),
v => ResultSectionEnum.ParseCode(v) ?? ResultSection.Other)
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

EF mapping for Result.SectionCode sets a conversion and IsFixedLength(), but doesn’t explicitly set the max length to 1. Since SectionCode is now an enum, the [StringLength(1)] attribute on the entity property may not be applied the way it was for a string, which can lead to schema drift in migrations. Consider adding .HasMaxLength(1) (and/or moving length config fully into Fluent API).

Suggested change
v => ResultSectionEnum.ParseCode(v) ?? ResultSection.Other)
v => ResultSectionEnum.ParseCode(v) ?? ResultSection.Other)
.HasMaxLength(1)

Copilot uses AI. Check for mistakes.
Comment on lines +849 to 851
// Is this used for tests??
private async Task CreateVotesWithTieWithinExtraSectionAsync(List<Ballot> ballots, List<Person> people)
{
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

This inline comment (// Is this used for tests??) reads like a temporary note and doesn’t add actionable documentation. Please remove it or replace it with a concrete explanation of why the helper exists and which test cases rely on it.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants