Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
155 changes: 155 additions & 0 deletions workspace-server/src/__tests__/services/DocsService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,161 @@ describe('DocsService', () => {
});
});

it('should extract text from smart chips (date, person, rich link)', async () => {
Comment thread
allenhutchison marked this conversation as resolved.
Outdated
const mockDoc = {
data: {
tabs: [
{
documentTab: {
body: {
content: [
{
paragraph: {
elements: [
{
textRun: { content: 'Meeting on ' },
},
{
dateElement: {
dateElementProperties: {
displayText: 'Jan 15, 2025',
timestamp: '1736899200',
},
},
},
{
textRun: { content: ' with ' },
},
{
person: {
personProperties: {
name: 'John Doe',
email: 'john@example.com',
},
},
},
{
textRun: { content: ' - see ' },
},
{
richLink: {
richLinkProperties: {
title: 'Project Plan',
uri: 'https://docs.google.com/document/d/abc123',
},
},
},
{
textRun: { content: '\n' },
},
],
},
},
],
},
},
},
],
},
};
mockDocsAPI.documents.get.mockResolvedValue(mockDoc);

const result = await docsService.getText({ documentId: 'test-doc-id' });

expect(result.content[0].text).toBe(
'Meeting on Jan 15, 2025 with [John Doe](mailto:john@example.com) - see [Project Plan](https://docs.google.com/document/d/abc123)\n',
);
});

it.each([
{
name: 'person without name falls back to email',
element: {
person: {
personProperties: {
email: 'jane@example.com',
},
},
},
expected: '[jane@example.com](mailto:jane@example.com)',
},
{
name: 'person without email falls back to name only',
element: {
person: {
personProperties: {
name: 'John Doe',
},
},
},
expected: 'John Doe',
},
{
name: 'rich link without title falls back to uri',
element: {
richLink: {
richLinkProperties: {
uri: 'https://docs.google.com/spreadsheets/d/xyz',
},
},
},
expected:
'[https://docs.google.com/spreadsheets/d/xyz](https://docs.google.com/spreadsheets/d/xyz)',
},
{
name: 'rich link without uri falls back to title only',
element: {
richLink: {
richLinkProperties: {
title: 'Some Document',
},
},
},
expected: 'Some Document',
},
{
name: 'date without displayText falls back to timestamp',
element: {
dateElement: {
dateElementProperties: {
timestamp: '1736899200',
},
},
},
expected: '1736899200',
},
])(
'should fall back correctly when $name',
async ({ element, expected }) => {
const mockDoc = {
data: {
tabs: [
{
documentTab: {
body: {
content: [
{
paragraph: {
elements: [element],
},
},
],
},
},
},
],
},
};
mockDocsAPI.documents.get.mockResolvedValue(mockDoc);

const result = await docsService.getText({
documentId: 'test-doc-id',
});

expect(result.content[0].text).toBe(expected);
},
);

it('should include text from nested child tabs', async () => {
const mockDoc = {
data: {
Expand Down
18 changes: 18 additions & 0 deletions workspace-server/src/services/DocsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,24 @@ export class DocsService {
element.paragraph.elements?.forEach((pElement) => {
if (pElement.textRun && pElement.textRun.content) {
text += pElement.textRun.content;
} else if (pElement.person?.personProperties) {
Comment thread
allenhutchison marked this conversation as resolved.
const { name, email } = pElement.person.personProperties;
if (email) {
text += `[${name || email}](mailto:${email})`;
} else if (name) {
text += name;
}
} else if (pElement.richLink?.richLinkProperties) {
const { title, uri } = pElement.richLink.richLinkProperties;
if (uri) {
text += `[${title || uri}](${uri})`;
} else if (title) {
text += title;
}
} else if (pElement.dateElement?.dateElementProperties) {
const { displayText, timestamp } =
pElement.dateElement.dateElementProperties;
text += displayText || timestamp || '';
}
});
} else if (element.table) {
Expand Down
Loading