Add user affiliations to Library page to fix affiliation widget on Commons (#36522)

* load affiliations data when rendering library page

* address Copilot review feedback on PR #36522

- default userAffiliations to [] if getUserFullEmails fails, matching
  ProjectListController's error handling, so Library/Trash still render
  when the institutions service is unavailable
- stop mutating the affiliation object when attaching the email
- rename a misleading test title (affiliation is not necessarily confirmed)
- fix sidebar-ds-nav "hides the widget" tests: they were only waiting for
  the /api/project fetch to be called, not for the project list state to
  settle, so they passed even before the affiliations check ran

GitOrigin-RevId: 7d04ae7f7dc8d1526c2deb8959099f6e9fe9c4ee
This commit is contained in:
Maria Florencia Besteiro Gonzalez
2026-09-17 11:56:03 +00:00
committed by Copybot
parent 531718c874
commit 173081aa6f
@@ -1,12 +1,20 @@
import { screen, waitFor } from '@testing-library/react'
import { expect } from 'chai'
import fetchMock from 'fetch-mock'
import SidebarDsNav from '../../../../../../frontend/js/features/project-list/components/sidebar/sidebar-ds-nav'
import {
renderWithProjectListContext,
resetProjectListContextFetch,
} from '../../helpers/render-with-context'
import { UserSettingsProvider } from '@/shared/context/user-settings-context'
import { useProjectListContext } from '@/features/project-list/context/project-list-context'
import { Affiliation } from '../../../../../../types/affiliation'
function ProjectListLoadingProbe() {
const { isLoading } = useProjectListContext()
return (
<div data-testid="project-list-loading-probe" data-loading={isLoading} />
)
}
async function renderSidebar(props: {
activePage: 'library' | 'projects'
@@ -15,10 +23,16 @@ async function renderSidebar(props: {
renderWithProjectListContext(
<UserSettingsProvider>
<SidebarDsNav {...props} />
<ProjectListLoadingProbe />
</UserSettingsProvider>
)
await waitFor(
() => expect(fetchMock.callHistory.called('/api/project')).to.be.true
// Wait for the projects fetch to resolve and the project list state (which
// the "add affiliation" widget's visibility partly depends on) to settle,
// not just for the request to have been made.
await waitFor(() =>
expect(
screen.getByTestId('project-list-loading-probe').dataset.loading
).to.equal('false')
)
}
@@ -77,4 +91,40 @@ describe('<SidebarDsNav />', function () {
screen.getByRole('button', { name: 'Trash' }).getAttribute('aria-current')
).to.be.null
})
describe('add affiliation widget', function () {
it('shows the widget on the library page when the user has no affiliations', async function () {
window.metaAttributesCache.set('ol-userAffiliations', [])
await renderSidebar({ activePage: 'library' })
await screen.findByText(/are you affiliated with an institution/i)
})
it('shows the widget on the projects page when the user has no affiliations', async function () {
window.metaAttributesCache.set('ol-userAffiliations', [])
await renderSidebar({ activePage: 'projects' })
await screen.findByText(/are you affiliated with an institution/i)
})
it('hides the widget on the library page when the user has affiliations', async function () {
window.metaAttributesCache.set('ol-userAffiliations', [{} as Affiliation])
await renderSidebar({ activePage: 'library' })
expect(screen.queryByText(/are you affiliated with an institution/i)).to
.be.null
})
it('hides the widget on the projects page when the user has affiliations', async function () {
window.metaAttributesCache.set('ol-userAffiliations', [{} as Affiliation])
await renderSidebar({ activePage: 'projects' })
expect(screen.queryByText(/are you affiliated with an institution/i)).to
.be.null
})
})
})