test reschedule form
This commit is contained in:
parent
7576ccaf09
commit
6ab6ed801a
1 changed files with 190 additions and 0 deletions
|
|
@ -184,6 +184,103 @@ const splitScheduleDetail = {
|
|||
},
|
||||
}
|
||||
|
||||
const rescheduleSourceDetail = {
|
||||
schedule: {
|
||||
...scheduleDetail.schedule,
|
||||
startDate: '2026-08-10',
|
||||
targetDate: '2026-08-20',
|
||||
assignmentCount: 4,
|
||||
days: [
|
||||
{
|
||||
date: '2026-08-10',
|
||||
assignments: [
|
||||
{
|
||||
...scheduleDetail.schedule.days[0]?.assignments[0],
|
||||
completedAt: '2026-08-11T08:30:00+00:00',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
date: '2026-08-18',
|
||||
assignments: [
|
||||
{
|
||||
id: 2,
|
||||
completedAt: null,
|
||||
element: {
|
||||
name: 'Chapter 2',
|
||||
kind: 'Chapter_sections-v2',
|
||||
path: ['Genesis', 'Creation', 'Chapter 2'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
date: '2026-08-19',
|
||||
assignments: [
|
||||
{
|
||||
id: 3,
|
||||
completedAt: null,
|
||||
element: {
|
||||
name: 'Chapter 3',
|
||||
kind: 'Chapter_sections-v2',
|
||||
path: ['Genesis', 'Creation', 'Chapter 3'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
date: '2026-08-20',
|
||||
assignments: [
|
||||
{
|
||||
id: 4,
|
||||
completedAt: null,
|
||||
element: {
|
||||
name: 'Chapter 4',
|
||||
kind: 'Chapter_sections-v2',
|
||||
path: ['Genesis', 'Creation', 'Chapter 4'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
const rescheduledDetail = {
|
||||
schedule: {
|
||||
...rescheduleSourceDetail.schedule,
|
||||
startDate: '2026-08-15',
|
||||
targetDate: '2026-08-16',
|
||||
days: [
|
||||
rescheduleSourceDetail.schedule.days[0],
|
||||
{
|
||||
date: '2026-08-15',
|
||||
assignments: [rescheduleSourceDetail.schedule.days[1]?.assignments[0]],
|
||||
},
|
||||
{
|
||||
date: '2026-08-16',
|
||||
assignments: [
|
||||
rescheduleSourceDetail.schedule.days[2]?.assignments[0],
|
||||
rescheduleSourceDetail.schedule.days[3]?.assignments[0],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
const fullyCompletedScheduleDetail = {
|
||||
schedule: {
|
||||
...scheduleDetail.schedule,
|
||||
days: scheduleDetail.schedule.days.map((day) => ({
|
||||
...day,
|
||||
assignments: day.assignments.map((assignment) => ({
|
||||
...assignment,
|
||||
completedAt: '2026-08-15T09:30:00+00:00',
|
||||
})),
|
||||
})),
|
||||
},
|
||||
}
|
||||
|
||||
function interceptAuthenticatedUser(): void {
|
||||
cy.intercept('GET', '**/api/me', {
|
||||
statusCode: 200,
|
||||
|
|
@ -458,6 +555,99 @@ describe('set scheduling', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('reschedules unfinished assignments while preserving completed work', () => {
|
||||
cy.clock(new Date(2026, 7, 15, 12).getTime(), ['Date'])
|
||||
cy.intercept('GET', '**/api/schedules/73', {
|
||||
statusCode: 200,
|
||||
body: rescheduleSourceDetail,
|
||||
}).as('schedule')
|
||||
cy.intercept('PATCH', '**/api/schedules/73', (request) => {
|
||||
expect(request.headers.accept).to.equal('application/json')
|
||||
expect(request.body).to.deep.equal({
|
||||
startDate: '2026-08-15',
|
||||
targetDate: '2026-08-16',
|
||||
workloadPlacement: 'end',
|
||||
})
|
||||
request.reply({ statusCode: 200, body: rescheduledDetail })
|
||||
}).as('reschedule')
|
||||
|
||||
cy.visit('/schedules/73')
|
||||
cy.wait('@me')
|
||||
cy.wait('@schedule')
|
||||
cy.get('[data-reschedule-form]').should('not.exist')
|
||||
cy.get('[data-reschedule-toggle]').should('have.text', 'Reschedule remaining').click()
|
||||
|
||||
cy.get('#reschedule-start-date').should('have.value', '2026-08-15')
|
||||
cy.get('#reschedule-target-date').should('have.value', '2026-08-20')
|
||||
cy.get('[data-workload-placement]').should('not.exist')
|
||||
cy.get('#reschedule-target-date').clear().type('2026-08-16')
|
||||
cy.get('[data-workload-placement]').should('be.visible').within(() => {
|
||||
cy.get('input[value="middle"]').should('be.checked')
|
||||
cy.get('input[value="end"]').check()
|
||||
})
|
||||
cy.get('[data-reschedule-form]').submit()
|
||||
cy.wait('@reschedule')
|
||||
|
||||
cy.get('[data-reschedule-form]').should('not.exist')
|
||||
cy.get('[data-reschedule-announcement]').should(
|
||||
'have.text',
|
||||
'3 remaining assignments rescheduled.',
|
||||
)
|
||||
cy.contains('4 Chapter_sections-v2 assignments across 2 days').should('be.visible')
|
||||
cy.get('.schedule-range').should('contain.text', 'Aug 15, 2026 to Aug 16, 2026')
|
||||
cy.get('[data-assignment-section="remaining"] [data-schedule-day]').then(($days) => {
|
||||
expect([...$days].map((day) => day.getAttribute('data-schedule-date'))).to.deep.equal([
|
||||
'2026-08-15',
|
||||
'2026-08-16',
|
||||
])
|
||||
})
|
||||
cy.get('[data-assignment-section="completed"] summary').click()
|
||||
cy.get('[data-assignment-section="completed"] [data-schedule-day]')
|
||||
.should('have.length', 1)
|
||||
.and('have.attr', 'data-schedule-date', '2026-08-10')
|
||||
|
||||
cy.get('[data-reschedule-toggle]').click()
|
||||
cy.get('#reschedule-start-date').should('have.value', '2026-08-15')
|
||||
cy.get('#reschedule-target-date').should('have.value', '2026-08-16')
|
||||
})
|
||||
|
||||
it('uses today for an expired target and validates before rescheduling', () => {
|
||||
cy.clock(new Date(2026, 7, 15, 12).getTime(), ['Date'])
|
||||
cy.intercept('GET', '**/api/schedules/73', {
|
||||
statusCode: 200,
|
||||
body: scheduleDetail,
|
||||
}).as('schedule')
|
||||
cy.intercept('PATCH', '**/api/schedules/73').as('reschedule')
|
||||
|
||||
cy.visit('/schedules/73')
|
||||
cy.wait('@me')
|
||||
cy.wait('@schedule')
|
||||
cy.get('[data-reschedule-toggle]').click()
|
||||
|
||||
cy.get('#reschedule-start-date').should('have.value', '2026-08-15')
|
||||
cy.get('#reschedule-target-date').should('have.value', '2026-08-15')
|
||||
cy.get('#reschedule-target-date').clear().type('2026-08-14')
|
||||
cy.get('[data-reschedule-form]').submit()
|
||||
cy.get('#reschedule-target-date-error').should(
|
||||
'have.text',
|
||||
'Target date cannot be before the start date.',
|
||||
)
|
||||
cy.get('@reschedule.all').should('have.length', 0)
|
||||
})
|
||||
|
||||
it('does not offer rescheduling after all assignments are complete', () => {
|
||||
cy.intercept('GET', '**/api/schedules/73', {
|
||||
statusCode: 200,
|
||||
body: fullyCompletedScheduleDetail,
|
||||
}).as('schedule')
|
||||
|
||||
cy.visit('/schedules/73')
|
||||
cy.wait('@me')
|
||||
cy.wait('@schedule')
|
||||
|
||||
cy.get('[data-reschedule-toggle]').should('not.exist')
|
||||
})
|
||||
|
||||
it('completes and reopens assignments from the schedule', () => {
|
||||
const completedAt = '2026-08-15T12:30:00+00:00'
|
||||
cy.intercept('GET', '**/api/schedules/73', {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue