diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index 1f03afe..0000000 --- a/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/src/components/LengthCaracters/LengthCaracters.js b/src/components/LengthCaracters/LengthCaracters.js index 5b1e6b6..e1fed00 100644 --- a/src/components/LengthCaracters/LengthCaracters.js +++ b/src/components/LengthCaracters/LengthCaracters.js @@ -24,7 +24,7 @@ class LengthCaracters extends Component { const { lengthPassword } = this.state; return ( -
+

{`LENGTH: ${ lengthPassword }`}

4 diff --git a/src/components/Main/Main.js b/src/components/Main/Main.js index 9dda5bd..c1fe350 100644 --- a/src/components/Main/Main.js +++ b/src/components/Main/Main.js @@ -30,7 +30,7 @@ class Main extends Component { > { btnCopy } -

{ password }

+

{ password }

) } diff --git a/src/data/caracters.js b/src/data/caracters.js index 325aaa7..0c189d5 100644 --- a/src/data/caracters.js +++ b/src/data/caracters.js @@ -4,8 +4,8 @@ const caracters = { uppercase: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'], numbers: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], - symbols: ['>', '<', '@', '?', '/', '+', '-', '!', '#', '$', '%', '¨', '&', '*', - '(', ')', '_', '=', '°', '®', 'ŧ', 'ø', '[', ']', '~', '^', '}', '{', '|', '.', ',', + symbols: ['&', '<', '>', '@', '?', '/', '+', '!', '#', '-', '$', '%', '*', + '(', ')', '_', '=', '[', ']', '~', '^', '}', '{', '|', '.', ',', ':', ';'], }; diff --git a/src/helpers/convertSymbols.js b/src/helpers/convertSymbols.js new file mode 100644 index 0000000..5dfbe0b --- /dev/null +++ b/src/helpers/convertSymbols.js @@ -0,0 +1,9 @@ +const convert = (str) => { + str = str.replaceAll('&', '&'); + str = str.replaceAll('<', '<'); + str = str.replaceAll('>', '>'); + str = str.replaceAll('"', '"'); + return str; +}; + +export default convert; diff --git a/src/helpers/renderWithRedux.js b/src/helpers/renderWithRedux.js new file mode 100644 index 0000000..641548c --- /dev/null +++ b/src/helpers/renderWithRedux.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { Provider } from 'react-redux'; +import { createStore } from 'redux'; +import { render } from '@testing-library/react'; +import rootReducer from '../redux/reducers'; + +const renderWithRedux = ( + component, + { initialState, store = createStore(rootReducer, initialState) } = {}, +) => ({ + ...render({component}), + store, +}); + +export default renderWithRedux; diff --git a/src/tests/App.test.js b/src/tests/App.test.js new file mode 100644 index 0000000..6111fe2 --- /dev/null +++ b/src/tests/App.test.js @@ -0,0 +1,59 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import App from '../App'; +import renderWithRedux from '../helpers/renderWithRedux'; + +describe('Testa a tela inicial', () => { + it('Verifica se tem um título', () => { + renderWithRedux(); + + const title = screen.getByRole('heading', { level: 1, name: /Password Generator/i }); + + expect(title).toBeInTheDocument(); + }); + + it('Verifica se tem o texto "CLICK GENERATE"', () => { + renderWithRedux(); + + const text = screen.getByText(/CLICK GENERATE/i); + + expect(text).toBeInTheDocument(); + }); + + it('Verifica se existe a opção de escolher o tamanho', () => { + renderWithRedux(); + + const optionLength = screen.getByTestId('option-length'); + + expect(optionLength).toBeInTheDocument(); + }); + + it('Verifica se existe quatro inputs do tipo checkbox', () => { + renderWithRedux(); + + const optionsCheckbox = screen.getAllByRole('checkbox'); + const length = 4; + expect(optionsCheckbox).toHaveLength(length); + + const optionUppercase = screen.getByRole('checkbox', { name: /Include Uppercase/i }); + expect(optionUppercase).toBeInTheDocument(); + + const optionLowercase = screen.getByRole('checkbox', { name: /Include Lowercase/i }); + expect(optionLowercase).toBeInTheDocument(); + + const optionNumbers = screen.getByRole('checkbox', { name: /Include Numbers/i }); + expect(optionNumbers).toBeInTheDocument(); + + const optionSymbols = screen.getByRole('checkbox', { name: /Include Symbols/i }); + expect(optionSymbols).toBeInTheDocument(); + }); + + it('Verifica se existe um botão', () => { + renderWithRedux(); + + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + expect(btnGenerate).toBeInTheDocument(); + expect(btnGenerate.disabled).toBeTruthy(); + }); +}); diff --git a/src/tests/BtnGenerate.test.js b/src/tests/BtnGenerate.test.js new file mode 100644 index 0000000..95fe58b --- /dev/null +++ b/src/tests/BtnGenerate.test.js @@ -0,0 +1,29 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import App from '../App'; +import renderWithRedux from '../helpers/renderWithRedux'; + +describe('Testa o botão de gerar senha', () => { + it('Verifica se o botão está desabilitado ao renderizar a tela inicial', () => { + renderWithRedux(); + + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + expect(btnGenerate.disabled).toBeTruthy(); + }); + + it('Verifica se o botão habilita ao clicar nas opções', () => { + renderWithRedux(); + + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + const optionsCheckbox = screen.getAllByRole('checkbox'); + optionsCheckbox.forEach((option) => { + userEvent.click(option); + expect(btnGenerate.disabled).toBeFalsy(); + userEvent.click(option); + expect(btnGenerate.disabled).toBeTruthy(); + }); + }); +}); diff --git a/src/tests/Checkbox.test.js b/src/tests/Checkbox.test.js new file mode 100644 index 0000000..6c2814b --- /dev/null +++ b/src/tests/Checkbox.test.js @@ -0,0 +1,28 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import App from '../App'; +import renderWithRedux from '../helpers/renderWithRedux'; + +describe('Testa os Checkbox', () => { + it('Verifica se ao renderizar a tela os checkbox vem desmarcado', () => { + renderWithRedux(); + + const optionsCheckbox = screen.getAllByRole('checkbox'); + optionsCheckbox.forEach((option) => { + expect(option.checked).toBeFalsy(); + }); + }); + + it('Verifica se ao clicar no checkbox ele fica marcado', () => { + renderWithRedux(); + + const optionsCheckbox = screen.getAllByRole('checkbox'); + optionsCheckbox.forEach((option) => { + userEvent.click(option); + expect(option.checked).toBeTruthy(); + userEvent.click(option); + expect(option.checked).toBeFalsy(); + }); + }); +}); diff --git a/src/tests/LengthPassword.test.js b/src/tests/LengthPassword.test.js new file mode 100644 index 0000000..9734167 --- /dev/null +++ b/src/tests/LengthPassword.test.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import App from '../App'; +import renderWithRedux from '../helpers/renderWithRedux'; + +describe('Testa o tamanho da senha', () => { + it('Verifica se a senha é gerada como o tamanho de 17 caracteres', () => { + const length = 17; + renderWithRedux(, { initialState: { lengthPasswordReducer: { + length } } }); + + const optionUppercase = screen.getByRole('checkbox', { name: /Include Uppercase/i }); + userEvent.click(optionUppercase); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + userEvent.click(btnGenerate); + const password = screen.getByTestId('password'); + expect(password.innerHTML).toHaveLength(length); + }); + + it('Verifica se a senha é gerada como o tamanho de 4 caracteres', () => { + const length = 4; + renderWithRedux(); + + const optionUppercase = screen.getByRole('checkbox', { name: /Include Uppercase/i }); + userEvent.click(optionUppercase); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + userEvent.click(btnGenerate); + const password = screen.getByTestId('password'); + expect(password.innerHTML).toHaveLength(length); + }); + + it('Verifica se a senha é gerada como o tamanho de 20 caracteres', () => { + const length = 20; + renderWithRedux(, { initialState: { lengthPasswordReducer: { + length } } }); + + const optionUppercase = screen.getByRole('checkbox', { name: /Include Uppercase/i }); + userEvent.click(optionUppercase); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + userEvent.click(btnGenerate); + const password = screen.getByTestId('password'); + expect(password.innerHTML).toHaveLength(length); + }); +}); diff --git a/src/tests/PasswordEachOption.test.js b/src/tests/PasswordEachOption.test.js new file mode 100644 index 0000000..b5ef19e --- /dev/null +++ b/src/tests/PasswordEachOption.test.js @@ -0,0 +1,74 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import App from '../App'; +import renderWithRedux from '../helpers/renderWithRedux'; +import caracters from '../data/caracters'; +import convert from '../helpers/convertSymbols'; + +describe('Verifica os caracteres da senha', () => { + beforeEach(() => { + renderWithRedux(); + }); + + it('Verifica se todos os caracteres são maiúsculas', () => { + const optionUppercase = screen.getByRole('checkbox', { name: /Include Uppercase/i }); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + userEvent.click(optionUppercase); + userEvent.click(btnGenerate); + + const password = screen.getByTestId('password'); + const passwordCompose = password.innerHTML.split(''); + const validation = passwordCompose + .every((character) => character === character.toUpperCase()); + + expect(validation).toBeTruthy(); + }); + + it('Verifica se todos os caracteres são minúsculos', () => { + const optionLowercase = screen.getByRole('checkbox', { name: /Include Lowercase/i }); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + userEvent.click(optionLowercase); + userEvent.click(btnGenerate); + + const password = screen.getByTestId('password'); + const passwordCompose = password.innerHTML.split(''); + const validation = passwordCompose + .every((character) => character === character.toLowerCase()); + + expect(validation).toBeTruthy(); + }); + + it('Verifica se todos os caracteres são números', () => { + const optionNumbers = screen.getByRole('checkbox', { name: /Include Numbers/i }); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + userEvent.click(optionNumbers); + userEvent.click(btnGenerate); + + const password = screen.getByTestId('password'); + const passwordCompose = password.innerHTML.split(''); + const validation = passwordCompose + .every((character) => caracters.numbers.includes(character)); + + expect(validation).toBeTruthy(); + }); + + it('Verifica se todos os caracteres são símbolos', () => { + const optionSymbols = screen.getByRole('checkbox', { name: /Include Symbols/i }); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + userEvent.click(optionSymbols); + userEvent.click(btnGenerate); + + const password = screen.getByTestId('password'); + const passwordConverted = convert(password.innerHTML); + const passwordCompose = passwordConverted.split(''); + const validation = passwordCompose + .every((character) => caracters.symbols.includes(character)); + + expect(validation).toBeTruthy(); + }); +}); diff --git a/src/tests/PasswordMultipleOptions.test.js b/src/tests/PasswordMultipleOptions.test.js new file mode 100644 index 0000000..e20aafc --- /dev/null +++ b/src/tests/PasswordMultipleOptions.test.js @@ -0,0 +1,88 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import App from '../App'; +import renderWithRedux from '../helpers/renderWithRedux'; +import caracters from '../data/caracters'; +import convert from '../helpers/convertSymbols'; + +describe('Testa se a senha inclui as opções desejadas', () => { + beforeEach(() => { + renderWithRedux(); + }); + + it('Verifica se a senha inclui maiúsculas e minúsculas', () => { + const optionUppercase = screen.getByRole('checkbox', { name: /Include Uppercase/i }); + const optionLowercase = screen.getByRole('checkbox', { name: /Include Lowercase/i }); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + userEvent.click(optionUppercase); + userEvent.click(optionLowercase); + userEvent.click(btnGenerate); + + const password = screen.getByTestId('password'); + const passwordCompose = password.innerHTML.split(''); + const chosenOptions = passwordCompose + .every((character) => caracters.uppercase.includes(character) + || caracters.lowercase.includes(character)); + + expect(chosenOptions).toBeTruthy(); + + const unchosenOptions = passwordCompose + .every((character) => caracters.numbers.includes(character) + || caracters.symbols.includes(character)); + + expect(unchosenOptions).toBeFalsy(); + }); + + it('Verifica se a senha inclui símbolos e números', () => { + const optionNumbers = screen.getByRole('checkbox', { name: /Include Numbers/i }); + const optionSymbols = screen.getByRole('checkbox', { name: /Include Symbols/i }); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + userEvent.click(optionNumbers); + userEvent.click(optionSymbols); + userEvent.click(btnGenerate); + + const password = screen.getByTestId('password'); + const passwordConverted = convert(password.innerHTML); + const passwordCompose = passwordConverted.split(''); + + const chosenOptions = passwordCompose + .every((character) => caracters.symbols.includes(character) + || caracters.numbers.includes(character)); + + expect(chosenOptions).toBeTruthy(); + + const unchosenOptions = passwordCompose + .every((character) => caracters.uppercase.includes(character) + || caracters.lowercase.includes(character)); + + expect(unchosenOptions).toBeFalsy(); + }); + + it('Verifica se a senha inclui todas as opções', () => { + const optionUppercase = screen.getByRole('checkbox', { name: /Include Uppercase/i }); + const optionLowercase = screen.getByRole('checkbox', { name: /Include Lowercase/i }); + const optionNumbers = screen.getByRole('checkbox', { name: /Include Numbers/i }); + const optionSymbols = screen.getByRole('checkbox', { name: /Include Symbols/i }); + const btnGenerate = screen.getByRole('button', { name: /GENERATE PASSWORD/i }); + + userEvent.click(optionUppercase); + userEvent.click(optionLowercase); + userEvent.click(optionNumbers); + userEvent.click(optionSymbols); + userEvent.click(btnGenerate); + + const password = screen.getByTestId('password'); + + const { uppercase, lowercase, numbers, symbols } = caracters; + const options = [uppercase, lowercase, numbers, symbols]; + + const validation = options.every((option) => ( + option.some((character) => password.innerHTML.includes(character)) + )); + + expect(validation).toBeTruthy(); + }); +});