hippo-fw 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/client/hippo/components/asset.jsx +22 -2
  3. data/client/hippo/components/asset.scss +1 -1
  4. data/client/hippo/components/data-list.jsx +38 -27
  5. data/client/hippo/components/data-list/data-list.scss +2 -0
  6. data/client/hippo/components/data-table.jsx +4 -2
  7. data/client/hippo/components/data-table/formatters.js +7 -0
  8. data/client/hippo/components/data-table/table-styles.scss +10 -0
  9. data/client/hippo/components/date-time.jsx +93 -133
  10. data/client/hippo/components/date-time.scss +1 -36
  11. data/client/hippo/components/form/api.js +4 -3
  12. data/client/hippo/components/form/fields.jsx +7 -1
  13. data/client/hippo/components/form/fields/date-wrapper.jsx +4 -4
  14. data/client/hippo/components/icon.jsx +10 -1
  15. data/client/hippo/components/query-builder.jsx +6 -1
  16. data/client/hippo/components/record-finder/query-layer.jsx +1 -1
  17. data/client/hippo/components/save-button.jsx +55 -0
  18. data/client/hippo/components/text-editor.jsx +10 -9
  19. data/client/hippo/components/text-editor/text-editor.scss +0 -1
  20. data/client/hippo/components/time-zone-select.jsx +60 -0
  21. data/client/hippo/models/asset.js +10 -5
  22. data/client/hippo/models/base.js +1 -1
  23. data/client/hippo/models/pub_sub.js +22 -67
  24. data/client/hippo/models/pub_sub/channel.js +28 -8
  25. data/client/hippo/models/pub_sub/map.js +57 -0
  26. data/client/hippo/models/query/array-result.js +5 -4
  27. data/client/hippo/models/query/field.js +19 -3
  28. data/client/hippo/models/system-setting.js +16 -1
  29. data/client/hippo/models/tenant.js +8 -7
  30. data/client/hippo/screens/system-settings.jsx +10 -12
  31. data/client/hippo/screens/user-management/edit-form.jsx +10 -11
  32. data/client/hippo/workspace/index.jsx +6 -3
  33. data/client/hippo/workspace/menu-option.jsx +2 -5
  34. data/client/hippo/workspace/menu.jsx +13 -1
  35. data/client/hippo/workspace/styles.scss +11 -26
  36. data/command-reference-files/initial/Gemfile +1 -1
  37. data/command-reference-files/model/client/appy-app/models/test_test.js +1 -1
  38. data/command-reference-files/model/spec/server/models/test_test_spec.rb +10 -0
  39. data/lib/hippo/api/cable.rb +0 -2
  40. data/lib/hippo/command/generate_model.rb +2 -3
  41. data/lib/hippo/spec_helper.rb +4 -2
  42. data/lib/hippo/tenant.rb +7 -1
  43. data/lib/hippo/version.rb +1 -1
  44. data/package-lock.json +60 -46
  45. data/package.json +5 -2
  46. data/spec/client/components/__snapshots__/record-finder.spec.jsx.snap +1 -0
  47. data/spec/client/components/__snapshots__/time-zone-select.spec.jsx.snap +48 -0
  48. data/spec/client/components/form.spec.jsx +7 -0
  49. data/spec/client/components/time-zone-select.spec.jsx +11 -0
  50. data/spec/client/models/pub_sub.spec.js +1 -3
  51. data/spec/client/models/pub_sub/channel.spec.js +45 -0
  52. data/spec/client/models/system-setting.spec.js +14 -0
  53. data/spec/client/workspace/__snapshots__/menu.spec.jsx.snap +9 -9
  54. data/spec/server/api/tenant_change_spec.rb +1 -1
  55. data/templates/client/models/model.js +1 -1
  56. data/templates/spec/factories/model.rb +6 -0
  57. data/templates/spec/server/model_spec.rb +4 -4
  58. data/views/hippo_root_view.erb +4 -0
  59. metadata +11 -10
  60. data/client/hippo/components/date-time/calendar.jsx +0 -113
  61. data/client/hippo/components/date-time/date-time-drop.jsx +0 -75
  62. data/client/hippo/components/date-time/date-time.scss +0 -157
  63. data/client/hippo/components/date-time/time.jsx +0 -119
  64. data/client/hippo/workspace/foo.js +0 -0
  65. data/command-reference-files/model/spec/fixtures/appy-app/test_test.yml +0 -11
  66. data/command-reference-files/model/spec/server/test_test_spec.rb +0 -10
  67. data/spec/client/components/date-time.spec.jsx +0 -20
@@ -1,37 +1,12 @@
1
1
  @import '../styles/global';
2
2
  @import '~grommet/scss/aruba/index';
3
3
 
4
- html {
5
- font-family: $brand-font-family;
6
- }
7
-
8
- a.anchor {
9
- display: block;
10
- }
11
-
12
- .request-access fieldset:first-of-type {
13
- padding-top: 0;
14
- }
15
-
16
- pre {
17
- width: 100%;
18
- max-width: 100%;
19
- }
20
-
21
- .generic-branding {
22
- display: none;
23
- }
24
-
25
- .content-pane .grommetux-tabs {
26
- padding-left: 20px;
27
- padding-right: 20px;
28
- }
29
-
30
4
  .screen {
31
5
  flex: 1;
32
6
  flex-direction: column;
33
7
  padding: 0.5rem;
34
8
  display: none;
9
+ min-height: min-content; min-height: -moz-min-content; min-height: -webkit-min-content;
35
10
  &.is-active {
36
11
  display: flex;
37
12
  }
@@ -53,3 +28,13 @@ pre {
53
28
  display:none;
54
29
  }
55
30
  }
31
+
32
+ .screen-selection-menu {
33
+ .grommetux-anchor > .icon {
34
+ margin-right: 0.5rem;
35
+ }
36
+ }
37
+
38
+ .screens-wrapper {
39
+ overflow: hidden;
40
+ }
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  # For development while Hippo is evolving track master branch
4
4
  gem "hippo-fw", git: "https://github.com/argosity/hippo", branch: 'master'
5
5
 
6
- # gem "hippo", '0.9.5'
6
+ # gem "hippo", '0.9.6'
7
7
 
8
8
  gem "rake"
9
9
  gem 'puma'
@@ -1,5 +1,5 @@
1
1
  import {
2
- BaseModel, identifiedBy, identifier, belongsTo, hasMany, field, computed
2
+ BaseModel, identifiedBy, identifier, field, session, belongsTo, hasMany,
3
3
  } from './base';
4
4
 
5
5
  @identifiedBy('appy-app/test_test')
@@ -0,0 +1,10 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe AppyApp::TestTest do
4
+
5
+ it "can be instantiated" do
6
+ model = AppyApp::TestTest.new
7
+ expect(model).to be_an(AppyApp::TestTest)
8
+ end
9
+
10
+ end
@@ -15,8 +15,6 @@ module Hippo
15
15
 
16
16
  def connect
17
17
  token = request.params['token']
18
- Hippo.logger_debug("NEW WS CONN: #{token}")
19
-
20
18
  begin
21
19
  self.current_user = User.for_jwt_token(token) if token
22
20
  rescue JWT::DecodeError
@@ -31,9 +31,8 @@ module Hippo
31
31
 
32
32
  def create_model
33
33
  template "lib/namespace/model.rb", "lib/#{identifier}/models/#{file_name}.rb"
34
- template "spec/server/model_spec.rb", "spec/server/#{file_name}_spec.rb"
35
- template "spec/fixtures/namespace/model.yml",
36
- "spec/fixtures/#{identifier}/#{file_name}.yml"
34
+ template "spec/server/model_spec.rb", "spec/server/models/#{file_name}_spec.rb"
35
+ template "spec/factories/model.rb", "spec/factories/#{file_name}.rb"
37
36
  end
38
37
 
39
38
  def create_client
@@ -87,8 +87,10 @@ RSpec.configure do |config|
87
87
  config.around(:each) do |example|
88
88
  Hippo.logger.level = ::Logger::WARN
89
89
  TEST_TENANT.perform do
90
- DatabaseCleaner.cleaning do
91
- example.run
90
+ Hippo::User.scoped_to(TEST_TENANT.users.first) do
91
+ DatabaseCleaner.cleaning do
92
+ example.run
93
+ end
92
94
  end
93
95
  end
94
96
  end
@@ -3,7 +3,7 @@ require 'activerecord-multi-tenant'
3
3
  module Hippo
4
4
  # Tenant
5
5
  class Tenant < Hippo::Model
6
- validates :slug, uniqueness: { case_sensitive: false }
6
+ validates :slug, uniqueness: true
7
7
  validates :name, :presence => { message: 'for company' }
8
8
  validates :email, :presence => true
9
9
 
@@ -12,6 +12,8 @@ module Hippo
12
12
 
13
13
  before_validation :auto_assign_slug, on: :create
14
14
 
15
+ before_save :downcase_slug
16
+
15
17
  def domain
16
18
  self.slug + '.' + Hippo.config.website_domain
17
19
  end
@@ -49,5 +51,9 @@ module Hippo
49
51
  end
50
52
  end
51
53
 
54
+ def downcase_slug
55
+ self.slug = self.slug.downcase.gsub(/\W/, '')
56
+ end
57
+
52
58
  end
53
59
  end
@@ -1,5 +1,5 @@
1
1
  module Hippo
2
2
 
3
- VERSION = "0.9.6"
3
+ VERSION = "0.9.7"
4
4
 
5
5
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hippo-fw",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "lockfileVersion": 1,
5
5
  "dependencies": {
6
6
  "@braintree/browser-detection": {
@@ -2304,6 +2304,11 @@
2304
2304
  "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz",
2305
2305
  "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y="
2306
2306
  },
2307
+ "flatpickr": {
2308
+ "version": "3.0.7",
2309
+ "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-3.0.7.tgz",
2310
+ "integrity": "sha512-wcs8au1XU5Sqm3KQLY7SN7W3DDzrUv9Lp364rZyZpXkqMYpE4XezKKMEhwjMUotEMNdfj4/pd2573FLyFZrIjQ=="
2311
+ },
2307
2312
  "flatten": {
2308
2313
  "version": "1.0.2",
2309
2314
  "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
@@ -4729,51 +4734,9 @@
4729
4734
  "integrity": "sha1-aureASDMP3i6pXGVAxYwoK6PE88="
4730
4735
  },
4731
4736
  "mobx-decorated-models": {
4732
- "version": "0.6.3",
4733
- "resolved": "https://registry.npmjs.org/mobx-decorated-models/-/mobx-decorated-models-0.6.3.tgz",
4734
- "integrity": "sha512-8tAjfbV/Qqyt/7RanGdTQjIOJj5d5ZLsC8hS6eTKK4xGf4unudT2E0nCocbl09VBT79e9HzwgwI1s9iKlRNyRg==",
4735
- "dependencies": {
4736
- "acorn": {
4737
- "version": "5.1.1",
4738
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz",
4739
- "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw=="
4740
- },
4741
- "ajv": {
4742
- "version": "5.2.2",
4743
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.2.tgz",
4744
- "integrity": "sha1-R8aNaehvXZUxA7AHSpQw3GPaXjk="
4745
- },
4746
- "cross-spawn": {
4747
- "version": "5.1.0",
4748
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
4749
- "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk="
4750
- },
4751
- "eslint": {
4752
- "version": "4.4.0",
4753
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.4.0.tgz",
4754
- "integrity": "sha1-o+FT5wS2T3gpDvA1kklOq6Io07w="
4755
- },
4756
- "espree": {
4757
- "version": "3.5.0",
4758
- "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz",
4759
- "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0="
4760
- },
4761
- "esprima": {
4762
- "version": "4.0.0",
4763
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
4764
- "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
4765
- },
4766
- "js-yaml": {
4767
- "version": "3.9.1",
4768
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz",
4769
- "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww=="
4770
- },
4771
- "pluralize": {
4772
- "version": "4.0.0",
4773
- "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz",
4774
- "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I="
4775
- }
4776
- }
4737
+ "version": "0.6.5",
4738
+ "resolved": "https://registry.npmjs.org/mobx-decorated-models/-/mobx-decorated-models-0.6.5.tgz",
4739
+ "integrity": "sha512-Vx7QfGYP0uBlkT0Rqn3SewzR/pIZmVrLk9lOO/qwyT5kc4dHrdn+z/F4+CxHxVxYSLQsxOKwFOizKWDZYnUcTQ=="
4777
4740
  },
4778
4741
  "mobx-persist": {
4779
4742
  "version": "0.3.3",
@@ -4795,6 +4758,11 @@
4795
4758
  "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
4796
4759
  "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8="
4797
4760
  },
4761
+ "moment-timezone": {
4762
+ "version": "0.5.13",
4763
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.13.tgz",
4764
+ "integrity": "sha1-mc5cfYJyYusPH3AgRBd/YHRde5A="
4765
+ },
4798
4766
  "mousetrap": {
4799
4767
  "version": "1.6.1",
4800
4768
  "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.1.tgz",
@@ -5837,6 +5805,52 @@
5837
5805
  "resolved": "https://registry.npmjs.org/react-sidebar/-/react-sidebar-2.3.2.tgz",
5838
5806
  "integrity": "sha1-7BQL6opvX6PY6npWR5ZltEz0+c8="
5839
5807
  },
5808
+ "react-swipeable-views": {
5809
+ "version": "0.12.8",
5810
+ "resolved": "https://registry.npmjs.org/react-swipeable-views/-/react-swipeable-views-0.12.8.tgz",
5811
+ "integrity": "sha512-VCPjjP9WTQejM6Yy46mzzHu9H6p5g/IuQMm6TUOEjj8d82a9ii+YAgWOR2KCR5ew/4lqD4WKX2hD6Ix+Lq80Eg=="
5812
+ },
5813
+ "react-swipeable-views-core": {
5814
+ "version": "0.12.8",
5815
+ "resolved": "https://registry.npmjs.org/react-swipeable-views-core/-/react-swipeable-views-core-0.12.8.tgz",
5816
+ "integrity": "sha512-VudJhi43DwgLFh25aeNPxSwONzyErPFRg13Hm3YcSwSjwhkvNf3oficuPT7/Kd6qxorDj046D8Nkunl/DG5srA=="
5817
+ },
5818
+ "react-swipeable-views-utils": {
5819
+ "version": "0.12.8",
5820
+ "resolved": "https://registry.npmjs.org/react-swipeable-views-utils/-/react-swipeable-views-utils-0.12.8.tgz",
5821
+ "integrity": "sha512-NHXFbB8Bq1RnuBn5IyZoSTofDHuwXbwbkdFIeTFCozeHvLeIHm6A2rRKy2CTYZggNRUukgHZrsGqRU+H1M2iSQ==",
5822
+ "dependencies": {
5823
+ "react-event-listener": {
5824
+ "version": "0.5.0",
5825
+ "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.5.0.tgz",
5826
+ "integrity": "sha1-2CEFE1Vz4Yfj2QDRgVCliCMEuNE=",
5827
+ "dependencies": {
5828
+ "babel-runtime": {
5829
+ "version": "6.26.0",
5830
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
5831
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4="
5832
+ },
5833
+ "fbjs": {
5834
+ "version": "0.8.14",
5835
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.14.tgz",
5836
+ "integrity": "sha1-0dviviVMNakeCfMfnNUKQLKg7Rw=",
5837
+ "dependencies": {
5838
+ "core-js": {
5839
+ "version": "1.2.7",
5840
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
5841
+ "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
5842
+ }
5843
+ }
5844
+ }
5845
+ }
5846
+ },
5847
+ "regenerator-runtime": {
5848
+ "version": "0.11.0",
5849
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
5850
+ "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A=="
5851
+ }
5852
+ }
5853
+ },
5840
5854
  "react-tap-event-plugin": {
5841
5855
  "version": "2.0.1",
5842
5856
  "resolved": "https://registry.npmjs.org/react-tap-event-plugin/-/react-tap-event-plugin-2.0.1.tgz",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hippo-fw",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Hippo is a framework for easily writing single page web applications",
5
5
  "main": "client/hippo/index.js",
6
6
  "repository": "https://github.com/argosity/hippo",
@@ -39,6 +39,7 @@
39
39
  "eslint": "^4.2.0",
40
40
  "eslint-config-argosity": "^1.1.5",
41
41
  "file-loader": "^0.11.2",
42
+ "flatpickr": "^3.0.7",
42
43
  "flexboxgrid": "^6.3.1",
43
44
  "grommet": "^1.5.0",
44
45
  "history": "^4.6.3",
@@ -53,9 +54,10 @@
53
54
  "lodash": "^4.17.4",
54
55
  "loglevel": "^1.4.1",
55
56
  "mobx": "^3.2.1",
56
- "mobx-decorated-models": "^0.6.3",
57
+ "mobx-decorated-models": "^0.6.5",
57
58
  "mobx-persist": "^0.3.3",
58
59
  "mobx-react": "^4.2.2",
60
+ "moment-timezone": "^0.5.13",
59
61
  "node-sass": "^4.5.0",
60
62
  "ory-editor": "^0.2.12",
61
63
  "pluralize": "^6.0.0",
@@ -77,6 +79,7 @@
77
79
  "react-router": "^4.1.2",
78
80
  "react-router-dom": "^4.1.2",
79
81
  "react-sidebar": "^2.3.0",
82
+ "react-swipeable-views": "^0.12.8",
80
83
  "react-tap-event-plugin": "^2.0.1",
81
84
  "react-test-renderer": "^15.6.1",
82
85
  "react-tippy": "^1.0.2",
@@ -30,6 +30,7 @@ exports[`RecordFinder Component renders 1`] = `
30
30
  onKeyDown={[Function]}
31
31
  onKeyPress={[Function]}
32
32
  placeholder={undefined}
33
+ tabIndex={0}
33
34
  type="text"
34
35
  value=""
35
36
  />
@@ -0,0 +1,48 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TimeZone Component matches snapshot 1`] = `
4
+ <div
5
+ className="grommetux-select"
6
+ onClick={[Function]}
7
+ >
8
+ <input
9
+ className="grommetux-input grommetux-select__input"
10
+ placeholder="None"
11
+ readOnly={true}
12
+ value="America/Chicago"
13
+ />
14
+ <button
15
+ aria-label="Select Icon"
16
+ className="grommetux-button grommetux-button--plain grommetux-select__control"
17
+ disabled={false}
18
+ href={undefined}
19
+ onBlur={[Function]}
20
+ onClick={[Function]}
21
+ onFocus={[Function]}
22
+ onMouseDown={[Function]}
23
+ onMouseUp={[Function]}
24
+ type="button"
25
+ >
26
+ <span
27
+ className="grommetux-button__icon"
28
+ >
29
+ <svg
30
+ aria-label="caret-down"
31
+ className="grommetux-control-icon grommetux-control-icon-caret-down grommetux-control-icon--responsive"
32
+ height="24px"
33
+ role="img"
34
+ version="1.1"
35
+ viewBox="0 0 24 24"
36
+ width="24px"
37
+ >
38
+ <polygon
39
+ fill="none"
40
+ points="22 8 12 20 2 8"
41
+ stroke="#000"
42
+ strokeWidth="2"
43
+ />
44
+ </svg>
45
+ </span>
46
+ </button>
47
+ </div>
48
+ `;
@@ -28,6 +28,13 @@ describe('Form Validation functions', () => {
28
28
  expect(form.isValid).toBe(true);
29
29
  });
30
30
 
31
+ it('sets field values when they check in', () => {
32
+ const form = new FormState();
33
+ form.set({ foo: 'bar' });
34
+ form.setField('foo', { label: 'Foo' });
35
+ expect(form.fields.get('foo').value).toEqual('bar');
36
+ });
37
+
31
38
  it('builds tests using blank', () => {
32
39
  const test = nonBlank();
33
40
  expect(test.message).toEqual('is required');
@@ -0,0 +1,11 @@
1
+ import React from 'react'; // eslint-disable-line no-unused-vars
2
+ import TZ from 'hippo/components/time-zone-select';
3
+ import { Snapshot } from 'hippo/testing/screens';
4
+
5
+
6
+ describe('TimeZone Component', () => {
7
+ it('matches snapshot', () => {
8
+ const oc = jest.fn();
9
+ expect(Snapshot(<TZ onChange={oc} value="America/Chicago" />)).toMatchSnapshot();
10
+ });
11
+ });
@@ -3,10 +3,10 @@ import PubSubChannel from 'hippo/models/pub_sub/channel';
3
3
  import Config from 'hippo/config';
4
4
  import { Ship, Container } from '../test-models';
5
5
 
6
+ jest.mock('hippo/models/pub_sub/channel');
6
7
  jest.mock('hippo/user', () => ({
7
8
  isLoggedIn: true,
8
9
  }));
9
- jest.mock('hippo/models/pub_sub/channel');
10
10
  jest.mock('hippo/config');
11
11
 
12
12
  describe('PubSub', () => {
@@ -15,8 +15,6 @@ describe('PubSub', () => {
15
15
  const ship = new Ship();
16
16
  const container = new Container({ id: '2' });
17
17
  onBoot();
18
- expect(PubSubChannel.prototype.subscribe)
19
- .not.toHaveBeenCalledWith('test/boat/test');
20
18
  expect(PubSubChannel.prototype.subscribe)
21
19
  .not.toHaveBeenCalledWith('test/container/2');
22
20
  observePubSub(ship, container);
@@ -0,0 +1,45 @@
1
+ import PubSubChannel from 'hippo/models/pub_sub/channel';
2
+
3
+ describe('PubSub Channel', () => {
4
+ it('subscribes/unsubscribes', () => {
5
+ const onModelChange = jest.fn();
6
+ const perform = jest.fn();
7
+ const received = jest.fn();
8
+ const chan = new PubSubChannel({
9
+ onModelChange,
10
+ cable: {
11
+ subscriptions: {
12
+ create: jest.fn(() => ({
13
+ received,
14
+ perform,
15
+ })),
16
+ },
17
+ },
18
+ });
19
+ const spy1 = jest.fn();
20
+ const channel = 'foo/bar/1';
21
+ chan.subscribe(channel, spy1);
22
+ expect(chan.callbacks.get(channel)).toHaveLength(1);
23
+ const msg = { channel: `ps:${channel}` };
24
+
25
+ const spy2 = jest.fn();
26
+ chan.subscribe(channel, spy2);
27
+
28
+ chan.received(msg);
29
+ expect(spy1).toHaveBeenCalledWith(msg);
30
+ expect(spy2).toHaveBeenCalledWith(msg);
31
+
32
+ chan.unsubscribe(channel, spy1);
33
+ chan.received(msg);
34
+ expect(spy1).toHaveBeenCalledTimes(1);
35
+ expect(spy2).toHaveBeenCalledTimes(2);
36
+
37
+ expect(onModelChange).not.toHaveBeenCalled();
38
+ chan.unsubscribe(channel, spy2);
39
+
40
+ chan.received(msg);
41
+ expect(onModelChange).toHaveBeenCalledWith('foo/bar', '1', {});
42
+ expect(spy1).toHaveBeenCalledTimes(1);
43
+ expect(spy2).toHaveBeenCalledTimes(2);
44
+ });
45
+ });