Skip to content

Commit

Permalink
fix: replaced ConsentFieldVariants enum with union types
Browse files Browse the repository at this point in the history
  • Loading branch information
mirovladimitrovski committed Jun 16, 2023
1 parent 22fcdb8 commit 0b69fc3
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 81 deletions.
3 changes: 1 addition & 2 deletions src/components/Account/Account.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import customer from '#test/fixtures/customer.json';
import { useAccountStore } from '#src/stores/AccountStore';
import { renderWithRouter } from '#test/testUtils';
import type { Consent } from '#types/account';
import type { ConsentFieldVariants } from '#src/services/inplayer.account.service';

describe('<Account>', () => {
test('renders and matches snapshot', () => {
useAccountStore.setState({
user: customer,
publisherConsents: Array.of({ name: 'marketing', label: 'Receive Marketing Emails' } as Consent<ConsentFieldVariants>),
publisherConsents: Array.of({ name: 'marketing', label: 'Receive Marketing Emails' } as Consent),
});

const { container } = renderWithRouter(<Account panelClassName={'panel-class'} panelHeaderClassName={'header-class'} canUpdateEmail={true} />);
Expand Down
10 changes: 5 additions & 5 deletions src/components/Account/Account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import styles from './Account.module.scss';

import type { FormSectionContentArgs, FormSectionProps } from '#components/Form/FormSection';
import type { Consent } from '#types/account';
import { ConsentFieldVariants } from '#src/services/inplayer.account.service';
import { REGISTER_FIELD_VARIANT } from '#src/services/inplayer.account.service';
import Alert from '#components/Alert/Alert';
import Visibility from '#src/icons/Visibility';
import VisibilityOff from '#src/icons/VisibilityOff';
Expand Down Expand Up @@ -69,11 +69,11 @@ const Account = ({ panelClassName, panelHeaderClassName, canUpdateEmail = true }
);

const [termsConsents, nonTermsConsents] = useMemo(() => {
const terms: Consent<ConsentFieldVariants>[] = [];
const nonTerms: Consent<ConsentFieldVariants>[] = [];
const terms: Consent[] = [];
const nonTerms: Consent[] = [];

publisherConsents?.forEach((consent) => {
if (consent.type === ConsentFieldVariants.CHECKBOX) {
if (consent.type === REGISTER_FIELD_VARIANT.CHECKBOX) {
terms.push(consent);
} else {
nonTerms.push(consent);
Expand Down Expand Up @@ -295,7 +295,7 @@ const Account = ({ panelClassName, panelHeaderClassName, canUpdateEmail = true }
label={formatConsentLabel(consent.label)}
placeholder={consent.placeholder}
value={section.values.consentsValues[consent.name]}
disabled={(consent.type === ConsentFieldVariants.CHECKBOX && consent.required) || section.isBusy}
disabled={(consent.type === REGISTER_FIELD_VARIANT.CHECKBOX && consent.required) || section.isBusy}
onChange={(name, value) => section.onChangeValue(name, value)}
/>
))}
Expand Down
20 changes: 12 additions & 8 deletions src/components/CustomRegisterField/CustomRegisterField.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,53 @@ import { render } from '@testing-library/react';

import CustomRegisterField from './CustomRegisterField';

import { ConsentFieldVariants } from '#src/services/inplayer.account.service';
import { REGISTER_FIELD_VARIANT } from '#src/services/inplayer.account.service';

describe('<CustomRegisterField>', () => {
test('renders and matches snapshot <Checkbox>', () => {
const { container } = render(<CustomRegisterField type={ConsentFieldVariants.CHECKBOX} label="label" name="name" value="value" onChange={vi.fn()} />);
const { container } = render(<CustomRegisterField type={REGISTER_FIELD_VARIANT.CHECKBOX} label="label" name="name" value="value" onChange={vi.fn()} />);

expect(container).toMatchSnapshot();
});

test('renders and matches snapshot <TextField>', () => {
const { container } = render(<CustomRegisterField type={ConsentFieldVariants.INPUT} label="label" name="name" value="value" onChange={vi.fn()} />);
const { container } = render(<CustomRegisterField type={REGISTER_FIELD_VARIANT.INPUT} label="label" name="name" value="value" onChange={vi.fn()} />);

expect(container).toMatchSnapshot();
});

test('renders and matches snapshot <Radio>', () => {
const { container } = render(<CustomRegisterField type={ConsentFieldVariants.RADIO} label="label" name="name" value="value" onChange={vi.fn()} />);
const { container } = render(<CustomRegisterField type={REGISTER_FIELD_VARIANT.RADIO} label="label" name="name" value="value" onChange={vi.fn()} />);

expect(container).toMatchSnapshot();
});

test('renders and matches snapshot <Dropdown type="select">', () => {
const { container } = render(<CustomRegisterField type={ConsentFieldVariants.GENERAL_SELECT} label="label" name="name" value="value" onChange={vi.fn()} />);
const { container } = render(
<CustomRegisterField type={REGISTER_FIELD_VARIANT.GENERIC_SELECT} label="label" name="name" value="value" onChange={vi.fn()} />,
);

expect(container).toMatchSnapshot();
});

test('renders and matches snapshot <Dropdown type="country">', () => {
const { container } = render(<CustomRegisterField type={ConsentFieldVariants.COUNTRY_SELECT} label="label" name="name" value="value" onChange={vi.fn()} />);
const { container } = render(
<CustomRegisterField type={REGISTER_FIELD_VARIANT.COUNTRY_SELECT} label="label" name="name" value="value" onChange={vi.fn()} />,
);

expect(container).toMatchSnapshot();
});

test('renders and matches snapshot <Dropdown type="us_state">', () => {
const { container } = render(
<CustomRegisterField type={ConsentFieldVariants.US_STATE_SELECT} label="label" name="name" value="value" onChange={vi.fn()} />,
<CustomRegisterField type={REGISTER_FIELD_VARIANT.US_STATE_SELECT} label="label" name="name" value="value" onChange={vi.fn()} />,
);

expect(container).toMatchSnapshot();
});

test('renders and matches snapshot <Dropdown type="datepicker">', () => {
const { container } = render(<CustomRegisterField type={ConsentFieldVariants.DATE_PICKER} label="label" name="name" value="value" onChange={vi.fn()} />);
const { container } = render(<CustomRegisterField type={REGISTER_FIELD_VARIANT.DATE_PICKER} label="label" name="name" value="value" onChange={vi.fn()} />);

expect(container).toMatchSnapshot();
});
Expand Down
22 changes: 11 additions & 11 deletions src/components/CustomRegisterField/CustomRegisterField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import TextField from '#components/TextField/TextField';
import Radio from '#components/Radio/Radio';
import Dropdown from '#components/Dropdown/Dropdown';
import DateField from '#components/DateField/DateField';
import { ConsentFieldVariants } from '#src/services/inplayer.account.service';
import { ConsentFieldVariants, REGISTER_FIELD_VARIANT } from '#src/services/inplayer.account.service';
import { countries, usStates } from '#static/json';

type Props = {
Expand All @@ -30,9 +30,9 @@ export const CustomRegisterField: FC<Props> = ({ type, name, value = '', onChang
const optionsList = useMemo(() => {
const optionsObject = (() => {
switch (type) {
case ConsentFieldVariants.COUNTRY_SELECT:
case REGISTER_FIELD_VARIANT.COUNTRY_SELECT:
return countries;
case ConsentFieldVariants.US_STATE_SELECT:
case REGISTER_FIELD_VARIANT.US_STATE_SELECT:
return usStates;
default:
return props.options;
Expand All @@ -48,7 +48,7 @@ export const CustomRegisterField: FC<Props> = ({ type, name, value = '', onChang

const changeHandler: ChangeEventHandler<HTMLInputElement> = useCallback(
({ currentTarget }) => {
const value = type === ConsentFieldVariants.CHECKBOX ? (currentTarget as HTMLInputElement).checked : currentTarget.value;
const value = type === REGISTER_FIELD_VARIANT.CHECKBOX ? (currentTarget as HTMLInputElement).checked : currentTarget.value;
onChange(name, value);
},
[type, name, onChange],
Expand All @@ -57,17 +57,17 @@ export const CustomRegisterField: FC<Props> = ({ type, name, value = '', onChang
const commonProps = { ...props, name, onChange: changeHandler };

switch (type) {
case ConsentFieldVariants.CHECKBOX:
case REGISTER_FIELD_VARIANT.CHECKBOX:
return <Checkbox {...commonProps} checked={value === true} />;
case ConsentFieldVariants.INPUT:
case REGISTER_FIELD_VARIANT.INPUT:
return <TextField {...commonProps} value={value as string} />;
case ConsentFieldVariants.RADIO:
case REGISTER_FIELD_VARIANT.RADIO:
return <Radio {...commonProps} values={optionsList} value={value as string} header={props.label} />;
case ConsentFieldVariants.GENERAL_SELECT:
case ConsentFieldVariants.COUNTRY_SELECT:
case ConsentFieldVariants.US_STATE_SELECT:
case REGISTER_FIELD_VARIANT.GENERIC_SELECT:
case REGISTER_FIELD_VARIANT.COUNTRY_SELECT:
case REGISTER_FIELD_VARIANT.US_STATE_SELECT:
return <Dropdown {...commonProps} options={optionsList} value={value as string} defaultLabel={props.placeholder} fullWidth />;
case ConsentFieldVariants.DATE_PICKER:
case REGISTER_FIELD_VARIANT.DATE_PICKER:
return <DateField {...commonProps} value={value as string} onChange={(dateString: string) => onChange(name, dateString)} />;
}

Expand Down
19 changes: 14 additions & 5 deletions src/services/cleeng.account.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import jwtDecode from 'jwt-decode';

import { post, put, patch, get } from './cleeng.service';
import { ConsentFieldVariants } from './inplayer.account.service';
import { REGISTER_FIELD_VARIANT } from './inplayer.account.service';

import type { Config } from '#types/Config';
import { getOverrideIP } from '#src/utils/common';
Expand Down Expand Up @@ -30,7 +30,6 @@ import type {
UpdateCustomerPayload,
ChangePasswordWithOldPassword,
UpdatePersonalShelves,
CleengConsent,
Consent,
} from '#types/account';
import cleengAuthService from '#src/services/cleeng.auth.service';
Expand Down Expand Up @@ -134,15 +133,25 @@ export async function getUser({ config }: { config: Config }) {
};
}

export const getPublisherConsents: GetPublisherConsents<ConsentFieldVariants, boolean> = async (config) => {
interface CleengConsent {
broadcasterId: number;
enabledByDefault: boolean;
label: string;
name: string;
required: boolean;
value: string;
version: string;
}

export const getPublisherConsents: GetPublisherConsents = async (config) => {
const { cleeng } = config.integrations;
const response = await get(!!cleeng?.useSandbox, `/publishers/${cleeng?.id}/consents`);

handleErrors(response.errors);

const consents = ((response?.responseData?.consents || []) as CleengConsent[]).map(
(cleengConsent): Consent<ConsentFieldVariants> => ({
type: ConsentFieldVariants.CHECKBOX,
(cleengConsent): Consent => ({
type: REGISTER_FIELD_VARIANT.CHECKBOX,
provider: 'cleeng',
defaultValue: cleengConsent.enabledByDefault,
name: cleengConsent.name,
Expand Down
30 changes: 16 additions & 14 deletions src/services/inplayer.account.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,17 @@ enum InPlayerEnv {
Daily = 'daily',
}

export enum ConsentFieldVariants {
INPUT = 'input',
GENERAL_SELECT = 'select',
COUNTRY_SELECT = 'country',
US_STATE_SELECT = 'us_state',
RADIO = 'radio',
CHECKBOX = 'checkbox',
DATE_PICKER = 'datepicker',
}
export const REGISTER_FIELD_VARIANT = {
INPUT: 'input',
GENERIC_SELECT: 'select',
COUNTRY_SELECT: 'country',
US_STATE_SELECT: 'us_state',
RADIO: 'radio',
CHECKBOX: 'checkbox',
DATE_PICKER: 'datepicker',
} as const;

export type ConsentFieldVariants = (typeof REGISTER_FIELD_VARIANT)[keyof typeof REGISTER_FIELD_VARIANT];

export const initialize = async (config: Config, _logoutFn: () => Promise<void>) => {
const env: string = config.integrations?.jwp?.useSandbox ? InPlayerEnv.Development : InPlayerEnv.Production;
Expand Down Expand Up @@ -163,18 +165,18 @@ export const updateCustomer: UpdateCustomer = async (customer) => {
}
};

export const getPublisherConsents: GetPublisherConsents<ConsentFieldVariants, string | boolean> = async (config) => {
export const getPublisherConsents: GetPublisherConsents = async (config) => {
try {
const { jwp } = config.integrations;
const { data } = await InPlayer.Account.getRegisterFields(jwp?.clientId || '');

const result = data?.collection
.filter((field) => field.name !== 'email_confirmation')
.map(
(field): Consent<ConsentFieldVariants> => ({
(field): Consent => ({
type: field.type as ConsentFieldVariants,
provider: 'jwp',
defaultValue: field.type === ConsentFieldVariants.CHECKBOX ? field.default_value === 'true' : field.default_value,
defaultValue: field.type === REGISTER_FIELD_VARIANT.CHECKBOX ? field.default_value === 'true' : field.default_value,
name: field.name,
label: field.label,
placeholder: field.placeholder,
Expand Down Expand Up @@ -467,11 +469,11 @@ function formatAuth(auth: InPlayerAuthData): AuthData {
};
}

function getTermsConsent(): Consent<ConsentFieldVariants> {
function getTermsConsent(): Consent {
const termsUrl = '<a href="https://inplayer.com/legal/terms" target="_blank">Terms and Conditions</a>';

return {
type: ConsentFieldVariants.CHECKBOX,
type: REGISTER_FIELD_VARIANT.CHECKBOX,
provider: 'jwp',
required: true,
name: 'terms',
Expand Down
7 changes: 3 additions & 4 deletions src/stores/AccountStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import type { PaymentDetail, Subscription, Transaction } from '#types/subscripti
import type { Consent, Customer, CustomerConsent } from '#types/account';
import { createStore } from '#src/stores/utils';
import type { Offer } from '#types/checkout';
import type { ConsentFieldVariants } from '#src/services/inplayer.account.service';

type AccountStore<T = string> = {
type AccountStore = {
loading: boolean;
user: Customer | null;
subscription: Subscription | null;
transactions: Transaction[] | null;
activePayment: PaymentDetail | null;
customerConsents: CustomerConsent[] | null;
publisherConsents: Consent<T>[] | null;
publisherConsents: Consent[] | null;
pendingOffer: Offer | null;
canUpdateEmail: boolean;
canRenewSubscription: boolean;
Expand All @@ -23,7 +22,7 @@ type AccountStore<T = string> = {
setLoading: (loading: boolean) => void;
};

export const useAccountStore = createStore<AccountStore<ConsentFieldVariants>>('AccountStore', (set) => ({
export const useAccountStore = createStore<AccountStore>('AccountStore', (set) => ({
loading: true,
user: null,
subscription: null,
Expand Down
6 changes: 3 additions & 3 deletions src/utils/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const generatePlaylistPlaceholder = (playlistLength: number = 15): Playlist => (
),
});

const formatConsentValues = <T = string>(publisherConsents: Consent<T>[] | null = [], customerConsents: CustomerConsent[] | null = []) => {
const formatConsentValues = (publisherConsents: Consent[] | null = [], customerConsents: CustomerConsent[] | null = []) => {
if (!publisherConsents || !customerConsents) {
return {};
}
Expand All @@ -84,7 +84,7 @@ const formatConsentValues = <T = string>(publisherConsents: Consent<T>[] | null
return values;
};

const formatConsents = <T = string>(publisherConsents: Consent<T>[] | null = [], customerConsents: CustomerConsent[] | null = []) => {
const formatConsents = (publisherConsents: Consent[] | null = [], customerConsents: CustomerConsent[] | null = []) => {
if (!publisherConsents || !customerConsents) {
return {};
}
Expand Down Expand Up @@ -112,7 +112,7 @@ const extractConsentValues = (consents?: Consent[]) => {
return values;
};

const formatConsentsFromValues = <T = string>(publisherConsents: Consent<T>[] | null, values?: GenericFormValues) => {
const formatConsentsFromValues = (publisherConsents: Consent[] | null, values?: GenericFormValues) => {
const consents: CustomerConsent[] = [];

if (!publisherConsents || !values) return consents;
Expand Down
36 changes: 7 additions & 29 deletions types/account.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import type { SerializedFavorite } from './favorite';

import type { Config } from '#types/Config';

export type StringedBoolean = 'true' | 'false';

export type AuthData = {
jwt: string;
refreshToken: string;
Expand Down Expand Up @@ -130,8 +128,8 @@ export type GetPublisherConsentsPayload = {
publisherId: string;
};

export type GetPublisherConsentsResponse<T = string, D = string> = {
consents: Consent<T, D>[];
export type GetPublisherConsentsResponse = {
consents: Consent[];
};

export type GetCustomerConsentsPayload = {
Expand Down Expand Up @@ -220,32 +218,12 @@ export type UpdateCustomerArgs = {
fullName?: string;
};

export interface CleengConsent {
broadcasterId: number;
enabledByDefault: boolean;
label: string;
name: string;
required: boolean;
value: string;
version: string;
}

export interface JwConsent<T = string> {
default_value: string | StringedBoolean;
id: number;
label: string;
name: string;
placeholder: string;
required: boolean;
type: T;
options: Record<string, string>;
}

export type ConsentProvider = 'cleeng' | 'jwp';

// the type in which both CleengConsent and JwConsent will be converted for consistency
export interface Consent<T = string> {
type: T;
export type ConsentFieldVariants = 'input' | 'select' | 'country' | 'us_state' | 'radio' | 'checkbox' | 'datepicker';

export interface Consent {
type: ConsentFieldVariantss;
provider: ConsentProvider;
defaultValue: string | boolean;
name: string;
Expand Down Expand Up @@ -362,7 +340,7 @@ type Login = PromiseRequest<AuthArgs, AuthResponse>;
type Register = PromiseRequest<AuthArgs, AuthResponse>;
type GetCustomer = EnvironmentServiceRequest<GetCustomerPayload, Customer>;
type UpdateCustomer = EnvironmentServiceRequest<UpdateCustomerArgs, Customer>;
type GetPublisherConsents<T = string, D = string> = PromiseRequest<Config, GetPublisherConsentsResponse<T, D>>;
type GetPublisherConsents = PromiseRequest<Config, GetPublisherConsentsResponse>;
type GetCustomerConsents = PromiseRequest<CustomerConsentArgs, GetCustomerConsentsResponse>;
type UpdateCustomerConsents = PromiseRequest<UpdateCustomerConsentsArgs, GetCustomerConsentsResponse>;
type GetCaptureStatus = EnvironmentServiceRequest<GetCaptureStatusArgs, GetCaptureStatusResponse>;
Expand Down

0 comments on commit 0b69fc3

Please sign in to comment.