richie-education 2.25.0-b2.dev127 → 2.25.0-b2.dev128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.spec.tsx +1 -1
- package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.tsx +2 -4
- package/js/utils/OrderHelper/index.ts +54 -0
- package/js/utils/test/factories/joanie.ts +1 -1
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +2 -2
- package/js/widgets/Dashboard/components/DashboardItem/Order/{OrderStateMessage → OrderStateLearnerMessage}/index.spec.tsx +10 -19
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.tsx +60 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateMessage/index.tsx +27 -77
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.spec.tsx +127 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.tsx +60 -0
- package/package.json +1 -1
|
@@ -55,7 +55,7 @@ describe('pages/CourseLearnerDataGrid', () => {
|
|
|
55
55
|
expect(cells[2]).toHaveTextContent(
|
|
56
56
|
intl.formatDate(new Date(courseOrder.created_on), DEFAULT_DATE_FORMAT),
|
|
57
57
|
);
|
|
58
|
-
expect(cells[3]).toHaveTextContent('
|
|
58
|
+
expect(cells[3]).toHaveTextContent('Certified');
|
|
59
59
|
expect(within(cells[4]).getByText('Contact')).toBeInTheDocument();
|
|
60
60
|
});
|
|
61
61
|
});
|
package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { Button, DataGrid, DataGridProps, PaginationProps, Row } from '@openfun/
|
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import { NestedCourseOrder } from 'types/Joanie';
|
|
5
5
|
import { DEFAULT_DATE_FORMAT } from 'hooks/useDateFormat';
|
|
6
|
-
import
|
|
6
|
+
import OrderStateTeacherMessage from 'widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage';
|
|
7
7
|
import DashboardListAvatar from 'widgets/Dashboard/components/DashboardListAvatar';
|
|
8
8
|
|
|
9
9
|
const messages = defineMessages({
|
|
@@ -74,10 +74,8 @@ const CourseLearnerDataGrid = ({
|
|
|
74
74
|
headerName: intl.formatMessage(messages.columnState),
|
|
75
75
|
enableSorting: false,
|
|
76
76
|
renderCell: (params: { row: Row }) => {
|
|
77
|
-
// TODO(rlecellier): create NestedOrderCourseStateMessage that's get label dedicated to teatchers.
|
|
78
|
-
// like signature needed for studdent is awaiting signature for a teacher.
|
|
79
77
|
return (
|
|
80
|
-
<
|
|
78
|
+
<OrderStateTeacherMessage
|
|
81
79
|
order={params.row.courseOrder}
|
|
82
80
|
contractDefinition={params.row.courseOrder.product.contract_definition_id}
|
|
83
81
|
/>
|
|
@@ -7,10 +7,52 @@ import {
|
|
|
7
7
|
NestedCourseOrder,
|
|
8
8
|
} from 'types/Joanie';
|
|
9
9
|
|
|
10
|
+
export enum OrderStatus {
|
|
11
|
+
DRAFT = 'draft',
|
|
12
|
+
SUBMITTED = 'submitted',
|
|
13
|
+
PENDING = 'pending',
|
|
14
|
+
CANCELED = 'canceled',
|
|
15
|
+
WAITING_SIGNATURE = 'waiting_signature',
|
|
16
|
+
WAITING_COUNTER_SIGNATURE = 'waiting_counter_signature',
|
|
17
|
+
COMPLETED = 'completed',
|
|
18
|
+
ON_GOING = 'on_going',
|
|
19
|
+
}
|
|
20
|
+
|
|
10
21
|
/**
|
|
11
22
|
* Helper class for orders
|
|
12
23
|
*/
|
|
13
24
|
export class OrderHelper {
|
|
25
|
+
static getState(order: Order | NestedCourseOrder, contractDefinition?: ContractDefinition) {
|
|
26
|
+
const { certificate_id: certificateId } = order;
|
|
27
|
+
|
|
28
|
+
if (order.state === OrderState.VALIDATED) {
|
|
29
|
+
if (OrderHelper.orderNeedsSignature(order, contractDefinition)) {
|
|
30
|
+
return OrderStatus.WAITING_SIGNATURE;
|
|
31
|
+
}
|
|
32
|
+
if (OrderHelper.orderNeedsCounterSignature(order)) {
|
|
33
|
+
return OrderStatus.WAITING_COUNTER_SIGNATURE;
|
|
34
|
+
}
|
|
35
|
+
if (certificateId) {
|
|
36
|
+
return OrderStatus.COMPLETED;
|
|
37
|
+
} else {
|
|
38
|
+
return OrderStatus.ON_GOING;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const orderStatusMap = {
|
|
43
|
+
[OrderState.DRAFT]: OrderStatus.DRAFT,
|
|
44
|
+
[OrderState.SUBMITTED]: OrderStatus.SUBMITTED,
|
|
45
|
+
[OrderState.PENDING]: OrderStatus.PENDING,
|
|
46
|
+
[OrderState.CANCELED]: OrderStatus.CANCELED,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
if (order.state in orderStatusMap) {
|
|
50
|
+
return orderStatusMap[order.state];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
14
56
|
/**
|
|
15
57
|
* return an Order from the given list that match given productId
|
|
16
58
|
*/
|
|
@@ -33,4 +75,16 @@ export class OrderHelper {
|
|
|
33
75
|
!(order.contract && order.contract.student_signed_on)
|
|
34
76
|
);
|
|
35
77
|
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* tell us if a order need to be sign by the organization.
|
|
81
|
+
*/
|
|
82
|
+
static orderNeedsCounterSignature(order: Order | NestedCourseOrder) {
|
|
83
|
+
return (
|
|
84
|
+
order?.state === OrderState.VALIDATED &&
|
|
85
|
+
order.contract &&
|
|
86
|
+
order.contract.student_signed_on &&
|
|
87
|
+
!order.contract.organization_signed_on
|
|
88
|
+
);
|
|
89
|
+
}
|
|
36
90
|
}
|
|
@@ -146,7 +146,7 @@ export const ContractFactory = factory((): Contract => {
|
|
|
146
146
|
export const ContractLightFactory = factory((): ContractLight => {
|
|
147
147
|
return {
|
|
148
148
|
id: faker.string.uuid(),
|
|
149
|
-
student_signed_on:
|
|
149
|
+
student_signed_on: null,
|
|
150
150
|
organization_signed_on: null,
|
|
151
151
|
};
|
|
152
152
|
});
|
|
@@ -20,7 +20,7 @@ import { DashboardSubItemsList } from '../DashboardSubItemsList';
|
|
|
20
20
|
import { DashboardItemCourseEnrolling } from '../CourseEnrolling';
|
|
21
21
|
import { DashboardItem } from '../index';
|
|
22
22
|
import { DashboardItemContract } from '../Contract';
|
|
23
|
-
import
|
|
23
|
+
import OrderStateLearnerMessage from './OrderStateLearnerMessage';
|
|
24
24
|
|
|
25
25
|
const messages = defineMessages({
|
|
26
26
|
accessCourse: {
|
|
@@ -159,7 +159,7 @@ export const DashboardItemOrder = ({
|
|
|
159
159
|
<div className="dashboard-item-order__footer">
|
|
160
160
|
<div className="dashboard-item__block__status">
|
|
161
161
|
<Icon name={IconTypeEnum.SCHOOL} />
|
|
162
|
-
<
|
|
162
|
+
<OrderStateLearnerMessage
|
|
163
163
|
order={order}
|
|
164
164
|
contractDefinition={product?.contract_definition}
|
|
165
165
|
/>
|
|
@@ -7,22 +7,10 @@ import {
|
|
|
7
7
|
CredentialOrderFactory,
|
|
8
8
|
} from 'utils/test/factories/joanie';
|
|
9
9
|
import { OrderState } from 'types/Joanie';
|
|
10
|
-
import
|
|
10
|
+
import OrderStateLearnerMessage, { messages } from '.';
|
|
11
11
|
|
|
12
12
|
const intl = createIntl({ locale: 'en' });
|
|
13
13
|
|
|
14
|
-
/*
|
|
15
|
-
@TODO (rlecellier): Rewrite everything with these guidlignes
|
|
16
|
-
Order lifecycle:
|
|
17
|
-
* Draft: order has been created
|
|
18
|
-
* Submitted: order information have been validated
|
|
19
|
-
* Pending: payment has failed but can be retried
|
|
20
|
-
* Validated:
|
|
21
|
-
* Completed (Validated with generated certificate)
|
|
22
|
-
* On going (Validated without generated certificate)
|
|
23
|
-
* Signature needed: !order.product.contract.isSign
|
|
24
|
-
* Canceled: has been canceled
|
|
25
|
-
*/
|
|
26
14
|
describe('<DashboardItemOrder/>', () => {
|
|
27
15
|
const Wrapper = ({ children }: PropsWithChildren) => (
|
|
28
16
|
<IntlProvider locale="en">{children}</IntlProvider>
|
|
@@ -39,7 +27,7 @@ describe('<DashboardItemOrder/>', () => {
|
|
|
39
27
|
const order = CredentialOrderFactory({ state }).one();
|
|
40
28
|
render(
|
|
41
29
|
<Wrapper>
|
|
42
|
-
<
|
|
30
|
+
<OrderStateLearnerMessage order={order} />
|
|
43
31
|
</Wrapper>,
|
|
44
32
|
);
|
|
45
33
|
expect(screen.getByText(expectedMessage)).toBeInTheDocument();
|
|
@@ -60,7 +48,7 @@ describe('<DashboardItemOrder/>', () => {
|
|
|
60
48
|
}).one();
|
|
61
49
|
render(
|
|
62
50
|
<Wrapper>
|
|
63
|
-
<
|
|
51
|
+
<OrderStateLearnerMessage order={orderWithContract} />
|
|
64
52
|
</Wrapper>,
|
|
65
53
|
);
|
|
66
54
|
expect(screen.getByText(expectedMessage)).toBeInTheDocument();
|
|
@@ -77,7 +65,7 @@ describe('<DashboardItemOrder/>', () => {
|
|
|
77
65
|
|
|
78
66
|
render(
|
|
79
67
|
<Wrapper>
|
|
80
|
-
<
|
|
68
|
+
<OrderStateLearnerMessage order={order} contractDefinition={contractDefinition} />
|
|
81
69
|
</Wrapper>,
|
|
82
70
|
);
|
|
83
71
|
expect(screen.getByText('Signature required')).toBeInTheDocument();
|
|
@@ -91,7 +79,7 @@ describe('<DashboardItemOrder/>', () => {
|
|
|
91
79
|
}).one();
|
|
92
80
|
render(
|
|
93
81
|
<Wrapper>
|
|
94
|
-
<
|
|
82
|
+
<OrderStateLearnerMessage order={order} />
|
|
95
83
|
</Wrapper>,
|
|
96
84
|
);
|
|
97
85
|
expect(
|
|
@@ -104,12 +92,15 @@ describe('<DashboardItemOrder/>', () => {
|
|
|
104
92
|
it('should display message for validated order that have a generated certificate', () => {
|
|
105
93
|
const order = CredentialOrderFactory({
|
|
106
94
|
state: OrderState.VALIDATED,
|
|
107
|
-
contract: ContractFactory({
|
|
95
|
+
contract: ContractFactory({
|
|
96
|
+
student_signed_on: new Date().toISOString(),
|
|
97
|
+
organization_signed_on: new Date().toISOString(),
|
|
98
|
+
}).one(),
|
|
108
99
|
certificate_id: 'FAKE_CERTIFICATE_ID',
|
|
109
100
|
}).one();
|
|
110
101
|
render(
|
|
111
102
|
<Wrapper>
|
|
112
|
-
<
|
|
103
|
+
<OrderStateLearnerMessage order={order} />
|
|
113
104
|
</Wrapper>,
|
|
114
105
|
);
|
|
115
106
|
expect(
|
package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.tsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
import OrderStateMessage, { OrderStateMessageBaseProps } from '../OrderStateMessage';
|
|
3
|
+
|
|
4
|
+
export const messages = defineMessages({
|
|
5
|
+
statusDraft: {
|
|
6
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusDraft',
|
|
7
|
+
description: 'Status shown on the dashboard order item when order is draft.',
|
|
8
|
+
defaultMessage: 'Draft',
|
|
9
|
+
},
|
|
10
|
+
statusSubmitted: {
|
|
11
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusSubmitted',
|
|
12
|
+
description: 'Status shown on the dashboard order item when order is submitted.',
|
|
13
|
+
defaultMessage: 'Submitted',
|
|
14
|
+
},
|
|
15
|
+
statusPending: {
|
|
16
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusPending',
|
|
17
|
+
description: 'Status shown on the dashboard order item when order is pending.',
|
|
18
|
+
defaultMessage: 'Pending',
|
|
19
|
+
},
|
|
20
|
+
statusOnGoing: {
|
|
21
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusOnGoing',
|
|
22
|
+
description:
|
|
23
|
+
'Status shown on the dashboard order item when order is validated with no certificate',
|
|
24
|
+
defaultMessage: 'On going',
|
|
25
|
+
},
|
|
26
|
+
statusCompleted: {
|
|
27
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusCompleted',
|
|
28
|
+
description:
|
|
29
|
+
'Status shown on the dashboard order item when order is validated with certificate',
|
|
30
|
+
defaultMessage: 'Completed',
|
|
31
|
+
},
|
|
32
|
+
statusWaitingSignature: {
|
|
33
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusWaitingSignature',
|
|
34
|
+
description:
|
|
35
|
+
"Status shown on the dashboard order item when order is validated with contract's learner signature missing.",
|
|
36
|
+
defaultMessage: 'Signature required',
|
|
37
|
+
},
|
|
38
|
+
statusWaitingCounterSignature: {
|
|
39
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusWaitingCounterSignature',
|
|
40
|
+
description:
|
|
41
|
+
"Status shown on the dashboard order item when order is validated with contract's organization signature missing.",
|
|
42
|
+
defaultMessage: 'On going',
|
|
43
|
+
},
|
|
44
|
+
statusCanceled: {
|
|
45
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusCanceled',
|
|
46
|
+
description: 'Status shown on the dashboard order item when order is canceled',
|
|
47
|
+
defaultMessage: 'Canceled',
|
|
48
|
+
},
|
|
49
|
+
statusOther: {
|
|
50
|
+
id: 'components.DashboardItem.Order.OrderStateMessage.statusOther',
|
|
51
|
+
description: 'Status shown on the dashboard order item when order status is unknown',
|
|
52
|
+
defaultMessage: '{state}',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const OrderStateLearnerMessage = (props: OrderStateMessageBaseProps) => {
|
|
57
|
+
return <OrderStateMessage {...props} messages={messages} />;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default OrderStateLearnerMessage;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FormattedMessage,
|
|
1
|
+
import { FormattedMessage, MessageDescriptor } from 'react-intl';
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
3
|
import {
|
|
4
4
|
CertificateOrder,
|
|
@@ -9,96 +9,46 @@ import {
|
|
|
9
9
|
} from 'types/Joanie';
|
|
10
10
|
import { StringHelper } from 'utils/StringHelper';
|
|
11
11
|
import { handle } from 'utils/errors/handle';
|
|
12
|
-
import { OrderHelper } from 'utils/OrderHelper';
|
|
12
|
+
import { OrderHelper, OrderStatus } from 'utils/OrderHelper';
|
|
13
13
|
|
|
14
|
-
export
|
|
15
|
-
statusDraft: {
|
|
16
|
-
id: 'components.DashboardItem.Order.OrderStateMessage.statusDraft',
|
|
17
|
-
description: 'Status shown on the dashboard order item when order is draft.',
|
|
18
|
-
defaultMessage: 'Draft',
|
|
19
|
-
},
|
|
20
|
-
statusSubmitted: {
|
|
21
|
-
id: 'components.DashboardItem.Order.OrderStateMessage.statusSubmitted',
|
|
22
|
-
description: 'Status shown on the dashboard order item when order is submitted.',
|
|
23
|
-
defaultMessage: 'Submitted',
|
|
24
|
-
},
|
|
25
|
-
statusPending: {
|
|
26
|
-
id: 'components.DashboardItem.Order.OrderStateMessage.statusPending',
|
|
27
|
-
description: 'Status shown on the dashboard order item when order is pending.',
|
|
28
|
-
defaultMessage: 'Pending',
|
|
29
|
-
},
|
|
30
|
-
statusOnGoing: {
|
|
31
|
-
id: 'components.DashboardItem.Order.OrderStateMessage.statusOnGoing',
|
|
32
|
-
description:
|
|
33
|
-
'Status shown on the dashboard order item when order is validated with no certificate',
|
|
34
|
-
defaultMessage: 'On going',
|
|
35
|
-
},
|
|
36
|
-
statusCompleted: {
|
|
37
|
-
id: 'components.DashboardItem.Order.OrderStateMessage.statusCompleted',
|
|
38
|
-
description:
|
|
39
|
-
'Status shown on the dashboard order item when order is validated with certificate',
|
|
40
|
-
defaultMessage: 'Completed',
|
|
41
|
-
},
|
|
42
|
-
statusWaitingSignature: {
|
|
43
|
-
id: 'components.DashboardItem.Order.OrderStateMessage.statusWaitingSignature',
|
|
44
|
-
description:
|
|
45
|
-
"Status shown on the dashboard order item when order is validated with contract's learner signature missing.",
|
|
46
|
-
defaultMessage: 'Signature required',
|
|
47
|
-
},
|
|
48
|
-
statusCanceled: {
|
|
49
|
-
id: 'components.DashboardItem.Order.OrderStateMessage.statusCanceled',
|
|
50
|
-
description: 'Status shown on the dashboard order item when order is canceled',
|
|
51
|
-
defaultMessage: 'Canceled',
|
|
52
|
-
},
|
|
53
|
-
statusOther: {
|
|
54
|
-
id: 'components.DashboardItem.Order.OrderStateMessage.statusOther',
|
|
55
|
-
description: 'Status shown on the dashboard order item when order status is unknown',
|
|
56
|
-
defaultMessage: '{state}',
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
interface OrderStateMessageProps {
|
|
14
|
+
export interface OrderStateMessageBaseProps {
|
|
61
15
|
order: CredentialOrder | CertificateOrder | NestedCourseOrder;
|
|
62
16
|
contractDefinition?: ContractDefinition;
|
|
63
17
|
}
|
|
64
18
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
[OrderState.DRAFT]: messages.statusDraft,
|
|
69
|
-
[OrderState.SUBMITTED]: messages.statusSubmitted,
|
|
70
|
-
[OrderState.PENDING]: messages.statusPending,
|
|
71
|
-
[OrderState.CANCELED]: messages.statusCanceled,
|
|
72
|
-
};
|
|
19
|
+
interface OrderStateMessageProps extends OrderStateMessageBaseProps {
|
|
20
|
+
messages: Record<string, MessageDescriptor>;
|
|
21
|
+
}
|
|
73
22
|
|
|
23
|
+
const OrderStateMessage = ({ order, contractDefinition, messages }: OrderStateMessageProps) => {
|
|
74
24
|
useEffect(() => {
|
|
75
25
|
if (!Object.values(OrderState).includes(order.state)) {
|
|
76
26
|
handle(new Error(`Unknown order state ${order.state}`));
|
|
77
27
|
}
|
|
78
28
|
}, [order.state]);
|
|
79
29
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
return
|
|
30
|
+
const orderStatusMessagesMap = {
|
|
31
|
+
[OrderStatus.DRAFT]: messages.statusDraft,
|
|
32
|
+
[OrderStatus.SUBMITTED]: messages.statusSubmitted,
|
|
33
|
+
[OrderStatus.PENDING]: messages.statusPending,
|
|
34
|
+
[OrderStatus.CANCELED]: messages.statusCanceled,
|
|
35
|
+
[OrderStatus.WAITING_SIGNATURE]: messages.statusWaitingSignature,
|
|
36
|
+
[OrderStatus.WAITING_COUNTER_SIGNATURE]: messages.statusWaitingCounterSignature,
|
|
37
|
+
[OrderStatus.COMPLETED]: messages.statusCompleted,
|
|
38
|
+
[OrderStatus.ON_GOING]: messages.statusOnGoing,
|
|
39
|
+
};
|
|
40
|
+
const status = OrderHelper.getState(order, contractDefinition);
|
|
41
|
+
|
|
42
|
+
if (status === null) {
|
|
43
|
+
return (
|
|
44
|
+
<FormattedMessage
|
|
45
|
+
{...messages.statusOther}
|
|
46
|
+
values={{ state: StringHelper.capitalizeFirst(order.state) }}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
94
49
|
}
|
|
95
50
|
|
|
96
|
-
return
|
|
97
|
-
<FormattedMessage
|
|
98
|
-
{...messages.statusOther}
|
|
99
|
-
values={{ state: StringHelper.capitalizeFirst(order.state) }}
|
|
100
|
-
/>
|
|
101
|
-
);
|
|
51
|
+
return <FormattedMessage {...orderStatusMessagesMap[status]} />;
|
|
102
52
|
};
|
|
103
53
|
|
|
104
54
|
export default OrderStateMessage;
|
package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.spec.tsx
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { IntlProvider, createIntl } from 'react-intl';
|
|
4
|
+
import {
|
|
5
|
+
ContractDefinitionFactory,
|
|
6
|
+
ContractFactory,
|
|
7
|
+
CredentialOrderFactory,
|
|
8
|
+
} from 'utils/test/factories/joanie';
|
|
9
|
+
import { OrderState } from 'types/Joanie';
|
|
10
|
+
import OrderStateTeacherMessage, { messages } from '.';
|
|
11
|
+
|
|
12
|
+
const intl = createIntl({ locale: 'en' });
|
|
13
|
+
|
|
14
|
+
describe('<OrderStateTeacherMessage/>', () => {
|
|
15
|
+
const Wrapper = ({ children }: PropsWithChildren) => (
|
|
16
|
+
<IntlProvider locale="en">{children}</IntlProvider>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
it.each([
|
|
20
|
+
[OrderState.DRAFT, 'Pending'],
|
|
21
|
+
[OrderState.SUBMITTED, 'Pending'],
|
|
22
|
+
[OrderState.PENDING, 'Pending'],
|
|
23
|
+
[OrderState.CANCELED, 'Canceled'],
|
|
24
|
+
])(
|
|
25
|
+
'should display message from order state: %s when order have no contract',
|
|
26
|
+
(state, expectedMessage) => {
|
|
27
|
+
const order = CredentialOrderFactory({ state }).one();
|
|
28
|
+
render(
|
|
29
|
+
<Wrapper>
|
|
30
|
+
<OrderStateTeacherMessage order={order} />
|
|
31
|
+
</Wrapper>,
|
|
32
|
+
);
|
|
33
|
+
expect(screen.getByText(expectedMessage)).toBeInTheDocument();
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
it.each([
|
|
38
|
+
[OrderState.DRAFT, 'Pending'],
|
|
39
|
+
[OrderState.SUBMITTED, 'Pending'],
|
|
40
|
+
[OrderState.PENDING, 'Pending'],
|
|
41
|
+
[OrderState.CANCELED, 'Canceled'],
|
|
42
|
+
])(
|
|
43
|
+
'should display message from order state: %s when order have contract',
|
|
44
|
+
(state, expectedMessage) => {
|
|
45
|
+
const orderWithContract = CredentialOrderFactory({
|
|
46
|
+
state,
|
|
47
|
+
contract: ContractFactory().one(),
|
|
48
|
+
}).one();
|
|
49
|
+
render(
|
|
50
|
+
<Wrapper>
|
|
51
|
+
<OrderStateTeacherMessage
|
|
52
|
+
order={orderWithContract}
|
|
53
|
+
contractDefinition={ContractDefinitionFactory().one()}
|
|
54
|
+
/>
|
|
55
|
+
</Wrapper>,
|
|
56
|
+
);
|
|
57
|
+
expect(screen.getByText(expectedMessage)).toBeInTheDocument();
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
it('should display message for validated order that need learner signature', () => {
|
|
62
|
+
const order = CredentialOrderFactory({
|
|
63
|
+
state: OrderState.VALIDATED,
|
|
64
|
+
contract: null,
|
|
65
|
+
}).one();
|
|
66
|
+
|
|
67
|
+
const contractDefinition = ContractDefinitionFactory().one();
|
|
68
|
+
|
|
69
|
+
render(
|
|
70
|
+
<Wrapper>
|
|
71
|
+
<OrderStateTeacherMessage order={order} contractDefinition={contractDefinition} />
|
|
72
|
+
</Wrapper>,
|
|
73
|
+
);
|
|
74
|
+
expect(screen.getByText("Pending for learner's signature")).toBeInTheDocument();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should display message for validated order that need organization signature', () => {
|
|
78
|
+
const order = CredentialOrderFactory({
|
|
79
|
+
state: OrderState.VALIDATED,
|
|
80
|
+
contract: ContractFactory({
|
|
81
|
+
student_signed_on: new Date().toISOString(),
|
|
82
|
+
}).one(),
|
|
83
|
+
}).one();
|
|
84
|
+
const contractDefinition = ContractDefinitionFactory().one();
|
|
85
|
+
|
|
86
|
+
render(
|
|
87
|
+
<Wrapper>
|
|
88
|
+
<OrderStateTeacherMessage order={order} contractDefinition={contractDefinition} />
|
|
89
|
+
</Wrapper>,
|
|
90
|
+
);
|
|
91
|
+
expect(screen.getByText('To be signed')).toBeInTheDocument();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should display message for validated order that don't have a generated certificate", () => {
|
|
95
|
+
const order = CredentialOrderFactory({
|
|
96
|
+
state: OrderState.VALIDATED,
|
|
97
|
+
certificate_id: undefined,
|
|
98
|
+
}).one();
|
|
99
|
+
render(
|
|
100
|
+
<Wrapper>
|
|
101
|
+
<OrderStateTeacherMessage order={order} />
|
|
102
|
+
</Wrapper>,
|
|
103
|
+
);
|
|
104
|
+
expect(
|
|
105
|
+
screen.getByText(intl.formatMessage(messages.statusOnGoing), {
|
|
106
|
+
exact: false,
|
|
107
|
+
}),
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should display message for validated order that have a generated certificate', () => {
|
|
112
|
+
const order = CredentialOrderFactory({
|
|
113
|
+
state: OrderState.VALIDATED,
|
|
114
|
+
certificate_id: 'FAKE_CERTIFICATE_ID',
|
|
115
|
+
}).one();
|
|
116
|
+
render(
|
|
117
|
+
<Wrapper>
|
|
118
|
+
<OrderStateTeacherMessage order={order} />
|
|
119
|
+
</Wrapper>,
|
|
120
|
+
);
|
|
121
|
+
expect(
|
|
122
|
+
screen.getByText(intl.formatMessage(messages.statusCompleted), {
|
|
123
|
+
exact: false,
|
|
124
|
+
}),
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
});
|
package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.tsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
import OrderStateMessage, { OrderStateMessageBaseProps } from '../OrderStateMessage';
|
|
3
|
+
|
|
4
|
+
export const messages = defineMessages({
|
|
5
|
+
statusDraft: {
|
|
6
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusDraft',
|
|
7
|
+
description: 'Status shown on the dashboard order item when order is draft.',
|
|
8
|
+
defaultMessage: 'Pending',
|
|
9
|
+
},
|
|
10
|
+
statusSubmitted: {
|
|
11
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusSubmitted',
|
|
12
|
+
description: 'Status shown on the dashboard order item when order is submitted.',
|
|
13
|
+
defaultMessage: 'Pending',
|
|
14
|
+
},
|
|
15
|
+
statusPending: {
|
|
16
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusPending',
|
|
17
|
+
description: 'Status shown on the dashboard order item when order is pending.',
|
|
18
|
+
defaultMessage: 'Pending',
|
|
19
|
+
},
|
|
20
|
+
statusOnGoing: {
|
|
21
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusOnGoing',
|
|
22
|
+
description:
|
|
23
|
+
'Status shown on the dashboard order item when order is validated with no certificate',
|
|
24
|
+
defaultMessage: 'Enrolled',
|
|
25
|
+
},
|
|
26
|
+
statusCompleted: {
|
|
27
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusCompleted',
|
|
28
|
+
description:
|
|
29
|
+
'Status shown on the dashboard order item when order is validated with certificate',
|
|
30
|
+
defaultMessage: 'Certified',
|
|
31
|
+
},
|
|
32
|
+
statusWaitingSignature: {
|
|
33
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusWaitingSignature',
|
|
34
|
+
description:
|
|
35
|
+
"Status shown on the dashboard order item when order is validated with contract's learner signature missing.",
|
|
36
|
+
defaultMessage: "Pending for learner's signature",
|
|
37
|
+
},
|
|
38
|
+
statusWaitingCounterSignature: {
|
|
39
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusWaitingCounterSignature',
|
|
40
|
+
description:
|
|
41
|
+
"Status shown on the dashboard order item when order is validated with contract's organization signature missing.",
|
|
42
|
+
defaultMessage: 'To be signed',
|
|
43
|
+
},
|
|
44
|
+
statusCanceled: {
|
|
45
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusCanceled',
|
|
46
|
+
description: 'Status shown on the dashboard order item when order is canceled',
|
|
47
|
+
defaultMessage: 'Canceled',
|
|
48
|
+
},
|
|
49
|
+
statusOther: {
|
|
50
|
+
id: 'components.DashboardItem.Order.OrderStateTeacherMessage.statusOther',
|
|
51
|
+
description: 'Status shown on the dashboard order item when order status is unknown',
|
|
52
|
+
defaultMessage: '{state}',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const OrderStateTeacherMessage = (props: OrderStateMessageBaseProps) => {
|
|
57
|
+
return <OrderStateMessage {...props} messages={messages} />;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default OrderStateTeacherMessage;
|