Skip to content

Commit

Permalink
Merge pull request #76 from ES2-UFPI/59-validar-dados-de-entrada-ex-h…
Browse files Browse the repository at this point in the history
…orário-válido-dosagem-permitida-back-endfront-end

✨ feat: Implementação da Validar dados de entrada para cadastro de medicações + Testes Front-end
  • Loading branch information
AveiaPodre authored Jan 7, 2025
2 parents ab736fd + 17e24d3 commit 2496916
Show file tree
Hide file tree
Showing 4 changed files with 7,715 additions and 6,371 deletions.
114 changes: 114 additions & 0 deletions frontend/__tests__/RegisterMedication.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import RegisterMedication from '../app/(tabs)/add'
import axios from 'axios';
import { Alert } from 'react-native';

jest.mock('axios');
jest.mock('expo-router', () => ({
Link: ({ children }) => children,
}));
jest.mock('expo-font', () => ({
useFonts: () => [true],
}));
jest.mock('@expo-google-fonts/katibeh', () => ({
Katibeh_400Regular: 'mocked-font',
}));
// Mock do Alert
jest.spyOn(Alert, 'alert');

describe('RegisterMedication', () => {
beforeEach(() => {
jest.clearAllMocks();
});

test('renderiza todos os campos do formulário', () => {
const { getByPlaceholderText, getByText } = render(<RegisterMedication />);

expect(getByPlaceholderText('Nome do medicamento')).toBeTruthy();
expect(getByPlaceholderText('Nome do laboratório')).toBeTruthy();
expect(getByText('Dosagem')).toBeTruthy();
expect(getByText('Data de início')).toBeTruthy();
expect(getByText('Horário de início')).toBeTruthy();
expect(getByText('Frequência')).toBeTruthy();
});

test('mostra erro quando campos obrigatórios estão vazios', async () => {
const { getByText } = render(<RegisterMedication />);

fireEvent.press(getByText('Confirmar'));

await waitFor(() => {
expect(Alert.alert).toHaveBeenCalledWith('Erro', 'Por favor, preencha todos os campos obrigatórios.');
});
});

test('valida dosagem inválida', async () => {
const { getByPlaceholderText, getByText } = render(<RegisterMedication />);

fireEvent.changeText(getByPlaceholderText('Nome do medicamento'), 'Dipirona');
fireEvent.changeText(getByPlaceholderText('Quantidade de medicamento por dose (ex.: 1, 2, 0.5)'), '101');

fireEvent.press(getByText('Confirmar'));

await waitFor(() => {
expect(Alert.alert).toHaveBeenCalledWith('Erro', 'Por favor, insira uma dosagem válida.');
});
});

test('cadastra medicação com sucesso', async () => {
const mockMedicamentoResponse = { data: { id: 1 } };
(axios.post as jest.Mock)
.mockResolvedValueOnce(mockMedicamentoResponse)
.mockResolvedValueOnce({ data: { success: true } });

const { getByPlaceholderText, getByText } = render(<RegisterMedication />);

// Preenche todos os campos obrigatórios
fireEvent.changeText(getByPlaceholderText('Nome do medicamento'), 'Dipirona');
fireEvent.changeText(getByPlaceholderText('Nome do laboratório'), 'EMS');
fireEvent.changeText(getByPlaceholderText('Quantidade de medicamento por dose (ex.: 1, 2, 0.5)'), '1');
fireEvent.changeText(getByPlaceholderText('Quantidade de comprimidos'), '30');

// Seleciona frequência
const picker = getByText('Selecionar frequência');
fireEvent(picker, 'onValueChange', '12');

fireEvent.press(getByText('Confirmar'));

await waitFor(() => {
expect(axios.post).toHaveBeenCalledWith('http://localhost:8080/medicamentos', {
nome: 'Dipirona',
laboratorio: 'EMS'
});
expect(axios.post).toHaveBeenCalledWith('http://localhost:8080/usuarios-medicamentos/1', expect.any(Object));
expect(Alert.alert).toHaveBeenCalledWith('Sucesso', 'Medicação cadastrada com sucesso!');
}, { timeout: 3000 });
});

test('trata erro na API corretamente', async () => {
(axios.post as jest.Mock).mockRejectedValueOnce(new Error('Erro de API'));

const { getByPlaceholderText, getByText } = render(<RegisterMedication />);

fireEvent.changeText(getByPlaceholderText('Nome do medicamento'), 'Dipirona');
fireEvent.changeText(getByPlaceholderText('Nome do laboratório'), 'EMS');
fireEvent.changeText(getByPlaceholderText('Quantidade de medicamento por dose (ex.: 1, 2, 0.5)'), '1');
fireEvent.changeText(getByPlaceholderText('Quantidade de comprimidos'), '30');

fireEvent.press(getByText('Confirmar'));

await waitFor(() => {
expect(Alert.alert).toHaveBeenCalledWith('Erro', 'Não foi possível cadastrar a medicação. Tente novamente.');
});
});

test('limpa formulário ao pressionar cancelar', () => {
const { getByPlaceholderText, getByText } = render(<RegisterMedication />);

fireEvent.changeText(getByPlaceholderText('Nome do medicamento'), 'Dipirona');
fireEvent.press(getByText('Cancelar'));

expect(getByPlaceholderText('Nome do medicamento').props.value).toBe('');
});
});
40 changes: 38 additions & 2 deletions frontend/app/(tabs)/add.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,28 @@ const RegisterMedication = () => {
const { width } = useWindowDimensions();
const cardWidth = Math.min(width - 32, 768);

// Function to check if a date is valid (not in the past)
// função para checar se uma data é válida e não está no passado
const validateDate = (date: Date) => {
const today = new Date();
today.setHours(0, 0, 0, 0); // Reset time to start of day for accurate comparison
today.setHours(0, 0, 0, 0); // resete o tempo para comparar apenas a data
return date >= today;
};

const validateTime = (time: string) => {
const [hours, minutes] = time.split(':').map(Number);
return hours >= 0 && hours < 24 && minutes >= 0 && minutes < 60;
};

const validateDosage = (dosage: string) => {
const dosageValue = parseFloat(dosage);
return dosageValue > 0 && dosageValue <= 100; // Exemplo de intervalo razoável
};

const validateStock = (stock: string) => {
const stockValue = parseInt(stock, 10);
return stockValue >= 0;
};

const frequencyOptions = [
{ label: '1 em 1 hora', value: 1 },
{ label: '2 em 2 horas', value: 2 },
Expand Down Expand Up @@ -76,6 +91,27 @@ const RegisterMedication = () => {
return;
}

// Validação de horário
if (!validateTime(startTime)) {
Alert.alert('Erro', 'Por favor, insira um horário válido.');
console.log('Horário inválido');
return;
}

// Validação de dosagem
if (!validateDosage(dosage)) {
Alert.alert('Erro', 'Por favor, insira uma dosagem válida.');
console.log('Dosagem inválida');
return;
}

// Validação de estoque atual
if (!validateStock(currentStock)) {
Alert.alert('Erro', 'Por favor, insira uma quantidade de estoque válida.');
console.log('Estoque inválido');
return;
}

setIsLoading(true);

try {
Expand Down
8 changes: 6 additions & 2 deletions frontend/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ module.exports = {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 'identity-obj-proxy',
}
};
},
preset: 'jest-expo',
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)'
]
};
Loading

0 comments on commit 2496916

Please sign in to comment.