Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit 963edea

Browse files
committed
add spec
1 parent b3bd933 commit 963edea

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# frozen_string_literal: true
2+
3+
Rspec.describe DiscourseAi::Utils::DiffUtils::SafetyChecker do
4+
subject { described_class }
5+
6+
describe ".safe_to_stream?" do
7+
it "returns the result of instance safe? method" do
8+
expect(subject.safe_to_stream?("text")).to eq(subject.new("text").safe?)
9+
end
10+
end
11+
12+
describe "#safe?" do
13+
subject { subject.new(text).safe? }
14+
15+
context "with safe text" do
16+
let(:text) { "This is completely normal text with no issues." }
17+
it { is_expected.to eq(true) }
18+
19+
context "with complete markdown constructs" do
20+
let(:text) { "This has [a link](https://example.com) and **bold** and *italic* text." }
21+
it { is_expected.to eq(true) }
22+
end
23+
24+
context "with complete HTML tags" do
25+
let(:text) { "This has <strong>bold</strong> and <em>italic</em> text." }
26+
it { is_expected.to eq(true) }
27+
end
28+
29+
context "with complete code blocks" do
30+
let(:text) { "Code block: ```ruby\ndef method\nend\n```" }
31+
it { is_expected.to eq(true) }
32+
end
33+
34+
context "with complete emoji" do
35+
let(:text) { "I love this :heart: emoji" }
36+
it { is_expected.to eq(true) }
37+
end
38+
39+
context "with complete quote blocks" do
40+
let(:text) { "Here's a quote: [quote]Something smart[/quote]" }
41+
it { is_expected.to eq(true) }
42+
end
43+
end
44+
45+
context "with unclosed markdown links" do
46+
let(:text) { "This has [a link(" }
47+
it { is_expected.to eq(false) }
48+
49+
context "with open bracket but no close bracket" do
50+
let(:text) { "This has [a link but missing closing bracket" }
51+
it { is_expected.to eq(false) }
52+
end
53+
54+
context "with missing closing parenthesis" do
55+
let(:text) { "This has [a link](https://example.com" }
56+
it { is_expected.to eq(false) }
57+
end
58+
end
59+
60+
context "with unclosed raw HTML tags" do
61+
let(:text) { "This has <strong>bold text" }
62+
it { is_expected.to eq(false) }
63+
64+
context "with just opening tag" do
65+
let(:text) { "This ends with <div" }
66+
it { is_expected.to eq(false) }
67+
end
68+
end
69+
70+
context "with trailing incomplete URLs" do
71+
let(:text) { "Check out this link https://example" }
72+
it { is_expected.to eq(false) }
73+
74+
context "when complete URL ending with punctuation is fine" do
75+
let(:text) { "Check out this link (https://example.com)." }
76+
it { is_expected.to eq(true) }
77+
end
78+
end
79+
80+
context "with unclosed backticks" do
81+
let(:text) { "This has `code that doesn't close" }
82+
it { is_expected.to eq(false) }
83+
end
84+
85+
context "with unbalanced bold or italic" do
86+
let(:text) { "This has **bold text but missing closing" }
87+
it { is_expected.to eq(false) }
88+
89+
context "with odd number of asterisks" do
90+
let(:text) { "This has *italic text but missing closing" }
91+
it { is_expected.to eq(false) }
92+
end
93+
94+
context "with odd number of underscores" do
95+
let(:text) { "This has _italic text but missing closing" }
96+
it { is_expected.to eq(false) }
97+
end
98+
end
99+
100+
context "with incomplete image markdown" do
101+
let(:text) { "This has an image ![alt text](https://example.com/image" }
102+
it { is_expected.to eq(false) }
103+
end
104+
105+
context "with unbalanced quote blocks" do
106+
let(:text) { "This has [quote]a quote but no closing tag" }
107+
it { is_expected.to eq(false) }
108+
109+
context "with attributed quotes" do
110+
let(:text) { "This has [quote=User]a quote but no closing tag" }
111+
it { is_expected.to eq(false) }
112+
end
113+
114+
context "when balanced is fine" do
115+
let(:text) { "This has [quote]a quote[/quote] that closes properly" }
116+
it { is_expected.to eq(true) }
117+
end
118+
end
119+
120+
context "with unclosed triple backticks" do
121+
let(:text) { "This has ```a code block but no closing" }
122+
it { is_expected.to eq(false) }
123+
end
124+
125+
context "with partial emoji" do
126+
let(:text) { "This has a partial :heart emoji" }
127+
it { is_expected.to eq(false) }
128+
129+
context "with just the opening colon" do
130+
let(:text) { "This has a : that could start an emoji" }
131+
it { is_expected.to eq(true) } # This should be safe as it's just a colon
132+
end
133+
134+
context "with emoji-like construct" do
135+
let(:text) { "This has a :something. at the end" }
136+
it { is_expected.to eq(false) }
137+
end
138+
end
139+
140+
context "with HTML that needs sanitizing" do
141+
let(:text) { "<span>This text has HTML tags</span> but is otherwise safe" }
142+
it { is_expected.to eq(true) }
143+
144+
context "with escaped HTML entities" do
145+
let(:text) { "This text has &lt;tags&gt; as entities" }
146+
it { is_expected.to eq(true) }
147+
end
148+
end
149+
end
150+
end

0 commit comments

Comments
 (0)