diff --git a/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.html b/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.html index 70fc8e12c..847b0da4b 100644 --- a/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.html +++ b/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.html @@ -17,6 +17,6 @@ \ No newline at end of file diff --git a/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.spec.ts b/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.spec.ts index 0cf02cee8..1c4483f17 100644 --- a/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.spec.ts +++ b/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.spec.ts @@ -5,19 +5,25 @@ import { ClarityModule } from "@clr/angular"; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { PasswordSettingService } from '../password-setting.service'; +import { InlineAlertComponent } from '../../../shared/inline-alert/inline-alert.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { of } from 'rxjs'; describe('ForgotPasswordComponent', () => { let component: ForgotPasswordComponent; let fixture: ComponentFixture; - let fakePasswordSettingService = null; + let fakePasswordSettingService = { + sendResetPasswordMail: () => of(null) + }; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ForgotPasswordComponent], + declarations: [ForgotPasswordComponent, InlineAlertComponent], imports: [ FormsModule, ClarityModule, - TranslateModule.forRoot() + TranslateModule.forRoot(), + BrowserAnimationsModule ], schemas: [CUSTOM_ELEMENTS_SCHEMA], providers: [ @@ -26,14 +32,53 @@ describe('ForgotPasswordComponent', () => { ] }).compileComponents(); })); - + let el; beforeEach(() => { fixture = TestBed.createComponent(ForgotPasswordComponent); component = fixture.componentInstance; - fixture.detectChanges(); + component.inlineAlert = TestBed.createComponent(InlineAlertComponent).componentInstance; + component.open(); + el = fixture.debugElement; + fixture.autoDetectChanges(); + }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should validate email', async () => { + await fixture.whenStable(); + let resetPwdInput: HTMLInputElement = fixture.nativeElement.querySelector('#reset_pwd_email'); + expect(resetPwdInput).toBeTruthy(); + resetPwdInput.value = '1234567'; + resetPwdInput.dispatchEvent(new Event('input')); + resetPwdInput.dispatchEvent(new Event('blur')); + await fixture.whenStable(); + const resetPwdError = fixture.nativeElement.querySelector('#reset_pwd_email-error'); + expect(resetPwdError.innerText).toEqual(' TOOLTIP.EMAIL '); + // success + resetPwdInput.value = '1234567@qq.com'; + resetPwdInput.dispatchEvent(new Event('input')); + resetPwdInput.dispatchEvent(new Event('blur')); + await fixture.whenStable(); + const resetPwdError1 = fixture.nativeElement.querySelector('#reset_pwd_email-error'); + expect(resetPwdError1).toBeNull(); + + }); + it('should send email to back end', async () => { + await fixture.whenStable(); + let resetPwdInput: HTMLInputElement = fixture.nativeElement.querySelector('#reset_pwd_email'); + resetPwdInput.value = '1234567@qq.com'; + resetPwdInput.dispatchEvent(new Event('input')); + resetPwdInput.dispatchEvent(new Event('blur')); + await fixture.whenStable(); + expect(el.nativeElement.querySelector('#submit-btn').disabled).toBeFalsy(); + const submitBtn = fixture.nativeElement.querySelector('#submit-btn'); + submitBtn.dispatchEvent(new Event('click')); + await fixture.whenStable(); + const alertText: HTMLSpanElement = fixture.nativeElement.querySelector('.alert-text'); + expect(alertText.innerText).toEqual(' RESET_PWD.SUCCESS '); + }); + }); diff --git a/src/portal/src/app/account/password-setting/password-setting.component.html b/src/portal/src/app/account/password-setting/password-setting.component.html index 050dde885..044b70f61 100644 --- a/src/portal/src/app/account/password-setting/password-setting.component.html +++ b/src/portal/src/app/account/password-setting/password-setting.component.html @@ -33,7 +33,7 @@ diff --git a/src/portal/src/app/account/password-setting/password-setting.component.spec.ts b/src/portal/src/app/account/password-setting/password-setting.component.spec.ts index a50888ce0..1347d3cf3 100644 --- a/src/portal/src/app/account/password-setting/password-setting.component.spec.ts +++ b/src/portal/src/app/account/password-setting/password-setting.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed, flush } from '@angular/core/testing'; import { PasswordSettingService } from './password-setting.service'; import { SessionService } from '../../shared/session.service'; import { MessageHandlerService } from '../../shared/message-handler/message-handler.service'; @@ -8,20 +8,29 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { FormsModule } from '@angular/forms'; import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { of } from 'rxjs'; describe('PasswordSettingComponent', () => { let component: PasswordSettingComponent; let fixture: ComponentFixture; - let fakePasswordSettingService = null; - let fakeSessionService = null; - let fakeMessageHandlerService = null; + let fakePasswordSettingService = { + changePassword: () => of(null) + }; + let fakeSessionService = { + getCurrentUser: () => true + }; + let fakeMessageHandlerService = { + showSuccess: () => { } + }; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ ClarityModule, TranslateModule.forRoot(), - FormsModule + FormsModule, + BrowserAnimationsModule ], declarations: [PasswordSettingComponent, InlineAlertComponent], providers: [ @@ -38,11 +47,86 @@ describe('PasswordSettingComponent', () => { fixture = TestBed.createComponent(PasswordSettingComponent); component = fixture.componentInstance; component.inlineAlert = - TestBed.createComponent(InlineAlertComponent).componentInstance; - fixture.detectChanges(); + TestBed.createComponent(InlineAlertComponent).componentInstance; + component.oldPwd = "Harbor12345"; + component.open(); + fixture.autoDetectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + it('should verify new Password invalid', async () => { + await fixture.whenStable(); + const newPasswordInput: HTMLInputElement = fixture.nativeElement.querySelector("#newPassword"); + newPasswordInput.value = "HarborHarbor"; + newPasswordInput.dispatchEvent(new Event("input")); + await fixture.whenStable(); + newPasswordInput.dispatchEvent(new Event("blur")); + await fixture.whenStable(); + const newPasswordInputError: any = fixture.nativeElement.querySelector("#newPassword-error"); + expect(newPasswordInputError.innerText) + .toEqual(' TOOLTIP.PASSWORD '); + }); + it('should verify new Password valid', async () => { + await fixture.whenStable(); + const newPasswordInput: HTMLInputElement = fixture.nativeElement.querySelector("#newPassword"); + newPasswordInput.value = "Harbor123456"; + newPasswordInput.dispatchEvent(new Event("input")); + await fixture.whenStable(); + newPasswordInput.dispatchEvent(new Event("blur")); + await fixture.whenStable(); + const newPasswordInputError: any = fixture.nativeElement.querySelector("#newPassword-error"); + expect(newPasswordInputError) + .toBeNull(); + }); + it('should verify comfirm Password invalid', async () => { + await fixture.whenStable(); + const newPasswordInput: HTMLInputElement = fixture.nativeElement.querySelector("#newPassword"); + newPasswordInput.value = "Harbor123456"; + newPasswordInput.dispatchEvent(new Event("blur")); + await fixture.whenStable(); + const reNewPasswordInput: HTMLInputElement = fixture.nativeElement.querySelector("#reNewPassword"); + reNewPasswordInput.value = "Harbor12345"; + reNewPasswordInput.dispatchEvent(new Event("blur")); + await fixture.whenStable(); + const reNewPasswordInputError: any = fixture.nativeElement.querySelector("#reNewPassword-error"); + expect(reNewPasswordInputError.innerText) + .toEqual(' TOOLTIP.CONFIRM_PWD '); + }); + it('should verify comfirm Password valid', async () => { + await fixture.whenStable(); + const newPasswordInput: HTMLInputElement = fixture.nativeElement.querySelector("#newPassword"); + newPasswordInput.value = "Harbor123456"; + newPasswordInput.dispatchEvent(new Event("blur")); + await fixture.whenStable(); + const reNewPasswordInput: HTMLInputElement = fixture.nativeElement.querySelector("#reNewPassword"); + reNewPasswordInput.value = "Harbor123456"; + reNewPasswordInput.dispatchEvent(new Event("input")); + reNewPasswordInput.dispatchEvent(new Event("blur")); + await fixture.whenStable(); + const reNewPasswordInputError: any = fixture.nativeElement.querySelector("#reNewPassword-error"); + expect(reNewPasswordInputError) + .toBeNull(); + }); + it('should save new password', async () => { + await fixture.whenStable(); + const newPasswordInput: HTMLInputElement = fixture.nativeElement.querySelector("#newPassword"); + newPasswordInput.value = "Harbor123456"; + newPasswordInput.dispatchEvent(new Event("input")); + newPasswordInput.dispatchEvent(new Event("blur")); + await fixture.whenStable(); + const reNewPasswordInput: HTMLInputElement = fixture.nativeElement.querySelector("#reNewPassword"); + reNewPasswordInput.value = "Harbor123456"; + reNewPasswordInput.dispatchEvent(new Event("input")); + reNewPasswordInput.dispatchEvent(new Event("blur")); + await fixture.whenStable(); + const okBtn: HTMLButtonElement = fixture.nativeElement.querySelector("#ok-btn"); + okBtn.dispatchEvent(new Event("click")); + await fixture.whenStable(); + + const newPasswordInput1: HTMLInputElement = fixture.nativeElement.querySelector("#newPassword"); + expect(newPasswordInput1) + .toBeNull(); + }); }); diff --git a/src/portal/src/app/account/password-setting/password-setting.service.spec.ts b/src/portal/src/app/account/password-setting/password-setting.service.spec.ts index 495f76116..9a20127de 100644 --- a/src/portal/src/app/account/password-setting/password-setting.service.spec.ts +++ b/src/portal/src/app/account/password-setting/password-setting.service.spec.ts @@ -1,8 +1,11 @@ -import { TestBed, inject } from '@angular/core/testing'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { TestBed, inject, getTestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { PasswordSettingService } from './password-setting.service'; describe('PasswordSettingService', () => { + let injector: TestBed; + let service: PasswordSettingService; + let httpMock: HttpTestingController; beforeEach(() => { TestBed.configureTestingModule({ imports: [ @@ -10,9 +13,45 @@ describe('PasswordSettingService', () => { ], providers: [PasswordSettingService] }); + injector = getTestBed(); + service = injector.get(PasswordSettingService); + httpMock = injector.get(HttpTestingController); }); - it('should be created', inject([PasswordSettingService], (service: PasswordSettingService) => { - expect(service).toBeTruthy(); + it('should be created', inject([PasswordSettingService], (service1: PasswordSettingService) => { + expect(service1).toBeTruthy(); })); + + const mockPasswordSetting = { + old_password: 'string', + new_password: 'string1' + }; + + it('changePassword() should success', () => { + service.changePassword(1, mockPasswordSetting).subscribe((res) => { + expect(res).toEqual(null); + }); + + const req = httpMock.expectOne('/api/users/1/password'); + expect(req.request.method).toBe('PUT'); + req.flush(null); + }); + it('sendResetPasswordMail() should return data', () => { + service.sendResetPasswordMail("123").subscribe((res) => { + expect(res).toEqual(null); + }); + + const req = httpMock.expectOne('/c/sendEmail?email=123'); + expect(req.request.method).toBe('GET'); + req.flush(null); + }); + it('resetPassword() should return data', () => { + service.resetPassword('1234', 'Harbor12345').subscribe((res) => { + expect(res).toEqual(null); + }); + + const req = httpMock.expectOne('/c/reset'); + expect(req.request.method).toBe('POST'); + req.flush(null); + }); }); diff --git a/src/portal/src/app/account/password-setting/reset-password/reset-password.component.spec.ts b/src/portal/src/app/account/password-setting/reset-password/reset-password.component.spec.ts index b07c008a7..db510a4f0 100644 --- a/src/portal/src/app/account/password-setting/reset-password/reset-password.component.spec.ts +++ b/src/portal/src/app/account/password-setting/reset-password/reset-password.component.spec.ts @@ -6,6 +6,9 @@ import { FormsModule } from '@angular/forms'; import { PasswordSettingService } from '../password-setting.service'; import { RouterTestingModule } from '@angular/router/testing'; import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { ClarityModule } from '@clr/angular'; +import { InlineAlertComponent } from '../../../shared/inline-alert/inline-alert.component'; describe('ResetPasswordComponent', () => { let component: ResetPasswordComponent; @@ -18,9 +21,11 @@ describe('ResetPasswordComponent', () => { imports: [ TranslateModule.forRoot(), FormsModule, - RouterTestingModule + RouterTestingModule, + BrowserAnimationsModule, + ClarityModule ], - declarations: [ResetPasswordComponent], + declarations: [ResetPasswordComponent, InlineAlertComponent], providers: [ TranslateService, { provide: PasswordSettingService, useValue: fakePasswordSettingService }, @@ -33,7 +38,9 @@ describe('ResetPasswordComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ResetPasswordComponent); component = fixture.componentInstance; - fixture.detectChanges(); + component.inlineAlert = TestBed.createComponent(InlineAlertComponent).componentInstance; + component.open(); + fixture.autoDetectChanges(); }); it('should create', () => { diff --git a/src/portal/src/app/account/password-setting/reset-password/reset-password.component.ts b/src/portal/src/app/account/password-setting/reset-password/reset-password.component.ts index ee962422c..f3673265b 100644 --- a/src/portal/src/app/account/password-setting/reset-password/reset-password.component.ts +++ b/src/portal/src/app/account/password-setting/reset-password/reset-password.component.ts @@ -37,7 +37,7 @@ export class ResetPasswordComponent implements OnInit { resetOk: boolean = false; confirmPwd: string = ""; - @ViewChild("resetPwdForm", {static: false}) resetPwdForm: NgForm; + @ViewChild("resetPwdForm", {static: true}) resetPwdForm: NgForm; @ViewChild(InlineAlertComponent, {static: false}) inlineAlert: InlineAlertComponent; diff --git a/src/portal/src/app/account/sign-up/sign-up.component.html b/src/portal/src/app/account/sign-up/sign-up.component.html index 957122873..bd1e972e5 100644 --- a/src/portal/src/app/account/sign-up/sign-up.component.html +++ b/src/portal/src/app/account/sign-up/sign-up.component.html @@ -6,7 +6,7 @@ \ No newline at end of file diff --git a/src/portal/src/app/account/sign-up/sign-up.component.spec.ts b/src/portal/src/app/account/sign-up/sign-up.component.spec.ts index edcac1b8f..838c97fca 100644 --- a/src/portal/src/app/account/sign-up/sign-up.component.spec.ts +++ b/src/portal/src/app/account/sign-up/sign-up.component.spec.ts @@ -8,20 +8,41 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { NewUserFormComponent } from '../../shared/new-user-form/new-user-form.component'; import { FormsModule } from '@angular/forms'; import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { of } from 'rxjs'; describe('SignUpComponent', () => { let component: SignUpComponent; let fixture: ComponentFixture; - let fakeSessionService = null; - let fakeUserService = null; - + let fakeSessionService = { + checkUserExisting: () => of(true) + }; + let fakeUserService = { + addUser: () => of(null) + }; + const mockUser = { + user_id: 1, + username: 'string', + realname: 'string', + email: 'string', + password: 'string', + comment: 'string', + deleted: false, + role_name: 'string', + role_id: 1, + has_admin_role: true, + reset_uuid: 'string', + creation_time: 'string', + update_time: 'string', + }; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [SignUpComponent, NewUserFormComponent, InlineAlertComponent], imports: [ FormsModule, ClarityModule, - TranslateModule.forRoot() + TranslateModule.forRoot(), + BrowserAnimationsModule ], providers: [ TranslateService, @@ -39,10 +60,35 @@ describe('SignUpComponent', () => { TestBed.createComponent(NewUserFormComponent).componentInstance; component.inlineAlert = TestBed.createComponent(InlineAlertComponent).componentInstance; - fixture.detectChanges(); + component.opened = true; + fixture.autoDetectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should close when no form change', async () => { + component.open(); + await fixture.whenStable(); + const closeBtn: HTMLButtonElement = fixture.nativeElement.querySelector("#close-btn"); + expect(closeBtn).toBeTruthy(); + closeBtn.dispatchEvent(new Event('click')); + await fixture.whenStable(); + const closeBtn1: HTMLButtonElement = fixture.nativeElement.querySelector("#close-btn"); + expect(closeBtn1).toBeNull(); + + }); + it('should create new user', async () => { + component.open(); + component.getNewUser = () => mockUser; + await fixture.whenStable(); + const createBtn = fixture.nativeElement.querySelector('#create-btn'); + createBtn.dispatchEvent(new Event('click')); + + await fixture.whenStable(); + const closeBtn1: HTMLButtonElement = fixture.nativeElement.querySelector("#close-btn"); + expect(closeBtn1).toBeNull(); + + }); }); diff --git a/src/portal/src/app/app-config.service.spec.ts b/src/portal/src/app/app-config.service.spec.ts index 30f8b8cb9..44eacda88 100644 --- a/src/portal/src/app/app-config.service.spec.ts +++ b/src/portal/src/app/app-config.service.spec.ts @@ -1,12 +1,17 @@ -import { TestBed, inject } from '@angular/core/testing'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { TestBed, inject, getTestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { CookieService } from 'ngx-cookie'; import { AppConfigService } from './app-config.service'; +import { AppConfig } from './app-config'; +import { Component } from '@angular/core'; describe('AppConfigService', () => { + let injector: TestBed; + let service: AppConfigService; + let httpMock: HttpTestingController; let fakeCookieService = { get: function (key) { - return key; + return null; } }; @@ -16,9 +21,27 @@ describe('AppConfigService', () => { providers: [AppConfigService, { provide: CookieService, useValue: fakeCookieService }] }); + injector = getTestBed(); + service = injector.get(AppConfigService); + httpMock = injector.get(HttpTestingController); }); - - it('should be created', inject([AppConfigService], (service: AppConfigService) => { - expect(service).toBeTruthy(); + let systeminfo = new AppConfig(); + it('should be created', inject([AppConfigService], (service1: AppConfigService) => { + expect(service1).toBeTruthy(); })); + + it('load() should return data', () => { + service.load().subscribe((res) => { + expect(res).toEqual(systeminfo); + }); + + const req = httpMock.expectOne('/api/systeminfo'); + expect(req.request.method).toBe('GET'); + req.flush(systeminfo); + expect(service.getConfig()).toEqual(systeminfo); + expect(service.isIntegrationMode()).toBeFalsy(); + expect(service.isLdapMode()).toBeFalsy(); + expect(service.isHttpAuthMode()).toBeFalsy(); + expect(service.isOidcMode()).toBeFalsy(); + }); }); diff --git a/src/portal/src/app/base/global-search/global-search.service.spec.ts b/src/portal/src/app/base/global-search/global-search.service.spec.ts index 9672d2ac0..d3789e49b 100644 --- a/src/portal/src/app/base/global-search/global-search.service.spec.ts +++ b/src/portal/src/app/base/global-search/global-search.service.spec.ts @@ -1,8 +1,15 @@ -import { TestBed, inject } from '@angular/core/testing'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { TestBed, inject, getTestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { GlobalSearchService } from './global-search.service'; +import { Injector } from '@angular/core'; +import { SearchResults } from './search-results'; describe('GlobalSearchService', () => { + let injector: TestBed; + let service: GlobalSearchService; + let httpMock: HttpTestingController; + + beforeEach(() => { TestBed.configureTestingModule({ providers: [GlobalSearchService], @@ -10,9 +17,22 @@ describe('GlobalSearchService', () => { HttpClientTestingModule ] }); + injector = getTestBed(); + service = injector.get(GlobalSearchService); + httpMock = injector.get(HttpTestingController); + }); - it('should be created', inject([GlobalSearchService], (service: GlobalSearchService) => { - expect(service).toBeTruthy(); + it('should be created', inject([GlobalSearchService], (service1: GlobalSearchService) => { + expect(service1).toBeTruthy(); })); + it('doSearch should return data', () => { + service.doSearch("library").subscribe((res) => { + expect(res).toEqual(new SearchResults()); + }); + + const req = httpMock.expectOne('/api/search?q=library'); + expect(req.request.method).toBe('GET'); + req.flush(new SearchResults()); + }); }); diff --git a/src/portal/src/app/base/global-search/search-result.component.spec.ts b/src/portal/src/app/base/global-search/search-result.component.spec.ts index 2f20cebb8..fd2ef1d45 100644 --- a/src/portal/src/app/base/global-search/search-result.component.spec.ts +++ b/src/portal/src/app/base/global-search/search-result.component.spec.ts @@ -5,59 +5,97 @@ import { SearchTriggerService } from './search-trigger.service'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { AppConfigService } from './../../app-config.service'; +import { ListProjectROComponent } from '../../shared/list-project-ro/list-project-ro.component'; import { MessageHandlerService } from '../../shared/message-handler/message-handler.service'; import { SearchResultComponent } from './search-result.component'; import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { of } from 'rxjs'; +import { AppConfig } from '../../app-config'; +import { ClarityModule } from '@clr/angular'; describe('SearchResultComponent', () => { let component: SearchResultComponent; let fixture: ComponentFixture; let fakeSearchResults = null; - let fakeGlobalSearchService = null; - let fakeAppConfigService = null; - let fakeMessageHandlerService = null; - let fakeSearchTriggerService = { - searchTriggerChan$: { - pipe() { - return { - subscribe() { - } - }; - } - }, - searchCloseChan$: { - subscribe() { - } + const project = { + project_id: 1, + owner_id: 1, + name: 'library', + creation_time: Date, + creation_time_str: 'string', + deleted: 1, + owner_name: 'string', + togglable: true, + update_time: Date, + current_user_role_id: 1, + repo_count: 1, + chart_count: 1, + has_project_admin_role: true, + is_member: true, + role_name: 'string', + metadata: { + public: 'string', + enable_content_trust: 'string', + prevent_vul: 'string', + severity: 'string', + auto_scan: 'string', + retention_id: 1 } }; - + let fakeGlobalSearchService = { + doSearch: () => of({ + project: [project], + repository: [], + chart: [] + }) + }; + let fakeAppConfigService = { + getConfig: () => new AppConfig() + }; + let searchResult = ""; + let fakeMessageHandlerService = null; + let fakeSearchTriggerService = { + searchTriggerChan$: of(searchResult), + searchCloseChan$: of(null), + clear: () => null + }; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ TranslateModule.forRoot(), - HttpClientTestingModule - ], - declarations: [SearchResultComponent], - providers: [ - TranslateService, - { provide: GlobalSearchService, useValue: fakeGlobalSearchService }, - { provide: AppConfigService, useValue: fakeAppConfigService }, - { provide: MessageHandlerService, useValue: fakeMessageHandlerService }, - { provide: SearchTriggerService, useValue: fakeSearchTriggerService }, - { provide: SearchResults, fakeSearchResults } - + HttpClientTestingModule, + ClarityModule ], + declarations: [SearchResultComponent, ListProjectROComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA] + }).overrideComponent(SearchResultComponent, { + set: { + providers: [ + TranslateService, + { provide: AppConfigService, useValue: fakeAppConfigService }, + { provide: MessageHandlerService, useValue: fakeMessageHandlerService }, + { provide: SearchTriggerService, useValue: fakeSearchTriggerService }, + { provide: GlobalSearchService, useValue: fakeGlobalSearchService }, + { provide: SearchResults, useValue: fakeSearchResults } + ] + } }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(SearchResultComponent); component = fixture.componentInstance; - fixture.detectChanges(); + component.stateIndicator = true; + fixture.autoDetectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + it('should search library', async () => { + searchResult = 'library'; + component.doSearch(searchResult); + await fixture.whenStable(); + expect(component.searchResults.project[0].name).toEqual('library'); + }); }); diff --git a/src/portal/src/app/base/global-search/search-result.component.ts b/src/portal/src/app/base/global-search/search-result.component.ts index cc03b710c..116fe326b 100644 --- a/src/portal/src/app/base/global-search/search-result.component.ts +++ b/src/portal/src/app/base/global-search/search-result.component.ts @@ -140,7 +140,13 @@ export class SearchResultComponent implements OnInit, OnDestroy { // Call search service to complete the search request doSearch(term: string): void { // Only search none empty term + // If term is empty, then clear the results if (!term || term.trim() === "") { + this.searchResults.project = []; + this.searchResults.repository = []; + if (this.withHelmChart) { + this.searchResults.chart = []; + } return; } // Do nothing if search is ongoing @@ -154,15 +160,6 @@ export class SearchResultComponent implements OnInit, OnDestroy { this.currentTerm = term; - // If term is empty, then clear the results - if (term === "") { - this.searchResults.project = []; - this.searchResults.repository = []; - if (this.withHelmChart) { - this.searchResults.chart = []; - } - return; - } // Show spinner this.onGoing = true; diff --git a/src/portal/src/app/base/harbor-shell/harbor-shell.component.spec.ts b/src/portal/src/app/base/harbor-shell/harbor-shell.component.spec.ts index ee35e610e..9c192922b 100644 --- a/src/portal/src/app/base/harbor-shell/harbor-shell.component.spec.ts +++ b/src/portal/src/app/base/harbor-shell/harbor-shell.component.spec.ts @@ -10,6 +10,16 @@ import { HarborShellComponent } from './harbor-shell.component'; import { ClarityModule } from "@clr/angular"; import { of } from 'rxjs'; import { ConfigScannerService } from "../../config/scanner/config-scanner.service"; +import { modalEvents } from '../modal-events.const'; +import { AccountSettingsModalComponent } from '../../account/account-settings/account-settings-modal.component'; +import { PasswordSettingComponent } from '../../account/password-setting/password-setting.component'; +import { AboutDialogComponent } from '../../shared/about-dialog/about-dialog.component'; +import { FormsModule } from '@angular/forms'; +import { MessageHandlerService } from '../../shared/message-handler/message-handler.service'; +import { AccountSettingsModalService } from '../../account/account-settings/account-settings-modal-service.service'; +import { PasswordSettingService } from '../../account/password-setting/password-setting.service'; +import { SkinableConfig } from '../../skinable-config.service'; +import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component'; describe('HarborShellComponent', () => { let component: HarborShellComponent; @@ -20,13 +30,18 @@ describe('HarborShellComponent', () => { } }; let fakeSearchTriggerService = { - searchTriggerChan$: { - subscribe: function () { - } - }, - searchCloseChan$: { - subscribe: function () { - } + searchTriggerChan$: of('null') + , + searchCloseChan$: of(null) + }; + let mockMessageHandlerService = null; + let mockAccountSettingsModalService = null; + let mockPasswordSettingService = null; + let mockSkinableConfig = { + getProject: function () { + return { + introduction: {} + }; } }; let fakeAppConfigService = { @@ -56,15 +71,21 @@ describe('HarborShellComponent', () => { RouterTestingModule, TranslateModule.forRoot(), ClarityModule, - BrowserAnimationsModule + BrowserAnimationsModule, + FormsModule ], - declarations: [HarborShellComponent], + declarations: [HarborShellComponent, AccountSettingsModalComponent + , PasswordSettingComponent, AboutDialogComponent, InlineAlertComponent], providers: [ TranslateService, { provide: SessionService, useValue: fakeSessionService }, { provide: SearchTriggerService, useValue: fakeSearchTriggerService }, { provide: AppConfigService, useValue: fakeAppConfigService }, - { provide: ConfigScannerService, useValue: fakeConfigScannerService } + { provide: ConfigScannerService, useValue: fakeConfigScannerService }, + { provide: MessageHandlerService, useValue: mockMessageHandlerService }, + { provide: AccountSettingsModalService, useValue: mockAccountSettingsModalService }, + { provide: PasswordSettingService, useValue: mockPasswordSettingService }, + { provide: SkinableConfig, useValue: mockSkinableConfig }, ], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA] }).compileComponents(); @@ -74,10 +95,32 @@ describe('HarborShellComponent', () => { fixture = TestBed.createComponent(HarborShellComponent); component = fixture.componentInstance; component.showScannerInfo = true; - fixture.detectChanges(); + component.accountSettingsModal = TestBed.createComponent(AccountSettingsModalComponent).componentInstance; + component.accountSettingsModal.inlineAlert = TestBed.createComponent(InlineAlertComponent).componentInstance; + component.pwdSetting = TestBed.createComponent(PasswordSettingComponent).componentInstance; + component.aboutDialog = TestBed.createComponent(AboutDialogComponent).componentInstance; + fixture.autoDetectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + it('should open users profile', async () => { + component.openModal({modalName: modalEvents.USER_PROFILE, modalFlag: false }); + await fixture.whenStable(); + const accountSettingsUsernameInput = fixture.nativeElement.querySelector("#account_settings_username"); + expect(accountSettingsUsernameInput).toBeTruthy(); + }); + it('should open users changPwd', async () => { + component.openModal({modalName: modalEvents.CHANGE_PWD, modalFlag: false }); + await fixture.whenStable(); + const oldPasswordInput = fixture.nativeElement.querySelector("#oldPassword"); + expect(oldPasswordInput).toBeTruthy(); + }); + it('should open users about-dialog', async () => { + component.openModal({modalName: modalEvents.ABOUT, modalFlag: false }); + await fixture.whenStable(); + const aboutVersionEl = fixture.nativeElement.querySelector(".about-version"); + expect(aboutVersionEl).toBeTruthy(); + }); }); diff --git a/src/portal/src/app/config/auth/config-auth.component.html b/src/portal/src/app/config/auth/config-auth.component.html index 1aecd99fc..794249a8c 100644 --- a/src/portal/src/app/config/auth/config-auth.component.html +++ b/src/portal/src/app/config/auth/config-auth.component.html @@ -399,7 +399,7 @@ [disabled]="!isValid() || !hasChanges()">{{'BUTTON.SAVE' | translate}} - \ No newline at end of file diff --git a/src/portal/src/app/config/auth/config-auth.component.spec.ts b/src/portal/src/app/config/auth/config-auth.component.spec.ts index 74032eed9..0a5f1cd7a 100644 --- a/src/portal/src/app/config/auth/config-auth.component.spec.ts +++ b/src/portal/src/app/config/auth/config-auth.component.spec.ts @@ -5,18 +5,29 @@ import { AppConfigService } from '../../app-config.service'; import { ConfigurationService } from '../config.service'; import { ConfigurationAuthComponent } from './config-auth.component'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { of } from 'rxjs'; import { ErrorHandler } from "../../../lib/utils/error-handler"; import { SystemInfoService } from "../../../lib/services"; +import { Configuration } from '../../../lib/components/config/config'; +import { clone } from '../../../lib/utils/utils'; +import { CONFIG_AUTH_MODE } from '../../../lib/entities/shared.const'; describe('ConfigurationAuthComponent', () => { let component: ConfigurationAuthComponent; let fixture: ComponentFixture; - let fakeMessageHandlerService = null; - let fakeConfigurationService = null; - let fakeAppConfigService = null; + let fakeMessageHandlerService = { + showSuccess: () => null + }; + let fakeConfigurationService = { + saveConfiguration: () => of(null), + testLDAPServer: () => of(null), + testOIDCServer: () => of(null) + }; + let fakeAppConfigService = { + load: () => of(null) + }; let fakeConfirmMessageService = null; let fakeSystemInfoService = { getSystemInfo: function () { @@ -49,10 +60,46 @@ describe('ConfigurationAuthComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ConfigurationAuthComponent); component = fixture.componentInstance; - fixture.detectChanges(); + (component as any).originalConfig = clone(component.currentConfig); + fixture.autoDetectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should save configuration', async () => { + const selfRegInput: HTMLInputElement = fixture.nativeElement.querySelector("#selfReg"); + selfRegInput.dispatchEvent(new Event('click')); + component.currentConfig.self_registration.value = true; + await fixture.whenStable(); + const configAuthSaveBtn: HTMLButtonElement = fixture.nativeElement.querySelector("#config_auth_save"); + component.onGoing = true; + configAuthSaveBtn.dispatchEvent(new Event('click')); + await fixture.whenStable(); + expect(component.onGoing).toBeFalsy(); + }); + it('should select ldap or uaa', () => { + component.handleOnChange({target: {value: 'ldap_auth'}}); + expect(component.currentConfig.self_registration.value).toEqual(false); + }); + it('should ping test server when ldap', async () => { + component.currentConfig.auth_mode.value = CONFIG_AUTH_MODE.LDAP_AUTH; + component.currentConfig.ldap_scope.value = 123456; + await fixture.whenStable(); + const pingTestBtn = fixture.nativeElement.querySelector("#ping-test"); + expect(pingTestBtn).toBeTruthy(); + pingTestBtn.dispatchEvent(new Event('click')); + await fixture.whenStable(); + expect(component.testingOnGoing).toBeFalsy(); + }); + it('should ping test server when oidc', async () => { + component.currentConfig.auth_mode.value = CONFIG_AUTH_MODE.OIDC_AUTH; + await fixture.whenStable(); + const pingTestBtn = fixture.nativeElement.querySelector("#ping-test"); + expect(pingTestBtn).toBeTruthy(); + pingTestBtn.dispatchEvent(new Event('click')); + await fixture.whenStable(); + expect(component.testingOnGoing).toBeFalsy(); + }); }); diff --git a/src/portal/src/app/config/config.component.spec.ts b/src/portal/src/app/config/config.component.spec.ts index b08f679c4..53bde1217 100644 --- a/src/portal/src/app/config/config.component.spec.ts +++ b/src/portal/src/app/config/config.component.spec.ts @@ -8,17 +8,43 @@ import { ClarityModule } from "@clr/angular"; import { AppConfigService } from '../app-config.service'; import { ConfigurationService } from './config.service'; import { ConfigurationComponent } from './config.component'; +import { of } from 'rxjs'; +import { ConfirmationAcknowledgement } from '../shared/confirmation-dialog/confirmation-state-message'; +import { ConfirmationState, ConfirmationTargets } from '../shared/shared.const'; +import { Configuration } from '../../lib/components/config/config'; describe('ConfigurationComponent', () => { let component: ConfigurationComponent; let fixture: ComponentFixture; - let fakeConfirmationDialogService = { - confirmationConfirm$: { - subscribe: function () { - } - } + let confirmationConfirmFlag = true; + let confirmationConfirm = () => { + return confirmationConfirmFlag ? of(new ConfirmationAcknowledgement(ConfirmationState.CONFIRMED, {}, ConfirmationTargets.CONFIG)) + : of(new ConfirmationAcknowledgement(ConfirmationState.CONFIRMED + , {change: { email_password: 'Harbor12345' }, tabId: '1'}, ConfirmationTargets.CONFIG_TAB)); + }; + let fakeConfirmationDialogService = { + confirmationConfirm$: confirmationConfirm() + }; + let mockConfigurationService = { + getConfiguration: () => of(new Configuration()), + confirmationConfirm$: of(new ConfirmationAcknowledgement(ConfirmationState.CONFIRMED, {}, ConfirmationTargets.CONFIG)) + }; + let fakeSessionService = { + getCurrentUser: function () { + return { + has_admin_role: true, + user_id: 1, + username: 'admin', + email: "", + realname: "admin", + role_name: "admin", + role_id: 1, + comment: "string", + }; + }, + updateAccountSettings: () => of(null), + renameAdmin: () => of(null), }; - beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ @@ -37,6 +63,7 @@ describe('ConfigurationComponent', () => { } }, { provide: ConfirmationDialogService, useValue: fakeConfirmationDialogService }, + { provide: SessionService, useValue: fakeSessionService }, { provide: MessageHandlerService, useValue: null }, { provide: AppConfigService, useValue: { @@ -46,12 +73,7 @@ describe('ConfigurationComponent', () => { } }, { - provide: ConfigurationService, useValue: { - confirmationConfirm$: { - subscribe: function () { - } - } - } + provide: ConfigurationService, useValue: mockConfigurationService } ] }).compileComponents(); @@ -66,4 +88,16 @@ describe('ConfigurationComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + it('should reset part of allConfig ', async () => { + confirmationConfirmFlag = false; + component.originalCopy.email_password.value = 'Harbor12345'; + component.reset({ + email_password: { + value: 'Harbor12345', + editable: true + } + }); + await fixture.whenStable(); + expect(component.allConfig.email_password.value).toEqual('Harbor12345'); + }); }); diff --git a/src/portal/src/app/config/config.component.ts b/src/portal/src/app/config/config.component.ts index 2d5ef8921..86acbf585 100644 --- a/src/portal/src/app/config/config.component.ts +++ b/src/portal/src/app/config/config.component.ts @@ -70,13 +70,6 @@ export class ConfigurationComponent implements OnInit, OnDestroy { return this.appConfigService.getConfig().with_admiral; } - isCurrentTabLink(tabId: string): boolean { - return this.currentTabId === tabId; - } - - isCurrentTabContent(contentId: string): boolean { - return TabLinkContentMap[this.currentTabId] === contentId; - } refreshAllconfig() { this.retrieveConfig(); } @@ -124,10 +117,6 @@ export class ConfigurationComponent implements OnInit, OnDestroy { , error => console.error('Failed to reload bootstrap option with error: ', error)); } - public tabLinkClick(tabLink: string) { - this.currentTabId = tabLink; - } - retrieveConfig(): void { this.onGoing = true; this.configService.getConfiguration() diff --git a/src/portal/src/app/config/email/config-email.component.html b/src/portal/src/app/config/email/config-email.component.html index 2e8aaa57e..b5a4ae5a4 100644 --- a/src/portal/src/app/config/email/config-email.component.html +++ b/src/portal/src/app/config/email/config-email.component.html @@ -79,7 +79,7 @@ | translate}} - \ No newline at end of file diff --git a/src/portal/src/app/config/email/config-email.component.spec.ts b/src/portal/src/app/config/email/config-email.component.spec.ts index c036a68c3..781cbec2b 100644 --- a/src/portal/src/app/config/email/config-email.component.spec.ts +++ b/src/portal/src/app/config/email/config-email.component.spec.ts @@ -6,11 +6,19 @@ import { ConfigurationEmailComponent } from './config-email.component'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { FormsModule } from '@angular/forms'; +import { clone } from '../../../lib/utils/utils'; +import { of } from 'rxjs'; describe('ConfigurationEmailComponent', () => { let component: ConfigurationEmailComponent; let fixture: ComponentFixture; - + let fakeConfigurationService = { + saveConfiguration: () => of(null), + testMailServer: () => of(null) + }; + let fakeMessageHandlerService = { + showSuccess: () => null + }; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ @@ -19,10 +27,10 @@ describe('ConfigurationEmailComponent', () => { ], declarations: [ConfigurationEmailComponent], providers: [ - { provide: MessageHandlerService, useValue: null }, + { provide: MessageHandlerService, useValue: fakeMessageHandlerService }, TranslateService, { provide: ConfirmMessageHandler, useValue: null }, - { provide: ConfigurationService, useValue: null } + { provide: ConfigurationService, useValue: fakeConfigurationService } ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }).compileComponents(); @@ -31,10 +39,34 @@ describe('ConfigurationEmailComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ConfigurationEmailComponent); component = fixture.componentInstance; + (component as any).originalConfig = clone(component.currentConfig); fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should save configuration', async () => { + component.currentConfig.email_host.value = 'smtp.mydomain.com'; + component.currentConfig.email_port.value = 25; + component.currentConfig.email_from.value = 'smtp.mydomain.com'; + await fixture.whenStable(); + const configEmailSaveBtn: HTMLButtonElement = fixture.nativeElement.querySelector("#config_email_save"); + component.onGoing = true; + configEmailSaveBtn.dispatchEvent(new Event('click')); + await fixture.whenStable(); + expect(component.onGoing).toBeFalsy(); + }); + it('should ping test server', async () => { + component.currentConfig.email_host.value = 'smtp.mydomain.com'; + component.currentConfig.email_port.value = 25; + component.currentConfig.email_from.value = 'smtp.mydomain.com'; + await fixture.whenStable(); + const pingTestBtn = fixture.nativeElement.querySelector("#ping-test"); + expect(pingTestBtn).toBeTruthy(); + pingTestBtn.dispatchEvent(new Event('click')); + await fixture.whenStable(); + expect(component.testingMailOnGoing).toBeFalsy(); + }); }); diff --git a/src/portal/src/app/dev-center/dev-center.component.spec.ts b/src/portal/src/app/dev-center/dev-center.component.spec.ts index 704da4104..f0f1f0893 100644 --- a/src/portal/src/app/dev-center/dev-center.component.spec.ts +++ b/src/portal/src/app/dev-center/dev-center.component.spec.ts @@ -1,5 +1,5 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { async, ComponentFixture, TestBed, getTestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { DevCenterComponent } from './dev-center.component'; import { CookieService } from 'ngx-cookie'; @@ -12,6 +12,9 @@ describe('DevCenterComponent', () => { return "xsrf"; } }; + let cookie = "fdsa|ds"; + let injector: TestBed; + let httpMock: HttpTestingController; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [DevCenterComponent], @@ -27,16 +30,25 @@ describe('DevCenterComponent', () => { ], }) .compileComponents(); + injector = getTestBed(); + httpMock = injector.get(HttpTestingController); })); beforeEach(() => { fixture = TestBed.createComponent(DevCenterComponent); component = fixture.componentInstance; - fixture.detectChanges(); + fixture.autoDetectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + it('get swagger should return data', () => { + const req = httpMock.expectOne('/swagger.json'); + expect(req.request.method).toBe('GET'); + req.flush({ + "host": '122.33', + }); + }); }); diff --git a/src/portal/src/app/group/add-group-modal/add-group-modal.component.spec.ts b/src/portal/src/app/group/add-group-modal/add-group-modal.component.spec.ts index 2979392fe..466deeeda 100644 --- a/src/portal/src/app/group/add-group-modal/add-group-modal.component.spec.ts +++ b/src/portal/src/app/group/add-group-modal/add-group-modal.component.spec.ts @@ -9,6 +9,7 @@ import { SessionService } from "./../../shared/session.service"; import { UserGroup } from "./../group"; import { AppConfigService } from "../../app-config.service"; import { AddGroupModalComponent } from './add-group-modal.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; describe('AddGroupModalComponent', () => { let component: AddGroupModalComponent; @@ -38,6 +39,7 @@ describe('AddGroupModalComponent', () => { imports: [ ClarityModule, FormsModule, + BrowserAnimationsModule, TranslateModule.forRoot() ], schemas: [ @@ -57,7 +59,8 @@ describe('AddGroupModalComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(AddGroupModalComponent); component = fixture.componentInstance; - fixture.detectChanges(); + component.open(); + fixture.autoDetectChanges(); }); it('should create', () => { diff --git a/src/portal/src/app/skinable-config.service.spec.ts b/src/portal/src/app/skinable-config.service.spec.ts index b6a898409..87541bbe1 100644 --- a/src/portal/src/app/skinable-config.service.spec.ts +++ b/src/portal/src/app/skinable-config.service.spec.ts @@ -1,8 +1,27 @@ -import { TestBed, inject } from '@angular/core/testing'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { TestBed, inject, getTestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { SkinableConfig } from './skinable-config.service'; describe('SkinableConfig', () => { + let injector: TestBed; + let service: SkinableConfig; + let httpMock: HttpTestingController; + let product = { + "name": "", + "introduction": { + "zh-cn": "", + "es-es": "", + "en-us": "" + } + }; + let mockCustomSkinData = { + "headerBgColor": "", + "headerLogo": "", + "loginBgImg": "", + "appTitle": "", + "product": product + }; + beforeEach(() => { TestBed.configureTestingModule({ imports: [ @@ -10,9 +29,26 @@ describe('SkinableConfig', () => { ], providers: [SkinableConfig] }); + injector = getTestBed(); + service = injector.get(SkinableConfig); + httpMock = injector.get(HttpTestingController); }); - it('should be created', inject([SkinableConfig], (service: SkinableConfig) => { - expect(service).toBeTruthy(); + it('should be created', inject([SkinableConfig], (service1: SkinableConfig) => { + expect(service1).toBeTruthy(); })); + it('getCustomFile() should return data', () => { + service.getCustomFile().subscribe((res) => { + expect(res).toEqual(mockCustomSkinData); + }); + + const req = httpMock.expectOne('setting.json'); + expect(req.request.method).toBe('GET'); + req.flush(mockCustomSkinData); + expect(service.getSkinConfig()).toEqual(mockCustomSkinData); + expect(service.getProject()).toEqual(product); + service.customSkinData = null; + expect(service.getProject()).toBeNull(); + + }); }); diff --git a/src/portal/src/lib/components/config/config.ts b/src/portal/src/lib/components/config/config.ts index 921cbd2ca..6149104d0 100644 --- a/src/portal/src/lib/components/config/config.ts +++ b/src/portal/src/lib/components/config/config.ts @@ -70,6 +70,7 @@ export class Configuration { ldap_group_attribute_name: StringValueItem; ldap_group_search_scope: NumberValueItem; ldap_group_membership_attribute: StringValueItem; + ldap_group_admin_dn: StringValueItem; uaa_client_id: StringValueItem; uaa_client_secret?: StringValueItem; uaa_endpoint: StringValueItem; @@ -120,6 +121,7 @@ export class Configuration { this.ldap_group_attribute_name = new StringValueItem("", true); this.ldap_group_search_scope = new NumberValueItem(0, true); this.ldap_group_membership_attribute = new StringValueItem("", true); + this.ldap_group_admin_dn = new StringValueItem("", true); this.uaa_client_id = new StringValueItem("", true); this.uaa_client_secret = new StringValueItem("", true); this.uaa_endpoint = new StringValueItem("", true);