test today's dashboard work
This commit is contained in:
parent
483ca6fc1d
commit
1c83eb1b84
5 changed files with 184 additions and 3 deletions
|
|
@ -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', () => {
|
||||||
|
|
|
||||||
|
|
@ -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', () => {
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
157
frontend/website/cypress/e2e/today-assignments.cy.ts
Normal file
157
frontend/website/cypress/e2e/today-assignments.cy.ts
Normal 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.',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue