* Reduce code duplication in onboarding tests * Update variable names for consistency * Improve test descriptions and format * Refactor a useless test This test was fairly pointless, but hopefully with this refactor it could detect a regression? Although, I think it's really just testing the that the Preact framework's state mechanism is working the way we expect it to, but it might be worth leaving this test in.
360 lines
10 KiB
JavaScript
360 lines
10 KiB
JavaScript
import { h } from 'preact';
|
|
import { deep } from 'preact-render-spy';
|
|
import fetch from 'jest-fetch-mock';
|
|
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
|
|
import Onboarding from '../Onboarding';
|
|
import BioForm from '../components/BioForm';
|
|
import PersonalInfoForm from '../components/PersonalInfoForm';
|
|
import EmailTermsConditionsForm from '../components/EmailListTermsConditionsForm';
|
|
import FollowTags from '../components/FollowTags';
|
|
import FollowUsers from '../components/FollowUsers';
|
|
|
|
global.fetch = fetch;
|
|
|
|
function flushPromises() {
|
|
return new Promise(resolve => setImmediate(resolve));
|
|
}
|
|
|
|
function initializeSlides(currentSlide, dataUser = null, mockData = null) {
|
|
const onboardingSlides = deep(<Onboarding />);
|
|
|
|
if (mockData) {
|
|
fetch.once(mockData);
|
|
}
|
|
|
|
document.body.setAttribute('data-user', dataUser);
|
|
onboardingSlides.setState({ currentSlide });
|
|
|
|
return onboardingSlides;
|
|
}
|
|
|
|
describe('<Onboarding />', () => {
|
|
beforeAll(() => {
|
|
expect.extend(toHaveNoViolations);
|
|
});
|
|
beforeEach(() => {
|
|
fetch.resetMocks();
|
|
});
|
|
|
|
const fakeTagsResponse = JSON.stringify([
|
|
{
|
|
bg_color_hex: '#000000',
|
|
id: 715,
|
|
name: 'discuss',
|
|
text_color_hex: '#ffffff',
|
|
},
|
|
{
|
|
bg_color_hex: '#f7df1e',
|
|
id: 6,
|
|
name: 'javascript',
|
|
text_color_hex: '#000000',
|
|
},
|
|
{
|
|
bg_color_hex: '#2a2566',
|
|
id: 630,
|
|
name: 'career',
|
|
text_color_hex: '#ffffff',
|
|
},
|
|
]);
|
|
const fakeUsersResponse = JSON.stringify([
|
|
{
|
|
id: 1,
|
|
name: 'Ben Halpern',
|
|
profile_image_url: 'ben.jpg',
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'Krusty the Clown',
|
|
profile_image_url: 'clown.jpg',
|
|
},
|
|
{
|
|
id: 3,
|
|
name: 'dev.to staff',
|
|
profile_image_url: 'dev.jpg',
|
|
},
|
|
]);
|
|
const dataUser = JSON.stringify({
|
|
followed_tag_names: ['javascript'],
|
|
});
|
|
|
|
describe('IntroSlide', () => {
|
|
let onboardingSlides;
|
|
|
|
beforeEach(() => {
|
|
onboardingSlides = initializeSlides(0);
|
|
});
|
|
|
|
test('renders properly', () => {
|
|
expect(onboardingSlides).toMatchSnapshot();
|
|
});
|
|
|
|
test('should not have basic a11y violations', async () => {
|
|
const results = await axe(onboardingSlides.toString());
|
|
|
|
expect(results).toHaveNoViolations();
|
|
});
|
|
|
|
test('should advance', () => {
|
|
onboardingSlides.find('.next-button').simulate('click');
|
|
expect(onboardingSlides.state().currentSlide).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('EmailTermsConditionsForm', () => {
|
|
let onboardingSlides;
|
|
const codeOfConductCheckEvent = {
|
|
target: {
|
|
value: 'checked_code_of_conduct',
|
|
name: 'checked_code_of_conduct',
|
|
},
|
|
};
|
|
const termsAndConditionsCheckEvent = {
|
|
target: {
|
|
value: 'checked_terms_and_conditions',
|
|
name: 'checked_terms_and_conditions',
|
|
},
|
|
};
|
|
const updateCodeOfConduct = () => {
|
|
onboardingSlides
|
|
.find('#checked_code_of_conduct')
|
|
.simulate('change', codeOfConductCheckEvent);
|
|
};
|
|
const updateTermsAndConditions = () => {
|
|
onboardingSlides
|
|
.find('#checked_terms_and_conditions')
|
|
.simulate('change', termsAndConditionsCheckEvent);
|
|
};
|
|
|
|
beforeEach(() => {
|
|
onboardingSlides = initializeSlides(1, dataUser);
|
|
});
|
|
|
|
test('renders properly', () => {
|
|
expect(onboardingSlides).toMatchSnapshot();
|
|
});
|
|
|
|
// Arguably this test is actually just testing the Preact framework
|
|
// but for the sake of detecting a regression I am refactoring it instead
|
|
// of removing it (@jacobherrington)
|
|
test('should track state changes', () => {
|
|
const emailTerms = onboardingSlides.find(<EmailTermsConditionsForm />);
|
|
|
|
expect(emailTerms.state('checked_code_of_conduct')).toBe(false);
|
|
expect(emailTerms.state('checked_terms_and_conditions')).toBe(false);
|
|
|
|
updateCodeOfConduct();
|
|
updateTermsAndConditions();
|
|
|
|
expect(emailTerms.state('checked_code_of_conduct')).toBe(true);
|
|
expect(emailTerms.state('checked_terms_and_conditions')).toBe(true);
|
|
});
|
|
|
|
test('should not advance if required boxes are not checked', () => {
|
|
// When none of the boxes are checked
|
|
onboardingSlides.find('.next-button').simulate('click');
|
|
expect(onboardingSlides.state().currentSlide).toBe(1);
|
|
|
|
// When only the code of conduct is checked
|
|
updateCodeOfConduct();
|
|
expect(onboardingSlides.state().currentSlide).toBe(1);
|
|
|
|
// When only the terms and conditions are checked
|
|
updateCodeOfConduct();
|
|
updateTermsAndConditions();
|
|
onboardingSlides.find('.next-button').simulate('click');
|
|
expect(onboardingSlides.state().currentSlide).toBe(1);
|
|
});
|
|
|
|
test('should advance if required boxes are checked', async () => {
|
|
fetch.once({});
|
|
|
|
updateCodeOfConduct();
|
|
updateTermsAndConditions();
|
|
|
|
onboardingSlides.find('.next-button').simulate('click');
|
|
await flushPromises();
|
|
expect(onboardingSlides.state().currentSlide).toBe(2);
|
|
});
|
|
|
|
it('should step backward', () => {
|
|
onboardingSlides.find('.back-button').simulate('click');
|
|
expect(onboardingSlides.state().currentSlide).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('BioForm', () => {
|
|
let onboardingSlides;
|
|
const meta = document.createElement('meta');
|
|
|
|
meta.setAttribute('name', 'csrf-token');
|
|
document.body.appendChild(meta);
|
|
|
|
beforeEach(() => {
|
|
onboardingSlides = initializeSlides(2, dataUser);
|
|
});
|
|
|
|
test('renders properly', () => {
|
|
expect(onboardingSlides).toMatchSnapshot();
|
|
});
|
|
|
|
test('should allow user to fill forms and advance', async () => {
|
|
fetch.once({});
|
|
const bioForm = onboardingSlides.find(<BioForm />);
|
|
const event = { target: { value: 'my bio', name: 'summary' } };
|
|
|
|
onboardingSlides.find('textarea').simulate('change', event);
|
|
expect(bioForm.state('summary')).toBe(event.target.value);
|
|
bioForm.find('.next-button').simulate('click');
|
|
await flushPromises();
|
|
expect(onboardingSlides.state().currentSlide).toBe(3);
|
|
});
|
|
|
|
it('should step backward', () => {
|
|
onboardingSlides.find('.back-button').simulate('click');
|
|
expect(onboardingSlides.state().currentSlide).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('PersonalInformationForm', () => {
|
|
let onboardingSlides;
|
|
const meta = document.createElement('meta');
|
|
|
|
meta.setAttribute('name', 'csrf-token');
|
|
document.body.appendChild(meta);
|
|
|
|
beforeEach(() => {
|
|
onboardingSlides = initializeSlides(3, dataUser);
|
|
});
|
|
|
|
test('renders properly', () => {
|
|
expect(onboardingSlides).toMatchSnapshot();
|
|
});
|
|
|
|
it('should move to the previous slide upon clicking the back button', () => {
|
|
onboardingSlides.find('.back-button').simulate('click');
|
|
expect(onboardingSlides.state().currentSlide).toBe(2);
|
|
});
|
|
|
|
test('should allow user to fill forms and advance', async () => {
|
|
fetch.once({});
|
|
|
|
const personalInfoForm = onboardingSlides.find(<PersonalInfoForm />);
|
|
const locationEvent = {
|
|
target: { value: 'my location', name: 'location' },
|
|
};
|
|
const titleEvent = {
|
|
target: { value: 'my title', name: 'employment_title' },
|
|
};
|
|
const employerEvent = {
|
|
target: { value: 'my employer name', name: 'employer_name' },
|
|
};
|
|
|
|
onboardingSlides.find('#location').simulate('change', locationEvent);
|
|
onboardingSlides.find('#employment_title').simulate('change', titleEvent);
|
|
onboardingSlides.find('#employer_name').simulate('change', employerEvent);
|
|
|
|
expect(personalInfoForm.state('location')).toBe(
|
|
locationEvent.target.value,
|
|
);
|
|
expect(personalInfoForm.state('employment_title')).toBe(
|
|
titleEvent.target.value,
|
|
);
|
|
expect(personalInfoForm.state('employer_name')).toBe(
|
|
employerEvent.target.value,
|
|
);
|
|
|
|
personalInfoForm.find('.next-button').simulate('click');
|
|
fetch.once(fakeTagsResponse);
|
|
await flushPromises();
|
|
expect(onboardingSlides.state().currentSlide).toBe(4);
|
|
});
|
|
});
|
|
|
|
describe('FollowTags', () => {
|
|
let onboardingSlides;
|
|
|
|
beforeEach(async () => {
|
|
onboardingSlides = initializeSlides(4, dataUser, fakeTagsResponse);
|
|
await flushPromises();
|
|
});
|
|
|
|
test('renders properly', () => {
|
|
expect(onboardingSlides).toMatchSnapshot();
|
|
});
|
|
|
|
test('should render three tags', async () => {
|
|
expect(onboardingSlides.find('.tag').length).toBe(3);
|
|
});
|
|
|
|
test('should allow a user to add a tag', async () => {
|
|
fetch.once({});
|
|
const followTags = onboardingSlides.find(<FollowTags />);
|
|
|
|
onboardingSlides
|
|
.find('.tag')
|
|
.first()
|
|
.simulate('click');
|
|
expect(followTags.state('selectedTags').length).toBe(1);
|
|
onboardingSlides.find('.next-button').simulate('click');
|
|
fetch.once(fakeUsersResponse);
|
|
await flushPromises();
|
|
expect(onboardingSlides.state().currentSlide).toBe(5);
|
|
});
|
|
|
|
it('should step backward', () => {
|
|
onboardingSlides.find('.back-button').simulate('click');
|
|
expect(onboardingSlides.state().currentSlide).toBe(3);
|
|
});
|
|
});
|
|
|
|
describe('FollowUsers', () => {
|
|
let onboardingSlides;
|
|
|
|
beforeEach(async () => {
|
|
onboardingSlides = initializeSlides(5, dataUser, fakeUsersResponse);
|
|
await flushPromises();
|
|
});
|
|
|
|
test('renders properly', () => {
|
|
expect(onboardingSlides).toMatchSnapshot();
|
|
});
|
|
|
|
test('should render three users', async () => {
|
|
expect(onboardingSlides.find('.user').length).toBe(3);
|
|
});
|
|
|
|
test('should allow a user to select and advance', async () => {
|
|
fetch.once({});
|
|
const followUsers = onboardingSlides.find(<FollowUsers />);
|
|
|
|
onboardingSlides
|
|
.find('.user')
|
|
.first()
|
|
.simulate('click');
|
|
expect(followUsers.state('selectedUsers').length).toBe(2);
|
|
onboardingSlides.find('.next-button').simulate('click');
|
|
await flushPromises();
|
|
expect(onboardingSlides.state().currentSlide).toBe(6);
|
|
});
|
|
|
|
it('should step backward', async () => {
|
|
fetch.once(fakeTagsResponse);
|
|
onboardingSlides.find('.back-button').simulate('click');
|
|
await flushPromises();
|
|
expect(onboardingSlides.state().currentSlide).toBe(4);
|
|
});
|
|
});
|
|
|
|
describe('CloseSlide', () => {
|
|
let onboardingSlides;
|
|
|
|
beforeEach(() => {
|
|
onboardingSlides = initializeSlides(6);
|
|
});
|
|
|
|
test('renders properly', () => {
|
|
expect(onboardingSlides).toMatchSnapshot();
|
|
});
|
|
});
|
|
});
|