Skip to content

Commit 2fd726a

Browse files
Merge pull request #882 from opentripplanner/dev
Release: May 2, 2023
2 parents cac98da + 839358d commit 2fd726a

File tree

324 files changed

+40358
-29118
lines changed

Some content is hidden

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

324 files changed

+40358
-29118
lines changed

.babelrc

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
{
2-
"plugins": ["babel-plugin-add-module-exports", "babel-plugin-lodash"],
2+
"plugins": [
3+
"babel-plugin-add-module-exports",
4+
"@babel/plugin-proposal-class-properties",
5+
"babel-plugin-lodash"
6+
],
37
"presets": [
48
"@babel/preset-env",
59
"@babel/preset-typescript",

.github/pull_request_template.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!--Please provide a brief description of what this PR accomplishes and note if it should be considered/merged with any related PR(s)-->
2+
**Description:**
3+
4+
<!--Check the following are met before requesting a review. Leave unchecked if unapplicable-->
5+
**PR Checklist:**
6+
- [ ] Does the code follow accessibility standards (WCAG 2.1 AA Compliant)?
7+
- [ ] Are all languages supported (Internationalization/Localization)?
8+
- [ ] Are appropriate Typescript types implemented?
9+
10+
<!--(Optional) Before and after screenshots for visual changes:-->
11+
<!--| Before | After |
12+
|--------|-------|
13+
| | | -->
14+

.github/workflows/codeql-analysis.yml

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# This file was generated by GitHub
2+
3+
# For most projects, this workflow file will not need changing; you simply need
4+
# to commit it to your repository.
5+
#
6+
# You may wish to alter this file to override the set of languages analyzed,
7+
# or to provide custom queries or build logic.
8+
#
9+
# ******** NOTE ********
10+
# We have attempted to detect the languages in your repository. Please check
11+
# the `language` matrix defined below to confirm you have the correct set of
12+
# supported CodeQL languages.
13+
#
14+
name: "CodeQL"
15+
16+
on:
17+
push:
18+
branches: [ "dev", master ]
19+
pull_request:
20+
# The branches below must be a subset of the branches above
21+
branches: [ "dev" ]
22+
schedule:
23+
- cron: '23 11 * * 4'
24+
25+
jobs:
26+
analyze:
27+
name: Analyze
28+
runs-on: ubuntu-latest
29+
permissions:
30+
actions: read
31+
contents: read
32+
security-events: write
33+
34+
strategy:
35+
fail-fast: false
36+
matrix:
37+
language: [ 'javascript' ]
38+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
39+
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
40+
41+
steps:
42+
- name: Checkout repository
43+
uses: actions/checkout@v3
44+
45+
# Initializes the CodeQL tools for scanning.
46+
- name: Initialize CodeQL
47+
uses: github/codeql-action/init@v2
48+
with:
49+
languages: ${{ matrix.language }}
50+
# If you wish to specify custom queries, you can do so here or in a config file.
51+
# By default, queries listed here will override any specified in a config file.
52+
# Prefix the list here with "+" to use these queries and those in the config file.
53+
54+
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
55+
# queries: security-extended,security-and-quality
56+
57+
58+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
59+
# If this step fails, then you should remove it and run the build manually (see below)
60+
- name: Autobuild
61+
uses: github/codeql-action/autobuild@v2
62+
63+
# ℹ️ Command-line programs to run using the OS shell.
64+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
65+
66+
# If the Autobuild fails above, remove it and uncomment the following three lines.
67+
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
68+
69+
# - run: |
70+
# echo "Run, Build Application using script"
71+
# ./location_of_script_within_repo/buildscript.sh
72+
73+
- name: Perform CodeQL Analysis
74+
uses: github/codeql-action/analyze@v2

.github/workflows/codespell.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- uses: codespell-project/actions-codespell@master
1313
with:
1414
check_filenames: true
15-
# skip git, yarn, and i18n non-english resources.
15+
# skip git, yarn, pixel test script, and all i18n resources.
1616
# Also, the a11y test file has a false positive and the ignore list does not work
1717
# see https://github.com/opentripplanner/otp-react-redux/pull/436/checks?check_run_id=3369380014
18-
skip: ./.git,yarn.lock,./a11y/a11y.test.js,./i18n/fr*
18+
skip: ./.git,yarn.lock,./a11y/a11y.test.js,./a11y/mocks,./percy/percy.test.js,./i18n

.github/workflows/percy.yml

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Percy
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- dev
8+
pull_request:
9+
10+
jobs:
11+
run-pixel-tests-with-otp1-real-server:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v2
16+
with:
17+
# This allows us to work with the repository during the lint step
18+
fetch-depth: 2
19+
- name: Use Node.js 16.x
20+
uses: actions/setup-node@v1
21+
with:
22+
node-version: 16.x
23+
- name: Install npm packages using cache
24+
uses: bahmutov/npm-install@v1
25+
- name: Download OTP1 config file
26+
run: curl $PERCY_OTP1_CONFIG_URL --output /tmp/otp1config.yml
27+
env:
28+
PERCY_OTP1_CONFIG_URL: ${{ secrets.PERCY_OTP1_CONFIG_URL_METRO }}
29+
- name: Take Percy Snapshots
30+
# Move everything from latest commit back to staged
31+
run: npx percy exec -- npx jest percy/percy.test.js --force-exit
32+
env:
33+
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
34+
PERCY_OTP_CONFIG_OVERRIDE: /tmp/otp1config.yml
35+
run-pixel-tests-with-otp2-real-server:
36+
runs-on: ubuntu-latest
37+
38+
steps:
39+
- uses: actions/checkout@v2
40+
with:
41+
# This allows us to work with the repository during the lint step
42+
fetch-depth: 2
43+
- name: Use Node.js 16.x
44+
uses: actions/setup-node@v1
45+
with:
46+
node-version: 16.x
47+
- name: Install npm packages using cache
48+
uses: bahmutov/npm-install@v1
49+
- name: Download OTP2 config file
50+
run: curl $PERCY_OTP2_CONFIG_URL --output /tmp/otp2config.yml
51+
env:
52+
PERCY_OTP2_CONFIG_URL: ${{ secrets.PERCY_OTP2_CONFIG_URL_METRO }}
53+
- name: Take Percy Snapshots
54+
# Move everything from latest commit back to staged
55+
run: npx percy exec -- npx jest percy/percy.test.js --force-exit
56+
env:
57+
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_OTP2 }}
58+
PERCY_OTP_CONFIG_OVERRIDE: /tmp/otp2config.yml
59+
OTP_RR_PERCY_MOBILE: true
60+
run-pixel-tests-with-otp2-real-server-call-taker:
61+
runs-on: ubuntu-latest
62+
63+
steps:
64+
- uses: actions/checkout@v2
65+
with:
66+
# This allows us to work with the repository during the lint step
67+
fetch-depth: 2
68+
- name: Use Node.js 16.x
69+
uses: actions/setup-node@v1
70+
with:
71+
node-version: 16.x
72+
- name: Install npm packages using cache
73+
uses: bahmutov/npm-install@v1
74+
- name: Download OTP2 config file
75+
run: curl $PERCY_OTP2_CONFIG_URL --output /tmp/otp2config.yml
76+
env:
77+
PERCY_OTP2_CONFIG_URL: ${{ secrets.PERCY_OTP2_CONFIG_URL_METRO }}
78+
- name: Take Percy Snapshots
79+
# Move everything from latest commit back to staged
80+
run: npx percy exec -- npx jest percy/percy.test.js --force-exit
81+
env:
82+
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_CALL_TAKER_OTP2 }}
83+
PERCY_OTP_CONFIG_OVERRIDE: /tmp/otp2config.yml
84+
OTP_RR_PERCY_CALL_TAKER: true

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ dist
1919
*config.yml
2020
!example-config.yml
2121
!test-config.yml
22+
!har-mock-config.yml

README.md

+83
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,89 @@ The same environment variables which affect the behavior of `yarn start` also af
3434
env JS_CONFIG=my-custom-js.js CUSTOM_CSS=my-custom-css.css yarn build
3535
```
3636

37+
## Internationalization
38+
39+
OTP-react-redux uses `react-intl` from the [`formatjs`](https://github.com/formatjs/formatjs) library for internationalization.
40+
Both `react-intl` and `formatjs` take advantage of native internationalization features provided by web browsers.
41+
42+
### `i18n` Folder
43+
44+
Language-specific content is located in YML files under the `i18n` folder
45+
(e.g. `en-US.yml` for American English, `fr.yml` for generic French, etc.).
46+
47+
In each of these files:
48+
- Messages are organized in various categories and sub-categories.
49+
- A component or JS module can use messages from one or more categories.
50+
- In the code, messages are retrieved using an ID that is simply the path to the message.
51+
Use the dot '.' to separate categories and sub-categories in the path.
52+
For instance, for the message defined in YML below:
53+
```yaml
54+
common
55+
modes
56+
subway: Metro
57+
```
58+
then use the snippet below with the corresponding message id:
59+
```jsx
60+
<FormattedMessage id="common.modes.subway" /> // renders "Metro".
61+
```
62+
63+
In these YML files, it is important that message ids in the code be consistent with
64+
the categories in this file. Below are some general guidelines:
65+
- For starters, there are an `actions`, `common`, `components`, and `config`
66+
categories. Additional categories may be added as needed.
67+
- Each sub-category under `components` denotes a React component and
68+
should contain messages that are used only by that component (e.g. button captions).
69+
- In contrast, some strings are common to multiple components,
70+
so it makes sense to group them by theme (e.g. accessModes) under the `common` category.
71+
72+
Note: Do not put comments in the YML files! They will be removed by `yaml-sort`.
73+
Instead, comments for other developers should be placed in the corresponding js/jsx/ts/tsx file.
74+
Comments for translators should be entered into Weblate (see [Contributing Translations](#contributing-translations))
75+
76+
### Internationalizable content in the configuration file
77+
78+
Most textual content from the `i18n` folder can also be customized on a per-configuration basis
79+
using the `language` section of `config.yml`, whether for all languages at once,
80+
or for each supported individual language.
81+
82+
### Using internationalizable content in the code
83+
84+
Use message id **literals** (no variables or other dynamic content) with either
85+
```jsx
86+
<FormattedMessage id="..." />
87+
```
88+
or
89+
```js
90+
intl.formatMessage({ id: ... })
91+
```
92+
93+
The reason for passing **literals** to `FormattedMessage` and `intl.formatMessage` is that we have a checker script `yarn check:i18n` that is based on the `formatJS` CLI and that detects unused messages in the code and exports translation tables.
94+
Passing variables or dynamic content will cause the `formatJS` CLI and the checker to ignore the corresponding messages and
95+
incorrectly claim that a string is unused or missing from a translation file.
96+
97+
One exception to this rule concerns configuration settings where message ids can be constructed dynamically.
98+
99+
### Contributing translations
100+
101+
OTP-react-redux now uses [Hosted Weblate](https://www.weblate.org) to manage translations!
102+
103+
<figure>
104+
<a href="https://hosted.weblate.org/engage/otp-react-redux/">
105+
<img src="https://hosted.weblate.org/widgets/otp-react-redux/-/horizontal-auto.svg" alt="Translation status" />
106+
</a>
107+
<figcaption>Translation status for
108+
<a href="https://hosted.weblate.org/engage/otp-react-redux/">OTP-react-redux and OTP-UI on Hosted Weblate</a>
109+
</figcaption>
110+
</figure>
111+
112+
113+
Translations from the community are welcome and very much appreciated,
114+
please see instructions at https://hosted.weblate.org/projects/otp-react-redux/.
115+
Community input from Weblate will appear as pull requests with changes to files in the `i18n` folder for our review.
116+
(Contributions may be edited or rejected to remain in line with long-term project goals.)
117+
118+
If changes to a specific language file is needed but not enabled in Weblate, please open an issue or a pull request with the changes needed.
119+
37120
## Library Documentation
38121

39122
More coming soon...

__tests__/actions/__snapshots__/api.js.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Array [
5656
"error": [Error: Received error from server],
5757
"requestId": "abcd1238",
5858
"searchId": "abcd1236",
59-
"url": "http://mock-host.com:80/api/plan?fromPlace=Origin%20%2812%2C34%29%3A%3A12%2C34&toPlace=Destination%20%2834%2C12%29%3A%3A34%2C12&mode=WALK%2CTRANSIT&ignoreRealtimeUpdates=false&batchId=abcd1236",
59+
"url": "http://mock-host.com:80/api/plan?fromPlace=%2812%2C34%29%3A%3A12%2C34&toPlace=%2834%2C12%29%3A%3A34%2C12&mode=WALK%2CTRANSIT&ignoreRealtimeUpdates=false&batchId=abcd1236",
6060
},
6161
"type": "ROUTING_ERROR",
6262
},
@@ -99,4 +99,4 @@ Array [
9999
]
100100
`;
101101

102-
exports[`actions > api routingQuery should make a query to OTP: OTP Query Path 1`] = `"/api/plan?fromPlace=Origin%20%2812%2C34%29%3A%3A12%2C34&toPlace=Destination%20%2834%2C12%29%3A%3A34%2C12&mode=WALK%2CTRANSIT&ignoreRealtimeUpdates=false&batchId=abcd1234"`;
102+
exports[`actions > api routingQuery should make a query to OTP: OTP Query Path 1`] = `"/api/plan?fromPlace=%2812%2C34%29%3A%3A12%2C34&toPlace=%2834%2C12%29%3A%3A34%2C12&mode=WALK%2CTRANSIT&ignoreRealtimeUpdates=false&batchId=abcd1234"`;

__tests__/actions/api.js

+14-13
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,27 @@
22

33
import nock from 'nock'
44

5+
import '../test-utils/mock-window-url'
56
import * as api from '../../lib/actions/api'
67

78
// Use mocked randId function and pass in searchId for routingQuery calls so that
89
// snapshots are deterministic (i.e., the random IDs don't change).
910
let idCounter = 1234
1011
const randId = () => `abcd${idCounter++}`
1112

13+
/**
14+
* Sets the requestId values as needed to deterministic IDs.
15+
*/
16+
function setMockRequestIds(calls) {
17+
calls.forEach((call) => {
18+
call.forEach((action) => {
19+
if (action.payload && action.payload.requestId) {
20+
action.payload.requestId = randId()
21+
}
22+
})
23+
})
24+
}
25+
1226
describe('actions > api', () => {
1327
describe('routingQuery', () => {
1428
const defaultState = {
@@ -64,16 +78,3 @@ describe('actions > api', () => {
6478
})
6579
})
6680
})
67-
68-
/**
69-
* Sets the requestId values as needed to deterministic IDs.
70-
*/
71-
function setMockRequestIds (calls) {
72-
calls.forEach(call => {
73-
call.forEach(action => {
74-
if (action.payload && action.payload.requestId) {
75-
action.payload.requestId = randId()
76-
}
77-
})
78-
})
79-
}

0 commit comments

Comments
 (0)