@@ -12,6 +12,7 @@ import { BehaviorSubject, of, throwError } from 'rxjs';
1212import { anything , instance , mock , verify , when } from 'ts-mockito' ;
1313import { ActivatedProjectService } from 'xforge-common/activated-project.service' ;
1414import { AuthService } from 'xforge-common/auth.service' ;
15+ import { CommandError , CommandErrorCode } from 'xforge-common/command.service' ;
1516import { FileService } from 'xforge-common/file.service' ;
1617import { I18nService } from 'xforge-common/i18n.service' ;
1718import { FileType } from 'xforge-common/models/file-offline-data' ;
@@ -308,6 +309,103 @@ describe('ServalProjectComponent', () => {
308309 verify ( mockSFProjectService . onlineSetServalConfig ( env . mockProjectId , anything ( ) ) ) . never ( ) ;
309310 expect ( env . statusDone ( env . servalConfigStatus ) ) . toBeNull ( ) ;
310311 } ) ) ;
312+
313+ it ( 'should notify of a backend error' , fakeAsync ( ( ) => {
314+ const env = new TestEnvironment ( ) ;
315+ when ( mockSFProjectService . onlineSetServalConfig ( env . mockProjectId , anything ( ) ) ) . thenReject (
316+ new CommandError ( CommandErrorCode . InternalError , 'error' )
317+ ) ;
318+ expect ( env . servalConfigTextArea . value ) . toBe ( '' ) ;
319+ expect ( env . statusError ( env . servalConfigStatus ) ) . toBeNull ( ) ;
320+
321+ env . setServalConfigValue ( '{}' ) ;
322+ env . clickElement ( env . saveServalConfigButton ) ;
323+
324+ verify ( mockSFProjectService . onlineSetServalConfig ( env . mockProjectId , anything ( ) ) ) . once ( ) ;
325+ expect ( env . statusError ( env . servalConfigStatus ) ) . not . toBeNull ( ) ;
326+ } ) ) ;
327+ } ) ;
328+
329+ describe ( 'quality estimation configuration' , ( ) => {
330+ it ( 'should change quality estimation config value' , fakeAsync ( ( ) => {
331+ const env = new TestEnvironment ( ) ;
332+ expect ( env . qualityEstimationConfigTextArea . value ) . toBe ( '' ) ;
333+ expect ( env . statusDone ( env . qualityEstimationConfigStatus ) ) . toBeNull ( ) ;
334+
335+ env . setQualityEstimationConfigValue ( '{ "version": "0.1", "slope": 109.6145, "intercept": -14.0633 }' ) ;
336+ env . clickElement ( env . saveQualityEstimationConfigButton ) ;
337+
338+ verify ( mockSFProjectService . onlineSetQualityEstimationConfig ( env . mockProjectId , anything ( ) ) ) . once ( ) ;
339+ expect ( env . statusDone ( env . qualityEstimationConfigStatus ) ) . not . toBeNull ( ) ;
340+ } ) ) ;
341+
342+ it ( 'should clear the quality estimation config value' , fakeAsync ( ( ) => {
343+ const env = new TestEnvironment ( {
344+ preTranslate : true ,
345+ draftConfig : { qualityEstimationConfig : { version : '0.1' , slope : 109.6145 , intercept : - 14.0633 } }
346+ } ) ;
347+ expect ( env . qualityEstimationConfigTextArea . value ) . toBe (
348+ '{"version":"0.1","slope":109.6145,"intercept":-14.0633}'
349+ ) ;
350+ expect ( env . statusDone ( env . qualityEstimationConfigStatus ) ) . toBeNull ( ) ;
351+
352+ env . setQualityEstimationConfigValue ( '' ) ;
353+ env . clickElement ( env . saveQualityEstimationConfigButton ) ;
354+
355+ verify ( mockSFProjectService . onlineSetQualityEstimationConfig ( env . mockProjectId , anything ( ) ) ) . once ( ) ;
356+ expect ( env . statusDone ( env . qualityEstimationConfigStatus ) ) . not . toBeNull ( ) ;
357+ } ) ) ;
358+
359+ it ( 'should not update an unchanged quality estimation config value' , fakeAsync ( ( ) => {
360+ const env = new TestEnvironment ( ) ;
361+ expect ( env . qualityEstimationConfigTextArea . value ) . toBe ( '' ) ;
362+ expect ( env . statusDone ( env . qualityEstimationConfigStatus ) ) . toBeNull ( ) ;
363+
364+ env . setQualityEstimationConfigValue ( '' ) ;
365+ env . clickElement ( env . saveQualityEstimationConfigButton ) ;
366+
367+ verify ( mockSFProjectService . onlineSetQualityEstimationConfig ( env . mockProjectId , anything ( ) ) ) . never ( ) ;
368+ expect ( env . statusDone ( env . qualityEstimationConfigStatus ) ) . toBeNull ( ) ;
369+ } ) ) ;
370+
371+ it ( 'should not update a non-JSON value' , fakeAsync ( ( ) => {
372+ const env = new TestEnvironment ( ) ;
373+ expect ( env . qualityEstimationConfigTextArea . value ) . toBe ( '' ) ;
374+ expect ( env . statusError ( env . qualityEstimationConfigStatus ) ) . toBeNull ( ) ;
375+
376+ env . setQualityEstimationConfigValue ( 'test' ) ;
377+ env . clickElement ( env . saveQualityEstimationConfigButton ) ;
378+
379+ verify ( mockSFProjectService . onlineSetQualityEstimationConfig ( env . mockProjectId , anything ( ) ) ) . never ( ) ;
380+ expect ( env . statusError ( env . qualityEstimationConfigStatus ) ) . not . toBeNull ( ) ;
381+ } ) ) ;
382+
383+ it ( 'should not update an invalid value' , fakeAsync ( ( ) => {
384+ const env = new TestEnvironment ( ) ;
385+ expect ( env . qualityEstimationConfigTextArea . value ) . toBe ( '' ) ;
386+ expect ( env . statusError ( env . qualityEstimationConfigStatus ) ) . toBeNull ( ) ;
387+
388+ env . setQualityEstimationConfigValue ( '{"prop": "value"}' ) ;
389+ env . clickElement ( env . saveQualityEstimationConfigButton ) ;
390+
391+ verify ( mockSFProjectService . onlineSetQualityEstimationConfig ( env . mockProjectId , anything ( ) ) ) . never ( ) ;
392+ expect ( env . statusError ( env . qualityEstimationConfigStatus ) ) . not . toBeNull ( ) ;
393+ } ) ) ;
394+
395+ it ( 'should notify of a backend error' , fakeAsync ( ( ) => {
396+ const env = new TestEnvironment ( ) ;
397+ when ( mockSFProjectService . onlineSetQualityEstimationConfig ( env . mockProjectId , anything ( ) ) ) . thenReject (
398+ new CommandError ( CommandErrorCode . InternalError , 'error' )
399+ ) ;
400+ expect ( env . qualityEstimationConfigTextArea . value ) . toBe ( '' ) ;
401+ expect ( env . statusError ( env . qualityEstimationConfigStatus ) ) . toBeNull ( ) ;
402+
403+ env . setQualityEstimationConfigValue ( '{ "version": "0.1", "slope": 109.6145, "intercept": -14.0633 }' ) ;
404+ env . clickElement ( env . saveQualityEstimationConfigButton ) ;
405+
406+ verify ( mockSFProjectService . onlineSetQualityEstimationConfig ( env . mockProjectId , anything ( ) ) ) . once ( ) ;
407+ expect ( env . statusError ( env . qualityEstimationConfigStatus ) ) . not . toBeNull ( ) ;
408+ } ) ) ;
311409 } ) ;
312410 } ) ;
313411
@@ -363,7 +461,8 @@ describe('ServalProjectComponent', () => {
363461 lastSelectedTrainingScriptureRanges : args . draftConfig ?. lastSelectedTrainingScriptureRanges ?? undefined ,
364462 lastSelectedTranslationScriptureRanges :
365463 args . draftConfig ?. lastSelectedTranslationScriptureRanges ?? undefined ,
366- servalConfig : args . draftConfig ?. servalConfig ?? undefined
464+ servalConfig : args . draftConfig ?. servalConfig ?? undefined ,
465+ qualityEstimationConfig : args . draftConfig ?. qualityEstimationConfig ?? undefined
367466 } ,
368467 preTranslate : args . preTranslate ,
369468 source : {
@@ -395,6 +494,7 @@ describe('ServalProjectComponent', () => {
395494 when ( mockDraftGenerationService . getBuildProgress ( anything ( ) ) ) . thenReturn ( of ( { additionalInfo : { } } as BuildDto ) ) ;
396495 when ( mockSFProjectService . hasDraft ( anything ( ) ) ) . thenReturn ( args . preTranslate ) ;
397496 when ( mockSFProjectService . onlineSetServalConfig ( this . mockProjectId , anything ( ) ) ) . thenResolve ( ) ;
497+ when ( mockSFProjectService . onlineSetQualityEstimationConfig ( this . mockProjectId , anything ( ) ) ) . thenResolve ( ) ;
398498 const trainingData : TrainingDataDoc [ ] = [
399499 {
400500 id : 'training01' ,
@@ -444,6 +544,18 @@ describe('ServalProjectComponent', () => {
444544 return this . fixture . nativeElement . querySelector ( '.training-data-table td button' ) ;
445545 }
446546
547+ get qualityEstimationConfigStatus ( ) : DebugElement {
548+ return this . fixture . debugElement . query ( By . css ( '#quality-estimation-config-status' ) ) ;
549+ }
550+
551+ get qualityEstimationConfigTextArea ( ) : HTMLTextAreaElement {
552+ return this . fixture . nativeElement . querySelector ( '#quality-estimation-config' ) as HTMLTextAreaElement ;
553+ }
554+
555+ get saveQualityEstimationConfigButton ( ) : HTMLInputElement {
556+ return this . fixture . nativeElement . querySelector ( '#save-quality-estimation-config' ) ;
557+ }
558+
447559 get saveServalConfigButton ( ) : HTMLInputElement {
448560 return this . fixture . nativeElement . querySelector ( '#save-serval-config' ) ;
449561 }
@@ -485,6 +597,14 @@ describe('ServalProjectComponent', () => {
485597 return node . querySelector ( '.translation-range' ) ?. textContent ?? '' ;
486598 }
487599
600+ setQualityEstimationConfigValue ( value : string ) : void {
601+ this . qualityEstimationConfigTextArea . value = value ;
602+ this . qualityEstimationConfigTextArea . dispatchEvent ( new Event ( 'input' ) ) ;
603+ this . fixture . detectChanges ( ) ;
604+ tick ( ) ;
605+ this . fixture . detectChanges ( ) ;
606+ }
607+
488608 setServalConfigValue ( value : string ) : void {
489609 this . servalConfigTextArea . value = value ;
490610 this . servalConfigTextArea . dispatchEvent ( new Event ( 'input' ) ) ;
@@ -496,5 +616,9 @@ describe('ServalProjectComponent', () => {
496616 statusDone ( element : DebugElement ) : HTMLElement {
497617 return element . nativeElement . querySelector ( '.check-icon' ) as HTMLElement ;
498618 }
619+
620+ statusError ( element : DebugElement ) : HTMLElement {
621+ return element . nativeElement . querySelector ( '.error-icon' ) as HTMLElement ;
622+ }
499623 }
500624} ) ;
0 commit comments