Features de gestión: casos de prueba
Casos de prueba unitarios (Karma + Jasmine) de las features de gestión: departamentos, etiquetas, respuestas rápidas, tickets bloqueados, control de acceso (módulos) y contactos. Son 10 specs y 112 it(). Salvo contacts-routing.module.spec.ts, todos usan TestBed con NO_ERRORS_SCHEMA; ninguno contiene xit, fdescribe ni fit, y no hay specs vacíos.
Departamentos
src/app/features/departments/components/department-modal/department-modal.component.spec.ts
- SUT:
DepartmentModalComponent(modal de alta/edición de departamento con formulario reactivo y pestañas). - Mocking:
TestBedconReactiveFormsModuleyTranslateModule.forRoot(). Providers:NgbActiveModalreal,DepartmentService(jasmine.createSpyObjconcreate,update,getDepartmentUsers,updateDepartmentUsers) yToastrNotificationService(showNotification). Fixture auxiliarmakeDepartment().spyOn(component.activeModal, 'close')donde se verifica el cierre.
ngOnInit — ADD action
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should build the form with default values | Dado action = ADD, cuando se ejecuta detectChanges(), entonces se construye el formulario. | name vacío, color #000000 y autoResolution.resolveInMinutes igual a 5. | Ninguno adicional. |
should set the ADD title | Dado action = ADD, cuando se inicializa el componente. | titleModal es departments.modal.add. | Ninguno. |
ngOnInit — EDIT action
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should populate the form from the department input | Dado action = EDIT y un department asignado, cuando se inicializa. | name es Support y autoResolution.notificationMessage es Closing soon. | makeDepartment(). |
should set the EDIT title | Dado action = EDIT, cuando se inicializa. | titleModal es departments.modal.edit. | makeDepartment(). |
resolution toggles
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should disable the autoResolution group when override is OFF | Dado el modo ADD, cuando overrideGlobalResolution pasa a false. | notificationMessage queda deshabilitado. | Ninguno. |
should enable the autoResolution group when override is ON | Dado el modo ADD, cuando overrideGlobalResolution pasa a true. | El grupo autoResolution no está deshabilitado. | Ninguno. |
should keep dependent fields disabled when override is ON but auto-resolution is OFF | Dado override true, cuando autoResolution.enabled pasa a false (caso límite). | notificationMessage sigue deshabilitado. | Ninguno. |
should enable notificationMessage when override AND auto-resolution are both ON | Dado override true, cuando autoResolution.enabled pasa a true. | notificationMessage queda habilitado. | Ninguno. |
notify before resolve validation
Precondición del beforeEach: modo ADD con override y auto-resolución activados.
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should be valid when notifyInMinutes is lower than resolveInMinutes | Dado resolveInMinutes: 5 y notifyInMinutes: 1. | notifyBeforeResolveError es false. | Ninguno. |
should flag the group when notifyInMinutes equals resolveInMinutes | Dado resolveInMinutes: 5 y notifyInMinutes: 5 (borde). | notifyBeforeResolveError es true y el formulario es inválido. | Ninguno. |
should flag the group when notifyInMinutes is greater than resolveInMinutes | Dado resolveInMinutes: 2 y notifyInMinutes: 5. | notifyBeforeResolveError es true. | Ninguno. |
should not block the form when the override is OFF | Dado un nombre válido y tiempos inválidos (2 y 5), el formulario es inválido; cuando se apaga el override. | El formulario pasa a válido. | Ninguno. |
should mark resolveInMinutes as required | Dado resolveInMinutes en null (fallo). | El control tiene el error required. | Ninguno. |
insertVariable
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should append the variable into an empty greetingMessage | Dado greetingMessage vacío, cuando se llama insertVariable('{{username}}'). | greetingMessage contiene {{username}}. | Ninguno. |
onSubmit — create
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should call DepartmentService.create with the built payload | Dado modo ADD con name New department, cuando se ejecuta onSubmit(). | create se invoca y el payload tiene name New department. | create devuelve of(created). |
should close the modal with the created department after successful creation | Dado el mismo caso, con create exitoso. | activeModal.close se llama con el departamento creado. | create devuelve of(created); spyOn(component.activeModal, 'close'). |
onSubmit — update
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should call DepartmentService.update with the department id | Dado modo EDIT con un departamento, cuando se ejecuta onSubmit(). | update se llama con _id y objectContaining({ name }). | update devuelve of(department). |
should include the autoResolution times in the save payload | Dado modo EDIT, cuando se guarda. | El payload lleva resolveInMinutes 10 y notifyInMinutes 2. | update devuelve of(department). |
should close the modal with the updated department after a successful update | Dado update que devuelve el departamento renombrado. | close se llama con el departamento actualizado. | update devuelve of(updated); spyOn(component.activeModal, 'close'). |
onTabChange
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should load department users when switching to the users tab for the first time | Dado modo EDIT, cuando se cambia a la pestaña users. | getDepartmentUsers se llama con el _id y activeTab es users. | getDepartmentUsers devuelve of([]). |
should NOT reload users on a second switch to the users tab | Dado un cambio users, resolution, users (borde). | getDepartmentUsers se llama una sola vez. | getDepartmentUsers devuelve of([]). |
Tests en este archivo: 21.
Etiquetas
src/app/features/labels/components/label-modal-form/label-modal-form.component.spec.ts
- SUT:
LabelModalFormComponent(modal de etiqueta con acciones ADD, EDIT y VIEW). - Mocking:
TestBedconReactiveFormsModuleyTranslateModule.forRootconTranslateFakeLoader.NgbActiveModal(createSpyObj:close,dismiss) yLabelService(createLabel,updateLabel). FixturemockLabel.
ADD action
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should create | Dado action = ADD, tras detectChanges(). | El componente existe. | Ninguno. |
should set titleModal to add key | Dado action = ADD. | titleModal es labels.modal.add. | Ninguno. |
should build an enabled form with default color #000000 | Dado action = ADD. | Formulario habilitado y color igual a #000000. | Ninguno. |
should be invalid when name is empty | Dado el formulario recién creado. | El control name es inválido. | Ninguno. |
should be valid with required fields filled | Dado patchValue con name, color e isActive. | El formulario es válido. | Ninguno. |
onSubmit: should call createLabel and close modal on valid form | Dado un formulario válido, cuando se ejecuta onSubmit(). | createLabel se llama con el valor del formulario y close con saved. | createLabel devuelve of(mockLabel); activeModal.close. |
onSubmit: should NOT call createLabel when form is invalid | Dado un formulario vacío (fallo). | createLabel no se llama. | createLabel. |
should reject name longer than MAX_LENGTH | Dado un name de 101 caracteres (borde). | El control name es inválido. | Ninguno. |
EDIT action
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should set titleModal to edit key | Dado action = EDIT y label asignada. | titleModal es labels.modal.edit. | Ninguno. |
should populate form with label values | Dado action = EDIT. | El valor del formulario es igual a los datos de mockLabel. | Ninguno. |
should leave the form enabled | Dado action = EDIT. | Formulario habilitado. | Ninguno. |
onSubmit: should call updateLabel with _id and form value | Dado action = EDIT, cuando se envía. | updateLabel se llama con oid-001 y el valor del formulario; close con saved. | updateLabel devuelve of(mockLabel); activeModal.close. |
VIEW action
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should set titleModal to view key | Dado action = VIEW. | titleModal es labels.modal.view. | Ninguno. |
should disable the form | Dado action = VIEW. | El formulario está deshabilitado. | Ninguno. |
onSubmit: should NOT call createLabel or updateLabel | Dado modo VIEW, cuando se ejecuta onSubmit() (borde). | No se llama a createLabel ni a updateLabel. | createLabel, updateLabel. |
Nivel raíz
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
closeModal: should call activeModal.dismiss | Dado modo ADD, cuando se llama closeModal(). | activeModal.dismiss se invoca. | activeModal.dismiss. |
Tests en este archivo: 16.
src/app/features/labels/components/labels-filter/labels-filter.component.spec.ts
- SUT:
LabelsFilterComponent(filtro por nombre y estado, emitefilterApplyyfilterReset). - Mocking:
TestBedconFormsModuleyTranslateModuleconTranslateFakeLoader; sin servicios. LosEventEmitterse espían conspyOn(component.filterApply, 'emit').
LabelsFilterComponent
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should create | Dado el componente inicializado. | El componente existe. | Ninguno. |
should start with empty filterForm | Dado el estado inicial. | filterForm es { name: '', isActive: '' }. | Ninguno. |
should start with activeFiltersCount = 0 | Dado el estado inicial. | activeFiltersCount es 0. | Ninguno. |
onApply: should emit empty filter when form is blank | Dado un formulario en blanco. | Emite {} y el contador sigue en 0. | spyOn(filterApply, 'emit'). |
onApply: should include name when filled in | Dado name igual a VIP. | Emite un objeto con name: 'VIP' y el contador es 1. | spyOn(filterApply, 'emit'). |
onApply: should trim whitespace from name | Dado name igual a VIP (borde). | Emite name: 'VIP' sin espacios. | spyOn(filterApply, 'emit'). |
onApply: should include isActive=true when "true" selected | Dado isActive igual a 'true'. | Emite isActive: true (booleano). | spyOn(filterApply, 'emit'). |
onApply: should include isActive=false when "false" selected | Dado isActive igual a 'false'. | Emite isActive: false (booleano). | spyOn(filterApply, 'emit'). |
onApply: should NOT include isActive when empty string selected | Dado isActive igual a ''. | El objeto emitido no contiene la clave isActive. | spyOn(filterApply, 'emit'). |
onApply: should count both filters when both are set | Dado name VIP e isActive 'true'. | activeFiltersCount es 2. | Ninguno. |
onReset: should reset form to empty state | Dado un formulario con valores, cuando se llama onReset(). | filterForm vuelve a { name: '', isActive: '' }. | Ninguno. |
onReset: should reset activeFiltersCount to 0 | Dado activeFiltersCount = 2. | El contador pasa a 0. | Ninguno. |
onReset: should emit filterReset | Cuando se llama onReset(). | filterReset.emit se invoca. | spyOn(filterReset, 'emit'). |
Tests en este archivo: 13.
src/app/features/labels/components/labels-table/labels-table.component.spec.ts
- SUT:
LabelsTableComponent(tabla paginada de etiquetas con filtros y modal). - Mocking:
TestBedconTranslateModuleyTranslateFakeLoader.LabelService(createSpyObj:findLabelsPaginated,removeLabel, ambos conof(...)) yNgbModal(open). El modal se simula con unNgbModalReffalso (componentInstance: {},closed: of('saved')).
LabelsTableComponent
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should create | Dado el componente inicializado. | El componente existe. | Ninguno. |
should call findLabelsPaginated on init | Dado ngOnInit. | findLabelsPaginated se llama con (1, 10, {}). | findLabelsPaginated. |
should populate labels after load | Dada una respuesta con una etiqueta. | labels es [mockLabel]. | findLabelsPaginated. |
should set isLoading to false after load | Tras la carga inicial. | isLoading es false. | findLabelsPaginated. |
onFilterApply: should reset to page 1 and fetch with new filter | Cuando se aplica el filtro { name: 'VIP' }. | Consulta (1, 10, { name: 'VIP' }). | calls.reset() previo. |
onFilterReset: should reset to page 1 and fetch with empty filter | Dado un filtro aplicado, cuando se resetea. | Consulta (1, 10, {}). | calls.reset() previo. |
onPageChange: should fetch the requested page | Cuando se pide la página 3. | Consulta (3, 10, {}). | calls.reset() previo. |
onLimitChange: should fetch page 1 with new limit | Cuando el límite pasa a 50. | Consulta (1, 50, {}). | calls.reset() previo. |
onDelete: should call removeLabel with _id and reload | Cuando se elimina mockLabel. | removeLabel se llama con oid-001 y se recarga la lista. | removeLabel, findLabelsPaginated. |
openModal: should open modal with ADD action and no label | Cuando se abre el modal en modo ADD. | modal.open se llama, action es ADD, label es undefined y se recarga al cerrar con saved. | NgbModal.open devuelve la ref falsa. |
openModal: should pass the label for EDIT action | Cuando se abre en modo EDIT con una etiqueta. | componentInstance.label es mockLabel. | NgbModal.open devuelve la ref falsa. |
Tests en este archivo: 11.
Respuestas rápidas
src/app/features/quick-responses/components/quick-response-modal-form/quick-response-modal-form.component.spec.ts
- SUT:
QuickResponseModalFormComponent(modal de alta, edición y vista de respuesta rápida). - Mocking:
TestBedconReactiveFormsModuleyTranslateModuleconTranslateFakeLoader.NgbActiveModal(close,dismiss) yQuickResponseService(create,update) comocreateSpyObj. FixturemockRecord.
ADD action
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should create | Dado action = ADD. | El componente existe. | Ninguno. |
should set titleModal to add key | Dado action = ADD. | titleModal es quickResponses.modal.add. | Ninguno. |
should build an enabled form | Dado action = ADD. | El formulario existe y está habilitado. | Ninguno. |
should be invalid when form is empty | Dado el formulario vacío. | Formulario inválido. | Ninguno. |
should be valid with shortcut and message filled | Dado shortcut /hi, message Hello! e isActive. | Formulario válido. | Ninguno. |
onSubmit: should call create and close modal on valid form | Dado un formulario válido, al enviar. | create se llama con el valor del formulario y close con saved. | create devuelve of(mockRecord); activeModal.close. |
onSubmit: should NOT call create when form is invalid | Dado un formulario vacío (fallo). | create no se llama. | create. |
EDIT action
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should set titleModal to edit key | Dado action = EDIT con registro. | titleModal es quickResponses.modal.edit. | Ninguno. |
should populate form with record values | Dado action = EDIT. | El formulario contiene shortcut, message e isActive del registro. | Ninguno. |
onSubmit: should call update with identifier and close modal | Dado action = EDIT, al enviar. | update se llama con uuid-001 (el identifier, no el _id) y el valor del formulario; close con saved. | update devuelve of(mockRecord); activeModal.close. |
VIEW action
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should set titleModal to view key | Dado action = VIEW. | titleModal es quickResponses.modal.view. | Ninguno. |
should disable the form | Dado action = VIEW. | El formulario está deshabilitado. | Ninguno. |
onSubmit: should NOT call create or update | Dado modo VIEW, al enviar (borde). | No se llama a create ni a update. | create, update. |
Nivel raíz
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
closeModal: should call activeModal.dismiss | Dado modo ADD, al llamar closeModal(). | activeModal.dismiss se invoca. | activeModal.dismiss. |
Tests en este archivo: 14.
src/app/features/quick-responses/components/quick-responses-filter/quick-responses-filter.component.spec.ts
- SUT:
QuickResponsesFilterComponent(filtro por atajo y estado). - Mocking:
TestBedconFormsModuleyTranslateModuleconTranslateFakeLoader; sin servicios.spyOnsobre losEventEmitterfilterApplyyfilterReset.
QuickResponsesFilterComponent
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should create | Dado el componente inicializado. | El componente existe. | Ninguno. |
should start with empty filterForm | Dado el estado inicial. | filterForm es { shortcut: '', isActive: '' }. | Ninguno. |
should start with activeFiltersCount = 0 | Dado el estado inicial. | El contador es 0. | Ninguno. |
onApply: should emit empty filter when form is blank | Dado un formulario en blanco. | Emite {} y el contador es 0. | spyOn(filterApply, 'emit'). |
onApply: should include shortcut when filled in | Dado shortcut /hi. | Emite shortcut: '/hi' y el contador es 1. | spyOn(filterApply, 'emit'). |
onApply: should trim whitespace from shortcut | Dado shortcut /hi (borde). | Emite shortcut: '/hi'. | spyOn(filterApply, 'emit'). |
onApply: should include isActive=true when "true" selected | Dado isActive 'true'. | Emite isActive: true. | spyOn(filterApply, 'emit'). |
onApply: should include isActive=false when "false" selected | Dado isActive 'false'. | Emite isActive: false. | spyOn(filterApply, 'emit'). |
onApply: should count both filters when both are set | Dados shortcut e isActive informados. | activeFiltersCount es 2. | Ninguno. |
onReset: should reset form to empty state | Dado un formulario con valores. | filterForm vuelve a su estado vacío. | Ninguno. |
onReset: should reset activeFiltersCount to 0 | Dado activeFiltersCount = 2. | El contador pasa a 0. | Ninguno. |
onReset: should emit filterReset | Al llamar onReset(). | filterReset.emit se invoca. | spyOn(filterReset, 'emit'). |
Tests en este archivo: 12. A diferencia del filtro de etiquetas, no hay caso que verifique que isActive en '' se omite del objeto emitido.
src/app/features/quick-responses/components/quick-responses-table/quick-responses-table.component.spec.ts
- SUT:
QuickResponsesTableComponent(tabla paginada con filtros, activación y modal). - Mocking:
TestBedconTranslateModuleyTranslateFakeLoader.QuickResponseService(findPaginated,toggleActive,remove, todos conof(...)) yNgbModal(open) conNgbModalReffalso.
QuickResponsesTableComponent
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should create | Dado el componente inicializado. | El componente existe. | Ninguno. |
should call findPaginated on init | Dado ngOnInit. | findPaginated se llama con (1, 10, {}). | findPaginated. |
should populate quickResponses after load | Dada una respuesta con un registro. | quickResponses es [mockRecord]. | findPaginated. |
should set isLoading to false after load | Tras la carga. | isLoading es false. | findPaginated. |
onFilterApply: should reset to page 1 and fetch with new filter | Con filtro { shortcut: '/hi' }. | Consulta (1, 10, { shortcut: '/hi' }). | calls.reset() previo. |
onFilterReset: should reset to page 1 and fetch with empty filter | Dado un filtro aplicado, al resetear. | Consulta (1, 10, {}). | calls.reset() previo. |
onPageChange: should fetch the requested page | Al pedir la página 2. | Consulta (2, 10, {}). | calls.reset() previo. |
onLimitChange: should fetch page 1 with new limit | Al cambiar el límite a 50. | Consulta (1, 50, {}). | calls.reset() previo. |
onToggleActive: should call toggleActive with identifier and reload | Al activar o desactivar mockRecord. | toggleActive se llama con uuid-001 y se recarga la lista. | toggleActive, findPaginated. |
openModal: should open modal with action and record | Al abrir el modal en modo EDIT con registro. | modal.open se llama, action es EDIT, quickResponse es el registro y se recarga al cerrar con saved. | NgbModal.open devuelve la ref falsa. |
openModal: should open modal without record for ADD action | Al abrir en modo ADD sin registro. | quickResponse es undefined. | NgbModal.open devuelve la ref falsa. |
Tests en este archivo: 11. El spec declara remove en el spy, pero ningún it() lo ejercita.
Tickets bloqueados
src/app/features/locked-tickets/components/locked-tickets-table/locked-tickets-table.component.spec.ts
- SUT:
LockedTicketsTableComponent(vista de administración de tickets bloqueados; servicio simple yngx-datatable, sin NgRx). - Mocking:
TestBedconTranslateModuleyTranslateFakeLoader.TicketService(getLockedTickets,forceUnlockTicket, conof(...)) yConfirmDialogService(confirm, que devuelvePromise). Los tests dereleaseTicketsonasyncy avanzan microtareas conawait Promise.resolve().
LockedTicketsTableComponent
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should create | Dado el componente inicializado. | El componente existe. | Ninguno. |
calls getLockedTickets(page:1, limit:10) on init | Dado ngOnInit. | getLockedTickets se llama con { page: 1, limit: 10 }. | getLockedTickets. |
populates tickets from the response | Dada la respuesta con un ticket. | tickets es [mockLockedTicket]. | getLockedTickets. |
sets isLoading to false after load | Tras la carga. | isLoading es false. | getLockedTickets. |
onPageChange
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
fetches the requested page | Al pedir la página 3. | Consulta con { page: 3, limit: 10 }. | calls.reset() previo. |
onLimitChange
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
resets to page 1 with the new limit | Al cambiar el límite a 50. | Consulta con { page: 1, limit: 50 }. | calls.reset() previo. |
getContactName
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
joins firstname + lastName | Dado un ticket con contacto Ada Lovelace. | Devuelve Ada Lovelace. | Ninguno. |
returns an empty string when there is no contact | Dado un ticket sin contact (borde). | Devuelve cadena vacía. | Ninguno. |
getLockedByName
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
joins the lockedByUser firstname + lastName | Dado un ticket bloqueado por Grace Hopper. | Devuelve Grace Hopper. | Ninguno. |
returns an empty string when lockedByUser is absent | Dado un ticket sin lockedByUser (borde). | Devuelve cadena vacía. | Ninguno. |
releaseTicket
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
does NOT call forceUnlockTicket when the confirmation is cancelled | Dado que el usuario cancela la confirmación. | forceUnlockTicket no se llama. | confirm devuelve Promise.resolve(false). |
calls forceUnlockTicket and reloads the list when confirmed | Dado que el usuario confirma. | forceUnlockTicket se llama con ticket-1 y se vuelve a consultar getLockedTickets. | confirm devuelve Promise.resolve(true); calls.reset() previo. |
Tests en este archivo: 12.
Control de acceso
src/app/features/access-control/features/modules/components/modules-table/modules-table.component.spec.ts
- SUT:
ModulesTableComponent(tabla de módulos del sistema). - Mocking:
TestBedconTranslateModule.forRootyTranslateFakeLoader.SystemModuleService(createSpyObj:getAll,remove;getAlldevuelveof([])) yNgbModalcomo objeto vacío. HelperbuildComponent()para crear el fixture.
ModulesTableComponent
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
loads modules on init | Dado un servicio que devuelve lista vacía, al llamar ngOnInit(). | getAll se invoca. | getAll devuelve of([]). |
Tests en este archivo: 1.
Contactos
src/app/features/contacts/contacts-routing.module.spec.ts
- SUT: constante
routesdecontacts-routing.module(cableado de permisos). - Mocking: sin
TestBedni espías; importaroutesypermissionGuardy comprueba la configuración de la ruta.
ContactsRoutingModule routes (permission wiring)
| it() | Escenario | Resultado esperado | Mocks/spies |
|---|---|---|---|
should gate the contacts page route on CONTACT_READ via permissionGuard | Dada la ruta con path === ''. | data es { permission: 'CONTACT_READ' } y canActivate contiene permissionGuard. | Ninguno. |
Tests en este archivo: 1.
Total de la página
| Spec | Tests |
|---|---|
department-modal.component.spec.ts | 21 |
label-modal-form.component.spec.ts | 16 |
labels-filter.component.spec.ts | 13 |
labels-table.component.spec.ts | 11 |
quick-response-modal-form.component.spec.ts | 14 |
quick-responses-filter.component.spec.ts | 12 |
quick-responses-table.component.spec.ts | 11 |
locked-tickets-table.component.spec.ts | 12 |
modules-table.component.spec.ts | 1 |
contacts-routing.module.spec.ts | 1 |
| Total | 112 |