All files / modules/75-cf/pages/feature-flags-detail/targeting-rules-tab/hooks useTargetingRulesFormValidation.tsx

100% Statements 21/21
100% Branches 2/2
100% Functions 7/7
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83              3x 3x 3x   3x                     3x 21x 21x 8x 8x         38x 4x   34x                 34x                   14x 28x 28x   14x                           3x     5x   21x         3x  
/*
 * Copyright 2022 Harness Inc. All rights reserved.
 * Use of this source code is governed by the PolyForm Shield 1.0.0 license
 * that can be found in the licenses directory at the root of this repository, also available at
 * https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
 */
 
import * as yup from 'yup'
import { FormikErrors, validateYupSchema, yupToFormErrors } from 'formik'
import { useStrings } from 'framework/strings'
import type { WeightedVariation } from 'services/cf'
import {
  FormVariationMap,
  TargetingRuleItemStatus,
  TargetingRulesFormValues,
  VariationPercentageRollout
} from '../types'
 
interface UseTargetingRulesFormValidationReturn {
  validate: (values: TargetingRulesFormValues) => FormikErrors<unknown>
}
 
const useTargetingRulesFormValidation = (): UseTargetingRulesFormValidationReturn => {
  const { getString } = useStrings()
  const validate = (values: TargetingRulesFormValues): FormikErrors<unknown> => {
    try {
      validateYupSchema(
        values,
        yup.object({
          targetingRuleItems: yup.array().of(
            yup.lazy(v => {
              if ((v as FormVariationMap | VariationPercentageRollout).status === TargetingRuleItemStatus.DELETED) {
                return yup.object({})
              }
              return yup.object({
                clauses: yup.array().of(
                  yup.object({
                    values: yup
                      .array()
                      .of(yup.string().required(getString('cf.featureFlags.rules.validation.selectTargetGroup')))
                  })
                ),
                variations: yup.lazy(value => {
                  return yup.array().of(
                    yup.object({
                      weight: yup
                        .number()
                        .typeError(getString('cf.creationModal.mustBeNumber'))
                        .required(getString('cf.featureFlags.rules.validation.valueRequired'))
                        .test(
                          'weight-sum-test',
                          getString('cf.featureFlags.rules.validation.valueMustAddTo100'),
                          () => {
                            const totalWeight = (value as WeightedVariation[])
                              .map(x => x.weight)
                              .reduce((previous, current) => previous + current, 0)
 
                            return totalWeight === 100
                          }
                        )
                    })
                  )
                })
              })
            })
          )
        }),
        true,
        values
      )
    } catch (err) {
      return yupToFormErrors(err) //for rendering validation errors
    }
 
    return {}
  }
  return {
    validate
  }
}
 
export default useTargetingRulesFormValidation