feat: tag sections, subsections, and the whole course (FC-0053) (#879)
* feat: tag sections, subsections, and the whole course * docs: add comments to useContentTagsCount
This commit is contained in:
@@ -8,6 +8,7 @@ export const getApiBaseUrl = () => getConfig().STUDIO_BASE_URL;
|
||||
export const getCreateOrRerunCourseUrl = () => new URL('course/', getApiBaseUrl()).href;
|
||||
export const getCourseRerunUrl = (courseId) => new URL(`/api/contentstore/v1/course_rerun/${courseId}`, getApiBaseUrl()).href;
|
||||
export const getOrganizationsUrl = () => new URL('organizations', getApiBaseUrl()).href;
|
||||
export const getTagsCountApiUrl = (contentPattern) => new URL(`api/content_tagging/v1/object_tag_counts/${contentPattern}/?count_implicit`, getApiBaseUrl()).href;
|
||||
|
||||
/**
|
||||
* Get's organizations data. Returns list of organization names.
|
||||
@@ -43,3 +44,18 @@ export async function createOrRerunCourse(courseData) {
|
||||
);
|
||||
return camelCaseObject(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tags count of multiple content by id separated by commas or a pattern using a '*' wildcard.
|
||||
* @param {string} contentPattern
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export async function getTagsCount(contentPattern) {
|
||||
if (contentPattern) {
|
||||
const { data } = await getAuthenticatedHttpClient()
|
||||
.get(getTagsCountApiUrl(contentPattern));
|
||||
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import MockAdapter from 'axios-mock-adapter';
|
||||
import { initializeMockApp } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
|
||||
import { contentTagsCountMock } from '../__mocks__';
|
||||
import {
|
||||
createOrRerunCourse,
|
||||
getApiBaseUrl,
|
||||
@@ -9,6 +10,8 @@ import {
|
||||
getCreateOrRerunCourseUrl,
|
||||
getCourseRerunUrl,
|
||||
getCourseRerun,
|
||||
getTagsCount,
|
||||
getTagsCountApiUrl,
|
||||
} from './api';
|
||||
|
||||
let axiosMock;
|
||||
@@ -72,4 +75,19 @@ describe('generic api calls', () => {
|
||||
expect(axiosMock.history.post[0].url).toEqual(getCreateOrRerunCourseUrl());
|
||||
expect(result).toEqual(courseRerunData);
|
||||
});
|
||||
|
||||
it('should get tags count', async () => {
|
||||
const pattern = 'this,is,a,pattern';
|
||||
const contentId = 'block-v1:SampleTaxonomyOrg1+STC1+2023_1+type@vertical+block@aaf8b8eb86b54281aeeab12499d2cb06';
|
||||
axiosMock.onGet().reply(200, contentTagsCountMock);
|
||||
const result = await getTagsCount(pattern);
|
||||
expect(axiosMock.history.get[0].url).toEqual(getTagsCountApiUrl(pattern));
|
||||
expect(result).toEqual(contentTagsCountMock);
|
||||
expect(contentTagsCountMock[contentId]).toEqual(15);
|
||||
});
|
||||
|
||||
it('should get null on empty pattern', async () => {
|
||||
const result = await getTagsCount('');
|
||||
expect(result).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getOrganizations } from './api';
|
||||
import { getOrganizations, getTagsCount } from './api';
|
||||
|
||||
/**
|
||||
* Builds the query to get a list of available organizations
|
||||
@@ -12,4 +12,23 @@ export const useOrganizationListData = () => (
|
||||
})
|
||||
);
|
||||
|
||||
export default useOrganizationListData;
|
||||
/**
|
||||
* Builds the query to get tags count of the whole contentId course and
|
||||
* returns the tags count of the specific contentId.
|
||||
* @param {string} contentId
|
||||
*/
|
||||
export const useContentTagsCount = (contentId) => {
|
||||
let contentPattern;
|
||||
if (contentId.includes('course-v1')) {
|
||||
// If the contentId is a course, we want to get the tags count only for the course
|
||||
contentPattern = contentId;
|
||||
} else {
|
||||
// If the contentId is not a course, we want to get the tags count for all the content of the course
|
||||
contentPattern = contentId.replace(/\+type@.*$/, '*');
|
||||
}
|
||||
return useQuery({
|
||||
queryKey: ['contentTagsCount', contentPattern],
|
||||
queryFn: /* istanbul ignore next */ () => getTagsCount(contentPattern),
|
||||
select: (data) => data[contentId] || 0, // Return the tags count of the specific contentId
|
||||
});
|
||||
};
|
||||
|
||||
28
src/generic/data/apiHooks.test.js
Normal file
28
src/generic/data/apiHooks.test.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useContentTagsCount } from './apiHooks';
|
||||
|
||||
jest.mock('@tanstack/react-query', () => ({
|
||||
useQuery: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('./api', () => ({
|
||||
getTagsCount: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('useContentTagsCount', () => {
|
||||
it('should return success response', () => {
|
||||
useQuery.mockReturnValueOnce({ isSuccess: true, data: 'data' });
|
||||
const pattern = '123';
|
||||
const result = useContentTagsCount(pattern);
|
||||
|
||||
expect(result).toEqual({ isSuccess: true, data: 'data' });
|
||||
});
|
||||
|
||||
it('should return failure response', () => {
|
||||
useQuery.mockReturnValueOnce({ isSuccess: false });
|
||||
const pattern = '123';
|
||||
const result = useContentTagsCount(pattern);
|
||||
|
||||
expect(result).toEqual({ isSuccess: false });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user