test today's dashboard work

This commit is contained in:
Yisroel Baum 2026-08-15 21:54:42 +03:00
parent 483ca6fc1d
commit 1c83eb1b84
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
5 changed files with 184 additions and 3 deletions

View file

@ -17,6 +17,12 @@ describe('email confirmation', () => {
statusCode: 200, statusCode: 200,
body: { schedules: [] }, body: { schedules: [] },
}) })
cy.intercept('GET', '**/api/assignments?date=*', (request) => {
request.reply({
statusCode: 200,
body: { date: request.query.date, assignments: [] },
})
})
}) })
it('chooses a password, confirms the account, and opens the dashboard', () => { it('chooses a password, confirms the account, and opens the dashboard', () => {
@ -39,7 +45,7 @@ describe('email confirmation', () => {
cy.wait('@confirmEmail') cy.wait('@confirmEmail')
cy.location('pathname').should('equal', '/dashboard') cy.location('pathname').should('equal', '/dashboard')
cy.get('h1').should('have.text', 'Available sets') cy.get('#sets-heading').should('have.text', 'Available sets')
}) })
it('validates password length and confirmation before submitting', () => { it('validates password length and confirmation before submitting', () => {

View file

@ -47,6 +47,12 @@ describe('session authentication', () => {
statusCode: 200, statusCode: 200,
body: { schedules: [] }, body: { schedules: [] },
}) })
cy.intercept('GET', '**/api/assignments?date=*', (request) => {
request.reply({
statusCode: 200,
body: { date: request.query.date, assignments: [] },
})
})
}) })
it('restores an authenticated session on a protected route', () => { it('restores an authenticated session on a protected route', () => {
@ -59,7 +65,7 @@ describe('session authentication', () => {
cy.wait('@me') cy.wait('@me')
cy.location('pathname').should('equal', '/dashboard') cy.location('pathname').should('equal', '/dashboard')
cy.get('h1').should('have.text', 'Available sets') cy.get('#sets-heading').should('have.text', 'Available sets')
}) })
it('redirects an unauthenticated protected route to login', () => { it('redirects an unauthenticated protected route to login', () => {

View file

@ -250,6 +250,12 @@ describe('set scheduling', () => {
}, },
}) })
}).as('schedules') }).as('schedules')
cy.intercept('GET', '**/api/assignments?date=*', (request) => {
request.reply({
statusCode: 200,
body: { date: request.query.date, assignments: [] },
})
})
cy.visit('/dashboard') cy.visit('/dashboard')
cy.wait('@me') cy.wait('@me')

View file

@ -17,6 +17,12 @@ describe('sets dashboard', () => {
statusCode: 200, statusCode: 200,
body: { schedules: [] }, body: { schedules: [] },
}) })
cy.intercept('GET', '**/api/assignments?date=*', (request) => {
request.reply({
statusCode: 200,
body: { date: request.query.date, assignments: [] },
})
})
}) })
it('shows every available set as a detail link', () => { it('shows every available set as a detail link', () => {
@ -38,7 +44,7 @@ describe('sets dashboard', () => {
cy.wait('@me') cy.wait('@me')
cy.wait('@sets') cy.wait('@sets')
cy.get('h1').should('have.text', 'Available sets') cy.get('#sets-heading').should('have.text', 'Available sets')
cy.get('ul[aria-label="Available sets"] h2').then(($headings) => { cy.get('ul[aria-label="Available sets"] h2').then(($headings) => {
expect([...$headings].map((heading) => heading.textContent)).to.deep.equal([ expect([...$headings].map((heading) => heading.textContent)).to.deep.equal([
'Bible', 'Bible',

View file

@ -0,0 +1,157 @@
const authenticatedUser = {
id: 7,
email: 'user@example.com',
}
const browserToday = '2026-08-15'
function interceptDashboardRequests(): void {
cy.intercept('GET', '**/api/me', {
statusCode: 200,
body: { user: authenticatedUser },
}).as('me')
cy.intercept('GET', '**/api/sets', {
statusCode: 200,
body: { sets: [] },
}).as('sets')
cy.intercept('GET', '**/api/schedules', {
statusCode: 200,
body: { schedules: [] },
}).as('schedules')
}
describe("today's assignments", () => {
beforeEach(() => {
cy.clock(new Date(2026, 7, 15, 0, 30).getTime())
interceptDashboardRequests()
})
it('uses the browser date and links every assignment to its schedule', () => {
cy.intercept('GET', `**/api/assignments?date=${browserToday}`, (request) => {
expect(request.headers.accept).to.equal('application/json')
request.reply({
statusCode: 200,
body: {
date: browserToday,
assignments: [
{
id: 12,
schedule: {
id: 73,
set: { name: 'Bible' },
},
element: {
name: 'Chapter 1',
kind: 'Chapter_sections-v2',
path: ['Genesis', 'Creation', 'Chapter 1'],
},
},
{
id: 13,
schedule: {
id: 81,
set: { name: 'Course' },
},
element: {
name: 'Introduction',
kind: 'lesson',
path: ['Introduction'],
},
},
],
},
})
}).as('todayAssignments')
cy.visit('/dashboard')
cy.wait('@me')
cy.wait('@todayAssignments')
cy.get('#today-heading').should('have.text', 'Today')
cy.get('[data-today-date]').should(
'have.attr',
'data-today-date',
browserToday,
)
cy.get('ul[aria-label="Today\'s assignments"] > li').should(
'have.length',
2,
)
cy.contains('a', 'Genesis / Creation / Chapter 1')
.should('contain.text', 'Bible')
.and('have.attr', 'href', '/schedules/73')
cy.contains('a', 'Introduction')
.should('contain.text', 'Course')
.and('have.attr', 'href', '/schedules/81')
cy.get('.today-assignment__kind')
.first()
.should('have.text', 'Chapter_sections-v2')
.and('have.css', 'text-transform', 'none')
})
it('shows loading and empty states', () => {
cy.intercept('GET', `**/api/assignments?date=${browserToday}`, {
delay: 500,
statusCode: 200,
body: {
date: browserToday,
assignments: [],
},
}).as('todayAssignments')
cy.visit('/dashboard')
cy.wait('@me')
cy.get('.today-assignments [role="status"]').should(
'have.text',
"Loading today's assignments...",
)
cy.wait('@todayAssignments')
cy.get('.today-assignments [role="status"]').should(
'have.text',
'Nothing is assigned for today.',
)
})
it('retries independently after the request fails', () => {
let requestCount = 0
cy.intercept(
'GET',
`**/api/assignments?date=${browserToday}`,
(request) => {
requestCount += 1
request.alias = `todayAssignments${requestCount}`
if (requestCount === 1) {
request.reply({ statusCode: 500 })
return
}
request.reply({
statusCode: 200,
body: {
date: browserToday,
assignments: [],
},
})
},
)
cy.visit('/dashboard')
cy.wait('@me')
cy.wait('@todayAssignments1')
cy.get('.today-assignments [role="alert"]')
.should('contain.text', "We couldn't load today's assignments.")
.within(() => {
cy.contains('button', 'Try again').click()
})
cy.get('#schedules-heading').should('have.text', 'Your schedules')
cy.wait('@todayAssignments2')
cy.get('.today-assignments [role="status"]').should(
'have.text',
'Nothing is assigned for today.',
)
})
})