-
brunoravera authoredbrunoravera authored
use-run-tests-button.ts 5.68 KiB
import React from 'react'
import { useDropzone } from 'react-dropzone'
import { useQueryClient } from 'react-query'
import {
FileWithName,
Formalization,
Implementation,
Pattern,
} from 'src/models'
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'
import { RunTestsStep1Mutation } from '../query-builder/run-tests-step-1-mutation'
import { RunTestsStep2Mutation } from '../query-builder/run-tests-step-2-mutation'
import { useToast } from '@chakra-ui/react'
import { navigate, routes } from '@redwoodjs/router'
export function useRunTestsButton({
patternId,
implementationId,
onClose,
}: {
patternId: Pattern['id']
implementationId: Implementation['id']
onClose: () => void
}) {
const queryClient = useQueryClient()
const toast = useToast()
const [name, setName] = React.useState('')
React.useEffect(() => {
queryClient.invalidateQueries(GetFormalizationsQuery.key)
}, [])
// Formalization
const [formalizationId, setFormalizationId] =
React.useState<Formalization['id']>('')
const formalizationsQuery = GetFormalizationsQuery.useQuery(
{
patternId: patternId,
},
{
onSettled: (data) => {
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
},
})
const onRemoveStrategy = () => setStrategy(null)
// 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)
)
setTestCasesInstantiation(res[0])
return [...res]
},
[]
)
const testCasesInstantiationDropzoneState = useDropzone({
onDrop: onDropTestCasesInstantiation,
noDrag: true,
validator: (file) => {
if (file.size > MAX_FILE_SIZE) {
return {
code: SIZE_TOO_LARGE,
message: `Maximo ${MAX_FILE_SIZE} MB.`,
}
}
return null
},
})
const onRemoveTestCasesInstantiation = () => setTestCasesInstantiation(null)
// 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)
// Utils
const isValid = React.useMemo(() => {
return (
Boolean(formalizationId) &&
Boolean(strategy) &&
Boolean(testCasesInstantiation) &&
Boolean(name)
)
}, [formalizationId, strategy, testCasesInstantiation, name])
const runTestsMutation = RunTestsStep1Mutation.useMutation()
type Step = 'Generating' | 'Testing' | 'Loading'
const [step, setStep] = React.useState<Step>('Generating')
const [genericJUnitPath, setGenericJUnitPath] = React.useState<string>(null)
const handleOnRunTestsStep1 = async () => {
if (!isValid) return
setStep('Loading')
const response = await runTestsMutation.mutateAsync({
id: formalizationId,
strategyFile: strategy.file,
testCasesInstantiationFile: testCasesInstantiation.file,
})
setGenericJUnitPath(response.path)
setStep('Testing')
}
const step2Mutation = RunTestsStep2Mutation.useMutation({
onSuccess: (report) => {
navigate(routes.report({ id: report.id }))
},
})
const handleOnRunTestsStep2 = async () => {
setStep('Loading')
await step2Mutation.mutateAsync({
id: formalizationId,
implementationId,
wrapperFile: wrapper.file,
name,
})
onClose()
toast({
status: 'success',
position: 'top',
title: `Se han corrido los tests satisfactoriamente.`,
})
}
return {
name,
setName,
formalizations: formalizationsQuery.data ?? [],
formalizationId,
setFormalizationId,
isValid,
strategyDropzoneState,
strategy,
onRemoveStrategy,
testCasesInstantiationDropzoneState,
testCasesInstantiation,
onRemoveTestCasesInstantiation,
handleOnRunTestsStep1,
handleOnRunTestsStep2,
wrapper,
onRemoveWrapper,
wrapperDropzoneState,
genericJUnitPath,
step,
}
}