Skip to content

Commit

Permalink
feat: Support runtime configuration
Browse files Browse the repository at this point in the history
frontend-platform supports runtime configuration since 2.5.0 (see the PR
that introduced it[1], but it requires MFE cooperation.  This implements
just that: by avoiding making configuration values constant, it should
now be possible to change them after initialization.

Almost all changes here relate to the `LMS_BASE_URL` setting, which in
most places was treated as a constant.

[1] openedx/frontend-platform#335
  • Loading branch information
Adolfo R. Brandes authored and arbrandes committed Dec 9, 2022
1 parent d60f1af commit 9f84230
Show file tree
Hide file tree
Showing 27 changed files with 86 additions and 76 deletions.
4 changes: 2 additions & 2 deletions src/components/NavigationBar/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { camelCaseObject } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

import { API_BASE_URL } from '../../../data/constants';
import { getApiBaseUrl } from '../../../data/constants';

function normalizeCourseHomeCourseMetadata(metadata, rootSlug) {
const data = camelCaseObject(metadata);
Expand All @@ -21,7 +21,7 @@ function normalizeCourseHomeCourseMetadata(metadata, rootSlug) {
}

export async function getCourseHomeCourseMetadata(courseId, rootSlug) {
const url = `${API_BASE_URL}/api/course_home/course_metadata/${courseId}`;
const url = `${getApiBaseUrl()}/api/course_home/course_metadata/${courseId}`;
// don't know the context of adding timezone in url. hence omitting it
// url = appendBrowserTimezoneToUrl(url);
const { data } = await getAuthenticatedHttpClient().get(url);
Expand Down
6 changes: 3 additions & 3 deletions src/data/api.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* eslint-disable import/prefer-default-export */
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

import { API_BASE_URL } from './constants';
import { getApiBaseUrl } from './constants';

export const blocksAPIURL = `${API_BASE_URL}/api/courses/v1/blocks/`;
export const getBlocksAPIURL = () => `${getApiBaseUrl()}/api/courses/v1/blocks/`;
export async function getCourseBlocks(courseId, username) {
const params = {
course_id: courseId,
Expand All @@ -14,6 +14,6 @@ export async function getCourseBlocks(courseId, username) {
student_view_data: 'discussion',
};
const { data } = await getAuthenticatedHttpClient()
.get(blocksAPIURL, { params });
.get(getBlocksAPIURL(), { params });
return data;
}
2 changes: 1 addition & 1 deletion src/data/constants.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getConfig } from '@edx/frontend-platform';

export const API_BASE_URL = getConfig().LMS_BASE_URL;
export const getApiBaseUrl = () => getConfig().LMS_BASE_URL;

/**
* Enum for thread types.
Expand Down
3 changes: 2 additions & 1 deletion src/data/redux.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { initializeMockApp } from '@edx/frontend-platform/testing';
import { initializeStore } from '../store';
import { executeThunk } from '../test-utils';
import { getBlocksAPIResponse } from './__factories__';
import { blocksAPIURL } from './api';
import { getBlocksAPIURL } from './api';
import { RequestStatus } from './constants';
import { fetchCourseBlocks } from './thunks';

const blocksAPIURL = getBlocksAPIURL();
const courseId = 'course-v1:edX+DemoX+Demo_Course';

let axiosMock;
Expand Down
4 changes: 1 addition & 3 deletions src/discussions/cohorts/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ ensureConfig([
'LMS_BASE_URL',
], 'Comments API service');

const apiBaseUrl = getConfig().LMS_BASE_URL;

export const getCohortsApiUrl = courseId => `${apiBaseUrl}/api/cohorts/v1/courses/${courseId}/cohorts/`;
export const getCohortsApiUrl = courseId => `${getConfig().LMS_BASE_URL}/api/cohorts/v1/courses/${courseId}/cohorts/`;

export async function getCourseCohorts(courseId) {
const params = snakeCaseObject({ courseId });
Expand Down
9 changes: 6 additions & 3 deletions src/discussions/comments/CommentsView.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@ import { AppProvider } from '@edx/frontend-platform/react';
import { initializeStore } from '../../store';
import { executeThunk } from '../../test-utils';
import { DiscussionContext } from '../common/context';
import { courseConfigApiUrl } from '../data/api';
import { getCourseConfigApiUrl } from '../data/api';
import { fetchCourseConfig } from '../data/thunks';
import DiscussionContent from '../discussions-home/DiscussionContent';
import { threadsApiUrl } from '../posts/data/api';
import { getThreadsApiUrl } from '../posts/data/api';
import { fetchThreads } from '../posts/data/thunks';
import { commentsApiUrl } from './data/api';
import { getCommentsApiUrl } from './data/api';

import '../posts/data/__factories__';
import './data/__factories__';

const courseConfigApiUrl = getCourseConfigApiUrl();
const commentsApiUrl = getCommentsApiUrl();
const threadsApiUrl = getThreadsApiUrl();
const discussionPostId = 'thread-1';
const questionPostId = 'thread-2';
const closedPostId = 'thread-2';
Expand Down
14 changes: 6 additions & 8 deletions src/discussions/comments/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ ensureConfig([
'LMS_BASE_URL',
], 'Comments API service');

const apiBaseUrl = getConfig().LMS_BASE_URL;

export const commentsApiUrl = `${apiBaseUrl}/api/discussion/v1/comments/`;
export const getCommentsApiUrl = () => `${getConfig().LMS_BASE_URL}/api/discussion/v1/comments/`;

/**
* Returns all the comments for the specified thread.
Expand All @@ -36,7 +34,7 @@ export async function getThreadComments(
});

const { data } = await getAuthenticatedHttpClient()
.get(commentsApiUrl, { params });
.get(getCommentsApiUrl(), { params });
return data;
}

Expand All @@ -53,7 +51,7 @@ export async function getCommentResponses(
pageSize,
} = {},
) {
const url = `${commentsApiUrl}${commentId}/`;
const url = `${getCommentsApiUrl()}${commentId}/`;
const params = snakeCaseObject({
page,
pageSize,
Expand All @@ -73,7 +71,7 @@ export async function getCommentResponses(
*/
export async function postComment(comment, threadId, parentId = null) {
const { data } = await getAuthenticatedHttpClient()
.post(commentsApiUrl, snakeCaseObject({ threadId, raw_body: comment, parentId }));
.post(getCommentsApiUrl(), snakeCaseObject({ threadId, raw_body: comment, parentId }));
return data;
}

Expand All @@ -94,7 +92,7 @@ export async function updateComment(commentId, {
endorsed,
editReasonCode,
}) {
const url = `${commentsApiUrl}${commentId}/`;
const url = `${getCommentsApiUrl()}${commentId}/`;
const postData = snakeCaseObject({
raw_body: comment,
voted,
Expand All @@ -113,7 +111,7 @@ export async function updateComment(commentId, {
* @param {string} commentId ID of comment to delete
*/
export async function deleteComment(commentId) {
const url = `${commentsApiUrl}${commentId}/`;
const url = `${getCommentsApiUrl()}${commentId}/`;
await getAuthenticatedHttpClient()
.delete(url);
}
3 changes: 2 additions & 1 deletion src/discussions/comments/data/redux.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import { initializeMockApp } from '@edx/frontend-platform/testing';
import { EndorsementStatus } from '../../../data/constants';
import { initializeStore } from '../../../store';
import { executeThunk } from '../../../test-utils';
import { commentsApiUrl } from './api';
import { getCommentsApiUrl } from './api';
import {
addComment, editComment, fetchCommentResponses, fetchThreadComments, removeComment,
} from './thunks';

import './__factories__';

const commentsApiUrl = getCommentsApiUrl();
let axiosMock;
let store;

Expand Down
3 changes: 2 additions & 1 deletion src/discussions/common/AuthorLabel.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import { AppProvider } from '@edx/frontend-platform/react';

import { initializeStore } from '../../store';
import { executeThunk } from '../../test-utils';
import { courseConfigApiUrl } from '../data/api';
import { getCourseConfigApiUrl } from '../data/api';
import { fetchCourseConfig } from '../data/thunks';
import AuthorLabel from './AuthorLabel';
import { DiscussionContext } from './context';

const courseId = 'course-v1:edX+DemoX+Demo_Course';
const courseConfigApiUrl = getCourseConfigApiUrl();
let store;
let axiosMock;
let container;
Expand Down
8 changes: 3 additions & 5 deletions src/discussions/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ ensureConfig([
'LMS_BASE_URL',
], 'Posts API service');

const apiBaseUrl = getConfig().LMS_BASE_URL;

export const courseConfigApiUrl = `${apiBaseUrl}/api/discussion/v1/courses/`;
export const getCourseConfigApiUrl = () => `${getConfig().LMS_BASE_URL}/api/discussion/v1/courses/`;

/**
* Get discussions course config
* @param {string} courseId
*/
export async function getDiscussionsConfig(courseId) {
const url = `${courseConfigApiUrl}${courseId}/`;
const url = `${getCourseConfigApiUrl()}${courseId}/`;
const { data } = await getAuthenticatedHttpClient().get(url);
return data;
}
Expand All @@ -26,7 +24,7 @@ export async function getDiscussionsConfig(courseId) {
* @param {string} courseId
*/
export async function getDiscussionsSettings(courseId) {
const url = `${courseConfigApiUrl}${courseId}/settings`;
const url = `${getCourseConfigApiUrl()}${courseId}/settings`;
const { data } = await getAuthenticatedHttpClient().get(url);
return data;
}
3 changes: 2 additions & 1 deletion src/discussions/data/hooks.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import { AppProvider } from '@edx/frontend-platform/react';
import { initializeStore } from '../../store';
import { executeThunk } from '../../test-utils';
import { DiscussionContext } from '../common/context';
import { courseConfigApiUrl } from './api';
import { getCourseConfigApiUrl } from './api';
import { useCurrentDiscussionTopic, useUserCanAddThreadInBlackoutDate } from './hooks';
import { fetchCourseConfig } from './thunks';

const courseId = 'course-v1:edX+TestX+Test_Course';
const courseConfigApiUrl = getCourseConfigApiUrl();
let store;
let axiosMock;

Expand Down
3 changes: 2 additions & 1 deletion src/discussions/discussions-home/DiscussionSidebar.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import { AppProvider } from '@edx/frontend-platform/react';
import { initializeStore } from '../../store';
import { DiscussionContext } from '../common/context';
import { fetchConfigSuccess } from '../data/slices';
import { threadsApiUrl } from '../posts/data/api';
import { getThreadsApiUrl } from '../posts/data/api';
import DiscussionSidebar from './DiscussionSidebar';

import '../posts/data/__factories__';

let store;
let container;
const courseId = 'course-v1:edX+DemoX+Demo_Course';
const threadsApiUrl = getThreadsApiUrl();
let axiosMock;

function renderComponent(displaySidebar = true, location = `/${courseId}/`) {
Expand Down
3 changes: 2 additions & 1 deletion src/discussions/empty-posts/EmptyPosts.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import { AppProvider } from '@edx/frontend-platform/react';
import { initializeStore } from '../../store';
import { executeThunk } from '../../test-utils';
import messages from '../messages';
import { threadsApiUrl } from '../posts/data/api';
import { getThreadsApiUrl } from '../posts/data/api';
import { fetchThreads } from '../posts/data/thunks';
import EmptyPosts from './EmptyPosts';

import '../posts/data/__factories__';

let store;
const courseId = 'course-v1:edX+DemoX+Demo_Course';
const threadsApiUrl = getThreadsApiUrl();

function renderComponent(location = `/${courseId}/`) {
return render(
Expand Down
4 changes: 2 additions & 2 deletions src/discussions/empty-posts/EmptyTopics.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { initializeMockApp } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider } from '@edx/frontend-platform/react';

import { API_BASE_URL } from '../../data/constants';
import { getApiBaseUrl } from '../../data/constants';
import { initializeStore } from '../../store';
import { executeThunk } from '../../test-utils';
import messages from '../messages';
Expand All @@ -20,7 +20,7 @@ import '../topics/data/__factories__';

let store;
const courseId = 'course-v1:edX+DemoX+Demo_Course';
const topicsApiUrl = `${API_BASE_URL}/api/discussion/v1/course_topics/${courseId}`;
const topicsApiUrl = `${getApiBaseUrl()}/api/discussion/v1/course_topics/${courseId}`;

function renderComponent(location = `/${courseId}/topics/`) {
return render(
Expand Down
6 changes: 4 additions & 2 deletions src/discussions/learners/LearnerPostsView.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ import { AppProvider } from '@edx/frontend-platform/react';
import { initializeStore } from '../../store';
import { executeThunk } from '../../test-utils';
import { DiscussionContext } from '../common/context';
import { courseConfigApiUrl } from '../data/api';
import { getCourseConfigApiUrl } from '../data/api';
import { fetchCourseConfig } from '../data/thunks';
import { coursesApiUrl } from './data/api';
import { getCoursesApiUrl } from './data/api';
import LearnerPostsView from './LearnerPostsView';

import './data/__factories__';

let store;
let axiosMock;
const coursesApiUrl = getCoursesApiUrl();
const courseConfigApiUrl = getCourseConfigApiUrl();
const courseId = 'course-v1:edX+TestX+Test_Course';
const username = 'abc123';

Expand Down
7 changes: 5 additions & 2 deletions src/discussions/learners/LearnersView.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@ import { AppProvider } from '@edx/frontend-platform/react';

import { initializeStore } from '../../store';
import { executeThunk } from '../../test-utils';
import { courseConfigApiUrl } from '../data/api';
import { getCourseConfigApiUrl } from '../data/api';
import { fetchCourseConfig } from '../data/thunks';
import { coursesApiUrl, userProfileApiUrl } from './data/api';
import { getCoursesApiUrl, getUserProfileApiUrl } from './data/api';
import { fetchLearners } from './data/thunks';
import LearnersView from './LearnersView';

import './data/__factories__';

let store;
let axiosMock;
const coursesApiUrl = getCoursesApiUrl();
const courseConfigApiUrl = getCourseConfigApiUrl();
const userProfileApiUrl = getUserProfileApiUrl();
const courseId = 'course-v1:edX+TestX+Test_Course';

function renderComponent() {
Expand Down
12 changes: 5 additions & 7 deletions src/discussions/learners/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ ensureConfig([
'LMS_BASE_URL',
], 'Posts API service');

const apiBaseUrl = getConfig().LMS_BASE_URL;

export const coursesApiUrl = `${apiBaseUrl}/api/discussion/v1/courses/`;
export const userProfileApiUrl = `${apiBaseUrl}/api/user/v1/accounts`;
export const getCoursesApiUrl = () => `${getConfig().LMS_BASE_URL}/api/discussion/v1/courses/`;
export const getUserProfileApiUrl = () => `${getConfig().LMS_BASE_URL}/api/user/v1/accounts`;

/**
* Fetches all the learners in the given course.
Expand All @@ -20,7 +18,7 @@ export const userProfileApiUrl = `${apiBaseUrl}/api/user/v1/accounts`;
* @returns {Promise<{}>}
*/
export async function getLearners(courseId, params) {
const url = `${coursesApiUrl}${courseId}/activity_stats/`;
const url = `${getCoursesApiUrl()}${courseId}/activity_stats/`;
const { data } = await getAuthenticatedHttpClient().get(url, { params });
return data;
}
Expand All @@ -30,7 +28,7 @@ export async function getLearners(courseId, params) {
* @param {string} usernames
*/
export async function getUserProfiles(usernames) {
const url = `${userProfileApiUrl}?username=${usernames.join()}`;
const url = `${getUserProfileApiUrl()}?username=${usernames.join()}`;
const { data } = await getAuthenticatedHttpClient().get(url);
return data;
}
Expand Down Expand Up @@ -67,7 +65,7 @@ export async function getUserPosts(courseId, {
countFlagged,
cohort,
} = {}) {
const learnerPostsApiUrl = `${coursesApiUrl}${courseId}/learner/`;
const learnerPostsApiUrl = `${getCoursesApiUrl()}${courseId}/learner/`;

const params = snakeCaseObject({
page,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider } from '@edx/frontend-platform/react';

import { getBlocksAPIResponse } from '../../../data/__factories__';
import { blocksAPIURL } from '../../../data/api';
import { API_BASE_URL, Routes } from '../../../data/constants';
import { getBlocksAPIURL } from '../../../data/api';
import { getApiBaseUrl, Routes } from '../../../data/constants';
import { fetchCourseBlocks } from '../../../data/thunks';
import { initializeStore } from '../../../store';
import { executeThunk } from '../../../test-utils';
Expand All @@ -25,7 +25,7 @@ import { BreadcrumbMenu } from '../index';
import '../../topics/data/__factories__';

const courseId = 'course-v1:edX+DemoX+Demo_Course';
const topicsApiUrl = `${API_BASE_URL}/api/discussion/v2/course_topics/${courseId}`;
const topicsApiUrl = `${getApiBaseUrl()}/api/discussion/v2/course_topics/${courseId}`;
let store;
let axiosMock;

Expand Down Expand Up @@ -78,7 +78,7 @@ describe('BreadcrumbMenu', () => {
Factory.resetAll();
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
blocksAPIResponse = getBlocksAPIResponse();
axiosMock.onGet(blocksAPIURL)
axiosMock.onGet(getBlocksAPIURL())
.reply(200, blocksAPIResponse);
await executeThunk(fetchCourseBlocks(courseId, 'test-user'), store.dispatch, store.getState);
const data = [
Expand Down
Loading

0 comments on commit 9f84230

Please sign in to comment.