1
0
Fork 0
Commit Graph

235 Commits (1aa51775f3d4b794b256574500c0d9aa708f4688)

Author SHA1 Message Date
Mike Gerwitz 44ad6437e2 {src,test}/.npmignore: New files
NPM was not publishing the compiled JS files (from the TS input) because
they were present in generated .gitignore files.  .npmignore takes
precedence.
2019-10-21 13:22:24 -04:00
Mike Gerwitz 16409a014f TokenedDataApi: Accept or kill token
Rather than leaving a token in a DONE state, we should either transition to
ACCEPTED or DEAD depending on whether the token was superceded.

* src/server/dapi/TokenedDataApi.ts (_replyUnlessStale): Accept token when
  not superceded, otherwise kill.
  [store]: New param.
  (request): Use it.
* test/server/dapi/TokenedDataApiTest.ts: Update accordingly.
2019-10-18 09:55:11 -04:00
Mike Gerwitz e003abcd4b Integrate TokenedDataApi into system
This changes the easejs interface for DataApi, which requires adding the
param to everything.  The TS interface was created in a previous commit and
already contained this parameter.  The idea is to remove the easejs
interface in the future, but traits are a barrier to that atm.

DocumentServer and controller demonstrate the mess that we have with regards
to instantiating dependencies.  This needs to change---DocumentServer itself
was something that was started but never fully realized.  It makes this
incredibly confusing, difficult to follow, and complicates important error
handling that ought to be taking place.  It also discourages implementing
additional dependencies.

I'm not going to go through and provide a ChangeLog-style commit message for
this commit.  I'm too exhausted by this crap.
2019-10-18 09:55:11 -04:00
Mike Gerwitz d8c065817f NodeCallback<T, R>: New type to simplify callback declarations
Just trying to reduce some boilerplate.  I kept this as a separate commit to
illustrate clearly how this type of things is done since we'll have people
learning TypeScript.

* src/types/misc.ts (NodeCallback<T,R>): New type.
* src/server/dapi/TokenedDataApi.ts: Use it.
* test/server/dapi/TokenedDataApiTest.ts: Use it.
2019-10-18 09:55:11 -04:00
Mike Gerwitz 07c8b55475 TokenedDataApi: New class
This integrates the PersistentTokenStore into the DataAPI system via a
decorator.  Unfortunately, it requires an API change and propagating data
through the system is a huge mess, which is the topic of a following
commit.  The API modification was a compromise.

This modifies the interface of DataApi to include a third parameter.  I am
continuing to export the old easejs interface for an incremental migration
away from it.  That old interface will be modified next commit, since
it requires modifying a lot of files and will muddy up this commit.

* src/dapi/DataApi.ts: Rename from js.  Add types.  Add new interface.
  Continue exporting old.
* src/server/dapi/TokenedDataApi.ts: New class.
* test/server/dapi/TokenedDataApiTest.ts: New test cases.
2019-10-18 09:55:11 -04:00
Mike Gerwitz b3ab082e9c {=>Persistent}TokenStore
This creates an interface for TokenStore.  The main motivation of this right
now is testing, since I'm punting on figuring out a mock framework right
now (due to time constraints).

* src/server/token/TokenStore.ts: Rename file.
* src/server/token/store/PersistentTokenStore.ts: Rename from TokenStore.
* test/server/token/TokenStoreTest.ts: Rename file.
* test/server/token/store/PersistentTokenStoreTest.ts: Rename from TokenStoreTest.
2019-10-18 09:55:11 -04:00
Mike Gerwitz c8589a1c57 TokenDao, TokenStore: Track most recently created tokens
This is much more useful information than the last modified.  For example:

- Token A is created.  It becomes the last modified.
- Token B is created.  It becomes the last modified.
- Token A completes.  Mismatch.  It becomes the last modified.
- Token B completes.  Mismatch.  It becomes the last modified.

So in this case, we're unable to use the flag to determine whether we should
ignore the token.  But if we instead us the new flag to see what token was
last _created_, the problem is solved.

This should have been obvious the first time around.

* src/server/token/MongoTokenDao.ts (updateToken): Query
    `lastState'.  Return its value.  Update its value.
  (getToken): Query lastState.  Return its value.
* src/server/token/Token.ts (Token)[last_state]: New field.
* src/server/token/TokenDao.ts (TokenQueryResult, TokenNamespaceResults):
    Use type instead of interface.
  (TokenStateHistory): New type.
  (TokenNamespaceData)[lastState]: New optional field.
  (TokenData)[prev_state]: New field.
* src/server/token/TokenStore.ts: Return previous state data for each
    method.
* test/server/token/MongoTokenDaoTest.ts: Add last_state.
* test/server/token/TokenStoreTest.ts: Likewise.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 0a9a5fe56e TokenStore: Provide document id via constructor
The primary use case for this is currently the DataAPI, and the quote id is
only available at the highest level of the server, before dapis are
processed.

In any case, the TokenStore was already described in terms of a combination
of document id; namespace; and root field; so it makes sense for doc id to
be part of the constructor.

If a more generic TokenStore is needed in the future, we could go back to
the previous API and wrap it in another class, like a partially applied
function (e.g. `DocumentTokenStore`).

* src/server/token/TokenStore.ts: Move doc_id out of arguments and into the
  constructor.
* test/server/token/TokenStoreTest.ts: Update accordingly.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 929acf0e90 TokenStore: Implement for token lookups and creation
Does not yet support token updates.

* src/server/token/Token.ts (TokenStateDeadable, TokenStateDoneable,
  TokenStateAcceptable, Token): New types.
* src/server/token/TokenStore.ts: New class.
* test/server/token/TokenStoreTest.ts: New test case.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 9997da3f65 TokenDao: Return previous state
This causes the DAO to return the state of the document prior to the
database operation (in the case of a retrieval, the previous state is the
same as the current state).  This will allow determining whether other
tokens were modified since a previous request.

* src/server/token/MongoTokenDao.ts: Stop using TokenType in favor of new
    TokenState.
  (updateToken): Query for and return previous state.  Use findAndModify
    instead of update.
  (getToken): Return previous state.  Minor changes to account for new
    TokenQueryResult types (null=>undefined).
* src/server/token/Token.ts: Add comments for existing Token{Id,Namespace}
    nominal types.
  (TokenState): New string enum.
* src/server/token/TokenDao.ts: Import new TokenState.
  (TokenDao)[updateToken]: Use it.
  (TokenType): Remove.
  (TokenQueryResult, TokenNamespaceResults, TokenNamespaceData):
    null=>undefined for unavailable value.  null was wrong.
  (TokenStatus): Token{Type=>State}.
  (TokenData)[prev_state, prev_status]: New fields.
* test/server/token/MongoTokenDaoTest.ts: Update tests accordingly.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 5b279f77cb TokenDao (#updateToken): Return updated data
Since some of these data are generated within TokenDao (e.g. the timestamp),
the caller cannot infer all values.

* src/server/token/MongoTokenDao.ts (updateToken): Return
  Promise<{void=>TokenData}>.
* src/server/token/TokenDao.ts (TokenDao)[#updateToken]: Update interface
  accordingly.
* test/server/token/MongoTokenDaoTest.ts: Update test accordingly.
2019-10-18 09:55:10 -04:00
Mike Gerwitz 4454e40e19 TokenDao: Add error context 2019-10-18 09:55:10 -04:00
Mike Gerwitz fe10578949 {Context,Chained}Error: New modules
This will allow us to provide additional useful information for structure
logging.
2019-10-18 09:55:09 -04:00
Mike Gerwitz 1f66a25658 TokenDao: Better error handling for unknown tokens
Rather than replying with null, which complicates using the returned promise
efficiently, we'll respond with a unique error that allows us to distinguish
between a database failure and a missing token.

These are more traditional errors, but we're moving toward structured
logging, so I want error objects that provide more context.  I'll explore
that a bit more in next commit.  Unfortunately, the untypedness of Promise
rejections make for a less than desirable situation here.  Async/await is
not yet an option since we're still compiling to ES5 (have to support
IE11), and TS compiles async/await into generators for environments that
don't support them, which also are not available in ES5.

* src/server/service/TokenedService.js (_getQuoteToken): Remove null check,
  since this situation can no longer occur.
* src/server/token/MongoTokenDao.ts (getToken): Remove null from return type
  union; reject with `UnknownTokenError' instead.
* src/server/token/TokenDao.ts: Modify interface accordingly.
* src/server/token/UnknownTokenError.ts: New class.
* test/server/token/MongoTokenDaoTest.ts: Modify tests accordingly.  Add
  missing test for latest token namespace missing.
2019-10-17 11:47:14 -04:00
Mike Gerwitz fb88ceeae6 TokenDao: class=>interface
TokenDao has been renamed to MongoTokenDao.  While it's good for this to
have its own interface anyway, the immediate motivation was for unit tests:
I started playing with mocking with TypeScript and researching some
libraries, but I don't have time to research enough to commit to any of them
at the moment.  Interfaces remove the need to mock at all.

This also stops using `export default' in favor of just importing by
name.  Using defaults only saves us a few characters, and it makes for
awkward syntax in various cases (e.g. with multiple exports).  But I'm still
new to TS, so who knows if I'll be flip-flopping on this decision in the
future.  If we kept to our normal 1:1 file:definition convention, it
wouldn't cause problems, but based on the types I've had to define so far,
that'd cause way too much bloat and boilerplate.

* src/server/daemon/controller.js: No long import `default'.  Use
  `MongoTokenDao'.
* src/server/token/TokenedService.js: Stop checking type (since TS
  interfaces do not result in compiler output, easejs cannot validate
  against them.)
* src/server/token/MongoTokenDao.ts: Rename from `TokenDao.ts'.
* src/server/token/TokenDao.ts: Rename from `TokenQueryResult.ts'.
  (TokenDao): New interface.
* src/server/token/TokenQueryResult.ts: Rename to `TokenDao.ts'.
* test/server/token/MongoTokenDaoTest.ts: Rename from `TokenDaoTest.ts'.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 37f1b86ac1 TokenDao: "quote"=>"document" with nominal type
* src/document/Document.ts: New file.
* src/server/token/TokenDao.ts: quote=>document and use DocumentId.
* test/server/token/TokenDaoTest.ts: Likewise.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 54b3f0db72 TokenDao: Nominal typing
This beings an experiment with nominal typing using what the TS community
calls "branding".  The lack of nominal types was one of my biggest
disappointments with TS, so this should really help to mitigate bugs
resulting from misappropriation of data.

* src/server/token/Token.ts: New file.
* src/server/token/TokenDao.ts: Use Token{Id,Namespace}.
* src/server/token/TokenQueryResult.ts: Likewise.
* src/types/misc.d.ts: Introduce NominalType and UnixTimestamp.
* test/server/token/TokenDaoTest.ts: Use nominal types.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 9ea66c0440 TokenDao: Lift out nondeterminism (date)
* src/server/daemon/controller.js (getUnixTimestamp): New method.  Not
  ideal, but better than where it was.
  (_initExportService): Pass to TokenDao constructor.
* src/server/token/TokenDao.ts (_getTimestamp): New field.
  (constructor)[get_timestamp]: New param.
  (updateToken): Use it.
* test/server/token/TokenDaoTest.ts: Provide stub timestamp function.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 9dd1ae3428 TokenDao: Export as default alongside TokenData
Our coding standards are to create a separate file for classes and
interfaces, but this is a bit different: this "interface" is more like a
struct, and it's used to define the return type of a method of this
class.  Since it's inherently coupled, I'm keeping it in the same file.

The idea is that the caller will provide its own abstraction rather than
continuing to export this one.  Note that Typescript does support
re-exporting symbols if need be.

* src/server/daemon/controller.js: Adjust import of TokenDao (TS compiles
  default modules as `default').
* src/server/service/TokenedService.js: Adjust import of TokenDao.
* src/server/token/TokenDao.ts: Export TokenDao as `default'.  Export
  TokenData.
* test/server/token/TokenDaoTest.ts: Adjust import of TokenDao.  Import
  TokenData.
2019-10-17 11:47:14 -04:00
Mike Gerwitz c90757a6d3 TokenDao: Callbacks=>promises
This makes minimal changes to TokenedService, even though there is obvious
refactoring that can be done to reduce duplication, because the class is
currently untested.

* src/server/service/TokenedService.js (_getQuoteToken, generateToken,
    killToken, acceptToken, completeToken): Expect promise.
* src/server/token/TokenDao.ts (updateToken, getToken): Remove callback
    param, return Promise.
* test/server/token/TokenDaoTest.ts: Use promises.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 18e86ebfe7 TokenDao: Add test and further refine types
This tests the existing state of TokenDao before additional modifications
are made.  This commit also further refines the types introduced in a
previous commit.

This is also the first test written in Typescript.

* package.json.in (devDependencies): Add node, chai, and mocha types.
* src/server/token/TokenDao.ts (updateToken): `data` accepts null (as it
    should).  Do not conditionall add data to object (it doesn't matter for
    later retrieval).  Note nondeterminism with date.  More concise syntax
    for object fields.
* src/server/token/TokenQueryResult.ts: Make all fields readonly.
  (TokenStatus): Date is no longer optional (see above mention).
* src/types/mongodb.d.ts: Remove generics (erroneously added).
  (Collection)[update]: Remove 3-argument declaration (see comment).
* test/server/token/TokenDaoTest.ts: New test case.
2019-10-17 11:47:14 -04:00
Mike Gerwitz 4f8aa3c90b FieldVisibilityEventHandler: Fix arrow function notation
This was a syntax recognized back in the day.
2019-10-17 11:47:14 -04:00
Joseph Frazer 28f938853a [DEV-5657] Check for TLD in email addresses
The DocuSign service rejects email addresses without a TLD, even though
they are valid.
2019-09-12 09:30:23 -04:00
Mike Gerwitz e058c8b509 Copyright range update
All files now have the same range, beginning from the conception of this
project.
2019-08-30 09:41:35 -04:00
Sarah Chintomby 8f0b12bd3a [DEV-5546] Change getdate to getUTCDate 2019-06-18 12:14:36 -04:00
Sarah Chintomby 53f3e2317e [DEV-5546] Fix calc relativedate for day and also month concerning edge cases 2019-06-18 12:14:36 -04:00
Austin Schaffer 9637fc22e1 [DEV-5333] Pass last rated date from the server quote back to the client quote
Correct and add more elaborate tests for RateEventHandler
2019-06-17 08:28:19 -04:00
Austin Schaffer 723a7f7ff7 [DEV-5333] Expose initialRatedDate to the client from the bucket
[DEV-5333] WIP

Add RateEventHandlerTest and fix RatingServiceSubmitNotifyTest

WIP: Add RateEventHandlerTest

Add stubs for RateEventHandlerTest

Finish RateEventHandlerTest

Move done to fix test bug
2019-06-14 10:40:46 -04:00
Andrew Fanton 0be64040f8 [DEV-3514] Fix bug with expiration date calculation
The nature of this bug was two-fold:
1.) A new Date was being instantiated with seconds,
but the constructor expects milliseconds.
2.) The expiration period was not cast to a number,
causing an expression to concatenate strings instead of
adding numeric values; this greatly increased the actual
expiration date.
2019-05-30 14:29:55 -04:00
Andrew Fanton f569a7e94d [DEV-3514] Display message explaining why quote is locked
Prior to this change, a single generic message was always shown simply
stating that the quote had been locked. These changes now allow for
different messages to be displayed in different circumstances.
2019-05-28 16:33:08 -04:00
Andrew Fanton 5a5c2ca629 [DEV-3514] Lock quotes that exceed expiration date 2019-05-28 16:33:05 -04:00
Corey Vollmer 14869d9041 [DEV-3514] Add more robust testing for BasicQuote
Also, updated README to include instructions on `npm install.`
2019-05-21 14:03:05 -04:00
Mike Gerwitz 20234bd906 db: Restore previous save-all-meta behavior
It looks like the metabucket is never initialized, so saving the quote is
right now the only thing that sets default values.  That should be fixed in
the future.

This also begins adding tests for the terrible MongoServerDao, that could
use some refactoring.

* src/server/db/MongoServerDao.js: Make `meta' mutable.  I had forgotten to
    remove the code that mutates it (since our version of v8 right now does
    not blow up for const assignments), so this is all that's needed.
* test/server/db/MongoServerDaoTest.js: New file to test this situation.
2019-02-12 09:18:48 -05:00
Joseph Frazer a2d1ea706a [DEV-4338] Change behavior of default data
Default data was converted to an empty array if the data evaluated to
false. We only want to convert it if it is undefined so values that are
false remain false.
2019-02-04 08:09:19 -05:00
Mike Gerwitz 6b3ab89e77 dapi: Fix *_label setting
The `*_label' fields were not being properly set because they were being
considered just as every other expanded field, which is subject to other
considerations to ensure that we do not overwrite user data.  Label fields,
on the other hand, _must_ always be set whenever the value changes, and are
_not_ modifiable by the user.

This codifies that `_label' assumption that I would like removed in the
future, but time does not permit that sort of refactoring right
now.  Ideally, labels would be treated generically like any other expanded
field and have an attribute set of them that would change their expansion
behavior.

* src/client/dapi/DataApiMediator.js (_updateFieldData): Pass label field id
    to `_populateWithMap'.
  (_populateWithMap): Use it to always populate the label field when the key
    matches, ignoring the other expansion criteria that would inhibit it.
* test/client/dapi/DataApiMediatorTest.js: Update test accordingly.
* src/dapi/DataApiManager.js (triggerFieldUpdate): Provide id to
    `_genUiFieldData'.
  (_genUiFieldData)[label_id]: New field.  Return it as part of the return
    object's `label_id' field.

DEV-4077
2018-12-17 13:32:00 -05:00
Mike Gerwitz f9f7cebce7 Accommodate ancient qtype data on init and clean
* src/program/ProgramInit.js (_isKnownType): Account for ancient qtype
    representation (as a string).
* src/server/quote/ProgramQuoteCleaner.js (_isKnownType): Likewise.
* test/program/ProgramInitTest.js: New test case for this situation.
* test/server/quote/ProgramQuoteCleanerTest.js: Modify existing test case
    for this situation.
2018-11-19 11:10:16 -05:00
Mike Gerwitz ecdfea5cdb ProgramInit: Do not initialize bucket values for undefined question types
These denote fields that are generated but do not actually have any data
associated with them.  For example, select options with predicates have a
field generated so that they contribute to the group field count (so that
the group will automatically show/hide appropriately), but those should
never have values associated with them in the bucket.

This was manifesting as a nasty bug:  The bucket contained a key for
generated options.  When the quote is loaded, the client "empties" the
bucket.  In doing so, it set the option value to the empty string, which had
the effect of rendering the dropdown useless---every value was the empty
string!

* src/program/ProgramInit.js (_isKnownType): New method.
  (init): Use it and ignore fields with unknown types.
* src/server/Server.js: Add note that we shouldn't have this logic
  duplicated between ProgramInit and ProgramQuoteCleaner.
* src/server/quote/ProgramQuoteCleaner.js (_fixGroup): Ignore fields with
    unknown types.
  (_isKnownType): New method.
* test/program/ProgramInitTest.js: Update existing tests.  Add new.
* test/server/quote/ProgramQuoteCleanerTest.js: Test this case.
2018-11-14 11:52:52 -05:00
Mike Gerwitz 2bc1b96a15 ProgramQuoteCleaner: Clean all groups (not just linked)
* src/server/quote/ProgramQuoteCleaner.js (clean): Add docblock.
    Replace previous linked group cleaning with call to `_fixGroup'.
  (_fixGroup): New method.  Similar logic to previous linked group cleaning,
    except that fields are never truncated.
  (_fixLinkedGroups, _getLinkedIndexLength): Remove methods.
  (_getGroupLength): New method determining group size from leader length,
    which also accounts for linked groups.
* test/server/quote/ProgramQuoteCleanerTest.js: New test case.
2018-10-21 23:41:58 -04:00
Joseph Frazer b4ecb5a14c [DEV-3393] Made sure the entity id is a number 2018-08-16 07:35:52 -04:00
Joseph Frazer 4b1fda57b8 [DEV-3393] minor changes to improve code quality 2018-08-15 15:05:21 -04:00
Joseph Frazer 2c0bf764d1 [DEV-3393] Add more metadata to the init endpoint 2018-08-15 14:06:07 -04:00
Mike Gerwitz e24038503b [bugfix] DapiMediator: Wait for stack to clear before updating options
This allows the UI to update before we add elements.  This really isn't the
best place to do this, but it will do for now.

DEV-3257
2018-08-10 15:25:29 -04:00
Mike Gerwitz b47deedf9c [DEV-3257] DataApiMediator: Set bucket data after stack clear
Allowing the stack to clear ensures that (in practice) DelayedStagingBucket
is given a chance to do necessary processing before data are requested from
it by bucket hooks as a result of _this_ invocation, which in turn
results (in some cases) in infinite recursion.

* src/client/dapi/DataApiMediator.js (_updateFieldData): Allow stack to
    clear before invoking `quote.setData'.
* test/client/dapi/DataApiMediatorTest.js: Test respectively.

DEV-3257
2018-08-10 13:33:54 -04:00
Mike Gerwitz 9243eeb8bc [DEV-3257] DelayedStagingBucket: Preempt infinite recursion on #processValues
* src/bucket/DelayedRecursionError.js: New class.
* src/bucket/DelayedStagingBucket.js: Update copyright and docblock.
  (_processing): New field.
  (getDataByName): Check against undefined before invoking
    `#processValues'.
  (processValues): Increment lock (_withProcessLock).
  (_withProcessLock): Error on recursion >= 5.

DEV-3257
2018-08-10 11:17:13 -04:00
Mike Gerwitz abc2564d9c DataApiMediator: Do not auto-expand into populated fields
* src/client/dapi/DataApiMediator.js (_populateWithMap): Update
    docblock.  Ignore field during expansion if it would overwrite an
    existing value.
* test/client/dapi/DataApiMediatorTest.js: Update tests data to include
    values for all bucket fields, not just `name'.  Add test for new
    condition.

DEV-3257
2018-07-17 15:44:37 -04:00
Mike Gerwitz 839952a56d [DEV-3257] DataApiMediator: Auto-expand into fields on reply [*]
[*] You should not use this commit directly since this may wipe out data in
fields the user has changed.  See future commit where this situation is
properly handled.

* src/client/Client (_init): Provide dapimap to DataApiMediator instance.
* src/client/dapi/DataApiMediator.js
  (_dapi_map): New field.
  (constructor): Accept dapimap.  BC break (which is okay, since this is
    still part of a topic branch).  Assing to _dapi_map.  Update docblock.
  (monitor): Bind `dapi_manager' to first argument of handlers.
  (_updateFieldData): Accept `dapi_manager' as first argument.  Use
    `_populateWithMap' to generate additional update data.
  (_populateWithMap): New method.
  (_clearFieldFailures): Accept `dapi_manager' as first argument.
* src/dapi/DataApiManager.js: Update copyright year.
  (getDataExpansion): Return empty object (consistent with interface) rather
    than `undefined' when field value is undefined.  Use
    {Error=>MissingDataError} when field data are missing.  Throw instead of
    emit.  Fix missing comma in var declarations.
* src/dapi/MissingDataError.js: New class.
* test/client/dapi/DataApiMediatorTest.js: Update test data to test field
    expansion.  New test against ignoring field expansion when data are not
    available.  Update Sut constructors of other tests for new dapimap
    parameter.

DEV-3257
2018-07-17 15:44:37 -04:00
Mike Gerwitz 160ab01f9a DataApiMediator: setData{ByName=>} to prepare for multi-field set
See following commit.

* src/client/dapi/DataApiMediator.js (_updateFieldData):
  `setData{ByName=>}'.
* test/client/dapi/DataApiMediatorTest.js: Update respective tests.

DEV-3257
2018-07-17 15:44:37 -04:00
Mike Gerwitz e25bec5ac0 DataApiMediator: New class
This extracts existing code from Client and adds tests.  The glue code is
far from ideal and highlights the amount of work needed to decouple Client
from so many parts of the system.

* src/client/Client.js (_dapiManager): New field.
  (_init): Use DataApiMediator.
  (_createProgram): Assign `_dapiManager' (this is not at all
  ideal).  Remove hooks from it: fieldLoading, updateFieldData,
  clearFieldData.
* src/client/ClientDependencyFactory.js (createDataApiMediator): New alias
  to DataApiMediator constructor.
* src/client/dapi/DataApiMediator.js: New class.
* test/client/dapi/DataApiMediatorTest.js: New test case.

DEV-3257
2018-07-17 15:44:33 -04:00
Jeffrey Fisher 8600c3beb7 [DEV-3192] Renamed variables and added test case 2018-06-19 10:28:48 -04:00
Jeffrey Fisher 94f76c5a77 [DEV-3192] fixed test cases 2018-06-19 10:28:48 -04:00
Jeffrey Fisher 8ac2a367db [DEV-3192] Fix populating default bucket data to meet min required bucket values 2018-06-19 10:28:48 -04:00
Mark Goldsmith 7935c699de [DEV-2871] DocumentProgramFormatter: Match on fields from FieldClassMatcher instead of __classes and program.whens 2018-06-13 15:42:45 -04:00
Mike Gerwitz de931cf91b FieldClassMatcher: Minor refactoring/cleanup
This does not go all the way, but helps improve the readability of the
algorithm a little bit and modernizes the code.

* src/field/FieldClassMatcher.js (constructor): Renamed from
    `__constructor'.
  (__constructor): Remove method.
  (match): Extract most code into `#_reduceFieldMatches'.
  (_reduceFieldMatches): New method, simplifying the algorithm slightly.
  (_reduceMatch): Simplify.
* test/field/FieldClassMatcherTest.js: Update accordingly.
2018-06-12 16:52:14 -04:00
Mike Gerwitz 5164c9dcbb FieldClassMatcher: Always yield integer indexes
* src/field/FieldClassMatcher.js (match): Cast `vis' to number.
* test/field/FieldClassMatcherTest.js: Remove FIXME and change assertion.
2018-06-12 15:11:24 -04:00
Mike Gerwitz 6d6e80aac7 FieldClassMatcherTest: Add tests for existing implementation
This is just to make sure that the current system is both well-understood
and does not break with changes.  This is a very important class, as it
drives the display of the entire UI.

* test/field/FieldClassMatcherTest.js: New file.
2018-06-12 15:09:30 -04:00
Mark Goldsmith 14a8af2282 [DEV-2871] Added link and id to group in DocumentProgramFormatter 2018-06-12 09:02:54 -04:00
Mark Goldsmith e2461a023c [DEV-2871] Added field type to DocumentProgramFormatter 2018-06-12 09:02:54 -04:00
Mark Goldsmith 856c9a1a83 [DEV-2871] Passed __classes directly into private functions, updated documentation 2018-06-12 09:02:54 -04:00
Mark Goldsmith 9907c698d1 [DEV-2871] Added DocumentProgramFormatter to format program data by step, group and field metadata 2018-06-12 09:02:54 -04:00
Mike Gerwitz 99e33a5089 RatingServiceSubmitNotify: Do not flag as notified on error
If the submission failed, we probably want to try again next time around.

* src/server/service/RatingServiceSubmitNotify.js
  (_maybeNotify): Extract logic from `#postProcessRaterData'.  Only set
    notification flag in absence of dapi error.
  (postProcessRaterData): Use it.
* test/server/service/RatingServiceSubmitNotifyTest.js: Update tests
    accordingly.
2018-05-02 14:23:39 -04:00
Mike Gerwitz ae0d9b3862 RatingServiceSubmitNotify: Create dapi dynamically with session
Session information needs to be available for request session spoofing.
2018-05-01 09:44:55 -04:00
Mike Gerwitz 2d1582059f RatingServiceSubmitNotify: Notify only once
* src/server/db/MongoServerDao.js
  (getDocumentField,setDocumentField): New methods.
* src/server/service/RatingServiceSubmitNotify.js
  (postProcessRaterData): Only notify when notification flag is not set.
  (_getNotifyState, _setNotified): New methods.
* test/server/service/RatingServiceSubmitNotifyTest.js: Modify accordingly.
2018-05-01 09:44:55 -04:00
Mike Gerwitz d8338b50e0 RatingServiceSubmitNotify: Add trait
* src/server/service/RatingServiceSubmitNotify.js: New trait.
* test/server/service/RatingServiceSubmitNotifyTest.js: Respective test.
2018-05-01 09:44:55 -04:00
Jeffrey Fisher 7d0dc97162 Add HttpDataApiUrlData 2018-05-01 09:44:53 -04:00
Jeffrey Fisher 5b410005cd RatingService: ensure #postProcessRaterData is called before save 2018-05-01 09:44:51 -04:00
Mike Gerwitz 9ad8cb96b8 Cmatch: Do not fail given __classes question
* src/client/Cmatch.js (handleClassMatch): Rename from
  _handleClassMatch.  Make protected.  Check for truthy `vis'.
* test/client/CmatchTest.js: Update accordingly.
2018-04-16 15:30:19 -04:00
Mike Gerwitz f83dfd0027 GeneralStepUiTest: Fix failing test case in newer version of Node
An error was being thrown outside the stack of the actual test, which
apparently was never noticed until more recent versions of node.  We're
still on a pretty ancient version for local development. :x

* test/ui/step/GeneralStepUiTest.js (createElementStyler)[getAnswerElementByName]:
  Properly return array for stub jQuery element.
2018-03-07 14:12:48 -05:00
Mike Gerwitz c33adee21d client: Truncate diff posted to server after first null
Before this change, since `undefined' is encoded as `null' when serialized,
there was no way for the server to disambiguate between unmodified values
and a truncation point.  For example:

  [ undefined, undefined, null, null, null ]

The above array represents two unmodified and three removed indexes.  But
this is serialzed into JSON as:

  [ null, null, null, null, null ]

It isn't possible for the server to determine what the truncation point is
from that diff.  The solution is to therefore truncate the array _before_
sending it to the server, providing a trailing null to indicate that a
truncation has occurred:

  [ null, null, null ]

The above means that the first two indexes are unmodified, and that index 2
and later should all be truncated.

* doc/client.texi (Saving to Server): New section.
* src/client/transport/XhttpQuoteTransport.js (_truncateDiff): New method to
  perform truncation.
  (getBucketDataJson): Use it.
* test/client/transport/XhttpQuoteTransportTest.js: New file with respective
  test case.
2018-03-07 13:46:05 -05:00
Mike Gerwitz 3b303e50a9 Cmatch: Fix combined show/hide of same field, multi-index
This is something that managed to slip by (but not unnoticed) for almost
exactly one year to this day (028606242a).  It
can only be reproduced by changing classes that result in visibility changes
differing on the same field by index.  The issue hides itself on first
load (because all fields are shown by default) and on refresh.

The problem is that, when one index shows a field but another hides it, the
hide overrode the show indexes, so only the hide took place.

* src/client/Cmatch.js (markShowHide): Make virtual.  New implementation to
    support concurrent show/hide.
  (_handleClassMatch): Use it.
* test/client/CmatchTest.js: New test.
* npm-shrinkwrap.json: ease.js v0.2.{8=>9}.
2018-02-09 11:55:46 -05:00
Mike Gerwitz 943231ee81 ValueSetEventHandler: New handler for `set' event
The `set' event already existed---this merely extracts it into its own
handler.

* src/client/Client.js (handleEvent): Extract `set' handler.
* src/client/ClientDependencyFactory.js (createClientEventHandler): Add
  `set'.
* src/client/event/ValueSetEventHandler.js: New class.
* test/event/ValueSetEventHandlerTest.js: Associated test case.
2018-02-07 14:59:50 -05:00
Mike Gerwitz 68649dfd9b [DEV-2692] [BC-BREAK] Bucket stability and consistency fixes and non-term nulls
This mixes in support for non-terminating nulls.  It would have been
nice to handle that in a separate commit for clarity, but the
refactoring came as a consequence of trying to provide a working
implementation.

Various inconsistencies and subtle bugs in unlikely situations have
been fixed by this, including modifying objects passed as arguments to
various methods, and inconsistent handling of diff data.

Changes are more consistently recognized.  Perhaps the most noticeable
consequence is that moving between steps no longer prompts to discard
changes---previously calculated values would trigger the dirty flag on
steps even if the user didn't actually change anything.  I (and
others) have wanted this fixed for many years.

This is a very dense commit that touches a core part of the
system.  Hopefully the Changelog below helps.

* src/bucket/Bucket.js
  (setValues): [BC-BREAK] Remove parameters `merge_index' and
    `merge_null' parameters.
* src/bucket/DelayedStagingBucket.js
  (setValues): [BC-BREAK] Remove `merge_index' and `merge_null
    parameters.  Remove distinction between `merge_index' and non-.
* src/bucket/QuoteDataBucket.js
  (setValues): [BC-BREAK] Remove `merge_index' and `merge_null
    parameters.  Remove respective arguments from `_mergeData' call.
  (_mergeData): Remove same parameters.  Remove handling of
    `merge_index' and `merge_null'.
  (overwriteValues): Append `null' to each vector.
* src/bucket/StagingBucket.js
  (_initState): Use `Object.create' instead of explicit prototype
    instantiation (functionally equivalent).
  (merge): Minor comment correction.
  (_hasChanged): Rename to `_parseChanges'.
  (_parseChanges): Rename from `_hasChanged'.  Remove `merge_index'
    parameter.  Generate new object rather than mutation original
    data (prevent dangerous and subtle bugs from side-effects).  Clone
    each vector rather than modifying/referencing directly (this was
    previously done during merge).  Remove `merge_index'
    distinction.  Handle non-terminating `null' values.
  (setValues): [BC-BREAK] Remove `merge_index' and `merge_null'
    parameters.  Use new object generated by `_parseChanges'.  Remove
    cloning of each vector (`_parseChanges' now does that).  Remove
    `merge_index' distinction.
  (overwriteValues): Remove argument to `setValues' call.
  (getFilledDiff): [BC-BREAK] Use `_staged' rather than `_curdata'.
  (commit): Remove second and third arguments of call to `setValues'
    of underlying bucket.
* src/client/Client.js
  (_initStepUi): Remove second argument of calls to quote `setData'.
* src/client/quote/ClientQuote.js
  (setData): [BC-BREAK] Remove `merge_nulls' parameter.  Remove second
    and third arguments of call to staging bucket `setValues'.  Add
    comment indicating a long-standing problem with committing the
    staging bucket contents before save has succeeded.
* src/server/request/DataProcessor.js
  (processDiff): Remove `permit_null' argument of `sanitizeDiff'
    call.
  (sanitizeDiff): Remove `permit_null' parameter.  Hard-code filter
    call's `permit_null' argument to `true'.
  (_determineDapiFields): Properly handle `null's (ignore) rather than
    inadvertently converting them into the string "null".
* test/bucket/StagingBucketTest.js: Modify test cases
    accordingly.  Add tests to verify that updates and diffs operate
    as expected, especially support for non-terminating `null's.
  (createStubBucket): Use `QuoteDataBucket'.  Ideally remove this
    coupling in the future, but this is a more realistic test case for
    the time being.
* test/server/request/DataProcessorTest.js: Update test to account for
    hard-coded `given_null' argument.
2017-09-06 09:03:45 -04:00
Mike Gerwitz 3fa464bc3a Extract bucket init code into ProgramInit
This represents a portion of the refactoring that I had intended to do
until I realized that there was a simpler solution to the problem that
we were having (having proguic add stored calculated values to the
defaults object).

So ideally we'll continue extracting all quote init code out of
`Server' and into `ProgramInit' in the future.

* doc/server.texi (Liza Server): Mention `ProgramInit'.
* src/program/ProgramInit.js: Add class.
* src/server/DocumentServer.js: Use it.
* src/server/Server.js (_progInit): Add private field.
  (__construct): Accept ProgramInit instance and assign to field.
  (initQuote): Use promise returned by `_getDefaultBucket'.
  (_getDefaultBucket): Proxy to `ProgramInit#init', which returns a
    promise.
2017-08-30 11:20:19 -04:00
Mike Gerwitz 445783c256 [BC BREAK] DataApi config lookup
This was a bit involved because the system had to be made async all
the way up the stack.  No attempt was made to clean up the mess up the
stack---no time.

* src/dapi/DataApiFactory.js
  (fromType): [BC BREAK] Fix docblock.  Add `api_name' param.  Call
    `#descLookup' and return promise.
  (descLookup): Add method.  Return promise resolving to provided
    descriptor.  Intended to be overridden by subtype.
* src/dapi/DataApiManager.js
  (_dataApis): Update docblock to indicate that it now stores
    promises.
  (getApiData): Expect promise for `DataApiFactory#fromType' call.
* src/server/DocumentServer.js: (create): [BC BREAK] Accept
    configuration.  Look up dapi conf and pass to
    `ServerDataApiFactory' ctor.  Return promise.
* src/server/daemon/Daemon.js (_initRouters): Provide configuration.
* src/server/daemon/controller.js
  (init): Accept configuration.  Handle return of promise from
    `_createDocumentServer'.
  (_createDocumentServer): Accept configuration, providing to
    `DocumentServer#create'.  Because of aforementioned change to
    `#create', returns promise.
* src/server/request/ServerDataApiFactory.js: Add StoreMissError
    import.
  (_conf): Add property.
  (constructor): [BC BREAK] Accept configuration.
  (descLookup): Add override.  Look up configuration for provided
    dapi.
2017-08-29 15:11:28 -04:00
Mike Gerwitz 24e8b51745 Add DelimitedKey Store trait
This will make life much easier and less verbose, especially
considering the verbosity of promises.

* src/store/DelimitedKey.js: Add trait.
* test/store/DelimitedKeyTest.js: Add test case.
2017-08-29 14:34:40 -04:00
Mike Gerwitz c857dcb056 Add ConfLoader
* src/conf/ConfLoader.js: Add class.
* test/conf/ConfLoaderTest.js: Respective test case.
2017-08-28 09:07:28 -04:00
Mike Gerwitz dfcca807de Add AutoObjectStore
* src/store/AutoObjectStore.js: Add class.
* test/store/AutoObjectStoreTest.js: Add test case.
2017-08-28 09:07:26 -04:00
Mike Gerwitz edce23f14b Add Store#populate
* src/store/DiffStore.js (populate): Add method.
* src/store/MemoryStore.js (populate): Add method.
* src/store/Store.js (populate): Add abstract method.
* test/store/DiffStoreTest.js: Add populate tests.
* test/store/MemoryStoreTest.js: Add populate tests.
2017-08-24 14:27:01 -04:00
Mike Gerwitz 0e1cbe7c34 Clear metadata for pending dapi calls
* src/server/Server.js (_monitorMetadataPromise): Save metadata
  immediately after pending dapi requests (to clear in db).
  (handlePost): Pass clear update to _monitorMetadataPromise.

* src/server/request/DataProcessor.js (processDiff): Return meta clear
  update.
  (_triggerDapis): Call _genClearMetaValues and return results to
  caller.
  (_genClearMetaValues): Add method to calculate bucket update.

* test/server/request/DataProcessorTest.js: Update accordingly.
2017-08-15 15:13:22 -04:00
Mike Gerwitz 8cb23711ce Recognize non-changes in posted data server-side
This is a terrible kluge, but time doesn't permit modifying the
system.  All of this also touches old code that is untested, which is
difficult to modify with confidence.

* src/server/DocumentServer.js (DocumentServer#create): Use
  StagingBucket.
* src/server/Server.js: Remove logic now handled by DataProcessor.
* src/server/request/DataProcessor.js (processDiff): Wrap in
  StagingBucket to filter out values that do not result in changes.
* test/server/request/DataProcessorTest.js: Update failing cases.
2017-08-11 13:40:55 -04:00
Mike Gerwitz 1123bccf71 StagingBucket: Better consideration of nulls for change detection
`null` indicates a truncation.

* src/bucket/StagingBucket.js (_length, _deepEqual): Add methods.
  (_hasChanged): Better consider how nulls affect the bucket.
* test/bucket/StagingBucketTest.js: Modify tests accordingly.
2017-08-11 12:03:34 -04:00
Mike Gerwitz 5078c7d8d9 [DEV-2506] StagingBucket: Add ability to prevent bypass
This is a kluge until time can be spent better factoring this
system (using Traits).

* src/bucket/StagingBucket.js (_noStagingBypass): Add field.
  (forbidBypass): Add method to set field.
  (setCommittedValues): Use field.
2017-08-11 11:57:48 -04:00
Mike Gerwitz c1b6f796fe Add `quote' Data API type
* src/dapi/DataApiFactory.js (_createDataApi): Add support for
  `quote'.
* src/dapi/http/HttpDataApi.js (__construct): New `enctype' argument.
  (_encodeData, _encodeKeys): Remove former, rename latter to former.
  (encodeData, _urlEncode): Encode based on enctype and method.
  (*): Strict mode, es6 style.
2017-08-10 09:52:07 -04:00
Mike Gerwitz d31e12193a Add ResponseApply
* src/dapi/format/ResponseApply.js: Add trait.
* test/dapi/format/ResponseApplyTest.js: Test it.
2017-08-10 09:52:07 -04:00
Mike Gerwitz 020ca01458 HttpDataApi: Only serialize JSON on POST
* src/dapi/http/HttpDataApi.js (_encodeKeys): JSON.stringify on POST.
* test/dapi/http/HttpDataApiTest.js: Update tests accordingly.
  Add POST test.
2017-08-10 09:52:07 -04:00
Mike Gerwitz 47cb736387 Add QuoteDataApi 2017-08-10 09:52:03 -04:00
Mike Gerwitz 4b04360b0d DummyDataApi: Add test class.
* test/dapi/DummyDataApi.js: Add class.
2017-08-07 11:34:22 -04:00
Mike Gerwitz 229a356a9a Do not convert non-truthy dapi return values to empty string
* src/dapi/DataApiManager.js (getDataExpansion): Explicit undefined
  check before triggering default (empty string).
* test/dapi/DataApiManagerTest.js: Add associated test cases.
2017-07-21 15:20:55 -04:00
Mike Gerwitz 1d8d382b4d Add missing test for previous commit
Oops.

* test/server/quote/ProgramQuoteCleanerTest.js: Add missing test for
  empty program.meta.
2017-07-14 15:19:35 -04:00
Mike Gerwitz 37f84b7da8 Initialize metadata on quote version change
Consequently, on quote load as well.

* src/server/quote/ProgramQuoteCleaner.js (_fixMeta): New method.
  (clean): Use it.
2017-07-10 10:09:22 -04:00
Mike Gerwitz 0c24e3d280 Populate document metadata using Data APIs
What a cluster.

This was a lot of work to work around existing, bad APIs; there is no
time to refactor at the moment; this already took much longer than
expected.
2017-06-28 16:33:24 -04:00
Mike Gerwitz 65ab92f701 Add SpoofedNodeHttpImpl
Session spoofing is needed for making authenticated requests.
2017-06-28 15:51:18 -04:00
Mike Gerwitz d47d77bb5e Add server.meta.DapiMetaSource
Encapsulates the nasty.

* src/server/meta/DapiMetaSource.js: Add class.
* test/server/meta/DapiMetaSourceTest.js: Add test case.
2017-06-28 14:56:28 -04:00
Mike Gerwitz 630af0a062 Add ability to provide origin to NodeHttpImpl
* src/dapi/http/NodeHttpImpl.js (_parseUrl): Add method.
  (__construct): Add argument.
  (requestData): Use it.

* test/dapi/http/NodeHttpImplTest.js: Add tests.
2017-06-21 13:55:15 -04:00
Mike Gerwitz 624f35a489 XhrHttpImpl: throw {=>Http}Error
* src/dapi/http/XhrHttpImpl.js (serveError): Throw HttpError instead
  of Error.
* test/dapi/http/XhrHttpImplTest.js: Test updated accordingly.
2017-06-21 10:52:46 -04:00
Mike Gerwitz a3e359a050 Add node dapi HTTP implementation
* src/dapi/http/HttpError.js: Add error subtype.
* src/dapi/http/NodeHttpImpl.js: Add node-based HTTP impl.
* test/dapi/http/HttpErrorTest.js: Add test.
* test/dapi/http/NodeHttpImplTest.js: Add test.
2017-06-21 10:52:46 -04:00
Mike Gerwitz 1bb5191e3e LoVullo Associates => R-T Specialty
Copyright notices updated.  More casual references to "LoVullo
Associates" replaced with "RT Specialty / Lovullo", which will be "RT
Specialty Buffalo" in the future.  Or "RT Specialty", depending on how
this is rolled out.  Or "Ryan Specialty Group".  Who knows.

"R-T Specialty, LLC." is the legal name, which includes the dash.  Not
to be confused with a certain television network.
2017-06-08 14:48:43 -04:00
Mike Gerwitz 657573ab63 Near-complete liberation of liza
I have sat on releasing a lot of this code for years because I wanted
the liza repo to be in a pristine state---tests and all---which
required a great deal of refactoring.  Well, that never happened, and
time is up.

LoVullo Associates---my employer---has been purchased by another
company.  This means that any agreement with LoVullo regarding
releasing free software is going to have to be re-negotiated with this
new company, and I have no idea how those negotiations will go.  So,
I have no choice but to simply release everything in its current state,
or risk it being lost forever.

This represents work over the past 6--7 years, 99.9% of it written by
me.  This project has been my baby for quite some time, and has been
through a number of battles with deadlines and other unfortunate
circumstances; the scars show.  I also didn't really "know" JS when
starting this project.  Perhaps you can help improve upon it.

There are some odds-and-ends that could be committed.  And references
to insurance and LoVullo need to be removed to generalize this.

I hope that this will not be the last public commit for this project.
I'll fight the good fight and we'll see where that takes us.  Maybe
it'll be easy.

Happy hacking.
2017-06-08 14:38:28 -04:00
Mike Gerwitz 7567306123 FieldStyler: Remove classes not added by #addClass
This code assumed that no classes would be removed that were _not_
added by #addClass.  Well, that's false.

* src/ui/styler/FieldStyler.js (removeClass): Consider both spaces and
  boundary preceding class name.

* test/ui/styler/FieldStylerTest.js: Add test case.
2017-03-17 14:11:16 -04:00
Mike Gerwitz 6bba4322bf ValidStateMonitor: Consider scalar diff to affect all indexes
Classifications often yield scalar results.  Since those results are
used directly in the diff, we have the situation where the expected
diff format (an array) is not provided.  Consistent with the rest of
the system, we should consider a scalar to affect every index.

* src/validate/ValidStateMonitor.js (_checkCauseFix): Consider scalar
    diffs to affect every index when checking for fixes.
* test/validate/ValidStateMonitorTest.js: Add test.
2017-03-17 11:17:42 -04:00
Mike Gerwitz 3460610808 ValidStateMonitorTest: remove accidental `debugger'
Didn't mean for this to be committed.

* test/validate/ValidStateMonitorTest.js: Remove `debugger'.
2017-02-22 09:54:03 -05:00