diff --git a/src/assets/wise5/classroomMonitor/dataExport/strategies/DiscussionComponentDataExportStrategy.spec.ts b/src/assets/wise5/classroomMonitor/dataExport/strategies/DiscussionComponentDataExportStrategy.spec.ts index a1ae5f1daf4..e606ec5e31b 100644 --- a/src/assets/wise5/classroomMonitor/dataExport/strategies/DiscussionComponentDataExportStrategy.spec.ts +++ b/src/assets/wise5/classroomMonitor/dataExport/strategies/DiscussionComponentDataExportStrategy.spec.ts @@ -1,97 +1,68 @@ -import { of } from 'rxjs'; -import { DataExportService } from '../../../services/dataExportService'; -import { DataExportComponent } from '../data-export/data-export.component'; import { DiscussionComponentDataExportStrategy } from './DiscussionComponentDataExportStrategy'; -import { TeacherDataService } from '../../../services/teacherDataService'; -import { ConfigService } from '../../../services/configService'; -import { AnnotationService } from '../../../services/annotationService'; -import { TeacherProjectService } from '../../../services/teacherProjectService'; -import { TeacherWebSocketService } from '../../../services/teacherWebSocketService'; +import { ExportStrategyTester } from './ExportStrategyTester'; -const componentId = 'component1'; -const componentPosition = 0; -const componentPrompt = 'Discuss with your classmates.'; -const componentType = 'Discussion'; -const nodeId = 'node1'; -const nodePositionAndTitle = '1.1: Discuss'; -const periodName = 'Period 1'; -const projectId = 10; -const projectTitle = 'Discussion Project'; -const runId = 10; -const stepNumber = '1.1'; -const studentName1 = 'Student A'; -const studentName2 = 'Student B'; +let exportStrategyTester: ExportStrategyTester; const studentWorkId1 = 10000; const studentWorkId2 = 10001; const studentWorkResponse1 = 'Hello'; const studentWorkResponse2 = 'World'; -const userId1 = 100; -const userId2 = 101; -const workgroupId1 = 1000; -const workgroupId2 = 1001; - -const componentPartNumber = componentPosition + 1; const studentData1 = { response: studentWorkResponse1 }; const studentData2 = { componentStateIdReplyingTo: studentWorkId1, response: studentWorkResponse2 }; -const workgroupUserInfo1 = { - periodName: periodName, - users: [{ id: userId1, name: studentName1 }] -}; -const workgroupUserInfo2 = { - periodName: periodName, - users: [{ id: userId2, name: studentName2 }] -}; - -const annotationService: AnnotationService = new AnnotationService(null, null, null); -let configService: ConfigService; -let dataExportService: DataExportService; -let discussionExportStrategy: DiscussionComponentDataExportStrategy; -let generateCSVFileSpy: jasmine.Spy; -let teacherDataService: TeacherDataService; -let teacherProjectService: TeacherProjectService; -const teacherWebSocketService: TeacherWebSocketService = new TeacherWebSocketService( - null, - null, - null, - null -); describe('DiscussionComponentDataExportStrategy', () => { + beforeEach(() => { + exportStrategyTester = new ExportStrategyTester(); + exportStrategyTester.setUpServices(); + }); describe('export', () => { it('generates export with correct rows of data', () => { - setUpServices(); - setUpDiscussionExportStrategy(); - setStudentData([ - createDiscussionComponentState(studentWorkId1, workgroupId1, studentData1), - createDiscussionComponentState(studentWorkId2, workgroupId2, studentData2) + exportStrategyTester.setComponent({ + id: exportStrategyTester.componentId, + type: 'Discussion', + prompt: exportStrategyTester.componentPrompt + }); + exportStrategyTester.setStudentData([ + createDiscussionComponentState( + studentWorkId1, + exportStrategyTester.workgroupId1, + studentData1 + ), + createDiscussionComponentState( + studentWorkId2, + exportStrategyTester.workgroupId2, + studentData2 + ) ]); - discussionExportStrategy.export(); - expect(discussionExportStrategy.controller.generateCSVFile).toHaveBeenCalledWith( + setUpExportStrategy(); + exportStrategyTester.componentExportStrategy.export(); + expect( + exportStrategyTester.componentExportStrategy.controller.generateCSVFile + ).toHaveBeenCalledWith( [ - discussionExportStrategy.defaultDiscussionColumnNames, + exportStrategyTester.componentExportStrategy.defaultDiscussionColumnNames, [ 1, - workgroupId1, - userId1, - studentName1, + exportStrategyTester.workgroupId1, + exportStrategyTester.userId1, + exportStrategyTester.studentName1, '', '', '', '', - periodName, - projectId, - projectTitle, - runId, + exportStrategyTester.periodName, + exportStrategyTester.projectId, + exportStrategyTester.projectTitle, + exportStrategyTester.runId, '', '', '', '', - nodeId, - componentId, - componentPartNumber, - nodePositionAndTitle, - componentType, - componentPrompt, + exportStrategyTester.nodeId, + exportStrategyTester.component.id, + exportStrategyTester.componentPartNumber, + exportStrategyTester.nodePositionAndTitle, + exportStrategyTester.component.type, + exportStrategyTester.component.prompt, studentData1, studentWorkId1, studentWorkId1, @@ -100,27 +71,27 @@ describe('DiscussionComponentDataExportStrategy', () => { ], [ 2, - workgroupId2, - userId2, - studentName2, + exportStrategyTester.workgroupId2, + exportStrategyTester.userId2, + exportStrategyTester.studentName2, '', '', '', '', - periodName, - projectId, - projectTitle, - runId, + exportStrategyTester.periodName, + exportStrategyTester.projectId, + exportStrategyTester.projectTitle, + exportStrategyTester.runId, '', '', '', '', - nodeId, - componentId, - componentPartNumber, - nodePositionAndTitle, - componentType, - componentPrompt, + exportStrategyTester.nodeId, + exportStrategyTester.componentId, + exportStrategyTester.componentPartNumber, + exportStrategyTester.nodePositionAndTitle, + exportStrategyTester.component.type, + exportStrategyTester.component.prompt, studentData2, studentWorkId1, studentWorkId2, @@ -128,98 +99,25 @@ describe('DiscussionComponentDataExportStrategy', () => { studentWorkResponse2 ] ], - `${runId}_step_${stepNumber}_component_${componentPartNumber}_discussion_work.csv` + exportStrategyTester.createExpectedFileName('discussion') ); }); }); }); -function setUpServices(): void { - setUpConfigService(); - setUpDataExportService(); - setUpTeacherProjectService(); - setUpTeacherDataService(); -} - -function setUpConfigService(): void { - configService = new ConfigService(null, null); - spyOn(configService, 'getUserInfoByWorkgroupId').and.callFake((workgroupId: number) => { - switch (workgroupId) { - case workgroupId1: - return workgroupUserInfo1; - case workgroupId2: - return workgroupUserInfo2; - } - }); - spyOn(configService, 'getRunId').and.returnValue(runId); - spyOn(configService, 'getProjectId').and.returnValue(projectId); -} - -function setUpDataExportService(): void { - dataExportService = new DataExportService(null, null, null); - spyOn(dataExportService, 'retrieveStudentData').and.returnValue(of({})); -} - -function setUpTeacherProjectService(): void { - teacherProjectService = new TeacherProjectService(null, null, null, null, null); - spyOn(teacherProjectService, 'getNodePositionById').and.returnValue(stepNumber); - spyOn(teacherProjectService, 'getNodePositionAndTitle').and.returnValue(nodePositionAndTitle); - spyOn(teacherProjectService, 'getComponentPosition').and.returnValue(componentPosition); - spyOn(teacherProjectService, 'getProjectTitle').and.returnValue(projectTitle); -} - -function setUpTeacherDataService(): void { - teacherDataService = new TeacherDataService( - null, - annotationService, - configService, - teacherProjectService, - teacherWebSocketService - ); -} - -function setUpDiscussionExportStrategy(): void { - discussionExportStrategy = new DiscussionComponentDataExportStrategy(nodeId, { - id: componentId, - type: componentType, - prompt: componentPrompt - }); - discussionExportStrategy.controller = createDataExportComponent(); - discussionExportStrategy.dataExportService = dataExportService; - discussionExportStrategy.teacherDataService = teacherDataService; - discussionExportStrategy.configService = configService; - discussionExportStrategy.projectService = teacherProjectService; -} - -function createDataExportComponent(): any { - const controller = new DataExportComponent( - null, - null, - null, - null, - null, - null, - null, - null, - null, - null +function setUpExportStrategy(): void { + exportStrategyTester.setUpExportStrategy( + new DiscussionComponentDataExportStrategy( + exportStrategyTester.nodeId, + exportStrategyTester.component + ) ); - spyOn(controller, 'showDownloadingExportMessage').and.callFake(() => {}); - generateCSVFileSpy = spyOn(controller, 'generateCSVFile').and.callFake(() => {}); - spyOn(controller, 'hideDownloadingExportMessage').and.callFake(() => {}); - controller.includeStudentNames = true; - return controller; } function createDiscussionComponentState(id: number, workgroupId: number, studentData: any): any { - const componentState = { + return { id: id, workgroupId: workgroupId, studentData: studentData }; - return componentState; -} - -function setStudentData(componentStates: any[]): void { - spyOn(teacherDataService, 'getComponentStatesByComponentId').and.returnValue(componentStates); } diff --git a/src/assets/wise5/classroomMonitor/dataExport/strategies/ExportStrategyTester.ts b/src/assets/wise5/classroomMonitor/dataExport/strategies/ExportStrategyTester.ts new file mode 100644 index 00000000000..74175aa8d37 --- /dev/null +++ b/src/assets/wise5/classroomMonitor/dataExport/strategies/ExportStrategyTester.ts @@ -0,0 +1,162 @@ +import { of } from 'rxjs'; +import { AnnotationService } from '../../../services/annotationService'; +import { ConfigService } from '../../../services/configService'; +import { DataExportService } from '../../../services/dataExportService'; +import { TeacherDataService } from '../../../services/teacherDataService'; +import { TeacherProjectService } from '../../../services/teacherProjectService'; +import { TeacherWebSocketService } from '../../../services/teacherWebSocketService'; +import { DataExportComponent } from '../data-export/data-export.component'; +import { AbstractDataExportStrategy } from './AbstractDataExportStrategy'; +import { millisecondsToDateTime } from '../../../common/datetime/datetime'; + +export class ExportStrategyTester { + annotationService: AnnotationService = new AnnotationService(null, null, null); + component: any; + componentExportStrategy: any; + componentId: string = 'component1'; + componentPrompt: string = 'This is the prompt.'; + componentPosition: number = 0; + componentPartNumber: number = this.componentPosition + 1; + configService: ConfigService; + dataExportService: DataExportService; + endTimeMilliseconds: number = 1606780800000; + endDate = millisecondsToDateTime(this.endTimeMilliseconds); + generateCSVFileSpy: jasmine.Spy; + nodeId: string = 'node1'; + nodePositionAndTitle: string = '1.1: Test Step'; + periodName: string = 'Period 1'; + projectId: number = 10; + projectTitle: string = 'Test Project'; + runId: number = 10; + startTimeMilliseconds: number = 1577836800000; + startDate = millisecondsToDateTime(this.startTimeMilliseconds); + stepNumber: string = '1.1'; + studentName1 = 'Student A'; + studentName2 = 'Student B'; + teacherDataService: TeacherDataService; + teacherProjectService: TeacherProjectService; + teacherWebSocketService: TeacherWebSocketService = new TeacherWebSocketService( + null, + null, + null, + null + ); + userId1: number = 100; + userId2: number = 101; + workgroupId1: number = 1000; + workgroupId2: number = 1001; + workgroupIdToUserInfo = {}; + workgroupUserInfo1 = { + periodName: this.periodName, + users: [{ id: this.userId1, name: this.studentName1 }] + }; + workgroupUserInfo2 = { + periodName: this.periodName, + users: [{ id: this.userId2, name: this.studentName2 }] + }; + + setUpServices(): void { + this.setUpConfigService(); + this.setUpDataExportService(); + this.setUpTeacherProjectService(); + this.setUpTeacherDataService(); + this.setUpWorkgroups(); + } + + setUpConfigService(): void { + this.configService = new ConfigService(null, null); + spyOn(this.configService, 'getUserInfoByWorkgroupId').and.callFake((workgroupId: number) => { + return this.workgroupIdToUserInfo[workgroupId]; + }); + spyOn(this.configService, 'getRunId').and.returnValue(this.runId); + spyOn(this.configService, 'getProjectId').and.returnValue(this.projectId); + spyOn(this.configService, 'getRunName').and.returnValue(this.projectTitle); + this.configService.config = { + startTime: this.startTimeMilliseconds, + endTime: this.endTimeMilliseconds + }; + } + + setUpDataExportService(): void { + this.dataExportService = new DataExportService(null, null, null); + spyOn(this.dataExportService, 'retrieveStudentData').and.returnValue(of({})); + } + + setUpTeacherProjectService(): void { + this.teacherProjectService = new TeacherProjectService(null, null, null, null, null); + spyOn(this.teacherProjectService, 'getNodePositionById').and.returnValue(this.stepNumber); + spyOn(this.teacherProjectService, 'getNodePositionAndTitle').and.returnValue( + this.nodePositionAndTitle + ); + spyOn(this.teacherProjectService, 'getComponentPosition').and.returnValue( + this.componentPosition + ); + spyOn(this.teacherProjectService, 'getProjectTitle').and.returnValue(this.projectTitle); + } + + setUpTeacherDataService(): void { + this.teacherDataService = new TeacherDataService( + null, + this.annotationService, + this.configService, + this.teacherProjectService, + this.teacherWebSocketService + ); + } + + setUpWorkgroups(): void { + this.addWorkgroup(this.workgroupId1, this.workgroupUserInfo1); + this.addWorkgroup(this.workgroupId2, this.workgroupUserInfo2); + } + + setUpExportStrategy(componentExportStrategy: AbstractDataExportStrategy): void { + this.componentExportStrategy = componentExportStrategy; + this.componentExportStrategy.controller = this.createDataExportComponent(); + this.componentExportStrategy.annotationService = this.annotationService; + this.componentExportStrategy.configService = this.configService; + this.componentExportStrategy.dataExportService = this.dataExportService; + this.componentExportStrategy.projectService = this.teacherProjectService; + this.componentExportStrategy.teacherDataService = this.teacherDataService; + } + + createDataExportComponent(): any { + const controller = new DataExportComponent( + this.annotationService, + null, + this.configService, + this.dataExportService, + null, + null, + this.teacherProjectService, + null, + null, + this.teacherDataService + ); + spyOn(controller, 'showDownloadingExportMessage').and.callFake(() => {}); + this.generateCSVFileSpy = spyOn(controller, 'generateCSVFile').and.callFake(() => {}); + spyOn(controller, 'hideDownloadingExportMessage').and.callFake(() => {}); + controller.includeStudentNames = true; + return controller; + } + + setStudentData(componentStates: any[]): void { + spyOn(this.teacherDataService, 'getComponentStatesByComponentId').and.returnValue( + componentStates + ); + } + + addWorkgroup(workgroupId: number, workgroupUserInfo: any): void { + this.workgroupIdToUserInfo[workgroupId] = workgroupUserInfo; + } + + setComponent(component: any): void { + this.component = component; + } + + createExpectedFileName(componentTypeWithUnderscore: string): string { + return ( + `${this.runId}_step_${this.stepNumber}_component_` + + `${this.componentPartNumber}_${componentTypeWithUnderscore}_work.csv` + ); + } +} diff --git a/src/assets/wise5/classroomMonitor/dataExport/strategies/PeerChatComponentDataExportStrategy.spec.ts b/src/assets/wise5/classroomMonitor/dataExport/strategies/PeerChatComponentDataExportStrategy.spec.ts new file mode 100644 index 00000000000..7304c2f50b7 --- /dev/null +++ b/src/assets/wise5/classroomMonitor/dataExport/strategies/PeerChatComponentDataExportStrategy.spec.ts @@ -0,0 +1,387 @@ +import { PeerChatComponentDataExportStrategy } from './PeerChatComponentDataExportStrategy'; +import { millisecondsToDateTime } from '../../../common/datetime/datetime'; +import { ExportStrategyTester } from './ExportStrategyTester'; +import { copy } from '../../../common/object/object'; + +const componentType = 'PeerChat'; +const dynamicPrompt1 = 'This is the dynamic prompt 1.'; +const dynamicPrompt2 = 'This is the dynamic prompt 2.'; +let exportStrategyTester: ExportStrategyTester; +const peerGroupId1 = 10; +const postPrompt: string = 'This is the post prompt.'; +const prePrompt: string = 'This is the pre prompt.'; +const question1 = 'This is the first question.'; +const question2 = 'This is the second question.'; +const questionId1 = 'q1'; +const questionId2 = 'q2'; +const studentWorkId1 = 10000; +const studentWorkId2 = 10001; +const studentWorkResponse1 = 'Hello'; +const studentWorkResponse2 = 'World'; +const studentWorkTimestamp1 = millisecondsToDateTime(1577923200000); +const studentWorkTimestamp2 = millisecondsToDateTime(1578009600000); + +describe('PeerChatComponentDataExportStrategy', () => { + beforeEach(() => { + exportStrategyTester = new ExportStrategyTester(); + exportStrategyTester.setUpServices(); + }); + describe('export', () => { + exportWithRegularPrompt(); + exportWithDynamicPrompt(); + exportWithQuestionBank(); + }); +}); + +function exportWithRegularPrompt(): void { + describe('peer chat component with regular prompt', () => { + it('generates export with correct rows of data', () => { + exportStrategyTester.setComponent({ + id: exportStrategyTester.componentId, + type: componentType, + prompt: exportStrategyTester.componentPrompt + }); + exportStrategyTester.setStudentData([ + createPeerChatComponentState( + studentWorkId1, + exportStrategyTester.workgroupId1, + peerGroupId1, + studentWorkTimestamp1, + { response: studentWorkResponse1 } + ), + createPeerChatComponentState( + studentWorkId2, + exportStrategyTester.workgroupId2, + peerGroupId1, + studentWorkTimestamp2, + { response: studentWorkResponse2 } + ) + ]); + setUpExportStrategy(); + exportStrategyTester.componentExportStrategy.export(); + const headerRow = createHeaderRow(['Prompt']); + expect( + exportStrategyTester.componentExportStrategy.controller.generateCSVFile + ).toHaveBeenCalledWith( + [ + headerRow, + [ + 1, + peerGroupId1, + exportStrategyTester.workgroupId1, + exportStrategyTester.userId1, + exportStrategyTester.studentName1, + '', + '', + '', + '', + exportStrategyTester.periodName, + exportStrategyTester.projectId, + exportStrategyTester.projectTitle, + exportStrategyTester.runId, + exportStrategyTester.startDate, + exportStrategyTester.endDate, + studentWorkTimestamp1, + studentWorkTimestamp1, + exportStrategyTester.nodeId, + exportStrategyTester.component.id, + exportStrategyTester.componentPartNumber, + exportStrategyTester.nodePositionAndTitle, + exportStrategyTester.component.type, + exportStrategyTester.component.prompt, + studentWorkResponse1 + ], + [ + 2, + peerGroupId1, + exportStrategyTester.workgroupId2, + exportStrategyTester.userId2, + exportStrategyTester.studentName2, + '', + '', + '', + '', + exportStrategyTester.periodName, + exportStrategyTester.projectId, + exportStrategyTester.projectTitle, + exportStrategyTester.runId, + exportStrategyTester.startDate, + exportStrategyTester.endDate, + studentWorkTimestamp2, + studentWorkTimestamp2, + exportStrategyTester.nodeId, + exportStrategyTester.component.id, + exportStrategyTester.componentPartNumber, + exportStrategyTester.nodePositionAndTitle, + exportStrategyTester.component.type, + exportStrategyTester.component.prompt, + studentWorkResponse2 + ] + ], + exportStrategyTester.createExpectedFileName('peer_chat') + ); + }); + }); +} + +function exportWithDynamicPrompt(): void { + describe('peer chat component with dynamic prompt', () => { + it('generates export with correct data', () => { + exportStrategyTester.setComponent({ + id: exportStrategyTester.componentId, + type: componentType, + prompt: exportStrategyTester.componentPrompt, + dynamicPrompt: { + enabled: true, + rules: [ + { id: 'r1', expression: '', prompt: dynamicPrompt1 }, + { id: 'r2', expression: '', prompt: dynamicPrompt2 } + ], + prePrompt: prePrompt, + postPrompt: postPrompt + } + }); + exportStrategyTester.setStudentData([ + createPeerChatComponentState( + studentWorkId1, + exportStrategyTester.workgroupId1, + peerGroupId1, + studentWorkTimestamp1, + { response: studentWorkResponse1, dynamicPrompt: { prompt: dynamicPrompt1 } } + ), + createPeerChatComponentState( + studentWorkId2, + exportStrategyTester.workgroupId2, + peerGroupId1, + studentWorkTimestamp2, + { response: studentWorkResponse2, dynamicPrompt: { prompt: dynamicPrompt2 } } + ) + ]); + setUpExportStrategy(); + exportStrategyTester.componentExportStrategy.export(); + const headerRow = createHeaderRow(['Pre Prompt', 'Dynamic Prompt', 'Post Prompt']); + expect( + exportStrategyTester.componentExportStrategy.controller.generateCSVFile + ).toHaveBeenCalledWith( + [ + headerRow, + [ + 1, + peerGroupId1, + exportStrategyTester.workgroupId1, + exportStrategyTester.userId1, + exportStrategyTester.studentName1, + '', + '', + '', + '', + exportStrategyTester.periodName, + exportStrategyTester.projectId, + exportStrategyTester.projectTitle, + exportStrategyTester.runId, + exportStrategyTester.startDate, + exportStrategyTester.endDate, + studentWorkTimestamp1, + studentWorkTimestamp1, + exportStrategyTester.nodeId, + exportStrategyTester.component.id, + exportStrategyTester.componentPartNumber, + exportStrategyTester.nodePositionAndTitle, + exportStrategyTester.component.type, + prePrompt, + dynamicPrompt1, + postPrompt, + studentWorkResponse1 + ], + [ + 2, + peerGroupId1, + exportStrategyTester.workgroupId2, + exportStrategyTester.userId2, + exportStrategyTester.studentName2, + '', + '', + '', + '', + exportStrategyTester.periodName, + exportStrategyTester.projectId, + exportStrategyTester.projectTitle, + exportStrategyTester.runId, + exportStrategyTester.startDate, + exportStrategyTester.endDate, + studentWorkTimestamp2, + studentWorkTimestamp2, + exportStrategyTester.nodeId, + exportStrategyTester.componentId, + exportStrategyTester.componentPartNumber, + exportStrategyTester.nodePositionAndTitle, + exportStrategyTester.component.type, + prePrompt, + dynamicPrompt2, + postPrompt, + studentWorkResponse2 + ] + ], + exportStrategyTester.createExpectedFileName('peer_chat') + ); + }); + }); +} + +function exportWithQuestionBank(): void { + describe('peer chat component with question bank', () => { + it('generates export with correct data', () => { + exportStrategyTester.setComponent({ + id: exportStrategyTester.componentId, + type: componentType, + prompt: exportStrategyTester.componentPrompt, + questionBank: { + enabled: true, + clickToUseEnabled: true, + rules: [ + { id: 'r1', expression: '', questions: [{ id: questionId1, text: question1 }] }, + { id: 'r2', expression: '', questions: [{ id: questionId2, text: question2 }] } + ] + } + }); + exportStrategyTester.setStudentData([ + createPeerChatComponentState( + studentWorkId1, + exportStrategyTester.workgroupId1, + peerGroupId1, + studentWorkTimestamp1, + { + response: studentWorkResponse1, + questionBank: [ + { + questions: [{ id: questionId1, text: question1 }] + } + ], + questionId: questionId1 + } + ), + createPeerChatComponentState( + studentWorkId2, + exportStrategyTester.workgroupId2, + peerGroupId1, + studentWorkTimestamp2, + { + response: studentWorkResponse2, + questionBank: [ + { + questions: [ + { id: questionId1, text: question1 }, + { id: questionId2, text: question2 } + ] + } + ], + questionId: questionId2 + } + ) + ]); + setUpExportStrategy(); + exportStrategyTester.componentExportStrategy.export(); + const headerRow = createHeaderRow(['Prompt', 'Question 1', 'Question 2', 'Question Used']); + expect( + exportStrategyTester.componentExportStrategy.controller.generateCSVFile + ).toHaveBeenCalledWith( + [ + headerRow, + [ + 1, + peerGroupId1, + exportStrategyTester.workgroupId1, + exportStrategyTester.userId1, + exportStrategyTester.studentName1, + '', + '', + '', + '', + exportStrategyTester.periodName, + exportStrategyTester.projectId, + exportStrategyTester.projectTitle, + exportStrategyTester.runId, + exportStrategyTester.startDate, + exportStrategyTester.endDate, + studentWorkTimestamp1, + studentWorkTimestamp1, + exportStrategyTester.nodeId, + exportStrategyTester.component.id, + exportStrategyTester.componentPartNumber, + exportStrategyTester.nodePositionAndTitle, + exportStrategyTester.component.type, + exportStrategyTester.component.prompt, + question1, + '', + question1, + studentWorkResponse1 + ], + [ + 2, + peerGroupId1, + exportStrategyTester.workgroupId2, + exportStrategyTester.userId2, + exportStrategyTester.studentName2, + '', + '', + '', + '', + exportStrategyTester.periodName, + exportStrategyTester.projectId, + exportStrategyTester.projectTitle, + exportStrategyTester.runId, + exportStrategyTester.startDate, + exportStrategyTester.endDate, + studentWorkTimestamp2, + studentWorkTimestamp2, + exportStrategyTester.nodeId, + exportStrategyTester.component.id, + exportStrategyTester.componentPartNumber, + exportStrategyTester.nodePositionAndTitle, + exportStrategyTester.component.type, + exportStrategyTester.component.prompt, + question1, + question2, + question2, + studentWorkResponse2 + ] + ], + exportStrategyTester.createExpectedFileName('peer_chat') + ); + }); + }); +} + +function setUpExportStrategy(): void { + exportStrategyTester.setUpExportStrategy( + new PeerChatComponentDataExportStrategy( + exportStrategyTester.nodeId, + exportStrategyTester.component + ) + ); +} + +function createPeerChatComponentState( + id: number, + workgroupId: number, + peerGroupId: number, + timestamp: string, + studentData: any +): any { + return { + id: id, + workgroupId: workgroupId, + peerGroupId: peerGroupId, + clientSaveTime: timestamp, + serverSaveTime: timestamp, + studentData: studentData + }; +} + +function createHeaderRow(additionalHeaderColumns: string[]): string[] { + const headerRow = copy(exportStrategyTester.componentExportStrategy.defaultColumnNames); + additionalHeaderColumns.forEach((columnName) => { + headerRow.splice(headerRow.indexOf('Reponse'), 0, columnName); + }); + return headerRow; +} diff --git a/src/assets/wise5/classroomMonitor/dataExport/strategies/PeerChatComponentDataExportStrategy.ts b/src/assets/wise5/classroomMonitor/dataExport/strategies/PeerChatComponentDataExportStrategy.ts index 98684ae76c4..7a481e6cab7 100644 --- a/src/assets/wise5/classroomMonitor/dataExport/strategies/PeerChatComponentDataExportStrategy.ts +++ b/src/assets/wise5/classroomMonitor/dataExport/strategies/PeerChatComponentDataExportStrategy.ts @@ -146,7 +146,7 @@ export class PeerChatComponentDataExportStrategy extends AbstractDataExportStrat const workRows = []; for (let r = 0; r < sortedComponentStates.length; r++) { const componentState = sortedComponentStates[r]; - const row = new Array(columnNames.length); + const row = new Array(columnNames.length).fill(''); this.setColumnValue(row, columnNameToNumber, '#', r + 1); this.setStudentInfo(row, columnNameToNumber, componentState); this.setRunInfo(row, columnNameToNumber, componentState); @@ -223,7 +223,9 @@ export class PeerChatComponentDataExportStrategy extends AbstractDataExportStrat this.projectService.getNodePositionAndTitle(nodeId) ); this.setColumnValue(row, columnNameToNumber, 'Component Type', component.type); - this.setColumnValue(row, columnNameToNumber, 'Prompt', component.prompt); + if (!this.hasDynamicPrompt(component)) { + this.setColumnValue(row, columnNameToNumber, 'Prompt', component.prompt); + } } private setStudentWork(