docbrown/app/javascript/onboarding/__tests__/Onboarding.test.jsx
Ali Spittel 52c60ce37e Feature/refactored onboarding (#3333)
* set up refactored onboarding

* create onboarding page

* add in first slide and change slide functionality

* fix test suite

* profile refactor

* profile refactor

* refactor to api

* add checkbox fields

* add checkbox fields

* remove puts

* add basic css

* add styling

* add redirect

* hide back and next at first and last slides

* test refactored onboarding

* test refactored onboarding

* remove article edits

* Fix schema

* Add deleted file back in

* Add default value for checked_t&c column

* Adjust HTML structure to keep nav buttons in place

* Fix ESLint issues on Onboarding.jsx file

* Handling for undefined or empty followedTags on getUserTags

* Fix codeclimate issues

* Fix codeclimate issues

* Fix more codeclimate issues

* Fix more codeclimate issues

* Update Onboarding snapshots

* Uncheck the CoC and T&C checkboxes on render

* Update snapshots

* Return false instead of raising error

* Update spec to use new onboarding

* Redirect to onboarding if haven't seen it yet

* Prevent redirect to onboarding from /signout_confirm

* Use assign_attributes instead of saving twice

* Move COC and T&C checkbox page to second slide

* Add 'go back to original page' functionality

* Reuse ready prototype logic

* Keep track of the last visited onboarding page

* Fix email subscription bug

* Fix overflow issue for tags page

* Remove height to prevent page container scrolling

* Check for CoC and T&C for displaying onboarding

* Add InstantClick redirect and preserve referrer in client

* Fix async update + check by using localStorage

* Turn off onboarding for tests

* Finalize design for onboarding

* Finalize design for onboarding

* Make bulk follows during onboarding

* Fix bulk follow test
2019-07-26 15:53:32 -04:00

317 lines
9.8 KiB
JavaScript

import { h } from 'preact';
import { deep } from 'preact-render-spy';
import fetch from 'jest-fetch-mock';
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));
}
describe('<Onboarding />', () => {
beforeEach(() => {
fetch.resetMocks();
});
const fakeTagResponse = 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 fakeUsersToFollowResponse = 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(() => {
document.body.setAttribute('data-user', null);
onboardingSlides = deep(<Onboarding />);
});
test('renders properly', () => {
expect(onboardingSlides).toMatchSnapshot();
});
test('should move to the next slide upon clicking the next button', () => {
onboardingSlides.find('.next-button').simulate('click');
expect(onboardingSlides.state().currentSlide).toBe(1);
});
});
describe('EmailTermsConditionsForm', () => {
let onboardingSlides;
beforeEach(() => {
document.body.setAttribute('data-user', dataUser);
onboardingSlides = deep(<Onboarding />);
onboardingSlides.setState({ currentSlide: 1 });
});
test('renders properly', () => {
expect(onboardingSlides).toMatchSnapshot();
});
test('should not move if code of conduct is not agreed to', () => {
onboardingSlides.find('.next-button').simulate('click');
expect(onboardingSlides.state().currentSlide).toBe(1);
});
test('should not move if terms and conditions are not met', () => {
const event = {
target: {
value: 'checked_code_of_conduct',
name: 'checked_code_of_conduct',
},
};
onboardingSlides
.find('#checked_code_of_conduct')
.simulate('change', event);
onboardingSlides.find('.next-button').simulate('click');
expect(onboardingSlides.state().currentSlide).toBe(1);
});
test('should move to the next slide if code of conduct and terms and conditions are met', async () => {
fetch.once({});
onboardingSlides.find('#checked_code_of_conduct').simulate('change', {
target: {
value: 'checked_code_of_conduct',
name: 'checked_code_of_conduct',
},
});
onboardingSlides
.find('#checked_terms_and_conditions')
.simulate('change', {
target: {
value: 'checked_terms_and_conditions',
name: 'checked_terms_and_conditions',
},
});
const emailTerms = onboardingSlides.find(<EmailTermsConditionsForm />);
expect(emailTerms.state('checked_code_of_conduct')).toBe(true);
onboardingSlides.find('.next-button').simulate('click');
await flushPromises();
expect(onboardingSlides.state().currentSlide).toBe(2);
});
it('should move to the previous slide upon clicking the back button', () => {
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 = deep(<Onboarding />);
onboardingSlides.setState({ currentSlide: 2 });
document.body.setAttribute('data-user', 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(1);
});
test('forms can be filled and submitted', 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('my bio');
bioForm.find('.next-button').simulate('click');
await flushPromises();
expect(onboardingSlides.state().currentSlide).toBe(3);
});
});
describe('PersonalInformationForm', () => {
let onboardingSlides;
const meta = document.createElement('meta');
meta.setAttribute('name', 'csrf-token');
document.body.appendChild(meta);
beforeEach(() => {
onboardingSlides = deep(<Onboarding />);
onboardingSlides.setState({ currentSlide: 3 });
document.body.setAttribute('data-user', 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('forms can be filled and submitted', async () => {
fetch.once({});
const personalInfoForm = onboardingSlides.find(<PersonalInfoForm />);
const locationEvent = {
target: { value: 'my location', name: 'location' },
};
onboardingSlides.find('#location').simulate('change', locationEvent);
const titleEvent = {
target: { value: 'my title', name: 'employment_title' },
};
onboardingSlides.find('#employment_title').simulate('change', titleEvent);
const employerEvent = {
target: { value: 'my employer name', name: 'employer_name' },
};
onboardingSlides.find('#employer_name').simulate('change', employerEvent);
expect(personalInfoForm.state('location')).toBe('my location');
expect(personalInfoForm.state('employment_title')).toBe('my title');
expect(personalInfoForm.state('employer_name')).toBe('my employer name');
personalInfoForm.find('.next-button').simulate('click');
fetch.once(fakeTagResponse);
await flushPromises();
expect(onboardingSlides.state().currentSlide).toBe(4);
});
});
describe('FollowTags', () => {
let onboardingSlides;
beforeEach(async () => {
document.body.setAttribute('data-user', dataUser);
onboardingSlides = deep(<Onboarding />);
fetch.once(fakeTagResponse);
onboardingSlides.setState({ currentSlide: 4 });
await flushPromises();
});
test('renders properly', () => {
expect(onboardingSlides).toMatchSnapshot();
});
test('it should render three tags', async () => {
expect(onboardingSlides.find('.tag').length).toBe(3);
});
test('adding a tag and submitting works', 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(fakeUsersToFollowResponse);
await flushPromises();
expect(onboardingSlides.state().currentSlide).toBe(5);
});
it('should move to the previous slide upon clicking the back button', () => {
onboardingSlides.find('.back-button').simulate('click');
expect(onboardingSlides.state().currentSlide).toBe(3);
});
});
describe('FollowUsers', () => {
let onboardingSlides;
beforeEach(async () => {
document.body.setAttribute('data-user', dataUser);
onboardingSlides = deep(<Onboarding />);
fetch.once(fakeUsersToFollowResponse);
onboardingSlides.setState({ currentSlide: 5 });
await flushPromises();
});
test('renders properly', () => {
expect(onboardingSlides).toMatchSnapshot();
});
test('it should render three users', async () => {
expect(onboardingSlides.find('.user').length).toBe(3);
});
test('adding a user and submitting works', 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 move to the previous slide upon clicking the back button', async () => {
fetch.once(fakeTagResponse);
onboardingSlides.find('.back-button').simulate('click');
await flushPromises();
expect(onboardingSlides.state().currentSlide).toBe(4);
});
});
describe('CloseSlide', () => {
let onboardingSlides;
beforeEach(() => {
document.body.setAttribute('data-user', null);
onboardingSlides = deep(<Onboarding />);
onboardingSlides.setState({ currentSlide: 6 });
});
test('renders properly', () => {
expect(onboardingSlides).toMatchSnapshot();
});
});
});