Skip to content

Commit

Permalink
fix: test coverage 100%
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryT-CG committed Feb 5, 2025
1 parent 7bb6110 commit dddea1d
Show file tree
Hide file tree
Showing 17 changed files with 479 additions and 71 deletions.
2 changes: 1 addition & 1 deletion src/app/shared/generated/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
README.md
api.module.ts
api/api.ts
api/imagesExportImport.service.ts
api/configExportImport.service.ts
api/imagesInternal.service.ts
configuration.ts
encoder.ts
Expand Down
6 changes: 3 additions & 3 deletions src/app/shared/generated/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from './imagesExportImport.service';
import { ImagesExportImportAPIService } from './imagesExportImport.service';
export * from './configExportImport.service';
import { ConfigExportImportAPIService } from './configExportImport.service';
export * from './imagesInternal.service';
import { ImagesInternalAPIService } from './imagesInternal.service';
export const APIS = [ImagesExportImportAPIService, ImagesInternalAPIService];
export const APIS = [ConfigExportImportAPIService, ImagesInternalAPIService];
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ import { BASE_PATH, COLLECTION_FORMATS } from '../variables'
import { Configuration } from '../configuration';


export interface ExportImagesRequestParams {
export interface ExportConfigurationRequestParams {
exportWelcomeRequest: ExportWelcomeRequest;
}

export interface ImportImagesRequestParams {
export interface ImportConfigurationRequestParams {
/** target workspace for import */
workspaceName: string;
welcomeSnapshot: WelcomeSnapshot;
Expand All @@ -44,7 +44,7 @@ export interface ImportImagesRequestParams {
@Injectable({
providedIn: 'any'
})
export class ImagesExportImportAPIService {
export class ConfigExportImportAPIService {

protected basePath = 'http://onecx-welcome-bff:8080';
public defaultHeaders = new HttpHeaders();
Expand Down Expand Up @@ -106,18 +106,18 @@ export class ImagesExportImportAPIService {
}

/**
* export images
* export configuration
* @param requestParameters
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public exportImages(requestParameters: ExportImagesRequestParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<WelcomeSnapshot>;
public exportImages(requestParameters: ExportImagesRequestParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<WelcomeSnapshot>>;
public exportImages(requestParameters: ExportImagesRequestParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<WelcomeSnapshot>>;
public exportImages(requestParameters: ExportImagesRequestParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
public exportConfiguration(requestParameters: ExportConfigurationRequestParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<WelcomeSnapshot>;
public exportConfiguration(requestParameters: ExportConfigurationRequestParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<WelcomeSnapshot>>;
public exportConfiguration(requestParameters: ExportConfigurationRequestParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<WelcomeSnapshot>>;
public exportConfiguration(requestParameters: ExportConfigurationRequestParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
const exportWelcomeRequest = requestParameters.exportWelcomeRequest;
if (exportWelcomeRequest === null || exportWelcomeRequest === undefined) {
throw new Error('Required parameter exportWelcomeRequest was null or undefined when calling exportImages.');
throw new Error('Required parameter exportWelcomeRequest was null or undefined when calling exportConfiguration.');
}

let localVarHeaders = this.defaultHeaders;
Expand Down Expand Up @@ -175,22 +175,22 @@ export class ImagesExportImportAPIService {
}

/**
* import images
* import configuration
* @param requestParameters
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public importImages(requestParameters: ImportImagesRequestParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any>;
public importImages(requestParameters: ImportImagesRequestParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<any>>;
public importImages(requestParameters: ImportImagesRequestParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<any>>;
public importImages(requestParameters: ImportImagesRequestParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
public importConfiguration(requestParameters: ImportConfigurationRequestParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any>;
public importConfiguration(requestParameters: ImportConfigurationRequestParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<any>>;
public importConfiguration(requestParameters: ImportConfigurationRequestParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<any>>;
public importConfiguration(requestParameters: ImportConfigurationRequestParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
const workspaceName = requestParameters.workspaceName;
if (workspaceName === null || workspaceName === undefined) {
throw new Error('Required parameter workspaceName was null or undefined when calling importImages.');
throw new Error('Required parameter workspaceName was null or undefined when calling importConfiguration.');
}
const welcomeSnapshot = requestParameters.welcomeSnapshot;
if (welcomeSnapshot === null || welcomeSnapshot === undefined) {
throw new Error('Required parameter welcomeSnapshot was null or undefined when calling importImages.');
throw new Error('Required parameter welcomeSnapshot was null or undefined when calling importConfiguration.');
}

let localVarHeaders = this.defaultHeaders;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p-dialog
[header]="'DIALOG.DETAIL.HEADER' | translate"
[(visible)]="displayDetailDialog"
[(visible)]="displayDialog"
(onHide)="onDialogHide()"
[modal]="true"
[closable]="true"
Expand Down Expand Up @@ -88,7 +88,7 @@
</div>
</p-fieldset>
</div>
<span *ngIf="imageInfos[imageIndex].url" class="p-float-label">
<span *ngIf="imageIndex > -1 && imageInfos[imageIndex].url" class="p-float-label">
<input
pInputText
type="text"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const imageCssForm = new FormGroup<ImageCssForm>({

const imageInfos: ImageInfo[] = [
{
id: '123',
imageId: '123',
id: '01',
imageId: '01',
modificationCount: 0,
visible: true,
position: '0',
Expand All @@ -29,10 +29,10 @@ const imageInfos: ImageInfo[] = [
objectPosition: 'center center',
backgroundColor: 'unset'
},
{ id: '1234', imageId: '1234', visible: true, position: '1', workspaceName: 'ws' },
{ id: '12345', imageId: '12345', visible: true, position: '2', workspaceName: 'ws' },
{ id: '123456', imageId: '123456', visible: true, position: '3', workspaceName: 'ws' },
{ id: '1234567', imageId: '1234567', visible: true, position: '4', workspaceName: 'ws' }
{ id: '02', imageId: '02', visible: true, position: '1', workspaceName: 'ws' },
{ id: '03', imageId: '03', visible: true, position: '2', workspaceName: 'ws' },
{ id: '04', imageId: '04', visible: true, position: '3', workspaceName: 'ws' },
{ id: '05', imageId: '05', visible: true, position: '4', workspaceName: 'ws' }
]

describe('ImageDetailComponent', () => {
Expand Down Expand Up @@ -68,6 +68,7 @@ describe('ImageDetailComponent', () => {
component = fixture.componentInstance
// satisfy the displaying of the url in HTML
component.imageInfos = [{ imageId: '1', url: 'http://example.com/image1.png', workspaceName: 'ws' }]
component.displayDialog = true
fixture.detectChanges()
})

Expand All @@ -80,6 +81,15 @@ describe('ImageDetailComponent', () => {
fixture.componentRef.setInput('imageInfos', imageInfos)
})

it('should fill the form with image values', () => {
spyOn(component, 'ngOnChanges').and.callThrough()
fixture.componentRef.setInput('imageIndex', -1)

fixture.detectChanges() // trigger lifecycle hook: ngOnChanges()

expect(component.ngOnChanges).toHaveBeenCalled()
})

it('should fill the form with image values', () => {
spyOn(component, 'ngOnChanges').and.callThrough()
fixture.componentRef.setInput('imageIndex', 0)
Expand All @@ -104,26 +114,26 @@ describe('ImageDetailComponent', () => {
})

describe('build image src', () => {
const imageData: ImageDataResponse[] = [{ imageId: '1', mimeType: 'mimeType', imageData: new Blob() }]
const imageData: ImageDataResponse[] = [{ imageId: '02', mimeType: 'mimeType', imageData: new Blob() }]
beforeEach(() => {
fixture.componentRef.setInput('imageIndex', 0)
fixture.detectChanges() // trigger lifecycle hook: ngOnChanges()
})

it('should return the base64 image source if image data are available', () => {
const imageInfo: ImageInfo = { imageId: '1', workspaceName: 'ws' }
const result = component.buildImageSrc(imageInfos[0], imageData)

const result = component.buildImageSrc(imageInfo, imageData)

expect(result).toBe('data:mimeType;base64,[object Blob]')
expect(result).toBe('http://example.com/image1.png')
})

it('should return the image URL if the image data are not found', () => {
const imageInfo: ImageInfo = { imageId: '2', url: 'http://example.com/image2.png', workspaceName: 'ws' }

const result = component.buildImageSrc(imageInfo, imageData)
const result = component.buildImageSrc(imageInfos[1], imageData)

expect(result).toBe('http://example.com/image2.png')
expect(result).toBe('data:mimeType;base64,[object Blob]')
})

it('should return the correct URL if imageData is empty', () => {
const imageInfo: ImageInfo = { imageId: '1', url: 'http://example.com/image1.png', workspaceName: 'ws' }
const imageInfo: ImageInfo = { imageId: '01', url: 'http://example.com/image1.png', workspaceName: 'ws' }
const result = component.buildImageSrc(imageInfo, [])

expect(result).toBe('http://example.com/image1.png')
Expand Down Expand Up @@ -186,6 +196,7 @@ describe('ImageDetailComponent', () => {
describe('Saving', () => {
beforeEach(() => {
fixture.componentRef.setInput('imageInfos', imageInfos)
fixture.componentRef.setInput('imageIndex', 0)
fixture.detectChanges() // trigger lifecycle hook: ngOnChanges()
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export interface ImageCssForm {
styleUrls: ['./image-detail.component.scss']
})
export class ImageDetailComponent implements OnChanges {
@Input() public displayDetailDialog = false
@Input() public displayDialog = false
@Input() public images: ImageDataResponse[] = []
@Input() public imageInfos: ImageInfo[] = []
@Input() public imageIndex = 0
@Input() public imageIndex = -1
@Output() public closeDialog = new EventEmitter<boolean>() // true on image changes

public isLoading = false
Expand All @@ -42,7 +42,7 @@ export class ImageDetailComponent implements OnChanges {
}

public ngOnChanges(): void {
this.fillForm()
if (this.displayDialog && this.imageIndex > -1) this.fillForm()
}

// fill form - use default values if values are not yet set
Expand All @@ -57,6 +57,7 @@ export class ImageDetailComponent implements OnChanges {
// if image data was captured before then use this data
// otherwise use the image url
public buildImageSrc(imageInfo: ImageInfo, images: ImageDataResponse[]): string | undefined {
if (this.imageIndex < 0) return
if (imageInfo.url) return imageInfo.url
const currentImage = images.find((image) => {
return image.imageId === imageInfo.imageId
Expand Down
21 changes: 19 additions & 2 deletions src/app/welcome/welcome-configure/welcome-configure.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,21 @@
tooltipPosition="top"
tooltipEvent="hover"
></p-button>
<p-button
id="wc_configure_action_import"
icon="pi pi-upload"
(onClick)="onImport()"
[label]="'ACTIONS.IMPORT.LABEL' | translate"
[ariaLabel]="'ACTIONS.IMPORT.LABEL' | translate"
[pTooltip]="'ACTIONS.IMPORT.TOOLTIP' | translate"
tooltipPosition="top"
tooltipEvent="hover"
></p-button>
<p-button
id="wc_configure_action_create"
icon="pi pi-plus"
(onClick)="onOpenCreateDialog()"
[disabled]="imageInfos.length === 0 || imageInfos.length >= maxImages"
[disabled]="imageInfos.length >= maxImages"
[label]="'ACTIONS.CREATE.LABEL' | translate"
[ariaLabel]="'ACTIONS.CREATE.LABEL' | translate"
[pTooltip]="'ACTIONS.CREATE.TOOLTIP' | translate"
Expand Down Expand Up @@ -146,11 +156,18 @@

<!-- DETAIL -->
<app-image-detail
[displayDetailDialog]="displayDetailDialog"
[displayDialog]="displayDetailDialog"
(closeDialog)="onCloseDetailDialog(false)"
[images]="images"
[imageInfos]="imageInfos"
[imageIndex]="detailImageIndex"
></app-image-detail>

<!-- IMPORT -->
<app-welcome-import
[displayDialog]="displayImportDialog"
(importEmitter)="onCloseDetailDialog(false)"
[workspaceName]="workspace?.workspaceName"
></app-welcome-import>
</div>
</ocx-portal-page>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
ImageDataResponse,
ImageInfo,
ImagesInternalAPIService,
ImagesExportImportAPIService,
ConfigExportImportAPIService,
WelcomeSnapshot,
ObjectFit
} from 'src/app/shared/generated'
Expand Down Expand Up @@ -42,7 +42,7 @@ const imageInfos: ImageInfo[] = [
{ id: '1234567', imageId: '1234567', visible: true, position: '3', workspaceName: 'ws' }
]

const imageExport: WelcomeSnapshot = {
const imageDTO: WelcomeSnapshot = {
id: 'export-id',
created: '2025-02-03T15:30:53.122632Z',
config: {
Expand Down Expand Up @@ -90,8 +90,7 @@ describe('WelcomeConfigureComponent', () => {
updateImageOrder: jasmine.createSpy('updateImageOrder').and.returnValue(of({}))
}
const eximServiceSpy = {
exportImages: jasmine.createSpy('exportImages').and.returnValue(of({})),
importImages: jasmine.createSpy('importImages').and.returnValue(of({}))
exportConfiguration: jasmine.createSpy('exportConfiguration').and.returnValue(of({}))
}

beforeEach(waitForAsync(() => {
Expand All @@ -109,7 +108,7 @@ describe('WelcomeConfigureComponent', () => {
provideHttpClientTesting(),
{ provide: PortalMessageService, useValue: msgServiceSpy },
{ provide: ImagesInternalAPIService, useValue: apiServiceSpy },
{ provide: ImagesExportImportAPIService, useValue: eximServiceSpy }
{ provide: ConfigExportImportAPIService, useValue: eximServiceSpy }
]
}).compileComponents()
// reset
Expand All @@ -119,8 +118,7 @@ describe('WelcomeConfigureComponent', () => {
apiServiceSpy.getImageById.calls.reset()
apiServiceSpy.deleteImageInfoById.calls.reset()
apiServiceSpy.updateImageInfo.calls.reset()
eximServiceSpy.exportImages.calls.reset()
eximServiceSpy.importImages.calls.reset()
eximServiceSpy.exportConfiguration.calls.reset()
}))

beforeEach(() => {
Expand Down Expand Up @@ -370,12 +368,14 @@ describe('WelcomeConfigureComponent', () => {
it('should not refresh after closing', () => {
component.displayCreateDialog = true
component.displayDetailDialog = true
component.displayImportDialog = true
spyOn(component, 'fetchImageInfos')

component.onCloseDetailDialog(false)

expect(component.displayCreateDialog).toBeFalse()
expect(component.displayDetailDialog).toBeFalse()
expect(component.displayImportDialog).toBeFalse()
expect(component.fetchImageInfos).not.toHaveBeenCalled()
})
})
Expand Down Expand Up @@ -444,31 +444,43 @@ describe('WelcomeConfigureComponent', () => {

component.onExport()

expect(eximServiceSpy.exportImages).not.toHaveBeenCalled()
expect(eximServiceSpy.exportConfiguration).not.toHaveBeenCalled()
})

it('should save export file', () => {
spyOn(JSON, 'stringify').and.returnValue('themejson')
spyOn(FileSaver, 'saveAs')

eximServiceSpy.exportImages.and.returnValue(of(imageExport) as any)
eximServiceSpy.exportConfiguration.and.returnValue(of(imageDTO) as any)

component.onExport()

expect(eximServiceSpy.exportImages).toHaveBeenCalledOnceWith(
expect(eximServiceSpy.exportConfiguration).toHaveBeenCalledOnceWith(
jasmine.objectContaining({ exportWelcomeRequest: { workspaceName: component.workspace?.workspaceName } })
)
})

it('should display error on export fail', () => {
const errorResponse = { status: 400, statusText: 'Error on exporting configuration' }
eximServiceSpy.exportImages.and.returnValue(throwError(() => errorResponse))
eximServiceSpy.exportConfiguration.and.returnValue(throwError(() => errorResponse))
spyOn(console, 'error')

component.onExport()

expect(console.error).toHaveBeenCalledWith('exportImages', errorResponse)
expect(console.error).toHaveBeenCalledWith('exportConfiguration', errorResponse)
expect(msgServiceSpy.error).toHaveBeenCalledOnceWith({ summaryKey: 'ACTIONS.EXPORT.MESSAGE_NOK' })
})
})

describe('Import', () => {
beforeEach(() => {
component.workspace = ws
})

it('should open import dialog', () => {
component.onImport()

expect(component.displayImportDialog).toBeTrue()
})
})
})
Loading

0 comments on commit dddea1d

Please sign in to comment.