pageflow-react 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.jshintrc +15 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +40 -0
- data/Rakefile +4 -0
- data/app/assets/javascripts/pageflow/react.js +8975 -0
- data/app/assets/javascripts/pageflow/react/components.js +4 -0
- data/app/views/pageflow/react/_widget.html.erb +1 -0
- data/app/views/pageflow/react/page.html.erb +7 -0
- data/js/.eslintrc +33 -0
- data/js/.gitignore +1 -0
- data/js/karma.conf.js +61 -0
- data/js/package.json +43 -0
- data/js/spec/.eslintrc +8 -0
- data/js/spec/components/background_image_spec.js +47 -0
- data/js/spec/components/page_thumbnail_spec.js +213 -0
- data/js/spec/create_container_spec.js +82 -0
- data/js/spec/resolve_spec.js +3 -0
- data/js/spec/resolvers/backbone_model_resolver_spec.js +256 -0
- data/js/spec/resolvers/create_recursive_resolver_spec.js +120 -0
- data/js/spec/resolvers/editor_file_ids_resolver_spec.js +49 -0
- data/js/spec/resolvers/i18n_resolver_spec.js +20 -0
- data/js/spec/resolvers/object_resolver_spec.js +165 -0
- data/js/spec/resolvers/page_type_resolver_spec.js +23 -0
- data/js/spec/resolvers/seed_resolver_spec.js +128 -0
- data/js/spec/stub_spec.js +16 -0
- data/js/spec/support/render_component.js +7 -0
- data/js/src/components/background_image.jsx +60 -0
- data/js/src/components/lazy_background_image.jsx +23 -0
- data/js/src/components/lazy_loaded_page_thumbnail.jsx +19 -0
- data/js/src/components/page_background.jsx +11 -0
- data/js/src/components/page_background_image.jsx +13 -0
- data/js/src/components/page_content.jsx +51 -0
- data/js/src/components/page_header.jsx +15 -0
- data/js/src/components/page_link.jsx +35 -0
- data/js/src/components/page_shadow.jsx +19 -0
- data/js/src/components/page_text.jsx +17 -0
- data/js/src/components/page_thumbnail.jsx +86 -0
- data/js/src/components/page_wrapper.jsx +11 -0
- data/js/src/components/scroller.js +43 -0
- data/js/src/create_container.jsx +53 -0
- data/js/src/create_page.jsx +38 -0
- data/js/src/create_page_component.jsx +45 -0
- data/js/src/create_page_type.js +57 -0
- data/js/src/create_resolver_root.jsx +21 -0
- data/js/src/create_widget.jsx +3 -0
- data/js/src/create_widget_type.js +12 -0
- data/js/src/index.js +69 -0
- data/js/src/mutate.js +17 -0
- data/js/src/mutations/mutation.js +5 -0
- data/js/src/mutations/update_page_link_mutation.js +30 -0
- data/js/src/mutations/update_page_mutation.js +19 -0
- data/js/src/resolve.js +45 -0
- data/js/src/resolvers/backbone_model_resolver.js +118 -0
- data/js/src/resolvers/create_recursive_resolver.js +20 -0
- data/js/src/resolvers/current_parent_page_resolver.js +38 -0
- data/js/src/resolvers/editor_chapter_resolver.js +10 -0
- data/js/src/resolvers/editor_file_ids_resolver.js +30 -0
- data/js/src/resolvers/editor_page_resolver.js +11 -0
- data/js/src/resolvers/i18n_resolver.js +11 -0
- data/js/src/resolvers/object_resolver.js +58 -0
- data/js/src/resolvers/page_type_resolver.js +12 -0
- data/js/src/resolvers/resolver.js +16 -0
- data/js/src/resolvers/seed_chapter_resolver.js +10 -0
- data/js/src/resolvers/seed_file_ids_resolver.js +11 -0
- data/js/src/resolvers/seed_page_resolver.js +11 -0
- data/js/src/resolvers/seed_resolver.js +75 -0
- data/js/src/utils/camelize.js +29 -0
- data/js/webpack.config.js +31 -0
- data/lib/pageflow-react.rb +13 -0
- data/lib/pageflow/react/engine.rb +15 -0
- data/lib/pageflow/react/page_type.rb +16 -0
- data/lib/pageflow/react/version.rb +5 -0
- data/lib/pageflow/react/widget_type.rb +21 -0
- data/pageflow-react.gemspec +29 -0
- metadata +205 -0
@@ -0,0 +1 @@
|
|
1
|
+
<%= content_tag(:div, '', data: {widget: name}) %>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<% if page.template.present? %>
|
2
|
+
<% concat React::ServerRendering.render(
|
3
|
+
Pageflow.config.page_types.find_by_name!(page.template).component_name, MultiJson.dump(
|
4
|
+
resolverSeed: @_pageflow_react_entry_seed ||= entry_seed(@entry),
|
5
|
+
pageId: page.perma_id
|
6
|
+
), true) %>
|
7
|
+
<% end %>
|
data/js/.eslintrc
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
{
|
2
|
+
"parser": "babel-eslint",
|
3
|
+
"plugins": ["react"],
|
4
|
+
"env": {
|
5
|
+
"browser": true,
|
6
|
+
"es6": true,
|
7
|
+
"node": true
|
8
|
+
},
|
9
|
+
"ecmaFeatures": {
|
10
|
+
"arrowFunctions": true,
|
11
|
+
"blockBindings": true,
|
12
|
+
"classes": true,
|
13
|
+
"defaultParams": true,
|
14
|
+
"destructuring": true,
|
15
|
+
"forOf": true,
|
16
|
+
"generators": true,
|
17
|
+
"modules": true,
|
18
|
+
"spread": true,
|
19
|
+
"templateStrings": true,
|
20
|
+
"jsx": true
|
21
|
+
},
|
22
|
+
"rules": {
|
23
|
+
"no-undef": [2],
|
24
|
+
"consistent-return": [0],
|
25
|
+
"key-spacing": [0],
|
26
|
+
"quotes": [0],
|
27
|
+
"new-cap": [0],
|
28
|
+
"no-multi-spaces": [0],
|
29
|
+
"no-shadow": [0],
|
30
|
+
"no-unused-vars": [1],
|
31
|
+
"no-use-before-define": [2, "nofunc"]
|
32
|
+
}
|
33
|
+
}
|
data/js/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/node_modules
|
data/js/karma.conf.js
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
var webpack = require('webpack');
|
2
|
+
var path = require('path');
|
3
|
+
|
4
|
+
module.exports = function (config) {
|
5
|
+
config.set({
|
6
|
+
browsers: ['PhantomJS'],
|
7
|
+
singleRun: false,
|
8
|
+
frameworks: ['mocha', 'chai', 'chai-sinon', 'phantomjs-shim'],
|
9
|
+
files: [
|
10
|
+
'node_modules/babel-polyfill/dist/polyfill.js',
|
11
|
+
'spec/*spec.js',
|
12
|
+
'spec/**/*spec.js'
|
13
|
+
],
|
14
|
+
exclude: [
|
15
|
+
'flycheck_*.js',
|
16
|
+
'**/flycheck_*.js',
|
17
|
+
'*/**/flycheck_*.js',
|
18
|
+
],
|
19
|
+
preprocessors: {
|
20
|
+
'spec/*spec.js': ['webpack', 'sourcemap'],
|
21
|
+
'spec/**/*spec.js': ['webpack', 'sourcemap']
|
22
|
+
},
|
23
|
+
reporters: ['dots'],
|
24
|
+
plugins: [
|
25
|
+
'karma-webpack',
|
26
|
+
'karma-sourcemap-loader',
|
27
|
+
'karma-mocha',
|
28
|
+
'karma-chai',
|
29
|
+
'karma-chai-sinon',
|
30
|
+
require('karma-phantomjs-shim'),
|
31
|
+
'karma-phantomjs-launcher'
|
32
|
+
],
|
33
|
+
webpack: {
|
34
|
+
devtool: 'inline-source-map',
|
35
|
+
plugins: [
|
36
|
+
new webpack.DefinePlugin({
|
37
|
+
PAGEFLOW_EDITOR: false
|
38
|
+
})
|
39
|
+
],
|
40
|
+
module: {
|
41
|
+
loaders: [
|
42
|
+
{
|
43
|
+
test: /\.jsx?$/,
|
44
|
+
exclude: /node_modules/,
|
45
|
+
loader: 'babel-loader?stage=0&optional[]=runtime'
|
46
|
+
},
|
47
|
+
{
|
48
|
+
test: require.resolve('react'),
|
49
|
+
loader: 'expose?React'
|
50
|
+
}
|
51
|
+
]
|
52
|
+
},
|
53
|
+
resolve: {
|
54
|
+
root: path.resolve('./src')
|
55
|
+
}
|
56
|
+
},
|
57
|
+
webpackServer: {
|
58
|
+
noInfo: true
|
59
|
+
}
|
60
|
+
});
|
61
|
+
};
|
data/js/package.json
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
{
|
2
|
+
"name": "pageflow-react",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "TODO: Write a gem description",
|
5
|
+
"main": "src/index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"author": "",
|
10
|
+
"license": "ISC",
|
11
|
+
"devDependencies": {
|
12
|
+
"babel-core": "^5.8.22",
|
13
|
+
"babel-loader": "^5.3.2",
|
14
|
+
"backbone": "^1.2.2",
|
15
|
+
"chai": "^3.2.0",
|
16
|
+
"expose-loader": "^0.7.1",
|
17
|
+
"imports-loader": "^0.6.4",
|
18
|
+
"karma": "^0.13.9",
|
19
|
+
"karma-chai": "^0.1.0",
|
20
|
+
"karma-chai-sinon": "^0.1.5",
|
21
|
+
"karma-es5-shim": "0.0.4",
|
22
|
+
"karma-mocha": "^0.2.0",
|
23
|
+
"karma-phantomjs-launcher": "^0.2.1",
|
24
|
+
"karma-phantomjs-shim": "^1.0.0",
|
25
|
+
"karma-sourcemap-loader": "^0.3.5",
|
26
|
+
"karma-webpack": "^1.7.0",
|
27
|
+
"mocha": "^2.2.5",
|
28
|
+
"phantomjs": "^1.9.18",
|
29
|
+
"react-addons-test-utils": "^0.14.7",
|
30
|
+
"sinon": "git://github.com/cjohansen/Sinon.JS#b672042043517b9f84e14ed0fb8265126168778a",
|
31
|
+
"sinon-chai": "^2.8.0",
|
32
|
+
"underscore": "^1.8.3",
|
33
|
+
"webpack": "^1.11.0"
|
34
|
+
},
|
35
|
+
"dependencies": {
|
36
|
+
"babel-polyfill": "^6.2.0",
|
37
|
+
"babel-runtime": "^5.8.20",
|
38
|
+
"classnames": "^2.1.3",
|
39
|
+
"react": "^0.14.3",
|
40
|
+
"react-dom": "^0.14.3",
|
41
|
+
"react-draggable": "git://github.com/tf/react-draggable#on-drag-fix"
|
42
|
+
}
|
43
|
+
}
|
data/js/spec/.eslintrc
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
import BackgroundImage from 'components/background_image.jsx';
|
2
|
+
|
3
|
+
import renderComponent from '../support/render_component';
|
4
|
+
|
5
|
+
describe('BackgroundImage', () => {
|
6
|
+
it('has image file css class', () => {
|
7
|
+
var backgroundImage = renderComponent(BackgroundImage, {imageFileId: 5});
|
8
|
+
|
9
|
+
expect(backgroundImage.props.className.split(' ')).to.contain('image_5');
|
10
|
+
});
|
11
|
+
|
12
|
+
it('has image_none css class if not imageFileId is given', () => {
|
13
|
+
var backgroundImage = renderComponent(BackgroundImage);
|
14
|
+
|
15
|
+
expect(backgroundImage.props.className.split(' ')).to.contain('image_none');
|
16
|
+
});
|
17
|
+
|
18
|
+
it('has load_image css class if loaded prop is present', () => {
|
19
|
+
var backgroundImage = renderComponent(BackgroundImage, {imageFileId: 5, loaded: true});
|
20
|
+
|
21
|
+
expect(backgroundImage.props.className.split(' ')).to.contain('load_image');
|
22
|
+
});
|
23
|
+
|
24
|
+
it('has image file css class', () => {
|
25
|
+
var backgroundImage = renderComponent(BackgroundImage, {imageFileId: 5});
|
26
|
+
|
27
|
+
expect(backgroundImage.props.className.split(' ')).to.contain('image_5');
|
28
|
+
});
|
29
|
+
|
30
|
+
it('defaults background position to center', () => {
|
31
|
+
var backgroundImage = renderComponent(BackgroundImage, {imageFileId: 5});
|
32
|
+
|
33
|
+
expect(backgroundImage.props.style.backgroundPosition).to.eq('50% 50%');
|
34
|
+
});
|
35
|
+
|
36
|
+
it('defaults background position to center', () => {
|
37
|
+
var backgroundImage = renderComponent(BackgroundImage, {imageFileId: 5, position: [undefined, undefined]});
|
38
|
+
|
39
|
+
expect(backgroundImage.props.style.backgroundPosition).to.eq('50% 50%');
|
40
|
+
});
|
41
|
+
|
42
|
+
it('sets background position inline styles', () => {
|
43
|
+
var backgroundImage = renderComponent(BackgroundImage, {imageFileId: 5, position: [10, 20]});
|
44
|
+
|
45
|
+
expect(backgroundImage.props.style.backgroundPosition).to.eq('10% 20%');
|
46
|
+
});
|
47
|
+
});
|
@@ -0,0 +1,213 @@
|
|
1
|
+
import {PageThumbnail} from 'components/page_thumbnail.jsx';
|
2
|
+
|
3
|
+
import renderComponent from '../support/render_component';
|
4
|
+
|
5
|
+
describe('PageThumbnail', () => {
|
6
|
+
it('has class names for thumbnail candidate', () => {
|
7
|
+
const page = {
|
8
|
+
type: {
|
9
|
+
thumbnailCandidates: [
|
10
|
+
{
|
11
|
+
attribute: 'thumbnailFileId',
|
12
|
+
collectionName: 'image_files',
|
13
|
+
cssClassPrefix: 'pageflow_image_file'
|
14
|
+
}
|
15
|
+
]
|
16
|
+
},
|
17
|
+
thumbnailFileId: 10
|
18
|
+
};
|
19
|
+
const fileIds = {
|
20
|
+
'image_files': [10]
|
21
|
+
};
|
22
|
+
|
23
|
+
const pageThumbnail = renderComponent(PageThumbnail, {page, fileIds, imageStyle: 'thumbnail'});
|
24
|
+
const className = pageThumbnail.props.className;
|
25
|
+
|
26
|
+
expect(className).to.contain('pageflow_image_file_thumbnail_10');
|
27
|
+
});
|
28
|
+
|
29
|
+
it('supports lazy thumbnail css class', () => {
|
30
|
+
const page = {
|
31
|
+
type: {
|
32
|
+
thumbnailCandidates: [
|
33
|
+
{
|
34
|
+
attribute: 'thumbnailFileId',
|
35
|
+
collectionName: 'image_files',
|
36
|
+
cssClassPrefix: 'pageflow_image_file'
|
37
|
+
}
|
38
|
+
]
|
39
|
+
},
|
40
|
+
thumbnailFileId: 10
|
41
|
+
};
|
42
|
+
const fileIds = {
|
43
|
+
'image_files': [10]
|
44
|
+
};
|
45
|
+
|
46
|
+
const pageThumbnail = renderComponent(PageThumbnail, {
|
47
|
+
page,
|
48
|
+
fileIds,
|
49
|
+
imageStyle: 'thumbnail',
|
50
|
+
lazy: true
|
51
|
+
});
|
52
|
+
const className = pageThumbnail.props.className;
|
53
|
+
|
54
|
+
expect(className).to.contain('lazy_pageflow_image_file_thumbnail_10');
|
55
|
+
});
|
56
|
+
|
57
|
+
it('adds load_image class if loaded prop is present', () => {
|
58
|
+
const page = {
|
59
|
+
type: {
|
60
|
+
thumbnailCandidates: [
|
61
|
+
{
|
62
|
+
attribute: 'thumbnailFileId',
|
63
|
+
collectionName: 'image_files',
|
64
|
+
cssClassPrefix: 'pageflow_image_file'
|
65
|
+
}
|
66
|
+
]
|
67
|
+
},
|
68
|
+
thumbnailFileId: 10
|
69
|
+
};
|
70
|
+
const fileIds = {
|
71
|
+
'image_files': [10]
|
72
|
+
};
|
73
|
+
|
74
|
+
const pageThumbnail = renderComponent(PageThumbnail, {
|
75
|
+
page,
|
76
|
+
fileIds,
|
77
|
+
imageStyle: 'thumbnail',
|
78
|
+
lazy: true,
|
79
|
+
loaded: true
|
80
|
+
});
|
81
|
+
const className = pageThumbnail.props.className;
|
82
|
+
|
83
|
+
expect(className).to.contain('load_image');
|
84
|
+
});
|
85
|
+
|
86
|
+
it('skips candidates whose attributes point to non existing files', () => {
|
87
|
+
const page = {
|
88
|
+
type: {
|
89
|
+
thumbnailCandidates: [
|
90
|
+
{
|
91
|
+
attribute: 'thumbnailFileId',
|
92
|
+
collectionName: 'image_files',
|
93
|
+
cssClassPrefix: 'pageflow_image_file'
|
94
|
+
},
|
95
|
+
{
|
96
|
+
attribute: 'videoId',
|
97
|
+
collectionName: 'video_files',
|
98
|
+
cssClassPrefix: 'pageflow_video_file'
|
99
|
+
}
|
100
|
+
]
|
101
|
+
},
|
102
|
+
thumbnailFileId: 10,
|
103
|
+
videoId: 5
|
104
|
+
};
|
105
|
+
const fileIds = {
|
106
|
+
'image_files': [],
|
107
|
+
'video_files': [5, 10],
|
108
|
+
};
|
109
|
+
|
110
|
+
const pageThumbnail = renderComponent(PageThumbnail, {page, fileIds, imageStyle: 'thumbnail'});
|
111
|
+
const className = pageThumbnail.props.className;
|
112
|
+
|
113
|
+
expect(className).to.contain('pageflow_video_file_thumbnail_5');
|
114
|
+
});
|
115
|
+
|
116
|
+
it('skips candidates whose attributes are not defined', () => {
|
117
|
+
const page = {
|
118
|
+
type: {
|
119
|
+
thumbnailCandidates: [
|
120
|
+
{
|
121
|
+
attribute: 'thumbnailFileId',
|
122
|
+
collectionName: 'image_files',
|
123
|
+
cssClassPrefix: 'pageflow_image_file'},
|
124
|
+
]
|
125
|
+
},
|
126
|
+
};
|
127
|
+
const fileIds = {};
|
128
|
+
|
129
|
+
const pageThumbnail = renderComponent(PageThumbnail, {page, fileIds});
|
130
|
+
const className = pageThumbnail.props.className;
|
131
|
+
|
132
|
+
expect(className).not.to.contain('pageflow_image_file');
|
133
|
+
});
|
134
|
+
|
135
|
+
it('prefers custom thumbnail id', () => {
|
136
|
+
const page = {
|
137
|
+
type: {
|
138
|
+
thumbnailCandidates: [
|
139
|
+
{
|
140
|
+
attribute: 'thumbnailFileId',
|
141
|
+
collectionName: 'image_files',
|
142
|
+
cssClassPrefix: 'pageflow_image_file'
|
143
|
+
}
|
144
|
+
]
|
145
|
+
},
|
146
|
+
thumbnailFileId: 10
|
147
|
+
};
|
148
|
+
const fileIds = {
|
149
|
+
'image_files': [10, 11]
|
150
|
+
};
|
151
|
+
|
152
|
+
const pageThumbnail = renderComponent(PageThumbnail, {page, fileIds, customThumbnailId: 11, imageStyle: 'thumbnail'});
|
153
|
+
const className = pageThumbnail.props.className;
|
154
|
+
|
155
|
+
expect(className).to.contain('pageflow_image_file_thumbnail_11');
|
156
|
+
});
|
157
|
+
|
158
|
+
it('skips custom thumbnail id pointing to non existent file', () => {
|
159
|
+
const page = {
|
160
|
+
type: {
|
161
|
+
thumbnailCandidates: []
|
162
|
+
}
|
163
|
+
};
|
164
|
+
const fileIds = {
|
165
|
+
'image_files': []
|
166
|
+
};
|
167
|
+
|
168
|
+
const pageThumbnail = renderComponent(PageThumbnail, {page, fileIds, customThumbnailId: 11, imageStyle: 'thumbnail'});
|
169
|
+
const className = pageThumbnail.props.className;
|
170
|
+
|
171
|
+
expect(className).not.to.contain('pageflow_image_file_thumbnail_11');
|
172
|
+
});
|
173
|
+
|
174
|
+
it('takes className prop', () => {
|
175
|
+
const page = {
|
176
|
+
type: {
|
177
|
+
thumbnailCandidates: []
|
178
|
+
}
|
179
|
+
};
|
180
|
+
const fileIds = {};
|
181
|
+
|
182
|
+
const pageThumbnail = renderComponent(PageThumbnail, {page, fileIds, className: 'custom'});
|
183
|
+
const className = pageThumbnail.props.className;
|
184
|
+
|
185
|
+
expect(className).to.contain('custom');
|
186
|
+
});
|
187
|
+
|
188
|
+
it('sets page type modifier class name', () => {
|
189
|
+
const page = {
|
190
|
+
type: {
|
191
|
+
name: 'video',
|
192
|
+
thumbnailCandidates: []
|
193
|
+
}
|
194
|
+
};
|
195
|
+
const fileIds = {};
|
196
|
+
|
197
|
+
const pageThumbnail = renderComponent(PageThumbnail, {page, fileIds});
|
198
|
+
const className = pageThumbnail.props.className;
|
199
|
+
|
200
|
+
expect(className).to.contain('is_video');
|
201
|
+
});
|
202
|
+
|
203
|
+
context('when page is null', function() {
|
204
|
+
it('sets is_dangling class name', () => {
|
205
|
+
const fileIds = {};
|
206
|
+
|
207
|
+
const pageThumbnail = renderComponent(PageThumbnail, {page: null, fileIds});
|
208
|
+
const className = pageThumbnail.props.className;
|
209
|
+
|
210
|
+
expect(className).to.contain('is_dangling');
|
211
|
+
});
|
212
|
+
});
|
213
|
+
})
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import createContainer from 'create_container.jsx';
|
2
|
+
import Resolver from 'resolvers/resolver';
|
3
|
+
|
4
|
+
import React from 'react';
|
5
|
+
import renderComponent from './support/render_component';
|
6
|
+
|
7
|
+
import TestUtils from 'react-addons-test-utils';
|
8
|
+
|
9
|
+
describe('createContainer', () => {
|
10
|
+
it('creates a wrapper component that passes props', () => {
|
11
|
+
var Component = class extends React.Component {};
|
12
|
+
|
13
|
+
var Container = createContainer(Component);
|
14
|
+
var result = renderComponent(Container, {some: 'prop'});
|
15
|
+
|
16
|
+
expect(result.type).to.eq(Component);
|
17
|
+
expect(result.props.some).to.eq('prop');
|
18
|
+
});
|
19
|
+
|
20
|
+
it('resolved fragments with given resolver', () => {
|
21
|
+
var Component = class extends React.Component {};
|
22
|
+
var FakeResolver = class extends Resolver {
|
23
|
+
get(props) {
|
24
|
+
return 'resolved page ' + props.targetPageId;
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
28
|
+
var Container = createContainer(Component, {
|
29
|
+
fragments: {
|
30
|
+
pageLink: {
|
31
|
+
targetPage: (callback) => {
|
32
|
+
return new FakeResolver(callback)
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
});
|
37
|
+
var result = renderComponent(Container, {
|
38
|
+
pageLink: {
|
39
|
+
targetPageId: 100
|
40
|
+
}
|
41
|
+
});
|
42
|
+
|
43
|
+
expect(result.props.pageLink.targetPage).to.eq('resolved page 100');
|
44
|
+
});
|
45
|
+
|
46
|
+
it('rerenders component when resolver invokes callback', () => {
|
47
|
+
var Component = class extends React.Component {};
|
48
|
+
var FakeResolver = class extends Resolver {
|
49
|
+
get(props) {
|
50
|
+
return `resolved page ${this.data}`;
|
51
|
+
}
|
52
|
+
};
|
53
|
+
var resolver;
|
54
|
+
|
55
|
+
var Container = createContainer(Component, {
|
56
|
+
fragments: {
|
57
|
+
pageLink: {
|
58
|
+
targetPage: (callback) => {
|
59
|
+
resolver = new FakeResolver(callback);
|
60
|
+
return resolver;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
});
|
65
|
+
|
66
|
+
const shallowRenderer = TestUtils.createRenderer();
|
67
|
+
const component = React.createElement(Container, {
|
68
|
+
pageLink: {
|
69
|
+
targetPageId: 100
|
70
|
+
}
|
71
|
+
});
|
72
|
+
|
73
|
+
shallowRenderer.render(component);
|
74
|
+
|
75
|
+
resolver.data = 2;
|
76
|
+
resolver._handleChange();
|
77
|
+
|
78
|
+
var result = shallowRenderer.getRenderOutput();
|
79
|
+
|
80
|
+
expect(result.props.pageLink.targetPage).to.eq('resolved page 2');
|
81
|
+
});
|
82
|
+
});
|