From e7912557eb3e1759880c69a415bf386fe6f08a28 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Tue, 20 Dec 2022 16:47:46 +0100 Subject: [PATCH] (test) UserProfileForm --- .../components/socials/edit-socials.tsx | 2 +- app/frontend/src/javascript/models/user.ts | 2 +- test/frontend/__fixtures__/auth_providers.ts | 15 +++++ .../__fixtures__/profile_custom_fields.ts | 16 +++++ test/frontend/__fixtures__/settings.ts | 24 ++++--- test/frontend/__fixtures__/users.ts | 28 ++++---- test/frontend/__lib__/auth.ts | 7 ++ test/frontend/__setup__/globals.js | 2 + test/frontend/__setup__/server.js | 17 ++++- .../user/user-profile-form.test.tsx | 64 +++++++++++++++++++ 10 files changed, 149 insertions(+), 28 deletions(-) create mode 100644 test/frontend/__fixtures__/auth_providers.ts create mode 100644 test/frontend/__fixtures__/profile_custom_fields.ts create mode 100644 test/frontend/__lib__/auth.ts create mode 100644 test/frontend/components/user/user-profile-form.test.tsx diff --git a/app/frontend/src/javascript/components/socials/edit-socials.tsx b/app/frontend/src/javascript/components/socials/edit-socials.tsx index 58b426500..13beb3953 100644 --- a/app/frontend/src/javascript/components/socials/edit-socials.tsx +++ b/app/frontend/src/javascript/components/socials/edit-socials.tsx @@ -21,7 +21,7 @@ interface EditSocialsProps { */ export const EditSocials = ({ register, setValue, networks, formState, disabled }: EditSocialsProps) => { const { t } = useTranslation('shared'); - // regular expression to validate the the input fields + // regular expression to validate the input fields const urlRegex = /^(https?:\/\/)([^.]+)\.(.{2,30})(\/.*)*\/?$/; const initSelectedNetworks = networks.filter(el => !['', null, undefined].includes(el.url)); diff --git a/app/frontend/src/javascript/models/user.ts b/app/frontend/src/javascript/models/user.ts index 322907bac..e7d5ccb9a 100644 --- a/app/frontend/src/javascript/models/user.ts +++ b/app/frontend/src/javascript/models/user.ts @@ -40,7 +40,7 @@ export interface User { _destroy?: boolean } }, - invoicing_profile_attributes?: { + invoicing_profile_attributes: { id?: number, external_id?: string, address_attributes: { diff --git a/test/frontend/__fixtures__/auth_providers.ts b/test/frontend/__fixtures__/auth_providers.ts new file mode 100644 index 000000000..05696e047 --- /dev/null +++ b/test/frontend/__fixtures__/auth_providers.ts @@ -0,0 +1,15 @@ +const providers = [ + { + id: 1, + name: 'Fablab', + status: 'active', + providable_type: 'DatabaseProvider', + strategy_name: 'database-fablab', + auth_provider_mappings_attributes: [], + mapping: [], + link_to_sso_profile: '/#!/dashboard/profile', + link_to_sso_connect: '/#' + } +]; + +export default providers; diff --git a/test/frontend/__fixtures__/profile_custom_fields.ts b/test/frontend/__fixtures__/profile_custom_fields.ts new file mode 100644 index 000000000..a289bdec8 --- /dev/null +++ b/test/frontend/__fixtures__/profile_custom_fields.ts @@ -0,0 +1,16 @@ +const fields = [ + { + id: 1, + label: 'N° SIRET', + required: false, + actived: true + }, + { + id: 2, + label: 'Code NAF', + required: false, + actived: true + } +]; + +export default fields; diff --git a/test/frontend/__fixtures__/settings.ts b/test/frontend/__fixtures__/settings.ts index bfcdea52c..cfe97fa97 100644 --- a/test/frontend/__fixtures__/settings.ts +++ b/test/frontend/__fixtures__/settings.ts @@ -542,37 +542,37 @@ export const settings: Array = [ localized: 'Code journal des ventes' }, { - name: 'accounting_card_client_code', + name: 'accounting_payment_card_code', value: '5801', last_update: '2022-11-22T17:27:19+0100', localized: 'Code clients par carte' }, { - name: 'accounting_card_client_label', + name: 'accounting_payment_card_label', value: 'Clients par carte', last_update: '2022-11-22T17:27:19+0100', localized: 'Libellé clients par carte' }, { - name: 'accounting_wallet_client_code', + name: 'accounting_payment_wallet_code', value: '5802', last_update: '2022-11-22T17:27:19+0100', localized: 'Code clients par porte-monnaie' }, { - name: 'accounting_wallet_client_label', + name: 'accounting_payment_wallet_label', value: 'Client par porte-monnaie', last_update: '2022-11-22T17:27:19+0100', localized: 'Libellé clients par porte-monnaie' }, { - name: 'accounting_other_client_code', + name: 'accounting_payment_other_code', value: '5803', last_update: '2022-11-22T17:27:19+0100', localized: 'Code clients autre moyen' }, { - name: 'accounting_other_client_label', + name: 'accounting_payment_other_label', value: 'Clients autres moyens de paiement', last_update: '2022-11-22T17:27:19+0100', localized: 'Libellé clients autre moyen' @@ -692,19 +692,19 @@ export const settings: Array = [ localized: 'Libellé erreurs' }, { - name: 'accounting_card_client_journal_code', + name: 'accounting_payment_card_journal_code', value: 'CB01', last_update: '2022-11-22T17:27:20+0100', localized: 'Libellé erreurs' }, { - name: 'accounting_wallet_client_journal_code', + name: 'accounting_payment_wallet_journal_code', value: 'W001', last_update: '2022-11-22T17:27:20+0100', localized: 'Libellé erreurs' }, { - name: 'accounting_other_client_journal_code', + name: 'accounting_payment_other_journal_code', value: 'CA01', last_update: '2022-11-22T17:27:20+0100', localized: 'Libellé erreurs' @@ -720,5 +720,11 @@ export const settings: Array = [ value: 'TVA1', last_update: '2022-11-22T17:27:20+0100', localized: 'Libellé erreurs' + }, + { + name: 'external_id', + value: 'true', + last_update: '2022-12-20T16:02:01+0100', + localized: 'identifiant externe' } ]; diff --git a/test/frontend/__fixtures__/users.ts b/test/frontend/__fixtures__/users.ts index 60e3de60d..d02904756 100644 --- a/test/frontend/__fixtures__/users.ts +++ b/test/frontend/__fixtures__/users.ts @@ -1,29 +1,29 @@ import { User } from '../../../app/frontend/src/javascript/models/user'; export const admins: Array = [ - { id: 1, name: 'Jean Dupont', group_id: 1, role: 'admin', email: 'jean.dupont@example.com', profile_attributes: { id: 1, first_name: 'Jean', last_name: 'Dupont' } }, - { id: 2, name: 'Germain Durand', group_id: 2, role: 'admin', email: 'germain.durand@example.com', profile_attributes: { id: 2, first_name: 'Germain', last_name: 'Durand' } } + { id: 1, name: 'Jean Dupont', group_id: 1, role: 'admin', email: 'jean.dupont@example.com', profile_attributes: { id: 1, first_name: 'Jean', last_name: 'Dupont' }, invoicing_profile_attributes: { address_attributes: { address: '11 rue des poireaux, 12340 Trilouilly-les-oies' } } }, + { id: 2, name: 'Germain Durand', group_id: 2, role: 'admin', email: 'germain.durand@example.com', profile_attributes: { id: 2, first_name: 'Germain', last_name: 'Durand' }, invoicing_profile_attributes: { address_attributes: { address: '12 rue des navets, 23450 Trilouilly-les-canards' } } } ]; export const managers: Array = [ - { id: 3, name: 'Louison Bobet', group_id: 1, role: 'manager', email: 'louison.bobet@example.com', profile_attributes: { id: 1, first_name: 'Louison', last_name: 'Bobet' } }, - { id: 4, name: 'Marlene Dietrich', group_id: 2, role: 'manager', email: 'marlene.dietrich@example.com', profile_attributes: { id: 4, first_name: 'Marlene', last_name: 'Dietrich' } } + { id: 3, name: 'Louison Bobet', group_id: 1, role: 'manager', email: 'louison.bobet@example.com', profile_attributes: { id: 1, first_name: 'Louison', last_name: 'Bobet' }, invoicing_profile_attributes: { address_attributes: { address: '13 rue des carottes, 34560 Trilouilly-les-poules' } } }, + { id: 4, name: 'Marlene Dietrich', group_id: 2, role: 'manager', email: 'marlene.dietrich@example.com', profile_attributes: { id: 4, first_name: 'Marlene', last_name: 'Dietrich' }, invoicing_profile_attributes: { address_attributes: { address: '14 rue des patates, 45670 Trilouilly-les-pintades' } } } ]; export const partners: Array = [ - { id: 5, name: 'Arthur Rimbaud', group_id: 1, role: 'partner', email: 'arthur.rimbaud@example.com', profile_attributes: { id: 5, first_name: 'Arthur', last_name: 'Rimbaud' } }, - { id: 6, name: 'Stanislas Leszczynski', group_id: 1, role: 'partner', email: 'stanislas.leszczynski@example.com', profile_attributes: { id: 6, first_name: 'Stanislas', last_name: 'Leszczynski' } } + { id: 5, name: 'Arthur Rimbaud', group_id: 1, role: 'partner', email: 'arthur.rimbaud@example.com', profile_attributes: { id: 5, first_name: 'Arthur', last_name: 'Rimbaud' }, invoicing_profile_attributes: { address_attributes: { address: '15 rue des choux-raves, 56780 Trilouilly-les-cailles' } } }, + { id: 6, name: 'Stanislas Leszczynski', group_id: 1, role: 'partner', email: 'stanislas.leszczynski@example.com', profile_attributes: { id: 6, first_name: 'Stanislas', last_name: 'Leszczynski' }, invoicing_profile_attributes: { address_attributes: { address: '16 rue des blettes, 67890 Trilouilly-les-dindes' } } } ]; export const members: Array = [ - { id: 7, name: 'Victor Hugo', group_id: 1, role: 'member', email: 'victor.hugo@example.com', profile_attributes: { id: 7, first_name: 'Victor', last_name: 'Hugo' } }, - { id: 8, name: 'Paul Verlaine', group_id: 2, role: 'member', email: 'paul.verlaine@example.com', profile_attributes: { id: 8, first_name: 'Paul', last_name: 'Verlaine' } }, - { id: 9, name: 'Alfred de Vigny', group_id: 1, role: 'member', email: 'alfred.de.vigny@example.com', profile_attributes: { id: 9, first_name: 'Alfred', last_name: 'de Vigny' } }, - { id: 10, name: 'Madeleine De Scudéry', group_id: 2, role: 'member', email: 'madeleine.de.scudery@example.com', profile_attributes: { id: 10, first_name: 'Madeleine', last_name: 'de Scudéry' } }, - { id: 11, name: 'Marie-Olympe De Gouges', group_id: 1, role: 'member', email: 'marie-olympe.de.gouges@example.com', profile_attributes: { id: 11, first_name: 'Marie-Olympe', last_name: 'de Gouges' } }, - { id: 12, name: 'Charles Fourier', group_id: 2, role: 'member', email: 'charles.fourier@example.com', profile_attributes: { id: 12, first_name: 'Charles', last_name: 'Fourier' } }, - { id: 13, name: 'Louise Michel', group_id: 1, role: 'member', email: 'louise.michel@example.com', profile_attributes: { id: 13, first_name: 'Louise', last_name: 'Michel' } }, - { id: 14, name: 'Hélène Bouvier', group_id: 2, role: 'member', email: 'helene.bouvier@example.com', profile_attributes: { id: 14, first_name: 'Hélène', last_name: 'Bouvier' } } + { id: 7, name: 'Victor Hugo', group_id: 1, role: 'member', email: 'victor.hugo@example.com', profile_attributes: { id: 7, first_name: 'Victor', last_name: 'Hugo' }, invoicing_profile_attributes: { address_attributes: { address: '17 rue des radis, 78910 Trilouilly-les-pigeons' } } }, + { id: 8, name: 'Paul Verlaine', group_id: 2, role: 'member', email: 'paul.verlaine@example.com', profile_attributes: { id: 8, first_name: 'Paul', last_name: 'Verlaine' }, invoicing_profile_attributes: { address_attributes: { address: '18 rue des topinambours, 89120 Trilouilly-les-lapins' } } }, + { id: 9, name: 'Alfred de Vigny', group_id: 1, role: 'member', email: 'alfred.de.vigny@example.com', profile_attributes: { id: 9, first_name: 'Alfred', last_name: 'de Vigny' }, invoicing_profile_attributes: { address_attributes: { address: '19 rue des choux-fleurs, 91230 Trilouilly-les-dindons' } } }, + { id: 10, name: 'Madeleine De Scudéry', group_id: 2, role: 'member', email: 'madeleine.de.scudery@example.com', profile_attributes: { id: 10, first_name: 'Madeleine', last_name: 'de Scudéry' }, invoicing_profile_attributes: { address_attributes: { address: '20 rue des céleris, 12450 Trilouilly-les-faisans' } } }, + { id: 11, name: 'Marie-Olympe De Gouges', group_id: 1, role: 'member', email: 'marie-olympe.de.gouges@example.com', profile_attributes: { id: 11, first_name: 'Marie-Olympe', last_name: 'de Gouges' }, invoicing_profile_attributes: { address_attributes: { address: '21 rue des artichauts, 12560 Trilouilly-les-autruches' } } }, + { id: 12, name: 'Charles Fourier', group_id: 2, role: 'member', email: 'charles.fourier@example.com', profile_attributes: { id: 12, first_name: 'Charles', last_name: 'Fourier' }, invoicing_profile_attributes: { address_attributes: { address: '22 rue des brocolis, 12780 Trilouilly-les-émeus' } } }, + { id: 13, name: 'Louise Michel', group_id: 1, role: 'member', email: 'louise.michel@example.com', profile_attributes: { id: 13, first_name: 'Louise', last_name: 'Michel' }, invoicing_profile_attributes: { address_attributes: { address: '23 rue des courgettes, 12780 Trilouilly-les-nandous' } } }, + { id: 14, name: 'Hélène Bouvier', group_id: 2, role: 'member', email: 'helene.bouvier@example.com', profile_attributes: { id: 14, first_name: 'Hélène', last_name: 'Bouvier' }, invoicing_profile_attributes: { address_attributes: { address: '24 rue des cornichons, 12780 Trilouilly-les-grenouilles' } } } ]; export const users = members.concat(managers).concat(admins); diff --git a/test/frontend/__lib__/auth.ts b/test/frontend/__lib__/auth.ts new file mode 100644 index 000000000..5866cbd49 --- /dev/null +++ b/test/frontend/__lib__/auth.ts @@ -0,0 +1,7 @@ +import { User } from '../../../app/frontend/src/javascript/models/user'; + +declare var loggedUser; // eslint-disable-line no-var + +export const loginAs = (user: User) => { + loggedUser = user; // eslint-disable-line @typescript-eslint/no-unused-vars +}; diff --git a/test/frontend/__setup__/globals.js b/test/frontend/__setup__/globals.js index 9eb50d808..68446f13a 100644 --- a/test/frontend/__setup__/globals.js +++ b/test/frontend/__setup__/globals.js @@ -57,3 +57,5 @@ global.Fablab.d3DateFormat = '%d/%m/%y'; global.Fablab.uibDateFormat = 'dd/MM/yyyy'; global.Fablab.maxProofOfIdentityFileSize = 5242880; global.Fablab.sessionTours = []; + +global.loggedUser = null; diff --git a/test/frontend/__setup__/server.js b/test/frontend/__setup__/server.js index 05a50f475..e4e0f1572 100644 --- a/test/frontend/__setup__/server.js +++ b/test/frontend/__setup__/server.js @@ -9,6 +9,8 @@ import products from '../__fixtures__/products'; import productCategories from '../__fixtures__/product_categories'; import productStockMovements from '../__fixtures__/product_stock_movements'; import machines from '../__fixtures__/machines'; +import providers from '../__fixtures__/auth_providers'; +import profileCustomFields from '../__fixtures__/profile_custom_fields'; export const server = setupServer( rest.get('/api/groups', (req, res, ctx) => { @@ -48,9 +50,9 @@ export const server = setupServer( return res(ctx.json({ setting })); }), rest.get('/api/settings', (req, res, ctx) => { - const { names } = req.params; - const foundSettings = settings.filter(name => names.replace(/[[\]']/g, '').split(',').includes(name)); - return res(ctx.json(foundSettings)); + const names = new URLSearchParams(req.url.search).get('names'); + const foundSettings = settings.filter(setting => names.replace(/[[\]']/g, '').split(',').includes(setting.name)); + return res(ctx.json(Object.fromEntries(foundSettings.map(s => [s.name, s.value])))); }), rest.patch('/api/settings/bulk_update', (req, res, ctx) => { return res(ctx.json(req.body)); @@ -73,6 +75,15 @@ export const server = setupServer( }), rest.get('/api/machines', (req, res, ctx) => { return res(ctx.json(machines)); + }), + rest.get('/api/auth_providers/active', (req, res, ctx) => { + return res(ctx.json(providers[0])); + }), + rest.get('/api/profile_custom_fields', (req, res, ctx) => { + return res(ctx.json(profileCustomFields)); + }), + rest.get('/api/members/current', (req, res, ctx) => { + return res(ctx.json(global.loggedUser)); }) ); diff --git a/test/frontend/components/user/user-profile-form.test.tsx b/test/frontend/components/user/user-profile-form.test.tsx new file mode 100644 index 000000000..2ffbbb097 --- /dev/null +++ b/test/frontend/components/user/user-profile-form.test.tsx @@ -0,0 +1,64 @@ +import { UserProfileForm } from '../../../../app/frontend/src/javascript/components/user/user-profile-form'; +import { render, waitFor, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { members, admins } from '../../__fixtures__/users'; +import { loginAs } from '../../__lib__/auth'; + +describe('UserProfileForm', () => { + const onError = jest.fn(); + const onSuccess = jest.fn(); + + test('render UserProfileForm', async () => { + loginAs(admins[0]); + render(); + await waitFor(() => screen.getByLabelText(/app.shared.user_profile_form.external_id/)); + expect(screen.getByRole('button', { name: /app.shared.avatar_input.add_an_avatar/ })).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.gender_input.man/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.gender_input.woman/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.surname/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.first_name/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.date_of_birth/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.phone_number/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.address/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.pseudonym/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.external_id/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.email_address/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.password_input.new_password/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.password_input.confirm_password/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.declare_organization/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.website/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.job/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.interests/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.CAD_softwares_mastered/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.allow_public_profile/)).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.allow_newsletter/)).toBeInTheDocument(); + }); + + test('admin should see the private note', async () => { + loginAs(admins[0]); + render(); + await waitFor(() => screen.getByLabelText(/app.shared.user_profile_form.external_id/)); + expect(screen.getByRole('button', { name: /app.shared.avatar_input.add_an_avatar/ })).toBeInTheDocument(); + expect(screen.getByLabelText(/app.shared.user_profile_form.note/)).toBeInTheDocument(); + }); + + test('member should not see the private note', async () => { + loginAs(members[0]); + render(); + await waitFor(() => screen.getByLabelText(/app.shared.user_profile_form.external_id/)); + expect(screen.getByRole('button', { name: /app.shared.avatar_input.add_an_avatar/ })).toBeInTheDocument(); + expect(screen.queryByLabelText(/app.shared.user_profile_form.note/)).toBeNull(); + }); +});