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

test: refactoring and adding tests #5

Closed
wants to merge 5 commits into from
Closed
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
128 changes: 86 additions & 42 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"expo-status-bar": "~1.12.1",
"expo-updates": "~0.25.22",
"jest": "^29.2.1",
"jest-expo": "~51.0.3",
"jest-mock-extended": "^3.0.5",
"jest-sonar": "^0.2.16",
"jest-sonar-reporter": "^2.0.0",
Expand Down Expand Up @@ -70,6 +69,7 @@
"better-sqlite3": "^11.2.1",
"eslint": "^8.52.0",
"eslint-config-universe": "^12.0.0",
"jest-expo": "^51.0.4",
"jest-sonar-reporter": "^2.0.0",
"prettier": "^3.0.3",
"typescript": "~5.3.3"
Expand Down
80 changes: 8 additions & 72 deletions reports/sonar-report.xml
Original file line number Diff line number Diff line change
@@ -1,75 +1,11 @@
<testExecutions version="1">
<file path="src/app/__tests__/login.spec.tsx">
<testCase name="Login Component renderiza corretamente" duration="211" />
<testCase name="Login Component deve alterar o estado do escondeSenha" duration="18" />
<testCase name="Login Component deve lidar com o login com falha" duration="27" />
<testCase name="Login Component deve lidar com o login com falha na requisicao" duration="39" />
<testCase name="Login Component deve lidar com o login com sucesso" duration="71" />
</file>
<file path="src/app/__tests__/LinkButton.spec.tsx">
<testCase name="LinkButton deve renderizar corretamente" duration="22" />
<testCase name="LinkButton deve usar a cor de fundo personalizada" duration="2" />
<testCase name="LinkButton deve chamar a fun&#xe7;&#xe3;o de navega&#xe7;&#xe3;o corretamente" duration="2" />
</file>
<file path="src/app/__tests__/perfil.spec.tsx">
<testCase name="Perfil renderiza corretamente" duration="165" />
<testCase name="Perfil renderiza corretamente com user id" duration="10" />
<testCase name="Perfil renderiza corretamente com user id e foto" duration="13" />
<testCase name="Perfil deve chamar logout" duration="105" />
<testCase name="Perfil deve chamar navigate" duration="104" />
</file>
<file path="src/app/__tests__/cadastro.spec.tsx">
<testCase name="Cadastro Component renderiza corretamente" duration="45" />
<testCase name="Cadastro Component deve chamar a fun&#xe7;&#xe3;o &apos;postUser&apos; quando n&#xe3;o h&#xe1; erros nos campos" duration="52" />
<testCase name="Cadastro Component n&#xe3;o deve chamar a fun&#xe7;&#xe3;o &apos;postUser&apos; quando h&#xe1; espec&#xed;ficos erros nos campos" duration="50" />
<testCase name="Cadastro Component n&#xe3;o deve chamar a fun&#xe7;&#xe3;o &apos;postUser&apos; quando h&#xe1; erros nos campos" duration="10" />
<testCase name="Cadastro Component n&#xe3;o deve chamar a fun&#xe7;&#xe3;o &apos;postUser&apos; quando h&#xe1; erros espec&#xed;ficos de nome nos campos" duration="15" />
<testCase name="Cadastro Component deve exibir o Toast de erro" duration="30" />
<testCase name="Cadastro Component deve alterar o estado do escondeSenha" duration="13" />
</file>
<file path="src/app/__tests__/forum.spec.tsx">
<testCase name="Forum renderiza corretamente" duration="57" />
</file>
<file path="src/app/__tests__/rotinas.spec.tsx">
<testCase name="Rotinas renderiza corretamente" duration="35" />
<testCase name="Rotinas renderiza corretamente com user id" duration="9" />
</file>
<file path="src/app/__tests__/tutorial.spec.tsx">
<testCase name="O componente Tutorial deve renderizar corretamente" duration="216" />
<testCase name="O bot&#xe3;o &quot;Pular&quot; deve chamar a fun&#xe7;&#xe3;o &quot;router.replace&quot; com o caminho correto" duration="7" />
<testCase name="O bot&#xe3;o &quot;Avan&#xe7;ar&quot; deve permitir navegar entre os slides" duration="12" />
<testCase name="O bot&#xe3;o &quot;Avan&#xe7;ar&quot; deve permitir navegar entre os slides" duration="9" />
</file>
<file path="src/app/__tests__/registros.spec.tsx">
<testCase name="Registros renderiza corretamente" duration="28" />
<testCase name="Registros renderiza corretamente com user id" duration="6" />
</file>
<file path="src/app/__tests__/index.spec.tsx">
<testCase name="Home renderiza corretamente" duration="32" />
<testCase name="Home deve conter um t&#xed;tulo" duration="4" />
<testCase name="Home deve conter bot&#xf5;es de a&#xe7;&#xe3;o" duration="5" />
</file>
<file path="src/app/__tests__/UploadImage.spec.tsx">
<testCase name="UploadImage renderiza corretamente sem imagem inicial" duration="153" />
<testCase name="UploadImage deve renderizar corretamente" duration="7" />
</file>
<file path="src/app/components/__tests__/ModalConfirmation.spec.tsx">
<testCase name="ModalConfirmation Component renderiza corretamente" duration="162" />
</file>
<file path="src/app/__tests__/BackButton.spec.tsx">
<testCase name="BackButton chama router.back() quando pressionado" duration="151" />
</file>
<file path="src/app/__tests__/ItemTutorial.spec.tsx">
<testCase name="ItemTutorial renderiza corretamente" duration="160" />
</file>
<file path="src/app/__tests__/CustomButton.spec.tsx">
<testCase name="CustomButton renderiza corretamente" duration="208" />
<testCase name="CustomButton Chama a fun&#xe7;&#xe3;o de callback quando pressionado" duration="3" />
</file>
<file path="src/app/__tests__/ErrorMessage.spec.tsx">
<testCase name="ErrorMessage renderiza corretamente" duration="168" />
</file>
<file path="src/app/__tests__/response.interface.spec.tsx">
<testCase name="IResponse Interface deve ser uma interface com as propriedades data e message" duration="2" />
<file path="src\app\__tests__\cadastrarIdoso.spec.tsx">
<testCase name="CadastrarIdoso component renders correctly" duration="1637" />
<testCase name="CadastrarIdoso component Salvar sem nome" duration="176" />
<testCase name="CadastrarIdoso component Salvar com nome muito grande" duration="118" />
<testCase name="CadastrarIdoso component Salvar com nome curto" duration="77" />
<testCase name="CadastrarIdoso component Salvar data com formato errado" duration="92" />
<testCase name="CadastrarIdoso component Salvar com telefone errado" duration="74" />
<testCase name="CadastrarIdoso component Navega para a tela anterior ao clicar no bot&#xe3;o de voltar" duration="54" />
</file>
</testExecutions>
45 changes: 42 additions & 3 deletions src/app/__tests__/cadastrarIdoso.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
import React from "react";
import { render, fireEvent, act } from "@testing-library/react-native";
import { render, fireEvent, act, waitFor } from "@testing-library/react-native";
import CadastrarIdoso from "../private/pages/cadastrarIdoso";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { router, useLocalSearchParams, useRouter } from "expo-router";

// Mock any dependencies if needed
// Substituindo o módulo real do expo-router por uma versão mockada
jest.mock('expo-router', () => ({
useLocalSearchParams: jest.fn().mockReturnValue({
id: "123",
nome: "Nome Teste",
foto: null,
}),
router: {
push: jest.fn(), // Mocka o método push para verificações de navegação
back: jest.fn(), // Mocka o método back para o caso de não haver a prop route
canGoBack: jest.fn().mockReturnValue(true), // Mocka o método canGoBack
},
useRouter: jest.fn().mockReturnValue({
push: jest.fn(), // Mocka novamente o push no caso do uso da função useRouter
back: jest.fn(),
canGoBack: jest.fn().mockReturnValue(true),
}),
}));


// Mock AsyncStorage
jest.mock("@react-native-async-storage/async-storage", () => ({
getItem: jest.fn(),
Expand Down Expand Up @@ -59,7 +80,7 @@ describe("CadastrarIdoso component", () => {
fireEvent.press(cadastrar);
});
const erroTitulo = getByText(
"O nome completo deve ter no máximo 60 caractéres.",
"O nome completo deve ter no máximo 60 caracteres.",
);

expect(erroTitulo).toBeTruthy();
Expand All @@ -80,7 +101,7 @@ describe("CadastrarIdoso component", () => {
const erroTitulo = getByTestId("Erro-nome");

expect(erroTitulo.props.children.props.text).toBe(
"O nome completo deve ter pelo menos 5 caractéres.",
"O nome completo deve ter pelo menos 5 caracteres.",
);
});

Expand Down Expand Up @@ -121,4 +142,22 @@ describe("CadastrarIdoso component", () => {
"Deve estar no formato (XX)XXXXX-XXXX",
);
});

// Novo teste para verificar a navegação ao clicar no botão de voltar na tela de cadastrar idoso
test("Navega para a tela anterior ao clicar no botão de voltar", async () => {
// Renderiza o componente EditarPerfil
const { getByTestId } = render(<CadastrarIdoso />);

// Obtendo o botão de voltar
const backButton = getByTestId("back-button-pressable");

// Simula o clique no botão de voltar
fireEvent.press(backButton);

// Verifica se a função de navegação foi chamada corretamente e se ele navega pra tela de listar idosos
await waitFor(() => {
// expect(router.push).toHaveBeenCalledWith("/private/pages/listarIdosos");
expect(router.push).toHaveBeenCalledWith("/private/pages/listarIdosos");
});
});
});
125 changes: 125 additions & 0 deletions src/app/__tests__/cadastrarRotina.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import React from "react";
import { render, fireEvent, act, waitFor } from "@testing-library/react-native";
import CadastrarRotina from "../private/pages/cadastrarRotina";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { router } from "expo-router";
import { Notifications } from "expo-notifications";
import Toast from "react-native-toast-message";

// Mock dependencies
jest.mock("expo-router", () => ({
router: {
push: jest.fn(),
replace: jest.fn(),
},
}));

jest.mock("@react-native-async-storage/async-storage", () => ({
getItem: jest.fn(),
}));

jest.mock("expo-notifications", () => ({
getPermissionsAsync: jest.fn(),
requestPermissionsAsync: jest.fn(),
getExpoPushTokenAsync: jest.fn(),
setNotificationChannelAsync: jest.fn(),
}));

jest.mock("react-native-toast-message", () => ({
show: jest.fn(),
}));

describe("CadastrarRotina component", () => {
beforeEach(() => {
jest.clearAllMocks();
});

test("renders correctly", () => {
(AsyncStorage.getItem as jest.Mock).mockImplementation((key) => {
if (key === "token") {
return Promise.resolve("mockedToken");
}
return Promise.resolve(null);
});

const { getByText } = render(<CadastrarRotina />);

const salvarButton = getByText("Salvar");
expect(salvarButton).toBeTruthy();
});

it("Mostra erro quando o título está vazio", async () => {
const { getByText, getByPlaceholderText, getByTestId } = render(<CadastrarRotina />);

const titulo = getByPlaceholderText("Adicionar título");
const salvar = getByText("Salvar");

act(() => {
fireEvent.changeText(titulo, "");
fireEvent.press(salvar);
});

const erroTitulo = getByTestId("Erro-titulo");
expect(erroTitulo.props.children.props.text).toBe("Campo obrigatório!");
});

it("Mostra erro quando o título é muito longo", async () => {
const { getByText, getByPlaceholderText, getByTestId } = render(<CadastrarRotina />);

const titulo = getByPlaceholderText("Adicionar título");
const salvar = getByText("Salvar");

act(() => {
fireEvent.changeText(titulo, "A".repeat(101));
fireEvent.press(salvar);
});

const erroTitulo = getByTestId("Erro-titulo");
expect(erroTitulo.props.children.props.text).toBe("O título deve ter no máximo 100 caracteres.");
});

it("Mostra erro para o formato de data incorreta", async () => {
const { getByText, getByPlaceholderText, getByTestId } = render(<CadastrarRotina />);

const data = getByPlaceholderText("Data da rotina");
const salvar = getByText("Salvar");

act(() => {
fireEvent.changeText(data, "2010");
fireEvent.press(salvar);
});

const erroData = getByTestId("Erro-data");
expect(erroData.props.children.props.text).toBe("Data deve ser no formato dd/mm/yyyy!");
});

it("Mostra erro para o formato de tempo incorreto", async () => {
const { getByText, getByPlaceholderText, getByTestId } = render(<CadastrarRotina />);

const hora = getByPlaceholderText("Horário de início");
const salvar = getByText("Salvar");

act(() => {
fireEvent.changeText(hora, "125:00");
fireEvent.press(salvar);
});

const erroHora = getByTestId("Erro-hora");
expect(erroHora.props.children.props.text).toBe("Hora deve ser no formato hh:mm!");
});

it("Mostra erro quando descrição é muito longa", async () => {
const { getByText, getByPlaceholderText, getByTestId } = render(<CadastrarRotina />);

const descricao = getByPlaceholderText("Descrição");
const salvar = getByText("Salvar");

act(() => {
fireEvent.changeText(descricao, "A".repeat(301));
fireEvent.press(salvar);
});

const erroDescricao = getByTestId("Erro-descricao");
expect(erroDescricao.props.children.props.text).toBe("A descrição deve ter no máximo 300 caracteres.");
});
});
34 changes: 34 additions & 0 deletions src/app/__tests__/editarPerfil.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
import React from "react";
import { render, fireEvent, waitFor, act } from "@testing-library/react-native";
import EditarPerfil from "../private/pages/editarPerfil";
import { router, useLocalSearchParams } from "expo-router";

// Substituindo o módulo real do expo-router por uma versão mockada
jest.mock('expo-router', () => ({
// função mockada com objeto de retorno especificado
useLocalSearchParams: jest.fn().mockReturnValue({
id: "123",
nome: "Nome Teste",
foto: null,
}),
// mockando o objeto router
router: {
push: jest.fn(),
back: jest.fn(),
canGoBack: jest.fn().mockReturnValue(true),
},
}));

describe("EditarPerfil component", () => {
test("Atualiza nome com o input", async () => {
Expand Down Expand Up @@ -110,4 +127,21 @@ describe("EditarPerfil component", () => {
expect(findByText("Prosseguir com a exclusão da conta?")).toBeTruthy();
});
});

// Novo teste para verificar a navegação ao clicar no botão de voltar
test("Navega para a tela anterior ao clicar no botão de voltar", async () => {
// Renderiza o componente EditarPerfil
const { getByTestId } = render(<EditarPerfil />);

// Obtendo o botão de voltar
const backButton = getByTestId("back-button-pressable");

// Simula o clique no botão de voltar
fireEvent.press(backButton);

// Verifica se a função de navegação foi chamada corretamente
await waitFor(() => {
expect(router.push).toHaveBeenCalledWith("/private/tabs/perfil");
});
});
});
10 changes: 10 additions & 0 deletions src/app/__tests__/reports/sonar-report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<testExecutions version="1">
<file path="src\app\__tests__\cadastrarRotina.spec.tsx">
<testCase name="CadastrarRotina component renders correctly" duration="619" />
<testCase name="CadastrarRotina component Mostra erro quando o t&#xed;tulo est&#xe1; vazio" duration="43" />
<testCase name="CadastrarRotina component Mostra erro quando o t&#xed;tulo &#xe9; muito longo" duration="34" />
<testCase name="CadastrarRotina component Mostra erro para o formato de data incorreta" duration="43" />
<testCase name="CadastrarRotina component Mostra erro para o formato de tempo incorreto" duration="30" />
<testCase name="CadastrarRotina component Mostra erro quando descri&#xe7;&#xe3;o &#xe9; muito longa" duration="33" />
</file>
</testExecutions>
1 change: 1 addition & 0 deletions src/app/db/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default schemaMigrations({
{ name: 'telefoneResponsavel', type: 'string' },
{ name: 'descricao', type: 'string', isOptional: true },
{ name: 'user_id', type: 'string', isIndexed: true },
{ name: 'foto', type: 'string' },
],
}),
},
Expand Down
1 change: 1 addition & 0 deletions src/app/model/Idoso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default class Idoso extends Model {
@field('tipoSanguineo') tipoSanguineo!: string;
@text('telefoneResponsavel') telefoneResponsavel!: string;
@text('descricao') descricao!: string;
@text('foto') foto!: string; // Adicione a propriedade foto aqui

@field('user_id') userId!: string;

Expand Down
Loading