Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat: Implementação da Validar dados de entrada para cadastro de medicações + Testes Front-end #76

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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