2016-03-29 16:41:24 +08:00
|
|
|
import React from 'react';
|
|
|
|
import ReactDOM from 'react-dom';
|
|
|
|
import {
|
2015-12-05 09:13:04 +08:00
|
|
|
findRenderedDOMComponentWithClass,
|
|
|
|
scryRenderedDOMComponentsWithClass,
|
|
|
|
Simulate,
|
2017-06-25 16:24:25 +08:00
|
|
|
} from 'react-dom/test-utils';
|
2016-03-29 16:41:24 +08:00
|
|
|
|
|
|
|
import EditableList from '../../src/components/editable-list';
|
2017-09-27 02:55:33 +08:00
|
|
|
import { renderIntoDocument, simulateCommand } from '../mailspring-test-utils';
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
const { findDOMNode } = ReactDOM;
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
const makeList = (items = [], props = {}) => {
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = renderIntoDocument(<EditableList {...props} items={items} />);
|
2016-03-04 04:37:20 +08:00
|
|
|
if (props.initialState) {
|
2017-09-27 02:55:33 +08:00
|
|
|
list.setState(props.initialState);
|
2016-03-04 04:37:20 +08:00
|
|
|
}
|
2017-09-27 02:55:33 +08:00
|
|
|
return list;
|
2015-12-05 09:13:04 +08:00
|
|
|
};
|
|
|
|
|
2016-05-05 05:03:15 +08:00
|
|
|
describe('EditableList', function editableList() {
|
2016-05-06 13:30:34 +08:00
|
|
|
describe('_onItemClick', () => {
|
|
|
|
it('calls onSelectItem', () => {
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
const onSelectItem = jasmine.createSpy('onSelectItem');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { onSelectItem });
|
2015-12-05 09:13:04 +08:00
|
|
|
const item = scryRenderedDOMComponentsWithClass(list, 'editable-item')[0];
|
|
|
|
|
|
|
|
Simulate.click(item);
|
|
|
|
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
expect(onSelectItem).toHaveBeenCalledWith('1', 0);
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
describe('_onItemEdit', () => {
|
|
|
|
it('enters editing mode when double click', () => {
|
2015-12-12 03:03:59 +08:00
|
|
|
const list = makeList(['1', '2']);
|
|
|
|
spyOn(list, 'setState');
|
|
|
|
const item = scryRenderedDOMComponentsWithClass(list, 'editable-item')[0];
|
|
|
|
|
|
|
|
Simulate.doubleClick(item);
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
expect(list.setState).toHaveBeenCalledWith({ editingIndex: 0 });
|
2015-12-12 03:03:59 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('enters editing mode when edit icon clicked', () => {
|
2015-12-12 03:03:59 +08:00
|
|
|
const list = makeList(['1', '2']);
|
|
|
|
spyOn(list, 'setState');
|
|
|
|
const editIcon = scryRenderedDOMComponentsWithClass(list, 'edit-icon')[0];
|
|
|
|
|
|
|
|
Simulate.click(editIcon);
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
expect(list.setState).toHaveBeenCalledWith({ editingIndex: 0 });
|
2015-12-15 06:29:45 +08:00
|
|
|
});
|
2015-12-12 03:03:59 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
describe('core:previous-item / core:next-item', () => {
|
|
|
|
it('calls onSelectItem', () => {
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
const onSelectItem = jasmine.createSpy('onSelectItem');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { selected: '1', onSelectItem });
|
2015-12-05 09:13:04 +08:00
|
|
|
const innerList = findRenderedDOMComponentWithClass(list, 'items-wrapper');
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
simulateCommand(innerList, 'core:next-item');
|
2015-12-05 09:13:04 +08:00
|
|
|
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
expect(onSelectItem).toHaveBeenCalledWith('2', 1);
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
2015-12-12 03:03:59 +08:00
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('does not select an item when at the bottom of the list and moves down', () => {
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
const onSelectItem = jasmine.createSpy('onSelectItem');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { selected: '2', onSelectItem });
|
2015-12-12 03:03:59 +08:00
|
|
|
const innerList = findRenderedDOMComponentWithClass(list, 'items-wrapper');
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
simulateCommand(innerList, 'core:next-item');
|
2015-12-12 03:03:59 +08:00
|
|
|
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
expect(onSelectItem).not.toHaveBeenCalled();
|
2015-12-12 03:03:59 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('does not select an item when at the top of the list and moves up', () => {
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
const onSelectItem = jasmine.createSpy('onSelectItem');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { selected: '1', onSelectItem });
|
2015-12-12 03:03:59 +08:00
|
|
|
const innerList = findRenderedDOMComponentWithClass(list, 'items-wrapper');
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
simulateCommand(innerList, 'core:previous-item');
|
2015-12-12 03:03:59 +08:00
|
|
|
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
expect(onSelectItem).not.toHaveBeenCalled();
|
2015-12-15 06:29:45 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('does not clear the selection when esc pressed but prop does not allow it', () => {
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
const onSelectItem = jasmine.createSpy('onSelectItem');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], {
|
|
|
|
selected: '1',
|
|
|
|
allowEmptySelection: false,
|
|
|
|
onSelectItem,
|
|
|
|
});
|
2015-12-15 06:29:45 +08:00
|
|
|
const innerList = findRenderedDOMComponentWithClass(list, 'items-wrapper');
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
Simulate.keyDown(innerList, { key: 'Escape' });
|
2015-12-15 06:29:45 +08:00
|
|
|
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
expect(onSelectItem).not.toHaveBeenCalled();
|
2015-12-15 06:29:45 +08:00
|
|
|
});
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
describe('_onCreateInputKeyDown', () => {
|
|
|
|
it('calls onItemCreated', () => {
|
2015-12-08 04:38:38 +08:00
|
|
|
const onItemCreated = jasmine.createSpy('onItemCreated');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { initialState: { creatingItem: true }, onItemCreated });
|
2015-12-08 07:59:24 +08:00
|
|
|
const createItem = findRenderedDOMComponentWithClass(list, 'create-item-input');
|
2016-03-29 16:41:24 +08:00
|
|
|
const input = createItem.querySelector('input');
|
2015-12-08 04:38:38 +08:00
|
|
|
findDOMNode(input).value = 'New Item';
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
Simulate.keyDown(input, { key: 'Enter' });
|
2015-12-08 04:38:38 +08:00
|
|
|
|
|
|
|
expect(onItemCreated).toHaveBeenCalledWith('New Item');
|
|
|
|
});
|
2016-02-02 04:45:52 +08:00
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('does not call onItemCreated when no value entered', () => {
|
2016-02-02 04:45:52 +08:00
|
|
|
const onItemCreated = jasmine.createSpy('onItemCreated');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { initialState: { creatingItem: true }, onItemCreated });
|
2016-02-02 04:45:52 +08:00
|
|
|
const createItem = findRenderedDOMComponentWithClass(list, 'create-item-input');
|
2016-03-29 16:41:24 +08:00
|
|
|
const input = createItem.querySelector('input');
|
2016-02-02 04:45:52 +08:00
|
|
|
findDOMNode(input).value = '';
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
Simulate.keyDown(input, { key: 'Enter' });
|
2016-02-02 04:45:52 +08:00
|
|
|
|
|
|
|
expect(onItemCreated).not.toHaveBeenCalled();
|
|
|
|
});
|
2015-12-08 04:38:38 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
describe('_onCreateItem', () => {
|
|
|
|
it('should call prop callback when provided', () => {
|
2015-12-08 04:38:38 +08:00
|
|
|
const onCreateItem = jasmine.createSpy('onCreateItem');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { onCreateItem });
|
2015-12-08 04:38:38 +08:00
|
|
|
|
|
|
|
list._onCreateItem();
|
|
|
|
expect(onCreateItem).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('should set state for creating item when no callback provided', () => {
|
2015-12-08 04:38:38 +08:00
|
|
|
const list = makeList(['1', '2']);
|
|
|
|
spyOn(list, 'setState');
|
|
|
|
list._onCreateItem();
|
2017-09-27 02:55:33 +08:00
|
|
|
expect(list.setState).toHaveBeenCalledWith({ creatingItem: true });
|
2015-12-08 04:38:38 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-07-12 03:28:37 +08:00
|
|
|
describe('_onDeleteItem', () => {
|
|
|
|
let onSelectItem;
|
|
|
|
let onDeleteItem;
|
|
|
|
beforeEach(() => {
|
|
|
|
onSelectItem = jasmine.createSpy('onSelectItem');
|
|
|
|
onDeleteItem = jasmine.createSpy('onDeleteItem');
|
2017-09-27 02:55:33 +08:00
|
|
|
});
|
2016-07-12 03:28:37 +08:00
|
|
|
it('deletes the item from the list', () => {
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { selected: '2', onDeleteItem, onSelectItem });
|
2016-07-12 03:28:37 +08:00
|
|
|
const button = scryRenderedDOMComponentsWithClass(list, 'btn-editable-list')[1];
|
|
|
|
|
|
|
|
Simulate.click(button);
|
|
|
|
expect(onDeleteItem).toHaveBeenCalledWith('2', 1);
|
2017-09-27 02:55:33 +08:00
|
|
|
});
|
2016-07-12 03:28:37 +08:00
|
|
|
it('sets the selected item to the one above if it exists', () => {
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { selected: '2', onDeleteItem, onSelectItem });
|
2016-07-12 03:28:37 +08:00
|
|
|
const button = scryRenderedDOMComponentsWithClass(list, 'btn-editable-list')[1];
|
|
|
|
|
|
|
|
Simulate.click(button);
|
2017-09-27 02:55:33 +08:00
|
|
|
expect(onSelectItem).toHaveBeenCalledWith('1', 0);
|
|
|
|
});
|
2016-07-12 03:28:37 +08:00
|
|
|
it('sets the selected item to the one below if it is at the top', () => {
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { selected: '1', onDeleteItem, onSelectItem });
|
2016-07-12 03:28:37 +08:00
|
|
|
const button = scryRenderedDOMComponentsWithClass(list, 'btn-editable-list')[1];
|
|
|
|
|
|
|
|
Simulate.click(button);
|
2017-09-27 02:55:33 +08:00
|
|
|
expect(onSelectItem).toHaveBeenCalledWith('2', 1);
|
|
|
|
});
|
2016-07-12 03:28:37 +08:00
|
|
|
it('sets the selected item to nothing when you delete the last item', () => {
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1'], { selected: '1', onDeleteItem, onSelectItem });
|
2016-07-12 03:28:37 +08:00
|
|
|
const button = scryRenderedDOMComponentsWithClass(list, 'btn-editable-list')[1];
|
|
|
|
|
|
|
|
Simulate.click(button);
|
2017-09-27 02:55:33 +08:00
|
|
|
expect(onSelectItem).not.toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
2016-05-06 13:30:34 +08:00
|
|
|
describe('_renderItem', () => {
|
|
|
|
const makeItem = (item, idx, state = {}, handlers = {}) => {
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList([], { initialState: state });
|
|
|
|
return renderIntoDocument(list._renderItem(item, idx, state, handlers));
|
2015-12-05 09:13:04 +08:00
|
|
|
};
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('binds correct click callbacks', () => {
|
2015-12-05 09:13:04 +08:00
|
|
|
const onClick = jasmine.createSpy('onClick');
|
2015-12-12 03:03:59 +08:00
|
|
|
const onEdit = jasmine.createSpy('onEdit');
|
2017-09-27 02:55:33 +08:00
|
|
|
const item = makeItem('item 1', 0, {}, { onClick, onEdit });
|
2015-12-05 09:13:04 +08:00
|
|
|
|
|
|
|
Simulate.click(item);
|
|
|
|
expect(onClick.calls[0].args[1]).toEqual('item 1');
|
|
|
|
expect(onClick.calls[0].args[2]).toEqual(0);
|
|
|
|
|
|
|
|
Simulate.doubleClick(item);
|
2015-12-12 03:03:59 +08:00
|
|
|
expect(onEdit.calls[0].args[1]).toEqual('item 1');
|
|
|
|
expect(onEdit.calls[0].args[2]).toEqual(0);
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('renders correctly when item is selected', () => {
|
2017-09-27 02:55:33 +08:00
|
|
|
const item = findDOMNode(makeItem('item 1', 0, { selected: 'item 1' }));
|
2015-12-05 09:13:04 +08:00
|
|
|
expect(item.className.indexOf('selected')).not.toEqual(-1);
|
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('renders correctly when item is string', () => {
|
2015-12-05 09:13:04 +08:00
|
|
|
const item = findDOMNode(makeItem('item 1', 0));
|
|
|
|
expect(item.className.indexOf('selected')).toEqual(-1);
|
|
|
|
expect(item.className.indexOf('editable-item')).not.toEqual(-1);
|
2016-04-13 07:58:45 +08:00
|
|
|
expect(item.innerText).toEqual('item 1');
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('renders correctly when item is component', () => {
|
2016-10-18 08:59:33 +08:00
|
|
|
const item = findDOMNode(makeItem(<div />, 0));
|
2015-12-05 09:13:04 +08:00
|
|
|
expect(item.className.indexOf('selected')).toEqual(-1);
|
|
|
|
expect(item.className.indexOf('editable-item')).toEqual(-1);
|
|
|
|
expect(item.childNodes[0].tagName).toEqual('DIV');
|
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('renders correctly when item is in editing state', () => {
|
2015-12-05 09:13:04 +08:00
|
|
|
const onInputBlur = jasmine.createSpy('onInputBlur');
|
|
|
|
const onInputFocus = jasmine.createSpy('onInputFocus');
|
|
|
|
const onInputKeyDown = jasmine.createSpy('onInputKeyDown');
|
|
|
|
|
2017-09-27 02:55:33 +08:00
|
|
|
const item = makeItem(
|
|
|
|
'item 1',
|
|
|
|
0,
|
|
|
|
{ editingIndex: 0 },
|
|
|
|
{ onInputBlur, onInputFocus, onInputKeyDown }
|
|
|
|
);
|
|
|
|
const input = item.querySelector('input');
|
2015-12-05 09:13:04 +08:00
|
|
|
|
|
|
|
Simulate.focus(input);
|
|
|
|
Simulate.keyDown(input);
|
|
|
|
Simulate.blur(input);
|
|
|
|
|
|
|
|
expect(onInputFocus).toHaveBeenCalled();
|
|
|
|
expect(onInputBlur).toHaveBeenCalled();
|
|
|
|
expect(onInputKeyDown.calls[0].args[1]).toEqual('item 1');
|
|
|
|
expect(onInputKeyDown.calls[0].args[2]).toEqual(0);
|
|
|
|
|
|
|
|
expect(findDOMNode(input).tagName).toEqual('INPUT');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
describe('render', () => {
|
|
|
|
it('renders list of items', () => {
|
2015-12-05 09:13:04 +08:00
|
|
|
const items = ['1', '2', '3'];
|
|
|
|
const list = makeList(items);
|
|
|
|
const innerList = findDOMNode(
|
2015-12-10 04:35:40 +08:00
|
|
|
findRenderedDOMComponentWithClass(list, 'scroll-region-content-inner')
|
2015-12-05 09:13:04 +08:00
|
|
|
);
|
2016-05-06 13:30:34 +08:00
|
|
|
expect(() => {
|
2015-12-08 07:59:24 +08:00
|
|
|
findRenderedDOMComponentWithClass(list, 'create-item-input');
|
2015-12-08 04:38:38 +08:00
|
|
|
}).toThrow();
|
|
|
|
|
2015-12-05 09:13:04 +08:00
|
|
|
expect(innerList.childNodes.length).toEqual(3);
|
2016-05-06 13:30:34 +08:00
|
|
|
items.forEach((item, idx) => expect(innerList.childNodes[idx].textContent).toEqual(item));
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('renders create input as an item when creating', () => {
|
2015-12-08 04:38:38 +08:00
|
|
|
const items = ['1', '2', '3'];
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(items, { initialState: { creatingItem: true } });
|
2015-12-08 07:59:24 +08:00
|
|
|
const createItem = findRenderedDOMComponentWithClass(list, 'create-item-input');
|
2015-12-08 04:38:38 +08:00
|
|
|
expect(createItem).toBeDefined();
|
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('renders add button', () => {
|
2015-12-08 04:38:38 +08:00
|
|
|
const list = makeList();
|
2015-12-05 09:13:04 +08:00
|
|
|
const button = scryRenderedDOMComponentsWithClass(list, 'btn-editable-list')[0];
|
|
|
|
|
2015-12-08 04:38:38 +08:00
|
|
|
expect(findDOMNode(button).textContent).toEqual('+');
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
|
|
|
|
2016-05-06 13:30:34 +08:00
|
|
|
it('renders delete button', () => {
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { selected: '2' });
|
2015-12-05 09:13:04 +08:00
|
|
|
const button = scryRenderedDOMComponentsWithClass(list, 'btn-editable-list')[1];
|
|
|
|
|
2015-12-08 04:38:38 +08:00
|
|
|
expect(findDOMNode(button).textContent).toEqual('—');
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
|
2016-07-12 03:28:37 +08:00
|
|
|
it('disables the delete button when no item is selected', () => {
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
const onSelectItem = jasmine.createSpy('onSelectItem');
|
|
|
|
const onDeleteItem = jasmine.createSpy('onDeleteItem');
|
2017-09-27 02:55:33 +08:00
|
|
|
const list = makeList(['1', '2'], { selected: null, onDeleteItem, onSelectItem });
|
feat(mail-rules): Per-account mail rules filter incoming, existing mail
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
2015-12-23 15:19:32 +08:00
|
|
|
const button = scryRenderedDOMComponentsWithClass(list, 'btn-editable-list')[1];
|
|
|
|
|
|
|
|
Simulate.click(button);
|
|
|
|
|
|
|
|
expect(onDeleteItem).not.toHaveBeenCalledWith('2', 1);
|
|
|
|
});
|
2015-12-05 09:13:04 +08:00
|
|
|
});
|
|
|
|
});
|