diff --git a/client/components/__test__/FileNode.test.jsx b/client/components/__test__/FileNode.test.jsx
index 60eededb..b78d6ab2 100644
--- a/client/components/__test__/FileNode.test.jsx
+++ b/client/components/__test__/FileNode.test.jsx
@@ -2,19 +2,74 @@ import React from 'react';
import { shallow } from 'enzyme';
import { FileNode } from '../../modules/IDE/components/FileNode';
-beforeAll(() => {});
describe('', () => {
let component;
let props = {};
+ let input;
+ let renameTriggerButton;
+ const changeName = (newFileName) => {
+ renameTriggerButton.simulate('click');
+ input.simulate('change', { target: { value: newFileName } });
+ input.simulate('blur');
+ };
+ const getState = () => component.state();
+ const getUpdatedName = () => getState().updatedName;
- describe('with valid props', () => {
+ describe('with valid props, regardless of filetype', () => {
+ ['folder', 'file'].forEach((fileType) => {
+ beforeEach(() => {
+ props = {
+ ...props,
+ id: '0',
+ name: 'test.jsx',
+ fileType,
+ canEdit: true,
+ children: [],
+ authenticated: false,
+ setSelectedFile: jest.fn(),
+ deleteFile: jest.fn(),
+ updateFileName: jest.fn(),
+ resetSelectedFile: jest.fn(),
+ newFile: jest.fn(),
+ newFolder: jest.fn(),
+ showFolderChildren: jest.fn(),
+ hideFolderChildren: jest.fn(),
+ openUploadFileModal: jest.fn(),
+ setProjectName: jest.fn(),
+ };
+ component = shallow();
+ });
+
+ describe('when changing name', () => {
+ beforeEach(() => {
+ input = component.find('.sidebar__file-item-input');
+ renameTriggerButton = component
+ .find('.sidebar__file-item-option')
+ .first();
+ component.setState({ isEditing: true });
+ });
+
+ describe('to an empty name', () => {
+ const newName = '';
+ beforeEach(() => changeName(newName));
+
+ it('should not save', () => expect(props.updateFileName).not.toHaveBeenCalled());
+ it('should reset name', () => expect(getUpdatedName()).toEqual(props.name));
+ });
+ });
+ });
+ });
+
+ describe('as file with valid props', () => {
beforeEach(() => {
props = {
...props,
id: '0',
- children: [],
name: 'test.jsx',
- fileType: 'dunno',
+ fileType: 'file',
+ canEdit: true,
+ children: [],
+ authenticated: false,
setSelectedFile: jest.fn(),
deleteFile: jest.fn(),
updateFileName: jest.fn(),
@@ -23,22 +78,12 @@ describe('', () => {
newFolder: jest.fn(),
showFolderChildren: jest.fn(),
hideFolderChildren: jest.fn(),
- canEdit: true,
- authenticated: false,
openUploadFileModal: jest.fn()
};
component = shallow();
});
describe('when changing name', () => {
- let input;
- let renameTriggerButton;
- const changeName = (newFileName) => {
- renameTriggerButton.simulate('click');
- input.simulate('change', { target: { value: newFileName } });
- input.simulate('blur');
- };
-
beforeEach(() => {
input = component.find('.sidebar__file-item-input');
renameTriggerButton = component
@@ -59,13 +104,79 @@ describe('', () => {
});
});
- describe('to an empty filename', () => {
- const newName = '';
+ // Failure Scenarios
+
+ describe('to an extensionless filename', () => {
+ const newName = 'extensionless';
+ beforeEach(() => changeName(newName));
+ });
+ it('should not save', () => expect(props.setProjectName).not.toHaveBeenCalled());
+ it('should reset name', () => expect(getUpdatedName()).toEqual(props.name));
+ describe('to different extension', () => {
+ const newName = 'name.gif';
beforeEach(() => changeName(newName));
- it('should not save the name', () => {
- expect(props.updateFileName).not.toHaveBeenCalled();
- });
+ it('should not save', () => expect(props.setProjectName).not.toHaveBeenCalled());
+ it('should reset name', () => expect(getUpdatedName()).toEqual(props.name));
+ });
+
+ describe('to just an extension', () => {
+ const newName = '.jsx';
+ beforeEach(() => changeName(newName));
+
+ it('should not save', () => expect(props.updateFileName).not.toHaveBeenCalled());
+ it('should reset name', () => expect(getUpdatedName()).toEqual(props.name));
+ });
+ });
+ });
+
+
+ describe('as folder with valid props', () => {
+ beforeEach(() => {
+ props = {
+ ...props,
+ id: '0',
+ children: [],
+ name: 'filename',
+ fileType: 'folder',
+ canEdit: true,
+ authenticated: false,
+ setSelectedFile: jest.fn(),
+ deleteFile: jest.fn(),
+ updateFileName: jest.fn(),
+ resetSelectedFile: jest.fn(),
+ newFile: jest.fn(),
+ newFolder: jest.fn(),
+ showFolderChildren: jest.fn(),
+ hideFolderChildren: jest.fn(),
+ openUploadFileModal: jest.fn()
+ };
+ component = shallow();
+ });
+
+ describe('when changing name', () => {
+ beforeEach(() => {
+ input = component.find('.sidebar__file-item-input');
+ renameTriggerButton = component
+ .find('.sidebar__file-item-option')
+ .first();
+ component.setState({ isEditing: true });
+ });
+
+ describe('to a foldername', () => {
+ const newName = 'newfoldername';
+ beforeEach(() => changeName(newName));
+
+ it('should save', () => expect(props.updateFileName).toBeCalledWith(props.id, newName));
+ it('should update name', () => expect(getUpdatedName()).toEqual(newName));
+ });
+
+ describe('to a filename', () => {
+ const newName = 'filename.jsx';
+ beforeEach(() => changeName(newName));
+
+ it('should not save', () => expect(props.updateFileName).not.toHaveBeenCalled());
+ it('should reset name', () => expect(getUpdatedName()).toEqual(props.name));
});
});
});
diff --git a/client/components/__test__/Toolbar.test.jsx b/client/components/__test__/Toolbar.test.jsx
new file mode 100644
index 00000000..a64f6f2d
--- /dev/null
+++ b/client/components/__test__/Toolbar.test.jsx
@@ -0,0 +1,105 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import { ToolbarComponent } from '../../modules/IDE/components/Toolbar';
+
+
+const initialProps = {
+ isPlaying: false,
+ preferencesIsVisible: false,
+ stopSketch: jest.fn(),
+ setProjectName: jest.fn(),
+ openPreferences: jest.fn(),
+ showEditProjectName: jest.fn(),
+ hideEditProjectName: jest.fn(),
+ infiniteLoop: false,
+ autorefresh: false,
+ setAutorefresh: jest.fn(),
+ setTextOutput: jest.fn(),
+ setGridOutput: jest.fn(),
+ startSketch: jest.fn(),
+ startAccessibleSketch: jest.fn(),
+ saveProject: jest.fn(),
+ currentUser: 'me',
+ originalProjectName: 'testname',
+
+ owner: {
+ username: 'me'
+ },
+ project: {
+ name: 'testname',
+ isEditingName: false,
+ id: 'id',
+ },
+};
+
+
+describe('', () => {
+ let component;
+ let props = initialProps;
+ let input;
+ let renameTriggerButton;
+ const changeName = (newFileName) => {
+ component.find('.toolbar__project-name').simulate('click', { preventDefault: jest.fn() });
+ input = component.find('.toolbar__project-name-input');
+ renameTriggerButton = component.find('.toolbar__edit-name-button');
+ renameTriggerButton.simulate('click');
+ input.simulate('change', { target: { value: newFileName } });
+ input.simulate('blur');
+ };
+ const setProps = (additionalProps) => {
+ props = {
+ ...props,
+ ...additionalProps,
+
+ project: {
+ ...props.project,
+ ...(additionalProps || {}).project
+ },
+ };
+ };
+
+ // Test Cases
+
+ describe('with valid props', () => {
+ beforeEach(() => {
+ setProps();
+ component = shallow();
+ });
+ it('renders', () => expect(component).toBeDefined());
+
+ describe('when use owns sketch', () => {
+ beforeEach(() => setProps({ currentUser: props.owner.username }));
+
+ describe('when changing sketch name', () => {
+ beforeEach(() => {
+ setProps({
+ project: { isEditingName: true, name: 'testname' },
+ setProjectName: jest.fn(name => component.setProps({ project: { name } })),
+ });
+ component = shallow();
+ });
+
+ describe('to a valid name', () => {
+ beforeEach(() => changeName('hello'));
+ it('should save', () => expect(props.setProjectName).toBeCalledWith('hello'));
+ });
+
+
+ describe('to an empty name', () => {
+ beforeEach(() => changeName(''));
+ it('should set name to empty', () => expect(props.setProjectName).toBeCalledWith(''));
+ it(
+ 'should detect empty name and revert to original',
+ () => expect(props.setProjectName).toHaveBeenLastCalledWith(initialProps.project.name)
+ );
+ });
+ });
+ });
+
+ describe('when user does not own sketch', () => {
+ beforeEach(() => setProps({ currentUser: 'not-the-owner' }));
+
+ it('should disable edition', () => expect(component.find('.toolbar__edit-name-button')).toEqual({}));
+ });
+ });
+});
diff --git a/client/modules/IDE/components/Toolbar.jsx b/client/modules/IDE/components/Toolbar.jsx
index dd5010ca..b3d13364 100644
--- a/client/modules/IDE/components/Toolbar.jsx
+++ b/client/modules/IDE/components/Toolbar.jsx
@@ -214,4 +214,5 @@ const mapDispatchToProps = {
...projectActions,
};
+export const ToolbarComponent = Toolbar;
export default connect(mapStateToProps, mapDispatchToProps)(Toolbar);