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
2 changes: 1 addition & 1 deletion __tests__/e2e/server/launch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
java -jar otp-1.4.0-shaded.jar --server --autoScan --basePath /tmp/otp --insecure --router default &

# Start the second process
java -jar datatools-server-3.8.1-SNAPSHOT.jar /config/env.yml /config/server.yml &
java -XX:-UseContainerSupport -jar datatools-server-3.8.1-SNAPSHOT.jar /config/env.yml /config/server.yml &

# Wait for any process to exit
wait -n
Expand Down
145 changes: 127 additions & 18 deletions __tests__/end-to-end.js
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,51 @@ async function elementType (elementHandle: any, selector: string, text: string)
await selectedElement.type(text)
}

/**
* A helper function to create a new fare media by filling out the fare media
* form and saving it. This function assumes that the fare media sidebar form is
* open and ready to be filled out.
*/
async function createNewFareMedia () {
await waitForAndClick('[data-test-id="create-first-faremedia-button"]')

// fare_media_id
await type(
'[data-test-id="faremedia-fare_media_id-input-container"] input',
'1'
)

// name
await type(
'[data-test-id="faremedia-fare_media_name-input-container"] input',
'Test Fare Media'
)

// type
await page.select(
'[data-test-id="faremedia-fare_media_type-input-container"] select',
'1' // physical paper ticket
)

// save
await click('[data-test-id="save-entity-button"]')
await wait(2000, 'for save to happen')

// reload to make sure stuff was saved
await page.reload({ waitUntil: 'networkidle0' })

// wait for fare media sidebar form to appear
await waitForSelector(
'[data-test-id="faremedia-fare_media_id-input-container"]'
)

// verify data was saved and retrieved from server
await expectSelectorToContainHtml(
'[data-test-id="faremedia-fare_media_id-input-container"]',
'1'
)
}

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Start of test suite
Expand Down Expand Up @@ -2424,36 +2469,100 @@ describe('end-to-end', () => {
}, defaultTestTimeout, 'should create fare')
})

// fares v2 tests
describe('fares v2', () => {
makeEditorEntityTest('should create fare media', async () => {
// open fares v2 sidebar
await click('[data-test-id="editor-fareproduct-nav-button"]')

// click dropdown to select fare_media
await page.select(
'[data-test-id="virtualized-entity-select-fareproduct] select',
'faremedia'
await reactSelectOption(
'[data-test-id="virtualized-entity-select-fareproduct"]',
'faremedia',
1,
true
)

// wait for fare media sidebar form to appear and click create button
await waitForAndClick('[data-test-id="create-first-faremedia-button"]')
await createNewFareMedia()
}, defaultTestTimeout)
makeEditorEntityTest('should update fare media data', async () => {
// update fare media name by appending to end
await appendText(
'[data-test-id="faremedia-fare_media_name-input-container"] input',
' updated'
)

// save
await click('[data-test-id="save-entity-button"]')
await wait(2000, 'for save to happen')

// fare_media_id
// reload to make sure stuff was saved
await page.reload({ waitUntil: 'networkidle0' })

// wait for fare media sidebar form to appear
await waitForSelector(
'[data-test-id="faremedia-fare_media_name-input-container"] input'
)

// verify data was saved and retrieved from server
await expectSelectorToContainHtml(
'[data-test-id="faremedia-fare_media_name-input-container"]',
'Test Fare Media updated'
)
}, defaultTestTimeout, 'should create fare media')
makeEditorEntityTest('should delete fare media', async () => {
// delete the fare media
await click('[data-test-id="delete-faremedia-button"]')
await waitForAndClick('[data-test-id="modal-confirm-ok-button"]')
await wait(2000, 'for delete to happen')

// verify that fare media to delete is no longer listed
await expectSelectorToContainHtml(
'[data-test-id="create-first-faremedia-button"]',
'Create first media'
)
}, defaultTestTimeout, 'should create fare media')
makeEditorEntityTest('should create fare product with fare media', async () => {
await createNewFareMedia()

// click dropdown to select fare_product
await reactSelectOption(
'[data-test-id="virtualized-entity-select-faremedia"]',
'fareproduct',
1,
true
)

// wait for fare product sidebar form to appear and click create button
await waitForAndClick('[data-test-id="create-first-fareproduct-button"]')

// fill out fare product form
await type(
'[data-test-id="faremedia-fare_media_id-input-container"] input',
'1'
'[data-test-id="fareproduct-fare_product_id-input-container"] input',
'test-fare-product-id'
)
await type(
'[data-test-id="fareproduct-fare_product_name-input-container"] input',
'Test Fare Product'
)
// select the previously created fare media
await reactSelectOption(
'[data-test-id="fareproduct-fare_media_id-input-container"]',
'Test Fare Media (1)',
1
)

// name
// amount
await type(
'[data-test-id="faremedia-fare_media_name-input-container"] input',
'Test Fare Media'
'[data-test-id="fareproduct-amount-input-container"] input',
'2.50'
)

// type
// currency
await page.select(
'[data-test-id="faremedia-fare_media_type-input-container"] select',
'1' // physical paper ticket
'[data-test-id="fareproduct-currency-input-container"] select',
'USD'
)

// save
Expand All @@ -2463,17 +2572,17 @@ describe('end-to-end', () => {
// reload to make sure stuff was saved
await page.reload({ waitUntil: 'networkidle0' })

// wait for fare media sidebar form to appear
// wait for fare product sidebar form to appear
await waitForSelector(
'[data-test-id="faremedia-fare_media_id-input-container"]'
'[data-test-id="fareproduct-fare_product_id-input-container"]'
)

// verify data was saved and retrieved from server
await expectSelectorToContainHtml(
'[data-test-id="faremedia-fare_media_id-input-container"]',
'1'
'[data-test-id="fareproduct-fare_product_id-input-container"]',
'test-fare-product-id'
)
}, defaultTestTimeout)
}, defaultTestTimeout, 'should create fare media')
})

// ---------------------------------------------------------------------------
Expand Down
8 changes: 5 additions & 3 deletions gtfs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1047,10 +1047,12 @@
- name: fare_product_name
required: false
inputType: TEXT
# FARE-TODO: Add rider_category_id?
- name: fare_media_id
required: false
inputType: GTFS_FARE_MEDIA
- name: rider_category_id
required: false
inputType: GTFS_RIDER_CATEGORY
- name: amount
inputType: NUMBER
required: true
Expand Down Expand Up @@ -1151,11 +1153,11 @@
helpContent: "The fare product required to transfer between two fare legs. If empty, the cost of the transfer rule is 0."
- id: farelegrule
name: fare_leg_rules.txt
# FARE-TODO: Some help content?
helpContent: Fare rules for individual legs of travel.
fields:
- name: leg_group_id
required: false
inputType: TEXT # FARE-TODO: should this be text or id?
inputType: GTFS_ID
- name: network_id
required: false
inputType: TEXT # FARE-TODO: Needs to reference networks.network_id or routes.network_id
Expand Down
15 changes: 15 additions & 0 deletions lib/editor/components/EditorInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,21 @@ export default class EditorInput extends React.Component<Props> {
<FormControl {...fieldProps} disabled={networkDisabled} value={stringValue} />
</FormGroup>
)
case 'GTFS_RIDER_CATEGORY':
const riderCategories = getTableById(tableData, 'ridercategory').map(riderCategory => ({
value: riderCategory.rider_category_id,
label: `${riderCategory.rider_category_id}`
}))
return (
<FormGroup {...formProps}>
{basicLabel}
<Select
clearable
onChange={this._onSelectChange}
value={currentValue}
options={riderCategories} />
</FormGroup>
)
default:
return null
}
Expand Down
1 change: 0 additions & 1 deletion lib/editor/components/FareProductSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export default class FareProductSelect extends Component<Props, State> {
return (
<Select
clearable
data-test-id='fare-product-selector'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Am I right in thinking that the fares v1 tests have been removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

they have not been removed. This was an unneeded test ID for a v2 fare product selector.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I added this on the OG fares v2 branch.

noResultsText={`No fare products found.`}
onChange={onChange || this._onChange}
options={options}
Expand Down
1 change: 0 additions & 1 deletion lib/editor/components/VirtualizedEntitySelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ export default class VirtualizedEntitySelect extends Component<Props, State> {
return (
<VirtualizedSelect
clearable={clearable}
data-test-id={`virtualized-entity-select-${component}`}
disabled={disabled}
onChange={this._onChange}
optionRenderer={optionRenderer}
Expand Down
22 changes: 12 additions & 10 deletions lib/editor/components/VirtualizedTableSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,18 @@ export default class VirtualizedEntitySelect extends Component<Props, State> {
.map(this._entityToOption)
}
return (
<VirtualizedSelect
placeholder={placeholder}
options={options}
searchable
disabled={disabled}
clearable={clearable}
onChange={this._onChange}
value={value}
style={style}
optionRenderer={optionRenderer} />
<div data-test-id={`virtualized-entity-select-${component}`}>
<VirtualizedSelect
placeholder={placeholder}
options={options}
searchable
disabled={disabled}
clearable={clearable}
onChange={this._onChange}
value={value}
style={style}
optionRenderer={optionRenderer} />
</div>
)
}
}
21 changes: 6 additions & 15 deletions lib/editor/util/gtfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ export function mapPatternShape (pattern: any): any {
return pattern
}

/* eslint-disable complexity */
export function getEntityName (entity: any): string {
const NO_NAME = '[no name]'
if (!entity) {
Expand Down Expand Up @@ -262,22 +263,18 @@ export function getEntityName (entity: any): string {
} else if (typeof entity.fare_media_id !== 'undefined') {
nameKey = 'fare_media_id'
} else if (typeof entity.from_leg_group_id !== 'undefined' && typeof entity.to_leg_group_id !== 'undefined' && entity.fare_product_id !== 'undefined') {
nameKey = 'fare_transfer_rule_id' // FARE-TODO: fare_media_name? Some combo?
nameKey = 'fare_transfer_rule_id'
} else if (typeof entity.fare_product_id !== 'undefined' && typeof entity.leg_group_id !== 'undefined') {
nameKey = 'fare_leg_rule_id' // FARE-TODO: fare_media_name? Some combo?
nameKey = 'fare_leg_rule_id'
} else if (typeof entity.area_id !== 'undefined') {
nameKey = 'area_id' // FARE-TODO: area_name?
nameKey = 'area_id'
} else if (typeof entity.network_id !== 'undefined') {
nameKey = 'network_id' // FARE-TODO: network_name?
nameKey = 'network_id'
} else if (typeof entity.timeframe_group_id !== 'undefined') {
nameKey = 'timeframe_group_id' // FARE-TODO: timeframe name?
nameKey = 'timeframe_group_id'
} else if (typeof entity.rider_category_id !== 'undefined') {
nameKey = 'rider_category_id'
}
// FARE-TODO: what to do with fare_products.txt?

// FARE-TODO: what to do with fare_transfer_rules.txt?
// FARE-TODO: what to do with fare_leg_rules.txt?
if (typeof entity.exemplar !== 'undefined') {
nameKey = 'name'
}
Expand Down Expand Up @@ -313,22 +310,16 @@ export function getEntityName (entity: any): string {
? `(${serviceCalendar.description})`
: ''}`
case 'fare_product_id':
// FARE-TODO: type!
return `${entity.fare_product_id} (${entity.fare_media_id})`
case 'fare_transfer_rule_id':
// FARE-TODO: type!
return `${entity.from_leg_group_id} ➡️ ${entity.to_leg_group_id} (${entity.fare_product_id})`
case 'fare_leg_rule_id':
// FARE-TODO: type!
return `${entity.fare_product_id} (${entity.leg_group_id})`
case 'area_id':
// FARE-TODO: type!
return `${entity.area_id} (${entity.area_name})`
case 'network_id':
// FARE-TODO: type!
return `${entity.network_id} (${entity.network_name})`
case 'timeframe_group_id':
// FARE-TODO: type!
return `${entity.timeframe_group_id}`
default:
const otherEntityType: any = entity
Expand Down
16 changes: 15 additions & 1 deletion lib/types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ type InputType =
'EXCEPTION_DATE' | // FARE-TODO NEW TYPES!!!!!
'GTFS_FARE_PRODUCT' |
'GTFS_FARE_MEDIA' |
'GTFS_STOP_AREA'
'GTFS_STOP_AREA' |
'GTFS_NETWORK' |
'GTFS_RIDER_CATEGORY' |
'GTFS_ROUTE_NETWORK'

export type RtdEntity = {
AgencyId: string,
Expand Down Expand Up @@ -692,6 +695,16 @@ export type GtfsFare = {|
transfers: number
|}

export type GtfsFareProduct = {|
amount: number,
currency: string,
fare_media_id: ?string,
fare_product_id: string,
fare_product_name: ?string,
id: number,
rider_category_id: ?string
|}

export type GtfsSpecField = {
adminOnly?: boolean,
bulkEditEnabled?: boolean,
Expand Down Expand Up @@ -980,6 +993,7 @@ export type Trip = {|
export type Entity = ScheduleException |
GtfsAgency |
GtfsFare |
GtfsFareProduct |
GtfsRoute |
ServiceCalendar |
GtfsStop |
Expand Down
Loading