Skip to content

Commit

Permalink
merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
mjhea0 committed Jan 16, 2019
2 parents 761c55f + db2847a commit 88163b7
Show file tree
Hide file tree
Showing 59 changed files with 1,575 additions and 126 deletions.
7 changes: 6 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ env:
EXERCISES_REPO: ${MAIN_REPO}#${TRAVIS_BRANCH}:services/exercises
EXERCISES_DB: test-driven-exercises_db
EXERCISES_DB_REPO: ${MAIN_REPO}#${TRAVIS_BRANCH}:services/exercises/project/db
SCORES: test-driven-scores
SCORES_REPO: ${MAIN_REPO}#${TRAVIS_BRANCH}:services/scores
SCORES_DB: test-driven-scores_db
SCORES_DB_REPO: ${MAIN_REPO}#${TRAVIS_BRANCH}:services/scores/project/db
SECRET_KEY: my_precious

before_install:
Expand All @@ -30,7 +34,8 @@ before_install:
before_script:
- export REACT_APP_USERS_SERVICE_URL=http://127.0.0.1
- export REACT_APP_EXERCISES_SERVICE_URL=http://127.0.0.1
- export REACT_APP_API_GATEWAY_URL=https://a6tlc4juke.execute-api.us-west-1.amazonaws.com/v1/execute
- export REACT_APP_SCORES_SERVICE_URL=http://127.0.0.1
- export REACT_APP_API_GATEWAY_URL=https://a6tlc4juke.execute-api.us-west-1.amazonaws.com/v2/execute
- if [[ "$TRAVIS_BRANCH" == "staging" ]]; then export LOAD_BALANCER_DNS_NAME=http://testdriven-staging-alb-2001734548.us-west-1.elb.amazonaws.com; fi
- if [[ "$TRAVIS_BRANCH" == "production" ]]; then export LOAD_BALANCER_DNS_NAME=http://testdriven-production-alb-2116729726.us-west-1.elb.amazonaws.com; fi
- npm install
Expand Down
50 changes: 46 additions & 4 deletions cypress/integration/exercises.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ describe('Exercises', () => {
.visit('/')
.get('h1').contains('Exercises')
.get('.notification.is-warning').contains('Please log in to submit an exercise.')
.get('button').should('not.be.visible');
.get('button').contains('Run Code').should('not.be.visible')
.get('.field.is-grouped')
.get('button').contains('Next')
.get('button').contains('Prev').should('not.be.visible');
});

it('should allow a user to submit an exercise if logged in', () => {
Expand All @@ -33,12 +36,51 @@ describe('Exercises', () => {
.get('h1').contains('Exercises')
.get('.notification.is-success').contains('Welcome!')
.get('.notification.is-danger').should('not.be.visible')
.get('button.button.is-primary').contains('Run Code');
.get('button.button.is-primary').contains('Run Code')
.get('.field.is-grouped')
.get('button').contains('Next')
.get('button').contains('Prev').should('not.be.visible');

// assert user can submit an exercise
for (let i = 0; i < 23; i++) {
cy.get('textarea').type('{backspace}', { force: true })
}
cy
.get('textarea').type('def sum(x,y):\nreturn x+y', { force: true })
.get('button').contains('Run Code').click()
.wait(800)
.get('h5 > .grade-text').contains('Incorrect!');
.wait('@gradeExercise')
.get('h5 > .grade-text').contains('Correct!');
});

it('should allow a user to move to different exercises', () => {
cy
.visit('/')
.get('h1').contains('Exercises')
.get('.notification.is-warning').contains('Please log in to submit an exercise.')
.get('button').contains('Run Code').should('not.be.visible')
.get('.field.is-grouped')
.get('button').contains('Next')
.get('button').contains('Prev').should('not.be.visible')
.get('.ace_comment').contains('# Enter your code here.')
// click next
.get('button').contains('Next').click()
.get('button').contains('Next')
.get('button').contains('Prev')
.get('.ace_comment').contains('# Enter your code here.')
// click next
.get('button').contains('Next').click()
.get('button').contains('Next').should('not.be.visible')
.get('button').contains('Prev')
.get('.ace_comment').contains('# Enter your code here.')
for (let i = 0; i < 23; i++) {
cy.get('textarea').type('{backspace}', { force: true })
}
cy
.get('textarea').type('def sum(x,y):\nreturn x+y', { force: true })
// click prev
.get('button').contains('Prev').click()
.get('button').contains('Next')
.get('button').contains('Prev')
.get('.ace_comment').contains('# Enter your code here.');
});
});
32 changes: 32 additions & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ services:
- REACT_APP_USERS_SERVICE_URL=${REACT_APP_USERS_SERVICE_URL}
- REACT_APP_API_GATEWAY_URL=${REACT_APP_API_GATEWAY_URL}
- REACT_APP_EXERCISES_SERVICE_URL=${REACT_APP_EXERCISES_SERVICE_URL}
- REACT_APP_SCORES_SERVICE_URL=${REACT_APP_SCORES_SERVICE_URL}
depends_on:
- users

Expand Down Expand Up @@ -98,3 +99,34 @@ services:
depends_on:
- users
- client

scores:
build:
context: ./services/scores
dockerfile: Dockerfile-dev
volumes:
- './services/scores:/usr/src/app'
ports:
- 5003:5000
environment:
- FLASK_ENV=development
- APP_SETTINGS=project.config.DevelopmentConfig
- SECRET_KEY=my_precious
- DATABASE_URL=postgres://postgres:postgres@scores-db:5432/scores_dev
- DATABASE_TEST_URL=postgres://postgres:postgres@scores-db:5432/scores_test
- USERS_SERVICE_URL=http://users:5000
- EXERCISES_SERVICE_URL=http://exercises:5000
depends_on:
- users
- scores-db
- exercises

scores-db:
build:
context: ./services/scores/project/db
dockerfile: Dockerfile
ports:
- 5438:5432
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
29 changes: 29 additions & 0 deletions docker-compose-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ services:
- REACT_APP_USERS_SERVICE_URL=${REACT_APP_USERS_SERVICE_URL}
- REACT_APP_API_GATEWAY_URL=${REACT_APP_API_GATEWAY_URL}
- REACT_APP_EXERCISES_SERVICE_URL=${REACT_APP_EXERCISES_SERVICE_URL}
- REACT_APP_SCORES_SERVICE_URL=${REACT_APP_SCORES_SERVICE_URL}
expose:
- 80
depends_on:
Expand Down Expand Up @@ -88,3 +89,31 @@ services:
- URL=swagger.json
depends_on:
- users

scores:
build:
context: ./services/scores
dockerfile: Dockerfile-prod
expose:
- 5000
environment:
- FLASK_ENV=production
- APP_SETTINGS=project.config.StagingConfig
- DATABASE_URL=postgres://postgres:postgres@scores-db:5432/scores_prod
- DATABASE_TEST_URL=postgres://postgres:postgres@scores-db:5432/scores_test
- USERS_SERVICE_URL=${REACT_APP_USERS_SERVICE_URL}
- EXERCISES_SERVICE_URL=${REACT_APP_EXERCISES_SERVICE_URL}
depends_on:
- users
- scores-db
- exercises

scores-db:
build:
context: ./services/scores/project/db
dockerfile: Dockerfile
expose:
- 5432
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
29 changes: 29 additions & 0 deletions docker-compose-stage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ services:
- REACT_APP_USERS_SERVICE_URL=${REACT_APP_USERS_SERVICE_URL}
- REACT_APP_API_GATEWAY_URL=${REACT_APP_API_GATEWAY_URL}
- REACT_APP_EXERCISES_SERVICE_URL=${REACT_APP_EXERCISES_SERVICE_URL}
- REACT_APP_SCORES_SERVICE_URL=${REACT_APP_SCORES_SERVICE_URL}
expose:
- 80
depends_on:
Expand Down Expand Up @@ -88,3 +89,31 @@ services:
depends_on:
- users
- client

scores:
build:
context: ./services/scores
dockerfile: Dockerfile-stage
expose:
- 5000
environment:
- FLASK_ENV=production
- APP_SETTINGS=project.config.StagingConfig
- DATABASE_URL=postgres://postgres:postgres@scores-db:5432/scores_stage
- DATABASE_TEST_URL=postgres://postgres:postgres@scores-db:5432/scores_test
- USERS_SERVICE_URL=${REACT_APP_USERS_SERVICE_URL}
- EXERCISES_SERVICE_URL=${REACT_APP_EXERCISES_SERVICE_URL}
depends_on:
- users
- scores-db
- exercises

scores-db:
build:
context: ./services/scores/project/db
dockerfile: Dockerfile
expose:
- 5432
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
10 changes: 10 additions & 0 deletions docker-push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ then
export DOCKER_ENV=stage
export REACT_APP_USERS_SERVICE_URL="http://testdriven-staging-alb-2001734548.us-west-1.elb.amazonaws.com"
export REACT_APP_EXERCISES_SERVICE_URL="http://testdriven-staging-alb-2001734548.us-west-1.elb.amazonaws.com"
export REACT_APP_SCORES_SERVICE_URL="http://testdriven-staging-alb-2001734548.us-west-1.elb.amazonaws.com"
elif [[ "$TRAVIS_BRANCH" == "production" ]]; then
export DOCKER_ENV=prod
export REACT_APP_USERS_SERVICE_URL="http://testdriven-production-alb-2116729726.us-west-1.elb.amazonaws.com"
export REACT_APP_EXERCISES_SERVICE_URL="http://testdriven-production-alb-2116729726.us-west-1.elb.amazonaws.com"
export REACT_APP_SCORES_SERVICE_URL="http://testdriven-production-alb-2116729726.us-west-1.elb.amazonaws.com"
export DATABASE_URL="$AWS_RDS_URI"
export SECRET_KEY="$PRODUCTION_SECRET_KEY"
fi
Expand Down Expand Up @@ -55,5 +57,13 @@ then
docker build $EXERCISES_DB_REPO -t $EXERCISES_DB:$COMMIT -f Dockerfile
docker tag $EXERCISES_DB:$COMMIT $REPO/$EXERCISES_DB:$TAG
docker push $REPO/$EXERCISES_DB:$TAG
# scores
docker build $SCORES_REPO -t $SCORES:$COMMIT -f Dockerfile-$DOCKER_ENV
docker tag $SCORES:$COMMIT $REPO/$SCORES:$TAG
docker push $REPO/$SCORES:$TAG
# scores db
docker build $SCORES_DB_REPO -t $SCORES_DB:$COMMIT -f Dockerfile
docker tag $SCORES_DB:$COMMIT $REPO/$SCORES_DB:$TAG
docker push $REPO/$SCORES_DB:$TAG
fi
fi
10 changes: 10 additions & 0 deletions init_db.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

# create
docker-compose -f docker-compose-dev.yml exec exercises python manage.py recreate_db
docker-compose -f docker-compose-dev.yml exec users python manage.py recreate_db
docker-compose -f docker-compose-dev.yml exec scores python manage.py recreate_db
# seed
docker-compose -f docker-compose-dev.yml exec exercises python manage.py seed_db
docker-compose -f docker-compose-dev.yml exec users python manage.py seed_db
docker-compose -f docker-compose-dev.yml exec scores python manage.py seed_db
2 changes: 2 additions & 0 deletions services/client/Dockerfile-prod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ ARG REACT_APP_API_GATEWAY_URL
ENV REACT_APP_API_GATEWAY_URL $REACT_APP_API_GATEWAY_URL
ARG REACT_APP_EXERCISES_SERVICE_URL
ENV REACT_APP_EXERCISES_SERVICE_URL $REACT_APP_EXERCISES_SERVICE_URL
ARG REACT_APP_SCORES_SERVICE_URL
ENV REACT_APP_SCORES_SERVICE_URL $REACT_APP_SCORES_SERVICE_URL

# create build
COPY . /usr/src/app
Expand Down
2 changes: 2 additions & 0 deletions services/client/Dockerfile-stage
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ ARG REACT_APP_API_GATEWAY_URL
ENV REACT_APP_API_GATEWAY_URL $REACT_APP_API_GATEWAY_URL
ARG REACT_APP_EXERCISES_SERVICE_URL
ENV REACT_APP_EXERCISES_SERVICE_URL $REACT_APP_EXERCISES_SERVICE_URL
ARG REACT_APP_SCORES_SERVICE_URL
ENV REACT_APP_SCORES_SERVICE_URL $REACT_APP_SCORES_SERVICE_URL

# create build
COPY . /usr/src/app
Expand Down
1 change: 1 addition & 0 deletions services/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"axios": "^0.18.0",
"prop-types": "^15.6.2",
"react": "^16.7.0",
"react-ace": "^6.3.2",
"react-dom": "^16.7.0",
Expand Down
8 changes: 8 additions & 0 deletions services/client/src/components/AddUser.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';

const AddUser = (props) => {
return (
Expand Down Expand Up @@ -34,4 +35,11 @@ const AddUser = (props) => {
)
};

AddUser.propTypes = {
username: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
handleChange: PropTypes.func.isRequired,
addUser: PropTypes.func.isRequired,
};

export default AddUser;
87 changes: 87 additions & 0 deletions services/client/src/components/Exercise.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React from 'react';
import AceEditor from 'react-ace';
import PropTypes from 'prop-types';
import 'brace/mode/python';
import 'brace/theme/solarized_dark';


const Exercise = (props) => {
return (
<div key={props.exercise.id}>
<h5 className="title is-5">{props.exercise.body}</h5>
<AceEditor
mode="python"
theme="solarized_dark"
name={(props.exercise.id).toString()}
fontSize={14}
height={'175px'}
showPrintMargin={true}
showGutter={true}
highlightActiveLine={true}
value={props.editor.value}
style={{
marginBottom: '10px'
}}
editorProps={{
$blockScrolling: Infinity
}}
onChange={props.onChange}
/>
{props.isAuthenticated &&
<div>
<button
className="button is-primary"
onClick={(evt) => props.submitExercise(evt, props.exercise.id)}
disabled={props.editor.button.isDisabled}
>Run Code</button>
{props.editor.showGrading &&
<h5 className="title is-5">
<span className="icon is-large">
<i className="fas fa-spinner fa-pulse"></i>
</span>
<span className="grade-text">Grading...</span>
</h5>
}
{props.editor.showCorrect &&
<h5 className="title is-5">
<span className="icon is-large">
<i className="fas fa-check"></i>
</span>
<span className="grade-text">Correct!</span>
</h5>
}
{props.editor.showIncorrect &&
<h5 className="title is-5">
<span className="icon is-large">
<i className="fas fa-times"></i>
</span>
<span className="grade-text">Incorrect!</span>
</h5>
}
</div>
}
<br/><br/>
</div>
)
};

Exercise.propTypes = {
exercise: PropTypes.shape({
body: PropTypes.string.isRequired,
id: PropTypes.number.isRequired,
test_code: PropTypes.string.isRequired,
test_code_solution: PropTypes.string.isRequired,
}).isRequired,
editor: PropTypes.shape({
button: PropTypes.object.isRequired,
showCorrect: PropTypes.bool.isRequired,
showGrading: PropTypes.bool.isRequired,
showIncorrect: PropTypes.bool.isRequired,
value: PropTypes.string.isRequired,
}).isRequired,
isAuthenticated: PropTypes.bool.isRequired,
onChange: PropTypes.func.isRequired,
submitExercise: PropTypes.func.isRequired,
};

export default Exercise;
Loading

0 comments on commit 88163b7

Please sign in to comment.