hola, puedes ayudarme creando las pruebas unitarias de esta clase "import { SelectionModel } from '@angular/cdk/collections';
import { Component, Input, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatTableDataSource } from '@angular/material/table';
import { finalize } from 'rxjs/operators';
import { CompaniesService } from 'src/app/services/companies/companies.service';
import { CreateAditionalChargeComponent } from '../create-aditional-charge/create-aditional-charge.component';
import { SuscriptionsService } from 'src/app/services/suscriptions/suscriptions.service';
import { AnnularAditionalChargeComponent } from '../annular-aditional-charge/annular-aditional-charge.component';
import { ResumeConfirmationPopupComponent } from '../resume-confirmation-popup/resume-confirmation-popup.component';
import { ConfirmationPopupComponent } from 'src/app/molecules/confirmation-popup/confirmation-popup.component';

@Component({
  selector: 'impulsa-charges',
  templateUrl: './charges.component.html',
  styleUrls: ['./charges.component.scss']
})
export class ChargesComponent implements OnInit {


  
  @Input() contractId : number;

  displayedColumns: string[] = [
    'select',
    'id',
    'to_charge',
    'concept',
    'plate',
    'date',
    'city',
    'value',
    'status',
    'proof',
    'observation'
  ];
  initialSelection = [];
  allowMultiSelect = true;
  columnsToDisplay: string[] = this.displayedColumns.slice();
  dataSource = new MatTableDataSource([]);
  selection = new SelectionModel(this.allowMultiSelect, this.initialSelection);
  isLoading: boolean;
  nodata:boolean = true;

  constructor(private companiesService: CompaniesService,
    public dialog: MatDialog,
  ) { }

  ngOnInit(): void {
    this.getCharges();
  }

  private getCharges(){
    this.isLoading = true;
    this.companiesService.getChargesAditionalsByContract(0, 25, { contractId: this.contractId})
      .pipe(finalize(()=> this.isLoading = false))
      .subscribe({
        next: (resp:any) => {
          console.log(resp);
          this.dataSource = new MatTableDataSource<any>(resp.content);
          this.nodata = resp.totalRows === 0 ? true : false;
        }
      })
  }
  createAdditionalCharge() {
    const dialogRef = this.dialog.open(CreateAditionalChargeComponent,{
      width:'412px',
      data:{
        contractId : this.contractId,
        mode: 'create',
        title: 'Crear cobro adicional'
      }
    });
    dialogRef.afterClosed().subscribe((resp:any) => {
      console.log(resp);
      if (resp) {
        let data = {
          ... resp,
          contractId : +this.contractId
        }
        if (data.file) {
          data.file.file = data.file.file.split(',')[1];
        }
        const dialogrefConfirmation = this.dialog.open(ResumeConfirmationPopupComponent, {
          width:'412px',
          data: {...data, 
            title:'¿Quieres aplicar este cobro adicional?',
            img:'../../../assets/fonts/icons/alert.svg'
          }
        })
        dialogrefConfirmation.afterClosed().subscribe((resp)=> {
          if (resp) {
            this.companiesService.createChargeAdditionalToContract(data).subscribe({
              next:(resp:any)=> {
                console.log(resp);
                this.getCharges();
                this.selection = new SelectionModel(this.allowMultiSelect, this.initialSelection);
                this.showPopupConfirmation('Cobro creado', '../../../assets/fonts/icons/Ok.svg', 'Se ha creado un cobro adicional, este cobro se verá reflejado en facturación.');
              }
            });
          }
        })
      }
    });
  }

  editPayment(element: any) {
    console.log("editpaiment" +JSON.stringify(element));
    
    const dialogRef = this.dialog.open(CreateAditionalChargeComponent,{
      width:'412px',
      data:{
        contractId : this.contractId,
        mode : 'edit',
        title : 'Editar cobro adicional',
        charge : {
          includePreInvoice: element.includePreInvoice,
          id : element.serviceId,
          plate : element.plate,
          value : element.totalPrice,
          observation : element.observation,
          file : element.file,
        }
      }
    });

    dialogRef.afterClosed().subscribe((resp:any) => {
      console.log(resp);
      if (resp) {
        let data = {
          ... resp,
          contractId : +this.contractId,
          id: element.id,

        }
        const dialogconfirmation = this.dialog.open(ResumeConfirmationPopupComponent, {
          width:'412px',
          data:{
            title:"¿Guardar los cambios de este cobro?",
            img:"../../../assets/fonts/icons/alert.svg",
            ...data
          }
        });
        dialogconfirmation.afterClosed().subscribe((resp)=> {
          if (resp) {
            this.editCharge(data);
            this.selection = new SelectionModel(this.allowMultiSelect, this.initialSelection);
          }
        });
      }
    });
    }


    annularPayment(element: any) {
      const dialogRef = this.dialog.open(AnnularAditionalChargeComponent,{
        width:'412px',
      });
      dialogRef.afterClosed().subscribe((resp:any)=> {  
        console.log(resp);
        if (resp) {
          this.companiesService.annularChargeAdditionalToContract(element.id,resp).subscribe({ 
            error:(error:any) => {
              console.error(error);
            }, 
            next:() => {
              this.showPopupConfirmation('Cobro anulado', '../../../assets/fonts/icons/Ok.svg', '');
              
            }
          }); 
          this.getCharges();
      }
    });
  }

  public download(element:any){
    this.companiesService.getProofChargeAdditionalToContract(element.id).subscribe({
      next:(resp:any)=> {
        const fileExtension = resp.data.name.split('.').pop().toLowerCase();

      let mimeTyp = '';
      switch (fileExtension) {
        case 'pdf':
          mimeTyp = 'application/pdf';
          break;
        case 'jpg':
        case 'jpeg':
          mimeTyp = 'image/jpeg';
          break;
        case 'png':
          mimeTyp = 'image/png';
          break;
        case 'txt':
          mimeTyp = 'text/plain';
          break;
        case 'doc':
          mimeTyp = 'application/msword';
          break;
        case 'docx':
          mimeTyp = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
          break;
        default:
          mimeTyp = 'application/octet-stream';
      }

      const blob = this.base64ToBlob(resp.data.file, mimeTyp);

      const blobUrl = URL.createObjectURL(blob);

      window.open(blobUrl, '_blank');

      setTimeout(() => URL.revokeObjectURL(blobUrl), 1000);
      }});

  }

  private base64ToBlob(base64Data: string, contentType: string) {
    const sliceSize = 512;
    const byteCharacters = atob(base64Data);
    const byteArrays = [];
    
    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
      const slice = byteCharacters.slice(offset, offset + sliceSize);
    
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
          byteNumbers[i] = slice.charCodeAt(i);
      }
    
      const byteArray = new Uint8Array(byteNumbers);
    
      byteArrays.push(byteArray);
    }
    
    const blob = new Blob(byteArrays, {type: contentType});
    return blob;
  }

  editCharge(data:any){
    console.log('editando '+JSON.stringify(data));
    
    this.companiesService.editChargeAdditionalToContract(data).subscribe({
      next:(resp:any)=> {
        console.log(resp);
        this.showPopupConfirmation('Cobro editado', '../../../assets/fonts/icons/Ok.svg','');
        this.getCharges();
      }
    });
  }

  slideChange(element:any){
    let data = {
        serviceId: element.serviceId,
        plateReference: element.plate != null ? element.plate : '',
        servicePrice: element.totalPrice,
        observation: element.observation,
        includePreInvoice: element.includePreInvoice,
        contractId : +this.contractId,
        id: element.id,
    }
    this.editCharge(data);
   }

   showPopupConfirmation(title:string, img:string, desc:string){
      this.dialog.open(ConfirmationPopupComponent, {
        width: '412px',
        data:{
          title: title,
          img: img,
          description:[desc],
          btnNext: 'Entendido'
        }
      })
   }
}
"