Skip to content
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ node_js:
addons:
postgresql: "9.6"
script: ./go test

5 changes: 2 additions & 3 deletions src/browser/components/common/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import ApprovalPage from '../pages/approval/index'
import Profile from '../pages/profile/index'
import Requests from './requests'

constructor(props) {
export default class Routes extends Component {
constructor(props) {
super(props)
this.state = {user: {},
topics: [],
Expand All @@ -24,8 +24,7 @@ export default class Routes extends Component {
componentDidMount() {
Promise.all([Requests.get('/api/users/current_user'), Requests.get('/api/topics/'), Requests.get('/api/topics/with-questions')])
.then(([user, topicsResponse, topicsWithQuestionsResponse]) => {
let currentState = this.state
this.setState(Object.assign(currentState, {user: user, topics: topicsResponse.topics, topicsWithQuestions: topicsWithQuestionsResponse, message: topicsResponse.message}))
this.setState(Object.assign(this.state, { user: user, topics: topicsResponse.topics, topicsWithQuestions: topicsWithQuestionsResponse.topics }))
})
}

Expand Down
2 changes: 1 addition & 1 deletion src/browser/components/pages/approval/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class ApprovalPage extends Component {
super(props)
this.inputModules = inputModules
Request.get('/api/topics/')
.then(topics => this.inputModules[2].options = topics)
.then(topics => this.inputModules[2].options = topics.topics)
this.state = {questions: [], id: 0, filter: "All", triggerState: true, currentQuestion: null, inputModules: this.inputModules}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ exports.up = function(knex, Promise) {
return Promise.all([
knex.schema.createTable('interviews', function(table) {
table.integer('user_id')
table.foreign('user_id').references('users.id')
table.foreign('user_id').references('users.id').onDelete('cascade')
table.text('feedback');
}),
])
Expand Down
27 changes: 19 additions & 8 deletions src/database/queries/questions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const create = ( question ) => {
is_approved : false,
level : question.level,
answer : question.answer,
game_mode : question.game_mode,
// game_mode : question.game_mode,
points : question.points}, 'id')
.then( newQuestionID => {
return knex('hints')
Expand All @@ -22,7 +22,7 @@ const create = ( question ) => {
.from('topics')
.whereIn('name',question.topics)
.then( topicIDs => {
if(topicIDs.length != question.topics.length){
if(topicIDs.length === 0 ){
return Promise.reject(new Error('topic not found'))
}
return knex('questionTopics')
Expand Down Expand Up @@ -75,7 +75,7 @@ const updatebyID = ( question ) => {
question : question.question,
level : question.level,
answer : question.answer,
game_mode: question.game_mode,
// game_mode: question.game_mode,
points : question.points,
is_approved : question.is_approved},
'id')
Expand All @@ -102,6 +102,10 @@ const updatebyID = ( question ) => {
.then(trx.commit)
.catch(trx.rollback)
})
.then(function(resp) {
return question
})
.catch(err => {err})
}

const findbyID = ( data ) => {
Expand All @@ -111,7 +115,8 @@ const findbyID = ( data ) => {
.where( 'questions.id', data)
.innerJoin('questionTopics','questions.id','questionTopics.question_id')
.innerJoin('topics','questionTopics.topic_id','topics.id')
.innerJoin('hints','questions.id','hints.question_id').then( results => {
.leftJoin('hints','questions.id','hints.question_id')
.then( results => {
return hintTopicMiddleWare(results)[0]
})
}
Expand Down Expand Up @@ -172,7 +177,8 @@ const deletebyID = ( data ) => {
.del()
}

function hintTopicMiddleWare(array){
// function hintTopicMiddleWare(array){
const hintTopicMiddleWare = (array) => {
var newObj = array.reduce(function(obj,question){
if(obj[question.id]){
if(!obj[question.id].topics.includes(question.topics)){
Expand All @@ -184,7 +190,11 @@ function hintTopicMiddleWare(array){
}else{
obj[question.id] = question
question.topics = [question.topics]
question.hints = [question.hints]
if(question.hints === null) {
question.hints = []
} else {
question.hints = [question.hints]
}
}
return obj
},{})
Expand All @@ -198,6 +208,7 @@ export {
findbyLevel,
findAllQuestions,
updatebyID,
findbyApproval,
deletebyID
findByApproval,
deletebyID,
hintTopicMiddleWare
}
2 changes: 1 addition & 1 deletion src/database/queries/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const findbyName = ( data ) =>
.then(user => user)

const updatebyGithub = ( data, attributes ) =>
utilities.update('users', 'github_handle', data.github_handle, attributes)
utilities.update('users', 'github_handle', data, attributes)
.then(users => users)

const updatebyName = ( data, attributes ) =>
Expand Down
12 changes: 7 additions & 5 deletions src/server/routes/questions.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ router.get('/approval', (request, response) => {
router.delete('/approval/:id', (request, response) => {
const { id } = request.params
questions.deletebyID( id )
.then( () => response.json( { 'message': 'deleted' } ) )
.then( () => response.json( { 'message': 'deleted', 'id': id } ) )
.catch( err => console.log('err', err) )
})

Expand All @@ -39,7 +39,9 @@ router.post('/', (request, response) => {
}
//TODO need to findOrCreate Topics if they don't exist;
questions.create( attributes )
.then( (question) => response.json( question ) )
.then( (questionId) => {
response.json( questionId )
})
.catch( err => response.status(400).json({error: 'Could not create the question.', errorMsg: err.message, params: attributes}) )
})

Expand All @@ -52,9 +54,9 @@ router.put('/approval/:id', (request, response) => {

router.get('/:id', (request, response) => {
const { id } = request.params
const attributes = request.body
questions.findbyID( id, attributes )
.then( question => response.json( question ) )
questions.findbyID( parseInt(id) )
.then( question => {
return response.json( question )} )
.catch( err => console.log('err', err) )
})

Expand Down
14 changes: 10 additions & 4 deletions src/server/routes/topics.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ const router = express.Router()

router.get('/', (request, response) => {
topics.all()
.then(results => response.json({message: "Retrieved all topics", topics: results}))
.catch( err => console.log('err', err) )
.then(results => response.json( { message: 'Successfully got back topics', topics: results } ))
.catch( err => {
console.log('err', err)
response.json( { error: err.message } )
} )
})

router.get('/with-questions', (request, response) => {
topics.withQuestions()
.then(results => response.json(results))
.catch( err => console.log('err', err) )
.then(results => response.json({ message: 'Successfully got back topics with questions', topics: results }))
.catch( err => {
console.log('err', err)
response.json( { error: err.message } )
} )
})

export default router
19 changes: 19 additions & 0 deletions test/browser/components/atoms/form-input-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react'
import { expect } from 'chai'
import { shallow, mount } from 'enzyme'
import { jsdom } from 'jsdom'

import FormInput from '../../../src/browser/components/atoms/form-input/index'

describe('<FormInput />', () => {

it('should return a div', () => {
const wrapper = shallow(<FormInput />)
expect(wrapper.find('div.uk-form-controls')).to.have.length(1)
})

it('should have an input field inside the main div', () => {
const wrapper = mount(<FormInput />)
expect(wrapper.find('input.form-horizontal-text')).to.have.length(1)
})
})
22 changes: 22 additions & 0 deletions test/browser/components/atoms/profile-box-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react'
import { expect } from 'chai'
import { shallow, mount } from 'enzyme'
import { jsdom } from 'jsdom'

import ProfileBox from '../../../src/browser/components/atoms/profile-box/index'

describe('<ProfileBox />', () => {

it('should return a div', () => {
const wrapper = shallow(<ProfileBox />)
expect(wrapper.children()).to.have.length(1)
})

it('the child element should be a div', () => {
const wrapper = mount(<ProfileBox />)
expect(wrapper.find('div.uk-grid-small').childAt(0).type()).to.equal('div')
})



});
48 changes: 48 additions & 0 deletions test/browser/components/atoms/select-tag-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react'
import { expect } from 'chai'
import { shallow, mount } from 'enzyme'
import { jsdom } from 'jsdom'

import SelectTag from '../../../src/browser/components/atoms/form-select/index'


describe('<SelectTag />', () => {
const label = 'difficulty'
const options = ['Javascript', 'SQL', 'http']
const value = 'SQL'

it('should return a div', () => {
const wrapper = shallow(<SelectTag options={[]} label={label} value={options[1]} />)
expect(wrapper.find('div.uk-margin')).to.have.length(1)
})

context('the outer div should contain two html elements', () => {
it('should have a label', () => {
const wrapper = mount(<SelectTag options={[]} label={label} value={options[1]} />)
expect(wrapper.find('div.uk-margin').childAt(0).type()).to.equal('label')
expect(wrapper.props().label).to.equal('difficulty')
})

it('should have a div', () => {
const wrapper = mount(<SelectTag options={[]} label={label} value={options[1]} />)
expect(wrapper.find('div.uk-margin').childAt(1).type()).to.equal('div')
})
})

context('inner divs child should be a select', () => {
it('is a selector', () => {
const wrapper = mount(<SelectTag options={[]} label={label} value={options[1]} />)
expect(wrapper.find('div.uk-form-controls').children().type()).to.equal('select')
})
it('should display a value', () => {
const wrapper = mount(<SelectTag options={[]} label={label} value={options[1]} />)
expect(wrapper.props().value).to.equal('SQL')
})
})

it('should render N+1 <option> tags', () => {
const wrapper = mount(<SelectTag options={options} label={label} />)
expect(wrapper.find('option').length).to.eql(3)
})

})
33 changes: 33 additions & 0 deletions test/browser/components/atoms/stat-box-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react'
import { expect } from 'chai'
import { shallow, mount } from 'enzyme'
import { jsdom } from 'jsdom'

global.document = jsdom('');
global.window = document.defaultView;

import StatBox from '../../../src/browser/components/atoms/stat-box/index'
import StatCounter from '../../../src/browser/components/atoms/stat-counter/index'

describe('<StatBox />', () => {

it('should return a div', () => {
const wrapper = shallow(<StatBox />)
expect(wrapper.find('div.uk-grid-small')).to.have.length(1)
})

context('should have a nested div', () => {
it('should have a div inside of the main div', () => {
const wrapper = mount(<StatBox />)
expect(wrapper.find('div.uk-grid-small').childAt(0).type()).to.equal('div')
expect(wrapper.find('div.uk-flex-left')).to.have.length(1)
})
})
context('inner div contains an instance of <StatCounter />', () => {
it('should render <StatCounter/>', () => {
const wrapper = mount(<StatBox />)
expect(wrapper.containsMatchingElement(<StatCounter />)).to.be.true
})
})

})
21 changes: 21 additions & 0 deletions test/browser/components/atoms/stat-counter-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import { expect } from 'chai'
import { shallow, mount } from 'enzyme'
import { jsdom } from 'jsdom'

global.document = jsdom('');
global.window = document.defaultView;

import StatCounter from '../../../src/browser/components/atoms/stat-counter/index'

describe('<StatCounter />', () => {
it('should contain a div', () => {
const wrapper = shallow(<StatCounter />)
expect(wrapper.find('div.uk-margin-small-left')).to.have.length(1)
})

it('should contain a nested div', () => {
const wrapper = mount(<StatCounter />)
expect(wrapper.find('div.uk-badge').exists()).to.be.true
})
})
26 changes: 26 additions & 0 deletions test/browser/components/common/routes-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'
import { Route } from 'react-router'
import { expect } from 'chai'
import { shallow, mount } from 'enzyme'

import jsdom from 'jsdom'
const doc = jsdom.jsdom('<!doctype html><html><body><div id="app"></div></body></html>')
global.document = doc
global.window = doc.defaultView

import Routes from '../../../src/browser/components/common/router'
import Landing from '../../../src/browser/components/pages/landing/index'

describe('<Routes />', () => {
it('should render correct routes', () => {
const wrapper = shallow( <Routes />)
const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
const routeProps = route.props()
pathMap[routeProps.path] = routeProps.component
return pathMap;
}, {})
//Note: commenting this out until the router.js file is fixed without
//needing the wrapper components to pass down the props
//expect(pathMap['/'].toString()).to.equal(Landing.toString())
})
})
Loading