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

Integrate signup api in onboarding #735

Merged
merged 31 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f6e5264
add signup api
vinit717 Nov 6, 2023
7aac6eb
feat: add onboarding service file
vinit717 Nov 25, 2023
1421457
Refactor: test for step one component
vinit717 Nov 25, 2023
90e189d
Merge branch 'develop-ember' into onboarding/signup-api
vinit717 Nov 25, 2023
9fff41f
Merge branch 'develop-ember' of https://github.com/Real-Dev-Squad/web…
vinit717 Dec 11, 2023
f4ca385
Merge branch 'develop-ember' of https://github.com/Real-Dev-Squad/web…
vinit717 Dec 12, 2023
279f95f
feat: add ember data in generate username api
vinit717 Dec 12, 2023
4431b9c
Merge branch 'onboarding/signup-api' of https://github.com/Real-Dev-S…
vinit717 Dec 12, 2023
be6d1b8
feat: add return type in json spec for username api
vinit717 Dec 14, 2023
237877d
feat: add ember data for patch call
vinit717 Dec 14, 2023
0b39e66
feat: add header and remove id from payload
vinit717 Dec 15, 2023
1817f80
remove unwanted code and console statement
vinit717 Dec 16, 2023
0bc093c
feat: wrote test for onboarding service
vinit717 Dec 16, 2023
7d32d5a
Merge branch 'develop-ember' of https://github.com/Real-Dev-Squad/web…
vinit717 Dec 17, 2023
117d9ba
refactor : remove unwanted code and add empty username condition
vinit717 Dec 17, 2023
3ede1db
feat: add test for signup btn
vinit717 Dec 17, 2023
28d8823
refactor: add verify steps in onboarding service
vinit717 Dec 17, 2023
38046e9
test: write onboarding service test for checking func is being called
vinit717 Dec 18, 2023
5055fd6
Refactor signup test in onboarding service unit tests
vinit717 Dec 19, 2023
cf0b64c
Refactor user model to add onobarding as default status
vinit717 Dec 19, 2023
be9b989
refactor and remove unnecessary code
vinit717 Dec 19, 2023
9d0d9e4
remove unnecessary assertion in test
vinit717 Dec 20, 2023
4013af1
fix number os assertions in test
vinit717 Dec 20, 2023
635f96b
removed username foe create record
vinit717 Dec 20, 2023
1d46661
Merge branch 'develop-ember' into onboarding/signup-api
satyam73 Dec 21, 2023
4b26a8b
Merge branch 'develop-ember' into onboarding/signup-api
vinit717 Dec 22, 2023
14421ad
move errors to constants
vinit717 Dec 22, 2023
343bddb
Merge branch 'onboarding/signup-api' of https://github.com/Real-Dev-S…
vinit717 Dec 22, 2023
fcd55e4
use const and define variable for username
vinit717 Dec 22, 2023
7e456fa
add comment for removing id in serializers
vinit717 Dec 25, 2023
1eb7b00
Merge branch 'develop-ember' into onboarding/signup-api
vinit717 Dec 26, 2023
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
5 changes: 5 additions & 0 deletions app/adapters/application.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import JSONAPIAdapter from '@ember-data/adapter/json-api';
import { APPS } from 'website-www/constants/urls';

export default class ApplicationAdapter extends JSONAPIAdapter {
host = APPS.API_BACKEND;

headers = {
'Content-Type': 'application/json',
};

ajaxOptions() {
const options = super.ajaxOptions(...arguments);
options.credentials = 'include';
Expand Down
11 changes: 11 additions & 0 deletions app/adapters/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,15 @@ export default class UserAdapter extends ApplicationAdapter {
}
return super.urlForQuery(...arguments);
}

urlForQueryRecord(query) {
if (query.firstname && query.lastname) {
return `${super.urlForQueryRecord(...arguments)}/username`;
}
return super.urlForQueryRecord(...arguments);
}

urlForUpdateRecord() {
return `${this.host}/users/self`;
}
}
18 changes: 2 additions & 16 deletions app/components/signup-steps/step-one.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,6 @@
<div class='error__message'>{{this.errorMessage.lastname}}</div>
{{/if}}

<Reusables::OnboardingInput
@field='Username'
@name='username'
@type='text'
@required={{true}}
@value={{this.data.username}}
@isValid={{this.isValid}}
@hasButtonInsideInput={{true}}
@classDisableInput='input-disable'
@onClickGetUsername={{this.getUsername}}
@onInput={{this.inputHandler}}
@disabled={{true}}
/>

<Reusables::Dropdown
@field='Select your role'
@name='role'
Expand Down Expand Up @@ -79,9 +65,9 @@
<Reusables::Button
@text='Signup'
@variant='dark'
@onClick={{this.handleButtonClick}}
@onClick={{this.signup}}
@test='signup'
@disabled={{if this.isSignupButtonDisabled true false}}
@disabled={{this.isSignupButtonDisabled}}
@type='button'
/>
</div>
36 changes: 23 additions & 13 deletions app/components/signup-steps/step-one.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { APPS } from '../../constants/urls';
import { toastNotificationTimeoutOptions } from '../../constants/toast-notification';
export default class SignupStepsStepOneComponent extends Component {
@service toast;
@service onboarding;
@tracked data = { firstname: '', lastname: '', username: '', role: '' };
@tracked isSignupButtonDisabled = true;
@tracked isValid = true;
Expand All @@ -35,17 +36,11 @@ export default class SignupStepsStepOneComponent extends Component {
return (
!!this.data.firstname &&
!!this.data.lastname &&
!!this.data.username &&
!!this.data.role &&
this.mavenRoleConfirm
);
} else {
return (
!!this.data.firstname &&
!!this.data.lastname &&
!!this.data.username &&
!!this.data.role
);
return !!this.data.firstname && !!this.data.lastname && !!this.data.role;
}
}

Expand Down Expand Up @@ -118,13 +113,28 @@ export default class SignupStepsStepOneComponent extends Component {
}
}

@action handleButtonClick() {
this.isSignupButtonDisabled = true;
this.signup();
localStorage.setItem('role', this.data.role);
}

@action async signup() {
const { username } = await this.onboarding.generateUsername(
this.data.firstname,
this.data.lastname,
);

let dataToUpdate = {
username,
first_name: this.data.firstname,
last_name: this.data.lastname,
};

if (this.data.role !== 'Developer') {
dataToUpdate.roles = {
maven: this.data.role === 'Maven',
designer: this.data.role === 'Designer',
productmanager: this.data.role === 'Product Manager',
};
}

await this.onboarding.signup(dataToUpdate);
localStorage.setItem('role', this.data.role);
satyam73 marked this conversation as resolved.
Show resolved Hide resolved
satyam73 marked this conversation as resolved.
Show resolved Hide resolved
this.args.incrementStep();
}
}
2 changes: 1 addition & 1 deletion app/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default class UserModel extends Model {
@attr first_name;
@attr last_name;
@attr username;
@attr('string', { defaultValue: 'active' }) status;
@attr('string', { defaultValue: 'onboarding' }) status;
satyam73 marked this conversation as resolved.
Show resolved Hide resolved
@attr roles;
@attr yoe;
@attr picture;
Expand Down
29 changes: 29 additions & 0 deletions app/serializers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default class UserSerializer extends ApplicationSerializer {
};
return { error };
}

const data = payload.users.map((user) => {
const { id, ...other } = user;
return {
Expand All @@ -21,4 +22,32 @@ export default class UserSerializer extends ApplicationSerializer {
const links = { ...payload.links, first: null, last: null };
return { data, links };
}

normalizeResponse(store, primaryModelClass, payload, id, requestType) {
if (requestType === 'queryRecord' && payload.username) {
return {
data: {
id: payload.username,
type: primaryModelClass.modelName,
attributes: {
username: payload.username,
},
},
};
} else {
satyam73 marked this conversation as resolved.
Show resolved Hide resolved
return super.normalizeResponse(
store,
primaryModelClass,
payload,
id,
requestType,
);
}
}

serialize() {
let json = super.serialize(...arguments);
delete json.id;
return json;
}
vinit717 marked this conversation as resolved.
Show resolved Hide resolved
}
58 changes: 58 additions & 0 deletions app/services/onboarding.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Service from '@ember/service';
import { inject as service } from '@ember/service';
import { TOAST_OPTIONS } from '../constants/toast-options';

export default class OnboardingService extends Service {
@service store;
@service login;
@service toast;

constructor() {
super(...arguments);
this.login.checkAuth();
satyam73 marked this conversation as resolved.
Show resolved Hide resolved
}
async signup(dataToUpdate) {
satyam73 marked this conversation as resolved.
Show resolved Hide resolved
try {
let user = this.store.peekRecord('user', dataToUpdate.username);
satyam73 marked this conversation as resolved.
Show resolved Hide resolved

if (!user) {
user = this.store.createRecord('user', {
username: dataToUpdate.username,
});
}
satyam73 marked this conversation as resolved.
Show resolved Hide resolved

if (dataToUpdate.roles) {
user.set('roles', {
...user.get('roles'),
...dataToUpdate.roles,
});
}

user.setProperties({
first_name: dataToUpdate.first_name,
last_name: dataToUpdate.last_name,
});

await user.save();
} catch (error) {
this.toast.error('Something went wrong!', 'error!', TOAST_OPTIONS);
vinit717 marked this conversation as resolved.
Show resolved Hide resolved
}
}

async generateUsername(firstname, lastname) {
try {
const sanitizedFirstname = firstname.toLowerCase();
const sanitizedLastname = lastname.toLowerCase();
const user = await this.store.queryRecord('user', {
firstname: sanitizedFirstname,
lastname: sanitizedLastname,
dev: true,
satyam73 marked this conversation as resolved.
Show resolved Hide resolved
});
if (user && user.get('username')) {
satyam73 marked this conversation as resolved.
Show resolved Hide resolved
return user;
}
} catch (err) {
this.toast.error('Username cannot be generated', 'error!', TOAST_OPTIONS);
}
}
}
74 changes: 5 additions & 69 deletions tests/integration/components/signup-steps/step-one-test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { module, test, skip } from 'qunit';
import { module, test } from 'qunit';
import { setupRenderingTest } from 'website-www/tests/helpers';
import { render, typeIn, select, click } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
Expand Down Expand Up @@ -47,67 +47,6 @@ module('Integration | Component | signup-steps/step-one', function (hooks) {
assert.dom('[data-test-input-field]').hasProperty('value', 'shubham');
});

test('it render disable username input field and disable Generate Username button on signupDetails page', async function (assert) {
assert.expect(19);

await render(hbs`<SignupSteps::StepOne />`);

assert
.dom('[data-test-input-field=username]')
.hasAttribute('name', 'username');
assert.dom('[data-test-input=username]').hasClass('input-box');
assert.dom('[data-test-input=username]').hasClass('input-box--btn');

assert.dom('[data-test-label=username]').hasClass('label');
assert.dom('[data-test-label=username]').hasText('Username');
assert.dom('[data-test-label=username]').hasAttribute('for', 'username');

assert.dom('[data-test-required=username]').hasClass('required');

assert.dom('[data-test-input-field=username]').hasClass('input__field');
assert.dom('[data-test-input-field=username]').hasClass('input-disable');

assert.dom('[data-test-input-field=username]').hasAttribute('required');
assert
.dom('[data-test-input-field=username]')
.hasAttribute('name', 'username');
assert.dom('[data-test-input-field=username]').hasProperty('type', 'text');
assert
.dom('[data-test-input-field=username]')
.hasAttribute('id', 'username');
assert
.dom('[data-test-input-field=username]')
.hasProperty('disabled', true);

assert.dom('[data-test-button=generateUsername]').exists();
assert
.dom('[data-test-button=generateUsername]')
.hasClass('btn-generateUsername');
assert
.dom('[data-test-button=generateUsername]')
.hasProperty('type', 'button');
assert
.dom('[data-test-button=generateUsername]')
.hasText('Generate Username');
assert
.dom('[data-test-button=generateUsername]')
.hasProperty('disabled', true);
});

test('generateUsername button is enabled when firstname and lastname input fields are not empty and valid input', async function (assert) {
assert.expect(1);
this.set('onInput', (e) => {
this.value = e.target.value;
});

await render(hbs`<SignupSteps::StepOne />`);
await typeIn('[data-test-input-field=firstname]', 'shubham');
await typeIn('[data-test-input-field=lastname]', 'sigdar');
assert
.dom('[data-test-button=generateUsername]')
.hasProperty('disabled', false);
});

test('render select your role dropdown on signup details page ', async function (assert) {
assert.expect(11);

Expand Down Expand Up @@ -140,9 +79,7 @@ module('Integration | Component | signup-steps/step-one', function (hooks) {
await typeIn('[data-test-input-field=firstname]', 'shubham_1');
await typeIn('[data-test-input-field=lastname]', 'sigdar@');
assert.dom('.error__message').exists();
assert
.dom('[data-test-button=generateUsername]')
.hasProperty('disabled', true);
assert.dom('[data-test-button=signup]').hasProperty('disabled', true);
});

test('it renders label and input checkbox when Maven role is chosen', async function (assert) {
Expand Down Expand Up @@ -180,17 +117,16 @@ module('Integration | Component | signup-steps/step-one', function (hooks) {
assert.dom('[data-test-button=signup]').hasText('Signup');
});

skip('role based button should be enabled when all required fields are filled', async function (assert) {
test('signup button should be enabled when all required fields are filled', async function (assert) {
assert.expect(1);
satyam73 marked this conversation as resolved.
Show resolved Hide resolved

await render(hbs`<SignupSteps::StepOne />`);

await typeIn('[data-test-input-field=firstname]', 'shubham');
await typeIn('[data-test-input-field=lastname]', 'sigdar');
await click('[data-test-button=generateUsername]');

select('[data-test-dropdown-field]', 'Maven');
await click('[data-test-dropdown-option="Maven"]');
select('[data-test-dropdown-field]', 'Designer');
await click('[data-test-dropdown-option="Designer"]');

assert.dom('[data-test-button=signup]').hasProperty('disabled', false);
});
Expand Down
Loading
Loading