Skip to content

Commit

Permalink
ASAP-21 (GP2) Add tags to news (#4218)
Browse files Browse the repository at this point in the history
  • Loading branch information
gabiayako authored Apr 3, 2024
1 parent a3d674f commit f192684
Show file tree
Hide file tree
Showing 21 changed files with 443 additions and 215 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/reusable-gp2-algolia-sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Re-Build
uses: ./.github/actions/build-rebuild
- name: Cache build typecheck output
uses: ./.github/actions/cache-unplugged
with:
Expand Down
6 changes: 3 additions & 3 deletions apps/gp2-frontend/src/news/NewsList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NewsItem, EmptyState, noNewsIcon } from '@asap-hub/gp2-components';
import { ResultList } from '@asap-hub/react-components';
import { EmptyState, noNewsIcon } from '@asap-hub/gp2-components';
import { NewsCard, ResultList } from '@asap-hub/react-components';
import { useNews } from './state';
import { usePagination, usePaginationParams } from '../hooks/pagination';

Expand All @@ -26,7 +26,7 @@ const NewsList: React.FC<NewsListProps> = ({ searchQuery, filters }) => {
renderPageHref={renderPageHref}
>
{items.map((news) => (
<NewsItem key={news.id} {...news} />
<NewsCard {...news} key={news.id} type="News" />
))}
</ResultList>
) : (
Expand Down
5 changes: 5 additions & 0 deletions apps/gp2-frontend/src/tags/ResultList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { gp2 as gp2Model } from '@asap-hub/model';
import {
EventCard,
NewsCard,
ResultList as ResultListComponent,
} from '@asap-hub/react-components';
import { eventMapper } from '../events/EventsList';
Expand Down Expand Up @@ -67,6 +68,10 @@ const ResultList: React.FC<ResultListProps> = ({ filters = new Set() }) => {
const tagData = data.tags.map((tag) => tag.name);
return <UserCard key={result.id} {...data} tags={tagData} />;
}
case 'news': {
const data = result as gp2Model.NewsResponse;
return <NewsCard {...data} key={data.id} type="News" />;
}
default:
return '';
}
Expand Down
29 changes: 25 additions & 4 deletions apps/gp2-frontend/src/tags/__tests__/ResultList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ClientSearchResponse } from '@asap-hub/algolia';
import {
render,
screen,
Expand Down Expand Up @@ -91,14 +92,34 @@ describe('ResultList', () => {
expect(screen.getByRole('link', { name: 'Output 1' })).toBeInTheDocument();
});

it('does not render unsupported types', async () => {
it('renders news', async () => {
mockGetTagSearchResults.mockResolvedValue(
createNewsListAlgoliaResponse(1, 1),
);
await renderList({}, 'test');
expect(screen.getByText('News Item')).toBeInTheDocument();
});

it('does not render unsupported types', async () => {
const response = createAlgoliaResponse<'external-user'>([
{
__meta: { type: 'external-user' },
displayName: 'John Doe',
id: 'external-1',
objectID: '1',
},
]);

mockGetTagSearchResults.mockResolvedValue(
response as unknown as ClientSearchResponse<
'gp2',
'output' | 'event' | 'user' | 'news' | 'project'
>,
);

await renderList({ filters: new Set() }, 'test');
expect(
screen.queryByRole('link', { name: 'News 1' }),
).not.toBeInTheDocument();

expect(screen.queryByText('John Doe')).not.toBeInTheDocument();
});

it('renders empty state', async () => {
Expand Down
3 changes: 3 additions & 0 deletions apps/gp2-server/src/data-providers/news.data-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,7 @@ export const parseGraphQlNews = (item: NewsItem): gp2Model.NewsDataObject => ({
linkText: item.linkText ?? undefined,
created: item.publishDate,
type: item.type as gp2Model.NewsType,
tags:
item.tagsCollection?.items.map((tag) => tag?.name || '').filter(Boolean) ||
[],
});
12 changes: 12 additions & 0 deletions apps/gp2-server/test/data-providers/news.data-provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ describe('News data provider', () => {
);
});

describe('tags', () => {
test('should return empty list when tagsCollection is null', async () => {
const newsResponse = getContentfulNewsGraphqlResponse();
newsResponse.newsCollection!.items[0]!.tagsCollection = null;

contentfulGraphqlClientMock.request.mockResolvedValueOnce(newsResponse);
const result = await newsDataProvider.fetch();

expect(result.items[0]!.tags).toEqual([]);
});
});

describe('Search', () => {
test('Should query data properly when passing search param', async () => {
contentfulGraphqlClientMock.request.mockResolvedValueOnce(
Expand Down
3 changes: 3 additions & 0 deletions apps/gp2-server/test/fixtures/news.fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '@asap-hub/model';
import { EventBridgeEvent, SQSEvent, SQSRecord } from 'aws-lambda';
import { createEventBridgeEventMock } from '../helpers/events';
import { getContentfulTagsCollectionGraphqlResponse } from './tag.fixtures';

export const getContentfulGraphqlNews = (): NonNullable<
NonNullable<gp2Contentful.FetchNewsQuery['newsCollection']>['items'][number]
Expand All @@ -27,6 +28,7 @@ export const getContentfulGraphqlNews = (): NonNullable<
},
publishDate: '2021-12-28T00:00:00.000Z',
type: 'news',
tagsCollection: { ...getContentfulTagsCollectionGraphqlResponse() },
});

export const getContentfulNewsGraphqlResponse =
Expand All @@ -46,6 +48,7 @@ export const getNewsDataObject = (): gp2Model.NewsDataObject => ({
link: 'http://example.com/a-link',
linkText: 'some link text',
type: 'news',
tags: ['tag-1'],
});

export const getListNewsDataObject = (): gp2Model.ListNewsDataObject => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module.exports.description = 'Add tags to news content model';

module.exports.up = (migration) => {
const news = migration.editContentType('news');

news
.createField('tags')
.name('Tags')
.type('Array')
.localized(false)
.required(false)
.validations([])
.disabled(false)
.omitted(false)
.items({
type: 'Link',

validations: [
{
linkContentType: ['tags'],
},
],

linkType: 'Entry',
});

news.moveField('tags').afterField('linkText');
};

module.exports.down = (migration) => {
migration.editContentType('news').deleteField('tags');
};
6 changes: 3 additions & 3 deletions packages/contentful/src/gp2/autogenerated-gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const documents = {
types.FetchExternalUsersDocument,
'\n query FetchExternalUserById($id: String!) {\n externalUsers(id: $id) {\n ...ExternalUsersContentData\n }\n }\n \n':
types.FetchExternalUserByIdDocument,
'\n fragment NewsContentData on News {\n sys {\n id\n firstPublishedAt\n }\n title\n shortText\n thumbnail {\n url\n }\n link\n linkText\n publishDate\n type\n }\n':
'\n fragment NewsContentData on News {\n sys {\n id\n firstPublishedAt\n }\n title\n shortText\n thumbnail {\n url\n }\n tagsCollection(limit: 20) {\n total\n items {\n sys {\n id\n }\n name\n }\n }\n link\n linkText\n publishDate\n type\n }\n':
types.NewsContentDataFragmentDoc,
'\n query FetchNewsById($id: String!) {\n news(id: $id) {\n ...NewsContentData\n }\n }\n \n':
types.FetchNewsByIdDocument,
Expand Down Expand Up @@ -245,8 +245,8 @@ export function gql(
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function gql(
source: '\n fragment NewsContentData on News {\n sys {\n id\n firstPublishedAt\n }\n title\n shortText\n thumbnail {\n url\n }\n link\n linkText\n publishDate\n type\n }\n',
): (typeof documents)['\n fragment NewsContentData on News {\n sys {\n id\n firstPublishedAt\n }\n title\n shortText\n thumbnail {\n url\n }\n link\n linkText\n publishDate\n type\n }\n'];
source: '\n fragment NewsContentData on News {\n sys {\n id\n firstPublishedAt\n }\n title\n shortText\n thumbnail {\n url\n }\n tagsCollection(limit: 20) {\n total\n items {\n sys {\n id\n }\n name\n }\n }\n link\n linkText\n publishDate\n type\n }\n',
): (typeof documents)['\n fragment NewsContentData on News {\n sys {\n id\n firstPublishedAt\n }\n title\n shortText\n thumbnail {\n url\n }\n tagsCollection(limit: 20) {\n total\n items {\n sys {\n id\n }\n name\n }\n }\n link\n linkText\n publishDate\n type\n }\n'];
/**
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
Loading

0 comments on commit f192684

Please sign in to comment.