Skip to content

Commit

Permalink
fix: display research draft updates for author
Browse files Browse the repository at this point in the history
  • Loading branch information
mariojsnunes committed May 24, 2024
1 parent 0ae5bd2 commit 1d4379f
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 162 deletions.
37 changes: 21 additions & 16 deletions src/pages/Research/Content/ResearchArticle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,25 @@ import {
UsefulStatsButton,
UserEngagementWrapper,
} from 'oa-components'
import { IModerationStatus, ResearchUpdateStatus } from 'oa-shared'
import { IModerationStatus } from 'oa-shared'
import { trackEvent } from 'src/common/Analytics'
import { useContributorsData } from 'src/common/hooks/contributorsData'
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { Breadcrumbs } from 'src/pages/common/Breadcrumbs/Breadcrumbs'
import { NotFoundPage } from 'src/pages/NotFound/NotFound'
import { useResearchStore } from 'src/stores/Research/research.store'
import {
getPublicUpdates,
getResearchTotalCommentCount,
isAllowedToDeleteContent,
isAllowedToEditContent,
} from 'src/utils/helpers'
import { seoTagsUpdate } from 'src/utils/seo'
import { Box, Flex } from 'theme-ui'

import {
getPublicUpdates,
getResearchTotalCommentCount,
researchUpdateStatusFilter,
} from '../researchHelpers'
import { researchCommentUrlPattern } from './helper'
import ResearchDescription from './ResearchDescription'
import ResearchUpdate from './ResearchUpdate'
Expand Down Expand Up @@ -217,23 +220,25 @@ const ResearchArticle = observer(() => {
subscribersCount={researchStore.subscribersCount}
commentsCount={getResearchTotalCommentCount(item)}
updatesCount={
item.updates?.filter(
(u) => u.status !== ResearchUpdateStatus.DRAFT && !u._deleted,
item.updates?.filter((u) =>
researchUpdateStatusFilter(item, u, researchStore.activeUser?._id),
).length || 0
}
/>
<Box sx={{ marginTop: 8, marginBottom: 4 }}>
{item &&
getPublicUpdates(item).map((update, index) => (
<ResearchUpdate
update={update}
key={update._id}
updateIndex={index}
isEditable={isEditable}
slug={item.slug}
showComments={areCommentVisible(index)}
/>
))}
getPublicUpdates(item, researchStore.activeUser?._id).map(
(update, index) => (
<ResearchUpdate
update={update}
key={update._id}
updateIndex={index}
isEditable={isEditable}
slug={item.slug}
showComments={areCommentVisible(index)}
/>
),
)}
</Box>

<UserEngagementWrapper>
Expand Down Expand Up @@ -267,7 +272,7 @@ const ResearchArticle = observer(() => {
isLoggedIn={!!loggedInUser}
hasUserSubscribed={researchStore.userHasSubscribed}
onFollowClick={() => onFollowClick(item.slug)}
></FollowButton>
/>
</ArticleCallToAction>
)}
</Box>
Expand Down
3 changes: 2 additions & 1 deletion src/pages/Research/Content/ResearchDescription.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import { IModerationStatus } from 'oa-shared'
import { trackEvent } from 'src/common/Analytics'
import { logger } from 'src/logger'
import { useResearchStore } from 'src/stores/Research/research.store'
import { buildStatisticsLabel, researchStatusColour } from 'src/utils/helpers'
import { buildStatisticsLabel } from 'src/utils/helpers'
import { incrementViewCount } from 'src/utils/incrementViewCount'
import { Box, Card, Divider, Flex, Heading, Text } from 'theme-ui'

import { ContentAuthorTimestamp } from '../../common/ContentAuthorTimestamp/ContentAuthorTimestamp'
import { researchStatusColour } from '../researchHelpers'

import type { ITag } from 'src/models'
import type { IResearch } from 'src/models/research.models'
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Research/Content/ResearchListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import {
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { cdnImageUrl } from 'src/utils/cdnImageUrl'
import { formatDate } from 'src/utils/date'
import { getPublicUpdates, researchStatusColour } from 'src/utils/helpers'
import { Box, Card, Flex, Grid, Heading, Image, Text } from 'theme-ui'

import defaultResearchThumbnail from '../../../assets/images/default-research-thumbnail.jpg'
import { getPublicUpdates, researchStatusColour } from '../researchHelpers'

import type { IResearch } from 'src/models/research.models'
import type { IUploadedFileMeta } from 'src/stores/storage'
Expand Down
180 changes: 180 additions & 0 deletions src/pages/Research/researchHelpers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { ResearchUpdateStatus } from 'oa-shared'
import { FactoryResearchItemUpdate } from 'src/test/factories/ResearchItem'

import {
getResearchTotalCommentCount,
researchUpdateStatusFilter,
} from './researchHelpers'

import type { IResearch } from 'src/models'

describe('Research Helpers', () => {
describe('getResearchTotalCommentCount Function', () => {
it('should return 0 when item has no updates', () => {
const item = { item: {} } as any
expect(getResearchTotalCommentCount(item)).toBe(0)
})

it('should return 0 when updates have no comments', () => {
const item = {
updates: Array.from({ length: 3 }).fill(
FactoryResearchItemUpdate({
status: ResearchUpdateStatus.PUBLISHED,
_deleted: false,
}),
),
} as IResearch.ItemDB
expect(getResearchTotalCommentCount(item)).toBe(0)
})

it('should use totalCommentCount if present', () => {
const item = {
totalCommentCount: 5,
updates: Array.from({ length: 3 }).fill(
FactoryResearchItemUpdate({
status: ResearchUpdateStatus.PUBLISHED,
_deleted: false,
}),
),
} as IResearch.ItemDB
expect(getResearchTotalCommentCount(item)).toBe(5)
})

it('should use totalCommentCount when 0', () => {
const item = {
totalCommentCount: 0,
updates: Array.from({ length: 3 }).fill(
FactoryResearchItemUpdate({
status: ResearchUpdateStatus.PUBLISHED,
_deleted: false,
}),
),
} as IResearch.ItemDB
expect(getResearchTotalCommentCount(item)).toBe(0)
})

it('should return the correct amount of comments', () => {
const item = {
updates: Array.from({ length: 3 }).fill(
FactoryResearchItemUpdate({
status: ResearchUpdateStatus.PUBLISHED,
_deleted: false,
comments: Array.from({ length: 3 }),
}),
),
} as IResearch.ItemDB
expect(getResearchTotalCommentCount(item)).toBe(9)
})

it('should ignore deleted and draft updates', () => {
const item = {
updates: Array.from({ length: 2 })
.fill(
FactoryResearchItemUpdate({
status: ResearchUpdateStatus.PUBLISHED,
_deleted: false,
comments: Array.from({ length: 2 }),
}),
)
.concat([
FactoryResearchItemUpdate({
status: ResearchUpdateStatus.PUBLISHED,
_deleted: true,
comments: Array.from({ length: 3 }),
}),
FactoryResearchItemUpdate({
status: ResearchUpdateStatus.DRAFT,
_deleted: false,
comments: Array.from({ length: 6 }),
}),
]),
} as IResearch.ItemDB
expect(getResearchTotalCommentCount(item)).toBe(4)
})
})

describe('Research Update Status Filter', () => {
it('should not show item when deleted', async () => {
// prepare
const authorId = 'author'
const item = { _createdBy: authorId } as IResearch.Item
const update = { _deleted: true } as IResearch.Update

// act
const show = researchUpdateStatusFilter(item, update, authorId)

// assert
expect(show).toEqual(false)
})

it('should not show item when deleted and draft', async () => {
// prepare
const authorId = 'author'
const item = { _createdBy: authorId } as IResearch.Item
const update = {
_deleted: true,
status: ResearchUpdateStatus.DRAFT,
} as IResearch.Update

// act
const show = researchUpdateStatusFilter(item, update, authorId)

// assert
expect(show).toEqual(false)
})

it('should not show when draft and not author', async () => {
// prepare
const authorId = 'author'
const item = { _createdBy: authorId } as IResearch.Item
const update = { status: ResearchUpdateStatus.DRAFT } as IResearch.Update

// act
const show = researchUpdateStatusFilter(item, update, 'not-author')

// assert
expect(show).toEqual(false)
})

it('should not show when draft and not authenticated', async () => {
// prepare
const authorId = 'author'
const item = { _createdBy: authorId } as IResearch.Item
const update = { status: ResearchUpdateStatus.DRAFT } as IResearch.Update

// act
const show = researchUpdateStatusFilter(item, update)

// assert
expect(show).toEqual(false)
})

it('should show when not draft and not deleted', async () => {
// prepare
const authorId = 'author'
const item = { _createdBy: authorId } as IResearch.Item
const update = {
status: ResearchUpdateStatus.PUBLISHED,
} as IResearch.Update

// act
const show = researchUpdateStatusFilter(item, update)

// assert
expect(show).toEqual(true)
})

it('should show when draft and current user is the author', async () => {
// prepare
const authorId = 'author'
const item = { _createdBy: authorId } as IResearch.Item
const update = { status: ResearchUpdateStatus.DRAFT } as IResearch.Update

// act
const show = researchUpdateStatusFilter(item, update, authorId)

// assert
expect(show).toEqual(true)
})
})
})
62 changes: 62 additions & 0 deletions src/pages/Research/researchHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { ResearchStatus, ResearchUpdateStatus } from 'oa-shared'

import type { IResearch } from 'src/models'

export const getResearchTotalCommentCount = (
item: IResearch.ItemDB,
): number => {
if (Object.hasOwnProperty.call(item, 'totalCommentCount')) {
return item.totalCommentCount || 0
}

if (item.updates) {
const commentOnUpdates = item.updates.reduce((totalComments, update) => {
const updateCommentsLength =
!update._deleted &&
update.status !== ResearchUpdateStatus.DRAFT &&
update.comments
? update.comments.length
: 0
return totalComments + updateCommentsLength
}, 0)

return commentOnUpdates ? commentOnUpdates : 0
} else {
return 0
}
}

export const researchUpdateStatusFilter = (
item: IResearch.Item,
update: IResearch.Update,
currentUserId?: string,
) => {
return (
(item._createdBy === currentUserId ||
update.status !== ResearchUpdateStatus.DRAFT) &&
!update._deleted
)
}

export const getPublicUpdates = (
item: IResearch.Item,
currentUserId?: string,
) => {
if (item.updates) {
return item.updates.filter((update) =>
researchUpdateStatusFilter(item, update, currentUserId),
)
} else {
return []
}
}

export const researchStatusColour = (
researchStatus?: ResearchStatus,
): string => {
return researchStatus === ResearchStatus.ARCHIVED
? 'lightgrey'
: researchStatus === ResearchStatus.COMPLETED
? 'betaGreen'
: 'accent.base'
}
Loading

0 comments on commit 1d4379f

Please sign in to comment.