Skip to content
Snippets Groups Projects
use-run-tests-button.ts 5.68 KiB
Newer Older
brunoravera's avatar
brunoravera committed
import React from 'react'
import { useDropzone } from 'react-dropzone'
brunoravera's avatar
brunoravera committed
import { useQueryClient } from 'react-query'
brunoravera's avatar
brunoravera committed
import {
  FileWithName,
  Formalization,
  Implementation,
  Pattern,
} from 'src/models'
brunoravera's avatar
brunoravera committed
import {
  MAX_FILE_SIZE,
  SIZE_TOO_LARGE,
} from 'src/pages/patterns/add-pattern/use-add-formalizations'
import { GetFormalizationsQuery } from 'src/pages/patterns/query-builder/get-formalizations-query'
brunoravera's avatar
brunoravera committed
import { RunTestsStep1Mutation } from '../query-builder/run-tests-step-1-mutation'
brunoravera's avatar
brunoravera committed
import { RunTestsStep2Mutation } from '../query-builder/run-tests-step-2-mutation'
brunoravera's avatar
brunoravera committed
import { useToast } from '@chakra-ui/react'
brunoravera's avatar
brunoravera committed
import { navigate, routes } from '@redwoodjs/router'
brunoravera's avatar
brunoravera committed

export function useRunTestsButton({
  patternId,
  implementationId,
brunoravera's avatar
brunoravera committed
  onClose,
brunoravera's avatar
brunoravera committed
}: {
  patternId: Pattern['id']
  implementationId: Implementation['id']
brunoravera's avatar
brunoravera committed
  onClose: () => void
brunoravera's avatar
brunoravera committed
}) {
brunoravera's avatar
brunoravera committed
  const queryClient = useQueryClient()
brunoravera's avatar
brunoravera committed
  const toast = useToast()
brunoravera's avatar
brunoravera committed

brunoravera's avatar
brunoravera committed
  const [name, setName] = React.useState('')

brunoravera's avatar
brunoravera committed
  React.useEffect(() => {
    queryClient.invalidateQueries(GetFormalizationsQuery.key)
  }, [])

brunoravera's avatar
brunoravera committed
  // Formalization
  const [formalizationId, setFormalizationId] =
    React.useState<Formalization['id']>('')

  const formalizationsQuery = GetFormalizationsQuery.useQuery(
    {
      patternId: patternId,
    },
    {
brunoravera's avatar
brunoravera committed
      onSettled: (data) => {
brunoravera's avatar
brunoravera committed
        setFormalizationId(data[0]?.id ?? '')
      },
    }
  )

  // Strategy
  const [strategy, setStrategy] = React.useState<FileWithName>()
  const onDropStrategy = React.useCallback((acceptedFiles: File[]) => {
    if (acceptedFiles.length > 1) {
      throw Error('Expected 1 strategy file')
    }
    const res = acceptedFiles.map(
      (f) =>
        ({
          file: f,
          name: f.name.split('.')[0] ?? f.name,
        } as FileWithName)
    )
    setStrategy(res[0])

    return [...res]
  }, [])

  const strategyDropzoneState = useDropzone({
    onDrop: onDropStrategy,
    noDrag: true,
    validator: (file) => {
      if (file.size > MAX_FILE_SIZE) {
        return {
          code: SIZE_TOO_LARGE,
          message: `Maximo ${MAX_FILE_SIZE} MB.`,
        }
      }
      return null
    },
  })

brunoravera's avatar
brunoravera committed
  const onRemoveStrategy = () => setStrategy(null)

brunoravera's avatar
brunoravera committed
  // Test cases instantiation
  const [testCasesInstantiation, setTestCasesInstantiation] =
    React.useState<FileWithName>()
  const onDropTestCasesInstantiation = React.useCallback(
    (acceptedFiles: File[]) => {
      if (acceptedFiles.length > 1) {
        throw Error('Expected 1 test file')
      }
      const res = acceptedFiles.map(
        (f) =>
          ({
            file: f,
            name: f.name.split('.')[0] ?? f.name,
          } as FileWithName)
      )
brunoravera's avatar
brunoravera committed
      setTestCasesInstantiation(res[0])
brunoravera's avatar
brunoravera committed

      return [...res]
    },
    []
  )

  const testCasesInstantiationDropzoneState = useDropzone({
brunoravera's avatar
brunoravera committed
    onDrop: onDropTestCasesInstantiation,
brunoravera's avatar
brunoravera committed
    noDrag: true,
    validator: (file) => {
      if (file.size > MAX_FILE_SIZE) {
        return {
          code: SIZE_TOO_LARGE,
          message: `Maximo ${MAX_FILE_SIZE} MB.`,
        }
      }
      return null
    },
  })

brunoravera's avatar
brunoravera committed
  const onRemoveTestCasesInstantiation = () => setTestCasesInstantiation(null)

brunoravera's avatar
brunoravera committed
  // Wrapper
  const [wrapper, setWrapper] = React.useState<FileWithName>()
  const onDropWrapper = React.useCallback((acceptedFiles: File[]) => {
    if (acceptedFiles.length > 1) {
      throw Error('Expected 1 test file')
    }
    const res = acceptedFiles.map(
      (f) =>
        ({
          file: f,
          name: f.name.split('.')[0] ?? f.name,
        } as FileWithName)
    )
    setWrapper(res[0])

    return [...res]
  }, [])

  const wrapperDropzoneState = useDropzone({
    onDrop: onDropWrapper,
    noDrag: true,
    validator: (file) => {
      if (file.size > MAX_FILE_SIZE) {
        return {
          code: SIZE_TOO_LARGE,
          message: `Maximo ${MAX_FILE_SIZE} MB.`,
        }
      }
      return null
    },
  })

  const onRemoveWrapper = () => setWrapper(null)

brunoravera's avatar
brunoravera committed
  // Utils

  const isValid = React.useMemo(() => {
    return (
      Boolean(formalizationId) &&
      Boolean(strategy) &&
brunoravera's avatar
brunoravera committed
      Boolean(testCasesInstantiation) &&
      Boolean(name)
brunoravera's avatar
brunoravera committed
    )
brunoravera's avatar
brunoravera committed
  }, [formalizationId, strategy, testCasesInstantiation, name])
brunoravera's avatar
brunoravera committed

brunoravera's avatar
brunoravera committed
  const runTestsMutation = RunTestsStep1Mutation.useMutation()
brunoravera's avatar
brunoravera committed

brunoravera's avatar
brunoravera committed
  type Step = 'Generating' | 'Testing' | 'Loading'
brunoravera's avatar
brunoravera committed
  const [step, setStep] = React.useState<Step>('Generating')
  const [genericJUnitPath, setGenericJUnitPath] = React.useState<string>(null)
brunoravera's avatar
brunoravera committed
  const handleOnRunTestsStep1 = async () => {
brunoravera's avatar
brunoravera committed
    if (!isValid) return

brunoravera's avatar
brunoravera committed
    setStep('Loading')
brunoravera's avatar
brunoravera committed

brunoravera's avatar
brunoravera committed
    const response = await runTestsMutation.mutateAsync({
brunoravera's avatar
brunoravera committed
      id: formalizationId,
      strategyFile: strategy.file,
      testCasesInstantiationFile: testCasesInstantiation.file,
    })

brunoravera's avatar
brunoravera committed
    setGenericJUnitPath(response.path)
brunoravera's avatar
brunoravera committed
    setStep('Testing')
brunoravera's avatar
brunoravera committed
  }
brunoravera's avatar
brunoravera committed

brunoravera's avatar
brunoravera committed
  const step2Mutation = RunTestsStep2Mutation.useMutation({
brunoravera's avatar
brunoravera committed
    onSuccess: (report) => {
      navigate(routes.report({ id: report.id }))
    },
brunoravera's avatar
brunoravera committed
  })
  const handleOnRunTestsStep2 = async () => {
    setStep('Loading')

brunoravera's avatar
brunoravera committed
    await step2Mutation.mutateAsync({
brunoravera's avatar
brunoravera committed
      id: formalizationId,
      implementationId,
      wrapperFile: wrapper.file,
brunoravera's avatar
brunoravera committed
      name,
brunoravera's avatar
brunoravera committed
    })
brunoravera's avatar
brunoravera committed

brunoravera's avatar
brunoravera committed
    onClose()

brunoravera's avatar
brunoravera committed
    toast({
      status: 'success',
      position: 'top',
      title: `Se han corrido los tests satisfactoriamente.`,
    })
brunoravera's avatar
brunoravera committed
  }

brunoravera's avatar
brunoravera committed
  return {
brunoravera's avatar
brunoravera committed
    name,
    setName,
brunoravera's avatar
brunoravera committed
    formalizations: formalizationsQuery.data ?? [],
    formalizationId,
    setFormalizationId,
    isValid,
    strategyDropzoneState,
brunoravera's avatar
brunoravera committed
    strategy,
    onRemoveStrategy,
brunoravera's avatar
brunoravera committed
    testCasesInstantiationDropzoneState,
brunoravera's avatar
brunoravera committed
    testCasesInstantiation,
    onRemoveTestCasesInstantiation,
brunoravera's avatar
brunoravera committed
    handleOnRunTestsStep1,
    handleOnRunTestsStep2,
    wrapper,
    onRemoveWrapper,
    wrapperDropzoneState,
brunoravera's avatar
brunoravera committed
    genericJUnitPath,
brunoravera's avatar
brunoravera committed
    step,
brunoravera's avatar
brunoravera committed
  }
}