diff --git a/src/app/extensions/captcha/shared/captcha/captcha-v2/captcha-v2.component.spec.ts b/src/app/extensions/captcha/shared/captcha/captcha-v2/captcha-v2.component.spec.ts
index bc50e5e440b..6fad94c7070 100644
--- a/src/app/extensions/captcha/shared/captcha/captcha-v2/captcha-v2.component.spec.ts
+++ b/src/app/extensions/captcha/shared/captcha/captcha-v2/captcha-v2.component.spec.ts
@@ -2,6 +2,10 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { RecaptchaModule } from 'ng-recaptcha';
+import { of } from 'rxjs';
+import { instance, mock, when } from 'ts-mockito';
+
+import { CaptchaFacade } from '../../../facades/captcha.facade';
import { CaptchaV2Component } from './captcha-v2.component';
@@ -11,9 +15,13 @@ describe('Captcha V2 Component', () => {
let element: HTMLElement;
beforeEach(async(() => {
+ const captchaFacade = mock(CaptchaFacade);
+ when(captchaFacade.captchaSiteKey$).thenReturn(of('captchaV2SiteKey'));
+
TestBed.configureTestingModule({
declarations: [CaptchaV2Component],
imports: [ReactiveFormsModule, RecaptchaModule.forRoot(), TranslateModule.forRoot()],
+ providers: [{ provide: CaptchaFacade, useFactory: () => instance(captchaFacade) }],
}).compileComponents();
}));
@@ -21,9 +29,8 @@ describe('Captcha V2 Component', () => {
fixture = TestBed.createComponent(CaptchaV2Component);
component = fixture.componentInstance;
element = fixture.nativeElement;
- component.captchaSiteKey = 'captchaV2SiteKey';
- const fb: FormBuilder = TestBed.get(FormBuilder);
+ const fb = TestBed.inject(FormBuilder);
component.parentForm = fb.group({
captcha: fb.control(''),
captchaAction: fb.control(''),
diff --git a/src/app/extensions/captcha/shared/captcha/captcha-v2/captcha-v2.component.ts b/src/app/extensions/captcha/shared/captcha/captcha-v2/captcha-v2.component.ts
index c79db8c7d46..ff7ac8d5ad3 100644
--- a/src/app/extensions/captcha/shared/captcha/captcha-v2/captcha-v2.component.ts
+++ b/src/app/extensions/captcha/shared/captcha/captcha-v2/captcha-v2.component.ts
@@ -1,5 +1,11 @@
-import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input, NgModule, OnInit } from '@angular/core';
import { AbstractControl, FormGroup } from '@angular/forms';
+import { RecaptchaModule } from 'ng-recaptcha';
+import { Observable } from 'rxjs';
+
+import { SharedModule } from 'ish-shared/shared.module';
+
+import { CaptchaFacade } from '../../../facades/captcha.facade';
/**
* The Captcha V2 Component
@@ -12,35 +18,36 @@ import { AbstractControl, FormGroup } from '@angular/forms';
changeDetection: ChangeDetectionStrategy.Default,
})
export class CaptchaV2Component implements OnInit {
- @Input() captchaSiteKey: string;
@Input() parentForm: FormGroup;
@Input() cssClass: string;
+ captchaSiteKey$: Observable;
+
+ constructor(private captchaFacade: CaptchaFacade) {}
+
ngOnInit() {
- this.getActionFormControl().setValue(undefined);
- this.getFormControl().updateValueAndValidity();
+ this.captchaSiteKey$ = this.captchaFacade.captchaSiteKey$;
+
+ this.parentForm.get('captchaAction').setValue(undefined);
+ this.formControl.updateValueAndValidity();
}
/* writes the captcha response token in the captcha form field */
resolved(captchaResponse: string) {
- this.getFormControl().setValue(captchaResponse);
+ this.formControl.setValue(captchaResponse);
}
- /**
- * get the captcha form control according to the controlName
- */
- getFormControl(): AbstractControl {
- return this.parentForm && this.parentForm.get('captcha');
- }
-
- /**
- * get the captcha action form control according to the controlName
- */
- getActionFormControl(): AbstractControl {
- return this.parentForm.get('captchaAction');
+ private get formControl(): AbstractControl {
+ return this.parentForm?.get('captcha');
}
get hasError(): boolean {
- return this.getFormControl() && this.getFormControl().invalid && this.getFormControl().dirty;
+ return this.formControl?.invalid && this?.formControl.dirty;
}
}
+
+@NgModule({
+ declarations: [CaptchaV2Component],
+ imports: [RecaptchaModule, SharedModule],
+})
+export class CaptchaV2ComponentModule {}
diff --git a/src/app/extensions/captcha/shared/captcha/captcha-v3/captcha-v3.component.spec.ts b/src/app/extensions/captcha/shared/captcha/captcha-v3/captcha-v3.component.spec.ts
index 3b7e39e21b8..bee7f31f40b 100644
--- a/src/app/extensions/captcha/shared/captcha/captcha-v3/captcha-v3.component.spec.ts
+++ b/src/app/extensions/captcha/shared/captcha/captcha-v3/captcha-v3.component.spec.ts
@@ -1,4 +1,5 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
+import { FormControl, FormGroup } from '@angular/forms';
import { RECAPTCHA_V3_SITE_KEY, RecaptchaV3Module } from 'ng-recaptcha';
import { CaptchaV3Component } from './captcha-v3.component';
@@ -21,6 +22,10 @@ describe('Captcha V3 Component', () => {
fixture = TestBed.createComponent(CaptchaV3Component);
component = fixture.componentInstance;
element = fixture.nativeElement;
+ component.parentForm = new FormGroup({
+ captcha: new FormControl(''),
+ captchaAction: new FormControl(''),
+ });
});
it('should be created', () => {
diff --git a/src/app/extensions/captcha/shared/captcha/captcha-v3/captcha-v3.component.ts b/src/app/extensions/captcha/shared/captcha/captcha-v3/captcha-v3.component.ts
index ec52062c9f0..b8bb8100168 100644
--- a/src/app/extensions/captcha/shared/captcha/captcha-v3/captcha-v3.component.ts
+++ b/src/app/extensions/captcha/shared/captcha/captcha-v3/captcha-v3.component.ts
@@ -1,9 +1,14 @@
-import { ChangeDetectionStrategy, Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input, NgModule, OnDestroy, OnInit } from '@angular/core';
import { FormGroup, Validators } from '@angular/forms';
-import { ReCaptchaV3Service } from 'ng-recaptcha';
+import { RECAPTCHA_V3_SITE_KEY, ReCaptchaV3Service, RecaptchaV3Module } from 'ng-recaptcha';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
+import {
+ SitekeyProviderService,
+ getSynchronizedSiteKey,
+} from '../../../services/sitekey-provider/sitekey-provider.service';
+
/**
* The Captcha V3 Component
*
@@ -14,26 +19,40 @@ import { takeUntil } from 'rxjs/operators';
template: '',
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class CaptchaV3Component implements OnChanges, OnDestroy {
+// tslint:disable-next-line: no-intelligence-in-artifacts
+export class CaptchaV3Component implements OnInit, OnDestroy {
@Input() parentForm: FormGroup;
private destroy$ = new Subject();
constructor(private recaptchaV3Service: ReCaptchaV3Service) {}
- /* write the captcha response token in the captcha form field */
- ngOnChanges(c: SimpleChanges) {
+ ngOnInit() {
this.parentForm.get('captchaAction').setValidators([Validators.required]);
- if (this.parentForm && c.parentForm.isFirstChange()) {
- this.recaptchaV3Service
- .execute(this.parentForm.get('captchaAction').value)
- .pipe(takeUntil(this.destroy$))
- .subscribe(token => this.parentForm.get('captcha').setValue(token));
- }
+ this.recaptchaV3Service
+ .execute(this.parentForm.get('captchaAction').value)
+ .pipe(takeUntil(this.destroy$))
+ .subscribe(token => {
+ this.parentForm.get('captcha').setValue(token);
+ this.parentForm.get('captcha').updateValueAndValidity();
+ });
}
ngOnDestroy() {
this.destroy$.next();
}
}
+
+@NgModule({
+ imports: [RecaptchaV3Module],
+ declarations: [CaptchaV3Component],
+ providers: [
+ {
+ provide: RECAPTCHA_V3_SITE_KEY,
+ useFactory: getSynchronizedSiteKey,
+ deps: [SitekeyProviderService],
+ },
+ ],
+})
+export class CaptchaV3ComponentModule {}
diff --git a/src/app/extensions/captcha/shared/captcha/captcha/captcha.component.html b/src/app/extensions/captcha/shared/captcha/captcha/captcha.component.html
deleted file mode 100644
index 5ea21dbe4f6..00000000000
--- a/src/app/extensions/captcha/shared/captcha/captcha/captcha.component.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
diff --git a/src/app/extensions/captcha/shared/captcha/captcha/captcha.component.spec.ts b/src/app/extensions/captcha/shared/captcha/captcha/captcha.component.spec.ts
deleted file mode 100644
index 97dea456326..00000000000
--- a/src/app/extensions/captcha/shared/captcha/captcha/captcha.component.spec.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { ComponentFixture, TestBed, async } from '@angular/core/testing';
-import { FormControl, FormGroup } from '@angular/forms';
-import { MockComponent } from 'ng-mocks';
-import { of } from 'rxjs';
-import { anyString, instance, mock, when } from 'ts-mockito';
-
-import { configurationReducer } from 'ish-core/store/configuration/configuration.reducer';
-import { ngrxTesting } from 'ish-core/utils/dev/ngrx-testing';
-
-import { CaptchaFacade } from '../../../facades/captcha.facade';
-import { CaptchaV2Component } from '../captcha-v2/captcha-v2.component';
-import { CaptchaV3Component } from '../captcha-v3/captcha-v3.component';
-
-import { CaptchaComponent } from './captcha.component';
-
-describe('Captcha Component', () => {
- let fixture: ComponentFixture;
- let component: CaptchaComponent;
- let element: HTMLElement;
-
- beforeEach(async(() => {
- const captchaFacade = mock(CaptchaFacade);
- when(captchaFacade.captchaVersion$).thenReturn(of(2 as 2));
- when(captchaFacade.captchaSiteKey$).thenReturn(of('captchaSiteKeyASDF'));
- when(captchaFacade.captchaActive$(anyString())).thenReturn(of(true));
-
- TestBed.configureTestingModule({
- declarations: [CaptchaComponent, MockComponent(CaptchaV2Component), MockComponent(CaptchaV3Component)],
- imports: [
- ngrxTesting({
- reducers: { configuration: configurationReducer },
- }),
- ],
- providers: [{ provide: CaptchaFacade, useFactory: () => instance(captchaFacade) }],
- }).compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(CaptchaComponent);
- component = fixture.componentInstance;
- element = fixture.nativeElement;
- component.form = new FormGroup({
- captcha: new FormControl(''),
- captchaAction: new FormControl(''),
- });
- component.cssClass = 'd-none';
- });
-
- it('should be created', () => {
- expect(component).toBeTruthy();
- expect(element).toBeTruthy();
- expect(() => fixture.detectChanges()).not.toThrow();
- expect(element).toMatchInlineSnapshot(`
-
- `);
- });
-
- // errors are thrown if required input parameters are missing
- it('should throw an error if there is no form set as input parameter', () => {
- component.form = undefined;
- expect(() => fixture.detectChanges()).toThrowErrorMatchingInlineSnapshot(
- `"required input parameter