Skip to content

Commit 19c6fc1

Browse files
Naragoddependabot[bot]david-yz-liudonny-wongMateo
authored
V2.9.6 (#7902)
* build(deps): bump loofah from 2.25.0 to 2.25.1 (#7870) Bumps [loofah](https://github.com/flavorjones/loofah) from 2.25.0 to 2.25.1. - [Release notes](https://github.com/flavorjones/loofah/releases) - [Changelog](https://github.com/flavorjones/loofah/blob/main/CHANGELOG.md) - [Commits](flavorjones/loofah@v2.25.0...v2.25.1) --- updated-dependencies: - dependency-name: loofah dependency-version: 2.25.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Improved assignment list loading time (#7868) * build(deps): bump picomatch (#7879) Bumps and [picomatch](https://github.com/micromatch/picomatch). These dependencies needed to be updated together. Updates `picomatch` from 2.3.1 to 2.3.2 - [Release notes](https://github.com/micromatch/picomatch/releases) - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md) - [Commits](micromatch/picomatch@2.3.1...2.3.2) Updates `picomatch` from 4.0.3 to 4.0.4 - [Release notes](https://github.com/micromatch/picomatch/releases) - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md) - [Commits](micromatch/picomatch@2.3.1...2.3.2) --- updated-dependencies: - dependency-name: picomatch dependency-version: 2.3.2 dependency-type: indirect - dependency-name: picomatch dependency-version: 4.0.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump json from 2.18.1 to 2.19.2 (#7871) Bumps [json](https://github.com/ruby/json) from 2.18.1 to 2.19.2. - [Release notes](https://github.com/ruby/json/releases) - [Changelog](https://github.com/ruby/json/blob/master/CHANGES.md) - [Commits](ruby/json@v2.18.1...v2.19.2) --- updated-dependencies: - dependency-name: json dependency-version: 2.19.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Modified LTI roster sync to update info for existing users (#7865) * Fix localization error in batch test run table for in-progress runs (#7869) Co-authored-by: Mateo <mateo@cs.toronto.edu> * Fixed Assignment Summary table filtering (#7880) Fixes #7822 * Improved assignment summary loading time (#7899) * v2.9.6 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: David Liu <david@cs.toronto.edu> Co-authored-by: donny-wong <141858744+donny-wong@users.noreply.github.com> Co-authored-by: Mateo <mateo@cs.toronto.edu> Co-authored-by: Karl-A. Michaud <karl.michaud@mail.utoronto.ca> Co-authored-by: Donny Wong <donnywong@cs.toronto.edu>
1 parent f47d2da commit 19c6fc1

14 files changed

Lines changed: 398 additions & 120 deletions

File tree

Changelog.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@
1212

1313
### 🔧 Internal changes
1414

15+
## [v2.9.6]
16+
17+
### ✨ New features and improvements
18+
- Improve assignment list loading time (#7868)
19+
- Update user info during roster sync (#7865)
20+
- Improve assignment summary loading time (#7899)
21+
22+
### 🐛 Bug fixes
23+
- Fixed missing translation for "in progress" status on the batch test runs table by removing redundant double-translation of the status value (#7869)
24+
- Fixed search box in the grades view being unresponsive to user input (#7880)
25+
- Fixed searching by grader name in the grades view crashing due to calling `.toLowerCase()` on an array (#7880)
26+
1527
## [v2.9.5]
1628

1729
### 🛡️ Security

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ GEM
234234
railties (>= 3.1)
235235
jsbundling-rails (1.3.1)
236236
railties (>= 6.0.0)
237-
json (2.16.0)
237+
json (2.19.2)
238238
jwt (2.10.1)
239239
base64
240240
kgio (2.11.4)
@@ -243,7 +243,7 @@ GEM
243243
rb-fsevent (~> 0.10, >= 0.10.3)
244244
rb-inotify (~> 0.9, >= 0.9.10)
245245
logger (1.7.0)
246-
loofah (2.24.1)
246+
loofah (2.25.1)
247247
crass (~> 1.0.2)
248248
nokogiri (>= 1.12.0)
249249
machinist (2.0)

app/MARKUS_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION=v2.9.5,PATCH_LEVEL=DEV
1+
VERSION=v2.9.6,PATCH_LEVEL=DEV

app/helpers/lti_helper.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
require 'net/http'
22
module LtiHelper
3+
USER_SYNC_ATTRIBUTES = %i[first_name last_name email id_number].freeze
4+
35
# Synchronize LMS user with MarkUs users.
46
# if role is not nil, attempt to create users
57
# based on the values of can_create_users and
@@ -62,13 +64,19 @@ def roster_sync(lti_deployment, role_types, can_create_users: false, can_create_
6264
markus_user = EndUser.find_by(user_name: lms_user[:user_name])
6365
if markus_user.nil? && can_create_users
6466
markus_user = EndUser.create(lms_user.except(:lti_user_id, :roles))
65-
if markus_user.nil?
67+
unless markus_user.persisted?
6668
error = true
6769
next
6870
end
6971
elsif markus_user.nil? && !can_create_users
7072
error = true
7173
next
74+
else
75+
user_attributes = {}
76+
USER_SYNC_ATTRIBUTES.each do |attr|
77+
user_attributes[attr] = lms_user[attr] if lms_user[attr].present?
78+
end
79+
markus_user.update!(user_attributes) unless user_attributes.empty?
7280
end
7381
course_role = Role.find_by(user: markus_user, course: course)
7482
if course_role.nil? && can_create_roles
@@ -85,6 +93,10 @@ def roster_sync(lti_deployment, role_types, can_create_users: false, can_create_
8593
lti_user = LtiUser.find_or_initialize_by(user: markus_user, lti_client: lti_deployment.lti_client)
8694
lti_user.update!(lti_user_id: lms_user[:lti_user_id])
8795
processed_lti_ids << lms_user[:lti_user_id]
96+
rescue ActiveRecord::RecordInvalid => e
97+
Rails.logger.error I18n.t('lti.sync_failed_log', user: lms_user[:user_name], message: e.message)
98+
error = true
99+
next
88100
end
89101

90102
# Handle inactive and missing students

app/javascript/Components/__tests__/assignment_summary.test.jsx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import {AssignmentSummaryTable} from "../assignment_summary_table";
66
import {render, screen, fireEvent, waitFor, act} from "@testing-library/react";
77
import {expect} from "@jest/globals";
8+
import {defaultSearchPlaceholderText} from "../table/search_filter";
89

910
describe("For the AssignmentSummaryTable's display of inactive groups", () => {
1011
let groups_sample;
@@ -173,6 +174,90 @@ describe("For the AssignmentSummaryTable's display of an assignment without auto
173174
});
174175
});
175176

177+
describe("For the AssignmentSummaryTable's search filter", () => {
178+
beforeEach(async () => {
179+
fetch.mockReset();
180+
fetch.mockResolvedValueOnce({
181+
ok: true,
182+
json: jest.fn().mockResolvedValueOnce({
183+
data: [
184+
{
185+
group_name: "group_0001",
186+
section: null,
187+
members: [["c8debuss", "Debussy", "Claude", false]],
188+
tags: [],
189+
graders: [["c9varoqu", "Nelle", "Varoquaux"]],
190+
marking_state: "complete",
191+
final_grade: 9.0,
192+
criteria: {},
193+
max_mark: "21.0",
194+
result_id: 1,
195+
submission_id: 1,
196+
total_extra_marks: null,
197+
},
198+
{
199+
group_name: "group_0002",
200+
section: null,
201+
members: [["c8holstg", "Holst", "Gustav", false]],
202+
tags: [],
203+
graders: [["c9varoqu", "Nelle", "Varoquaux"]],
204+
marking_state: "complete",
205+
final_grade: 6.0,
206+
criteria: {},
207+
max_mark: "21.0",
208+
result_id: 2,
209+
submission_id: 2,
210+
total_extra_marks: null,
211+
},
212+
],
213+
criteriaColumns: [],
214+
numAssigned: 2,
215+
numMarked: 2,
216+
ltiDeployments: [],
217+
}),
218+
});
219+
220+
await act(async () => {
221+
render(
222+
<AssignmentSummaryTable
223+
assignment_id={1}
224+
course_id={1}
225+
is_instructor={false}
226+
lti_deployments={[]}
227+
/>
228+
);
229+
});
230+
await screen.findByText("group_0001", {exact: false});
231+
});
232+
233+
it("filters rows as the user types in the search box", () => {
234+
fireEvent.change(screen.getAllByPlaceholderText(defaultSearchPlaceholderText())[0], {
235+
target: {value: "0001"},
236+
});
237+
238+
expect(screen.queryByText(/group_0001/)).toBeInTheDocument();
239+
expect(screen.queryByText(/group_0002/)).not.toBeInTheDocument();
240+
});
241+
242+
it("restores all rows when the search query is cleared", () => {
243+
const searchInput = screen.getAllByPlaceholderText(defaultSearchPlaceholderText())[0];
244+
fireEvent.change(searchInput, {target: {value: "0001"}});
245+
fireEvent.change(searchInput, {target: {value: ""}});
246+
247+
expect(screen.queryByText(/group_0001/)).toBeInTheDocument();
248+
expect(screen.queryByText(/group_0002/)).toBeInTheDocument();
249+
});
250+
251+
it("shows no rows when the search query matches nothing", () => {
252+
fireEvent.change(screen.getAllByPlaceholderText(defaultSearchPlaceholderText())[0], {
253+
target: {value: "zzznomatch"},
254+
});
255+
256+
expect(screen.queryByText(/group_0001/)).not.toBeInTheDocument();
257+
expect(screen.queryByText(/group_0002/)).not.toBeInTheDocument();
258+
});
259+
});
260+
176261
describe("For the AssignmentSummaryTable's subcomponent behavior", () => {
177262
let groups_sample;
178263
beforeEach(async () => {

app/javascript/Components/__tests__/test_run_table.test.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ describe("For the TestRunTable's display of in_progress status", () => {
232232
});
233233

234234
it("displays in progress status when a test is running", async () => {
235-
const status = test_run_data[0]["test_runs.status"]; // "in progress"
235+
const status = test_run_data[0]["test_runs.status"]; // "in_progress"
236236
const statusKey = I18n.t(`automated_tests.test_runs_statuses.${status}`);
237237

238238
expect(statusKey).toEqual(I18n.t("automated_tests.test_runs_statuses.in_progress"));

app/javascript/Components/assignment_summary_table.jsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ export class AssignmentSummaryTable extends React.Component {
8282
}
8383

8484
// Check grader user names
85-
return row.original.graders.some(grader => grader.toLowerCase().includes(filterValue));
85+
return row.original.graders.some(grader =>
86+
grader.some(name => name.toLowerCase().includes(filterValue))
87+
);
8688
} else {
8789
return true;
8890
}
@@ -427,6 +429,15 @@ export class AssignmentSummaryTable extends React.Component {
427429
sorting: [{id: "group_name"}],
428430
}}
429431
columnFilters={this.state.columnFilters}
432+
onColumnFiltersChange={updaterOrValue => {
433+
this.setState(prevState => {
434+
const newFilters =
435+
typeof updaterOrValue === "function"
436+
? updaterOrValue(prevState.columnFilters)
437+
: updaterOrValue;
438+
return {columnFilters: newFilters};
439+
});
440+
}}
430441
getRowCanExpand={() => true}
431442
renderSubComponent={renderSubComponent}
432443
loading={this.state.loading}

app/javascript/Components/batch_test_run_table.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ class BatchTestRunTable extends React.Component {
6161
);
6262
// increment in_progress number for this batch_id
6363
status[row.test_batch_id].in_progress += 1;
64-
row.status = I18n.t("automated_tests.test_runs_statuses.in_progress");
6564
} else {
6665
row.time_to_completion = "";
6766
row.action = "";

0 commit comments

Comments
 (0)