mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
fix(shared-barcode, crm-customer-card): improve barcode rendering with transparent SVG background Enhance barcode component flexibility by separating container and SVG background colors. The SVG barcode now defaults to transparent background while maintaining container background control, enabling better integration with various card designs. Changes: - Add separate svgBackground input for SVG element (default: transparent) - Keep background input for container styling (default: #ffffff) - Add containerWidth and containerHeight inputs for flexible sizing - Update customer card to remove explicit white background on barcode - Add opacity styling for inactive customer cards - Enhance test coverage for new background and sizing inputs The separation of concerns allows the barcode to adapt to parent container backgrounds while maintaining consistent rendering across different contexts. Ref: #5498
254 lines
7.1 KiB
TypeScript
254 lines
7.1 KiB
TypeScript
import { Component } from '@angular/core';
|
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { BarcodeDirective } from './barcode.directive';
|
|
|
|
// Mock JsBarcode
|
|
vi.mock('jsbarcode', () => ({
|
|
default: vi.fn((element, value, options) => {
|
|
// Simulate JsBarcode by adding a rect element to the SVG
|
|
if (element && element.tagName === 'svg') {
|
|
const rect = document.createElementNS(
|
|
'http://www.w3.org/2000/svg',
|
|
'rect',
|
|
);
|
|
rect.setAttribute('data-value', value);
|
|
rect.setAttribute('data-format', options?.format || 'CODE128');
|
|
element.appendChild(rect);
|
|
|
|
// Call valid callback if provided
|
|
if (options?.valid) {
|
|
const isValid = value && value.length > 0;
|
|
options.valid(isValid);
|
|
}
|
|
}
|
|
}),
|
|
}));
|
|
|
|
@Component({
|
|
standalone: true,
|
|
imports: [BarcodeDirective],
|
|
template: `
|
|
<svg
|
|
sharedBarcode
|
|
[value]="barcodeValue"
|
|
[format]="format"
|
|
[width]="width"
|
|
[height]="height"
|
|
[displayValue]="displayValue"
|
|
></svg>
|
|
`,
|
|
})
|
|
class TestHostComponent {
|
|
barcodeValue = '123456789';
|
|
format = 'CODE128';
|
|
width = 2;
|
|
height = 100;
|
|
displayValue = true;
|
|
}
|
|
|
|
describe('BarcodeDirective', () => {
|
|
let fixture: ComponentFixture<TestHostComponent>;
|
|
let component: TestHostComponent;
|
|
let svgElement: SVGElement;
|
|
|
|
beforeEach(async () => {
|
|
await TestBed.configureTestingModule({
|
|
imports: [TestHostComponent],
|
|
}).compileComponents();
|
|
|
|
fixture = TestBed.createComponent(TestHostComponent);
|
|
component = fixture.componentInstance;
|
|
svgElement = fixture.nativeElement.querySelector('svg');
|
|
fixture.detectChanges();
|
|
});
|
|
|
|
describe('Initialization', () => {
|
|
it('should create the directive', () => {
|
|
expect(component).toBeTruthy();
|
|
});
|
|
|
|
it('should apply to SVG element', () => {
|
|
expect(svgElement).toBeTruthy();
|
|
expect(svgElement.tagName).toBe('svg');
|
|
});
|
|
|
|
it('should render barcode on initialization', () => {
|
|
// JsBarcode adds child elements to the SVG
|
|
expect(svgElement.children.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('Barcode Rendering', () => {
|
|
it('should render barcode with default CODE128 format', () => {
|
|
const rect = svgElement.querySelector('rect');
|
|
expect(rect).toBeTruthy();
|
|
});
|
|
|
|
it('should render barcode with custom value', () => {
|
|
component.barcodeValue = '987654321';
|
|
fixture.detectChanges();
|
|
|
|
// SVG should be updated with new value
|
|
expect(svgElement.children.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should update barcode when value changes', () => {
|
|
component.barcodeValue = 'NEWVALUE123';
|
|
fixture.detectChanges();
|
|
|
|
// Barcode should be re-rendered (may have different number of bars)
|
|
expect(svgElement.children.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should render with custom width', () => {
|
|
component.width = 4;
|
|
fixture.detectChanges();
|
|
|
|
expect(svgElement.children.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should render with custom height', () => {
|
|
component.height = 200;
|
|
fixture.detectChanges();
|
|
|
|
const rect = svgElement.querySelector('rect');
|
|
expect(rect).toBeTruthy();
|
|
});
|
|
|
|
it('should render without display value when disabled', () => {
|
|
component.displayValue = false;
|
|
fixture.detectChanges();
|
|
|
|
// Check that SVG is still rendered
|
|
expect(svgElement.children.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('Input Changes', () => {
|
|
it('should re-render when format changes', () => {
|
|
component.format = 'CODE128';
|
|
fixture.detectChanges();
|
|
|
|
expect(svgElement.children.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should handle multiple rapid value changes', () => {
|
|
component.barcodeValue = 'VALUE1';
|
|
fixture.detectChanges();
|
|
|
|
component.barcodeValue = 'VALUE2';
|
|
fixture.detectChanges();
|
|
|
|
component.barcodeValue = 'VALUE3';
|
|
fixture.detectChanges();
|
|
|
|
expect(svgElement.children.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('Error Handling', () => {
|
|
it('should handle empty value gracefully', () => {
|
|
// JsBarcode should handle this or log warning
|
|
component.barcodeValue = '';
|
|
fixture.detectChanges();
|
|
|
|
// Directive should not crash
|
|
expect(component).toBeTruthy();
|
|
});
|
|
|
|
it('should handle very long values', () => {
|
|
component.barcodeValue = '1'.repeat(100);
|
|
fixture.detectChanges();
|
|
|
|
expect(svgElement.children.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('Customization Options', () => {
|
|
it('should render with custom line color', () => {
|
|
@Component({
|
|
standalone: true,
|
|
imports: [BarcodeDirective],
|
|
template: `
|
|
<svg sharedBarcode [value]="'123456'" [lineColor]="'#FF0000'"></svg>
|
|
`,
|
|
})
|
|
class ColorTestComponent {}
|
|
|
|
const colorFixture = TestBed.createComponent(ColorTestComponent);
|
|
colorFixture.detectChanges();
|
|
|
|
const svg = colorFixture.nativeElement.querySelector('svg');
|
|
expect(svg).toBeTruthy();
|
|
expect(svg.children.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should render with custom background', () => {
|
|
@Component({
|
|
standalone: true,
|
|
imports: [BarcodeDirective],
|
|
template: `
|
|
<svg sharedBarcode [value]="'123456'" [background]="'#F0F0F0'"></svg>
|
|
`,
|
|
})
|
|
class BackgroundTestComponent {}
|
|
|
|
const bgFixture = TestBed.createComponent(BackgroundTestComponent);
|
|
bgFixture.detectChanges();
|
|
|
|
const svg = bgFixture.nativeElement.querySelector('svg');
|
|
expect(svg).toBeTruthy();
|
|
});
|
|
|
|
it('should render with transparent background by default', () => {
|
|
@Component({
|
|
standalone: true,
|
|
imports: [BarcodeDirective],
|
|
template: ` <svg sharedBarcode [value]="'123456'"></svg> `,
|
|
})
|
|
class DefaultBackgroundTestComponent {}
|
|
|
|
const bgFixture = TestBed.createComponent(DefaultBackgroundTestComponent);
|
|
bgFixture.detectChanges();
|
|
|
|
const svg = bgFixture.nativeElement.querySelector('svg');
|
|
expect(svg).toBeTruthy();
|
|
});
|
|
|
|
it('should render with custom font size', () => {
|
|
@Component({
|
|
standalone: true,
|
|
imports: [BarcodeDirective],
|
|
template: `
|
|
<svg sharedBarcode [value]="'123456'" [fontSize]="30"></svg>
|
|
`,
|
|
})
|
|
class FontSizeTestComponent {}
|
|
|
|
const fontFixture = TestBed.createComponent(FontSizeTestComponent);
|
|
fontFixture.detectChanges();
|
|
|
|
const svg = fontFixture.nativeElement.querySelector('svg');
|
|
expect(svg).toBeTruthy();
|
|
});
|
|
|
|
it('should render with custom margin', () => {
|
|
@Component({
|
|
standalone: true,
|
|
imports: [BarcodeDirective],
|
|
template: `
|
|
<svg sharedBarcode [value]="'123456'" [margin]="20"></svg>
|
|
`,
|
|
})
|
|
class MarginTestComponent {}
|
|
|
|
const marginFixture = TestBed.createComponent(MarginTestComponent);
|
|
marginFixture.detectChanges();
|
|
|
|
const svg = marginFixture.nativeElement.querySelector('svg');
|
|
expect(svg).toBeTruthy();
|
|
});
|
|
});
|
|
});
|