pageflow-react 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
});
|