feat(admin): add pending tag suggestions detector
This commit is contained in:
parent
ab3f0a8b39
commit
0dc1b6ddbc
2 changed files with 72 additions and 0 deletions
|
|
@ -226,4 +226,35 @@ export async function detectEventsNearCapacity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function detectPendingTagSuggestions() {
|
||||||
|
await connectDB()
|
||||||
|
const suggestions = await TagSuggestion
|
||||||
|
.find({ status: 'pending' })
|
||||||
|
.select('_id')
|
||||||
|
.lean()
|
||||||
|
if (suggestions.length === 0) {
|
||||||
|
return {
|
||||||
|
type: 'tag_suggestions_pending',
|
||||||
|
severity: 'attention',
|
||||||
|
title: 'Pending tag suggestions',
|
||||||
|
items: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'tag_suggestions_pending',
|
||||||
|
severity: 'attention',
|
||||||
|
title: 'Pending tag suggestions',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: 'tag-suggestions',
|
||||||
|
label: `${suggestions.length} pending tag suggestion${suggestions.length === 1 ? '' : 's'}`,
|
||||||
|
sublabel: 'Review and approve in Tags',
|
||||||
|
href: '/admin/tags'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// signature is computed from the underlying suggestion ids, not the rendered item id
|
||||||
|
signatureIds: suggestions.map((s) => String(s._id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Aggregator lands in task 8.
|
// Aggregator lands in task 8.
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ import {
|
||||||
import Member from '../../../server/models/member.js'
|
import Member from '../../../server/models/member.js'
|
||||||
import PreRegistration from '../../../server/models/preRegistration.js'
|
import PreRegistration from '../../../server/models/preRegistration.js'
|
||||||
import Event from '../../../server/models/event.js'
|
import Event from '../../../server/models/event.js'
|
||||||
|
import { detectPendingTagSuggestions } from '../../../server/utils/adminAlerts.js'
|
||||||
|
import TagSuggestion from '../../../server/models/tagSuggestion.js'
|
||||||
|
|
||||||
describe('adminAlerts module shell', () => {
|
describe('adminAlerts module shell', () => {
|
||||||
describe('ALERT_THRESHOLDS', () => {
|
describe('ALERT_THRESHOLDS', () => {
|
||||||
|
|
@ -349,4 +351,43 @@ describe('adminAlerts module shell', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('tag suggestion alert', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
function mockTagSuggestionFind(result) {
|
||||||
|
TagSuggestion.find.mockReturnValue({
|
||||||
|
select: vi.fn().mockReturnValue({
|
||||||
|
lean: vi.fn().mockResolvedValue(result)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
it('returns a single aggregated item with the count', async () => {
|
||||||
|
mockTagSuggestionFind([
|
||||||
|
{ _id: 't1' }, { _id: 't2' }, { _id: 't3' }
|
||||||
|
])
|
||||||
|
|
||||||
|
const alert = await detectPendingTagSuggestions()
|
||||||
|
|
||||||
|
expect(alert.type).toBe('tag_suggestions_pending')
|
||||||
|
expect(alert.severity).toBe('attention')
|
||||||
|
expect(alert.items).toHaveLength(1)
|
||||||
|
expect(alert.items[0]).toEqual({
|
||||||
|
id: 'tag-suggestions',
|
||||||
|
label: '3 pending tag suggestions',
|
||||||
|
sublabel: 'Review and approve in Tags',
|
||||||
|
href: '/admin/tags'
|
||||||
|
})
|
||||||
|
expect(TagSuggestion.find).toHaveBeenCalledWith({ status: 'pending' })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns an empty list when nothing is pending', async () => {
|
||||||
|
mockTagSuggestionFind([])
|
||||||
|
const alert = await detectPendingTagSuggestions()
|
||||||
|
expect(alert.items).toEqual([])
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue