Skip to content

Commit

Permalink
refactor: merge useContentTaxonomyTagsCount and useContentTagsCount
Browse files Browse the repository at this point in the history
  • Loading branch information
rpenido committed Mar 15, 2024
1 parent d57d5ad commit a9fd664
Show file tree
Hide file tree
Showing 19 changed files with 92 additions and 149 deletions.
14 changes: 0 additions & 14 deletions src/content-tags-drawer/data/apiHooks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
getContentTaxonomyTagsData,
getContentData,
updateContentTaxonomyTags,
getContentTaxonomyTagsCount,
} from './api';

/** @typedef {import("../../taxonomy/tag-list/data/types.mjs").TagListData} TagListData */
Expand Down Expand Up @@ -106,18 +105,6 @@ export const useContentTaxonomyTagsData = (contentId) => (
})
);

/**
* Build the query to get the count og taxonomy tags applied to the content object
* @param {string} contentId The ID of the content object to fetch the count of the applied tags for
*/
// FixMe: remove
// export const useContentTaxonomyTagsCount = (contentId) => (
// useQuery({
// queryKey: ['contentTaxonomyTagsCount', contentId],
// queryFn: () => getContentTaxonomyTagsCount(contentId),
// })
// );

/**
* Builds the query to get meta data about the content object
* @param {string} contentId The id of the content object (unit/component)
Expand Down Expand Up @@ -159,7 +146,6 @@ export const useContentTaxonomyTagsUpdater = (contentId, taxonomyId) => {
}
queryClient.invalidateQueries({ queryKey: ['contentTagsCount', contentPattern] });
// FixMe: remove code below
// queryClient.invalidateQueries({ queryKey: ['unitTagsCount'] });
// queryClient.invalidateQueries({ queryKey: ['contentTaxonomyTagsCount', contentId] });
},
});
Expand Down
19 changes: 0 additions & 19 deletions src/content-tags-drawer/data/apiHooks.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
useContentTaxonomyTagsData,
useContentData,
useContentTaxonomyTagsUpdater,
useContentTaxonomyTagsCount,
} from './apiHooks';

import { updateContentTaxonomyTags } from './api';
Expand Down Expand Up @@ -135,24 +134,6 @@ describe('useContentTaxonomyTagsData', () => {
});
});

describe('useContentTaxonomyTagsCount', () => {
it('should return success response', () => {
useQuery.mockReturnValueOnce({ isSuccess: true, data: 'data' });
const contentId = '123';
const result = useContentTaxonomyTagsCount(contentId);

expect(result).toEqual({ isSuccess: true, data: 'data' });
});

it('should return failure response', () => {
useQuery.mockReturnValueOnce({ isSuccess: false });
const contentId = '123';
const result = useContentTaxonomyTagsCount(contentId);

expect(result).toEqual({ isSuccess: false });
});
});

describe('useContentData', () => {
it('should return success response', () => {
useQuery.mockReturnValueOnce({ isSuccess: true, data: 'data' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import { Stack } from '@openedx/paragon';
import { useParams } from 'react-router-dom';
import { useIntl } from '@edx/frontend-platform/i18n';

import { useContentTagsCount } from '../../generic/data/apiHooks';
import messages from '../messages';
import { useContentTaxonomyTagsCount } from '../data/apiHooks';
import TagCount from '../../generic/tag-count';

const TagsSidebarHeader = () => {
const intl = useIntl();
const contentId = useParams().blockId;

const {
data: contentTaxonomyTagsCount,
isSuccess: isContentTaxonomyTagsCountLoaded,
} = useContentTaxonomyTagsCount(contentId || '');
data: contentTagsCount,
isSuccess: isContentTagsCountLoaded,
} = useContentTagsCount(contentId || '');

return (
<Stack
Expand All @@ -25,8 +25,8 @@ const TagsSidebarHeader = () => {
<h3 className="course-unit-sidebar-header-title m-0">
{intl.formatMessage(messages.tagsSidebarTitle)}
</h3>
{ isContentTaxonomyTagsCountLoaded
&& <TagCount count={contentTaxonomyTagsCount} />}
{ isContentTagsCountLoaded
&& <TagCount count={contentTagsCount} />}
</Stack>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import TagsSidebarHeader from './TagsSidebarHeader';
import { useContentTaxonomyTagsCount } from '../data/apiHooks';

jest.mock('../data/apiHooks', () => ({
useContentTaxonomyTagsCount: jest.fn(() => ({
isSuccess: false,
data: 17,
})),
const mockGetTagsCount = jest.fn();

jest.mock('../../generic/data/api', () => ({
...jest.requireActual('../../generic/data/api'),
getTagsCount: () => mockGetTagsCount(),
}));

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: () => ({ blockId: '123' }),
}));

const queryClient = new QueryClient();

const RootWrapper = () => (
<IntlProvider locale="en" messages={{}}>
<TagsSidebarHeader />
<QueryClientProvider client={queryClient}>
<TagsSidebarHeader />
</QueryClientProvider>
</IntlProvider>
);

describe('<TagsSidebarHeader>', () => {
it('should not render count on loading', () => {
it('should render count only after query is complete', async () => {
let resolvePromise;
mockGetTagsCount.mockReturnValueOnce(new Promise((resolve) => { resolvePromise = resolve; }));
render(<RootWrapper />);
expect(screen.getByRole('heading', { name: /unit tags/i })).toBeInTheDocument();
expect(screen.queryByText('17')).not.toBeInTheDocument();
});

it('should render count after query is complete', () => {
useContentTaxonomyTagsCount.mockReturnValue({
isSuccess: true,
data: 17,
});
render(<RootWrapper />);
expect(screen.getByRole('heading', { name: /unit tags/i })).toBeInTheDocument();
expect(screen.getByText('17')).toBeInTheDocument();
resolvePromise({ 123: 17 });
expect(await screen.findByText('17')).toBeInTheDocument();
});
});
1 change: 0 additions & 1 deletion src/course-outline/__mocks__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ export { default as courseBestPracticesMock } from './courseBestPractices';
export { default as courseLaunchMock } from './courseLaunch';
export { default as courseSectionMock } from './courseSection';
export { default as courseSubsectionMock } from './courseSubsection';
export { default as contentTagsCountMock } from './contentTagsCount';
2 changes: 1 addition & 1 deletion src/course-outline/card-header/CardHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
EditOutline as EditIcon,
} from '@openedx/paragon/icons';

import { useContentTagsCount } from '../data/apiHooks';
import { useContentTagsCount } from '../../generic/data/apiHooks';
import { ContentTagsDrawer } from '../../content-tags-drawer';
import TagCount from '../../generic/tag-count';
import { useEscapeClick } from '../../hooks';
Expand Down
4 changes: 2 additions & 2 deletions src/course-outline/card-header/CardHeader.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const closeFormMock = jest.fn();

const mockGetTagsCount = jest.fn();

jest.mock('../data/api', () => ({
...jest.requireActual('../data/api'),
jest.mock('../../generic/data/api', () => ({
...jest.requireActual('../../generic/data/api'),
getTagsCount: () => mockGetTagsCount(),
}));

Expand Down
16 changes: 0 additions & 16 deletions src/course-outline/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export const getXBlockBaseApiUrl = () => `${getApiBaseUrl()}/xblock/`;
export const getCourseItemApiUrl = (itemId) => `${getXBlockBaseApiUrl()}${itemId}`;
export const getXBlockApiUrl = (blockId) => `${getXBlockBaseApiUrl()}outline/${blockId}`;
export const getClipboardUrl = () => `${getApiBaseUrl()}/api/content-staging/v1/clipboard/`;
export const getTagsCountApiUrl = (contentPattern) => new URL(`api/content_tagging/v1/object_tag_counts/${contentPattern}/?count_implicit`, getApiBaseUrl()).href;

/**
* @typedef {Object} courseOutline
Expand Down Expand Up @@ -473,18 +472,3 @@ export async function dismissNotification(url) {
await getAuthenticatedHttpClient()
.delete(url);
}

/**
* Gets the tags count of multiple content by id separated by commas.
* @param {string} contentPattern
* @returns {Promise<Object>}
*/
export async function getTagsCount(contentPattern) {
if (contentPattern) {
const { data } = await getAuthenticatedHttpClient()
.get(getTagsCountApiUrl(contentPattern));

return data;
}
return null;
}
40 changes: 0 additions & 40 deletions src/course-outline/data/api.test.js

This file was deleted.

25 changes: 0 additions & 25 deletions src/course-outline/data/apiHooks.jsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/course-outline/status-bar/StatusBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ContentTagsDrawer } from '../../content-tags-drawer';
import TagCount from '../../generic/tag-count';
import { useHelpUrls } from '../../help-urls/hooks';
import { VIDEO_SHARING_OPTIONS } from '../constants';
import { useContentTagsCount } from '../data/apiHooks';
import { useContentTagsCount } from '../../generic/data/apiHooks';
import messages from './messages';
import { getVideoSharingOptionText } from '../utils';

Expand Down
4 changes: 2 additions & 2 deletions src/course-outline/status-bar/StatusBar.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ jest.mock('react-router-dom', () => ({
}),
}));

jest.mock('../data/api', () => ({
...jest.requireActual('../data/api'),
jest.mock('../../generic/data/api', () => ({
...jest.requireActual('../../generic/data/api'),
getTagsCount: jest.fn().mockResolvedValue({ 'course-v1:123': 17 }),
}));

Expand Down
2 changes: 1 addition & 1 deletion src/course-unit/CourseUnit.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jest.mock('@tanstack/react-query', () => ({
},
isSuccess: true,
};
} if (queryKey[0] === 'contentTaxonomyTagsCount') {
} if (queryKey[0] === 'contentTagsCount') {
return {
data: 17,
isSuccess: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default {
'block-v1:SampleTaxonomyOrg1+STC1+2023_1+type@vertical+block@aaf8b8eb86b54281aeeab12499d2cb01': 10,
'block-v1:SampleTaxonomyOrg1+STC1+2023_1+type@vertical+block@aaf8b8eb86b54281aeeab12499d2cb02': 11,
'block-v1:SampleTaxonomyOrg1+STC1+2023_1+type@vertical+block@aaf8b8eb86b54281aeeab12499d2cb03': 12,
Expand Down
2 changes: 2 additions & 0 deletions src/generic/__mocks__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint-disable import/prefer-default-export */
export { default as contentTagsCountMock } from './contentTagsCount';
16 changes: 16 additions & 0 deletions src/generic/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}
18 changes: 18 additions & 0 deletions src/generic/data/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ 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,
getOrganizations,
getCreateOrRerunCourseUrl,
getCourseRerunUrl,
getCourseRerun,
getTagsCount,
getTagsCountApiUrl,
} from './api';

let axiosMock;
Expand Down Expand Up @@ -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);
});
});
Loading

0 comments on commit a9fd664

Please sign in to comment.