Skip to content

Commit e8de4ec

Browse files
committed
Merge branch 'trunk' into change/update-course-lesson-wizard
2 parents 034ea11 + 0a5408f commit e8de4ec

File tree

83 files changed

+45644
-67838
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+45644
-67838
lines changed

.codecov.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
codecov:
2+
require_ci_to_pass: yes
3+
4+
coverage:
5+
precision: 2
6+
round: down
7+
range: "70...100"
8+
9+
comment:
10+
layout: "reach,diff,flags,files,footer"
11+
behavior: default
12+
require_changes: no

.github/workflows/build-docs.yml

+4-6
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,12 @@ jobs:
99
hookdocs:
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v2
13-
- name: Use Node.js 10
14-
uses: actions/setup-node@v2
15-
with:
16-
node-version: '10.x'
12+
- uses: actions/checkout@v3
13+
- name: Updates the npm version
14+
run: npm install -g npm@8.9.0
1715
- name: npm install, and build docs
1816
run: |
19-
npm install
17+
npm ci
2018
npm run build:docs
2119
- name: Deploy to GH Pages
2220
uses: peaceiris/actions-gh-pages@v3

.github/workflows/build.yml

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ jobs:
77
name: Plugin Build
88
runs-on: ubuntu-18.04
99
steps:
10-
- uses: actions/checkout@v2
10+
- uses: actions/checkout@v3
1111
- name: Get npm cache directory
1212
id: npm-cache
1313
run: |
1414
echo "::set-output name=dir::$(npm config get cache)"
15-
- uses: actions/cache@v2
15+
- uses: actions/cache@v3
1616
with:
1717
path: ${{ steps.npm-cache.outputs.dir }}
1818
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
@@ -26,7 +26,11 @@ jobs:
2626
- name: Get composer cache directory
2727
id: composer-cache
2828
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
29-
- uses: actions/cache@v2
29+
30+
- name: Updates the npm version
31+
run: npm install -g npm@8.9.0
32+
33+
- uses: actions/cache@v3
3034
with:
3135
path: ${{ steps.composer-cache.outputs.dir }}
3236
key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }}

.github/workflows/e2e-playwright.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ jobs:
2121
- name: Checkout code
2222
uses: actions/checkout@v3
2323

24-
- name: Use specific NodeJS version
25-
uses: actions/setup-node@v3
26-
with:
27-
node-version: '16'
24+
- name: Updates the npm version
25+
run: npm install -g npm@8.9.0
2826

2927
- name: Install dependencies
3028
run: npm ci

.github/workflows/js.yml

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ jobs:
88
runs-on: ubuntu-latest
99
steps:
1010
- uses: actions/checkout@v3
11+
12+
- name: Updates the CI npm
13+
run: npm install -g npm@8.9.0
14+
1115
- uses: actions/cache@v3
1216
with:
1317
path: ~/.npm/
@@ -27,6 +31,10 @@ jobs:
2731
steps:
2832
# clone the repository
2933
- uses: actions/checkout@v3
34+
35+
- name: Updates the npm version
36+
run: npm install -g npm@8.9.0
37+
3038
- uses: actions/cache@v3
3139
with:
3240
path: ~/.npm

.github/workflows/php.yml

+67
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,70 @@ jobs:
127127

128128
- name: Run tests
129129
run: ./vendor/bin/phpunit
130+
coverage:
131+
name: PHP Test Coverage
132+
runs-on: ubuntu-latest
133+
continue-on-error: false
134+
env:
135+
WP_VERSION: latest
136+
WP_MULTISITE: 0
137+
PHP_VERSION: 7.4
138+
services:
139+
database:
140+
image: mysql:5.6
141+
env:
142+
MYSQL_ROOT_PASSWORD: root
143+
ports:
144+
- 3306:3306
145+
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5
146+
steps:
147+
- name: Checkout code
148+
uses: actions/checkout@v2
149+
150+
- name: Get cached composer directories
151+
uses: actions/cache@v2
152+
with:
153+
path: ~/.cache/composer/
154+
key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }}
155+
- uses: actions/cache@v2
156+
with:
157+
path: vendor/
158+
key: ${{ runner.os }}-vendor-${{ hashFiles('composer.lock') }}
159+
160+
- name: Setup PHP
161+
uses: shivammathur/setup-php@v2
162+
with:
163+
php-version: 7.4
164+
extensions: mysql
165+
tools: composer
166+
coverage: xdebug
167+
168+
- name: Tool versions
169+
run: |
170+
php --version
171+
composer --version
172+
173+
- name: Install PHP dependencies
174+
run: composer install --no-ansi --no-interaction --prefer-dist --no-progress --ignore-platform-reqs
175+
176+
- name: Add PHP 7.4+ compatibility
177+
run: |
178+
if [ "$(php -r "echo version_compare(PHP_VERSION,'7.4','>=');")" ]; then
179+
curl -L https://github.com/woocommerce/phpunit/archive/add-compatibility-with-php8-to-phpunit-7.zip -o /tmp/phpunit-7.5-fork.zip
180+
unzip -d /tmp/phpunit-7.5-fork /tmp/phpunit-7.5-fork.zip
181+
rm ./vendor/bin/phpunit
182+
composer bin phpunit config --unset platform
183+
composer bin phpunit config repositories.0 '{"type": "path", "url": "/tmp/phpunit-7.5-fork/phpunit-add-compatibility-with-php8-to-phpunit-7", "options": {"symlink": false}}'
184+
composer bin phpunit require --dev -W phpunit/phpunit:@dev --ignore-platform-reqs
185+
rm -rf ./vendor/phpunit/
186+
composer dump-autoload
187+
fi
188+
189+
- name: Setup test environment
190+
run: bash ./tests/bin/install-wp-tests.sh wordpress_test root root 127.0.0.1 $WP_VERSION
191+
192+
- name: Run tests with coverage
193+
run: php -dxdebug.mode=coverage ./vendor/bin/phpunit --coverage-clover ./coverage.xml
194+
195+
- name: Upload coverage reports to Codecov with GitHub Action
196+
uses: codecov/codecov-action@v3

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ vendor/
1313
tests/e2e/screenshots
1414
/*.zip
1515
/coverage/
16+
coverage.xml
1617
tests/e2e-playwright/contexts/*

.npmrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
save-exact = true
1+
save-exact = true
2+
engine-strict = true

assets/admin/students/student-action-menu/index.test.js

+19-5
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@ import { StudentActionMenu } from './index';
1616

1717
jest.mock( '@wordpress/data' );
1818

19+
const studentName = 'johndoe';
20+
const studentDisplayName = 'John Doe';
21+
1922
describe( '<StudentActionMenu />', () => {
2023
it( 'Should display modal when "Add to Course" is selected', async () => {
2124
useSelect.mockReturnValue( { courses: [], isFetching: false } );
22-
render( <StudentActionMenu /> );
25+
render(
26+
<StudentActionMenu studentDisplayName={ studentDisplayName } />
27+
);
2328

2429
// Open the dropdown menu.
2530
const button = screen.getByRole( 'button' );
@@ -42,7 +47,9 @@ describe( '<StudentActionMenu />', () => {
4247

4348
it( 'Should display modal when "Remove from Course" is selected', async () => {
4449
useSelect.mockReturnValue( { courses: [], isFetching: false } );
45-
render( <StudentActionMenu /> );
50+
render(
51+
<StudentActionMenu studentDisplayName={ studentDisplayName } />
52+
);
4653

4754
// Open the dropdown menu.
4855
const button = screen.getByRole( 'button' );
@@ -65,7 +72,9 @@ describe( '<StudentActionMenu />', () => {
6572

6673
it( 'Should display modal when "Reset or Remove progress" is selected', async () => {
6774
useSelect.mockReturnValue( { courses: [], isFetching: false } );
68-
render( <StudentActionMenu /> );
75+
render(
76+
<StudentActionMenu studentDisplayName={ studentDisplayName } />
77+
);
6978

7079
// Open the dropdown menu.
7180
const button = screen.getByRole( 'button' );
@@ -87,7 +96,12 @@ describe( '<StudentActionMenu />', () => {
8796
} );
8897

8998
it( "Should display student's ungraded quizzes when Grading menu item is selected", () => {
90-
render( <StudentActionMenu studentName="mary" /> );
99+
render(
100+
<StudentActionMenu
101+
studentName={ studentName }
102+
studentDisplayName={ studentDisplayName }
103+
/>
104+
);
91105

92106
// Open the dropdown menu.
93107
const button = screen.getByRole( 'button' );
@@ -106,7 +120,7 @@ describe( '<StudentActionMenu />', () => {
106120
fireEvent.click( menuItem );
107121

108122
expect( windowSpy ).toBeCalledWith(
109-
'edit.php?post_type=course&page=sensei_grading&view=ungraded&s=mary',
123+
`edit.php?post_type=course&page=sensei_grading&view=ungraded&s=${ studentName }`,
110124
'_self'
111125
);
112126

assets/admin/students/student-modal/index.js

+60-31
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,39 @@ import { Button, Modal, Notice, Spinner } from '@wordpress/components';
55
import { useCallback, useState, RawHTML } from '@wordpress/element';
66
import { search } from '@wordpress/icons';
77
import { __, _n, sprintf } from '@wordpress/i18n';
8+
import { escapeHTML } from '@wordpress/escape-html';
89
import apiFetch from '@wordpress/api-fetch';
910

10-
/**
11-
* External dependencies
12-
*/
13-
import { escape } from 'lodash';
14-
1511
/**
1612
* Internal dependencies
1713
*/
1814
import CourseList from './course-list';
1915
import InputControl from '../../../blocks/editor-components/input-control';
2016
import useAbortController from '../hooks/use-abort-controller';
2117

22-
const getAction = ( action, studentCount ) => {
18+
const getAction = ( action, studentCount, studentDisplayName ) => {
19+
const safeStudentDisplayName = escapeHTML( studentDisplayName );
20+
2321
const possibleActions = {
2422
add: {
25-
// Translators: placeholder is the number of selected students for plural, student's name for singular.
26-
description: _n(
27-
'Select the course(s) you would like to add <strong>%1$s</strong> to:',
28-
'Select the course(s) you would like to add <strong>%1$d students</strong> to:',
29-
studentCount,
30-
'sensei-lms'
31-
),
23+
description:
24+
studentCount > 1
25+
? sprintf(
26+
// Translators: placeholder is the number of selected students.
27+
__(
28+
'Select the course(s) you would like to add <strong>%d students</strong> to:',
29+
'sensei-lms'
30+
),
31+
studentCount
32+
)
33+
: sprintf(
34+
// Translators: placeholder is the student's name.
35+
__(
36+
'Select the course(s) you would like to add <strong>%s</strong> to:',
37+
'sensei-lms'
38+
),
39+
safeStudentDisplayName
40+
),
3241
buttonLabel: __( 'Add to Course', 'sensei-lms' ),
3342
errorMessage: ( students ) =>
3443
_n(
@@ -47,13 +56,24 @@ const getAction = ( action, studentCount ) => {
4756
isDestructive: false,
4857
},
4958
remove: {
50-
// Translators: placeholder is the number of selected students for plural, student's name for singular.
51-
description: _n(
52-
'Select the course(s) you would like to remove <strong>%1$s</strong> from:',
53-
'Select the course(s) you would like to remove <strong>%1$d students</strong> from:',
54-
studentCount,
55-
'sensei-lms'
56-
),
59+
description:
60+
studentCount > 1
61+
? sprintf(
62+
// Translators: placeholder is the number of selected students.
63+
__(
64+
'Select the course(s) you would like to remove <strong>%d students</strong> from:',
65+
'sensei-lms'
66+
),
67+
studentCount
68+
)
69+
: sprintf(
70+
// Translators: placeholder is the student's name.
71+
__(
72+
'Select the course(s) you would like to remove <strong>%s</strong> from:',
73+
'sensei-lms'
74+
),
75+
safeStudentDisplayName
76+
),
5777
buttonLabel: __( 'Remove from Course', 'sensei-lms' ),
5878
errorMessage: ( students ) =>
5979
_n(
@@ -73,12 +93,24 @@ const getAction = ( action, studentCount ) => {
7393
},
7494
'reset-progress': {
7595
// Translators: placeholder is the number of selected students for plural, student's name for singular.
76-
description: _n(
77-
'Select the course(s) you would like to reset or remove progress from for <strong>%1$s</strong>:',
78-
'Select the course(s) you would like to reset or remove progress from for <strong>%1$d students</strong>:',
79-
studentCount,
80-
'sensei-lms'
81-
),
96+
description:
97+
studentCount > 1
98+
? sprintf(
99+
// Translators: placeholder is the number of selected students.
100+
__(
101+
'Select the course(s) you would like to reset or remove progress from for <strong>%d students</strong>:',
102+
'sensei-lms'
103+
),
104+
studentCount
105+
)
106+
: sprintf(
107+
// Translators: placeholder is the student's name.
108+
__(
109+
'Select the course(s) you would like to reset or remove progress from for <strong>%s</strong>:',
110+
'sensei-lms'
111+
),
112+
safeStudentDisplayName
113+
),
82114
buttonLabel: __( 'Reset or Remove Progress', 'sensei-lms' ),
83115
errorMessage: ( students ) =>
84116
_n(
@@ -122,15 +154,12 @@ export const StudentModal = ( {
122154
errorMessage,
123155
isDestructive,
124156
sendAction,
125-
} = getAction( action, students.length );
157+
} = getAction( action, students.length, studentDisplayName );
126158
const [ selectedCourses, setCourses ] = useState( [] );
127159
const [ searchQuery, setSearchQuery ] = useState( '' );
128160
const [ isSending, setIsSending ] = useState( false );
129161
const [ error, setError ] = useState( false );
130162
const { getSignal } = useAbortController();
131-
const replacementString =
132-
students.length === 1 ? escape( studentDisplayName ) : students.length;
133-
const replacedDescription = sprintf( description, replacementString );
134163

135164
const send = useCallback( async () => {
136165
setIsSending( true );
@@ -158,7 +187,7 @@ export const StudentModal = ( {
158187
title={ __( 'Choose Course', 'sensei-lms' ) }
159188
onRequestClose={ () => onClose() }
160189
>
161-
<RawHTML>{ replacedDescription }</RawHTML>
190+
<RawHTML>{ description }</RawHTML>
162191

163192
<InputControl
164193
iconRight={ search }

0 commit comments

Comments
 (0)