Skip to content

Commit

Permalink
feat(Authoring): Add Peer Grouping Different Scores logic (#901)
Browse files Browse the repository at this point in the history
  • Loading branch information
geoffreykwan authored Nov 18, 2022
1 parent a481f65 commit ee226ad
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 42 deletions.
21 changes: 21 additions & 0 deletions src/app/domain/peerGrouping.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import {
DIFFERENT_IDEAS_REGEX,
DIFFERENT_SCORES_REGEX
} from '../../assets/wise5/authoringTool/peer-grouping/PeerGroupingLogic';
import { ReferenceComponent } from './referenceComponent';

export class PeerGrouping {
logic: string;
maxMembershipCount: number;
Expand All @@ -13,4 +19,19 @@ export class PeerGrouping {
}
}
}

getDifferentIdeasReferenceComponent(): ReferenceComponent {
const result = new RegExp(DIFFERENT_IDEAS_REGEX).exec(this.logic);
return new ReferenceComponent(result[1], result[2]);
}

getDifferentScoresReferenceComponent(): ReferenceComponent {
const result = new RegExp(DIFFERENT_SCORES_REGEX).exec(this.logic);
return new ReferenceComponent(result[1], result[2]);
}

getDifferentScoresMode(): string {
const result = new RegExp(DIFFERENT_SCORES_REGEX).exec(this.logic);
return result[4];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@ export interface PeerGroupingLogic {
export const DIFFERENT_IDEAS_NAME = $localize`Different Ideas`;
export const DIFFERENT_IDEAS_REGEX = /differentIdeas\("(\w+)",\s*"(\w+)"\)/g;
export const DIFFERENT_IDEAS_VALUE = 'differentIdeas';
export const DIFFERENT_SCORES_NAME = $localize`Different Scores`;
export const DIFFERENT_SCORES_REGEX = /differentKIScores\("(\w+)",\s*"(\w+)?"(,\s*")?(\w+)?(")?\)/g;
export const DIFFERENT_SCORES_VALUE = 'differentKIScores';

export const AVAILABLE_LOGIC: PeerGroupingLogic[] = [
{ name: $localize`Random`, value: 'random' },
{ name: $localize`Manual`, value: 'manual' },
{ name: DIFFERENT_IDEAS_NAME, value: DIFFERENT_IDEAS_VALUE }
{ name: DIFFERENT_IDEAS_NAME, value: DIFFERENT_IDEAS_VALUE },
{ name: DIFFERENT_SCORES_NAME, value: DIFFERENT_SCORES_VALUE }
];

export const AVAILABLE_MODES: any[] = [
{ name: $localize`Any`, value: 'any' },
{ name: $localize`Maximize`, value: 'maximize' }
];
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ import { MatDialogRef } from '@angular/material/dialog';
import { PeerGrouping } from '../../../../../app/domain/peerGrouping';
import { ReferenceComponent } from '../../../../../app/domain/referenceComponent';
import { ProjectService } from '../../../services/projectService';
import { AVAILABLE_LOGIC, DIFFERENT_IDEAS_VALUE, PeerGroupingLogic } from '../PeerGroupingLogic';
import {
AVAILABLE_LOGIC,
AVAILABLE_MODES,
DIFFERENT_IDEAS_VALUE,
DIFFERENT_SCORES_VALUE,
PeerGroupingLogic
} from '../PeerGroupingLogic';

@Directive()
export abstract class AuthorPeerGroupingDialogComponent implements OnInit {
allowedReferenceComponentTypes: string[] = ['OpenResponse'];
availableLogic: PeerGroupingLogic[];
logicType: string;
mode: string;
availableModes: any[] = AVAILABLE_MODES;
peerGrouping: PeerGrouping;
referenceComponent: ReferenceComponent = new ReferenceComponent(null, null);

Expand Down Expand Up @@ -39,10 +47,30 @@ export abstract class AuthorPeerGroupingDialogComponent implements OnInit {
}

protected updatePeerGroupingLogic(): void {
this.peerGrouping.logic =
this.logicType === DIFFERENT_IDEAS_VALUE
? `${DIFFERENT_IDEAS_VALUE}("${this.referenceComponent.nodeId}", "${this.referenceComponent.componentId}")`
: this.logicType;
switch (this.logicType) {
case DIFFERENT_IDEAS_VALUE:
this.peerGrouping.logic = `${DIFFERENT_IDEAS_VALUE}("${this.referenceComponent.nodeId}", "${this.referenceComponent.componentId}")`;
break;
case DIFFERENT_SCORES_VALUE:
this.peerGrouping.logic = this.generateDifferentScoresLogic(
this.referenceComponent,
this.mode
);
break;
default:
this.peerGrouping.logic = this.logicType;
}
}

private generateDifferentScoresLogic(
referenceComponent: ReferenceComponent,
mode: string
): string {
if (mode == null) {
return `${DIFFERENT_SCORES_VALUE}("${referenceComponent.nodeId}", "${referenceComponent.componentId}")`;
} else {
return `${DIFFERENT_SCORES_VALUE}("${referenceComponent.nodeId}", "${referenceComponent.componentId}", "${mode}")`;
}
}

cancel(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ <h3 mat-dialog-title i18n>Create New Peer Grouping</h3>
</mat-option>
</mat-select>
</mat-form-field>
<ng-container *ngIf="logicType === 'differentIdeas'">
<ng-container *ngIf="logicType === 'differentIdeas' || logicType === 'differentKIScores'">
<edit-connected-component-node-select
[connectedComponent]="referenceComponent"
(connectedComponentChange)="referenceComponentNodeIdChanged($event)">
Expand All @@ -26,6 +26,18 @@ <h3 mat-dialog-title i18n>Create New Peer Grouping</h3>
[allowedConnectedComponentTypes]="allowedReferenceComponentTypes">
</edit-connected-component-component-select>
</ng-container>
<ng-container *ngIf="logicType === 'differentKIScores'">
<mat-form-field>
<mat-label i18n>Mode</mat-label>
<mat-select [(ngModel)]="mode">
<ng-container *ngFor="let mode of availableModes">
<mat-option [value]="mode.value">
{{ mode.name }}
</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
</ng-container>
</div>
<!-- <div>
<mat-form-field>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ describe('CreateNewPeerGroupingDialogComponent', () => {
function create() {
create_RandomLogic_ShouldCreatePeerGroup();
create_DifferentIdeasLogic_ShouldCreatePeerGroup();
create_DifferentScoresAnyLogic_ShouldCreatePeerGroup();
create_DifferentScoresMaximizeLogic_ShouldCreatePeerGroup();
}

function create_RandomLogic_ShouldCreatePeerGroup() {
Expand Down Expand Up @@ -73,3 +75,33 @@ function create_DifferentIdeasLogic_ShouldCreatePeerGroup() {
expect(dialogCloseSpy).toHaveBeenCalled();
});
}

function create_DifferentScoresAnyLogic_ShouldCreatePeerGroup() {
it('should create peer grouping with different scores any logic', async () => {
expectDifferentScoresLogicCreateNewPeerGrouping('any');
});
}

function create_DifferentScoresMaximizeLogic_ShouldCreatePeerGroup() {
it('should create peer grouping with different scores maximize logic', async () => {
expectDifferentScoresLogicCreateNewPeerGrouping('maximize');
});
}

function expectDifferentScoresLogicCreateNewPeerGrouping(mode: string) {
const newPeerGrouping = new PeerGrouping({
logic: `differentKIScores("${REFERENCE_COMPONENT_NODE_ID1}", "${REFERENCE_COMPONENT_COMPONENT_ID1}", "${mode}")`,
maxMembershipCount: 2,
tag: TAG1
});
createNewPeerGroupingSpy.and.returnValue(of(newPeerGrouping));
component.logicType = 'differentKIScores';
component.referenceComponent = new ReferenceComponent(
REFERENCE_COMPONENT_NODE_ID1,
REFERENCE_COMPONENT_COMPONENT_ID1
);
component.mode = mode;
component.create();
expect(createNewPeerGroupingSpy).toHaveBeenCalledWith(newPeerGrouping);
expect(dialogCloseSpy).toHaveBeenCalled();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h3 mat-dialog-title i18n>Edit Peer Grouping</h3>
</mat-option>
</mat-select>
</mat-form-field>
<ng-container *ngIf="logicType === 'differentIdeas'">
<ng-container *ngIf="logicType === 'differentIdeas' || logicType === 'differentKIScores'">
<edit-connected-component-node-select
[connectedComponent]="referenceComponent"
(connectedComponentChange)="referenceComponentNodeIdChanged($event)">
Expand All @@ -23,6 +23,18 @@ <h3 mat-dialog-title i18n>Edit Peer Grouping</h3>
[allowedConnectedComponentTypes]="allowedReferenceComponentTypes">
</edit-connected-component-component-select>
</ng-container>
<ng-container *ngIf="logicType === 'differentKIScores'">
<mat-form-field>
<mat-label i18n>Mode</mat-label>
<mat-select [(ngModel)]="mode">
<ng-container *ngFor="let mode of availableModes">
<mat-option [value]="mode.value">
{{ mode.name }}
</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
</ng-container>
</div>
<div>
<mat-form-field>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,43 @@ function savePeerGrouping() {
});

it('should save peer grouping with random logic', () => {
savePeerGroupingWithLogic('random', 'random');
savePeerGroupingWithLogic('random', null, 'random');
});

it('should save peer grouping with manual logic', () => {
savePeerGroupingWithLogic('manual', 'manual');
savePeerGroupingWithLogic('manual', null, 'manual');
});

it('should save peer grouping with different ideas logic', () => {
savePeerGroupingWithLogic(DIFFERENT_IDEAS_VALUE, 'differentIdeas("node1", "component1")');
savePeerGroupingWithLogic(DIFFERENT_IDEAS_VALUE, null, 'differentIdeas("node1", "component1")');
});

it('should save peer grouping with different scores any logic', () => {
savePeerGroupingWithLogic(
'differentKIScores',
'any',
'differentKIScores("node1", "component1", "any")'
);
});

it('should save peer grouping with different scores maximize logic', () => {
savePeerGroupingWithLogic(
'differentKIScores',
'maximize',
'differentKIScores("node1", "component1", "maximize")'
);
});
}

function savePeerGroupingWithLogic(logicType: string, expectedLogic: string) {
function savePeerGroupingWithLogic(logicType: string, mode: string, expectedLogic: string) {
const peerGrouping = new PeerGrouping();
component.peerGrouping = peerGrouping;
component.logicType = logicType;
component.referenceComponent = {
nodeId: 'node1',
componentId: 'component1'
};
component.mode = mode;
spyOn(TestBed.inject(PeerGroupingAuthoringService), 'updatePeerGrouping').and.returnValue(
of(peerGrouping)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { PeerGrouping } from '../../../../../app/domain/peerGrouping';
import { PeerGroupingAuthoringService } from '../../../services/peerGroupingAuthoringService';
import { ProjectService } from '../../../services/projectService';
import { UtilService } from '../../../services/utilService';
import { AuthorPeerGroupingDialogComponent } from '../author-peer-grouping-dialog/author-peer-grouping-dialog.component';
import { DIFFERENT_IDEAS_REGEX, DIFFERENT_IDEAS_VALUE } from '../PeerGroupingLogic';
import { ReferenceComponent } from '../../../../../app/domain/referenceComponent';
import {
DIFFERENT_IDEAS_REGEX,
DIFFERENT_IDEAS_VALUE,
DIFFERENT_SCORES_REGEX,
DIFFERENT_SCORES_VALUE
} from '../PeerGroupingLogic';

@Component({
selector: 'edit-peer-grouping-dialog',
Expand All @@ -20,28 +23,31 @@ export class EditPeerGroupingDialogComponent extends AuthorPeerGroupingDialogCom
@Inject(MAT_DIALOG_DATA) public peerGrouping: PeerGrouping,
protected dialogRef: MatDialogRef<EditPeerGroupingDialogComponent>,
private peerGroupingAuthoringService: PeerGroupingAuthoringService,
protected projectService: ProjectService,
private utilService: UtilService
protected projectService: ProjectService
) {
super(dialogRef, projectService);
}

ngOnInit(): void {
this.peerGrouping = this.utilService.makeCopyOfJSONObject(this.peerGrouping);
this.peerGrouping = new PeerGrouping(this.peerGrouping);
this.stepsUsedIn = this.peerGroupingAuthoringService.getStepsUsedIn(this.peerGrouping.tag);
this.logicType = this.getLogicType(this.peerGrouping.logic);
if (this.logicType === DIFFERENT_IDEAS_VALUE) {
this.referenceComponent = this.getDifferentIdeasReferenceComponent(this.peerGrouping.logic);
this.referenceComponent = this.peerGrouping.getDifferentIdeasReferenceComponent();
} else if (this.logicType === DIFFERENT_SCORES_VALUE) {
this.referenceComponent = this.peerGrouping.getDifferentScoresReferenceComponent();
this.mode = this.peerGrouping.getDifferentScoresMode();
}
}

private getLogicType(logic: string): string {
return new RegExp(DIFFERENT_IDEAS_REGEX).exec(logic) != null ? DIFFERENT_IDEAS_VALUE : logic;
}

private getDifferentIdeasReferenceComponent(logic: string): ReferenceComponent {
const result = new RegExp(DIFFERENT_IDEAS_REGEX).exec(logic);
return new ReferenceComponent(result[1], result[2]);
if (new RegExp(DIFFERENT_IDEAS_REGEX).exec(logic) != null) {
return DIFFERENT_IDEAS_VALUE;
} else if (new RegExp(DIFFERENT_SCORES_REGEX).exec(logic) != null) {
return DIFFERENT_SCORES_VALUE;
} else {
return logic;
}
}

save(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SelectPeerGroupingOptionComponent } from './select-peer-grouping-option
import { getDialogOpenSpy } from '../peer-grouping-testing-helper';
import { PeerGrouping } from '../../../../../app/domain/peerGrouping';
import { StudentTeacherCommonServicesModule } from '../../../../../app/student-teacher-common-services.module';
import { DIFFERENT_IDEAS_NAME } from '../PeerGroupingLogic';
import { DIFFERENT_IDEAS_NAME, DIFFERENT_SCORES_NAME } from '../PeerGroupingLogic';

let component: SelectPeerGroupingOptionComponent;
let deleteEventSpy: jasmine.Spy;
Expand Down Expand Up @@ -68,10 +68,25 @@ function setPeerGroupingLogicName() {
it('should set peer grouping logic name when logic is different ideas', () => {
setAndExpectPeerGroupingLogic('differentIdeas("node1", "componen1")', DIFFERENT_IDEAS_NAME);
});
it('should set peer grouping logic name when logic is different scores any', () => {
setAndExpectPeerGroupingLogic(
'differentKIScores("node1", "componen1", "any")',
DIFFERENT_SCORES_NAME
);
});
it('should set peer grouping logic name when logic is different scores maximize', () => {
setAndExpectPeerGroupingLogic(
'differentKIScores("node1", "componen1", "maximize")',
DIFFERENT_SCORES_NAME
);
});
}

function setAndExpectPeerGroupingLogic(logic: string, expectedLogicName: string) {
component.peerGrouping.logic = logic;
component.setPeerGroupingLogicName();
fixture = TestBed.createComponent(SelectPeerGroupingOptionComponent);
component = fixture.componentInstance;
peerGrouping1 = new PeerGrouping({ tag: tag1, logic: logic });
component.peerGrouping = peerGrouping1;
fixture.detectChanges();
expect(component.peerGroupingLogicName).toEqual(expectedLogicName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { MatDialog } from '@angular/material/dialog';
import { PeerGrouping } from '../../../../../app/domain/peerGrouping';
import { PeerGroupingAuthoringService } from '../../../services/peerGroupingAuthoringService';
import { EditPeerGroupingDialogComponent } from '../edit-peer-grouping-dialog/edit-peer-grouping-dialog.component';
import { AVAILABLE_LOGIC, DIFFERENT_IDEAS_NAME, DIFFERENT_IDEAS_REGEX } from '../PeerGroupingLogic';
import {
AVAILABLE_LOGIC,
DIFFERENT_IDEAS_NAME,
DIFFERENT_IDEAS_REGEX,
DIFFERENT_SCORES_NAME,
DIFFERENT_SCORES_REGEX
} from '../PeerGroupingLogic';

@Component({
selector: 'select-peer-grouping-option',
Expand Down Expand Up @@ -34,9 +40,11 @@ export class SelectPeerGroupingOptionComponent implements OnInit {
}
}

setPeerGroupingLogicName(): void {
private setPeerGroupingLogicName(): void {
if (new RegExp(DIFFERENT_IDEAS_REGEX).exec(this.peerGrouping.logic) != null) {
this.peerGroupingLogicName = DIFFERENT_IDEAS_NAME;
} else if (new RegExp(DIFFERENT_SCORES_REGEX).exec(this.peerGrouping.logic) != null) {
this.peerGroupingLogicName = DIFFERENT_SCORES_NAME;
} else {
this.peerGroupingLogicName = AVAILABLE_LOGIC.find(
(logic) => logic.value === this.peerGrouping.logic
Expand Down
Loading

0 comments on commit ee226ad

Please sign in to comment.