Skip to content

Commit

Permalink
Issue #IQ-681 feat: Enhance QuML editor to upload audio based solutions.
Browse files Browse the repository at this point in the history
  • Loading branch information
rajnishdargan committed Mar 1, 2024
2 parents 467efc0 + f6130a5 commit ed381ef
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 23 deletions.
2 changes: 1 addition & 1 deletion projects/questionset-editor-library/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@project-sunbird/sunbird-questionset-editor",
"version": "7.0.4",
"version": "8.0.0-beta.0",
"dependencies": {
"tslib": "^2.0.0"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<ng-container [ngSwitch]="pageId">
<ng-container *ngSwitchCase="'questionset_editor'">
<div class="add-to-library mb-10">
<lib-header [pageId]="pageId" [publishchecklist]="publishchecklist"
[labelConfigData]="toolbarConfig" [buttonLoaders]="buttonLoaders" (toolbarEmitter)="toolbarEventListener($event)"> </lib-header>
<lib-header [pageId]="pageId" [publishchecklist]="publishchecklist" [rejectComment]="draftComment"
[labelConfigData]="toolbarConfig" [buttonLoaders]="buttonLoaders" (toolbarEmitter)="toolbarEventListener($event)" (reviewerComment)="saveDraftComments($event)"> </lib-header>
<div class="h-100vh sb-bg-white">
<div class="ui">
<div class="ui twelve column grid m-0 ">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4012,3 +4012,11 @@ export const categoryDefinitionPublishCheckList = {
}
}
};
export const fakeComment = 'sample comment';
export const fakeApiResponse = {
result: {
comments: [
{ identifier: 'do_113431883451195392169', comment: fakeComment },
],
},
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EditorService } from './../../services/editor/editor.service';
import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing';
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { EditorComponent } from './editor.component';
import { CUSTOM_ELEMENTS_SCHEMA, EventEmitter } from '@angular/core';
import { HttpClientTestingModule } from '@angular/common/http/testing';
Expand All @@ -15,7 +15,7 @@ import {
SelectedNodeMockData, observationAndRubericsField,
questionsetRead, questionsetHierarchyRead, nodesModifiedData, treeNodeData,
questionSetEditorConfig, categoryDefinitionPublishCheckList,
frameworkData, serverResponse } from './editor.component.spec.data';
frameworkData, serverResponse, fakeApiResponse } from './editor.component.spec.data';
import { ConfigService } from '../../services/config/config.service';
import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
import { treeData } from './../fancy-tree/fancy-tree.component.spec.data';
Expand Down Expand Up @@ -124,6 +124,7 @@ describe('EditorComponent', () => {
spyOn(editorService, 'getshowQuestionLibraryPageEmitter').and.callFake(() => {return questionLibraryPage});
spyOn(component, 'showQuestionLibraryComponentPage').and.callFake(() => {});
spyOn(component, 'getFrameworkDetails').and.callFake(() => {})
spyOn(editorService, 'readComment').and.returnValue(of(fakeApiResponse));
component.ngOnInit();
expect(component.editorConfig).toBeDefined();
expect(editorService.initialize).toHaveBeenCalledWith(editorConfig);
Expand All @@ -141,6 +142,7 @@ describe('EditorComponent', () => {
expect(telemetryService.initializeTelemetry).toHaveBeenCalled();
expect(telemetryService.telemetryPageId).toEqual('questionset_editor');
expect(telemetryService.start).toHaveBeenCalled();
expect(editorService.readComment).toHaveBeenCalled();
});

it('#ngOnInit() should call all methods inside it (for objectType Question)', () => {
Expand Down Expand Up @@ -1544,6 +1546,12 @@ describe('EditorComponent', () => {
expect(returnChildrenData).toBeDefined();
});


it('should save draft comments successfully', () => {
const comment = { id: 1, text: 'Valid comment' };
const editorService = TestBed.inject(EditorService);
spyOn(editorService, 'updateComment')
component.saveDraftComments(comment);
expect(editorService.updateComment).toHaveBeenCalled();
});
});

Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export class EditorComponent implements OnInit, OnDestroy, AfterViewInit {
public unSubscribeshowQuestionLibraryPageEmitter: Subscription;
public sourcingSettings: any;
public setChildQuestion: any;
draftComment:string = '';
public unsubscribe$ = new Subject<void>();
public onComponentDestroy$ = new Subject<any>();
constructor(private editorService: EditorService, public treeService: TreeService, private frameworkService: FrameworkService,
Expand Down Expand Up @@ -153,6 +154,9 @@ export class EditorComponent implements OnInit, OnDestroy, AfterViewInit {
this.getFrameworkDetails(this.primaryCategoryDef);
}
});
this.editorService.readComment(this.collectionId).subscribe((res) => {
this.draftComment = res.result.comments[0].comment;
})
}

handleQuestionObjectType() {
Expand Down Expand Up @@ -1130,4 +1134,10 @@ export class EditorComponent implements OnInit, OnDestroy, AfterViewInit {
return response;
}

saveDraftComments(comment) {
this.editorService.updateComment(this.collectionId,comment);
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@
<sui-modal *ngIf="showRequestChangesPopup" [mustScroll]="true" [isClosable]="false" [transitionDuration]="0"
[size]="'normal'" class="sb-modal bx-none overflow-modal" appBodyScroll #modal (dismissed)="showRequestChangesPopup = false;">
<div class="sb-modal-header">
{{configService.labelConfig?.lbl?.addReviewComments}}
<h5>{{configService.labelConfig?.lbl?.addReviewComments}}</h5>
<i class="close icon" (click)="modal.deny('denied')"></i>
</div>
<form #FormControl="ngForm" class="ui form">
<div class="sb-modal-content">
Expand All @@ -198,12 +199,12 @@
</div>
</div>
<div class="sb-modal-actions">
<button id="submitReview" type="submit" class="sb-btn sb-btn-normal" [ngClass]="{'sb-btn-primary': FormControl.form.valid, 'sb-btn-disabled': !FormControl.form.valid}" (click)="buttonEmitter({type: actionType, comment: rejectComment}); showRequestChangesPopup = false;"
[disabled]="!FormControl.form.valid" libTelemetryInteract
[telemetryInteractEdata]="telemetryService.getTelemetryInteractEdata('submit_review','click','submit', telemetryService.telemetryPageId, {key: 'dialog_id', value: 'add_review_comments'})"
> {{configService.labelConfig?.button_labels?.submit_review_btn_label}} </button>
<button class="sb-btn sb-btn-normal sb-btn-outline-primary" (click)="modal.deny('denied')"
libTelemetryInteract [telemetryInteractEdata]="telemetryService.getTelemetryInteractEdata('cancel','click','cancel', telemetryService.telemetryPageId, {key: 'dialog_id', value: 'add_review_comments'})">{{configService.labelConfig?.button_labels?.cancel_btn_label}}</button>
<button id="submitReview" class="sb-btn sb-btn-normal" [ngClass]="{'sb-btn-primary': FormControl.form.valid, 'sb-btn-disabled': !FormControl.form.valid}" (click)="saveDraftComments()"
libTelemetryInteract
[telemetryInteractEdata]="telemetryService.getTelemetryInteractEdata('save_comment','click','save', telemetryService.telemetryPageId, {key: 'dialog_id', value: 'add_review_comments'})"
> {{configService.labelConfig?.button_labels?.save_draft_btn_label}} </button>
<button [disabled]="!FormControl.form.valid" type="submit" class="sb-btn sb-btn-normal sb-btn-outline-primary" (click)="buttonEmitter({type: actionType, comment: rejectComment}); showRequestChangesPopup = false;"
libTelemetryInteract [telemetryInteractEdata]="telemetryService.getTelemetryInteractEdata('submit_review','click','submit', telemetryService.telemetryPageId, {key: 'dialog_id', value: 'add_review_comments'})">{{configService.labelConfig?.button_labels?.submit_review_btn_label}}</button>
</div>
</form>
</sui-modal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@
.sb-modal-fullscreen .modals.dimmer .ui.scrolling.modal{
margin: 0 auto !important;
}
.sb-modal-header {
display: flex;
justify-content: space-between;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ComponentFixture, TestBed, tick,fakeAsync, waitForAsync } from '@angular/core/testing';
import { HeaderComponent } from './header.component';
import { CUSTOM_ELEMENTS_SCHEMA, EventEmitter } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TelemetryInteractDirective } from '../../directives/telemetry-interact/telemetry-interact.directive';
import { EditorService } from '../../services/editor/editor.service';
import { of } from 'rxjs/internal/observable/of';

describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
let editorService: EditorService;
let emitSpy :jasmine.Spy;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
Expand All @@ -23,6 +26,8 @@ describe('HeaderComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
editorService = TestBed.inject(EditorService);
emitSpy = spyOn(component.reviewerComment, 'emit').and.callThrough();
// fixture.detectChanges();
});

Expand Down Expand Up @@ -57,10 +62,10 @@ describe('HeaderComponent', () => {
component.handleActionButtons();
expect(component.visibility).toBeDefined();
});
it('#openRequestChangePopup() should actionType defined', () => {
it('#openRequestChangePopup() should actionType defined',() => {
component.openRequestChangePopup('sendForCorrections');
expect(component.showRequestChangesPopup).toBeTruthy();
expect(component.actionType).toBe('sendForCorrections');
expect(component.showRequestChangesPopup).toBe(true);
});
it('#buttonEmitter() should call buttonEmitter', () => {
const data = { type: 'previewContent' };
Expand Down Expand Up @@ -97,4 +102,17 @@ describe('HeaderComponent', () => {
expect(component.showPublishCollectionPopup).toBeTruthy();
expect(component.actionType).toBeDefined();
});

it('should deny modal and emit reviewer comment', () => {
const rejectComment = 'Your reject comment'; // Provide a reject comment for testing
component.rejectComment = rejectComment;
component.modal = {
deny: jasmine.createSpy('denied')
};

component.saveDraftComments();

expect(component.modal.deny).toBeDefined() // Expect modal.deny to be called with 'denied'
expect(emitSpy).toHaveBeenCalledWith(rejectComment); // Expect reviewerComment.emit to be called with the provided reject comment
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { NgForm } from '@angular/forms';
})
export class HeaderComponent implements OnDestroy, OnInit {
@Input() pageId: any;
@Input() rejectComment: string;
@Input() labelConfigData: any;
@Input() buttonLoaders: any;
@Input() publishchecklist: any;
Expand All @@ -22,13 +23,13 @@ export class HeaderComponent implements OnDestroy, OnInit {
}
}
@Output() toolbarEmitter = new EventEmitter<any>();
@Output() reviewerComment = new EventEmitter<any>();
@ViewChild('FormControl') FormControl: NgForm;
@ViewChild('modal') public modal;
@Output() qualityParamEmitter = new EventEmitter<any>();
public visibility: any;
public showPublishCollectionPopup: boolean;
public showRequestChangesPopup: boolean;
public rejectComment: string;
public actionType: string;
public objectType: string;
public sourcingStatusText: string;
Expand Down Expand Up @@ -103,6 +104,11 @@ export class HeaderComponent implements OnDestroy, OnInit {
}
}

saveDraftComments() {
this.modal.deny('denied')
this.reviewerComment.emit(this.rejectComment);
}

ngOnDestroy() {
if (this?.modal && this?.modal?.deny) {
this.modal.deny();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"create_new_btn_label":"Create New",
"add_from_library_btn_label":" Add from library",
"submit_review_btn_label":"Submit Review",
"save_draft_btn_label":"Save as draft",
"delete_btn_label":"Delete",
"next_btn_label":"Next",
"remove_btn_label":"Remove",
Expand Down Expand Up @@ -233,7 +234,8 @@
"037": "Question accepted successfully",
"038": "Content is successfully approved",
"039": "Content is successfully rejected",
"040": "Content sent back for corrections"
"040": "Content sent back for corrections",
"043": "Comment saved successfully"
}
},
"categoryLabels": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"HIERARCHY_READ": "questionset/v2/hierarchy",
"SYSYTEM_UPDATE": "questionset/v5/system/update/",
"HIERARCHY_UPDATE": "questionset/v2/hierarchy/update",
"DEFAULT_PARAMS_FIELDS": "instructions,outcomeDeclaration"
"DEFAULT_PARAMS_FIELDS": "instructions,outcomeDeclaration",
"UPDATE_COMMENT":"questionset/v2/comment/update/",
"READ_COMMENT":"questionset/v2/comment/read"
},
"Question": {
"HIERARCHY_READ": "questionset/v2/hierarchy",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ConfigService } from '../config/config.service';
import * as urlConfig from '../../services/config/url.config.json';
import * as labelConfig from '../../services/config/label.config.json';
import * as categoryConfig from '../../services/config/category.config.json';
import { of } from 'rxjs';
import { of, throwError } from 'rxjs';
import { PublicDataService } from '../public-data/public-data.service';
import { ToasterService } from '../../services/toaster/toaster.service';
import { TreeService } from '../tree/tree.service';
Expand All @@ -19,6 +19,7 @@ import * as _ from 'lodash-es';
describe('EditorService', () => {
let editorService: EditorService;
let treeService;
let toasterService;
const configStub = {
urlConFig: (urlConfig as any).default,
labelConfig: (labelConfig as any).default,
Expand All @@ -39,7 +40,9 @@ describe('EditorService', () => {
urlConFig: {
URLS: {
questionSet: {
SYSYTEM_UPDATE: ''
SYSYTEM_UPDATE: '',
UPDATE_COMMENT:"questionset/v2/comment/update/",
READ_COMMENT:"questionset/v2/comment/read"
}
}
}
Expand All @@ -53,6 +56,7 @@ describe('EditorService', () => {
PublicDataService,
{ provide: ConfigService, useValue: configStub }]
});
toasterService = TestBed.inject(ToasterService);
editorService = TestBed.inject(EditorService);
treeService = TestBed.inject(TreeService);
editorService.initialize(editorConfig);
Expand Down Expand Up @@ -486,4 +490,33 @@ describe('EditorService', () => {
expect(config).toEqual({});
});

it('#readComment() should read comments of questionset', async () => {
const publicDataService = TestBed.inject(PublicDataService);
spyOn(publicDataService, 'get').and.returnValue(of(mockData.serverResponse));
editorService.readComment('do_113941643543011328112').subscribe(data => {
expect(data.responseCode).toEqual('OK');
});
});

it('should handle successful comment update', () => {
const publicDataService = TestBed.inject(PublicDataService);
spyOn(publicDataService,'patch').and.returnValue(of(mockData.serverResponse));
spyOn(toasterService, 'success');

editorService.updateComment('contentId', 'comment');

expect(publicDataService.patch).toHaveBeenCalled();
});

it('should handle error during comment update', () => {
const publicDataService = TestBed.inject(PublicDataService);
const error = new Error('Failed to update comment');
spyOn(publicDataService,'patch').and.returnValue(throwError(error));

editorService.updateComment('contentId', 'comment');

expect(publicDataService.patch).toHaveBeenCalled();
});


});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable, EventEmitter } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Observable, Subject, throwError } from 'rxjs';
import * as _ from 'lodash-es';
import { TreeService } from '../tree/tree.service';
import { PublicDataService } from '../public-data/public-data.service';
Expand Down Expand Up @@ -249,7 +249,32 @@ export class EditorService {
return this.publicDataService.post(option);
}

submitRequestChanges(contentId, comment) {
updateComment(contentId,comment) {
const url = this.configService.urlConFig.URLS[this.editorConfig.config.objectType];
const option = {
url: url.UPDATE_COMMENT+contentId,
data: { request: { comments : [{ comment : comment }] }}
};
this.publicDataService.patch(option).subscribe((res) => {
this.toasterService.success(_.get(this.configService, 'labelConfig.messages.success.043'));
},(error) => {
const errInfo = {
errorMsg: _.get(this.configService, 'labelConfig.messages.error.006'),
};
return throwError(this.apiErrorHandling(error, errInfo))
});
}

readComment(contentId:string): Observable<any> {
const url = this.configService.urlConFig.URLS[this.editorConfig.config.objectType];
const hierarchyUrl = `${url.READ_COMMENT}/${contentId}`;
const req = {
url: hierarchyUrl,
};
return this.publicDataService.get(req);
}

submitRequestChanges(contentId:string, comment:string) {
let objType = this.configService.categoryConfig[this.editorConfig.config.objectType];
objType = objType.toLowerCase();
const url = this.configService.urlConFig.URLS[this.editorConfig.config.objectType];
Expand Down

0 comments on commit ed381ef

Please sign in to comment.