-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#12588] Added unit tests for SessionEditFormComponent #12627
Changes from 7 commits
ee741e1
9bdac69
8b38440
71f5ba9
c3a9d53
80599c2
2b7921f
9d29348
f7159f1
dc9eaba
fe25c7a
264bfaf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,26 @@ | ||
import { HttpClientTestingModule } from '@angular/common/http/testing'; | ||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; | ||
import { RouterTestingModule } from '@angular/router/testing'; | ||
import { TimeFormat } from 'src/web/types/datetime-const'; | ||
import moment from 'moment-timezone'; | ||
import SpyInstance = jest.SpyInstance; | ||
import { DateTimeService } from '../../../services/datetime.service'; | ||
import { SimpleModalService } from '../../../services/simple-modal.service'; | ||
import { createMockNgbModalRef } from '../../../test-helpers/mock-ngb-modal-ref'; | ||
import { Course, ResponseVisibleSetting, SessionVisibleSetting } from '../../../types/api-output'; | ||
import { DateFormat, TimeFormat, getDefaultDateFormat, getDefaultTimeFormat } from '../../../types/datetime-const'; | ||
import { SimpleModalType } from '../simple-modal/simple-modal-type'; | ||
import { TeammatesRouterModule } from '../teammates-router/teammates-router.module'; | ||
import { SessionEditFormMode } from './session-edit-form-model'; | ||
import { SessionEditFormComponent } from './session-edit-form.component'; | ||
import { SessionEditFormModule } from './session-edit-form.module'; | ||
|
||
describe('SessionEditFormComponent', () => { | ||
let component: SessionEditFormComponent; | ||
let fixture: ComponentFixture<SessionEditFormComponent>; | ||
let simpleModalService: SimpleModalService; | ||
let service: DateTimeService; | ||
|
||
const submissionStartDateField = 'submissionStartDate'; | ||
|
||
beforeEach(waitForAsync(() => { | ||
TestBed.configureTestingModule({ | ||
|
@@ -24,6 +36,8 @@ describe('SessionEditFormComponent', () => { | |
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(SessionEditFormComponent); | ||
simpleModalService = TestBed.inject(SimpleModalService); | ||
service = TestBed.inject(DateTimeService); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
@@ -53,4 +67,312 @@ describe('SessionEditFormComponent', () => { | |
expect(time.minute).toEqual(0); | ||
}); | ||
|
||
it('should set the submission start time correctly when the date is same as' | ||
+ ' earliest date and time is earlier than earliest possible time', () => { | ||
const date: DateFormat = component.minDateForSubmissionStart; | ||
const minTime: TimeFormat = component.minTimeForSubmissionStart; | ||
const time: TimeFormat = { hour: minTime.hour - 1, minute: minTime.minute }; | ||
const configureSubmissionOpeningTimeSpy = jest.spyOn(component, 'configureSubmissionOpeningTime'); | ||
const triggerModelChangeSpy = jest.spyOn(component, 'triggerModelChange'); | ||
component.model.submissionStartTime = time; | ||
component.triggerSubmissionOpeningDateModelChange(submissionStartDateField, date); | ||
component.configureSubmissionOpeningTime(minTime); | ||
expect(component.model.submissionStartTime).toStrictEqual(minTime); | ||
expect(configureSubmissionOpeningTimeSpy).toHaveBeenCalledWith(minTime); | ||
weiquu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
expect(triggerModelChangeSpy).toHaveBeenCalledWith(submissionStartDateField, date); | ||
}); | ||
|
||
it('should trigger the change of the model when the submission opening date changes', () => { | ||
const date: DateFormat = component.minDateForSubmissionStart; | ||
const minTime: TimeFormat = component.minTimeForSubmissionStart; | ||
const time: TimeFormat = { hour: minTime.hour + 1, minute: minTime.minute }; | ||
const triggerModelChangeSpy = jest.spyOn(component, 'triggerModelChange'); | ||
component.model.submissionStartTime = time; | ||
component.triggerSubmissionOpeningDateModelChange(submissionStartDateField, date); | ||
expect(triggerModelChangeSpy).toHaveBeenCalledWith(submissionStartDateField, date); | ||
weiquu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
|
||
it('should emit a modelChange event with the updated field when triggerModelChange is called', () => { | ||
const field = 'courseId'; | ||
const data = 'testId'; | ||
const modelChangeSpy = jest.spyOn(component.modelChange, 'emit'); | ||
component.triggerModelChange(field, data); | ||
expect(modelChangeSpy).toHaveBeenCalledWith({ | ||
...component.model, | ||
[field]: data, | ||
}); | ||
}); | ||
|
||
it('should emit modelChange event when a valid course ID is provided', () => { | ||
const newCourseId = 'testId1'; | ||
const courseCandidates: Course[] = [ | ||
{ | ||
courseId: 'testId1', | ||
courseName: 'testCourse1', | ||
timeZone: 'Asia/Singapore', | ||
institute: 'Institute 1', | ||
creationTimestamp: 1000000000000, | ||
deletionTimestamp: 1500000000000, | ||
}, | ||
]; | ||
component.courseCandidates = courseCandidates; | ||
const modelChangeSpy = jest.spyOn(component.modelChange, 'emit'); | ||
component.courseIdChangeHandler(newCourseId); | ||
expect(modelChangeSpy).toHaveBeenCalledWith({ | ||
...component.model, | ||
courseId: newCourseId, | ||
courseName: 'testCourse1', | ||
timeZone: 'Asia/Singapore', | ||
}); | ||
}); | ||
|
||
it('should not emit a modelChange event when no candidates are found', () => { | ||
const newCourseId = 'testId1'; | ||
const courseCandidates: Course[] = []; | ||
component.courseCandidates = courseCandidates; | ||
const modelChangeSpy = jest.spyOn(component.modelChange, 'emit'); | ||
component.courseIdChangeHandler(newCourseId); | ||
expect(modelChangeSpy).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should return the minimum session closing datetime as the session opening datetime ' | ||
+ 'if it is later than one hour before now', () => { | ||
const now = moment().tz(component.model.timeZone); | ||
const date = service.getDateInstance(now.add(1, 'days')); | ||
const time = service.getTimeInstance(now); | ||
component.model.submissionStartDate = date; | ||
component.model.submissionStartTime = time; | ||
const minTimeForSubmissionEnd = component.minTimeForSubmissionEnd; | ||
expect(minTimeForSubmissionEnd).toStrictEqual(time); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: let's just use component.minTimeForSubmissionEnd here instead of the const |
||
}); | ||
|
||
it('should return the minimum session closing datetime as one hour before now ' | ||
+ 'if it is later than the session opening datetime', () => { | ||
const now = moment().tz(component.model.timeZone); | ||
const date = service.getDateInstance(now.subtract(1, 'days')); | ||
const time = service.getTimeInstance(now); | ||
const oneHourBeforeNow = service.getTimeInstance(now.subtract(1, 'hours')); | ||
component.model.submissionStartDate = date; | ||
component.model.submissionStartTime = time; | ||
const minTimeForSubmissionEnd = component.minTimeForSubmissionEnd; | ||
expect(minTimeForSubmissionEnd).toStrictEqual(oneHourBeforeNow); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, use |
||
}); | ||
|
||
it('should return the minimum date for session visibility as 30 days before session opening datetime', () => { | ||
const expectedMinDateForSessionVisible = service.getDateInstance( | ||
service.getMomentInstanceFromDate(component.model.submissionStartDate).subtract(30, 'days'), | ||
); | ||
const minDateForSessionVisible = component.minDateForSessionVisible; | ||
expect(minDateForSessionVisible).toEqual(expectedMinDateForSessionVisible); | ||
}); | ||
|
||
it('should return the minimum time for session visibility as 30 days before session opening datetime', () => { | ||
const expectedMinTimeForSessionVisible = service.getTimeInstance( | ||
service.getMomentInstanceFromDate(component.model.submissionStartDate).subtract(30, 'days'), | ||
); | ||
const minTimeForSessionVisible = component.minTimeForSessionVisible; | ||
expect(minTimeForSessionVisible).toEqual(expectedMinTimeForSessionVisible); | ||
}); | ||
|
||
it('should return the submissionStartDate as the maximum date for session visibility ' | ||
+ 'when response visible setting is LATER', () => { | ||
component.model.responseVisibleSetting = ResponseVisibleSetting.LATER; | ||
component.model.submissionStartDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
const maxDateForSessionVisible = component.maxDateForSessionVisible; | ||
expect(maxDateForSessionVisible).toEqual(component.model.submissionStartDate); | ||
}); | ||
|
||
it('should return the submissionStartDate as the maximum date for session visibility ' | ||
+ 'when response visible setting is AT_VISIBLE', () => { | ||
component.model.responseVisibleSetting = ResponseVisibleSetting.AT_VISIBLE; | ||
component.model.submissionStartDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
const maxDateForSessionVisible = component.maxDateForSessionVisible; | ||
expect(maxDateForSessionVisible).toEqual(component.model.submissionStartDate); | ||
}); | ||
|
||
it('should return the submissionStartDate as the maximum date for session visibility ' | ||
+ 'when response visible setting is CUSTOM and submissionStartDate is before customResponseVisibleDate', () => { | ||
component.model.responseVisibleSetting = ResponseVisibleSetting.CUSTOM; | ||
component.model.submissionStartDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's save |
||
component.model.customResponseVisibleDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone).add(1, 'days')); | ||
const maxDateForSessionVisible = component.maxDateForSessionVisible; | ||
expect(maxDateForSessionVisible).toEqual(component.model.submissionStartDate); | ||
}); | ||
|
||
it('should return the customResponseVisibleDate as the maximum date for session visibility ' | ||
+ 'when response visible setting is CUSTOM and submissionStartDate is after customResponseVisibleDate', () => { | ||
component.model.responseVisibleSetting = ResponseVisibleSetting.CUSTOM; | ||
component.model.submissionStartDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone).add(1, 'days')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above here |
||
component.model.customResponseVisibleDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
const maxDateForSessionVisible = component.maxDateForSessionVisible; | ||
expect(maxDateForSessionVisible).toEqual(component.model.customResponseVisibleDate); | ||
}); | ||
|
||
it('should return the default date format if response visible setting is not defined', () => { | ||
const maxDateForSessionVisible = component.maxDateForSessionVisible; | ||
expect(maxDateForSessionVisible).toEqual(getDefaultDateFormat()); | ||
}); | ||
|
||
it('should return the submissionStartTime as the maximum time for session visibility ' | ||
+ 'when response visible setting is LATER', () => { | ||
component.model.responseVisibleSetting = ResponseVisibleSetting.LATER; | ||
component.model.submissionStartTime = service.getTimeInstance(moment()); | ||
const maxTimeForSessionVisible = component.maxTimeForSessionVisible; | ||
expect(maxTimeForSessionVisible).toEqual(component.model.submissionStartTime); | ||
}); | ||
|
||
it('should return the submissionStartTime as the maximum time for session visibility ' | ||
+ 'when response visible setting is AT_VISIBLE', () => { | ||
component.model.responseVisibleSetting = ResponseVisibleSetting.AT_VISIBLE; | ||
component.model.submissionStartTime = service.getTimeInstance(moment()); | ||
const maxTimeForSessionVisible = component.maxTimeForSessionVisible; | ||
expect(maxTimeForSessionVisible).toEqual(component.model.submissionStartTime); | ||
}); | ||
|
||
it('should return submissionStartTime as the maximum time for session visibility ' | ||
+ 'when response visible setting is CUSTOM and submissionStartDate is before customResponseVisibleDate', () => { | ||
component.model.responseVisibleSetting = ResponseVisibleSetting.CUSTOM; | ||
component.model.submissionStartTime = | ||
service.getTimeInstance(moment()); | ||
component.model.customResponseVisibleTime = | ||
service.getTimeInstance(moment()); | ||
component.model.submissionStartDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
component.model.customResponseVisibleDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone).add(1, 'days')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, let's save all the moment() calls into a const instead |
||
const maxTimeForSessionVisible = component.maxTimeForSessionVisible; | ||
expect(maxTimeForSessionVisible).toEqual(component.model.submissionStartTime); | ||
}); | ||
|
||
it('should return customResponseVisibleTime as the maximum time for session visibility ' | ||
+ 'when response visible setting is CUSTOM and submissionStartDate is after customResponseVisibleDate', () => { | ||
component.model.responseVisibleSetting = ResponseVisibleSetting.CUSTOM; | ||
component.model.submissionStartTime = | ||
service.getTimeInstance(moment()); | ||
component.model.customResponseVisibleTime = | ||
service.getTimeInstance(moment()); | ||
component.model.submissionStartDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone).add(1, 'days')); | ||
component.model.customResponseVisibleDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
const maxTimeForSessionVisible = component.maxTimeForSessionVisible; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above here |
||
expect(maxTimeForSessionVisible).toEqual(component.model.customResponseVisibleTime); | ||
}); | ||
|
||
it('should return the default time format if response visible setting is not recognized', () => { | ||
const maxTimeForSessionVisible = component.maxTimeForSessionVisible; | ||
expect(maxTimeForSessionVisible).toEqual(getDefaultTimeFormat()); | ||
}); | ||
|
||
it('should return submissionStartDate as the minimum date for response visibility' | ||
+ ' when session visible setting is AT_OPEN', () => { | ||
component.model.sessionVisibleSetting = SessionVisibleSetting.AT_OPEN; | ||
component.model.submissionStartDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
const minDateForResponseVisible = component.minDateForResponseVisible; | ||
expect(minDateForResponseVisible).toEqual(component.model.submissionStartDate); | ||
}); | ||
|
||
it('should return customSessionVisibleDate as the minimum date for response visibility ' | ||
+ 'when session visible setting is CUSTOM', () => { | ||
component.model.sessionVisibleSetting = SessionVisibleSetting.CUSTOM; | ||
component.model.submissionStartDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
component.model.customSessionVisibleDate = | ||
service.getDateInstance(moment().tz(component.model.timeZone)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should make customerSessionVisibleDate different from submissionStartDate here |
||
const minDateForResponseVisible = component.minDateForResponseVisible; | ||
expect(minDateForResponseVisible).toEqual(component.model.customSessionVisibleDate); | ||
}); | ||
|
||
it('should return the default date format if session visible setting is not recognized', () => { | ||
const minDateForResponseVisible = component.minDateForResponseVisible; | ||
expect(minDateForResponseVisible).toEqual(getDefaultDateFormat()); | ||
}); | ||
|
||
it('should return submissionStartTime as the minimum time for response visibility ' | ||
+ 'when session visible setting is AT_OPEN', () => { | ||
component.model.sessionVisibleSetting = SessionVisibleSetting.AT_OPEN; | ||
component.model.submissionStartTime = | ||
service.getTimeInstance(moment().tz(component.model.timeZone)); | ||
const minTimeForResponseVisible = component.minTimeForResponseVisible; | ||
expect(minTimeForResponseVisible).toEqual(component.model.submissionStartTime); | ||
}); | ||
|
||
it('should return customSessionVisibleTime as the minimum time for response visibility ' | ||
+ 'when session visible setting is CUSTOM', () => { | ||
component.model.sessionVisibleSetting = SessionVisibleSetting.CUSTOM; | ||
component.model.submissionStartTime = | ||
service.getTimeInstance(moment().tz(component.model.timeZone)); | ||
component.model.customSessionVisibleTime = | ||
service.getTimeInstance(moment().tz(component.model.timeZone)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, let's make the customSessionVisibleTime different from submissionStartTime |
||
const minTimeForResponseVisible = component.minTimeForResponseVisible; | ||
expect(minTimeForResponseVisible).toEqual(component.model.customSessionVisibleTime); | ||
}); | ||
|
||
it('should return the default time format if session visible setting is not defined', () => { | ||
const minTimeForResponseVisible = component.minTimeForResponseVisible; | ||
expect(minTimeForResponseVisible).toEqual(getDefaultTimeFormat()); | ||
}); | ||
|
||
it('should emit addNewSessionEvent when session edit form mode is ADD', () => { | ||
component.formMode = SessionEditFormMode.ADD; | ||
const addNewSessionSpy = jest.spyOn(component.addNewSessionEvent, 'emit'); | ||
component.submitFormHandler(); | ||
expect(addNewSessionSpy).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should display warning when discarding edit to current feedback session', async () => { | ||
const promise: Promise<void> = Promise.resolve(); | ||
const modalSpy: SpyInstance = jest.spyOn(simpleModalService, 'openConfirmationModal') | ||
.mockReturnValue(createMockNgbModalRef({}, promise)); | ||
component.cancelHandler(); | ||
await promise; | ||
expect(modalSpy).toHaveBeenCalledTimes(1); | ||
expect(modalSpy).toHaveBeenLastCalledWith('Discard unsaved edit?', | ||
SimpleModalType.WARNING, 'Warning: Any unsaved changes will be lost.'); | ||
}); | ||
|
||
it('should display warning when deleting the current feedback session', async () => { | ||
const promise: Promise<void> = Promise.resolve(); | ||
const modalSpy: SpyInstance = jest.spyOn(simpleModalService, 'openConfirmationModal') | ||
.mockReturnValue(createMockNgbModalRef({}, promise)); | ||
component.deleteHandler(); | ||
await promise; | ||
expect(modalSpy).toHaveBeenCalledTimes(1); | ||
expect(modalSpy) | ||
.toHaveBeenLastCalledWith(`Delete the session <strong>${component.model.feedbackSessionName}</strong>?`, | ||
SimpleModalType.WARNING, 'The session will be moved to the recycle bin. This action can be reverted ' | ||
+ 'by going to the "Sessions" tab and restoring the desired session(s).'); | ||
}); | ||
|
||
it('should emit editExistingSessionEvent when session edit form Mode is EDIT', () => { | ||
component.formMode = SessionEditFormMode.EDIT; | ||
const editExistingSessionSpy = jest.spyOn(component.editExistingSessionEvent, 'emit'); | ||
component.submitFormHandler(); | ||
expect(editExistingSessionSpy).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should emit copyCurrentSessionEvent when copyHandler is called', () => { | ||
const copyCurrentSessionSpy = jest.spyOn(component.copyCurrentSessionEvent, 'emit'); | ||
component.copyHandler(); | ||
expect(copyCurrentSessionSpy).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should emit copyOtherSessionsEvent when copyOthersHandler is called', () => { | ||
const copyOtherSessionsSpy = jest.spyOn(component.copyOtherSessionsEvent, 'emit'); | ||
component.copyOthersHandler(); | ||
expect(copyOtherSessionsSpy).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should emit closeEditFormEvent when closeEditFormHandler is called', () => { | ||
const closeEditFormSpy = jest.spyOn(component.closeEditFormEvent, 'emit'); | ||
component.closeEditFormHandler(); | ||
expect(closeEditFormSpy).toHaveBeenCalled(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: let's rename this
dateTimeService
for better readability