feat(api): ✨ Add get sample result endpoint
This commit is contained in:
@ -1,9 +1,9 @@
|
||||
import { ResultWithAnswers, Typebot, VariableWithValue } from 'models'
|
||||
import { ResultWithAnswers, VariableWithValue } from 'models'
|
||||
import useSWRInfinite from 'swr/infinite'
|
||||
import { fetcher } from './utils'
|
||||
import { stringify } from 'qs'
|
||||
import { Answer } from 'db'
|
||||
import { byId, isDefined, sendRequest } from 'utils'
|
||||
import { isDefined, sendRequest } from 'utils'
|
||||
|
||||
const paginationLimit = 50
|
||||
|
||||
@ -112,28 +112,3 @@ export const convertResultsToTableData = (results?: ResultWithAnswers[]) =>
|
||||
return { ...o, [variable.id]: variable.value }
|
||||
}, {}),
|
||||
}))
|
||||
|
||||
export const parseAnswers = (
|
||||
result: ResultWithAnswers,
|
||||
{ blocks, variables }: Pick<Typebot, 'blocks' | 'variables'>
|
||||
) => ({
|
||||
submittedAt: result.createdAt,
|
||||
...[...result.answers, ...result.prefilledVariables].reduce<{
|
||||
[key: string]: string
|
||||
}>((o, answerOrVariable) => {
|
||||
if ('blockId' in answerOrVariable) {
|
||||
const answer = answerOrVariable as Answer
|
||||
const key = answer.variableId
|
||||
? variables.find(byId(answer.variableId))?.name
|
||||
: blocks.find(byId(answer.blockId))?.title
|
||||
if (!key) return o
|
||||
return {
|
||||
...o,
|
||||
[key]: answer.content,
|
||||
}
|
||||
}
|
||||
const variable = answerOrVariable as VariableWithValue
|
||||
if (isDefined(o[variable.id])) return o
|
||||
return { ...o, [variable.id]: variable.value }
|
||||
}, {}),
|
||||
})
|
||||
|
@ -0,0 +1,98 @@
|
||||
import prisma from 'libs/prisma'
|
||||
import { Block, InputStep, InputStepType, Typebot } from 'models'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { authenticateUser } from 'services/api/utils'
|
||||
import { byId, isDefined, isInputStep, methodNotAllowed } from 'utils'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method === 'GET') {
|
||||
const user = await authenticateUser(req)
|
||||
if (!user) return res.status(401).json({ message: 'Not authenticated' })
|
||||
const typebotId = req.query.typebotId.toString()
|
||||
const blockId = req.query.blockId.toString()
|
||||
const typebot = (await prisma.typebot.findUnique({
|
||||
where: { id_ownerId: { id: typebotId, ownerId: user.id } },
|
||||
})) as Typebot | undefined
|
||||
if (!typebot) return res.status(400).send({ message: 'Typebot not found' })
|
||||
const previousBlockIds = getPreviousBlocks(typebot)(blockId)
|
||||
const previousBlocks = typebot.blocks.filter((b) =>
|
||||
previousBlockIds.includes(b.id)
|
||||
)
|
||||
return res.send(parseSampleResult(typebot)(previousBlocks))
|
||||
}
|
||||
methodNotAllowed(res)
|
||||
}
|
||||
|
||||
const parseSampleResult =
|
||||
(typebot: Typebot) =>
|
||||
(blocks: Block[]): Record<string, string> => {
|
||||
const parsedBlocks = parseBlocksResultSample(typebot, blocks)
|
||||
return {
|
||||
message: 'This is a sample result, it has been generated ⬇️',
|
||||
'Submitted at': new Date().toISOString(),
|
||||
...parsedBlocks,
|
||||
...parseVariablesHeaders(typebot, parsedBlocks),
|
||||
}
|
||||
}
|
||||
|
||||
const parseBlocksResultSample = (typebot: Typebot, blocks: Block[]) =>
|
||||
blocks
|
||||
.filter((block) => typebot && block.steps.some((step) => isInputStep(step)))
|
||||
.reduce<Record<string, string>>((blocks, block) => {
|
||||
const inputStep = block.steps.find((step) => isInputStep(step))
|
||||
if (!inputStep || !isInputStep(inputStep)) return blocks
|
||||
const matchedVariableName =
|
||||
inputStep.options.variableId &&
|
||||
typebot.variables.find(byId(inputStep.options.variableId))?.name
|
||||
const value = getSampleValue(inputStep)
|
||||
return {
|
||||
...blocks,
|
||||
[matchedVariableName ?? block.title]: value,
|
||||
}
|
||||
}, {})
|
||||
|
||||
const getSampleValue = (step: InputStep) => {
|
||||
switch (step.type) {
|
||||
case InputStepType.CHOICE:
|
||||
return 'Item 1, Item 2, Item3'
|
||||
case InputStepType.DATE:
|
||||
return new Date().toUTCString()
|
||||
case InputStepType.EMAIL:
|
||||
return 'test@email.com'
|
||||
case InputStepType.NUMBER:
|
||||
return '20'
|
||||
case InputStepType.PHONE:
|
||||
return '+33665566773'
|
||||
case InputStepType.TEXT:
|
||||
return 'answer value'
|
||||
case InputStepType.URL:
|
||||
return 'https://test.com'
|
||||
}
|
||||
}
|
||||
|
||||
const parseVariablesHeaders = (
|
||||
typebot: Typebot,
|
||||
parsedBlocks: Record<string, string>
|
||||
) =>
|
||||
typebot.variables.reduce<Record<string, string>>((headers, v) => {
|
||||
if (parsedBlocks[v.name]) return headers
|
||||
return {
|
||||
...headers,
|
||||
[v.name]: 'value',
|
||||
}
|
||||
}, {})
|
||||
|
||||
const getPreviousBlocks =
|
||||
(typebot: Typebot) =>
|
||||
(blockId: string): string[] => {
|
||||
const previousBlocks = typebot.edges
|
||||
.map((edge) =>
|
||||
edge.to.blockId === blockId ? edge.from.blockId : undefined
|
||||
)
|
||||
.filter(isDefined)
|
||||
return previousBlocks.concat(
|
||||
previousBlocks.flatMap(getPreviousBlocks(typebot))
|
||||
)
|
||||
}
|
||||
|
||||
export default handler
|
381
apps/viewer/playwright/fixtures/typebots/api.json
Normal file
381
apps/viewer/playwright/fixtures/typebots/api.json
Normal file
@ -0,0 +1,381 @@
|
||||
{
|
||||
"id": "qujHPjZ44xbrHb1hS1d8qC",
|
||||
"createdAt": "2022-02-05T06:21:16.522Z",
|
||||
"updatedAt": "2022-02-05T06:21:16.522Z",
|
||||
"name": "My typebot",
|
||||
"ownerId": "ckzwaq0p000149f1a2ejh3qm0",
|
||||
"publishedTypebotId": null,
|
||||
"folderId": null,
|
||||
"blocks": [
|
||||
{
|
||||
"id": "k6kY6gwRE6noPoYQNGzgUq",
|
||||
"steps": [
|
||||
{
|
||||
"id": "22HP69iipkLjJDTUcc1AWW",
|
||||
"type": "start",
|
||||
"label": "Start",
|
||||
"blockId": "k6kY6gwRE6noPoYQNGzgUq",
|
||||
"outgoingEdgeId": "oNvqaqNExdSH2kKEhKZHuE"
|
||||
}
|
||||
],
|
||||
"title": "Start",
|
||||
"graphCoordinates": { "x": 0, "y": 0 }
|
||||
},
|
||||
{
|
||||
"id": "kinRXxYop2X4d7F9qt8WNB",
|
||||
"steps": [
|
||||
{
|
||||
"id": "sc1y8VwDabNJgiVTBi4qtif",
|
||||
"type": "text",
|
||||
"blockId": "kinRXxYop2X4d7F9qt8WNB",
|
||||
"content": {
|
||||
"html": "<div>Welcome to <span class=\"slate-bold\">AA</span> (Awesome Agency)</div>",
|
||||
"richText": [
|
||||
{
|
||||
"type": "p",
|
||||
"children": [
|
||||
{ "text": "Welcome to " },
|
||||
{ "bold": true, "text": "AA" },
|
||||
{ "text": " (Awesome Agency)" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"plainText": "Welcome to AA (Awesome Agency)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "s7YqZTBeyCa4Hp3wN2j922c",
|
||||
"type": "image",
|
||||
"blockId": "kinRXxYop2X4d7F9qt8WNB",
|
||||
"content": {
|
||||
"url": "https://media2.giphy.com/media/XD9o33QG9BoMis7iM4/giphy.gif?cid=fe3852a3ihg8rvipzzky5lybmdyq38fhke2tkrnshwk52c7d&rid=giphy.gif&ct=g"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sbjZWLJGVkHAkDqS4JQeGow",
|
||||
"type": "choice input",
|
||||
"items": [
|
||||
{
|
||||
"id": "hQw2zbp7FDX7XYK9cFpbgC",
|
||||
"type": 0,
|
||||
"stepId": "sbjZWLJGVkHAkDqS4JQeGow",
|
||||
"content": "Hi!"
|
||||
}
|
||||
],
|
||||
"blockId": "kinRXxYop2X4d7F9qt8WNB",
|
||||
"options": { "buttonLabel": "Send", "isMultipleChoice": false },
|
||||
"outgoingEdgeId": "i51YhHpk1dtSyduFNf5Wim"
|
||||
}
|
||||
],
|
||||
"title": "Welcome",
|
||||
"graphCoordinates": { "x": 1, "y": 148 }
|
||||
},
|
||||
{
|
||||
"id": "o4SH1UtKANnW5N5D67oZUz",
|
||||
"steps": [
|
||||
{
|
||||
"id": "sxeYubYN6XzhAfG7m9Fivhc",
|
||||
"type": "text",
|
||||
"blockId": "o4SH1UtKANnW5N5D67oZUz",
|
||||
"content": {
|
||||
"html": "<div>Great! Nice to meet you {{Name}}</div>",
|
||||
"richText": [
|
||||
{
|
||||
"type": "p",
|
||||
"children": [{ "text": "Great! Nice to meet you {{Name}}" }]
|
||||
}
|
||||
],
|
||||
"plainText": "Great! Nice to meet you {{Name}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "scQ5kduafAtfP9T8SHUJnGi",
|
||||
"type": "text",
|
||||
"blockId": "o4SH1UtKANnW5N5D67oZUz",
|
||||
"content": {
|
||||
"html": "<div>What's the best email we can reach you at?</div>",
|
||||
"richText": [
|
||||
{
|
||||
"type": "p",
|
||||
"children": [
|
||||
{ "text": "What's the best email we can reach you at?" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"plainText": "What's the best email we can reach you at?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "snbsad18Bgry8yZ8DZCfdFD",
|
||||
"type": "email input",
|
||||
"blockId": "o4SH1UtKANnW5N5D67oZUz",
|
||||
"options": {
|
||||
"labels": { "button": "Send", "placeholder": "Type your email..." },
|
||||
"variableId": "3VFChNVSCXQ2rXv4DrJ8Ah"
|
||||
},
|
||||
"outgoingEdgeId": "w3MiN1Ct38jT5NykVsgmb5"
|
||||
}
|
||||
],
|
||||
"title": "Email",
|
||||
"graphCoordinates": { "x": 669, "y": 141 }
|
||||
},
|
||||
{
|
||||
"id": "q5dAhqSTCaNdiGSJm9B9Rw",
|
||||
"steps": [
|
||||
{
|
||||
"id": "sgtE2Sy7cKykac9B223Kq9R",
|
||||
"type": "text",
|
||||
"blockId": "q5dAhqSTCaNdiGSJm9B9Rw",
|
||||
"content": {
|
||||
"html": "<div>What's your name?</div>",
|
||||
"richText": [
|
||||
{ "type": "p", "children": [{ "text": "What's your name?" }] }
|
||||
],
|
||||
"plainText": "What's your name?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sqEsMo747LTDnY9FjQcEwUv",
|
||||
"type": "text input",
|
||||
"blockId": "q5dAhqSTCaNdiGSJm9B9Rw",
|
||||
"options": {
|
||||
"isLong": false,
|
||||
"labels": {
|
||||
"button": "Send",
|
||||
"placeholder": "Type your answer..."
|
||||
},
|
||||
"variableId": "giiLFGw5xXBCHzvp1qAbdX"
|
||||
},
|
||||
"outgoingEdgeId": "4tYbERpi5Po4goVgt6rWXg"
|
||||
}
|
||||
],
|
||||
"title": "Name",
|
||||
"graphCoordinates": { "x": 340, "y": 143 }
|
||||
},
|
||||
{
|
||||
"id": "fKqRz7iswk7ULaj5PJocZL",
|
||||
"steps": [
|
||||
{
|
||||
"id": "su7HceVXWyTCzi2vv3m4QbK",
|
||||
"type": "text",
|
||||
"blockId": "fKqRz7iswk7ULaj5PJocZL",
|
||||
"content": {
|
||||
"html": "<div>What services are you interested in?</div>",
|
||||
"richText": [
|
||||
{
|
||||
"type": "p",
|
||||
"children": [{ "text": "What services are you interested in?" }]
|
||||
}
|
||||
],
|
||||
"plainText": "What services are you interested in?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "s5VQGsVF4hQgziQsXVdwPDW",
|
||||
"type": "choice input",
|
||||
"items": [
|
||||
{
|
||||
"id": "fnLCBF4NdraSwcubnBhk8H",
|
||||
"type": 0,
|
||||
"stepId": "s5VQGsVF4hQgziQsXVdwPDW",
|
||||
"content": "Website dev"
|
||||
},
|
||||
{
|
||||
"id": "a782h8ynMouY84QjH7XSnR",
|
||||
"type": 0,
|
||||
"stepId": "s5VQGsVF4hQgziQsXVdwPDW",
|
||||
"content": "Content Marketing"
|
||||
},
|
||||
{
|
||||
"id": "jGvh94zBByvVFpSS3w97zY",
|
||||
"type": 0,
|
||||
"stepId": "s5VQGsVF4hQgziQsXVdwPDW",
|
||||
"content": "Social Media"
|
||||
},
|
||||
{
|
||||
"id": "6PRLbKUezuFmwWtLVbvAQ7",
|
||||
"type": 0,
|
||||
"stepId": "s5VQGsVF4hQgziQsXVdwPDW",
|
||||
"content": "UI / UX Design"
|
||||
}
|
||||
],
|
||||
"blockId": "fKqRz7iswk7ULaj5PJocZL",
|
||||
"options": { "buttonLabel": "Send", "isMultipleChoice": true },
|
||||
"outgoingEdgeId": "ohTRakmcYJ7GdFWRZrWRjk"
|
||||
}
|
||||
],
|
||||
"title": "Services",
|
||||
"graphCoordinates": { "x": 1002, "y": 144 }
|
||||
},
|
||||
{
|
||||
"id": "7qHBEyCMvKEJryBHzPmHjV",
|
||||
"steps": [
|
||||
{
|
||||
"id": "sqR8Sz9gW21aUYKtUikq7qZ",
|
||||
"type": "text",
|
||||
"blockId": "7qHBEyCMvKEJryBHzPmHjV",
|
||||
"content": {
|
||||
"html": "<div>Can you tell me a bit more about your needs?</div>",
|
||||
"richText": [
|
||||
{
|
||||
"type": "p",
|
||||
"children": [
|
||||
{ "text": "Can you tell me a bit more about your needs?" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"plainText": "Can you tell me a bit more about your needs?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sqFy2G3C1mh9p6s3QBdSS5x",
|
||||
"type": "text input",
|
||||
"blockId": "7qHBEyCMvKEJryBHzPmHjV",
|
||||
"options": {
|
||||
"isLong": true,
|
||||
"labels": { "button": "Send", "placeholder": "Type your answer..." }
|
||||
},
|
||||
"outgoingEdgeId": "sH5nUssG2XQbm6ZidGv9BY"
|
||||
}
|
||||
],
|
||||
"title": "Additional information",
|
||||
"graphCoordinates": { "x": 1337, "y": 145 }
|
||||
},
|
||||
{
|
||||
"id": "vF7AD7zSAj7SNvN3gr9N94",
|
||||
"steps": [
|
||||
{
|
||||
"id": "seLegenCgUwMopRFeAefqZ7",
|
||||
"type": "text",
|
||||
"blockId": "vF7AD7zSAj7SNvN3gr9N94",
|
||||
"content": {
|
||||
"html": "<div>Perfect!</div>",
|
||||
"richText": [{ "type": "p", "children": [{ "text": "Perfect!" }] }],
|
||||
"plainText": "Perfect!"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "s779Q1y51aVaDUJVrFb16vv",
|
||||
"type": "text",
|
||||
"blockId": "vF7AD7zSAj7SNvN3gr9N94",
|
||||
"content": {
|
||||
"html": "<div>We'll get back to you at {{Email}}</div>",
|
||||
"richText": [
|
||||
{
|
||||
"type": "p",
|
||||
"children": [{ "text": "We'll get back to you at {{Email}}" }]
|
||||
}
|
||||
],
|
||||
"plainText": "We'll get back to you at {{Email}}"
|
||||
},
|
||||
"outgoingEdgeId": "fTVo43AG97eKcaTrZf9KyV"
|
||||
}
|
||||
],
|
||||
"title": "Bye",
|
||||
"graphCoordinates": { "x": 1668, "y": 143 }
|
||||
},
|
||||
{
|
||||
"id": "webhookBlock",
|
||||
"graphCoordinates": { "x": 1996, "y": 134 },
|
||||
"title": "Webhook",
|
||||
"steps": [
|
||||
{
|
||||
"id": "webhookStep",
|
||||
"blockId": "webhookBlock",
|
||||
"type": "Webhook",
|
||||
"options": { "responseVariableMapping": [], "variablesForTest": [] },
|
||||
"webhook": {
|
||||
"id": "3zZp4961n6CeorWR43jdV9",
|
||||
"method": "GET",
|
||||
"headers": [],
|
||||
"queryParams": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"variables": [
|
||||
{ "id": "giiLFGw5xXBCHzvp1qAbdX", "name": "Name" },
|
||||
{ "id": "3VFChNVSCXQ2rXv4DrJ8Ah", "name": "Email" }
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "oNvqaqNExdSH2kKEhKZHuE",
|
||||
"to": { "blockId": "kinRXxYop2X4d7F9qt8WNB" },
|
||||
"from": {
|
||||
"stepId": "22HP69iipkLjJDTUcc1AWW",
|
||||
"blockId": "k6kY6gwRE6noPoYQNGzgUq"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "i51YhHpk1dtSyduFNf5Wim",
|
||||
"to": { "blockId": "q5dAhqSTCaNdiGSJm9B9Rw" },
|
||||
"from": {
|
||||
"stepId": "sbjZWLJGVkHAkDqS4JQeGow",
|
||||
"blockId": "kinRXxYop2X4d7F9qt8WNB"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "4tYbERpi5Po4goVgt6rWXg",
|
||||
"to": { "blockId": "o4SH1UtKANnW5N5D67oZUz" },
|
||||
"from": {
|
||||
"stepId": "sqEsMo747LTDnY9FjQcEwUv",
|
||||
"blockId": "q5dAhqSTCaNdiGSJm9B9Rw"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "w3MiN1Ct38jT5NykVsgmb5",
|
||||
"to": { "blockId": "fKqRz7iswk7ULaj5PJocZL" },
|
||||
"from": {
|
||||
"stepId": "snbsad18Bgry8yZ8DZCfdFD",
|
||||
"blockId": "o4SH1UtKANnW5N5D67oZUz"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "ohTRakmcYJ7GdFWRZrWRjk",
|
||||
"to": { "blockId": "7qHBEyCMvKEJryBHzPmHjV" },
|
||||
"from": {
|
||||
"stepId": "s5VQGsVF4hQgziQsXVdwPDW",
|
||||
"blockId": "fKqRz7iswk7ULaj5PJocZL"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sH5nUssG2XQbm6ZidGv9BY",
|
||||
"to": { "blockId": "vF7AD7zSAj7SNvN3gr9N94" },
|
||||
"from": {
|
||||
"stepId": "sqFy2G3C1mh9p6s3QBdSS5x",
|
||||
"blockId": "7qHBEyCMvKEJryBHzPmHjV"
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": {
|
||||
"blockId": "vF7AD7zSAj7SNvN3gr9N94",
|
||||
"stepId": "s779Q1y51aVaDUJVrFb16vv"
|
||||
},
|
||||
"to": { "blockId": "webhookBlock" },
|
||||
"id": "fTVo43AG97eKcaTrZf9KyV"
|
||||
}
|
||||
],
|
||||
"theme": {
|
||||
"chat": {
|
||||
"inputs": {
|
||||
"color": "#303235",
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"placeholderColor": "#9095A0"
|
||||
},
|
||||
"buttons": { "color": "#FFFFFF", "backgroundColor": "#0042DA" },
|
||||
"hostBubbles": { "color": "#303235", "backgroundColor": "#F7F8FF" },
|
||||
"guestBubbles": { "color": "#FFFFFF", "backgroundColor": "#FF8E21" }
|
||||
},
|
||||
"general": { "font": "Open Sans", "background": { "type": "None" } }
|
||||
},
|
||||
"settings": {
|
||||
"general": { "isBrandingEnabled": true },
|
||||
"metadata": {
|
||||
"description": "Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form."
|
||||
},
|
||||
"typingEmulation": { "speed": 300, "enabled": true, "maxDelay": 1.5 }
|
||||
},
|
||||
"publicId": null,
|
||||
"customDomain": null
|
||||
}
|
@ -1,28 +1,14 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import {
|
||||
createResults,
|
||||
createTypebots,
|
||||
parseDefaultBlockWithStep,
|
||||
} from '../services/database'
|
||||
import {
|
||||
IntegrationStepType,
|
||||
defaultWebhookOptions,
|
||||
defaultWebhookAttributes,
|
||||
} from 'models'
|
||||
import { createResults, importTypebotInDatabase } from '../services/database'
|
||||
import path from 'path'
|
||||
|
||||
const typebotId = 'webhook-flow'
|
||||
test.beforeAll(async () => {
|
||||
try {
|
||||
await createTypebots([
|
||||
{
|
||||
id: typebotId,
|
||||
...parseDefaultBlockWithStep({
|
||||
type: IntegrationStepType.WEBHOOK,
|
||||
options: defaultWebhookOptions,
|
||||
webhook: { id: 'webhookId', ...defaultWebhookAttributes },
|
||||
}),
|
||||
},
|
||||
])
|
||||
await importTypebotInDatabase(
|
||||
path.join(__dirname, '../fixtures/typebots/api.json'),
|
||||
{ id: typebotId }
|
||||
)
|
||||
await createResults({ typebotId })
|
||||
} catch (err) {}
|
||||
})
|
||||
@ -54,9 +40,9 @@ test('can get webhook steps', async ({ request }) => {
|
||||
const { steps } = await response.json()
|
||||
expect(steps).toHaveLength(1)
|
||||
expect(steps[0]).toEqual({
|
||||
id: 'step1',
|
||||
blockId: 'block1',
|
||||
name: 'Block #1 > step1',
|
||||
id: 'webhookStep',
|
||||
blockId: 'webhookBlock',
|
||||
name: 'Webhook > webhookStep',
|
||||
})
|
||||
})
|
||||
|
||||
@ -64,13 +50,13 @@ test('can subscribe webhook', async ({ request }) => {
|
||||
expect(
|
||||
(
|
||||
await request.patch(
|
||||
`/api/typebots/${typebotId}/blocks/block1/steps/step1/subscribeWebhook`,
|
||||
`/api/typebots/${typebotId}/blocks/webhookBlock/steps/webhookStep/subscribeWebhook`,
|
||||
{ data: { url: 'https://test.com' } }
|
||||
)
|
||||
).status()
|
||||
).toBe(401)
|
||||
const response = await request.patch(
|
||||
`/api/typebots/${typebotId}/blocks/block1/steps/step1/subscribeWebhook`,
|
||||
`/api/typebots/${typebotId}/blocks/webhookBlock/steps/webhookStep/subscribeWebhook`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: 'Bearer userToken',
|
||||
@ -88,12 +74,12 @@ test('can unsubscribe webhook', async ({ request }) => {
|
||||
expect(
|
||||
(
|
||||
await request.delete(
|
||||
`/api/typebots/${typebotId}/blocks/block1/steps/step1/unsubscribeWebhook`
|
||||
`/api/typebots/${typebotId}/blocks/webhookBlock/steps/webhookStep/unsubscribeWebhook`
|
||||
)
|
||||
).status()
|
||||
).toBe(401)
|
||||
const response = await request.delete(
|
||||
`/api/typebots/${typebotId}/blocks/block1/steps/step1/unsubscribeWebhook`,
|
||||
`/api/typebots/${typebotId}/blocks/webhookBlock/steps/webhookStep/unsubscribeWebhook`,
|
||||
{
|
||||
headers: { Authorization: 'Bearer userToken' },
|
||||
}
|
||||
@ -104,6 +90,31 @@ test('can unsubscribe webhook', async ({ request }) => {
|
||||
})
|
||||
})
|
||||
|
||||
test('can get a sample result', async ({ request }) => {
|
||||
expect(
|
||||
(
|
||||
await request.get(
|
||||
`/api/typebots/${typebotId}/blocks/webhookBlock/steps/webhookStep/sampleResult`
|
||||
)
|
||||
).status()
|
||||
).toBe(401)
|
||||
const response = await request.get(
|
||||
`/api/typebots/${typebotId}/blocks/webhookBlock/steps/webhookStep/sampleResult`,
|
||||
{
|
||||
headers: { Authorization: 'Bearer userToken' },
|
||||
}
|
||||
)
|
||||
const data = await response.json()
|
||||
expect(data).toMatchObject({
|
||||
message: 'This is a sample result, it has been generated ⬇️',
|
||||
Welcome: 'Item 1, Item 2, Item3',
|
||||
Email: 'test@email.com',
|
||||
Name: 'answer value',
|
||||
Services: 'Item 1, Item 2, Item3',
|
||||
'Additional information': 'answer value',
|
||||
})
|
||||
})
|
||||
|
||||
test('can list results', async ({ request }) => {
|
||||
expect(
|
||||
(await request.get(`/api/typebots/${typebotId}/results`)).status()
|
||||
@ -116,5 +127,4 @@ test('can list results', async ({ request }) => {
|
||||
)
|
||||
const { results } = await response.json()
|
||||
expect(results).toHaveLength(10)
|
||||
expect(results[0]).toMatchObject({ 'Block #1': 'content199' })
|
||||
})
|
||||
|
Reference in New Issue
Block a user