Skip to content

Commit 7f45b43

Browse files
author
Vidas P
committed
Fix short agent description parsing
We used to use the first line of agent description in the agent selection cards verbatim (as html_safe). Agent description (being markdown) can start with peculiar things: headers, paragraphs, images, links and even html comments. When you include it in the template as html_safe it breaks everything down the page. Now we find the first paragraph or header (h1, h2 or h3) and include its text stripped of any formatting.
1 parent 5388982 commit 7f45b43

File tree

3 files changed

+63
-12
lines changed

3 files changed

+63
-12
lines changed

app/helpers/agent_helper.rb

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,26 @@ def agent_type_icon(agent, agents)
8282
end
8383
end
8484

85-
def agent_type_select_options
86-
Rails.cache.fetch('agent_type_select_options') do
87-
[['Select an Agent Type', 'Agent', { title: '' }]] + Agent.types.map { |type| [agent_type_to_human(type), type, { title: h(Agent.build_for_type(type.name, User.new(id: 0), {}).html_description.lines.first.strip) }] }
88-
end
85+
def agent_short_description(agent)
86+
html = agent.html_description
87+
doc = Nokogiri::HTML::Document.parse(html)
88+
text = doc.xpath('(//*[self::h1 or self::h2 or self::h3 or self::p])[1]/descendant-or-self::*/text()').to_s
89+
return 'No description' if text.blank?
90+
text
8991
end
92+
module_function :agent_short_description
9093

9194
def agent_types
92-
Agent.types.map do |type|
93-
agent = Agent.build_for_type(type.name, User.new(id: 0), {})
94-
{
95-
type: type,
96-
name: agent_type_to_human(type),
97-
description: agent.html_description
98-
}
95+
Rails.cache.fetch('agent_types') do
96+
Agent.types.map do |type|
97+
agent = Agent.build_for_type(type.name, User.new(id: 0), {})
98+
{
99+
type: type,
100+
name: agent_type_to_human(type),
101+
short_description: agent_short_description(agent),
102+
description: agent.html_description
103+
}
104+
end
99105
end
100106
end
101107

app/views/agents/_form.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<%= type[:name] %>
3232
</div>
3333
<div class="card-body d-flex flex-column">
34-
<%= type[:description].lines.first.html_safe %>
34+
<p><%= type[:short_description] %></p>
3535
<button class="btn btn-primary select_agent_type align-self-end mt-auto"
3636
data-type="<%= type[:type] %>"
3737
data-name="<%= type[:name] %>">Create</button>

spec/helpers/agent_helper_spec.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require 'rails_helper'
2+
3+
describe AgentHelper do
4+
describe '#agent_short_description' do
5+
subject(:short_description) do
6+
AgentHelper.agent_short_description(agent)
7+
end
8+
9+
let(:agent) do
10+
Agent.new.tap do |a|
11+
stub(a).description { description }
12+
end
13+
end
14+
15+
context 'when description is simple text' do
16+
let(:description) { 'Good!' }
17+
it { is_expected.to eq 'Good!' }
18+
end
19+
20+
context 'When description is multi paragraph text' do
21+
let(:description) { "Good!\n\nLong text." }
22+
it { is_expected.to eq 'Good!' }
23+
end
24+
25+
context 'When description starts with header' do
26+
let(:description) { "# Good!\n\nLong text." }
27+
it { is_expected.to eq 'Good!' }
28+
end
29+
30+
context 'When description starts with h2' do
31+
let(:description) { "## Good!\n\nLong text." }
32+
it { is_expected.to eq 'Good!' }
33+
end
34+
35+
context 'When description starts with a comment' do
36+
let(:description) { "<!-- Comment -->\nGood!" }
37+
it { is_expected.to eq 'Good!' }
38+
end
39+
40+
context 'When description includes formatting/subtags' do
41+
let(:description) { "Good `agent` **here**!" }
42+
it { is_expected.to eq 'Good agent here!' }
43+
end
44+
end
45+
end

0 commit comments

Comments
 (0)