Skip to content

Commit b7bc01b

Browse files
committed
feat: Add support for editor interface
1 parent 0e5bf04 commit b7bc01b

File tree

8 files changed

+143
-1
lines changed

8 files changed

+143
-1
lines changed

lib/create-space-api.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export default function createSpaceApi ({
6767
const {wrapRole, wrapRoleCollection} = entities.role
6868
const {wrapSpaceMembership, wrapSpaceMembershipCollection} = entities.spaceMembership
6969
const {wrapApiKey, wrapApiKeyCollection} = entities.apiKey
70+
const {wrapEditorInterface} = entities.editorInterface
7071

7172
/**
7273
* Space instances.
@@ -122,6 +123,20 @@ export default function createSpaceApi ({
122123
.then((response) => wrapContentType(http, response.data), errorHandler)
123124
}
124125

126+
/**
127+
* Gets an EditorInterface for a ContentType
128+
* @memberof ContentfulSpaceAPI
129+
* @param {string} contentTypeId
130+
* @return {Promise<EditorInterface.EditorInterface>} Promise for an EditorInterface
131+
* @example
132+
* space.getEditorInterfaceForContentType('contentTypeId')
133+
* .then(editorInterface => console.log(editorInterface))
134+
*/
135+
function getEditorInterfaceForContentType (contentTypeId) {
136+
return http.get('content_types/' + contentTypeId + '/editor_interface')
137+
.then((response) => wrapEditorInterface(http, response.data), errorHandler)
138+
}
139+
125140
/**
126141
* Gets a collection of Content Types
127142
* @memberof ContentfulSpaceAPI
@@ -622,6 +637,7 @@ export default function createSpaceApi ({
622637
getContentTypes: getContentTypes,
623638
createContentType: createContentType,
624639
createContentTypeWithId: createContentTypeWithId,
640+
getEditorInterfaceForContentType: getEditorInterfaceForContentType,
625641
getEntry: getEntry,
626642
getEntries: getEntries,
627643
createEntry: createEntry,

lib/entities/content-type.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
createUpdatedChecker,
1616
createDraftChecker
1717
} from '../instance-actions'
18+
import {wrapEditorInterface} from './editor-interface'
19+
import errorHandler from '../error-handler'
1820

1921
/**
2022
* @memberof ContentType
@@ -90,6 +92,19 @@ function createContentTypeApi (http) {
9092
wrapperMethod: wrapContentType
9193
}),
9294

95+
/**
96+
* get the editor interface for the object
97+
* @memberof ContentType
98+
* @func getEditorInterface
99+
* @return {Promise<EditorInterface>} Object returned from the server with the current editor interface.
100+
* @example
101+
* contentType.getEditorInterface()
102+
* .then(editorInterface => console.log(editorInterface.controls))
103+
*/
104+
getEditorInterface: function () {
105+
return http.get('content_types/' + this.sys.id + '/editor_interface')
106+
.then((response) => wrapEditorInterface(http, response.data), errorHandler)
107+
},
93108
/**
94109
* Checks if the contentType is published. A published contentType might have unpublished changes (@see {ContentType.isUpdated})
95110
* @memberof ContentType

lib/entities/editor-interface.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Editor Interface instances
3+
* @namespace EditorInterface
4+
*/
5+
6+
import cloneDeep from 'lodash/cloneDeep'
7+
import freezeSys from 'contentful-sdk-core/freeze-sys'
8+
import enhanceWithMethods from '../enhance-with-methods'
9+
import mixinToPlainObject from 'contentful-sdk-core/mixins/to-plain-object'
10+
import omit from 'lodash/omit'
11+
import errorHandler from '../error-handler'
12+
13+
function createEditorInterfaceApi (http) {
14+
return {
15+
update: function () {
16+
const raw = this.toPlainObject()
17+
const data = omit(raw, ['sys'])
18+
return http.put('content_types' + '/' +
19+
this.sys.contentType.id +
20+
'/editor_interface',
21+
data,
22+
{
23+
headers: {
24+
'X-Contentful-Version': this.sys.version
25+
}
26+
}
27+
)
28+
.then((response) => wrapEditorInterface(http, response.data), errorHandler)
29+
}
30+
}
31+
}
32+
33+
/**
34+
* @private
35+
* @param {Object} http - HTTP client instance
36+
* @param {Object} data - Raw editor-interface data
37+
* @return {EditorInterface} Wrapped editor-interface data
38+
*/
39+
export function wrapEditorInterface (http, data) {
40+
const editorInterface = mixinToPlainObject(cloneDeep(data))
41+
enhanceWithMethods(editorInterface, createEditorInterfaceApi(http))
42+
return freezeSys(editorInterface)
43+
}

lib/entities/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as space from './space'
22
import * as entry from './entry'
33
import * as asset from './asset'
44
import * as contentType from './content-type'
5+
import * as editorInterface from './editor-interface'
56
import * as locale from './locale'
67
import * as webhook from './webhook'
78
import * as spaceMembership from './space-membership'
@@ -13,6 +14,7 @@ export default {
1314
entry,
1415
asset,
1516
contentType,
17+
editorInterface,
1618
locale,
1719
webhook,
1820
spaceMembership,

test/unit/create-space-api-test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import mixinToPlainObject from 'contentful-sdk-core/mixins/to-plain-object'
44
import createSpaceApi, {__RewireAPI__ as createSpaceApiRewireApi} from '../../lib/create-space-api'
55
import {
66
contentTypeMock,
7+
editorInterfaceMock,
78
assetMock,
89
entryMock,
910
localeMock,
@@ -157,6 +158,20 @@ test('API call createContentTypeWithId fails', (t) => {
157158
})
158159
})
159160

161+
test('API call getEditorInterfaceForContentType', (t) => {
162+
makeGetEntityTest(t, setup, teardown, {
163+
entityType: 'editorInterface',
164+
mockToReturn: editorInterfaceMock,
165+
methodToTest: 'getEditorInterfaceForContentType'
166+
})
167+
})
168+
169+
test('API call getEditorInterfaceForContentType fails', (t) => {
170+
makeEntityMethodFailingTest(t, setup, teardown, {
171+
methodToTest: 'getEditorInterfaceForContentType'
172+
})
173+
})
174+
160175
test('API call getEntry', (t) => {
161176
makeGetEntityTest(t, setup, teardown, {
162177
entityType: 'entry',

test/unit/entities/content-type-test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,20 @@ test('ContentType unpublish fails', (t) => {
8888
})
8989
})
9090

91+
test('ContentType getEditorInterface', (t) => {
92+
return entityActionTest(t, setup, {
93+
wrapperMethod: wrapContentType,
94+
actionMethod: 'getEditorInterface'
95+
})
96+
})
97+
98+
test('ContentType getEditorInterface fails', (t) => {
99+
return failingActionTest(t, setup, {
100+
wrapperMethod: wrapContentType,
101+
actionMethod: 'getEditorInterface'
102+
})
103+
})
104+
91105
test('ContentType isPublished', (t) => {
92106
isPublishedTest(t, setup, {wrapperMethod: wrapContentType})
93107
})
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import test from 'tape'
2+
import {cloneMock} from '../mocks/entities'
3+
import setupHttpMock from '../mocks/http'
4+
import {wrapEditorInterface} from '../../../lib/entities/editor-interface'
5+
import {
6+
entityWrappedTest
7+
} from '../test-creators/instance-entity-methods'
8+
9+
function setup (promise) {
10+
return {
11+
httpMock: setupHttpMock(promise),
12+
entityMock: cloneMock('editorInterface')
13+
}
14+
}
15+
16+
test('Editor Interface is wrapped', (t) => {
17+
return entityWrappedTest(t, setup, {
18+
wrapperMethod: wrapEditorInterface
19+
})
20+
})

test/unit/mocks/entities.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,19 @@ const entryMock = {
5252
field1: 'str'
5353
}
5454
}
55-
55+
const editorInterfaceMock = {
56+
sys: assign(cloneDeep(sysMock), {
57+
type: 'EditorInterface',
58+
contentType: assign(cloneDeep(linkMock), {linkType: 'ContentType'}),
59+
space: assign(cloneDeep(linkMock), {linkType: 'Space'})
60+
}),
61+
controls: [
62+
{
63+
'fieldId': 'fieldid',
64+
'widgetId': 'singleLine'
65+
}
66+
]
67+
}
5668
const assetMock = {
5769
sys: assign(cloneDeep(sysMock), {
5870
type: 'Asset',
@@ -112,6 +124,7 @@ const mocks = {
112124
link: linkMock,
113125
sys: sysMock,
114126
contentType: contentTypeMock,
127+
editorInterface: editorInterfaceMock,
115128
entry: entryMock,
116129
asset: assetMock,
117130
locale: localeMock,
@@ -172,6 +185,9 @@ function setupEntitiesMock (rewiredModuleApi) {
172185
apiKey: {
173186
wrapApiKey: sinon.stub(),
174187
wrapApiKeyCollection: sinon.stub()
188+
},
189+
editorInterface: {
190+
wrapEditorInterface: sinon.stub()
175191
}
176192
}
177193
rewiredModuleApi.__Rewire__('entities', entitiesMock)
@@ -184,6 +200,7 @@ export {
184200
sysMock,
185201
spaceMock,
186202
contentTypeMock,
203+
editorInterfaceMock,
187204
entryMock,
188205
assetMock,
189206
localeMock,

0 commit comments

Comments
 (0)