Skip to content

Commit

Permalink
Use a form on theme import (#296)
Browse files Browse the repository at this point in the history
* fix: use a form on theme import

* fix: code cleanup
  • Loading branch information
HenryT-CG authored Nov 10, 2024
1 parent fdb0fe3 commit b8e28f9
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 95 deletions.
34 changes: 23 additions & 11 deletions src/app/theme/theme-import/theme-import.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
[closable]="true"
[modal]="true"
(onHide)="onImportThemeHide()"
[style]="{ 'max-width': '700px' }"
>
<p-fileUpload
inputId="th_import_upload"
Expand All @@ -19,22 +20,25 @@
(onRemove)="onImportThemeClear()"
(onSelect)="onImportThemeSelect($event)"
(uploadHandler)="onThemeUpload()"
[showUploadButton]="displayName && !themeImportError"
[showUploadButton]="formGroup.valid && !themeImportError"
[uploadLabel]="'ACTIONS.UPLOAD' | translate"
[cancelLabel]="'ACTIONS.CANCEL' | translate"
[chooseLabel]="'ACTIONS.CHOOSE' | translate"
></p-fileUpload>
<div *ngIf="themeSnapshot" class="flex flex-wrap justify-content-start align-items-center gap-3 mt-4">
<div
*ngIf="themeSnapshot"
[formGroup]="formGroup"
class="flex flex-wrap justify-content-start align-items-center gap-3 mt-4"
>
<span class="p-float-label w-full md:w-15rem" controlErrorAnchor>
<input
#themeNameInput
pInputText
type="text"
id="th_import_theme_name"
class="w-full pt-3 pb-2 text-responsive"
[(ngModel)]="themeName"
(ngModelChange)="checkThemeExistence()"
(keyup)="checkThemeExistence()"
formControlName="themeName"
(keyup)="onThemeNameChange()"
[pTooltip]="'THEME.THEME_NAME' | translate"
tooltipPosition="top"
tooltipEvent="hover"
Expand All @@ -47,9 +51,8 @@
type="text"
id="th_import_theme_display_name"
class="w-full pt-3 pb-2 text-responsive"
[(ngModel)]="displayName"
(ngModelChange)="checkThemeExistence()"
(keyup)="checkThemeExistence()"
formControlName="displayName"
(keyup)="onThemeNameChange()"
[pTooltip]="'THEME.DISPLAY_NAME' | translate"
tooltipPosition="top"
tooltipEvent="hover"
Expand All @@ -61,12 +64,20 @@
<app-theme-color-box *ngIf="properties" [properties]="properties" styleClass="h-inputtext w-15rem" />
<div *ngIf="!properties">{{ 'THEME.NO_PROPERTIES' | translate }}</div>
</div>

<p-message
*ngIf="themeSnapshot && themeNameExists"
severity="warn"
styleClass="mt-3"
id="th_import_name_exists_message"
[text]="'THEME.IMPORT.NAME_EXISTS_MESSAGE' | translate"
></p-message>
<p-message
*ngIf="themeSnapshot && (themeNameExists || displayNameExists)"
*ngIf="themeSnapshot && !themeNameExists && displayNameExists"
severity="warn"
styleClass="mt-3"
id="th_import_exists_message"
[text]="'THEME.IMPORT.THEME_EXISTS_MESSAGE' | translate"
id="th_import_display_name_exists_message"
[text]="'THEME.IMPORT.DISPLAY_NAME_EXISTS_MESSAGE' | translate"
></p-message>
<p-message
*ngIf="themeImportError"
Expand All @@ -83,6 +94,7 @@
id="th_import_button_close"
(onClick)="onImportThemeHide()"
[label]="'ACTIONS.NAVIGATION.CLOSE' | translate"
[ariaLabel]="'ACTIONS.NAVIGATION.CLOSE' | translate"
[pTooltip]="'ACTIONS.NAVIGATION.CLOSE.TOOLTIP' | translate"
tooltipPosition="top"
tooltipEvent="hover"
Expand Down
81 changes: 40 additions & 41 deletions src/app/theme/theme-import/theme-import.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,30 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { HttpResponse, provideHttpClient } from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { FormControl, FormGroup } from '@angular/forms'
import { provideRouter, Router } from '@angular/router'
import { TranslateTestingModule } from 'ngx-translate-testing'
import { of, throwError } from 'rxjs'

import { PortalMessageService } from '@onecx/portal-integration-angular'

import { Theme, ThemesAPIService, GetThemesResponse } from 'src/app/shared/generated'
import { Theme, ThemesAPIService } from 'src/app/shared/generated'
import { ThemeImportComponent } from './theme-import.component'

describe('ThemeImportComponent', () => {
let component: ThemeImportComponent
let fixture: ComponentFixture<ThemeImportComponent>
const themes: Theme[] = [
{ name: 'theme1', displayName: 'Theme-1' },
{ name: 'theme2', displayName: 'Theme-2' }
]
const formGroup = new FormGroup({
themeName: new FormControl(null),
displayName: new FormControl(null)
})

const msgServiceSpy = jasmine.createSpyObj<PortalMessageService>('PortalMessageService', ['success', 'error'])

const themeApiSpy = jasmine.createSpyObj<ThemesAPIService>('ThemesAPIService', ['getThemes', 'importThemes'])
const themeApiSpy = jasmine.createSpyObj<ThemesAPIService>('ThemesAPIService', ['importThemes'])

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
Expand All @@ -37,45 +45,32 @@ describe('ThemeImportComponent', () => {
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents()
themeApiSpy.getThemes.and.returnValue(of({ stream: [] }) as any)
msgServiceSpy.success.calls.reset()
msgServiceSpy.error.calls.reset()
}))

beforeEach(() => {
fixture = TestBed.createComponent(ThemeImportComponent)
component = fixture.componentInstance
component.displayThemeImport = true
component.themes = themes
component.formGroup = formGroup
fixture.detectChanges()
})

it('should create', () => {
expect(component).toBeTruthy()
})

it('should initialize themes and headers onInit', () => {
const themeArr: Theme[] = [
{ name: 'theme1', displayName: 'Theme-1' },
{ name: 'theme2', displayName: 'Theme-2' }
]
const themesResponse: GetThemesResponse = { stream: themeArr }

themeApiSpy.getThemes.and.returnValue(of(themesResponse as any))

component.displayThemeImport = true
component.ngOnInit()

expect(component.themes).toEqual(themeArr)
component.ngOnChanges()
})

it('should read file on theme import select', async () => {
const themeSnapshot = JSON.stringify({
themes: {
themeName: {
displayName: 'themeDisplayName',
logoUrl: 'logo_url',
properties: {
general: {
'primary-color': '#000000'
}
general: { 'primary-color': '#000000' }
}
}
}
Expand All @@ -87,11 +82,9 @@ describe('ThemeImportComponent', () => {

expect(component.themeImportError).toBe(false)
expect(component.themeSnapshot).toBeDefined()
expect(component.properties).toEqual({
general: {
'primary-color': '#000000'
}
})
expect(component.properties).toEqual({ general: { 'primary-color': '#000000' } })
expect(component.formGroup.controls['themeName'].value).toEqual('themeName')
expect(component.formGroup.controls['displayName'].value).toEqual('themeDisplayName')
expect(component.themeNameExists).toBe(false)
})

Expand All @@ -105,7 +98,6 @@ describe('ThemeImportComponent', () => {
expect(component.themeImportError).toBe(true)
expect(component.themeSnapshot).toBe(null)
expect(console.error).toHaveBeenCalledOnceWith('Theme Import Error: not valid data ')
// TODO: if error is visible
})

it('should log error on data parsing error', async () => {
Expand All @@ -121,10 +113,9 @@ describe('ThemeImportComponent', () => {
})

it('should indicate theme name existance if already present', async () => {
component.themes = [{ name: 'themeName', displayName: 'Theme-1' }]
const themeSnapshot = JSON.stringify({
themes: {
themeName: {
theme1: {
displayName: 'Theme-1',
logoUrl: 'logo_url',
properties: {}
Expand All @@ -142,12 +133,12 @@ describe('ThemeImportComponent', () => {
expect(component.displayNameExists).toBe(true)
})

it('should emit displayThemeImportChange on import hide', () => {
spyOn(component.displayThemeImportChange, 'emit')
it('should emit uploadEmitter false on closing import dialog', () => {
spyOn(component.uploadEmitter, 'emit')

component.onImportThemeHide()

expect(component.displayThemeImportChange.emit).toHaveBeenCalledOnceWith(false)
expect(component.uploadEmitter.emit).toHaveBeenCalledOnceWith(false)
})

it('should clear error and import data on import clear', () => {
Expand Down Expand Up @@ -182,22 +173,22 @@ describe('ThemeImportComponent', () => {
created: 'created',
themes: { ['theme']: { description: 'themeDescription' } }
}
component.themeName = 'themeName'
component.displayName = 'themeDisplayName'
component.formGroup.controls['themeName'].setValue('themeName')
component.formGroup.controls['displayName'].setValue('themeDisplayName')
component.properties = {}

component.onThemeUpload()

expect(msgServiceSpy.success).toHaveBeenCalledOnceWith({ summaryKey: 'THEME.IMPORT.IMPORT_THEME_SUCCESS' })
expect(component.uploadEmitter.emit).toHaveBeenCalledTimes(1)
expect(component.uploadEmitter.emit).toHaveBeenCalledOnceWith(true)
})

it('should return if no themes available', () => {
themeApiSpy.importThemes.and.returnValue(of(new HttpResponse({ body: { id: 'id' } })))
spyOn(component.uploadEmitter, 'emit')

component.themeName = 'themeName'
component.displayName = 'themeDisplayName'
component.formGroup.controls['themeName'].setValue('themeName')
component.formGroup.controls['displayName'].setValue('themeDisplayName')
component.properties = {}
component.onThemeUpload()

Expand All @@ -210,7 +201,7 @@ describe('ThemeImportComponent', () => {
themeApiSpy.importThemes.and.returnValue(of(new HttpResponse({ body: { id: 'id' } })))
spyOn(component.uploadEmitter, 'emit')

component.themeName = 'themeName'
component.formGroup.controls['themeName'].setValue('themeName')
component.onThemeUpload()

expect(component.uploadEmitter.emit).not.toHaveBeenCalled()
Expand All @@ -224,11 +215,19 @@ describe('ThemeImportComponent', () => {
themes: { ['theme']: { description: 'themeDescription' } }
}

component.themeName = 'themeName'
component.displayName = 'themeDisplayName'
component.formGroup.controls['themeName'].setValue('themeName')
component.formGroup.controls['displayName'].setValue('themeDisplayName')
component.properties = {}
component.onThemeUpload()

expect(msgServiceSpy.error).toHaveBeenCalledOnceWith({ summaryKey: 'THEME.IMPORT.IMPORT_THEME_FAIL' })
})

it('should not check existence if form is not ready', () => {
component.themeNameExists = true
spyOnProperty(component.formGroup, 'valid').and.returnValue(false)
component.onThemeNameChange()

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

0 comments on commit b8e28f9

Please sign in to comment.