Skip to content

Instantly share code, notes, and snippets.

@aaronj1335
Created May 21, 2014 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronj1335/db544761e295ae9ce6d0 to your computer and use it in GitHub Desktop.
Save aaronj1335/db544761e295ae9ce6d0 to your computer and use it in GitHub Desktop.
Using worker: worker-linux-3-1.bb.travis-ci.com:travis-linux-17
Installing an SSH key
$ git clone --depth=50 git@github.com:WaterfallEngineering/frontend.git WaterfallEngineering/frontend
Cloning into 'WaterfallEngineering/frontend'...
Warning: Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts.
remote: Counting objects: 1382, done.
remote: Compressing objects: 100% (1035/1035), done.
remote: Total 1382 (delta 433), reused 956 (delta 230)
Receiving objects: 100% (1382/1382), 2.45 MiB | 0 bytes/s, done.
Resolving deltas: 100% (433/433), done.
Checking connectivity... done.
$ cd WaterfallEngineering/frontend
$ git fetch origin +refs/pull/725/merge:
remote: Counting objects: 46, done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 17 (delta 13), reused 3 (delta 0)
Unpacking objects: 100% (17/17), done.
From github.com:WaterfallEngineering/frontend
* branch refs/pull/725/merge -> FETCH_HEAD
$ git checkout -qf FETCH_HEAD
setup build cache
attempting to download cache archive
found cache
adding /home/travis/build/WaterfallEngineering/frontend/webapps/msgme3.0/node_modules to cache
$ nvm use 0.8
Now using node v0.8.26
$ node --version
v0.8.26
$ npm --version
1.2.30
$ cd webapps/msgme3.0
$ npm install
npm WARN package.json expect.js@0.2.0 No repository field.
npm WARN package.json growl@1.5.1 No repository field.
npm WARN package.json ms@0.3.0 No repository field.
npm WARN package.json dateformat@1.0.2-1.2.3 No repository field.
npm WARN package.json pause@0.0.1 No repository field.
npm WARN package.json bytes@0.2.0 No repository field.
npm WARN package.json cookie-signature@1.0.1 No repository field.
npm WARN package.json fresh@0.1.0 No repository field.
npm WARN package.json uglify-js@2.2.5 'repositories' (plural) Not supported.
npm WARN package.json Please pick one as the 'repository' field
npm WARN package.json css@1.0.8 No repository field.
npm WARN package.json faye-websocket@0.4.4 'repositories' (plural) Not supported.
npm WARN package.json Please pick one as the 'repository' field
npm WARN package.json range-parser@0.0.4 No repository field.
npm WARN package.json growl@1.7.0 No repository field.
npm WARN package.json css-parse@1.0.4 No repository field.
npm WARN package.json css-stringify@1.0.5 No repository field.
$ npm test
> three@0.1.0 test /home/travis/build/WaterfallEngineering/frontend/webapps/msgme3.0
> grunt citest
Running "shell:showNpmDeps" (shell) task
three@0.1.0 /home/travis/build/WaterfallEngineering/frontend/webapps/msgme3.0
├── expect.js@0.2.0
├── grunt@0.4.1
├── grunt-bg-shell@2.0.3
├── grunt-browserstack@0.1.1
├── grunt-cli@0.1.9
├── grunt-contrib-clean@0.5.0
├── grunt-contrib-connect@0.3.0
├── grunt-contrib-copy@0.4.1
├── grunt-contrib-jade@0.8.0
├── grunt-contrib-jshint@0.6.4
├── grunt-contrib-less@0.5.2
├── grunt-contrib-requirejs@0.4.1
├── grunt-contrib-watch@0.4.3
├── grunt-mocha-phantomjs@0.2.8
├── grunt-shell@0.6.0
├── grunt-yaml@0.2.1
├── jade@0.35.0
├── js-yaml@1.0.3
├── mocha@1.6.0
├── proxy-middleware@0.4.0
├── requirejs@2.1.9
├── shelljs@0.1.4
└── sinon@1.7.3
Running "jshint:all" (jshint) task
>> 162 files lint free.
Running "copy:environment_dev" (copy) task
Copied 1 files
Running "jade:test" (jade) task
File "tests/runner.html" created.
File "tests/integration-runner.html" created.
Running "jade:app" (jade) task
File "dist/index.html" created.
Running "jade:widgets" (jade) task
File "widgets/async-button/template.html" created.
File "widgets/async-button/test-template.html" created.
File "widgets/audience-filter/template.html" created.
File "widgets/audience-row/template.html" created.
File "widgets/bar-chart/template.html" created.
File "widgets/character-counter/template.html" created.
File "widgets/contact-stat-card/template.html" created.
File "widgets/create-report/template.html" created.
File "widgets/dashboard-tour/popover.html" created.
File "widgets/dashboard-tour/restart.html" created.
File "widgets/dashboard/template.html" created.
File "widgets/datetimepicker/template.html" created.
File "widgets/dynamic-insertion/template.html" created.
File "widgets/facebook-message-body/template.html" created.
File "widgets/file-uploader/template.html" created.
File "widgets/follower-stat-card/template.html" created.
File "widgets/footer/template.html" created.
File "widgets/likes-stat-card/template.html" created.
File "widgets/line-chart/template.html" created.
File "widgets/message-body/template.html" created.
File "widgets/message-preview/template.html" created.
File "widgets/message-preview/test-message-modal.html" created.
File "widgets/metadata-value/template.html" created.
File "widgets/mobile-message-body/template.html" created.
File "widgets/navbar/template.html" created.
File "widgets/push-message-body/template.html" created.
File "widgets/report-parameters/template.html" created.
File "widgets/select/test-template.html" created.
File "widgets/sms-engagement-chart/popover-template.html" created.
File "widgets/sms-engagement-chart/template.html" created.
File "widgets/sms-message-body/template.html" created.
File "widgets/spinner/test-template.html" created.
File "widgets/stat-card/template.html" created.
File "widgets/stream-entry/sub-widgets/add-metadata.html" created.
File "widgets/stream-entry/sub-widgets/add-to-list.html" created.
File "widgets/stream-entry/sub-widgets/remove-from-list.html" created.
File "widgets/stream-entry/template.html" created.
File "widgets/stream/template.html" created.
File "widgets/subscriber-growth-chart/template.html" created.
File "widgets/subscriber-search/template.html" created.
File "widgets/subscriber-stat-card/template.html" created.
File "widgets/toolbar/template.html" created.
File "widgets/twitter-message-body/template.html" created.
Running "jade:widgetsIncremental" (jade) task
Running "less:app" (less) task
File dist/css/three.css created.
Running "yaml:strings" (yaml) task
Compiled widgets/audience-filter/strings/en-us.yaml -> widgets/audience-filter/strings.json
Compiled widgets/audience-row/strings/en-us.yaml -> widgets/audience-row/strings.json
Compiled widgets/character-counter/strings/en-us.yaml -> widgets/character-counter/strings.json
Compiled widgets/contact-stat-card/strings/en-us.yaml -> widgets/contact-stat-card/strings.json
Compiled widgets/create-report/strings/en-us.yaml -> widgets/create-report/strings.json
Compiled widgets/dashboard-tour/strings/en-us.yaml -> widgets/dashboard-tour/strings.json
Compiled widgets/dashboard/strings/en-us.yaml -> widgets/dashboard/strings.json
Compiled widgets/datetimepicker/strings/en-us.yaml -> widgets/datetimepicker/strings.json
Compiled widgets/dynamic-insertion/strings/en-us.yaml -> widgets/dynamic-insertion/strings.json
Compiled widgets/facebook-message-body/strings/en-us.yaml -> widgets/facebook-message-body/strings.json
Compiled widgets/file-uploader/strings/en-us.yaml -> widgets/file-uploader/strings.json
Compiled widgets/follower-stat-card/strings/en-us.yaml -> widgets/follower-stat-card/strings.json
Compiled widgets/likes-stat-card/strings/en-us.yaml -> widgets/likes-stat-card/strings.json
Compiled widgets/message-body/strings/en-us.yaml -> widgets/message-body/strings.json
Compiled widgets/message-preview/strings/en-us.yaml -> widgets/message-preview/strings.json
Compiled widgets/mobile-message-body/strings/en-us.yaml -> widgets/mobile-message-body/strings.json
Compiled widgets/navbar/strings/en-us.yaml -> widgets/navbar/strings.json
Compiled widgets/report-parameters/strings/en-us.yaml -> widgets/report-parameters/strings.json
Compiled widgets/shared-strings/en-us.yaml -> widgets/shared-strings.json
Compiled widgets/sms-engagement-chart/strings/en-us.yaml -> widgets/sms-engagement-chart/strings.json
Compiled widgets/sms-message-body/strings/en-us.yaml -> widgets/sms-message-body/strings.json
Compiled widgets/stat-card/strings/en-us.yaml -> widgets/stat-card/strings.json
Compiled widgets/stream-entry/strings/en-us.yaml -> widgets/stream-entry/strings.json
Compiled widgets/stream/strings/en-us.yaml -> widgets/stream/strings.json
Compiled widgets/subscriber-growth-chart/strings/en-us.yaml -> widgets/subscriber-growth-chart/strings.json
Compiled widgets/subscriber-search/strings/en-us.yaml -> widgets/subscriber-search/strings.json
Compiled widgets/subscriber-stat-card/strings/en-us.yaml -> widgets/subscriber-stat-card/strings.json
Compiled widgets/toolbar/strings/en-us.yaml -> widgets/toolbar/strings.json
Compiled widgets/twitter-message-body/strings/en-us.yaml -> widgets/twitter-message-body/strings.json
Running "connect:test" (connect) task
Started connect web server on localhost:8890.
Running "mocha_phantomjs:all" (mocha_phantomjs) task
GET /tests/runner.html 200 5ms - 7.55kb
GET /node_modules/expect.js/expect.js 200 10ms - 34.68kb
GET /scripts/modernizr-2.5.3.js 200 10ms - 46.99kb
GET /node_modules/mocha/mocha.js 200 11ms - 95.22kb
GET /tests/util/sinon-1.4.2.js 200 12ms - 123.66kb
GET /dist/css/three.css 200 16ms - 249.15kb
GET /scripts/require-jquery.js 200 18ms - 340.67kb
GET /tests/spec/main.js 200 3ms - 5.89kb
GET /scripts/waterfall-jquery.js 200 3ms - 103.5kb
GET /scripts/jquery-ui.js 200 3ms - 154.33kb
GET /dist/font/ProximaNova-Reg-webfont.woff 404 2ms
GET /dist/font/ProximaNova-Reg-webfont.ttf 404 1ms
GET /dist/img/three/login-bg-pattern.png 404 0ms
GET /scripts/msgme/ko.js 200 7ms - 1.83kb
GET /tests/util/mock-xhr-server.js 200 7ms - 3.32kb
GET /tests/util/expect-assertions.js 200 5ms - 1.01kb
GET /tests/util/mock-account-features.js 200 6ms - 252b
GET /scripts/msgme/underscore.js 200 0ms - 147b
GET /scripts/lib/knockout.validation.js 200 5ms - 35.45kb
GET /scripts/lib/knockout.mapping.js 200 5ms - 25.04kb
GET /scripts/msgme/ko/extenders.js 200 4ms - 186b
GET /scripts/lib/knockout.js 200 9ms - 166.59kb
GET /scripts/msgme/ko/ignore.js 200 4ms - 304b
GET /scripts/msgme/ko/mapping.js 200 4ms - 11.36kb
GET /scripts/msgme/ko/mapping/subscribe.js 200 3ms - 2.31kb
GET /scripts/msgme/ko/mapping/validation.js 200 3ms - 5.36kb
GET /scripts/msgme/ko/observableDate.js 200 3ms - 3kb
GET /scripts/msgme/ko/extenders/api-date.js 200 1ms - 9.61kb
GET /scripts/lib/underscore.string.js 200 1ms - 16.57kb
GET /scripts/msgme/ko/extenders/index-by.js 200 1ms - 3.62kb
GET /scripts/msgme/util/deep.js 200 1ms - 2.68kb
GET /scripts/msgme/util/format.js 200 1ms - 5.44kb
GET /scripts/lib/sugar.js 200 1ms - 94.83kb
Loading specs
GET /tests/spec/msgme/auth.js 200 4ms - 7.26kb
GET /tests/spec/msgme/ko/extenders/api-date.js 200 4ms - 27.74kb
GET /tests/spec/msgme/ko/extenders/index-by.js 200 3ms - 7.31kb
GET /tests/spec/msgme/ko/mapping.subscribe.js 200 7ms - 3.77kb
GET /tests/spec/msgme/ko/mapping.local.js 200 7ms - 1.04kb
GET /tests/spec/msgme/ko/mapping.extend.js 200 6ms - 1.45kb
GET /tests/spec/msgme/ko/mapping.js 200 6ms - 23.64kb
GET /tests/spec/msgme/ko/mapping.validation.js 200 6ms - 8.21kb
GET /tests/spec/msgme/ko/validation.js 200 1ms - 5kb
GET /tests/spec/msgme/ko/validation/all-are-valid.js 200 2ms - 5.96kb
GET /tests/spec/msgme/ko/validation/unique.js 200 2ms - 6.78kb
GET /tests/spec/msgme/ko/ignore.js 200 1ms - 882b
GET /tests/spec/msgme/util/deep.js 200 2ms - 2.72kb
GET /tests/spec/msgme/util/format.js 200 1ms - 8.17kb
GET /tests/spec/msgme/util/ko-wrap-observable.js 200 3ms - 1.38kb
GET /tests/spec/msgme/util/feature-flags.js 200 2ms - 2.73kb
GET /tests/spec/msgme/util/promise.js 200 1ms - 9.93kb
GET /tests/spec/msgme/viewmodel.js 200 1ms - 775b
GET /tests/spec/msgme/viewmodel/mapping.js 200 1ms - 3.93kb
GET /tests/spec/msgme/viewmodel/coupon.js 200 1ms - 3.78kb
GET /tests/spec/msgme/viewmodel/group.js 200 4ms - 4.63kb
GET /tests/spec/msgme/viewmodel/flow.js 200 3ms - 418b
GET /tests/spec/msgme/viewmodel/pass.js 200 4ms - 61.26kb
GET /tests/spec/msgme/viewmodel/keywords.js 200 1ms - 625b
GET /tests/spec/msgme/viewmodel/list.js 200 3ms - 5.61kb
GET /tests/spec/msgme/viewmodel/metadata.js 200 2ms - 8.69kb
GET /tests/spec/msgme/viewmodel/message.js 200 3ms - 21.84kb
GET /tests/spec/msgme/viewmodel/report.js 200 0ms - 9.85kb
GET /tests/spec/msgme/viewmodel/subscriber.js 200 3ms - 460b
GET /tests/spec/msgme/viewmodel/role.js 200 3ms - 6.64kb
GET /tests/spec/msgme/viewmodel/user.js 200 1ms - 8kb
GET /tests/spec/msgme/viewmodel/query-filter.js 200 2ms - 17.24kb
GET /tests/spec/msgme/viewmodel/add-to-list.js 200 1ms - 345b
GET /tests/spec/msgme/viewmodel/flowmodule-posttourl.js 200 1ms - 1.83kb
GET /tests/spec/msgme/viewmodel/flowmodule-dynamiccontent.js 200 0ms - 1.85kb
GET /tests/spec/msgme/viewmodel/flowmodule-basictext.js 200 1ms - 667b
GET /tests/spec/msgme/viewmodel/flowmodule-passbook.js 200 1ms - 1.97kb
GET /tests/spec/msgme/viewmodel/flowmodule-tagmetadata.js 200 1ms - 7.05kb
GET /tests/spec/msgme/viewmodel/flowmodule-sweeps.js 200 1ms - 3.88kb
GET /tests/spec/msgme/viewmodel/flowmodule-collectmetadata.js 200 2ms - 2.09kb
GET /tests/spec/msgme/viewmodel/flowmodule-poll.js 200 3ms - 5.65kb
GET /tests/spec/msgme/viewmodel/flowmodule-subscription.js 200 1ms - 2.06kb
GET /tests/spec/msgme/viewmodel/flowmodule-agegate.js 200 3ms - 6.18kb
GET /tests/spec/msgme/viewmodel/flowmodule-validation.js 200 5ms - 20.53kb
GET /tests/spec/msgme/viewmodel/flowmodule-texttowin.js 200 5ms - 14.52kb
GET /tests/spec/msgme/viewmodel/send-message.js 200 5ms - 1.03kb
GET /tests/spec/msgme/viewmodel/add-metadata.js 200 6ms - 369b
GET /tests/spec/msgme/viewmodel/remove-from-list.js 200 4ms - 375b
GET /tests/spec/msgme/viewmodel/subscriber-profile.js 200 1ms - 8.81kb
GET /tests/spec/msgme/viewmodel/util/dateparts.js 200 1ms - 1.62kb
GET /tests/spec/msgme/modelcollection.js 200 3ms - 16.06kb
GET /tests/spec/msgme/user-preferences.js 200 1ms - 4.37kb
GET /tests/spec/msgme/routing.js 200 1ms - 2.54kb
GET /tests/spec/msgme/widgets/message-textbox.js 200 2ms - 4.34kb
GET /tests/spec/msgme/widgets/add-metadata.js 200 6ms - 2.99kb
GET /tests/spec/msgme/widgets/add-to-list.js 200 3ms - 3.38kb
GET /tests/spec/msgme/widgets/send-message.js 200 2ms - 1.12kb
GET /widgets/bar-chart/spec.js 200 2ms - 6.88kb
GET /widgets/sms-message-body/spec.js 200 1ms - 13.05kb
GET /widgets/twitter-message-body/spec.js 200 1ms - 2.56kb
GET /widgets/file-uploader/spec.js 200 2ms - 6.52kb
GET /widgets/facebook-message-body/spec.js 200 1ms - 1.01kb
GET /widgets/datetimepicker/spec.js 200 1ms - 3.99kb
GET /widgets/metadata-value/spec.js 200 1ms - 5.34kb
GET /widgets/audience-filter/spec.js 200 1ms - 25.02kb
GET /widgets/audience-row/spec.js 200 1ms - 5.36kb
GET /widgets/message-preview/spec.js 200 1ms - 6.47kb
GET /widgets/navbar/spec.js 200 4ms - 5.83kb
GET /widgets/footer/spec.js 200 4ms - 2.96kb
GET /widgets/report-parameters/spec.js 200 5ms - 17.6kb
GET /widgets/create-report/spec.js 200 4ms - 7.21kb
GET /widgets/select/spec.js 200 7ms - 1.99kb
GET /widgets/spinner/spec.js 200 1ms - 937b
GET /widgets/async-button/spec.js 200 1ms - 3.25kb
GET /widgets/line-chart/spec.js 200 2ms - 903b
GET /widgets/subscriber-growth-chart/spec.js 200 0ms - 1.85kb
GET /widgets/sms-engagement-chart/spec.js 200 1ms - 1.81kb
GET /widgets/stream-entry/spec.js 200 1ms - 13.75kb
GET /widgets/stream/spec.js 200 1ms - 5.88kb
GET /widgets/three-widget-spec.js 200 1ms - 2.15kb
GET /widgets/stat-card/spec.js 200 1ms - 3.12kb
GET /widgets/dashboard/spec.js 200 1ms - 656b
GET /widgets/subscriber-stat-card/spec.js 200 1ms - 886b
GET /widgets/contact-stat-card/spec.js 200 2ms - 881b
GET /widgets/likes-stat-card/spec.js 200 1ms - 1010b
GET /widgets/follower-stat-card/spec.js 200 1ms - 880b
GET /widgets/dashboard-tour/spec.js 200 4ms - 714b
GET /widgets/mobile-message-body/spec.js 200 2ms - 10.48kb
GET /widgets/toolbar/spec.js 200 4ms - 784b
GET /widgets/subscriber-search/spec.js 200 1ms - 721b
GET /scripts/msgme/util/promise.js 200 1ms - 3.07kb
GET /scripts/msgme/auth.js 200 1ms - 4.24kb
GET /scripts/msgme/viewmodel.js 200 3ms - 6.95kb
GET /scripts/msgme/ko/validation.js 200 0ms - 2.31kb
GET /scripts/msgme/viewmodel/mapping.js 200 1ms - 4.36kb
GET /scripts/msgme/util/feature-flags.js 200 2ms - 3.38kb
GET /tests/util/mock-data.js 200 1ms - 14.64kb
GET /scripts/msgme/util/ko-wrap-observable.js 200 1ms - 263b
GET /scripts/msgme/viewmodel/pass.js 200 5ms - 17.34kb
GET /tests/util/shared/validation.js 200 9ms - 1.21kb
GET /scripts/msgme/viewmodel/message.js 200 5ms - 16.09kb
GET /scripts/msgme/viewmodel/coupon.js 200 3ms - 1.4kb
GET /scripts/msgme/viewmodel/flow.js 200 2ms - 11.14kb
GET /scripts/msgme/viewmodel/group.js 200 2ms - 2.12kb
GET /scripts/msgme/viewmodel/keywords.js 200 1ms - 409b
GET /scripts/msgme/viewmodel/list.js 200 1ms - 1.77kb
GET /scripts/msgme/viewmodel/query-filter.js 200 1ms - 3.89kb
GET /scripts/json.js 200 1ms - 2.27kb
GET /scripts/msgme/viewmodel/metadata.js 200 2ms - 6.2kb
GET /scripts/msgme/viewmodel/report.js 200 1ms - 14.07kb
GET /scripts/msgme/viewmodel/subscriber.js 200 1ms - 746b
GET /scripts/msgme/viewmodel/role.js 200 3ms - 8.32kb
GET /tests/util/shared/defaults.js 200 1ms - 425b
GET /scripts/text.js 200 3ms - 3.05kb
GET /scripts/msgme/viewmodel/add-to-list.js 200 4ms - 1.56kb
GET /scripts/msgme/viewmodel/user.js 200 4ms - 2.43kb
GET /tests/spec/msgme/viewmodel/shared.js 200 2ms - 12.39kb
GET /scripts/msgme/viewmodel/flowmodule-posttourl.js 200 1ms - 634b
GET /scripts/msgme/viewmodel/flowmodule-dynamiccontent.js 200 1ms - 638b
GET /scripts/msgme/viewmodel/flowmodule-basictext.js 200 1ms - 1.03kb
GET /scripts/msgme/viewmodel/flowmodule-passbook.js 200 1ms - 1.53kb
GET /scripts/msgme/widgets/flowmodule.js 200 4ms - 2.7kb
GET /scripts/msgme/viewmodel/flowmodule-tagmetadata.js 200 1ms - 3.85kb
GET /scripts/msgme/viewmodel/flowmodule-validation.js 200 1ms - 10.42kb
GET /scripts/msgme/viewmodel/flowmodule-sweeps.js 200 4ms - 3.17kb
GET /scripts/msgme/viewmodel/flowmodule-collectmetadata.js 200 1ms - 1.2kb
GET /scripts/msgme/viewmodel/flowmodule-poll.js 200 1ms - 4.87kb
GET /scripts/msgme/globals.js 200 1ms - 179b
GET /scripts/msgme/viewmodel/flowmodule-subscription.js 200 0ms - 3.58kb
GET /scripts/msgme/viewmodel/flowmodule-agegate.js 200 1ms - 3.33kb
GET /scripts/msgme/viewmodel/flowmodule-texttowin.js 200 2ms - 11.31kb
GET /scripts/msgme/modelcollection.js 200 1ms - 7.17kb
GET /scripts/msgme/viewmodel/send-message.js 200 1ms - 729b
GET /scripts/msgme/viewmodel/remove-from-list.js 200 3ms - 540b
GET /scripts/msgme/viewmodel/add-metadata.js 200 3ms - 1.53kb
GET /scripts/msgme/viewmodel/subscriber-profile.js 200 1ms - 6.16kb
GET /scripts/msgme/viewmodel/util/dateparts.js 200 1ms - 2.83kb
GET /scripts/msgme/user-preferences.js 200 1ms - 3.62kb
GET /scripts/msgme/path.js 200 1ms - 7.5kb
GET /scripts/msgme/widgets/message-textbox.js 200 1ms - 3.58kb
GET /scripts/msgme/widgets/add-to-list.js 200 2ms - 881b
GET /scripts/msgme/widgets/add-metadata.js 200 1ms - 1.17kb
GET /scripts/msgme/widgets/send-message.js 200 1ms - 513b
GET /widgets/bar-chart/index.js 200 4ms - 3.93kb
GET /widgets/test-utils.js 200 1ms - 3.45kb
GET /scripts/msgme/util/api.js 200 1ms - 2.75kb
GET /tests/util/shared/interactions.js 200 1ms - 656b
GET /widgets/sms-message-body/index.js 200 1ms - 3.48kb
GET /widgets/audience-filter/index.js 200 1ms - 14.51kb
GET /widgets/file-uploader/index.js 200 2ms - 6.8kb
GET /widgets/twitter-message-body/index.js 200 1ms - 1.22kb
GET /widgets/facebook-message-body/index.js 200 1ms - 1.19kb
GET /widgets/datetimepicker/index.js 200 1ms - 3.8kb
GET /widgets/metadata-value/index.js 200 1ms - 4.1kb
GET /widgets/report-parameters/index.js 200 1ms - 8.69kb
GET /widgets/audience-row/index.js 200 3ms - 6.24kb
GET /widgets/message-preview/index.js 200 1ms - 6.75kb
GET /widgets/navbar/index.js 200 0ms - 9.23kb
GET /widgets/footer/index.js 200 0ms - 1.04kb
GET /widgets/create-report/index.js 200 1ms - 12.17kb
GET /widgets/select/index.js 200 1ms - 560b
GET /widgets/spinner/index.js 200 1ms - 241b
GET /widgets/async-button/index.js 200 0ms - 2kb
GET /widgets/line-chart/index.js 200 0ms - 10.58kb
GET /widgets/subscriber-growth-chart/index.js 200 1ms - 5.43kb
GET /widgets/sms-engagement-chart/index.js 200 4ms - 3.47kb
GET /widgets/stream-entry/index.js 200 2ms - 27.41kb
GET /scripts/msgme/util/errors.js 200 1ms - 1.18kb
GET /widgets/stream/index.js 200 1ms - 5.13kb
GET /widgets/three-widget.js 200 1ms - 3.04kb
GET /tests/util/mock-stream.js 200 1ms - 2.72kb
GET /widgets/stat-card/index.js 200 1ms - 2.21kb
GET /widgets/dashboard/index.js 200 1ms - 2.59kb
GET /widgets/subscriber-stat-card/index.js 200 1ms - 1.28kb
GET /widgets/contact-stat-card/index.js 200 1ms - 989b
GET /widgets/follower-stat-card/index.js 200 4ms - 1.64kb
GET /widgets/likes-stat-card/index.js 200 3ms - 3.14kb
GET /widgets/dashboard-tour/index.js 200 1ms - 4.26kb
GET /widgets/mobile-message-body/index.js 200 1ms - 8.61kb
GET /widgets/toolbar/index.js 200 1ms - 3.33kb
GET /widgets/subscriber-search/index.js 200 1ms - 3.17kb
GET /scripts/msgme.js 200 1ms - 73b
GET /scripts/msgme/ko/validation/all-are-valid.js 200 1ms - 1.94kb
GET /scripts/msgme/ko/validation/unique.js 200 1ms - 1.71kb
GET /scripts/msgme/util/is-mms-enabled.js 200 1ms - 247b
GET /scripts/msgme/util/account-features.js 200 3ms - 2.85kb
GET /tests/util/querystring.js 200 1ms - 1.16kb
GET /scripts/msgme/util/traverse.js 200 1ms - 265b
GET /tests/fixtures/rolePermsFixtures.json 200 1ms - 6.44kb
GET /tests/spec/msgme/viewmodel/util/dateparts.html 200 1ms - 398b
GET /widgets/select/test-template.html 200 1ms - 595b
GET /widgets/spinner/test-template.html 200 1ms - 242b
GET /widgets/async-button/test-template.html 200 1ms - 164b
GET /tests/fixtures/group.json 200 2ms - 2.91kb
GET /tests/fixtures/stream.json 200 1ms - 31.7kb
GET /tests/fixtures/role.json 200 1ms - 22.19kb
GET /tests/fixtures/user.json 200 1ms - 26.84kb
GET /tests/fixtures/flow.json 200 2ms - 436b
GET /tests/fixtures/list.json 200 1ms - 7.11kb
GET /tests/fixtures/metadata.json 200 1ms - 10.12kb
GET /tests/fixtures/filter.json 200 1ms - 257b
GET /tests/fixtures/shortcodes.json 200 1ms - 42.75kb
GET /tests/fixtures/sessionshortcode.json 200 1ms - 816b
GET /tests/fixtures/file.json 200 1ms - 369b
GET /tests/fixtures/keyword.json 200 0ms - 11.42kb
GET /tests/fixtures/coupon.json 200 1ms - 4.62kb
GET /tests/fixtures/channel.json 200 1ms - 171b
GET /tests/fixtures/post.json 200 1ms - 177b
GET /tests/fixtures/facebookAudience.json 200 1ms - 1.74kb
GET /tests/fixtures/facebookProfile.json 200 1ms - 545b
GET /tests/fixtures/report.subscriberGrowth.json 200 1ms - 12.6kb
GET /tests/fixtures/report.messageSummary.MOBILEFLOW.json 200 1ms - 21.44kb
GET /tests/fixtures/subscriber.json 200 0ms - 430b
GET /tests/fixtures/whoami.json 200 1ms - 2.28kb
GET /tests/fixtures/twitterAudience.json 200 1ms - 233b
GET /widgets/shared-strings.json 200 1ms - 6.38kb
GET /widgets/report-parameters/strings.json 200 1ms - 794b
GET /widgets/create-report/strings.json 200 0ms - 2.54kb
GET /tests/fixtures/line-chart.json 200 1ms - 1019b
GET /widgets/stream-entry/strings.json 200 1ms - 2.01kb
GET /widgets/stat-card/strings.json 200 1ms - 468b
GET /widgets/mobile-message-body/strings.json 200 1ms - 456b
GET /config/environment.json 200 2ms - 28b
GET /widgets/subscriber-search/strings.json 200 2ms - 263b
GET /scripts/msgme/widgets/widget.js 200 1ms - 6.49kb
GET /scripts/lib/path.js 200 1ms - 7.31kb
GET /widgets/dynamic-insertion/index.js 200 1ms - 1.72kb
GET /widgets/bar-chart/template.html 200 1ms - 45b
GET /scripts/msgme/alert.js 200 1ms - 3.5kb
GET /scripts/lib/d3.js 200 4ms - 308.16kb
GET /widgets/message-body/index.js 200 2ms - 8.79kb
GET /widgets/sms-message-body/template.html 200 1ms - 2.55kb
GET /widgets/sms-message-body/strings.json 200 1ms - 342b
GET /widgets/message-body/strings.json 200 1ms - 325b
GET /scripts/msgme/modelcollection/filter.js 200 2ms - 632b
GET /widgets/audience-filter/template.html 200 1ms - 2.69kb
GET /widgets/audience-filter/strings.json 200 1ms - 187b
GET /scripts/lib/bootstrap.js 200 1ms - 46.76kb
GET /widgets/file-uploader/template.html 200 3ms - 1.75kb
GET /widgets/file-uploader/strings.json 200 2ms - 222b
GET /scripts/jquery.form.js 200 1ms - 38.64kb
GET /widgets/twitter-message-body/template.html 200 1ms - 2.2kb
GET /widgets/twitter-message-body/strings.json 200 0ms - 103b
GET /widgets/facebook-message-body/template.html 200 1ms - 2.08kb
GET /widgets/facebook-message-body/strings.json 200 1ms - 73b
GET /widgets/datetimepicker/template.html 200 1ms - 286b
GET /widgets/datetimepicker/strings.json 200 1ms - 38b
GET /widgets/metadata-value/template.html 200 2ms - 467b
GET /scripts/lib/bootstrap-datetimepicker.js 200 1ms - 42.58kb
GET /widgets/report-parameters/template.html 200 1ms - 93b
GET /widgets/audience-row/template.html 200 1ms - 1.91kb
GET /widgets/audience-row/strings.json 200 1ms - 198b
GET /widgets/message-preview/template.html 200 1ms - 3.7kb
GET /widgets/message-preview/strings.json 200 2ms - 358b
GET /scripts/msgme/widgets/modal.js 200 3ms - 4.24kb
GET /widgets/navbar/template.html 200 1ms - 2.65kb
GET /widgets/navbar/strings.json 200 1ms - 151b
GET /widgets/footer/template.html 200 1ms - 545b
GET /widgets/create-report/template.html 200 1ms - 9.95kb
GET /scripts/lib/select2.js 200 2ms - 132.5kb
GET /scripts/msgme/modal.js 200 1ms - 4.19kb
GET /widgets/stream-entry/template.html 200 1ms - 7.06kb
GET /widgets/stream-entry/sub-widgets/add-to-list.html 200 1ms - 3.18kb
GET /widgets/stream-entry/sub-widgets/remove-from-list.html 200 0ms - 831b
GET /widgets/stream-entry/sub-widgets/add-metadata.html 200 1ms - 1.12kb
GET /scripts/msgme/plugins.js 200 1ms - 1014b
GET /scripts/msgme/widgets/remove-from-list.js 200 1ms - 212b
GET /scripts/lib/spin.js 200 1ms - 10.16kb
GET /widgets/async-button/template.html 200 1ms - 109b
GET /widgets/line-chart/template.html 200 1ms - 46b
GET /widgets/subscriber-growth-chart/template.html 200 1ms - 1.02kb
GET /widgets/subscriber-growth-chart/strings.json 200 1ms - 433b
GET /widgets/sms-engagement-chart/template.html 200 1ms - 84b
GET /widgets/sms-engagement-chart/popover-template.html 200 1ms - 155b
GET /widgets/sms-engagement-chart/strings.json 200 1ms - 48b
GET /widgets/stream/template.html 200 1ms - 817b
GET /widgets/stream/strings.json 200 1ms - 165b
GET /tests/fixtures/conversation.json 200 3ms - 2.11kb
GET /widgets/stat-card/template.html 200 2ms - 538b
GET /widgets/dashboard/strings.json 200 1ms - 187b
GET /widgets/dashboard/template.html 200 1ms - 1.51kb
GET /widgets/subscriber-stat-card/template.html 200 1ms - 752b
GET /widgets/contact-stat-card/template.html 200 1ms - 382b
GET /widgets/follower-stat-card/template.html 200 1ms - 740b
GET /widgets/likes-stat-card/template.html 200 1ms - 854b
GET /widgets/dashboard-tour/strings.json 200 2ms - 1018b
GET /widgets/dashboard-tour/popover.html 200 2ms - 447b
GET /widgets/dashboard-tour/restart.html 200 2ms - 93b
GET /scripts/lib/bootstrap-tour.js 200 1ms - 23.28kb
GET /widgets/mobile-message-body/template.html 200 1ms - 1.4kb
GET /widgets/toolbar/strings.json 200 1ms - 97b
GET /widgets/toolbar/template.html 200 1ms - 332b
GET /widgets/character-counter/index.js 200 1ms - 2.79kb
GET /widgets/subscriber-search/template.html 200 1ms - 865b
GET /widgets/dynamic-insertion/strings.json 200 1ms - 181b
GET /widgets/dynamic-insertion/template.html 200 5ms - 918b
GET /widgets/message-body/template.html 200 1ms - 1.27kb
GET /widgets/character-counter/strings.json 200 1ms - 97b
GET /widgets/character-counter/template.html 200 1ms - 74b
Specs loaded
the apiDate extender
when read
◦ if null, returns null:
✓ if null, returns null
◦ if a Date instance, returns its value formatted as an API date:
✓ if a Date instance, returns its value formatted as an API date
◦ if a valid date string, returns it formatted as an API date:
✓ if a valid date string, returns it formatted as an API date
◦ if an epoch date, returns it formatted as an API date:
✓ if an epoch date, returns it formatted as an API date
◦ if an invalid date string, returns null:
✓ if an invalid date string, returns null
when written
◦ accepts a Date instance:
✓ accepts a Date instance
- accepts a Date instance for today
◦ accepts a valid date string:
✓ accepts a valid date string
◦ accepts a null:
✓ accepts a null
◦ ignores values that result in an invalid date:
✓ ignores values that result in an invalid date
adds a seconds subcomputed
called with no argument
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns the seconds:
✓ if value is a date, returns the seconds
called with an argument
◦ throws if apiDate value is null:
✓ throws if apiDate value is null
◦ if arg is a valid seconds value, sets the seconds:
✓ if arg is a valid seconds value, sets the seconds
◦ otherwise it throws:
✓ otherwise it throws
adds a minutes subcomputed
called with no argument
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns the minutes:
✓ if value is a date, returns the minutes
called with an argument
◦ throws if apiDate value is null:
✓ throws if apiDate value is null
◦ if arg is a valid minutes value, sets the minutes:
✓ if arg is a valid minutes value, sets the minutes
◦ otherwise it throws:
✓ otherwise it throws
adds a hours subcomputed
called with no argument
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns the hours:
✓ if value is a date, returns the hours
called with an argument
◦ throws if apiDate value is null:
✓ throws if apiDate value is null
◦ if arg is a valid hours value, sets the hours:
✓ if arg is a valid hours value, sets the hours
◦ otherwise it throws:
✓ otherwise it throws
adds a period subcomputed
called with no argument
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns the period:
✓ if value is a date, returns the period
called with an argument
◦ throws if apiDate value is null:
✓ throws if apiDate value is null
◦ if arg is a valid period value, sets the period and hours:
✓ if arg is a valid period value, sets the period and hours
◦ otherwise it throws:
✓ otherwise it throws
adds a date subcomputed
called with no argument
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns the date:
✓ if value is a date, returns the date
called with an argument
◦ throws if apiDate value is null:
✓ throws if apiDate value is null
◦ if arg is a valid date value, sets the date:
✓ if arg is a valid date value, sets the date
◦ otherwise it throws:
✓ otherwise it throws
adds a month subcomputed
called with no argument
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns the month:
✓ if value is a date, returns the month
called with an argument
◦ throws if apiDate value is null:
✓ throws if apiDate value is null
◦ if arg is a valid month value, sets the month:
✓ if arg is a valid month value, sets the month
◦ otherwise it throws:
✓ otherwise it throws
adds a year subcomputed
called with no argument
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns the year:
✓ if value is a date, returns the year
called with an argument
◦ throws if apiDate value is null:
✓ throws if apiDate value is null
◦ if arg is a valid year value, sets the year:
✓ if arg is a valid year value, sets the year
◦ otherwise it throws:
✓ otherwise it throws
adds an offsetMinutes subcomputed
called with no argument
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns the offsetMinutes from UTC in minutes:
✓ if value is a date, returns the offsetMinutes from UTC in minutes
called with an argument
◦ if arg is an integer, sets offsetMinutes of API date:
✓ if arg is an integer, sets offsetMinutes of API date
◦ otherwise it throws:
✓ otherwise it throws
adds an offset subcomputed
◦ can be set by the "offset" config option:
✓ can be set by the "offset" config option
called with no argument
◦ if value is a date, returns the offset from UTC:
✓ if value is a date, returns the offset from UTC
called with an argument
◦ if arg is a valid offset string, sets offset:
✓ if arg is a valid offset string, sets offset
◦ if arg is an integer, interprets it as minutes from UTC:
✓ if arg is an integer, interprets it as minutes from UTC
◦ otherwise it throws:
✓ otherwise it throws
adds a format subobservable
◦ can be set by the "format" config option:
✓ can be set by the "format" config option
◦ defaults to m/d/yyyy h:MM TT:
✓ defaults to m/d/yyyy h:MM TT
adds a formatted subcomputed
◦ if value is null, formatted returns null:
✓ if value is null, formatted returns null
◦ if value is a date, returns it formatted by format:
✓ if value is a date, returns it formatted by format
adds an asDate subcomputed
when read
◦ if value is null, returns null:
✓ if value is null, returns null
◦ if value is a date, returns a Date instance:
✓ if value is a date, returns a Date instance
when written
◦ accepts a Date instance:
✓ accepts a Date instance
◦ accepts a valid date string:
✓ accepts a valid date string
◦ accepts a null:
✓ accepts a null
◦ ignores values that result in an invalid date:
✓ ignores values that result in an invalid date
the indexBy extender
◦ throws if extending an observable not containing an array:
✓ throws if extending an observable not containing an array
◦ unwraps observable values if necessary:
✓ unwraps observable values if necessary
when passed a string "foo"
◦ indexes the array by "foo":
✓ indexes the array by "foo"
when passed an array of strings
◦ indexes the array by each string:
✓ indexes the array by each string
when passed a config object
◦ throws if config.keys is not a non-empty array:
✓ throws if config.keys is not a non-empty array
◦ indexes the array by config.keys:
✓ indexes the array by config.keys
◦ returns one element per key if config.unique is `true`:
✓ returns one element per key if config.unique is `true`
when indexing an observableArray
◦ reindexes if the observableArray changes:
✓ reindexes if the observableArray changes
◦ the index notifies subscribers if the observableArray changes:
✓ the index notifies subscribers if the observableArray changes
the local plugin
◦ provides the root model to subcomputeds and computeds:
✓ provides the root model to subcomputeds and computeds
the extend plugin
◦ calls extend on the mapped field, passing the value of the mapping:
✓ calls extend on the mapped field, passing the value of the mapping
◦ overwrites the mapped field with the result of the extender:
✓ overwrites the mapped field with the result of the extender
◦ throws if the mapping value names a non-existent extender:
✓ throws if the mapping value names a non-existent extender
the subscribe plugin
◦ calls subscribe on the mapped field, passing a function that calls the subscriber:
✓ calls subscribe on the mapped field, passing a function that calls the subscriber
◦ calls the subscriber for initial values:
✓ calls the subscriber for initial values
◦ calls the subscriber in the context of the model:
✓ calls the subscriber in the context of the model
◦ throws if the mapping value is not a function:
✓ throws if the mapping value is not a function
the validation plugin
◦ adds validation to the mapped observable:
✓ adds validation to the mapped observable
◦ extend is called on the observable and passed the mapped value:
✓ extend is called on the observable and passed the mapped value
◦ calls anonymous validators in a context that provides observable, parent, and root as properties:
✓ calls anonymous validators in a context that provides observable, parent, and root as properties
◦ calls message functions in a context that provides observable, parent, and root as properties:
✓ calls message functions in a context that provides observable, parent, and root as properties
◦ calls onlyIf functions in a context that provides observable, parent, and root as properties:
✓ calls onlyIf functions in a context that provides observable, parent, and root as properties
if the mapped value is a function
◦ the function is used as an anonymous validator:
✓ the function is used as an anonymous validator
if the mapped value is an object w/ a "validator" key
◦ the function is used as an anonymous validator:
✓ the function is used as an anonymous validator
ignore binding handler
◦ prevents ko from applying bindings to descendents:
✓ prevents ko from applying bindings to descendents
deep
defaults
◦ performs a deep update of an object with defaults:
✓ performs a deep update of an object with defaults
◦ doesnt overwrite null with a string:
✓ doesnt overwrite null with a string
◦ doesnt overwrite null with an array:
✓ doesnt overwrite null with an array
◦ doesnt overwrite null with an object:
✓ doesnt overwrite null with an object
◦ preserves functions passed in as defaults:
✓ preserves functions passed in as defaults
format.uiDate
◦ returns a formatted date if passed a valid Date:
✓ returns a formatted date if passed a valid Date
◦ returns a formatted date if passed a valid date string:
✓ returns a formatted date if passed a valid date string
◦ returns "Invalid Date" if passed an invalid Date:
✓ returns "Invalid Date" if passed an invalid Date
◦ returns "Invalid Date" if passed an invalid date string:
✓ returns "Invalid Date" if passed an invalid date string
format.apiReportingDate
◦ handes the format MM/DD/YYYY:
✓ handes the format MM/DD/YYYY
◦ handes the format YYYY/MM/D:
✓ handes the format YYYY/MM/D
◦ handes the format MM-DD-YYYY:
✓ handes the format MM-DD-YYYY
format.apiDate
◦ returns a formatted date if passed a valid Date:
✓ returns a formatted date if passed a valid Date
◦ returns "Invalid Date" if passed an invalid Date:
✓ returns "Invalid Date" if passed an invalid Date
◦ returns "Invalid Date" if passed an invalid date string:
✓ returns "Invalid Date" if passed an invalid date string
format.uiDateOnly
◦ returns a formatted date if passed a valid Date:
✓ returns a formatted date if passed a valid Date
◦ returns "Invalid Date" if passed an invalid Date:
✓ returns "Invalid Date" if passed an invalid Date
◦ returns "Invalid Date" if passed an invalid date string:
✓ returns "Invalid Date" if passed an invalid date string
format.uiShortRelativeDate
◦ returns a short relative date if passed a date in the past:
✓ returns a short relative date if passed a date in the past
◦ returns an absolute date if passed a date in the future:
✓ returns an absolute date if passed a date in the future
format.integer
returns an integer as a string with commas inserted as expected
◦ for zero:
✓ for zero
◦ for positive integers:
✓ for positive integers
- for negative
◦ for floating-point numbers:
✓ for floating-point numbers
◦ for string, date:
✓ for string, date
format.phoneNo
◦ returns a string as a US telephone number if passed a string:
✓ returns a string as a US telephone number if passed a string
◦ returns a string as a US telephone number if passed a number:
✓ returns a string as a US telephone number if passed a number
- returns "invalid" if passed a non string or number > No Test
◦ returns a string if passed an incomplete string:
✓ returns a string if passed an incomplete string
◦ returns a number if passed an incomplete number:
✓ returns a number if passed an incomplete number
format.urlString
◦ returns null or undefined as "":
✓ returns null or undefined as ""
◦ returns a string url-encoded, in lowercase:
✓ returns a string url-encoded, in lowercase
format.parseUrlString
◦ returns a string url-decoded, with pluses as spaces:
✓ returns a string url-decoded, with pluses as spaces
format.unformattedPhoneNo
◦ returns a ten digit telephone number:
✓ returns a ten digit telephone number
◦ strips formatting and returns telephone number:
✓ strips formatting and returns telephone number
◦ passing in null/undefined:
✓ passing in null/undefined
◦ passing in a number:
✓ passing in a number
msgme.ko.mapping
◦ applies mappings to the current nesting level only:
✓ applies mappings to the current nesting level only
◦ handles undefined fields:
✓ handles undefined fields
◦ calls create handlers for fields with nested mappings:
✓ calls create handlers for fields with nested mappings
◦ correctly maps a nested array:
✓ correctly maps a nested array
◦ does not define default mappings for array elements:
✓ does not define default mappings for array elements
◦ does not recursively map children if mapping === false:
✓ does not recursively map children if mapping === false
◦ uses the original mapping when updating:
✓ uses the original mapping when updating
◦ does not recursively map plugin mappings:
✓ does not recursively map plugin mappings
accepts an optional root model argument
◦ uses target as the root if none is provided:
✓ uses target as the root if none is provided
◦ overrides the root if passed:
✓ overrides the root if passed
defines an isValid computed on mapped models
◦ is true only if all validatable children are valid:
✓ is true only if all validatable children are valid
◦ validates child models recursively:
✓ validates child models recursively
defines a default isValid on observableArrays
◦ listens for changes in array member validity:
✓ listens for changes in array member validity
◦ recursively validates unvalidated arrays:
✓ recursively validates unvalidated arrays
◦ does not alter validation of validated arrays:
✓ does not alter validation of validated arrays
defines an errors computed on mapped models
◦ returns an array containing child errors:
✓ returns an array containing child errors
◦ flattens child model errors:
✓ flattens child model errors
describe a recursive isModified on recursively mapped models
◦ returns true if any descendant returns true:
✓ returns true if any descendant returns true
◦ returns false if all descendants define isModified:
✓ returns false if all descendants define isModified
◦ returns false if no descendants define isModified:
✓ returns false if no descendants define isModified
◦ passes its argument to its descendants:
✓ passes its argument to its descendants
◦ recurses into observable array descendants:
✓ recurses into observable array descendants
◦ unwraps observables that do not define isModified:
✓ unwraps observables that do not define isModified
◦ unwraps observable array members that do not define isModified:
✓ unwraps observable array members that do not define isModified
util/promise
defer
◦ returns a promise:
✓ returns a promise
◦ calls the function on a later turn of the event loop:
✓ calls the function on a later turn of the event loop
◦ resolves with the function return value:
✓ resolves with the function return value
◦ rejects with the error if one is thrown:
✓ rejects with the error if one is thrown
◦ uses identity function for default param:
✓ uses identity function for default param
timeout
◦ resolves the deferred after the specified timeout in ms:
✓ resolves the deferred after the specified timeout in ms (112ms)
◦ resolves with the given args:
✓ resolves with the given args
deferValue
◦ returns a promise:
✓ returns a promise
◦ resolves to the passed value on a later event loop turn:
✓ resolves to the passed value on a later event loop turn
series
◦ returns a promise:
✓ returns a promise
◦ immediately executes the first function passed:
✓ immediately executes the first function passed
◦ executes subsequent functions serially:
✓ executes subsequent functions serially
◦ passes each function the result of the previous:
✓ passes each function the result of the previous
◦ resolves with the result of the final function:
✓ resolves with the result of the final function
◦ rejects with the error if the first function rejects:
✓ rejects with the error if the first function rejects
◦ rejects with the error if any subsequent function rejects:
✓ rejects with the error if any subsequent function rejects
deferSeries
◦ returns a promise:
✓ returns a promise
◦ executes the functions serially, on their own event loop turn:
✓ executes the functions serially, on their own event loop turn
◦ passes each function the result of the previous:
✓ passes each function the result of the previous
◦ resolves with the result of the final function:
✓ resolves with the result of the final function
◦ rejects with the error if any function throws:
✓ rejects with the error if any function throws
msgme.viewmodel.mapping
CursorModel
create()
◦ returns a RecordModel:
✓ returns a RecordModel
◦ populates the returned RecordModel with configured default data:
✓ populates the returned RecordModel with configured default data
◦ overrides default data with config.data if passed:
✓ overrides default data with config.data if passed
RecordModel
◦ calls create on the source on the first call to save:
✓ calls create on the source on the first call to save
◦ calls create on the source on the first call to save:
✓ calls create on the source on the first call to save
koWrapObservable
Passed an observable
◦ Return an observable:
✓ Return an observable
◦ Return same value wrapped in an observable:
✓ Return same value wrapped in an observable
◦ Return the same observable:
✓ Return the same observable
Passed an non-observable
◦ Return an observable:
✓ Return an observable
◦ Return same value wrapped in an observable:
✓ Return same value wrapped in an observable
standalone mapping for flow viewmodel
◦ exports model:
✓ exports model
◦ exports collection:
✓ exports collection
standalone mapping for keywords viewmodel
◦ is exported correctly:
✓ is exported correctly
◦ has the correct defaults:
✓ has the correct defaults
standalone mapping for list viewmodel
◦ exports model:
✓ exports model
◦ exports collection:
✓ exports collection
sets the correct collection defaults
◦ for rows:
✓ for rows
◦ for pageIndex:
✓ for pageIndex
◦ for pageCount:
✓ for pageCount
◦ for pageSize:
✓ for pageSize
◦ for links:
✓ for links
◦ for url:
✓ for url
sets the correct subscribers defaults
◦ for rows:
✓ for rows
◦ for pageIndex:
✓ for pageIndex
◦ for pageCount:
✓ for pageCount
◦ for pageSize:
✓ for pageSize
◦ for links:
✓ for links
◦ for url:
✓ for url
provides a urlName computed
◦ is "" if no name is set:
✓ is "" if no name is set
◦ is the list name in lowercase:
✓ is the list name in lowercase
provides a url computed
◦ is /lists if no name is set:
✓ is /lists if no name is set
◦ is /lists/ + the list name, url-encoded and lowercase:
✓ is /lists/ + the list name, url-encoded and lowercase
validation
name
◦ is required:
✓ is required
◦ is at least 5 characters:
✓ is at least 5 characters
◦ is less than 30 characters:
✓ is less than 30 characters
◦ accepts valid names:
✓ accepts valid names
flowmodule-tagmetadata viewmodel
◦ sets default values:
✓ sets default values
validation
◦ metadata field is required:
✓ metadata field is required
◦ metadata freeValue is required if no validValues:
✓ metadata freeValue is required if no validValues
◦ metadata fixedValue is required if validValues:
✓ metadata fixedValue is required if validValues
computed value
◦ metadataId:
✓ metadataId
fixedValue
◦ returns the params value if validValues is not null and params is set:
✓ returns the params value if validValues is not null and params is set
◦ returns an empty string if validValues is not null and params is an empty object:
✓ returns an empty string if validValues is not null and params is an empty object
◦ is set when validValues is set:
✓ is set when validValues is set
◦ is not set when validValues is not set:
✓ is not set when validValues is not set
◦ is not set when metadataId is null:
✓ is not set when metadataId is null
freeValue
◦ returns the params value if it exists and validValues is null:
✓ returns the params value if it exists and validValues is null
◦ returns an empty string if params is an empty object andvalidValues is null:
✓ returns an empty string if params is an empty object andvalidValues is null
◦ is not set when validValues is set:
✓ is not set when validValues is set
◦ is not set when metadataId is null:
✓ is not set when metadataId is null
◦ is set when validValues is null and metadataId is set:
✓ is set when validValues is null and metadataId is set
flowmodule-collectmetadata mapping
validation
◦ metadataId is required:
✓ metadataId is required
sets the correct defaults
◦ title:
✓ title
◦ metadataId:
✓ metadataId
◦ requestMessage:
✓ requestMessage
◦ responseMessage:
✓ responseMessage
provides a subcomputed widgetId
◦ for request:
✓ for request
◦ for response:
✓ for response
◦ for invalidFormat:
✓ for invalidFormat
add to list viewmodel
shared tests
sets the correct defaults
◦ default opt-in type is single:
✓ default opt-in type is single
◦ default confirm message string:
✓ default confirm message string
◦ default opt-in message string:
✓ default opt-in message string
◦ default subscribed message is empty:
✓ default subscribed message is empty
provides a widgetId computed
◦ returns widgetId:
✓ returns widgetId
provides a widgetId subcomputed
◦ for optIn:
✓ for optIn
◦ for confirm:
✓ for confirm
◦ for subscribed:
✓ for subscribed
widgetId computed
◦ increments:
✓ increments
modelcollection
fetchOne
◦ returns a single record model:
✓ returns a single record model
◦ triggers a change on oneById when a new model is fetched:
✓ triggers a change on oneById when a new model is fetched
◦ updates existing models when items change:
✓ updates existing models when items change
fetch
◦ returns a list of record models that matches _items:
✓ returns a list of record models that matches _items (50ms)
◦ adds new items to existing items:
✓ adds new items to existing items
◦ triggers a change on _items only on change:
✓ triggers a change on _items only on change
indexOneBy
◦ indexes id if available:
✓ indexes id if available
◦ maps items to an object keyed by their ids:
✓ maps items to an object keyed by their ids (55ms)
◦ changes when items are added to _items:
✓ changes when items are added to _items
◦ changes when _items is spliced:
✓ changes when _items is spliced
◦ changes when something is appended to _items:
✓ changes when something is appended to _items
◦ changes when an item is removed to _items:
✓ changes when an item is removed to _items
◦ throws when a model does not have the prop:
✓ throws when a model does not have the prop
indexAllBy
◦ returns an object of lists for prop values:
✓ returns an object of lists for prop values
◦ throws when a model does not have the prop:
✓ throws when a model does not have the prop
create
◦ returns a record model instance:
✓ returns a record model instance
◦ overrides the save method to call Collection#create:
✓ overrides the save method to call Collection#create
◦ adds the new recordmodel to the collection:
✓ adds the new recordmodel to the collection
send message viewmodel
send message mapping sets the correct defaults
◦ for message:
✓ for message
provides a send-message widgetId computed
◦ returns widgetId:
✓ returns widgetId
widgetId computed
◦ increments:
✓ increments
provides a message-textbox widgetId subcomputed
◦ returns widgetId:
✓ returns widgetId
remove from list viewmodel
widgetId computed
◦ increments:
✓ increments
shared tests
sets the correct defaults
◦ for listId:
✓ for listId
◦ for lists:
✓ for lists
provides a widgetId computed
◦ returns widgetId:
✓ returns widgetId
add metadata viewmodel
widgetId computed
◦ increments:
✓ increments
shared tests
sets the correct defaults
◦ for validValues:
✓ for validValues
◦ for format:
✓ for format
◦ for metadataId:
✓ for metadataId
◦ for value:
✓ for value
provides a widgetId computed
◦ returns a widgetId:
✓ returns a widgetId
provides subcomputeds for
free value
when there are no validValues
◦ returns the correct value:
✓ returns the correct value
◦ sets value:
✓ sets value
when validValues exist
◦ returns the correct value:
✓ returns the correct value
◦ value does not get set:
✓ value does not get set
fixed value
if no validValues
◦ returns the correct value:
✓ returns the correct value
◦ value does not get set:
✓ value does not get set
if validValues
◦ returns the correct value:
✓ returns the correct value
◦ sets value:
✓ sets value
subscriber profile viewmodel
◦ sets the correct defaults:
✓ sets the correct defaults
validation
◦ sets modals.sendmessage.isValid based on children:
✓ sets modals.sendmessage.isValid based on children
◦ requires modals.sendmessage.message to be truthy:
✓ requires modals.sendmessage.message to be truthy
◦ sets modals.subscribe.isValid based on children:
✓ sets modals.subscribe.isValid based on children
◦ requires modals.subscribe.listId to be truthy:
✓ requires modals.subscribe.listId to be truthy
◦ requires modals.subscribe.optInMessage to be nonempty for non-single-optin:
✓ requires modals.subscribe.optInMessage to be nonempty for non-single-optin
◦ sets modals.unsubscribe.isValid based on child:
✓ sets modals.unsubscribe.isValid based on child
◦ requires modals.unsubscribe.listId to be truthy:
✓ requires modals.unsubscribe.listId to be truthy
◦ sets modals.metadata.isValid based on children:
✓ sets modals.metadata.isValid based on children
◦ requires modals.metadata.id to be truthy:
✓ requires modals.metadata.id to be truthy
◦ requires modals.metadata.value to be truthy:
✓ requires modals.metadata.value to be truthy
computed value
◦ modals.sendmessage.widgetId is provided:
✓ modals.sendmessage.widgetId is provided
◦ modals.subscribe.optIn.widgetId is provided:
✓ modals.subscribe.optIn.widgetId is provided
◦ modals.subscribe.confirm.widgetId is provided:
✓ modals.subscribe.confirm.widgetId is provided
◦ modals.subscribe.subscribed.widgetId is provided:
✓ modals.subscribe.subscribed.widgetId is provided
◦ modals.metadata.value.free only returns value if validValues isnt set:
✓ modals.metadata.value.free only returns value if validValues isnt set
◦ modals.metadata.value.free only updates value if validValues isnt set:
✓ modals.metadata.value.free only updates value if validValues isnt set
◦ modals.metadata.value.fixed only returns value if validValues is set:
✓ modals.metadata.value.fixed only returns value if validValues is set
◦ modals.metadata.value.fixed only updates value if validValues is set:
✓ modals.metadata.value.fixed only updates value if validValues is set
standalone mapping for subscriber viewmodel
◦ exports model:
✓ exports model
◦ exports collection:
✓ exports collection
user preferences
module
◦ is a function that returns a promise:
✓ is a function that returns a promise
◦ resolves to a RecordModel-like instance:
✓ resolves to a RecordModel-like instance
◦ provides a clear method which removes the preferences:
✓ provides a clear method which removes the preferences
record model
save
◦ persists values to localStorage:
✓ persists values to localStorage
del
◦ removes the value from local storage:
✓ removes the value from local storage
initPref
◦ initializes a preference to the given value:
✓ initializes a preference to the given value
◦ adds the preference to the mapping:
✓ adds the preference to the mapping
◦ doesn't overwrite an existing value:
✓ doesn't overwrite an existing value
◦ returns the prefs:
✓ returns the prefs
init
◦ initializes multiple values:
✓ initializes multiple values
msgme.auth
defines a has method
◦ returns true if the user has permision for the actions exactly:
✓ returns true if the user has permision for the actions exactly
◦ returns true if user has permision for the actions by account:
✓ returns true if user has permision for the actions by account
◦ returns false if the user does not have permision for the actions by account:
✓ returns false if the user does not have permision for the actions by account
◦ returns true if user has permision for the actions by group:
✓ returns true if user has permision for the actions by group
◦ returns false if the user does not have permision for the actions by group:
✓ returns false if the user does not have permision for the actions by group
◦ returns true if the user has permission for the actions on the type:
✓ returns true if the user has permission for the actions on the type
◦ returns true if the user has permission for the actions on all types:
✓ returns true if the user has permission for the actions on all types
◦ returns false if the user does not have permission for the actions on the type:
✓ returns false if the user does not have permission for the actions on the type
◦ returns true if the user has permission for more actions than needed:
✓ returns true if the user has permission for more actions than needed
◦ returns false if the user has permission for fewer actions than needed:
✓ returns false if the user has permission for fewer actions than needed
◦ returns false if the user does not have the passed permission:
✓ returns false if the user does not have the passed permission
defines a hasAny method
◦ returns true if the user has any of the passed permissions:
✓ returns true if the user has any of the passed permissions
◦ returns false if the user has none of the passed permissions:
✓ returns false if the user has none of the passed permissions
◦ returns true if the group is included in a list:
✓ returns true if the group is included in a list
◦ returns false if the group is not included in a list:
✓ returns false if the group is not included in a list
defines a hasAll method
◦ returns true if the user has all of the passed permissions:
✓ returns true if the user has all of the passed permissions
◦ returns false if the user is missing any of the passed permissions:
✓ returns false if the user is missing any of the passed permissions
msgme/ko/validation
promise method
◦ is attached to the isValid observable of asynchronously validated observables:
✓ is attached to the isValid observable of asynchronously validated observables
◦ is not attached to the isValid observable of synchronously validated observables:
✓ is not attached to the isValid observable of synchronously validated observables
◦ the promise resolves with the value of isValid when isValidating is next true:
✓ the promise resolves with the value of isValid when isValidating is next true
◦ gives isValid a chance to update before resolving:
✓ gives isValid a chance to update before resolving (88ms)
◦ resolves on a later tick if async validation not in progress:
✓ resolves on a later tick if async validation not in progress
msgme/ko/validation/uniqueValue
◦ queries the provided cursor model:
✓ queries the provided cursor model
◦ is valid if no results are returned:
✓ is valid if no results are returned
◦ aborts any pending previous query:
✓ aborts any pending previous query
if results are returned
◦ is invalid if the id does not match:
✓ is invalid if the id does not match
◦ is valid if the id matches:
✓ is valid if the id matches
◦ is invalid if no id is provided:
✓ is invalid if no id is provided
if fetch fails
it tries again
◦ unless the fetch was aborted:
✓ unless the fetch was aborted (204ms)
◦ a default of 3 times:
✓ a default of 3 times (303ms)
◦ as many times as specified by retries:
✓ as many times as specified by retries (703ms)
◦ the field is still validating after max retries exhausted:
✓ the field is still validating after max retries exhausted (703ms)
msgme/ko/validation/all-are-valid
validates observable arrays
◦ asynchronously if no element is validated async:
✓ asynchronously if no element is validated async
◦ asynchronously if at least one element is validated async:
✓ asynchronously if at least one element is validated async
◦ calls isValid on every element that defines it:
✓ calls isValid on every element that defines it
◦ unwraps observables if they do not define isValid:
✓ unwraps observables if they do not define isValid
◦ does not unwrap observables if that define isValid:
✓ does not unwrap observables if that define isValid
◦ resolves to true if all elements are valid:
✓ resolves to true if all elements are valid
◦ resolves to false if any element is invalid:
✓ resolves to false if any element is invalid
The flowmodule-posttourl viewmodel
validation
◦ url is required:
✓ url is required
◦ url must be a valid URL:
✓ url must be a valid URL
mapping sets the correct defaults
◦ for title:
✓ for title
◦ for url:
✓ for url
The flowmodule-dynamiccontent viewmodel
validation
◦ url is required:
✓ url is required
◦ url must be a valid URL:
✓ url must be a valid URL
mapping sets the correct defaults
◦ for title:
✓ for title
◦ for url:
✓ for url
flowmodule-subscription mapping
sets the correct defaults
◦ title:
✓ title
◦ default opt-in type is single:
✓ default opt-in type is single
◦ default confirm message string:
✓ default confirm message string
◦ default opt-in message string:
✓ default opt-in message string
◦ default subscribed message is empty:
✓ default subscribed message is empty
provides a widgetId subcomputed
◦ for optIn:
✓ for optIn
◦ for confirm:
✓ for confirm
◦ for subscribed:
✓ for subscribed
The coupon viewmodel
mapping
◦ sets correct defaults:
✓ sets correct defaults
◦ provides a delivered computable which is === total - available:
✓ provides a delivered computable which is === total - available
coupons
◦ is a CursorModel:
✓ is a CursorModel
model
◦ is exported:
✓ is exported
collection
◦ is exported:
✓ is exported
validation
name
◦ is required:
✓ is required
◦ is at least 5 characters:
✓ is at least 5 characters
◦ is less than 30 characters:
✓ is less than 30 characters
◦ accepts valid names:
✓ accepts valid names
dateparts
◦ allows the user to set a Date of noon:
GET /dist/font/ProximaNova-Reg-webfont.svg 404 0ms
✓ allows the user to set a Date of noon (55ms)
◦ allows the user to change from 12 PM to 12 AM:
✓ allows the user to change from 12 PM to 12 AM
The pass viewmodel
mapping
sets correct defaults
◦ for system values:
✓ for system values
◦ for the settings pane:
✓ for the settings pane
◦ for the color & images pane:
✓ for the color & images pane
◦ for the front content pane:
✓ for the front content pane
◦ for the back content pane:
✓ for the back content pane
◦ for the locations pane:
✓ for the locations pane
◦ for the distribution pane:
✓ for the distribution pane
provides a lock screen datetime computed
◦ returns passbook.relevantDate.formatted:
✓ returns passbook.relevantDate.formatted (70ms)
◦ sets passbook.relevantDate:
✓ sets passbook.relevantDate
provides an adamId computed
◦ has value "" if passbook.associatedStoreIdentifiers is empty:
✓ has value "" if passbook.associatedStoreIdentifiers is empty
◦ otherwise, joins the elements of passbook.associatedStoreIdentifiers:
✓ otherwise, joins the elements of passbook.associatedStoreIdentifiers
◦ accepts a comma-delimited string of integers and sets passbook.associatedStoreIdentifiers to the equivalent array:
✓ accepts a comma-delimited string of integers and sets passbook.associatedStoreIdentifiers to the equivalent array
◦ ignores values that cannot be parsed as integers:
✓ ignores values that cannot be parsed as integers
provides a dateRestrictionChoice computed
◦ has value "UNRESTRICTED" if dateRestriction is null:
✓ has value "UNRESTRICTED" if dateRestriction is null
◦ has value "RESTRICTED" otherwise:
✓ has value "RESTRICTED" otherwise
◦ sets dateRestriction to null if set to "UNRESTRICTED":
✓ sets dateRestriction to null if set to "UNRESTRICTED"
◦ sets dateRestriction to Date.now() if set to "RESTRICTED":
✓ sets dateRestriction to Date.now() if set to "RESTRICTED"
provides a previewPayload computed
◦ outputs a valid landing page template payload by default:
✓ outputs a valid landing page template payload by default
◦ listens for changes to the model:
✓ listens for changes to the model
provides a limitQuantity computed
◦ returns true when passbook.barcode.messageType is "DYNAMICCODE":
✓ returns true when passbook.barcode.messageType is "DYNAMICCODE"
when passbook.barcode.messageType is "STATIC"
◦ returns true if quantityRestriction is >= 0:
✓ returns true if quantityRestriction is >= 0
◦ returns false if quantityRestriction is -1:
✓ returns false if quantityRestriction is -1
◦ sets quantityRestriction to -1 if set to false:
✓ sets quantityRestriction to -1 if set to false
◦ sets quantityRestriction to 0 if set to true:
✓ sets quantityRestriction to 0 if set to true (108ms)
images.icon
provides a src subcomputed
◦ returns "/api/v1/file/" + images.icon if images.logo is not null:
✓ returns "/api/v1/file/" + images.icon if images.logo is not null
◦ return "" if images.icon is falsy:
✓ return "" if images.icon is falsy
images.logo
provides a src subcomputed
◦ returns "/api/v1/file/" + images.logo if images.logo is not null:
✓ returns "/api/v1/file/" + images.logo if images.logo is not null
◦ return "" if images.logo is falsy:
✓ return "" if images.logo is falsy
images.strip
provides a src subcomputed
◦ returns "/api/v1/file/" + images.strip if images.logo is not null:
✓ returns "/api/v1/file/" + images.strip if images.logo is not null
◦ return "" if images.strip is falsy:
✓ return "" if images.strip is falsy
passbook.barcode.message
provides a statik subcomputed
◦ returns the value of message if messageType is STATIC:
✓ returns the value of message if messageType is STATIC
◦ otherwise it returns null:
✓ otherwise it returns null
◦ sets the value of message if messageType is STATIC:
✓ sets the value of message if messageType is STATIC
◦ otherwise it has no effect:
✓ otherwise it has no effect
provides a dynamic subcomputed
◦ returns the value of message if messageType is DYNAMICCODE:
✓ returns the value of message if messageType is DYNAMICCODE
◦ otherwise it returns null:
✓ otherwise it returns null
◦ sets message if messageType is DYNAMICCODE:
✓ sets message if messageType is DYNAMICCODE
◦ otherwise it has no effect:
✓ otherwise it has no effect
validation
name
◦ is required:
✓ is required
◦ is at least 5 characters:
✓ is at least 5 characters
◦ is less than 30 characters:
✓ is less than 30 characters
◦ accepts valid names:
✓ accepts valid names
organization
◦ is selected:
✓ is selected
icon
◦ is selected:
✓ is selected
logo
◦ is selected:
✓ is selected (135ms)
strip
◦ is selected:
✓ is selected
passbook
type
◦ is selected and is "coupon":
✓ is selected and is "coupon"
description
◦ is required:
✓ is required
◦ is at least 5 characters:
✓ is at least 5 characters
◦ accepts valid descriptions:
✓ accepts valid descriptions
backgroundColor
◦ is selected and is a hex color:
✓ is selected and is a hex color
foregroundColor
◦ is selected and is a hex color:
✓ is selected and is a hex color
labelColor
◦ is selected and is a hex color:
✓ is selected and is a hex color
logoText
◦ is less than 30 characters:
✓ is less than 30 characters
◦ accepts valid texts:
✓ accepts valid texts
passbook.coupon
header fields
◦ is required:
✓ is required
primary fields
◦ is required:
✓ is required
secondary fields
◦ is required:
✓ is required
back fields
◦ is required:
✓ is required
passbook.barcode
message
◦ is required:
✓ is required
altText
◦ valid if altTextType not null:
✓ valid if altTextType not null
altTextType
◦ cant be "DYNAMICCODE" if messageType "DYNAMICCODE":
✓ cant be "DYNAMICCODE" if messageType "DYNAMICCODE"
passbook.locations
latitude
◦ is valid:
✓ is valid
longitude
◦ is valid:
✓ is valid
relevantText
◦ required if latitude or longitude are with values:
✓ required if latitude or longitude are with values
◦ is at least 5 characters:
✓ is at least 5 characters
◦ is less than 50 characters:
✓ is less than 50 characters
◦ is valid:
✓ is valid
distribution
quantityRestriction
◦ is required if limitQuantity is true:
✓ is required if limitQuantity is true
dateRestriction
◦ is required if dateRestrictionChoice is RESTRICTED:
✓ is required if dateRestrictionChoice is RESTRICTED
noPassbook
message
◦ is valid if noPassbook.action is "MESSAGE":
✓ is valid if noPassbook.action is "MESSAGE"
outOfCouponsMessage
◦ is required:
✓ is required (154ms)
◦ is at least 5 characters:
✓ is at least 5 characters
◦ is less than 50 characters:
✓ is less than 50 characters
◦ accepts valid values:
✓ accepts valid values
collection
◦ is available:
✓ is available
message viewmodel
◦ exports model:
✓ exports model
◦ exports collection:
✓ exports collection
◦ collection sets the correct defaults:
✓ collection sets the correct defaults
mapping
◦ sets correct defaults for the message:
✓ sets correct defaults for the message
◦ sets correct defaults for content:
✓ sets correct defaults for content
◦ sets correct defaults for content slices:
✓ sets correct defaults for content slices
targetAudiences computed
◦ is an empty object if no content:
✓ is an empty object if no content
◦ has an array per unique targeted channel:
✓ has an array per unique targeted channel
◦ each array contains unique audiences for the channel:
✓ each array contains unique audiences for the channel
validation
content
slices
◦ slice percentages must be > 0:
✓ slice percentages must be > 0
◦ slice percentages must be <= 100:
✓ slice percentages must be <= 100
◦ multiple slice percentages must sum to 100:
✓ multiple slice percentages must sum to 100 (48ms)
subject
◦ be required only for MMS:
✓ be required only for MMS
◦ maximum length 80 characters:
✓ maximum length 80 characters
mms message
◦ must be present if no files are present:
✓ must be present if no files are present
◦ can be empty if files are present:
✓ can be empty if files are present
sendAt
◦ is valid if it's a date in the future (i.e. after page load):
✓ is valid if it's a date in the future (i.e. after page load)
◦ is invalid if it's a date in the past (i.e. before page load):
✓ is invalid if it's a date in the past (i.e. before page load)
isFuture computed
◦ returns true if date is in the future:
✓ returns true if date is in the future
◦ returns false if date is not in the future:
✓ returns false if date is not in the future
isQuietTime computed
◦ does not throw an error if `sendAt` is null:
✓ does not throw an error if `sendAt` is null
◦ returns true if `sendAt`is between 10pm and 10am:
✓ returns true if `sendAt`is between 10pm and 10am
◦ returns false if `sendAt` is not between 10pm and 10am:
✓ returns false if `sendAt` is not between 10pm and 10am
standalone metadata viewmodel
exports
◦ model:
✓ model
◦ collection:
✓ collection
computed property
◦ overwrite is the inverse of multiValue:
✓ overwrite is the inverse of multiValue
◦ event is a boolean version of eventUrl:
✓ event is a boolean version of eventUrl
type
◦ returns format name, but defaults to Text:
✓ returns format name, but defaults to Text
◦ sets format correctly:
✓ sets format correctly
values
◦ returns value based on validValues:
✓ returns value based on validValues
◦ sets validValues based on its value:
✓ sets validValues based on its value
validValues asString
◦ just acts like toString when getting:
✓ just acts like toString when getting
◦ is the inverse of toString when setting:
✓ is the inverse of toString when setting
validation
name
◦ is required:
✓ is required
◦ is at least 5 characters:
✓ is at least 5 characters
◦ is less than 30 characters:
✓ is less than 30 characters
◦ accepts valid names:
✓ accepts valid names
type
◦ is required:
✓ is required
values
◦ is required:
✓ is required
length
◦ is required if values is "open":
✓ is required if values is "open"
validValues
◦ is required if values is "predefined":
✓ is required if values is "predefined"
eventUrl
◦ is required and is an url if event is true:
✓ is required and is an url if event is true
The flowmodule-basictext viewmodel
mapping sets the correct defaults
◦ for title:
✓ for title
◦ for response:
✓ for response
report viewmodel
defaults
◦ set id:
✓ set id
◦ set account:
✓ set account
◦ set group:
✓ set group
◦ set shortCode:
✓ set shortCode
◦ set name:
✓ set name
◦ set query:
✓ set query
◦ set query type:
✓ set query type
◦ set query summaryType:
✓ set query summaryType
◦ set query mobileFlow:
✓ set query mobileFlow
◦ set query campaign:
✓ set query campaign
◦ set query keyword:
✓ set query keyword
◦ set query contentType:
✓ set query contentType
◦ set query messageType:
✓ set query messageType
◦ set query timeframe:
✓ set query timeframe
◦ set query beginOn:
✓ set query beginOn
◦ set query endOn:
✓ set query endOn
◦ set query lists:
✓ set query lists
timeframe
◦ submits a null value for custom timeframe:
✓ submits a null value for custom timeframe
validation
◦ requires query type:
✓ requires query type
◦ requires summaryType for messageSummary:
✓ requires summaryType for messageSummary
◦ ensures mobileFlow campaign and keyword are mutually exclusive:
✓ ensures mobileFlow campaign and keyword are mutually exclusive
◦ ensures that either timeframe or start and end is set:
✓ ensures that either timeframe or start and end is set (234ms)
◦ ensures start date is after limit:
✓ ensures start date is after limit
◦ ensures end date is within limit:
✓ ensures end date is within limit
flowmodule passbook viewmodel
◦ defines the correct defaults:
✓ defines the correct defaults
◦ validates passbookTemplateId is truthy:
✓ validates passbookTemplateId is truthy
subcomputed
◦ defines responseMessage.widgetId:
✓ defines responseMessage.widgetId
◦ defines outOfCoupons.widgetId:
✓ defines outOfCoupons.widgetId
flowmodule-validation mapping
sets the correct defaults
◦ defaults:
validating rightHand
✓ defaults
◦ local:
validating rightHand
✓ local
provides a computed
◦ sendConsequentResponse:
validating rightHand
✓ sendConsequentResponse
◦ sendAlternativeResponse:
validating rightHand
✓ sendAlternativeResponse
validation
◦ alternativeNextStep:
validating rightHand
✓ alternativeNextStep
◦ alternativeMobileFlow:
validating rightHand
✓ alternativeMobileFlow
◦ consequentNextStep:
validating rightHand
✓ consequentNextStep
◦ consequentMobileFlow:
validating rightHand
✓ consequentMobileFlow
◦ consequentResponse:
validating rightHand
✓ consequentResponse
◦ alternativeResponse:
validating rightHand
✓ alternativeResponse
conditions mapping
◦ defaults:
validating rightHand
✓ defaults
provides a subcomputed
◦ innerOperator selected:
validating rightHand
✓ innerOperator selected
rightHand
◦ hasMetadatumValue hasValue:
validating rightHand
✓ hasMetadatumValue hasValue
◦ hasMetadatumValue doesNotHaveValue:
validating rightHand
✓ hasMetadatumValue doesNotHaveValue
valueType
◦ list:
validating rightHand
✓ list
◦ metadatum:
validating rightHand
✓ metadatum
list
◦ read:
validating rightHand
✓ read
◦ write:
validating rightHand
validating rightHand
✓ write
metadatum
◦ read:
validating rightHand
✓ read
◦ write:
validating rightHand
validating rightHand
✓ write
rightHandValue
fixed
◦ read:
validating rightHand
✓ read
◦ write:
validating rightHand
✓ write
free
◦ read:
validating rightHand
✓ read
◦ write:
validating rightHand
✓ write
validation
◦ operator:
validating rightHand
✓ operator
◦ rightHandValue required for "hasValue" and "doesNotHaveValue" operators:
validating rightHand
✓ rightHandValue required for "hasValue" and "doesNotHaveValue" operators
rightHand
- is required for "on" operators
- required for "hasValue" and "doesNotHaveValue"operators
- required for "has" and "doesNotHave" operators
flowmodule sweeps viewmodel
◦ correctly defines defaults:
✓ correctly defines defaults
◦ correctly defines params subcomputed widgetIds:
✓ correctly defines params subcomputed widgetIds
validation
◦ fails when endDate < startDate:
✓ fails when endDate < startDate
◦ fails when listId is falsy:
✓ fails when listId is falsy
startDateTime date parts
asDate
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
date
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
hour
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
◦ setting 12PM does not increment the day:
✓ setting 12PM does not increment the day
minute
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
period
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
endDateTime date parts
asDate
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
date
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
hour
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
◦ setting 12PM does not increment the day:
✓ setting 12PM does not increment the day
minute
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
period
◦ correctly gets value:
✓ correctly gets value
◦ correctly sets value:
✓ correctly sets value
flowmodule-poll mapping
◦ sets the correct defaults:
✓ sets the correct defaults
provides a computed
◦ widgetId:
✓ widgetId
◦ choiceCount:
✓ choiceCount
◦ choicesList:
✓ choicesList
validation
◦ pollQuestion:
✓ pollQuestion
choices mapping
◦ sets the correct defaults:
✓ sets the correct defaults
provides a computed
◦ widgetId:
✓ widgetId
sendMessage
◦ read:
✓ read
◦ write:
✓ write
validation
◦ nextStep:
✓ nextStep
◦ description:
✓ description
◦ mobileFlow:
✓ mobileFlow
◦ message:
✓ message
flowmodule-agegate mapping
◦ sets the correct defaults:
✓ sets the correct defaults
◦ correctly defines params subcomputed widgetIds:
✓ correctly defines params subcomputed widgetIds
validation
◦ requires that metadataId is truthy:
✓ requires that metadataId is truthy
◦ requires that ageRequestMessage is truthy:
✓ requires that ageRequestMessage is truthy
◦ requires that invalidFormatMessage is truthy:
✓ requires that invalidFormatMessage is truthy
◦ ageThreshold is a number greater than 0:
✓ ageThreshold is a number greater than 0
◦ mobileFlowId required if nextStep is forwardToMobileFlow:
✓ mobileFlowId required if nextStep is forwardToMobileFlow
◦ notOfAgeMessage required if nextStep is terminate:
✓ notOfAgeMessage required if nextStep is terminate
msgme_add_to_list
optIn actions
◦ opt in message is hidden when single opt in is selected:
GET /dist/font/ProximaNova-Sbold-webfont.woff 404 1ms
GET /dist/font/ProximaNova-Sbold-webfont.ttf 404 1ms
✓ opt in message is hidden when single opt in is selected
GET /dist/font/ProximaNova-Sbold-webfont.svg 404 1ms
◦ opt in message is shown when double opt in is selected:
✓ opt in message is shown when double opt in is selected
text in textarea are displayed correctly
◦ opt in message text:
✓ opt in message text
◦ confirm message text:
✓ confirm message text
◦ subscribed message text:
✓ subscribed message text
msgme_send_message
textarea
◦ displays the correct text in the textarea:
✓ displays the correct text in the textarea
ThreeWidget
knockout binding
◦ instantiates a three widget from a string:
✓ instantiates a three widget from a string
◦ ignores descendent bindings:
✓ ignores descendent bindings
◦ only instantiates one widget:
✓ only instantiates one widget
routing
campaigns
◦ works for /campaigns:
✓ works for /campaigns
◦ works for /campaigns/page/2:
✓ works for /campaigns/page/2
◦ works for /campaigns/new:
✓ works for /campaigns/new
◦ works for /campaigns/5181fddb0cf2916da07ff6df:
✓ works for /campaigns/5181fddb0cf2916da07ff6df
◦ works for /campaigns/5181fddb0cf2916da07ff6df/clone:
✓ works for /campaigns/5181fddb0cf2916da07ff6df/clone
lists
◦ works for /lists:
✓ works for /lists
◦ works for /lists/page/2:
✓ works for /lists/page/2
◦ works for /lists/0+astacy+deploy+test+2+deleteme:
✓ works for /lists/0+astacy+deploy+test+2+deleteme
◦ works for /lists/new:
✓ works for /lists/new
msgme_bar_chart
renders bars
◦ one bar per datum:
✓ one bar per datum (304ms)
◦ adjacent, with desired spacing:
✓ adjacent, with desired spacing (312ms)
◦ filling the root element vertically:
✓ filling the root element vertically (304ms)
◦ filling the root element horizontally:
✓ filling the root element horizontally (303ms)
◦ height proportional to datum value:
✓ height proportional to datum value (314ms)
◦ width proportional to data length:
✓ width proportional to data length (308ms)
◦ updates when data changes:
✓ updates when data changes (605ms)
visual test
- instantiates the widget
flowmodule-texttowin mapping
◦ sets the correct defaults:
✓ sets the correct defaults
validation
◦ requires that methodology is truthy:
✓ requires that methodology is truthy
◦ metadataId required if tagMetadata:
✓ metadataId required if tagMetadata
winnerGroups
◦ defaults:
✓ defaults
validation
◦ freeValue required if tagMetadata and no valid values:
✓ freeValue required if tagMetadata and no valid values
◦ fixedValue required if tagMetadata and valid values:
✓ fixedValue required if tagMetadata and valid values
messageLimit
◦ required if winners limited:
✓ required if winners limited
◦ is a number:
✓ is a number
everyNth
◦ required for PATTERN methodology:
✓ required for PATTERN methodology
◦ is a number:
✓ is a number
percentage
◦ required for RANDOM methodology:
✓ required for RANDOM methodology
◦ is a number between 1 and 99:
✓ is a number between 1 and 99 (39ms)
msgme_add_metadata
validValues
◦ fixed value dropdown shown if validValues contains values:
✓ fixed value dropdown shown if validValues contains values
◦ free value input is hidden if validValues contains values:
✓ free value input is hidden if validValues contains values
◦ fixed value dropdown hidden if validValues is empty:
✓ fixed value dropdown hidden if validValues is empty
◦ free value input is shown if validValues is empty:
✓ free value input is shown if validValues is empty
◦ value in fixed value is displayed correctly:
✓ value in fixed value is displayed correctly
◦ value in free value input is displayed correctly:
✓ value in free value input is displayed correctly
datetimepicker
toggling date and time
◦ works twice in a row:
GET /dist/font/fontawesome-webfont.woff?v=3.2.1 404 0ms
GET /dist/font/fontawesome-webfont.ttf?v=3.2.1 404 0ms
✓ works twice in a row (137ms)
GET /dist/font/fontawesome-webfont.svg 404 1ms
calendar button
◦ if date was empty, sets it to the next hour from now, on the hour:
✓ if date was empty, sets it to the next hour from now, on the hour
◦ if date wasn't empty, preserves the old value:
✓ if date wasn't empty, preserves the old value
clear button
◦ clears the input:
✓ clears the input
binding
◦ is set up between the widget and the data:
✓ is set up between the widget and the data
visual test
- instantiates the widget
select2
◦ sets the value on blur:
GET /img/select2/select2.png 200 1ms - 613b
✓ sets the value on blur
value binding
◦ updates the observable:
✓ updates the observable
◦ is updated by the observable:
✓ is updated by the observable
placeholder
◦ is displayed for null value:
✓ is displayed for null value
spinner
◦ displays correctly:
✓ displays correctly
async button
◦ shows the spinner when the pending observable is truthy:
✓ shows the spinner when the pending observable is truthy
◦ disables the button when pending observable is truthy:
✓ disables the button when pending observable is truthy
◦ shows the original content when pending observable is falsy:
✓ shows the original content when pending observable is falsy
with a promise as an observable
◦ shows the spinner when promise is pending:
✓ shows the spinner when promise is pending
◦ hides the spinner the promise resolves:
✓ hides the spinner the promise resolves
◦ hides the spinner the promise rejects:
✓ hides the spinner the promise rejects
line chart
◦ updates the chart with new data:
GET /dist/font/ProximaNova-Light-webfont.woff 404 1ms
GET /dist/font/ProximaNova-Light-webfont.ttf 404 1ms
GET /dist/font/ProximaNova-Light-webfont.svg 404 1ms
✓ updates the chart with new data (614ms)
visual test
- instantiates the widget
feature flags
when whoami fails
◦ should reject the promise:
✓ should reject the promise
when whoami succeeds
◦ should provide access to the flags via promise:
✓ should provide access to the flags via promise
◦ should reject the promise for falsy flags:
✓ should reject the promise for falsy flags
viewmodel
indexable
◦ is not affected by changes to its array:
✓ is not affected by changes to its array
group viewmodel
exports
◦ model:
✓ model
◦ collection:
✓ collection
validation
name
◦ is required:
✓ is required
◦ is at least 3 characters:
✓ is at least 3 characters
◦ is less than 26 characters:
✓ is less than 26 characters
◦ accepts valid names:
✓ accepts valid names
computed value
roles
◦ adds groupName and noOfUsers to group models:
✓ adds groupName and noOfUsers to group models (263ms)
◦ returns an object with the rows set properly:
✓ returns an object with the rows set properly
users
◦ adds groupName and roleName to user models:
✓ adds groupName and roleName to user models
◦ returns an object with the rows set properly:
✓ returns an object with the rows set properly
The queryFilter viewmodel
mapping
◦ sets correct defaults:
✓ sets correct defaults
validation
queryFilterDetails
◦ metadata is required:
✓ metadata is required
◦ operator is required:
✓ operator is required
value
operators allowing one value
◦ fixed values must be in validValues:
✓ fixed values must be in validValues
◦ free values must match format when trimmed:
✓ free values must match format when trimmed
◦ gives a relevant error message when possible:
✓ gives a relevant error message when possible
◦ gives a default error message otherwise:
✓ gives a default error message otherwise
operators allowing multiple values
◦ each fixed value must be in validValues:
✓ each fixed value must be in validValues
◦ each free value must match format when trimmed:
✓ each free value must match format when trimmed (48ms)
◦ gives a relevant error message when possible:
✓ gives a relevant error message when possible
◦ gives a default error message otherwise:
✓ gives a default error message otherwise
"exists" operator
◦ validates only when the value is true or false:
✓ validates only when the value is true or false
◦ does not apply the format regex:
✓ does not apply the format regex
role viewmodel tests
exports
◦ exports model:
✓ exports model
◦ exports collection:
✓ exports collection
defaults
◦ correctly initialize account:
✓ correctly initialize account
◦ correctly initialize group:
✓ correctly initialize group
◦ correctly initialize groupsVisible:
✓ correctly initialize groupsVisible
◦ correctly initialize name:
✓ correctly initialize name
◦ correctly initialize permissions:
✓ correctly initialize permissions
validation
name
◦ is required:
✓ is required
◦ is at least 5 characters:
✓ is at least 5 characters
◦ is less than 30 characters:
✓ is less than 30 characters
◦ accepts valid names:
✓ accepts valid names
groupsVisible
◦ is selected:
✓ is selected
group
◦ is selected:
✓ is selected
computed permissions
◦ are correctly calculated:
✓ are correctly calculated
◦ are correctly updated:
✓ are correctly updated
user viewmodel
exports
◦ model:
✓ model
◦ collection:
✓ collection
default values
◦ correctly initialize group:
✓ correctly initialize group
◦ correctly initialize password:
✓ correctly initialize password
◦ correctly initialize name:
✓ correctly initialize name
◦ correctly initialize role:
✓ correctly initialize role
◦ correctly initialize defaultShortCode:
✓ correctly initialize defaultShortCode
◦ correctly initialize shortCodes:
✓ correctly initialize shortCodes
computed values
◦ rolesByGroup:
✓ rolesByGroup
validation
name
◦ is required:
✓ is required
◦ accepts valid names:
✓ accepts valid names
password
◦ is required:
✓ is required
◦ is at least 5 characters:
✓ is at least 5 characters
◦ is less than 30 characters:
✓ is less than 30 characters
◦ accepts valid values:
✓ accepts valid values
group
◦ is selected:
✓ is selected
role
◦ is selected:
✓ is selected
defaultShortCode
◦ is selected:
✓ is selected
shortCodes
◦ is selected:
✓ is selected
audience filter
add segment button
◦ adds a row:
✓ adds a row (191ms)
◦ preserves values of previous rows:
✓ preserves values of previous rows (224ms)
trash button
◦ removes a row:
✓ removes a row (225ms)
◦ preserves values of rows not removed:
✓ preserves values of rows not removed (256ms)
metadata types
◦ shows radius inputs for geo:
✓ shows radius inputs for geo (188ms)
◦ produces a list of zipcodes for geo:
check 1
check 2
check 3
check 4
check 5
1) produces a list of zipcodes for geo
◦ shows no inputs for exists:
✓ shows no inputs for exists (204ms)
◦ correctly sets the value for exists:
✓ correctly sets the value for exists (209ms)
◦ shows free value input for equal to:
✓ shows free value input for equal to (165ms)
operator
◦ clears the true value when switching from exists:
✓ clears the true value when switching from exists (194ms)
◦ clears the true value when switching from notexists:
✓ clears the true value when switching from notexists
rollback
◦ works for snapshot:
check 1
check 2
check 3
check 4
check 5
check 6
check 7
check 8
✓ works for snapshot (407ms)
validation
◦ ensures correct geoValues:
✓ ensures correct geoValues (234ms)
◦ fails unless geo values validate:
check 1
check 2
check 3
check 5
failed zipcode validation test:
'' is not a function (evaluating 'fn()') message
22 "line"
140067702576896 "sourceId"
http://localhost:8890/scripts/msgme/util/promise.js sourceURL
TypeError: '' is not a function (evaluating 'fn()')
at http://localhost:8890/scripts/msgme/util/promise.js:22
at http://localhost:8890/scripts/waterfall-jquery.js:667 stack
[{"sourceURL":"http://localhost:8890/scripts/msgme/util/promise.js","line":22},{"sourceURL":"http://localhost:8890/scripts/waterfall-jquery.js","line":667}] "stackArray"
2) fails unless geo values validate
Error: expected { message: '\'\' is not a function (evaluating \'fn()\')',
line: 22,
sourceId: 140067702576896,
sourceURL: 'http://localhost:8890/scripts/msgme/util/promise.js',
stack: 'TypeError: \'\' is not a function (evaluating \'fn()\')\n at http://localhost:8890/scripts/msgme/util/promise.js:22\n at http://localhost:8890/scripts/waterfall-jquery.js:667',
stackArray:
[ { sourceURL: 'http://localhost:8890/scripts/msgme/util/promise.js',
line: 22 },
{ sourceURL: 'http://localhost:8890/scripts/waterfall-jquery.js',
line: 667 } ] } to be falsy
http://localhost:8890/node_modules/expect.js/expect.js:99
http://localhost:8890/node_modules/expect.js/expect.js:115
http://localhost:8890/node_modules/expect.js/expect.js:480
http://localhost:8890/widgets/audience-filter/spec.js:513
http://localhost:8890/scripts/require-jquery.js:2993
http://localhost:8890/scripts/require-jquery.js:3103
http://localhost:8890/scripts/require-jquery.js:3110
http://localhost:8890/scripts/require-jquery.js:2993
http://localhost:8890/scripts/require-jquery.js:3103
http://localhost:8890/scripts/require-jquery.js:3110
http://localhost:8890/scripts/require-jquery.js:2993
http://localhost:8890/scripts/require-jquery.js:3103
http://localhost:8890/scripts/require-jquery.js:3110
http://localhost:8890/scripts/require-jquery.js:2993
http://localhost:8890/scripts/require-jquery.js:3103
http://localhost:8890/scripts/require-jquery.js:3110
http://localhost:8890/scripts/require-jquery.js:2993
http://localhost:8890/scripts/require-jquery.js:3103
http://localhost:8890/scripts/require-jquery.js:3110
http://localhost:8890/scripts/msgme/util/promise.js:24
http://localhost:8890/scripts/waterfall-jquery.js:667
Warning: 1 tests failed Use --force to continue.
Aborted due to warnings.
npm ERR! weird error 6
npm ERR! not ok code 0
The command "npm test" exited with 1.
Done. Your build exited with 1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment