Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const categoriesFilterableColumns: AdministrationGridColDef[] = [
categoryId: params.row.id,
categoryName: params.row.name,
})}
text={params.value.toString()}
text={params.value?.toString()}
/>
,
},
Expand Down Expand Up @@ -100,7 +100,7 @@ const categoriesFilterableColumns: AdministrationGridColDef[] = [
categoryId: params.row.parentId,
categoryName: params.row.parent,
})}
text={params.value.toString()}
text={params.value?.toString()}
/>
,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const contestFilterableColumns: AdministrationGridColDef[] = [
contestId: params.row.id,
contestName: params.row.name,
})}
text={params.value.toString()}
text={params.value?.toString()}
/>
,
},
Expand All @@ -73,7 +73,7 @@ const contestFilterableColumns: AdministrationGridColDef[] = [
contestId: params.row.id,
contestName: params.row.name,
})}
text={params.value.toString()}
text={params.value?.toString()}
/>
,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const examGroupsFilterableColumns: AdministrationGridColDef[] = [
contestId: params.row.contestId,
contestName: params.row.contestName,
})}
text={params.value.toString()}
text={params.value?.toString()}
/>
,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const participantsFilteringColumns: AdministrationGridColDef[] = [
contestId: params.row.contestId,
contestName: params.row.contestName,
})}
text={params.value.toString()}
text={params.value?.toString()}
/>
,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const problemFilterableColumns: AdministrationGridColDef[] = [
contestId: params.row.contestId,
contestName: params.row.contest,
})}
text={params.value.toString()}
text={params.value?.toString()}
/>
,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ namespace OJS.Workers.ExecutionStrategies.Models
public class JsonExecutionResult
{
private const string InvalidJsonReplace = "]}[},!^@,Invalid,!^@,{]{[";
private const string MissingJsonStructureError = "Invalid console output! Please make sure there are no console.log statements in the solution. The system expects JSON output from Mocha test results.";
private const string MissingPassingFieldError = "Invalid console output! Please make sure there are no console.log statements in the solution. Missing or invalid 'passing' array in test results.";
private const string MissingFailuresFieldError = "Invalid console output! Please make sure there are no console.log statements in the solution. Missing or invalid 'failures' array with 'err.message' fields.";

public IList<string> TestErrors { get; set; }

Expand Down Expand Up @@ -68,7 +71,7 @@ public static JsonExecutionResult Parse(string result, bool forceErrorExtracting
}
catch
{
error = "Invalid console output!";
error = MissingJsonStructureError;
}

var testsIndexes = new List<int>();
Expand All @@ -80,7 +83,7 @@ public static JsonExecutionResult Parse(string result, bool forceErrorExtracting
}
catch
{
error = "Invalid console output!";
error = MissingPassingFieldError;
}
}

Expand All @@ -97,7 +100,7 @@ public static JsonExecutionResult Parse(string result, bool forceErrorExtracting
}
catch
{
error = "Invalid console output!";
error = MissingFailuresFieldError;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,18 @@ protected override async Task<IExecutionResult<TestResult>> ExecuteAgainstTestsI
protected static string FormatTests(IEnumerable<TestContext> tests, bool isTypeScript)
{
var formattedTests = new List<string>();
var testCounter = 1;

foreach (var test in tests)
{
// Use simple sequential test names
var testName = $"Test{testCounter}";
var testContent = test.Input.Trim();

// Format the test with proper it() wrapper
var formattedTest = $@"
{(isTypeScript ? "// @ts-ignore" : "")}
it('{testName}', function () {{
{testContent}
}})";
{testContent}";

formattedTests.Add(formattedTest);
testCounter++;
}

// Join all formatted tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@ protected override async Task<IExecutionResult<TestResult>> ExecuteAgainstTestsI
{
SaveZipSubmission(executionContext.FileContent, this.WorkingDirectory);

var esBuildExecutionArguments = new[]
{
"src/index.ts",
"--bundle",
"--platform=node",
"--format=cjs",
"--target=node21",
"--packages=external",
"--drop:console",
"--outfile=dist/app.bundle.js"
};

var executor = this.CreateStandardExecutor();
var bundleResult = await executor.Execute(
this.Settings.EsBuildModulePath,
executionContext.TimeLimit,
executionContext.MemoryLimit,
executionArguments: ["src/index.ts", "--bundle", "--platform=node", "--format=cjs", "--target=node21", "--packages=external", "--outfile=dist/app.bundle.js"],
executionArguments: esBuildExecutionArguments,
workingDirectory: this.WorkingDirectory,
cancellationToken: cancellationToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace OJS.Services.Ui.Business.Implementations;
using OJS.Services.Infrastructure.Constants;
using OJS.Services.Infrastructure.Extensions;
using OJS.Services.Infrastructure.Models;
using OJS.Services.Infrastructure;
using OJS.Services.Ui.Business.Cache;
using OJS.Services.Ui.Business.Validations.Implementations.Contests;
using OJS.Services.Ui.Data;
Expand All @@ -34,7 +35,8 @@ public class ContestsBusinessService(
IContestParticipantsCacheService contestParticipantsCacheService,
IContestsCacheService contestsCacheService,
ILecturersInContestsCacheService lecturersInContestsCache,
IContestDetailsValidationService contestDetailsValidationService)
IContestDetailsValidationService contestDetailsValidationService,
IDatesService datesService)
: IContestsBusinessService
{
public async Task<ServiceResult<ContestDetailsServiceModel>> GetContestDetails(int id)
Expand Down Expand Up @@ -328,6 +330,8 @@ public async Task<ContestSearchServiceResultModel> GetSearchContestsByName(
.MapCollection<ContestForListingServiceModel>()
.ToPagedListAsync(model.PageNumber, model.ItemsPerPage);

this.SetContestVisibility(searchContests);

modelResult.Contests = searchContests;
modelResult.TotalContestsCount = allContestsQueryable.Count();

Expand All @@ -344,6 +348,8 @@ public async Task<PagedResult<ContestForListingServiceModel>> GetAllByFiltersAnd
var pagedContests =
await contestsData.GetAllAsPageByFiltersAndSorting<ContestForListingServiceModel>(model, includeHidden);

this.SetContestVisibility(pagedContests.Items);

var participantResultsByContest = new Dictionary<int, List<ParticipantResultServiceModel>>();
if (user.IsAuthenticated)
{
Expand Down Expand Up @@ -390,6 +396,8 @@ public async Task<PagedResult<ContestForListingServiceModel>> GetParticipatedByU
participatedContests,
sortAndFilterModel);

this.SetContestVisibility(participatedContestsInPage.Items);

var participantResultsByContest = new Dictionary<int, List<ParticipantResultServiceModel>>();
var loggedInUser = userProviderService.GetCurrentUser();

Expand Down Expand Up @@ -499,10 +507,16 @@ await pagedContests.Items.ForEachAsync(c =>
.ToListAsync();

public async Task<IEnumerable<ContestForListingServiceModel>> GetAllParticipatedContests(string username)
=> await contestsData
.GetLatestForParticipantByUsername(username)
.MapCollection<ContestForListingServiceModel>()
.ToListAsync();
{
var contests = await contestsData
.GetLatestForParticipantByUsername(username)
.MapCollection<ContestForListingServiceModel>()
.ToListAsync();

this.SetContestVisibility(contests);

return contests;
}

private static async Task<Dictionary<int, List<ParticipantResultServiceModel>>> MapParticipationResultsToContestsInPage(
IQueryable<Participant> participants)
Expand Down Expand Up @@ -565,4 +579,13 @@ private async Task<ContestFiltersServiceModel> GetNestedFilterCategoriesIfAny(Co
official,
isUserAdminOrLecturerInContest);
}

private void SetContestVisibility(IEnumerable<ContestForListingServiceModel> contests)
{
var now = datesService.GetUtcNow();
foreach (var contest in contests)
{
contest.IsVisible = contest.IsVisible || contest.VisibleFrom <= now;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ public void RegisterMappings(IProfileExpression configuration)
.SelectMany(pg => pg.Problems)
.Where(x => !x.IsDeleted)
.Sum(pr => pr.MaximumPoints)))
.ForMember(
c => c.IsVisible,
opt => opt.MapFrom(s => s.IsVisible || s.VisibleFrom <= DateTime.UtcNow))
// For online contests:
// In a problem group with multiple problems, compete points are derived from a single problem,
// unlike practice mode where points can be accumulated from all problems across groups.
Expand Down
Loading