Skip to content

Commit

Permalink
Merge pull request #235 from catalogueglobal/flow-type-components
Browse files Browse the repository at this point in the history
Flow type components
  • Loading branch information
Landon Reed authored Aug 28, 2018
2 parents d9ccc70 + 17fd1cf commit 9dca466
Show file tree
Hide file tree
Showing 164 changed files with 4,791 additions and 3,297 deletions.
34 changes: 17 additions & 17 deletions __tests__/end-to-end.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,8 @@ async function expectSelectorToNotContainHtml (selector: string, html: string) {
async function createProject (projectName: string) {
log.info(`creating project with name: ${projectName}`)
await click('#context-dropdown')
await waitForSelector('a[href="/project"]')
await click('a[href="/project"]')
await waitForSelector('[data-test-id="create-new-project-button"]')
await wait(2000, 'for projects to load')
await click('[data-test-id="create-new-project-button"]')
await waitForAndClick('a[href="/project"]')
await waitForAndClick('[data-test-id="create-new-project-button"]')
await waitForSelector('.project-name-editable input')
await page.type('.project-name-editable input', projectName)
await click('.project-name-editable button')
Expand All @@ -172,17 +169,15 @@ async function deleteProject (projectId: string) {
await goto(`http://localhost:9966/project/${projectId}/settings`)

// delete that project
await waitForSelector('[data-test-id="delete-project-button"]')
await click('[data-test-id="delete-project-button"]')
await waitForSelector('[data-test-id="modal-confirm-ok-button"]')
await click('[data-test-id="modal-confirm-ok-button"]')
await waitForAndClick('[data-test-id="delete-project-button"]')
await wait(500, 'for modal to appear')
await waitForAndClick('[data-test-id="modal-confirm-ok-button"]')
log.info('deleted project')

// verify deletion
await goto(`http://localhost:9966/project/${projectId}`)
await waitForSelector('.project-not-found')
await expectSelectorToContainHtml('.project-not-found', projectId)
await click('[data-test-id="status-modal-close-button"]')
log.info(`confirmed successful deletion of project with id ${projectId}`)
}

Expand Down Expand Up @@ -410,14 +405,15 @@ async function appendText (selector: string, text: string) {
async function waitForSelector (selector: string, options?: any) {
const startTime = new Date()
await wait(100, 'delay before looking for selector...')
log.info(`waiting for selector: ${selector}`)
await page.waitForSelector(selector, options)
log.info(`selector ${selector} took ${formatSecondsElapsed(startTime)}`)
}

async function click (selector: string) {
log.info(`clicking selector: ${selector}`)
await page.click(selector)
await page.click(selector) // , {delay: 3})
}

async function waitForAndClick (selector: string, waitOptions?: any) {
Expand All @@ -441,9 +437,10 @@ describe('end-to-end', () => {
// Ping the otp endpoint to ensure the server is running.
try {
log.info(`Pinging OTP at ${OTP_ROOT}`)
const response = await fetch(`${OTP_ROOT}`)
if (response.status !== 200) throw new Error('OTP not ready!')
else log.info('OTP is OK.')
await fetch(`${OTP_ROOT}`)
log.info('OTP is OK.')
// if (response.status !== 200) throw new Error('OTP not ready!')
// else log.info('OTP is OK.')
} catch (e) {
if (testOptions.failFast) {
log.error('OpenTripPlanner not accepting requests. Exiting due to fail fast option.')
Expand Down Expand Up @@ -477,15 +474,18 @@ describe('end-to-end', () => {
log.info('Chromium closed.')
})

/// Begin tests

makeTest('should load the page', async () => {
await goto('http://localhost:9966')
await waitForSelector('h1')
await expectSelectorToContainHtml('h1', 'Conveyal Datatools')
testResults['should load the page'] = true
})

makeTest('should login', async () => {
await goto('http://localhost:9966')
await click('[data-test-id="header-log-in-button"]')
await waitForAndClick('[data-test-id="header-log-in-button"]')
await waitForSelector('button[class="auth0-lock-submit"]')
await page.type('input[class="auth0-lock-input"][name="email"]', config.username)
await page.type('input[class="auth0-lock-input"][name="password"]', config.password)
Expand Down Expand Up @@ -520,7 +520,7 @@ describe('end-to-end', () => {

makeTestPostLogin('should update a project by adding a otp server', async () => {
// open settings tab
await click('#project-viewer-tabs-tab-settings')
await waitForAndClick('#project-viewer-tabs-tab-settings')

// navigate to deployments
await waitForAndClick('[data-test-id="deployment-settings-link"]', { visible: true })
Expand Down Expand Up @@ -645,7 +645,7 @@ describe('end-to-end', () => {
// set fetch url
await page.type(
'[data-test-id="feed-source-url-input-group"] input',
'https://github.com/catalogueglobal/datatools-ui/raw/end-to-end/configurations/end-to-end/test-gtfs-to-fetch.zip'
'https://github.com/catalogueglobal/datatools-ui/raw/dev/configurations/end-to-end/test-gtfs-to-fetch.zip'
)
await click('[data-test-id="feed-source-url-input-group"] button')
await wait(2000, 'for feed source to update')
Expand Down
48 changes: 26 additions & 22 deletions lib/admin/components/CreateUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import UserSettings from './UserSettings'
import UserPermissions from '../../common/user/UserPermissions'
import {getComponentMessages, getMessage} from '../../common/util/config'

import type {UserState} from '../../manager/reducers/user'
import type {Organization, Project} from '../../types'

type Props = {
createUser: ({email: string, password: string, permissions: UserPermissions}) => void,
fetchProjectFeeds: string => void,
projects: Array<Project>,
creatingUser: boolean,
creatingUser: UserState,
organizations: Array<Organization>
}

Expand All @@ -24,39 +25,37 @@ type State = {
showModal: boolean
}

const DEFAULT_STATE = {
email: '',
password: '',
showModal: false
}

export default class CreateUser extends Component<Props, State> {
state = {
email: '',
password: '',
showModal: false
}
state = DEFAULT_STATE

save = (e: any) => {
save = (e: SyntheticInputEvent<HTMLInputElement>) => {
e.preventDefault()
if (!e.target.checkValidity()) {
console.warn('Form inputs are invalid!')
return
}
this.setState({showModal: false})
const {email, password} = this.state
this.props.createUser({
email,
password,
permissions: this.refs.userSettings.getSettings()
})
this.setState(DEFAULT_STATE)
}

cancel () {
this.setState({
showModal: false
})
_updateField = (evt: SyntheticInputEvent<HTMLInputElement>) => {
this.setState({[evt.target.name]: evt.target.value})
}

open = () => {
this.setState({
showModal: true
})
}
cancel = () => this.setState(DEFAULT_STATE)

open = () => this.setState({showModal: true})

render () {
const messages = getComponentMessages('CreateUser')
Expand All @@ -66,6 +65,7 @@ export default class CreateUser extends Component<Props, State> {
projects,
fetchProjectFeeds
} = this.props
const {email, password, showModal} = this.state
return (
<div>
<Button
Expand All @@ -75,7 +75,9 @@ export default class CreateUser extends Component<Props, State> {
<Icon type='plus' />{' '}
Create User
</Button>
<Modal show={this.state.showModal} onHide={this.cancel.bind(this)}>
<Modal
show={showModal}
onHide={this.cancel}>
<Modal.Header closeButton>
<Modal.Title>Create User</Modal.Title>
</Modal.Header>
Expand All @@ -84,18 +86,20 @@ export default class CreateUser extends Component<Props, State> {
<FormGroup controlId='formControlsEmail'>
<ControlLabel>Email Address</ControlLabel>
<FormControl
ref='email'
name='email'
autoFocus
value={this.state.email}
onChange={this._updateField}
value={email}
autoComplete='username email'
type='email'
placeholder='Enter email' />
</FormGroup>
<FormGroup controlId='formControlsPassword'>
<ControlLabel>Password</ControlLabel>
<FormControl
ref='password'
value={this.state.password}
name='password'
onChange={this._updateField}
value={password}
minLength='8'
type='password'
placeholder='Enter password for new user'
Expand Down
61 changes: 32 additions & 29 deletions lib/admin/components/OrganizationList.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
// @flow

import Icon from '@conveyal/woonerf/components/icon'
import React, { PropTypes, Component} from 'react'
import React, {Component} from 'react'
import { Panel, Modal, Row, Col, Button, FormControl, Label, ListGroup, ListGroupItem, Image } from 'react-bootstrap'
import validator from 'validator'

import UserPermissions from '../../common/user/UserPermissions'
import { getComponentMessages, getMessage } from '../../common/util/config'
import OrganizationSettings from './OrganizationSettings'

export default class OrganizationList extends Component {
static propTypes = {
// userSearch: PropTypes.func,
// page: PropTypes.number,
// perPage: PropTypes.number,
// userCount: PropTypes.number,
// projects: PropTypes.array,
// fetchProjectFeeds: PropTypes.func,
// createUser: PropTypes.func,
// setPage: PropTypes.func,
// isFetching: PropTypes.bool,
organizations: PropTypes.object,
users: PropTypes.object
// setUserPermission: PropTypes.func,
// saveUser: PropTypes.func,
// deleteUser: PropTypes.func,
// token: PropTypes.string
}
import type {OrganizationsState} from '../reducers/organizations'
import type {UsersState} from '../reducers/users'
import type {Organization, UserProfile, Project} from '../../types'

type Props = {
createOrganization: any => Promise<any>,
deleteOrganization: Organization => void,
fetchOrganizations: () => void,
saveOrganization: Organization => void,
isFetching: boolean,
organizations: OrganizationsState,
projects: Array<Project>,
updateOrganization: (Organization, any) => void,
users: UsersState
}

type State = {
showModal?: boolean
}

export default class OrganizationList extends Component<Props, State> {
state = {}

componentWillMount () {
Expand Down Expand Up @@ -82,15 +86,15 @@ export default class OrganizationList extends Component {
</ListGroupItem>
: organizations.data && organizations.data.map((organization, i) => {
const orgUsers = users.data ? users.data.filter(u => {
const permissions = new UserPermissions(u.app_metadata && u.app_metadata.datatools ? u.app_metadata.datatools : null)
const permissions = new UserPermissions(u.app_metadata && u.app_metadata.datatools)
return permissions.getOrganizationId() === organization.id
}) : []
return (
<OrganizationRow
{...this.props}
organization={organization}
key={i}
users={orgUsers} />
orgUsers={orgUsers} />
)
})
}
Expand Down Expand Up @@ -119,12 +123,11 @@ export default class OrganizationList extends Component {
}
}

class OrganizationRow extends Component {
static propTypes = {
organization: PropTypes.object,
users: PropTypes.array
}

class OrganizationRow extends Component<Props & {
organization: Organization,
orgUsers: Array<UserProfile>
},
{isEditing: boolean}> {
state = {
isEditing: false
}
Expand Down Expand Up @@ -152,7 +155,7 @@ class OrganizationRow extends Component {
render () {
const {
organization,
users
orgUsers
} = this.props
return (
<ListGroupItem
Expand All @@ -167,7 +170,7 @@ class OrganizationRow extends Component {
<Col xs={8} sm={5} md={6}>
<h5>
{organization.name}{' '}
{users.length ? <Label>{users.length} users</Label> : null}
{orgUsers.length ? <Label>{orgUsers.length} users</Label> : null}
</h5>
<small />
</Col>
Expand Down
Loading

0 comments on commit 9dca466

Please sign in to comment.