More spec fixes
replace process.nextTick with setTimeout(fn, 0) for specs
Also added an unspy in the afterEach
Temporarily disable specs
fix(spec): start fixing specs
Summary:
This is the WIP fix to our spec runner.
Several tests have been completely commented out that will require
substantially more work to fix. These have been added to our sprint
backlog.
Other tests have been fixed to update to new APIs or to deal with genuine
bugs that were introduced without our knowing!
The most common non-trivial change relates to observing the `NylasAPI` and
`NylasAPIRequest`. We used to observe the arguments to `makeRequest`.
Unfortunately `NylasAPIRequest.run` is argumentless. Instead you can do:
`NylasAPIRequest.prototype.run.mostRecentCall.object.options` to get the
`options` passed into the object. the `.object` property grabs the context
of the spy when it was last called.
Fixing these tests uncovered several concerning issues with our test
runner. I spent a while tracking down why our participant-text-field-spec
was failling every so often. I chose that spec because it was the first
spec to likely fail, thereby requiring looking at the least number of
preceding files. I tried binary searching, turning on and off, several
files beforehand only to realize that the failure rate was not determined
by a particular preceding test, but rather the existing and quantity of
preceding tests, AND the number of console.log statements I had. There is
some processor-dependent race condition going on that needs further
investigation.
I also discovered an issue with the file-download-spec. We were getting
errors about it accessing a file, which was very suspicious given the code
stubs out all fs access. This was caused due to a spec that called an
async function outside ot a `waitsForPromise` block or a `waitsFor` block.
The test completed, the spies were cleaned up, but the downstream async
chain was still running. By the time the async chain finished the runner
was already working on the next spec and the spies had been restored
(causing the real fs access to run).
Juan had an idea to kill the specs once one fails to prevent cascading
failures. I'll implement this in the next diff update
Test Plan: npm test
Reviewers: juan, halla, jackie
Differential Revision: https://phab.nylas.com/D3501
Disable other specs
Disable more broken specs
All specs turned off till passing state
Use async-safe versions of spec functions
Add async test spec
Remove unused package code
Remove canary spec
Summary:
Threads can now be opened in separate windows. This can be done via the popout
icon next to the print icon, or by double-clicking the thread when in double-
pane mode. Note that the single-click action is still fired, which is why
double-clicking does not work in single-pane mode. The popout icon changes to a
pop-in icon while in the popout window, to allow users to collapse it back into
the main window.
Test Plan: Tested locally
Reviewers: evan, juan
Reviewed By: juan
Subscribers: sdw
Differential Revision: https://phab.nylas.com/D3332
Summary:
We originally didn't do this because creating a DOM tree was loading images.
Using range.createContextualFragment seems to do it without the tree ever
being attached.
Accompanying changes to src/pro are here:
https://phab.nylas.com/D3300https://github.com/nylas/edgehill/compare/bengotow/draft-dom-transformations?expand=1
Also rename applyTransformsToDraft => applyTransformsForSending. Needed
a new name because the function signature has changed. AFAIK there are no
open source plugins using the old functions.
Test Plan: All specs updated
Reviewers: evan, juan
Reviewed By: evan, juan
Differential Revision: https://phab.nylas.com/D3299
Summary:
Up until now, we've been requiring that every plugin control in the composer take the draftClientId, retreive the session, listen to it, build state from the draft, etc. This is a huge pain and is hard to explain to newcomers becaus it frankly makes no sense.
In 0.3.45 we made it so that the ComposerView always has a non-null draft and session. (It isn't rendered until they're available). In this diff, I just pass those through to all the plugins and remove all the session retrieval cruft.
Almost none of the buttons have state of their own, which I think is appropriate.
They do render on every keystroke, but they were already running code (to recompute their state) on each keystroke and profiling suggests this has no impact.
Prepare for immutable
In preparation for Immutable models, make the draft store proxy returns a !== draft if any changes have been made. This means you can safely know that a draft has changed if `props.draft !== nextProps.draft`
Test Plan: Run tests
Reviewers: juan, evan
Reviewed By: juan, evan
Differential Revision: https://phab.nylas.com/D2902
* fix(imports): switch to Electron's require('electron')
Electron in 0.37.5 phases out the usage of `require('built-in-module')`
in favor of `require('electron').builtInModule`. This commit corrects usage in
some cases that cause N1 to not start under Electron 0.37.5.
* fix(specs): use new Electron remote import
Summary:
- Removes controlled focus in the composer!
- No React components ever perfom focus in lifecycle methods. Never again.
- A new `Utils.schedule({action, after, timeout})` helper makes it easy to say "setState or load draft, etc. and then focus"
- The DraftStore issues a focusDraft action after creating a draft, which causes the MessageList to focus and scroll to the desired composer, which itself decides which field to focus.
- The MessageList never focuses anything automatically.
- Refactors ComposerView apart — ComposerHeader handles all top fields, DraftSessionContainer handles draft session initialization and exposes props to ComposerView
- ComposerHeader now uses a KeyCommandRegion (with focusIn and focusOut) to do the expanding and collapsing of the participants fields. May rename that container very soon.
- Removes all CommandRegistry handling of tab and shift-tab. Unless you preventDefault, the browser does it's thing.
- Removes all tabIndexes greater than 1. This is an anti-pattern—assigning everything a tabIndex of 0 tells the browser to move between them based on their order in the DOM, and is almost always what you want.
- Adds "TabGroupRegion" which allows you to create a tab/shift-tabbing group, (so tabbing does not leave the active composer). Can't believe this isn't a browser feature.
Todos:
- Occasionally, clicking out of the composer contenteditable requires two clicks. This is because atomicEdit is restoring selection within the contenteditable and breaking blur.
- Because the ComposerView does not render until it has a draft, we're back to it being white in popout composers for a brief moment. We will fix this another way - all the "return unless draft" statements were untenable.
- Clicking a row in the thread list no longer shifts focus to the message list and focuses the last draft. This will be restored soon.
Test Plan: Broken
Reviewers: juan, evan
Reviewed By: juan, evan
Differential Revision: https://phab.nylas.com/D2814
Summary:
Adds new redesigned preferences with horizontal tab bar and refactored code.
Converts Preferences, Plugins, and a few components to ES6.
Test Plan: Tested locally.
Reviewers: evan, bengotow
Reviewed By: bengotow
Subscribers: juan
Differential Revision: https://phab.nylas.com/D2818
Summary:
Previously we always created <blockquote class="gmail_quote"> to wrap quoted text. This is not correct.
Gmail uses blockquotes only when it wants visual indentation, and <div>s to wrap other quoted text, like forwarded
messages which are not displayed indented.
This diff updates N1 to match Gmail exactly. Note that for replies, Gmail actually nests a blockquote.gmail_quote
inside a div.gmail_quote.
I also updated signature handling because it turns out the regexp that was removing existing signatures would blow
away any and all divs until it reached a <blockquote> tag.
Test Plan: See updated specs. Manually tested by creating a thread in Google Inbox and then performing fwd and reply in both N1 and Inbox. Results match.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2750
Summary:
This diff replaces "finalizeSessionBeforeSending" with a
plugin hook that is bidirectional and allows us to put the draft in
the "ready to send" state every time we save it, and restore it to
the "ready to edit" state every time a draft session is created to
edit it.
This diff also significantly restructures the draft tasks:
1. SyncbackDraftUploadsTask:
- ensures that `uploads` are converted to `files` and that any
existing files on the draft are part of the correct account.
1. SyncbackDraftTask:
- saves the draft, nothing else.
3. SendDraftTask
- sends the draft, nothing else.
- deletes the entire uploads directory for the draft
Test Plan: WIP
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2753
Summary: Shortens and simplifies UI variables so that unused variables are no longer present.
Test Plan: Tested locally.
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2738
Summary:
- FixedPopover now correctly adjusts itself when overflowing outside
window, in all directions
- Updates styles
- Adds specs
- Remove Popover and popover.less, and refactor all code that used it in
favor of the new FixedPopover
Test Plan: Unit tests
Reviewers: drew, evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2697
Summary:
Now all plugins get passed a `cloudState` object to their `activate`
method.
The `cloudState` object is an instance of `CloudState` and acts like a
key-value store backed by the yet-to-be-implemented Metadata service.
It has a `get`, `getAll`, and `observe` method. The `observe` method
returns a new `Rx.Observable` for the given key.
It has a `set`, and `unset` method that doesn't actually mutate state, but
rather dispatches new `Task`s to Create, Update, and Delete `Metadata`
objects.
The whole object is backed by `Metadata` objects. Since these are standard
Database Objects that will appear on the delta sync streaming API, any
updates from the server will automatically propagate down to listening
views via the `Rx.Observable`s.
Additionally, there is a new `N1-Send-Later` stub plugin that demonstrates
how to use the `cloudState`.
There are few other minor refactors included in this diff:
**Generic CUD Tasks**: There is now a generic `CreateModelTask`,
`UpdateModelTask`, and `DestroyModelTask`. These can either be used as-is
or trivially overridden to easily update simple objects. Hopefully all of
the boilerplate rollback, error handling, and undo logic won't have to be
re-duplicated on every task. There are also tests for these tasks. We use
them to perform mutating actions on `Metadata` objects.
**New `boundProps` for `InjectedComponents`**: When making the
`N1-Send_later` plugin, I realized that the injected component needed to
get the `cloudState` somehow. Traditionally components would require
Stores and load data that way, but these are setup at `require`-time. Now
that `cloudState` only is available on `activate` we needed a way to get
the data to the components. There's now the concept of `boundProps` which
will be props added to the Component when it gets injected. This required
changing the return signature of `findComponentMatching`, which got
renamed to `findComponentDataMatching`.
**Failing on Promise Rejects**: Turns out that if a Promise rejected
due to an error or `Promise.reject` we were ignoring it and letting tests
pass. Now, tests will Fail if any unhandled promise rejects. This
uncovered a variety of errors throughout the test suite that had to be
fixed. The most significant one was during the `theme-manager` tests when
all packages (and their stores with async DB requests) was loaded. Long
after the `theme-manager` specs finished, those DB requests were
(somtimes) silently failing.
**Globally stub `DatabaseStore._query`**: All tests shouldn't actually
make queries on the database. Furthremore, the `inTransaction` block
doesn't resolve at all unless `_query` is stubbed. Instead of manually
remembering to do this in every test that touches the DB, it's now mocked
in `spec_helper`. This broke a handful of tests that needed to be manually
fixed.
**ESLint Fixes**: Some minor fixes to the linter config to prevent
yelling about minor ES6 things and ensuring we have the correct parser.
Test Plan: new tests
Reviewers: drew, bengotow, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2419