@botonic/plugin-contentful
Version:
## What Does This Plugin Do?
285 lines (242 loc) • 6.99 kB
text/typescript
import { ContentType } from '../cms'
import { HandoffAgentEmail, OnFinish } from '../contents'
import {
CarouselBuilder,
DocumentBuilder,
ElementBuilder,
HandoffBuilder,
InputBuilder,
MediaBuilder,
StartUpBuilder,
TextBuilder,
TopContentBuilder,
} from '../factories/content-factories'
import {
Button,
ButtonStyle,
Callback,
CmsException,
CommonFields,
ContentCallback,
Element,
Text,
TopContentId,
} from '../index'
/**
* The Builder classes below create Content instances with minimal effort
* to speedup the implementation of unit tests by setting random values for the
* non specified fields.
* They are exported by the plugin so that the can be used in bots' unit tests
*/
export function rndStr(): string {
return Math.random().toString()
}
export function rndBool(): boolean {
return Math.random() >= 0.5
}
export class ContentCallbackBuilder {
callback: Callback | undefined
withContentId(contentId: TopContentId): ContentCallbackBuilder {
this.callback = ContentCallback.ofContentId(contentId)
return this
}
build(): Callback {
return this.callback || new ContentCallback(ContentType.TEXT, rndStr())
}
}
export class RndButtonsBuilder {
name: string | undefined
text: string | undefined
buttons: Button[] = []
callbackBuilder = new ContentCallbackBuilder()
callback: Callback | undefined
build(): Button[] {
return this.buttons
}
withCallback(callback: Callback): this {
this.callback = callback
return this
}
withName(name: string): this {
this.name = name
return this
}
withText(text: string): this {
this.text = text
return this
}
addButton(): this {
this.buttons.push(
new Button(
rndStr(),
this.name ?? rndStr(),
this.text ?? rndStr(),
this.callback ?? this.callbackBuilder.build()
)
)
return this
}
}
export class RndTopContentBuilder {
keywords = []
withRandomFields(builder: TopContentBuilder) {
builder.shortText = rndStr()
builder.keywords = [rndStr(), rndStr()]
builder.followUp = rndBool()
? undefined
: new Text(new CommonFields(rndStr(), rndStr()), rndStr(), [])
}
}
export class RndTextBuilder extends TextBuilder {
public buttonsBuilder = new RndButtonsBuilder()
readonly topComponentBuilder = new RndTopContentBuilder()
constructor(name: string = rndStr(), text: string = rndStr()) {
super(rndStr(), name, text)
}
/** @deprecated use buttonsBuilder */
withButtonsBuilder(): RndButtonsBuilder {
return this.buttonsBuilder
}
build(): Text {
const buttons = this.buttonsBuilder.build()
// TODO too complex. resurrect withButtonsBuilder?
if (buttons.length > 0) {
if (this.buttons.length > 0) {
throw new CmsException(
'Not supported to add buttons with both .buttons & buttonsBuilder'
)
}
this.buttonsBuilder.buttons = []
this.buttons = buttons
}
return super.build()
}
withRandomFields(): this {
this.buttonsBuilder.addButton().addButton()
this.topComponentBuilder.withRandomFields(this)
this.buttonsStyle = rndBool() ? ButtonStyle.QUICK_REPLY : ButtonStyle.BUTTON
return this
}
}
export class RndElementBuilder extends ElementBuilder {
// move ButtonsBuilder to ElementBuilder?
private buttonsBuilder: RndButtonsBuilder | undefined
constructor() {
super(rndStr())
}
withButtonsBuilder(): RndButtonsBuilder {
if (this.buttons.length > 0) {
throw new CmsException(
'cannot use withButtonsBuilder if addButtons was previously called'
)
}
if (!this.buttonsBuilder) {
this.buttonsBuilder = new RndButtonsBuilder()
}
return this.buttonsBuilder
}
withButtons(buttons: Button[]): this {
if (this.buttonsBuilder) {
throw new CmsException(
'cannot use addButtons if withButtonsBuilder was previously called'
)
}
return super.withButtons(buttons)
}
withRandomFields(): this {
if (!this.buttonsBuilder) {
this.buttonsBuilder = new RndButtonsBuilder().addButton().addButton()
}
this.title = rndStr()
this.subtitle = rndStr()
this.imgUrl = rndStr()
return this
}
build(): Element {
if (this.buttonsBuilder) {
this.buttons = this.buttonsBuilder.build()
}
return super.build()
}
}
export class RndCarouselBuilder extends CarouselBuilder {
readonly topComponentBuilder = new RndTopContentBuilder()
readonly elementBuilder = new RndElementBuilder()
constructor(name: string = rndStr()) {
super(rndStr(), name)
}
withRandomFields(numElements = 2): this {
for (let i = 0; i < numElements; i++) {
this.elementBuilder.withRandomFields()
this.addElement()
}
this.topComponentBuilder.withRandomFields(this)
return this
}
}
export class RndStartUpBuilder extends StartUpBuilder {
readonly topComponentBuilder = new RndTopContentBuilder()
readonly buttonsBuilder = new RndButtonsBuilder()
constructor(name: string = rndStr(), text: string = rndStr()) {
super(rndStr(), name, text)
}
withRandomFields(): this {
this.buttons = this.buttonsBuilder.addButton().addButton().build()
this.topComponentBuilder.withRandomFields(this)
return this
}
}
export class RndMediaBuilder extends MediaBuilder {
readonly topComponentBuilder = new RndTopContentBuilder()
constructor(
name: string = rndStr(),
mediaUrl: string = 'http://' + rndStr()
) {
super(rndStr(), name, mediaUrl)
}
withRandomFields(): this {
this.topComponentBuilder.withRandomFields(this)
return this
}
}
export class RndDocumentBuilder extends DocumentBuilder {
readonly topComponentBuilder = new RndTopContentBuilder()
constructor(name: string = rndStr(), docUrl: string = 'http://' + rndStr()) {
super(rndStr(), name, docUrl)
}
withRandomFields(): this {
this.topComponentBuilder.withRandomFields(this)
return this
}
}
export class RndHandoffBuilder extends HandoffBuilder {
readonly topComponentBuilder = new RndTopContentBuilder()
constructor(
name: string = rndStr(),
onFinish: OnFinish = new ContentCallbackBuilder().build()
) {
super(rndStr(), name, onFinish)
}
withRandomFields(): this {
this.message = new Text(new CommonFields(rndStr(), rndStr()), rndStr(), [])
this.failMessage = new Text(
new CommonFields(rndStr(), rndStr()),
rndStr(),
[]
)
this.agent = new HandoffAgentEmail(rndStr())
this.shadowing = rndBool()
this.topComponentBuilder.withRandomFields(this)
return this
}
}
export class RndInputBuilder extends InputBuilder {
readonly topComponentBuilder = new RndTopContentBuilder()
constructor(
name: string = rndStr(),
keywords: string[] = [rndStr(), rndStr()],
target: Callback = new ContentCallbackBuilder().build()
) {
super(rndStr(), name, rndStr(), keywords, target)
}
}