diff --git a/projects/aca-content/src/lib/components/search/search-results-row/search-results-row.component.spec.ts b/projects/aca-content/src/lib/components/search/search-results-row/search-results-row.component.spec.ts
index 7e5d0c180..146c1c372 100644
--- a/projects/aca-content/src/lib/components/search/search-results-row/search-results-row.component.spec.ts
+++ b/projects/aca-content/src/lib/components/search/search-results-row/search-results-row.component.spec.ts
@@ -133,8 +133,82 @@ describe('SearchResultsRowComponent', () => {
it('should pass node to badge component', () => {
component.context = { row: { node: nodeEntry } };
+ fixture.detectChanges();
+
const badgeElement = fixture.debugElement.query(By.css('aca-datatable-cell-badges'));
expect(badgeElement).not.toBe(null);
- expect(badgeElement.componentInstance.node).toBe(component.context.node);
+ expect(badgeElement.componentInstance.node).toBe(component.context.row.node);
+ });
+
+ it('should escape plain < and > in values', (done) => {
+ const customEntry: ResultSetRowEntry = {
+ entry: {
+ ...nodeEntry.entry,
+ name: '2 < 5 > 3',
+ search: { score: 5 }
+ }
+ } as ResultSetRowEntry;
+
+ component.context = { row: { node: customEntry } };
+ component.name$
+ .asObservable()
+ .pipe(first())
+ .subscribe(() => {
+ fixture.detectChanges();
+
+ const nameElement: HTMLSpanElement = fixture.debugElement.query(By.css('.aca-link.aca-crop-text')).nativeElement;
+ expect(nameElement.innerHTML).toBe('2 < 5 > 3');
+ expect(nameElement.textContent).toBe('2 < 5 > 3');
+ done();
+ });
+ fixture.detectChanges();
+ });
+
+ it('should not render script tags as HTML', (done) => {
+ const customEntry: ResultSetRowEntry = {
+ entry: {
+ ...nodeEntry.entry,
+ name: '',
+ search: { score: 5 }
+ }
+ } as ResultSetRowEntry;
+
+ component.context = { row: { node: customEntry } };
+ component.name$
+ .asObservable()
+ .pipe(first())
+ .subscribe(() => {
+ fixture.detectChanges();
+
+ const nameElement: HTMLSpanElement = fixture.debugElement.query(By.css('.aca-link.aca-crop-text')).nativeElement;
+ expect(nameElement.innerHTML).toContain('<script>alert("xss")</script>');
+ expect(nameElement.textContent).toBe('');
+ done();
+ });
+ fixture.detectChanges();
+ });
+
+ it('should allow highlight spans but escape other tags', (done) => {
+ const customEntry: ResultSetRowEntry = {
+ entry: {
+ ...nodeEntry.entry,
+ name: 'BoldHighlight',
+ search: { score: 5 }
+ }
+ } as ResultSetRowEntry;
+
+ component.context = { row: { node: customEntry } };
+ component.name$
+ .asObservable()
+ .pipe(first())
+ .subscribe(() => {
+ fixture.detectChanges();
+
+ const nameElement: HTMLSpanElement = fixture.debugElement.query(By.css('.aca-link.aca-crop-text')).nativeElement;
+ expect(nameElement.innerHTML).toBe('<b>BoldHighlight</b>');
+ expect(nameElement.textContent).toBe('BoldHighlight');
+ done();
+ });
+ fixture.detectChanges();
});
});