mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
feature(ui-modal): add QR code display for URLs in dialog modals Add automatic URL detection and QR code rendering in dialog modals: - Parse dialog content to extract URLs (http/https) - Display extracted URLs as QR codes using angularx-qrcode library - Split content around URL to show text before and after the QR code - Auto-detect URLs by default, with optional showUrlAsQrCode override - Add comprehensive unit tests for URL parsing helpers Ref: #5511
153 lines
4.6 KiB
TypeScript
153 lines
4.6 KiB
TypeScript
import { contentHasUrl, parseDialogContentForUrl } from './dialog.helper';
|
|
import { ParsedDialogContent } from './dialog.model';
|
|
|
|
describe('parseDialogContentForUrl', () => {
|
|
it('should return empty result for undefined content', () => {
|
|
const result = parseDialogContentForUrl(undefined);
|
|
|
|
expect(result).toEqual<ParsedDialogContent>({
|
|
textBefore: '',
|
|
url: null,
|
|
textAfter: '',
|
|
});
|
|
});
|
|
|
|
it('should return empty result for empty string', () => {
|
|
const result = parseDialogContentForUrl('');
|
|
|
|
expect(result).toEqual<ParsedDialogContent>({
|
|
textBefore: '',
|
|
url: null,
|
|
textAfter: '',
|
|
});
|
|
});
|
|
|
|
it('should return content as textBefore when no URL is found', () => {
|
|
const content = 'This is some text without a URL';
|
|
|
|
const result = parseDialogContentForUrl(content);
|
|
|
|
expect(result).toEqual<ParsedDialogContent>({
|
|
textBefore: content,
|
|
url: null,
|
|
textAfter: '',
|
|
});
|
|
});
|
|
|
|
it('should extract https URL from content', () => {
|
|
const content = 'Text before https://example.com text after';
|
|
|
|
const result = parseDialogContentForUrl(content);
|
|
|
|
expect(result).toEqual<ParsedDialogContent>({
|
|
textBefore: 'Text before',
|
|
url: 'https://example.com',
|
|
textAfter: 'text after',
|
|
});
|
|
});
|
|
|
|
it('should extract http URL from content', () => {
|
|
const content = 'Text before http://example.com text after';
|
|
|
|
const result = parseDialogContentForUrl(content);
|
|
|
|
expect(result).toEqual<ParsedDialogContent>({
|
|
textBefore: 'Text before',
|
|
url: 'http://example.com',
|
|
textAfter: 'text after',
|
|
});
|
|
});
|
|
|
|
it('should handle URL at the beginning of content', () => {
|
|
const content = 'https://example.com/path text after';
|
|
|
|
const result = parseDialogContentForUrl(content);
|
|
|
|
expect(result).toEqual<ParsedDialogContent>({
|
|
textBefore: '',
|
|
url: 'https://example.com/path',
|
|
textAfter: 'text after',
|
|
});
|
|
});
|
|
|
|
it('should handle URL at the end of content', () => {
|
|
const content = 'Text before https://example.com/path';
|
|
|
|
const result = parseDialogContentForUrl(content);
|
|
|
|
expect(result).toEqual<ParsedDialogContent>({
|
|
textBefore: 'Text before',
|
|
url: 'https://example.com/path',
|
|
textAfter: '',
|
|
});
|
|
});
|
|
|
|
it('should handle real-world content with newlines', () => {
|
|
const content = `Punkte: 80500
|
|
Um alle Vorteile der Kundenkarte nutzen zu können, ist eine Verknüpfung zu einem Online-Konto notwendig. Kund:innen können sich über den QR-Code selbstständig anmelden oder die Kundenkarte dem bestehendem Konto hinzufügen. Bereits gesammelte Punkte werden übernommen.
|
|
https://h-k.me/QOHNTFVA`;
|
|
|
|
const result = parseDialogContentForUrl(content);
|
|
|
|
expect(result.url).toBe('https://h-k.me/QOHNTFVA');
|
|
expect(result.textBefore).toContain('Punkte: 80500');
|
|
expect(result.textBefore).toContain(
|
|
'Bereits gesammelte Punkte werden übernommen.',
|
|
);
|
|
expect(result.textAfter).toBe('');
|
|
});
|
|
|
|
it('should extract only the first URL when multiple URLs are present', () => {
|
|
const content = 'First https://first.com then https://second.com';
|
|
|
|
const result = parseDialogContentForUrl(content);
|
|
|
|
expect(result).toEqual<ParsedDialogContent>({
|
|
textBefore: 'First',
|
|
url: 'https://first.com',
|
|
textAfter: 'then https://second.com',
|
|
});
|
|
});
|
|
|
|
it('should handle URLs with paths and query parameters', () => {
|
|
const content =
|
|
'Visit https://example.com/path?query=value&foo=bar for more';
|
|
|
|
const result = parseDialogContentForUrl(content);
|
|
|
|
expect(result.url).toBe('https://example.com/path?query=value&foo=bar');
|
|
expect(result.textBefore).toBe('Visit');
|
|
expect(result.textAfter).toBe('for more');
|
|
});
|
|
});
|
|
|
|
describe('contentHasUrl', () => {
|
|
it('should return false for undefined content', () => {
|
|
expect(contentHasUrl(undefined)).toBe(false);
|
|
});
|
|
|
|
it('should return false for empty string', () => {
|
|
expect(contentHasUrl('')).toBe(false);
|
|
});
|
|
|
|
it('should return false for content without URL', () => {
|
|
expect(contentHasUrl('This is text without a URL')).toBe(false);
|
|
});
|
|
|
|
it('should return true for content with https URL', () => {
|
|
expect(contentHasUrl('Check out https://example.com')).toBe(true);
|
|
});
|
|
|
|
it('should return true for content with http URL', () => {
|
|
expect(contentHasUrl('Check out http://example.com')).toBe(true);
|
|
});
|
|
|
|
it('should return true for real-world content', () => {
|
|
const content = `Punkte: 80500
|
|
Um alle Vorteile der Kundenkarte nutzen zu können...
|
|
https://h-k.me/QOHNTFVA`;
|
|
|
|
expect(contentHasUrl(content)).toBe(true);
|
|
});
|
|
});
|