Skip to content

Commit 04ba340

Browse files
authored
Merge pull request #72 from CodeYourFuture/staging
merge staging into master
2 parents 243d43c + bce018a commit 04ba340

File tree

15 files changed

+345
-165
lines changed

15 files changed

+345
-165
lines changed

.circleci/config.yml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,22 @@ commands:
2424
--paths /\*
2525
2626
jobs:
27-
test:
27+
build:
2828
docker:
2929
- image: circleci/node:11.12
3030
working_directory: ~/repo
3131
steps:
3232
- checkout
33+
- restore_cache:
34+
keys:
35+
- yarn-dependencies-{{ checksum "package.json" }}
3336
- run:
34-
name: Install dependencies for lint and test
37+
name: Install dependencies
3538
command: yarn
39+
- save_cache:
40+
key: yarn-dependencies-{{ checksum "package.json" }}
41+
paths:
42+
- ~/.cache
3643
- run:
3744
name: Set env variables
3845
command: echo 'export VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)' >> $BASH_ENV
@@ -92,20 +99,20 @@ workflows:
9299
version: 2
93100
test_and_deploy:
94101
jobs:
95-
- test:
102+
- build:
96103
context: build
97104
- deploy_staging:
98105
context: deployments_staging
99106
requires:
100-
- test
107+
- build
101108
filters:
102109
branches:
103110
only:
104111
- staging
105112
- deploy_production:
106113
context: deployments
107114
requires:
108-
- test
115+
- build
109116
filters:
110117
branches:
111118
only:

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
# testing
99
/coverage
10-
/e2e/screenshot
10+
/e2e/screenshots
1111

1212
# production
1313
/build

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ Your app is ready to be deployed!
4646

4747
Runs the [Cypress] end-to-end tests, which means:
4848

49-
- Starting a mock for the Google server on port 3100
50-
- Starting the forms app in TESTING mode on port 3000
49+
- Starting a mock for the backend server on port 3100
50+
- Starting the forms app in LOCAL mode on port 3000
5151
- Waiting for the app to start then running the tests
5252

5353
[cypress]: https://www.cypress.io/

e2e/fixtures/server.js

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,8 @@ const app = express()
99

1010
const calls = []
1111

12-
app.post('/google', (req, res) => {
13-
console.log({
14-
body: req.body,
15-
headers: req.headers
16-
})
17-
calls.push({
18-
body: req.body,
19-
headers: req.headers
20-
})
21-
res.sendStatus(204)
12+
app.get('/cities', (_, res) => {
13+
res.json({ cities: [{ _id: '123abc', name: 'London' }] })
2214
})
2315

2416
app.post('/volunteer', (req, res) => {
@@ -30,7 +22,7 @@ app.post('/volunteer', (req, res) => {
3022
body: req.body,
3123
headers: req.headers
3224
})
33-
res.sendStatus(204)
25+
res.json({ volunteer: req.body })
3426
})
3527

3628
app.get('/_calls', (req, res) => {

e2e/integration/journey.test.js

Lines changed: 23 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,17 @@
11
const mockServerURL = `http://localhost:3001`
22

33
const timestamp = 1559822173490
4-
const thanks = '#NailedItThank you! Your submission is now on its way to us.'
54

65
const initialData = {
76
firstName: 'Jane',
87
lastName: 'Doe',
9-
city: 'London',
8+
cityName: 'London',
109
11-
phone: '01189998819991197253'
12-
}
13-
14-
const codeData = {
15-
codeExpertise: {
16-
'HTML/CSS': '5',
17-
JavaScript: '4',
18-
React: '3',
19-
'SQL/Mongo': '2',
20-
'Agile Methodologies': '1'
21-
},
22-
otherCodeExpertise: 'Rock star developer, but humble',
23-
availableOnWeekends: 'Yes'
24-
}
25-
26-
const orgData = {
27-
skillSets: {
28-
accounting: true,
29-
events: true
30-
},
31-
availability: {
32-
weekend: true
33-
}
10+
tel: '01189998819991197253',
11+
interestedInVolunteer: 'just sounds interesting',
12+
interestedInCYF: 'trying to do my bit',
13+
industry: 'Education',
14+
hearAboutCYF: 'Social media'
3415
}
3516

3617
beforeEach(() => {
@@ -40,85 +21,26 @@ beforeEach(() => {
4021
cy.visit('/')
4122
})
4223

43-
it('can submit a code-only form', () => {
44-
const extra = {
45-
interests: {
46-
teachingCode: true
47-
}
48-
}
49-
50-
cy.fillInitialForm({ ...initialData, ...extra }, 'Next')
51-
cy.fillCodeForm(codeData, 'Submit')
52-
cy.log(`submitting data: ${JSON.stringify(codeData)}`)
53-
cy.get('.applicationForm_thankYou').should('contains.text', thanks)
54-
55-
cy.request(`${mockServerURL}/_calls`).then(response => {
56-
expect(response.body[0].body).to.deep.eq({
57-
...initialData,
58-
...extra,
59-
...codeData
60-
})
61-
expect(response.body[1].body).to.deep.eq({
62-
Authorization: `Timestamp ${timestamp}`,
63-
...initialData,
64-
...extra,
65-
...codeData
66-
})
67-
})
24+
const generateExpected = data => ({
25+
firstName: data.firstName,
26+
lastName: data.lastName,
27+
email: data.email,
28+
tel: `+${data.tel}`,
29+
cityId: '123abc',
30+
interestedInVolunteer: data.interestedInVolunteer,
31+
interestedInCYF: data.interestedInCYF,
32+
industry: data.industry || '',
33+
hearAboutCYF: data.hearAboutCYF || '',
34+
guidePeople: data.guidePeople || [],
35+
techSkill: data.techSkill || [],
36+
otherSkill: data.otherSkill || [],
37+
userId: ''
6838
})
6939

70-
it('can submit an org-only form', () => {
71-
const extra = {
72-
interests: { runningOrganisation: true }
73-
}
74-
75-
cy.fillInitialForm({ ...initialData, ...extra }, 'Next')
76-
cy.fillOrgForm(orgData, 'Submit')
77-
78-
cy.get('.applicationForm_thankYou').should('contains.text', thanks)
79-
80-
cy.request(`${mockServerURL}/_calls`).then(response => {
81-
expect(response.body[0].body).to.deep.eq({
82-
...initialData,
83-
...extra,
84-
...orgData
85-
})
86-
expect(response.body[1].body).to.deep.eq({
87-
Authorization: `Timestamp ${timestamp}`,
88-
...initialData,
89-
...extra,
90-
...orgData
91-
})
92-
})
93-
})
94-
95-
it('can submit both', () => {
96-
const extra = {
97-
interests: {
98-
runningOrganisation: true,
99-
teachingCode: true
100-
}
101-
}
102-
103-
cy.fillInitialForm({ ...initialData, ...extra }, 'Next')
104-
cy.fillCodeForm(codeData, 'Next')
105-
cy.fillOrgForm(orgData, 'Submit')
106-
107-
cy.get('.applicationForm_thankYou').should('contains.text', thanks)
40+
it('can submit a minimal form', () => {
41+
cy.fillInitialForm(initialData)
10842

10943
cy.request(`${mockServerURL}/_calls`).then(response => {
110-
expect(response.body[0].body).to.deep.eq({
111-
...initialData,
112-
...extra,
113-
...codeData,
114-
...orgData
115-
})
116-
expect(response.body[1].body).to.deep.eq({
117-
Authorization: `Timestamp ${timestamp}`,
118-
...initialData,
119-
...extra,
120-
...codeData,
121-
...orgData
122-
})
44+
expect(response.body[0].body).to.deep.eq(generateExpected(initialData))
12345
})
12446
})

e2e/support/commands.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,28 @@
44
// https://on.cypress.io/custom-commands
55
// ***********************************************//
66

7-
Cypress.Commands.add('fillInitialForm', (data, button) => {
7+
Cypress.Commands.add('fillInitialForm', data => {
8+
// mandatory fields
89
cy.get('[name="firstName"]').type(data.firstName)
910
cy.get('[name="lastName"]').type(data.lastName)
10-
cy.get('[name="city"]').select(data.city)
11+
cy.get('[name="cityId"]').select(data.cityName)
1112
cy.get('[name="email"]').type(data.email)
12-
cy.get('[name="phone"]').type(data.phone)
13-
Object.keys(data.interests).forEach(field => {
14-
cy.get(`[name="interests[${field}]"]`).check()
15-
})
13+
cy.get('input[type="tel"]').type(data.tel)
14+
cy.get('[name="interestedInVolunteer"]').type(data.interestedInVolunteer)
15+
cy.get('[name="interestedInCYF"]').type(data.interestedInCYF)
16+
17+
// optional fields
18+
if (data.industry) {
19+
cy.get('[name="industry"]').select(data.industry)
20+
}
21+
if (data.hearAboutCYF) {
22+
cy.get('[name="hearAboutCYF"]').select(data.hearAboutCYF)
23+
}
24+
25+
// submission
26+
cy.get('[name="acknowledgement"]').click()
1627
cy.get('button')
17-
.contains(button)
28+
.contains('Submit')
1829
.click()
1930
})
2031

package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
"delete-map-files": "find ./build -name '*.map' -delete",
4141
"delete-references-to-map-files": "find ./build -regex '.*\\.\\(js\\|css\\)' -exec sed -i -E '\\/[\\*\\/]#\\ssourceMappingURL=main(\\.[0-9a-f]+)?\\.(css|js)\\.map(\\*\\/)?/g' {} +",
4242
"test": "react-scripts test --env=jsdom",
43+
"e2e:dev": "concurrently -k -n \"app,mock,e2e\" \"yarn start\" \"yarn e2e:mock\" \"cypress open\"",
44+
"e2e": "concurrently -k -s first -n \"app,mock,e2e\" \"BROWSER=none yarn start\" \"yarn e2e:mock\" \"yarn e2e:run\"",
45+
"e2e:mock": "node ./e2e/fixtures/server.js",
46+
"e2e:run": "wait-on -l http-get://localhost:3000 && cypress run",
4347
"lint:fix": "./node_modules/.bin/eslint --fix src",
4448
"prettier": "./node_modules/.bin/prettier --config .prettierrc --write 'src/**/*.js'",
4549
"eject": "react-scripts eject"
@@ -62,6 +66,9 @@
6266
},
6367
"devDependencies": {
6468
"autoprefixer": "^9.6.1",
69+
"concurrently": "^5.0.0",
70+
"cors": "^2.8.5",
71+
"cypress": "^3.4.1",
6572
"eslint": "^6.2.2",
6673
"eslint-config-airbnb": "^18.0.1",
6774
"eslint-config-prettier": "^6.1.0",
@@ -71,7 +78,8 @@
7178
"eslint-plugin-react": "^7.14.3",
7279
"husky": "^3.0.4",
7380
"lint-staged": "^9.2.5",
74-
"prettier": "^1.18.2"
81+
"prettier": "^1.18.2",
82+
"wait-on": "^3.3.0"
7583
},
7684
"browserslist": [
7785
">0.2%",

src/App.css

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@ body {
2323
-webkit-animation: spin 2s linear infinite;
2424
animation: spin 2s linear infinite;
2525
}
26+
27+
@-webkit-keyframes spin {
28+
0% {
29+
-webkit-transform: rotate(0deg);
30+
}
31+
100% {
32+
-webkit-transform: rotate(360deg);
33+
}
34+
}
35+
36+
@keyframes spin {
37+
0% {
38+
transform: rotate(0deg);
39+
}
40+
100% {
41+
transform: rotate(360deg);
42+
}
43+
}
44+
2645
button:disabled {
2746
background: gray;
2847
}

src/App.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import React from 'react'
22
import { Provider } from 'react-redux'
33
import { BrowserRouter as Router } from 'react-router-dom'
4-
import { applyMiddleware, createStore } from 'redux'
4+
import { applyMiddleware, compose, createStore } from 'redux'
55
import ReduxThunk from 'redux-thunk'
66
import './App.css'
77
import Footer from './Components/Footer'
88
import Navbar from './Components/Navbar'
99
import reducers from './Redux/Reducer'
1010
import Routes from './Routes'
1111

12-
const store = createStore(reducers, applyMiddleware(ReduxThunk))
12+
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
13+
const store = createStore(reducers, composeEnhancers(applyMiddleware(ReduxThunk)))
14+
1315
const App = () => (
1416
<Provider store={store}>
1517
<Router>

src/Components/forms/header.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
import React from 'react'
22

3-
export default ({ err, formInComplete, userId }) => {
3+
export default ({ formInComplete, userId }) => {
44
return (
55
<div>
66
<div className="mb-2">
7-
{err && (
8-
<p className="errors">
9-
{err}
10-
{window.scrollTo(0, 0)}
11-
</p>
12-
)}
137
{formInComplete ? (
148
<p className="errors">
159
Form is incomplete, please check all your details.

0 commit comments

Comments
 (0)