]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr/dashboard: Add binary min and max validators
authorStephan Müller <smueller@suse.com>
Fri, 15 Nov 2019 12:27:52 +0000 (13:27 +0100)
committerStephan Müller <smueller@suse.com>
Fri, 13 Dec 2019 14:43:45 +0000 (15:43 +0100)
Adds simple validators that resemble the min and max validators for
numbers.

As a binary size (the string) has first be converted into bytes
(the number) to validate against some other number and in case of an
error the other number want's to be converted into a size to display,
the whole process needs a bunch of conversion, but these validators take
care of all that.

Fixes: https://tracker.ceph.com/issues/38287
Signed-off-by: Stephan Müller <smueller@suse.com>
src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.ts

index d6b2b00454686631fd5f3d21a087d86dc3d59a1e..06a3a230b6db187e1d458ab7e3248a08453e5642 100644 (file)
@@ -526,4 +526,33 @@ describe('CdValidators', () => {
       expect(validatorFn(form.get('z'))).toEqual({ required: true });
     });
   });
+
+  describe('dimmlessBinary validators', () => {
+    const i18nMock = (a: string, b: { value: string }) => a.replace('{{value}}', b.value);
+
+    beforeEach(() => {
+      form = new CdFormGroup({
+        x: new FormControl('2 KiB', [CdValidators.binaryMin(1024), CdValidators.binaryMax(3072)])
+      });
+      formHelper = new FormHelper(form);
+    });
+
+    it('should not raise exception an exception for valid change', () => {
+      formHelper.expectValidChange('x', '2.5 KiB');
+    });
+
+    it('should not raise minimum error', () => {
+      formHelper.expectErrorChange('x', '0.5 KiB', 'binaryMin');
+      expect(form.get('x').getError('binaryMin')(i18nMock)).toBe(
+        'Size has to be at least 1 KiB or more'
+      );
+    });
+
+    it('should not raise maximum error', () => {
+      formHelper.expectErrorChange('x', '4 KiB', 'binaryMax');
+      expect(form.get('x').getError('binaryMax')(i18nMock)).toBe(
+        'Size has to be at most 3 KiB or less'
+      );
+    });
+  });
 });
index 9a83753e942100a48f44e0cb824f5be3b6e7f31c..11533f7d60a6d86c14f0442fee9012357d3fd1fa 100644 (file)
@@ -6,10 +6,14 @@ import {
   Validators
 } from '@angular/forms';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import { Observable, of as observableOf, timer as observableTimer } from 'rxjs';
 import { map, switchMapTo, take } from 'rxjs/operators';
 
+import { DimlessBinaryPipe } from '../pipes/dimless-binary.pipe';
+import { FormatterService } from '../services/formatter.service';
+
 export function isEmptyInputValue(value: any): boolean {
   return value == null || value.length === 0;
 }
@@ -321,4 +325,44 @@ export class CdValidators {
       return { invalidUuid: 'This is not a valid UUID' };
     };
   }
+
+  /**
+   * A simple minimum validator vor cd-binary inputs.
+   *
+   * To use the validation message pass I18n into the function as it cannot
+   * be called in a static one.
+   */
+  static binaryMin(bytes: number): ValidatorFn {
+    return (control: AbstractControl): { [key: string]: (i18n: I18n) => string } | null => {
+      const formatterService = new FormatterService();
+      const currentBytes = new FormatterService().toBytes(control.value);
+      if (bytes <= currentBytes) {
+        return null;
+      }
+      const value = new DimlessBinaryPipe(formatterService).transform(bytes);
+      return {
+        binaryMin: (i18n: I18n) => i18n(`Size has to be at least {{value}} or more`, { value })
+      };
+    };
+  }
+
+  /**
+   * A simple maximum validator vor cd-binary inputs.
+   *
+   * To use the validation message pass I18n into the function as it cannot
+   * be called in a static one.
+   */
+  static binaryMax(bytes: number): ValidatorFn {
+    return (control: AbstractControl): { [key: string]: (i18n: I18n) => string } | null => {
+      const formatterService = new FormatterService();
+      const currentBytes = formatterService.toBytes(control.value);
+      if (bytes >= currentBytes) {
+        return null;
+      }
+      const value = new DimlessBinaryPipe(formatterService).transform(bytes);
+      return {
+        binaryMax: (i18n: I18n) => i18n(`Size has to be at most {{value}} or less`, { value })
+      };
+    };
+  }
 }