import { Component, signal } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { ShippingModeService } from '@africanies/africanies-core';
import type { ShippingMode } from '@africanies/africanies-models';
import { TableComponent } from './table.component';
import type { TableColumn } from './table-column';
interface Row {
id: number;
name: string;
}
@Component({
standalone: true,
imports: [TableComponent],
template: `
`,
})
class TableHostComponent {
readonly columns: TableColumn[] = [{ key: 'name', header: 'Name' }];
readonly rows = signal([]);
readonly loading = signal(false);
readonly error = signal(null);
readonly showRefresh = signal(false);
readonly showFilter = signal(false);
readonly filterCount = signal(0);
readonly cleared = signal(0);
}
describe('TableComponent keep-rows loading', () => {
let fixture: ComponentFixture;
let host: TableHostComponent;
beforeEach(async () => {
// jsdom does not provide ResizeObserver; the table measures expand width.
globalThis.ResizeObserver = class {
observe(): void {
/* no-op */
}
unobserve(): void {
/* no-op */
}
disconnect(): void {
/* no-op */
}
} as typeof ResizeObserver;
const mode = signal('sfn');
await TestBed.configureTestingModule({
imports: [TableHostComponent],
providers: [
{
provide: ShippingModeService,
useValue: {
mode: mode.asReadonly(),
requestModeChange: () => of(true),
},
},
],
}).compileComponents();
fixture = TestBed.createComponent(TableHostComponent);
host = fixture.componentInstance;
fixture.detectChanges();
});
afterEach(() => {
fixture.destroy();
});
it('shows a keep-rows overlay when loading with rows on screen', () => {
host.rows.set([{ id: 1, name: 'Ada' }]);
host.loading.set(true);
fixture.detectChanges();
const root = fixture.nativeElement as HTMLElement;
expect(
root.querySelector('[data-testid="africanies-table-keep-rows-loading"]'),
).not.toBeNull();
expect(root.textContent).toContain('Ada');
expect(root.textContent).toContain('Loading page…');
});
it('uses the in-grid body loader on first load with no rows', () => {
host.rows.set([]);
host.loading.set(true);
fixture.detectChanges();
const root = fixture.nativeElement as HTMLElement;
expect(
root.querySelector('[data-testid="africanies-table-keep-rows-loading"]'),
).toBeNull();
expect(root.textContent).toContain('Loading page…');
});
it('shows a full-width stale error when rows remain after a failed fetch', () => {
host.rows.set([{ id: 1, name: 'Ada' }]);
host.error.set('Could not load page.');
fixture.detectChanges();
const root = fixture.nativeElement as HTMLElement;
const indicator = root.querySelector('africanies-error-indicator');
expect(indicator).not.toBeNull();
expect(indicator?.className).toContain('w-full');
expect(root.textContent).toContain('Could not load page.');
expect(root.textContent).toContain('Ada');
});
it('shows Clear when filters are active and emits filterClearClick', () => {
host.rows.set([{ id: 1, name: 'Ada' }]);
host.showFilter.set(true);
host.filterCount.set(2);
fixture.detectChanges();
const root = fixture.nativeElement as HTMLElement;
const clear = Array.from(root.querySelectorAll('button')).find((button) =>
/Clear/.test(button.textContent ?? ''),
) as HTMLButtonElement | undefined;
expect(clear).toBeTruthy();
clear?.click();
expect(host.cleared()).toBe(1);
});
it('renders africanies-refresh when showRefresh and rows are present', () => {
host.rows.set([{ id: 1, name: 'Ada' }]);
host.showRefresh.set(true);
fixture.detectChanges();
const root = fixture.nativeElement as HTMLElement;
expect(root.querySelector('africanies-refresh')).not.toBeNull();
});
});