Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tloncorp/api",
"version": "0.0.6",
"version": "0.0.8",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0.0.7 was published but the version bump wasn't committed

"type": "module",
"files": [
"dist",
Expand Down
163 changes: 163 additions & 0 deletions packages/api/src/__tests__/a2ui.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import { describe, expect, test } from 'vitest';

import { A2UI } from '../client/a2ui';
import { appendToPostBlob, parsePostBlob } from '../client/content-helpers';

const a2uiBlobEntry: A2UI.BlobEntry = {
type: 'a2ui',
version: 1,
messages: [
{
version: 'v0.9',
createSurface: {
surfaceId: 'weather-card',
catalogId: 'tlon.a2ui.basic.v1',
},
},
{
version: 'v0.9',
updateComponents: {
surfaceId: 'weather-card',
root: 'root',
components: [
{ id: 'root', component: 'Card', child: 'body' },
{
id: 'body',
component: 'Column',
children: ['title', 'summary', 'refreshButton'],
},
{ id: 'title', component: 'Text', text: 'Weather' },
{ id: 'summary', component: 'Text', text: '72F and clear' },
{
id: 'refreshButton',
component: 'Button',
child: 'refreshLabel',
action: {
event: {
name: 'tlon.sendMessage',
context: { text: 'refresh weather' },
},
},
},
{ id: 'refreshLabel', component: 'Text', text: 'Refresh' },
],
},
},
],
};

describe('a2ui blob entries', () => {
test('validates supported a2ui payloads', () => {
expect(A2UI.validateBlobEntry(a2uiBlobEntry)).toBe(true);
});

test('parsePostBlob parses supported a2ui entries', () => {
const blob = appendToPostBlob(undefined, a2uiBlobEntry);

expect(parsePostBlob(blob)).toEqual([a2uiBlobEntry]);
});

test('rejects unsupported a2ui components and actions', () => {
expect(
parsePostBlob(
JSON.stringify([
{
...a2uiBlobEntry,
messages: [
a2uiBlobEntry.messages[0],
{
version: 'v0.9',
updateComponents: {
surfaceId: 'weather-card',
components: [
{ id: 'root', component: 'Badge', text: 'unsupported' },
],
},
},
],
},
{
...a2uiBlobEntry,
messages: [
a2uiBlobEntry.messages[0],
{
version: 'v0.9',
updateComponents: {
surfaceId: 'weather-card',
components: [
{ id: 'root', component: 'Button', child: 'label' },
{ id: 'label', component: 'Text', text: 'Call function' },
],
},
},
],
},
])
)
).toEqual([{ type: 'unknown' }, { type: 'unknown' }]);
});

test('rejects malformed a2ui button optional fields', () => {
expect(
A2UI.validateBlobEntry({
...a2uiBlobEntry,
messages: [
a2uiBlobEntry.messages[0],
{
version: 'v0.9',
updateComponents: {
surfaceId: 'weather-card',
root: 'root',
components: [
{
id: 'root',
component: 'Button',
child: 'label',
disabled: 'false',
action: {
event: {
name: 'tlon.sendMessage',
context: { text: 'refresh weather' },
},
},
},
{ id: 'label', component: 'Text', text: 'Refresh' },
],
},
},
],
})
).toBe(false);

expect(
A2UI.validateBlobEntry({
...a2uiBlobEntry,
messages: [
a2uiBlobEntry.messages[0],
{
version: 'v0.9',
updateComponents: {
surfaceId: 'weather-card',
root: 'root',
components: [
{
id: 'root',
component: 'Button',
child: 'label',
variant: 'danger',
action: {
event: {
name: 'tlon.sendMessage',
context: { text: 'refresh weather' },
},
},
},
{ id: 'label', component: 'Text', text: 'Refresh' },
],
},
},
],
})
).toBe(false);
});
});
39 changes: 39 additions & 0 deletions packages/api/src/__tests__/postContent.a2ui.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { expect, test } from 'vitest';

import { convertContent } from '../client/postContent';

test('convertContent renders supported a2ui blob entries before story content', () => {
const a2ui = {
type: 'a2ui',
version: 1,
messages: [
{
version: 'v0.9',
createSurface: {
surfaceId: 'approval-card',
catalogId: 'tlon.a2ui.basic.v1',
},
},
{
version: 'v0.9',
updateComponents: {
surfaceId: 'approval-card',
root: 'root',
components: [
{ id: 'root', component: 'Card', child: 'body' },
{ id: 'body', component: 'Column', children: ['title'] },
{ id: 'title', component: 'Text', text: 'Approve DM?' },
],
},
},
],
};

const content = convertContent(
[{ inline: ['Fallback text'] }],
JSON.stringify([a2ui])
);

expect(content[0]).toEqual({ type: 'a2ui', a2ui });
expect(content[1]).toMatchObject({ type: 'paragraph' });
});
Loading
Loading