Skip to content
This repository was archived by the owner on Feb 14, 2025. It is now read-only.

Commit a935d29

Browse files
author
kenclary
authored
Merge pull request #355 from openedx/kenclary/TNL-10743
feat: more/correct v2 url handling. TNL-10742
2 parents 3565741 + 7178e5e commit a935d29

File tree

4 files changed

+43
-17
lines changed

4 files changed

+43
-17
lines changed

src/editors/containers/EditorContainer/hooks.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const handleSaveClicked = ({
2727
returnFunction,
2828
}) => {
2929
// eslint-disable-next-line react-hooks/rules-of-hooks
30-
const destination = useSelector(selectors.app.returnUrl);
30+
const destination = returnFunction ? '' : useSelector(selectors.app.returnUrl);
3131
// eslint-disable-next-line react-hooks/rules-of-hooks
3232
const analytics = useSelector(selectors.app.analytics);
3333

@@ -57,7 +57,7 @@ export const handleCancel = ({ onClose, returnFunction }) => {
5757
return navigateCallback({
5858
returnFunction,
5959
// eslint-disable-next-line react-hooks/rules-of-hooks
60-
destination: useSelector(selectors.app.returnUrl),
60+
destination: returnFunction ? '' : useSelector(selectors.app.returnUrl),
6161
analyticsEvent: analyticsEvt.editorCancelClick,
6262
// eslint-disable-next-line react-hooks/rules-of-hooks
6363
analytics: useSelector(selectors.app.analytics),

src/editors/data/services/cms/api.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export const apiMethods = {
143143
response = {
144144
data: content.olx,
145145
category: blockType,
146-
couseKey: learningContextId,
146+
courseKey: learningContextId,
147147
has_changes: true,
148148
id: blockId,
149149
metadata: { display_name: title, ...content.settings },

src/editors/data/services/cms/urls.js

+21-8
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,39 @@ export const unit = ({ studioEndpointUrl, unitUrl }) => (
77
);
88

99
export const returnUrl = ({ studioEndpointUrl, unitUrl, learningContextId }) => {
10-
if (learningContextId && learningContextId.includes('library-v1')) {
10+
if (learningContextId && learningContextId.startsWith('library-v1')) {
1111
// when the learning context is a v1 library, return to the library page
1212
return libraryV1({ studioEndpointUrl, learningContextId });
1313
}
14+
if (learningContextId && learningContextId.startsWith('lib')) {
15+
// when it's a v2 library, there will be no return url (instead a closed popup)
16+
throw new Error('Return url not available (or needed) for V2 libraries');
17+
}
1418
// when the learning context is a course, return to the unit page
15-
return unitUrl ? unit({ studioEndpointUrl, unitUrl }) : '';
19+
if (unitUrl) {
20+
return unit({ studioEndpointUrl, unitUrl });
21+
}
22+
throw new Error('No unit url for return url');
1623
};
1724

1825
export const block = ({ studioEndpointUrl, blockId }) => (
19-
blockId.includes('block-v1')
26+
blockId.startsWith('block-v1')
2027
? `${studioEndpointUrl}/xblock/${blockId}`
21-
: `${studioEndpointUrl}/api/xblock/v2/xblocks/${blockId}`
28+
: `${studioEndpointUrl}/api/xblock/v2/xblocks/${blockId}/fields/`
2229
);
2330

24-
export const blockAncestor = ({ studioEndpointUrl, blockId }) => (
25-
`${block({ studioEndpointUrl, blockId })}?fields=ancestorInfo`
26-
);
31+
export const blockAncestor = ({ studioEndpointUrl, blockId }) => {
32+
if (blockId.startsWith('block-v1')) {
33+
return `${block({ studioEndpointUrl, blockId })}?fields=ancestorInfo`;
34+
}
35+
// this url only need to get info to build the return url, which isn't used by V2 blocks
36+
throw new Error('Block ancestor not available (and not needed) for V2 blocks');
37+
};
2738

2839
export const blockStudioView = ({ studioEndpointUrl, blockId }) => (
29-
`${block({ studioEndpointUrl, blockId })}/studio_view`
40+
blockId.startsWith('block-v1')
41+
? `${block({ studioEndpointUrl, blockId })}/studio_view`
42+
: `${studioEndpointUrl}/api/xblock/v2/xblocks/${blockId}/view/studio_view/`
3043
);
3144

3245
export const courseAssets = ({ studioEndpointUrl, learningContextId }) => (

src/editors/data/services/cms/urls.test.js

+19-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ describe('cms url methods', () => {
2626
const learningContextId = 'lEarnIngCOntextId123';
2727
const courseId = 'course-v1:courseId123';
2828
const libraryV1Id = 'library-v1:libaryId123';
29+
const libraryV2Id = 'lib:libaryId123';
2930
const language = 'la';
3031
const handout = '/aSSet@hANdoUt';
3132
const videoId = '123-SOmeVidEOid-213';
@@ -41,17 +42,21 @@ describe('cms url methods', () => {
4142
],
4243
},
4344
};
44-
it('returns the library page when given the library', () => {
45+
it('returns the library page when given the v1 library', () => {
4546
expect(returnUrl({ studioEndpointUrl, unitUrl, learningContextId: libraryV1Id }))
4647
.toEqual(`${studioEndpointUrl}/library/${libraryV1Id}`);
4748
});
49+
it('throws error when given the v2 library', () => {
50+
expect(() => { returnUrl({ studioEndpointUrl, unitUrl, learningContextId: libraryV2Id }); })
51+
.toThrow('Return url not available (or needed) for V2 libraries');
52+
});
4853
it('returns url with studioEndpointUrl and unitUrl', () => {
4954
expect(returnUrl({ studioEndpointUrl, unitUrl, learningContextId: courseId }))
5055
.toEqual(`${studioEndpointUrl}/container/${unitUrl.data.ancestors[0].id}`);
5156
});
52-
it('returns empty string if no unit url', () => {
53-
expect(returnUrl({ studioEndpointUrl, unitUrl: null, learningContextId: courseId }))
54-
.toEqual('');
57+
it('throws error if no unit url', () => {
58+
expect(() => { returnUrl({ studioEndpointUrl, unitUrl: null, learningContextId: courseId }); })
59+
.toThrow('No unit url for return url');
5560
});
5661
it('returns the library page when given the library', () => {
5762
expect(libraryV1({ studioEndpointUrl, learningContextId: libraryV1Id }))
@@ -69,20 +74,28 @@ describe('cms url methods', () => {
6974
});
7075
it('returns v2 url with studioEndpointUrl and v2BlockId', () => {
7176
expect(block({ studioEndpointUrl, blockId: v2BlockId }))
72-
.toEqual(`${studioEndpointUrl}/api/xblock/v2/xblocks/${v2BlockId}`);
77+
.toEqual(`${studioEndpointUrl}/api/xblock/v2/xblocks/${v2BlockId}/fields/`);
7378
});
7479
});
7580
describe('blockAncestor', () => {
7681
it('returns url with studioEndpointUrl, blockId and ancestor query', () => {
7782
expect(blockAncestor({ studioEndpointUrl, blockId }))
7883
.toEqual(`${block({ studioEndpointUrl, blockId })}?fields=ancestorInfo`);
7984
});
85+
it('throws error with studioEndpointUrl, v2 blockId and ancestor query', () => {
86+
expect(() => { blockAncestor({ studioEndpointUrl, blockId: v2BlockId }); })
87+
.toThrow('Block ancestor not available (and not needed) for V2 blocks');
88+
});
8089
});
8190
describe('blockStudioView', () => {
82-
it('returns url with studioEndpointUrl, blockId and studio_view query', () => {
91+
it('returns v1 url with studioEndpointUrl, blockId and studio_view query', () => {
8392
expect(blockStudioView({ studioEndpointUrl, blockId }))
8493
.toEqual(`${block({ studioEndpointUrl, blockId })}/studio_view`);
8594
});
95+
it('returns v2 url with studioEndpointUrl, v2 blockId and studio_view query', () => {
96+
expect(blockStudioView({ studioEndpointUrl, blockId: v2BlockId }))
97+
.toEqual(`${studioEndpointUrl}/api/xblock/v2/xblocks/${v2BlockId}/view/studio_view/`);
98+
});
8699
});
87100

88101
describe('courseAssets', () => {

0 commit comments

Comments
 (0)