Skip to content

Commit 672f171

Browse files
committed
adjust the logic to use response codes added to the mitxonline attach endpoint
1 parent 34a403f commit 672f171

File tree

3 files changed

+35
-71
lines changed

3 files changed

+35
-71
lines changed

frontends/api/src/mitxonline/hooks/organizations/queries.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ const organizationQueries = {
3232
const useB2BAttachMutation = (opts: B2bApiB2bAttachCreateRequest) => {
3333
const queryClient = useQueryClient()
3434
return useMutation({
35-
mutationFn: () => b2bApi.b2bAttachCreate(opts),
35+
mutationFn: async () => {
36+
const response = await b2bApi.b2bAttachCreate(opts)
37+
// 200 (already attached) indicates user already attached to all contracts
38+
// 201 (successfully attached) is success
39+
// 404 (invalid or expired code) will be thrown as error by axios
40+
return response
41+
},
3642
onSuccess: () => {
3743
queryClient.invalidateQueries({ queryKey: ["mitxonline"] })
3844
},

frontends/main/src/app-pages/EnrollmentCodePage/EnrollmentCodePage.test.tsx

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -67,29 +67,14 @@ describe("EnrollmentCodePage", () => {
6767
})
6868
})
6969

70-
test("Redirects to dashboard on successful attachment", async () => {
70+
test("Redirects to dashboard on successful attachment (201 status)", async () => {
7171
setMockResponse.get(urls.userMe.get(), {
7272
[Permission.Authenticated]: true,
7373
})
7474

75-
const initialOrg = factories.organizations.organization({})
76-
const newOrg = factories.organizations.organization({})
77-
const initialMitxUser = factories.user.user({
78-
b2b_organizations: [initialOrg],
79-
})
80-
const updatedMitxUser = factories.user.user({
81-
b2b_organizations: [initialOrg, newOrg],
82-
})
83-
84-
// First call returns initial user, subsequent calls return updated user
85-
let callCount = 0
86-
setMockResponse.get(b2bUrls.userMe.get(), () => {
87-
callCount++
88-
return callCount === 1 ? initialMitxUser : updatedMitxUser
89-
})
90-
9175
const attachUrl = b2bUrls.b2bAttach.b2bAttachView("test-code")
92-
setMockResponse.post(attachUrl, updatedMitxUser)
76+
// 201 status indicates successful attachment to new contract(s)
77+
setMockResponse.post(attachUrl, {}, { code: 201 })
9378

9479
renderWithProviders(<EnrollmentCodePage code="test-code" />, {
9580
url: commonUrls.B2B_ATTACH_VIEW,
@@ -104,47 +89,36 @@ describe("EnrollmentCodePage", () => {
10489
})
10590
})
10691

107-
test("Redirects to dashboard with error when b2b organizations don't change", async () => {
92+
test("Redirects to dashboard when user already attached to all contracts (200 status)", async () => {
10893
setMockResponse.get(urls.userMe.get(), {
10994
[Permission.Authenticated]: true,
11095
})
11196

112-
const organization = factories.organizations.organization({})
113-
const mitxUser = factories.user.user({
114-
b2b_organizations: [organization],
115-
})
116-
117-
setMockResponse.get(b2bUrls.userMe.get(), mitxUser)
118-
119-
const attachUrl = b2bUrls.b2bAttach.b2bAttachView("invalid-code")
120-
setMockResponse.post(attachUrl, mitxUser)
97+
const attachUrl = b2bUrls.b2bAttach.b2bAttachView("already-used-code")
98+
// 200 status indicates user already attached to all contracts - still redirect to dashboard without error
99+
setMockResponse.post(attachUrl, {}, { code: 200 })
121100

122-
renderWithProviders(<EnrollmentCodePage code="invalid-code" />, {
101+
renderWithProviders(<EnrollmentCodePage code="already-used-code" />, {
123102
url: commonUrls.B2B_ATTACH_VIEW,
124103
})
125104

126105
await waitFor(() => {
127106
expect(makeRequest).toHaveBeenCalledWith("post", attachUrl, undefined)
128107
})
129108

130-
expect(mockPush).toHaveBeenCalledWith(
131-
commonUrls.DASHBOARD_HOME_ENROLLMENT_ERROR,
132-
)
109+
await waitFor(() => {
110+
expect(mockPush).toHaveBeenCalledWith(commonUrls.DASHBOARD_HOME)
111+
})
133112
})
134113

135-
test("Redirects to dashboard with error when user has no organizations initially", async () => {
114+
test("Redirects to dashboard with error for invalid code (404 status)", async () => {
136115
setMockResponse.get(urls.userMe.get(), {
137116
[Permission.Authenticated]: true,
138117
})
139118

140-
const mitxUser = factories.user.user({
141-
b2b_organizations: [],
142-
})
143-
144-
setMockResponse.get(b2bUrls.userMe.get(), mitxUser)
145-
146119
const attachUrl = b2bUrls.b2bAttach.b2bAttachView("invalid-code")
147-
setMockResponse.post(attachUrl, mitxUser)
120+
// 404 status indicates invalid or expired enrollment code
121+
setMockResponse.post(attachUrl, {}, { code: 404 })
148122

149123
renderWithProviders(<EnrollmentCodePage code="invalid-code" />, {
150124
url: commonUrls.B2B_ATTACH_VIEW,
@@ -154,8 +128,10 @@ describe("EnrollmentCodePage", () => {
154128
expect(makeRequest).toHaveBeenCalledWith("post", attachUrl, undefined)
155129
})
156130

157-
expect(mockPush).toHaveBeenCalledWith(
158-
commonUrls.DASHBOARD_HOME_ENROLLMENT_ERROR,
159-
)
131+
await waitFor(() => {
132+
expect(mockPush).toHaveBeenCalledWith(
133+
commonUrls.DASHBOARD_HOME_ENROLLMENT_ERROR,
134+
)
135+
})
160136
})
161137
})

frontends/main/src/app-pages/EnrollmentCodePage/EnrollmentCodePage.tsx

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { useB2BAttachMutation } from "api/mitxonline-hooks/organizations"
66
import { userQueries } from "api/hooks/user"
77
import { useQuery } from "@tanstack/react-query"
88
import { useRouter } from "next-nprogress-bar"
9-
import { mitxUserQueries } from "api/mitxonline-hooks/user"
109

1110
type EnrollmentCodePage = {
1211
code: string
@@ -18,18 +17,7 @@ const InterstitialMessage = styled(Typography)(({ theme }) => ({
1817
}))
1918

2019
const EnrollmentCodePage: React.FC<EnrollmentCodePage> = ({ code }) => {
21-
const mitxOnlineUser = useQuery(mitxUserQueries.me())
22-
const initialOrgsRef = React.useRef<number | null>(null)
2320
const [hasEnrolled, setHasEnrolled] = React.useState(false)
24-
25-
// Capture initial organization count once
26-
if (
27-
initialOrgsRef.current === null &&
28-
mitxOnlineUser.data?.b2b_organizations
29-
) {
30-
initialOrgsRef.current = mitxOnlineUser.data.b2b_organizations.length
31-
}
32-
3321
const router = useRouter()
3422

3523
const enrollment = useB2BAttachMutation({
@@ -48,23 +36,17 @@ const EnrollmentCodePage: React.FC<EnrollmentCodePage> = ({ code }) => {
4836
}
4937
}, [user?.is_authenticated, hasEnrolled, enrollment])
5038

51-
// Handle redirect after mutation succeeds and query is refetched
39+
// Handle redirect based on response status code
40+
// 201: Successfully attached to new contract(s) -> redirect to dashboard
41+
// 200: Already attached to all contracts -> redirect to dashboard
42+
// 404: Invalid or expired code -> show error
5243
React.useEffect(() => {
53-
if (enrollment.isSuccess && !enrollment.isPending) {
54-
const currentOrgCount =
55-
mitxOnlineUser.data?.b2b_organizations?.length ?? 0
56-
if (initialOrgsRef.current === currentOrgCount) {
57-
router.push(urls.DASHBOARD_HOME_ENROLLMENT_ERROR)
58-
} else {
59-
router.push(urls.DASHBOARD_HOME)
60-
}
44+
if (enrollment.isSuccess) {
45+
router.push(urls.DASHBOARD_HOME)
46+
} else if (enrollment.isError) {
47+
router.push(urls.DASHBOARD_HOME_ENROLLMENT_ERROR)
6148
}
62-
}, [
63-
enrollment.isSuccess,
64-
enrollment.isPending,
65-
mitxOnlineUser.data?.b2b_organizations?.length,
66-
router,
67-
])
49+
}, [enrollment.isSuccess, enrollment.isError, router])
6850

6951
React.useEffect(() => {
7052
if (userLoading) {

0 commit comments

Comments
 (0)