Skip to content

Commit

Permalink
Merge pull request #1320 from contentful/feat/SPA-2047-experience-type
Browse files Browse the repository at this point in the history
feat: support annotation for experience types [SPA-2047]
  • Loading branch information
Chaoste authored Jun 21, 2024
2 parents 2ab60f9 + ac527f6 commit 63f81cb
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 5 deletions.
90 changes: 90 additions & 0 deletions examples/54-create-experience-type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
module.exports = function (migration) {
const experienceType = migration.createContentType('experienceType').name('Experience')

experienceType
.createField('title')
.name('Title')
.type('Symbol')
.localized(false)
.required(true)
.validations([])
.disabled(false)
.omitted(false)

experienceType.displayField('title')

experienceType
.createField('slug')
.name('Slug')
.type('Symbol')
.localized(false)
.required(true)
.validations([{ unique: true }])
.disabled(false)
.omitted(false)

experienceType
.createField('componentTree')
.name('Component Tree')
.type('Object')
.localized(false)
.required(true)
.validations([])
.disabled(false)
.omitted(false)

experienceType
.createField('dataSource')
.name('Data Source')
.type('Object')
.localized(false)
.required(true)
.validations([])
.disabled(false)
.omitted(false)

experienceType
.createField('unboundValues')
.name('Unbound Values')
.type('Object')
.localized(false)
.required(true)
.validations([])
.disabled(false)
.omitted(false)

experienceType
.createField('componentSettings')
.name('Component Settings')
.type('Object')
.localized(false)
.required(false)
.validations([])
.disabled(false)
.omitted(false)

experienceType
.createField('usedComponents')
.name('Used Components')
.type('Array')
.localized(false)
.required(false)
.validations([])
.disabled(false)
.omitted(false)
.items({
type: 'Link',
validations: [{ linkContentType: ['experienceType'] }],
linkType: 'Entry'
})

experienceType.changeFieldControl('title', 'builtin', 'singleLine')
experienceType.changeFieldControl('slug', 'builtin', 'slugEditor')
experienceType.changeFieldControl('componentTree', 'builtin', 'objectEditor')
experienceType.changeFieldControl('dataSource', 'builtin', 'objectEditor')
experienceType.changeFieldControl('unboundValues', 'builtin', 'objectEditor')
experienceType.changeFieldControl('componentSettings', 'builtin', 'objectEditor')
experienceType.changeFieldControl('usedComponents', 'builtin', 'entryLinksEditor')

experienceType.setAnnotations(['Contentful:ExperienceType'])
}
10 changes: 10 additions & 0 deletions src/lib/interfaces/annotation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export class Annotation {
}

export const availableAnnotations = {
// Targeting ContentType
'Contentful:AggregateRoot': new Annotation({
id: 'Contentful:AggregateRoot',
targets: [
Expand All @@ -74,6 +75,15 @@ export const availableAnnotations = {
}
]
}),
'Contentful:ExperienceType': new Annotation({
id: 'Contentful:ExperienceType',
targets: [
{
type: 'ContentType'
}
]
}),
// Targeting ContentTypeField
'Contentful:AggregateComponent': new Annotation({
id: 'Contentful:AggregateComponent',
targets: [
Expand Down
4 changes: 2 additions & 2 deletions src/lib/offline-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { PayloadValidationError, InvalidActionError } from '../interfaces/errors
import DisplayFieldValidator from './validator/display-field'
import SchemaValidator from './validator/schema/index'
import TypeChangeValidator from './validator/type-change'
import AnnotationValidator from './validator/annotations'
import AnnotationsValidator from './validator/annotations'
import TagsOnEntryValidator from './validator/tags-on-entry'
import { Intent } from '../interfaces/intent'
import APIEntry from '../interfaces/api-entry'
Expand Down Expand Up @@ -221,7 +221,7 @@ class OfflineAPI {
new DisplayFieldValidator(),
new SchemaValidator(),
new TypeChangeValidator(),
new AnnotationValidator(),
new AnnotationsValidator(),
new ResourceLinksValidator()
)

Expand Down
17 changes: 14 additions & 3 deletions test/end-to-end/assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ module.exports = {
contentType: {
create: function (id, params) {
return (result) => {
expect(result.stdout).not.to.be.empty()
expect(result.stdout).not.to.be.empty(result.stderr)

const withoutAnsiCodes = stripAnsi(result.stdout)
expect(withoutAnsiCodes).to.include(`Create Content Type ${id}`)
Expand All @@ -108,7 +108,7 @@ module.exports = {
},
update: function (id, params) {
return (result) => {
expect(result.stdout).not.to.be.empty()
expect(result.stdout).not.to.be.empty(result.stderr)

const withoutAnsiCodes = stripAnsi(result.stdout)
expect(withoutAnsiCodes).to.include(`Update Content Type ${id}`)
Expand All @@ -121,7 +121,7 @@ module.exports = {
},
delete: function (id) {
return (result) => {
expect(result.stdout).not.to.be.empty()
expect(result.stdout).not.to.be.empty(result.stderr)

const withoutAnsiCodes = stripAnsi(result.stdout)
expect(withoutAnsiCodes).to.include(`Delete Content Type ${id}`)
Expand Down Expand Up @@ -426,6 +426,17 @@ module.exports = {
expect(withoutAnsiCodes).to.include(`Delete Tag ${id}`)
}
}
},
annotation: {
assign: function (id) {
return (result) => {
expect(result.stdout).not.to.be.empty(result.stderr)

const withoutAnsiCodes = stripAnsi(result.stdout)

expect(withoutAnsiCodes).to.include(`Assign annotation ${id}`)
}
}
}
},
help: {
Expand Down
35 changes: 35 additions & 0 deletions test/end-to-end/content-type.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,39 @@ describe('apply content-type migration examples', function () {
})
)
})

it('applies 54-create-experience-type', function (done) {
cli()
.run(
`--space-id ${SOURCE_TEST_SPACE} --environment-id ${environmentId} ./examples/54-create-experience-type.js`
)
.on(/\? Do you want to apply the migration \(Y\/n\)/)
.respond('Y\n')
.expect(assert.plans.contentType.create('experienceType'))
.expect(assert.plans.annotation.assign('Contentful:ExperienceType'))
.expect(assert.plans.actions.apply())
.end(
co(function* () {
const contentType = yield getDevContentType(
SOURCE_TEST_SPACE,
environmentId,
'experienceType'
)
expect(contentType.metadata).to.eql({
annotations: {
ContentType: [
{
sys: {
id: 'Contentful:ExperienceType',
type: 'Link',
linkType: 'Annotation'
}
}
]
}
})
done()
})
)
})
})
24 changes: 24 additions & 0 deletions test/integration/migration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const moveFieldOnContentTypeWithEditorLayout = require('../../examples/51-move-f
const deleteFieldOnContentTypeWithEditorLayout = require('../../examples/52-delete-field-in-content-type-with-editor-layout')
const renameFieldOnContentTypeWithEditorLayout = require('../../examples/53-rename-field-in-content-type-with-editor-layout')
const createRichTextFieldWithValidation = require('../../examples/22-create-rich-text-field-with-validation')
const createExperienceType = require('../../examples/54-create-experience-type')

const { createMigrationParser } = require('../../built/lib/migration-parser')
const { DEFAULT_SIDEBAR_LIST } = require('../../built/lib/action/sidebarwidget')
Expand Down Expand Up @@ -1378,4 +1379,27 @@ describe('the migration', function () {
]
})
})

// Note: Requires space to be enabled for Studio Experiences via org settings
it('assigns experience type annotation', async function () {
await migrator(createExperienceType)
const ct = await request({
method: 'GET',
url: '/content_types/experienceType'
})

expect(ct.metadata).to.eql({
annotations: {
ContentType: [
{
sys: {
id: 'Contentful:ExperienceType',
type: 'Link',
linkType: 'Annotation'
}
}
]
}
})
})
})

0 comments on commit 63f81cb

Please sign in to comment.