Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 12 additions & 1 deletion includes/Experiments/Summarization/Summarization.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,22 @@ public function enqueue_assets( string $hook_suffix ): void {
}

Asset_Loader::enqueue_script( 'summarization', 'experiments/summarization' );

/**
* Filters the minimum content length required to enable summarization.
*
* @since x.x.x
*
* @param int $min_content_length The minimum number of characters required. Default 100.
*/
$min_content_length = (int) apply_filters( 'wpai_summarization_min_content_length', 100 );

Asset_Loader::localize_script(
'summarization',
'SummarizationData',
array(
'enabled' => $this->is_enabled(),
'enabled' => $this->is_enabled(),
'minContentLength' => $min_content_length,
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const { aiSummarizationData } = window as any;
* Block controls component.
*/
const Controls = () => {
const { isSummarizing, hasSummary, handleSummarize } =
const { isSummarizing, hasSummary, handleSummarize, isContentTooShort } =
useSummaryGeneration();
let buttonLabel: string = __( 'Generate Summary', 'ai' );

Expand All @@ -46,7 +46,7 @@ const Controls = () => {
icon={ update }
className="ai-summarization-block-controls-button"
onClick={ handleSummarize }
disabled={ isSummarizing }
disabled={ isSummarizing || isContentTooShort }
isBusy={ isSummarizing }
/>
</ToolbarGroup>
Expand Down
45 changes: 33 additions & 12 deletions src/experiments/summarization/components/SummarizationPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { Button, Flex, FlexItem } from '@wordpress/components';
import { PluginPostStatusInfo } from '@wordpress/editor';
import { __ } from '@wordpress/i18n';
import { __, sprintf } from '@wordpress/i18n';
import { update } from '@wordpress/icons';

/**
Expand All @@ -21,8 +21,13 @@ const { aiSummarizationData } = window as any;
* Summarization plugin component.
*/
export default function SummarizationPlugin() {
const { isSummarizing, hasSummary, handleSummarize } =
useSummaryGeneration();
const {
isSummarizing,
hasSummary,
handleSummarize,
isContentTooShort,
minContentLength,
} = useSummaryGeneration();

let buttonLabel: string = __( 'Generate Summary', 'ai' );

Expand All @@ -31,15 +36,31 @@ export default function SummarizationPlugin() {
} else if ( hasSummary ) {
buttonLabel = __( 'Regenerate Summary', 'ai' );
}
const buttonDescription = hasSummary
? __(
'This will update the generated summary block with a new summary of the content of this post.',
'ai'
)
: __(
'This will create a block that is a summary of the content of this post.',

const isDisabled = isSummarizing || isContentTooShort;

let buttonDescription: string;

if ( isContentTooShort ) {
buttonDescription = sprintf(
/* translators: %d: minimum number of characters required */
__(
'Summarization will be available when the post content has at least %d characters.',
'ai'
);
),
minContentLength
);
} else if ( hasSummary ) {
buttonDescription = __(
'This will update the generated summary block with a new summary of the content of this post.',
'ai'
);
} else {
buttonDescription = __(
'This will create a block that is a summary of the content of this post.',
'ai'
);
}

// Don't render if disabled.
if ( ! aiSummarizationData?.enabled ) {
Expand All @@ -60,7 +81,7 @@ export default function SummarizationPlugin() {
label={ buttonLabel }
icon={ update }
onClick={ handleSummarize }
disabled={ isSummarizing }
disabled={ isDisabled }
isBusy={ isSummarizing }
__next40pxDefaultSize
>
Expand Down
11 changes: 11 additions & 0 deletions src/experiments/summarization/functions/useSummaryGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { store as noticesStore } from '@wordpress/notices';
* Internal dependencies
*/
import { generateSummary } from './generate-summary';
import { count } from '@wordpress/wordcount';

const { aiSummarizationData } = window as any;

/**
* Summary generation hook.
Expand Down Expand Up @@ -117,10 +120,18 @@ export function useSummaryGeneration() {
}
};

// Minimum content length required for summarization.
const minContentLength: number =
aiSummarizationData?.minContentLength ?? 100;
const isContentTooShort =
count( content, 'characters_including_spaces' ) < minContentLength;

return {
isSummarizing,
hasSummary: summary && summary.trim().length > 0,
summary,
handleSummarize,
isContentTooShort,
minContentLength,
};
}
81 changes: 79 additions & 2 deletions tests/e2e/specs/experiments/content-summarization.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ test.describe( 'Content Summarization Experiment', () => {
// Enable the Content Summarization Experiment.
await enableExperiment( admin, page, 'Content Summarization' );

// Create a new post.
// Create a new post with content that meets the minimum length requirement (>= 100 chars).
await admin.createNewPost( {
postType: 'post',
title: 'Test Content Summarization Experiment',
content:
'This is some test content for the Content Summarization Experiment.',
'This is some test content for the Content Summarization Experiment. It needs to be at least one hundred characters long.',
} );

// Save the post.
Expand Down Expand Up @@ -121,6 +121,83 @@ test.describe( 'Content Summarization Experiment', () => {
).not.toBeVisible();
} );

test( 'Summarize button is disabled when content is shorter than the minimum length', async ( {
admin,
editor,
page,
} ) => {
// Globally turn on Experiments.
await enableExperiments( admin, page );

// Enable the Content Summarization Experiment.
await enableExperiment( admin, page, 'Content Summarization' );

// Create a new post with content shorter than 100 characters.
await admin.createNewPost( {
postType: 'post',
title: 'Test Short Content',
content: 'Too short.',
} );

// Save the post.
await editor.saveDraft();

// Ensure the sidebar is visible.
await editor.openDocumentSettingsSidebar();

const generateButton = page.locator(
'.ai-summarization-plugin-container button'
);

// Button should be visible but disabled.
await expect( generateButton ).toBeVisible();
await expect( generateButton ).toBeDisabled();

// The descriptive text should explain when the button will be enabled.
await expect(
page.locator( '.ai-summarization-plugin-container .description' )
).toContainText( '100 characters' );
} );

test( 'Summarize button is enabled when content meets the minimum length', async ( {
admin,
editor,
page,
} ) => {
// Globally turn on Experiments.
await enableExperiments( admin, page );

// Enable the Content Summarization Experiment.
await enableExperiment( admin, page, 'Content Summarization' );

// Create a new post with content that is at least 100 characters.
await admin.createNewPost( {
postType: 'post',
title: 'Test Sufficient Content',
content:
'This post has enough content to meet the minimum character requirement for the summarization feature to be enabled.',
} );

// Save the post.
await editor.saveDraft();

// Ensure the sidebar is visible.
await editor.openDocumentSettingsSidebar();

const generateButton = page.locator(
'.ai-summarization-plugin-container button'
);

// Button should be visible and enabled.
await expect( generateButton ).toBeVisible();
await expect( generateButton ).toBeEnabled();

// The descriptive text should NOT mention the minimum character requirement.
await expect(
page.locator( '.ai-summarization-plugin-container .description' )
).not.toContainText( 'characters' );
} );

test( 'Ensure the Content Summarization Experiment UI is not visible when the experiment is disabled', async ( {
admin,
editor,
Expand Down
Loading