Skip to content
This repository has been archived by the owner on Mar 24, 2022. It is now read-only.

Commit

Permalink
Partial implementation of #106346840
Browse files Browse the repository at this point in the history
Signed-off-by: David Alvarado <dalvarado@pivotal.io>
  • Loading branch information
zankich authored and dalvarado committed Nov 18, 2015
1 parent 876a948 commit 4621f2d
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE PROJECT ADD CONSTRAINT unique_name UNIQUE (NAME);
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,5 @@ public void contextLoads() {

}

@Test
public void thereExistsProjectData() {
Project project = new Project();

project.setName("Foo");

projectRepository.save(project);

}

}
22 changes: 21 additions & 1 deletion frontend/app/js/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,35 @@ import { pushState } from 'redux-router';
import 'es6-promise';

export const CREATE_PROJECT_SUCCESS = 'CREATE_PROJECT_SUCCESS';
export const CREATE_PROJECT_FAILURE = 'CREATE_PROJECT_FAILURE';


export function createProjectSuccess(payload) {
return {type: CREATE_PROJECT_SUCCESS, payload};
}

export function createProjectFailure(payload) {
return {type: CREATE_PROJECT_FAILURE, payload};
}

export function createProject(payload) {
return (dispatch) => {
return post(`${API_HOST_URL}/projects`, payload)
.then(() => dispatch(createProjectSuccess(payload)))
.then(() => dispatch(pushState(null, '/')));
.then(() => dispatch(pushState(null, '/')))
.catch(function (response) {
if (response instanceof Error) {
// Something happened in setting up the request that triggered an Error
console.log('Error', response.message);
} else {
// The request was made, but the server responded with a status code
// that falls out of the range of 2xx
let message = "An unknown error occurred";
if (response.status === 409) {
message = "Project name already exists";
}
dispatch(createProjectFailure({...payload, data: message}));
}
});
};
}
4 changes: 3 additions & 1 deletion frontend/app/js/reducers/alert.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { CREATE_PROJECT_SUCCESS } from '../actions';
import { CREATE_PROJECT_SUCCESS, CREATE_PROJECT_FAILURE } from '../actions';

export default function alert(state={}, action={}) {
switch(action.type) {
case CREATE_PROJECT_SUCCESS:
return {message: `${action.payload.name} was created`};
case CREATE_PROJECT_FAILURE:
return {message: `There was a problem creating ${action.payload.name}: ${action.payload.data}`}
default:
return state;
}
Expand Down
18 changes: 18 additions & 0 deletions frontend/test/actions_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,23 @@ describe('actions', () => {

store.dispatch(actions.createProject(fields));
});

it('creates a CREATE_PROJECT_FAILURE action after posting a duplicate project name', (done) => {
const fields = {name: 'Persephone'};
const expectedActions = [
{ type: actions.CREATE_PROJECT_FAILURE, payload: fields }
];

jasmine.Ajax.stubRequest(`${API_HOST_URL}/projects`, undefined, 'POST').andReturn({ status: 409 });

const store = mockStore({}, expectedActions, (err) => {
// error is non-null if there are extra actions we didn't specify; we can ignore these
//if (err) throw err;
expect(jasmine.Ajax.requests.mostRecent()).toBeDefined('Request was not called');
done();
});

store.dispatch(actions.createProject(fields));
});
});
});
10 changes: 9 additions & 1 deletion frontend/test/reducers/alert_spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import reducer from '../../app/js/reducers/alert';
import { CREATE_PROJECT_SUCCESS } from '../../app/js/actions';
import { CREATE_PROJECT_SUCCESS, CREATE_PROJECT_FAILURE } from '../../app/js/actions';


describe('alert reducer', () => {
it('initializes to a default state', () => {
Expand All @@ -12,4 +13,11 @@ describe('alert reducer', () => {
payload: {name: 'George', id: 12345}
})).toEqual({message: 'George was created'});
});

it('creates a new alert upon receiving a CREATE_PROJECT_FAILURE action', () => {
expect(reducer({}, {
type: CREATE_PROJECT_FAILURE,
payload: {name: 'George', data: "db error"}
})).toEqual({message: 'There was a problem creating George: db error'});
});
});
14 changes: 13 additions & 1 deletion integration_tests/spec/project_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
Capybara.default_driver = :poltergeist

describe 'Anchor configures a new project', type: :feature do

it 'creates a new project' do
navigates_to_new_project_page
saves_project
end

it 'displays an error alert on project name duplicate' do
navigates_to_new_project_page
saves_duplicate_project_name
end
end

def navigates_to_new_project_page
Expand All @@ -32,3 +35,12 @@ def saves_project
expect(page).to have_content(/My Lovely Project was created/)
expect(current_path).to eq '/'
end

def saves_duplicate_project_name
fill_in 'Name', with: 'My Lovely Project'
click_on 'Submit'

expect(page.status_code).to eq 200
expect(page).to have_content(/Project name already exists/)
expect(current_path).to eq '/projects/new'
end

0 comments on commit 4621f2d

Please sign in to comment.