diff --git a/src/app/extensions/captcha/exports/lazy-captcha/lazy-captcha.component.spec.ts b/src/app/extensions/captcha/exports/lazy-captcha/lazy-captcha.component.spec.ts
index d10339efbd..1d6725f378 100644
--- a/src/app/extensions/captcha/exports/lazy-captcha/lazy-captcha.component.spec.ts
+++ b/src/app/extensions/captcha/exports/lazy-captcha/lazy-captcha.component.spec.ts
@@ -1,10 +1,14 @@
import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { FormControl, FormGroup } from '@angular/forms';
import { By } from '@angular/platform-browser';
-import { RECAPTCHA_V3_SITE_KEY } from 'ng-recaptcha';
+import { TranslateModule } from '@ngx-translate/core';
+import { MockDirective } from 'ng-mocks';
+import { RECAPTCHA_V3_SITE_KEY, ReCaptchaV3Service } from 'ng-recaptcha';
import { EMPTY, of } from 'rxjs';
import { anyString, instance, mock, when } from 'ts-mockito';
+import { ServerHtmlDirective } from 'ish-core/directives/server-html.directive';
+
import { CaptchaFacade } from '../../facades/captcha.facade';
import { CaptchaV2Component, CaptchaV2ComponentModule } from '../../shared/captcha-v2/captcha-v2.component';
import { CaptchaV3Component, CaptchaV3ComponentModule } from '../../shared/captcha-v3/captcha-v3.component';
@@ -30,8 +34,13 @@ describe('Lazy Captcha Component', () => {
.overrideModule(CaptchaV2ComponentModule, { set: { entryComponents: [CaptchaV2Component] } })
.overrideModule(CaptchaV3ComponentModule, {
set: {
+ imports: [TranslateModule.forRoot()],
+ declarations: [CaptchaV3Component, MockDirective(ServerHtmlDirective)],
entryComponents: [CaptchaV3Component],
- providers: [{ provide: RECAPTCHA_V3_SITE_KEY, useValue: 'captchaSiteKeyQWERTY' }],
+ providers: [
+ { provide: RECAPTCHA_V3_SITE_KEY, useValue: 'captchaSiteKeyQWERTY' },
+ { provide: ReCaptchaV3Service },
+ ],
},
})
.compileComponents();
@@ -70,7 +79,14 @@ describe('Lazy Captcha Component', () => {
fixture.detectChanges();
tick(500);
- expect(element).toMatchInlineSnapshot(``);
+ expect(element).toMatchInlineSnapshot(`
+
+ `);
const v3Cmp: CaptchaV3Component = fixture.debugElement.query(By.css('ish-captcha-v3'))?.componentInstance;
expect(v3Cmp).toBeTruthy();
}));
diff --git a/src/app/extensions/captcha/exports/lazy-captcha/lazy-captcha.component.ts b/src/app/extensions/captcha/exports/lazy-captcha/lazy-captcha.component.ts
index d31d289359..544919acf3 100644
--- a/src/app/extensions/captcha/exports/lazy-captcha/lazy-captcha.component.ts
+++ b/src/app/extensions/captcha/exports/lazy-captcha/lazy-captcha.component.ts
@@ -88,6 +88,7 @@ export class LazyCaptchaComponent implements OnInit, AfterViewInit, OnDestroy {
const componentRef = this.anchor.createComponent(factory);
componentRef.instance.parentForm = this.form;
+ componentRef.changeDetectorRef.markForCheck();
} else if (version === 2) {
this.formControl.setValidators([Validators.required]);
this.formControl.updateValueAndValidity();
@@ -103,6 +104,7 @@ export class LazyCaptchaComponent implements OnInit, AfterViewInit, OnDestroy {
componentRef.instance.cssClass = this.cssClass;
componentRef.instance.parentForm = this.form;
+ componentRef.changeDetectorRef.markForCheck();
}
});
}
diff --git a/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.html b/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.html
new file mode 100644
index 0000000000..e5972a8a9e
--- /dev/null
+++ b/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.html
@@ -0,0 +1,12 @@
+
diff --git a/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.spec.ts b/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.spec.ts
index abebf37700..4cc9308666 100644
--- a/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.spec.ts
+++ b/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.spec.ts
@@ -1,7 +1,12 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormControl, FormGroup } from '@angular/forms';
+import { TranslateModule } from '@ngx-translate/core';
+import { MockDirective } from 'ng-mocks';
import { RECAPTCHA_V3_SITE_KEY, RecaptchaV3Module } from 'ng-recaptcha';
+import { ServerHtmlDirective } from 'ish-core/directives/server-html.directive';
+import { findAllDataTestingIDs } from 'ish-core/utils/dev/html-query-utils';
+
import { CaptchaV3Component } from './captcha-v3.component';
describe('Captcha V3 Component', () => {
@@ -12,8 +17,8 @@ describe('Captcha V3 Component', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
- declarations: [CaptchaV3Component],
- imports: [RecaptchaV3Module],
+ declarations: [CaptchaV3Component, MockDirective(ServerHtmlDirective)],
+ imports: [RecaptchaV3Module, TranslateModule.forRoot()],
providers: [{ provide: RECAPTCHA_V3_SITE_KEY, useValue: captchaSiteKey }],
}).compileComponents();
});
@@ -33,4 +38,13 @@ describe('Captcha V3 Component', () => {
expect(element).toBeTruthy();
expect(() => fixture.detectChanges()).not.toThrow();
});
+
+ it('should render recaptcha info text when created', () => {
+ fixture.detectChanges();
+ expect(findAllDataTestingIDs(fixture)).toMatchInlineSnapshot(`
+ Array [
+ "recaptcha-v3-info",
+ ]
+ `);
+ });
});
diff --git a/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.ts b/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.ts
index 14b13002af..a625751a73 100644
--- a/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.ts
+++ b/src/app/extensions/captcha/shared/captcha-v3/captcha-v3.component.ts
@@ -1,9 +1,12 @@
import { ChangeDetectionStrategy, Component, Input, NgModule, OnDestroy, OnInit } from '@angular/core';
import { FormGroup, Validators } from '@angular/forms';
+import { TranslateModule } from '@ngx-translate/core';
import { RECAPTCHA_V3_SITE_KEY, ReCaptchaV3Service, RecaptchaV3Module } from 'ng-recaptcha';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
+import { DirectivesModule } from 'ish-core/directives.module';
+
import {
SitekeyProviderService,
getSynchronizedSiteKey,
@@ -16,7 +19,7 @@ import {
*/
@Component({
selector: 'ish-captcha-v3',
- template: '',
+ templateUrl: './captcha-v3.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CaptchaV3Component implements OnInit, OnDestroy {
@@ -45,7 +48,7 @@ export class CaptchaV3Component implements OnInit, OnDestroy {
}
@NgModule({
- imports: [RecaptchaV3Module],
+ imports: [RecaptchaV3Module, TranslateModule, DirectivesModule],
declarations: [CaptchaV3Component],
providers: [
{
diff --git a/src/assets/i18n/de_DE.json b/src/assets/i18n/de_DE.json
index 934739bb24..b224503125 100644
--- a/src/assets/i18n/de_DE.json
+++ b/src/assets/i18n/de_DE.json
@@ -868,6 +868,7 @@
"quote.state.unknown": "Unbekannt",
"quoterequest.not_editable.error": "Sie haben die Preisanfrage bereits gesendet. Laden Sie diese Seite neu, um die Änderungen zu sehen.",
"recaptcha.v2.incorrect.error": "Beweisen Sie, dass Sie keine Maschine sind.",
+ "recaptcha.v3.info_text": "Diese Seite ist durch reCAPTCHA geschützt und es gelten die Google Datenschutzbestimmungen und Nutzungsbedingungen.",
"recentlyViewed.component.heading": "Zuletzt angesehen",
"registration.tac.error.tip": "Bitte stimmen Sie den Bedingungen zu, um fortzufahren.",
"registration.tac_privacy_policy.text": "Ich akzeptiere die AGB und Datenschutzhinweise.",
diff --git a/src/assets/i18n/en_US.json b/src/assets/i18n/en_US.json
index 5b6ac69171..70578a09fc 100644
--- a/src/assets/i18n/en_US.json
+++ b/src/assets/i18n/en_US.json
@@ -870,6 +870,7 @@
"quote.state.unknown": "Unknown",
"quoterequest.not_editable.error": "You have already submitted the quote request. Please reload this page to view the changes.",
"recaptcha.v2.incorrect.error": "Please verify you are a real person.",
+ "recaptcha.v3.info_text": "This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.",
"recentlyViewed.component.heading": "Recently Viewed",
"registration.tac.error.tip": "Please agree to the terms to continue.",
"registration.tac_privacy_policy.text": "I agree to the Terms & Conditions and Privacy Policy.",
diff --git a/src/assets/i18n/fr_FR.json b/src/assets/i18n/fr_FR.json
index c41a705c5a..bd68a6a4f4 100644
--- a/src/assets/i18n/fr_FR.json
+++ b/src/assets/i18n/fr_FR.json
@@ -870,6 +870,7 @@
"quote.state.unknown": "Inconnu",
"quoterequest.not_editable.error": "Vous avez déjà soumis la demande de devis. Veuillez rafraîchir cette page pour afficher les modifications.",
"recaptcha.v2.incorrect.error": "Veuillez vérifier que vous êtes une personne réelle.",
+ "recaptcha.v3.info_text": "Ce site est protégé par reCAPTCHA et la politique de confidentialité de Google ainsi que ses conditions de service s'appliquent.",
"recentlyViewed.component.heading": "Récemment consultés",
"registration.tac.error.tip": "Veuillez accepter les conditions pour continuer.",
"registration.tac_privacy_policy.text": "J’accepte les Conditions générales et la Politique de confidentialité.",
diff --git a/src/styles/global/forms/forms.scss b/src/styles/global/forms/forms.scss
index b0f1d82f3a..7461b74f34 100644
--- a/src/styles/global/forms/forms.scss
+++ b/src/styles/global/forms/forms.scss
@@ -99,6 +99,10 @@ input[type='file'] {
}
}
+.grecaptcha-badge {
+ visibility: hidden;
+}
+
.filter-dropdown {
position: relative;
padding-bottom: 15px;