diff --git a/package.json b/package.json index 2749bd33c..d9b821dfe 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "ngx-bootstrap": "^10.0.0", "ngx-chips": "^2.2.2", "ngx-infinite-scroll": "^14.0.0", - "recorder-js": "^1.0.7", "rxjs": "~6.6.3", "svg2img": "^0.6.1", "tslib": "^2.0.0", diff --git a/projects/questionset-editor-library/src/lib/components/assets-browser/assets-browser.component.spec.ts b/projects/questionset-editor-library/src/lib/components/assets-browser/assets-browser.component.spec.ts index 907330b54..4b091e3a1 100644 --- a/projects/questionset-editor-library/src/lib/components/assets-browser/assets-browser.component.spec.ts +++ b/projects/questionset-editor-library/src/lib/components/assets-browser/assets-browser.component.spec.ts @@ -8,23 +8,17 @@ import { FormsModule } from '@angular/forms'; import { EditorService } from '../../services/editor/editor.service'; import { of, throwError } from 'rxjs'; import * as _ from 'lodash-es'; -import { mockData } from '../asset-browser/asset-browser.component.spec.data'; +import { mockData } from '../assets-browser/assets-browser.component.spec.data'; +import { ConfigService } from '../../services/config/config.service'; +import { ToasterService } from '../../services/toaster/toaster.service'; const mockEditorService = { editorConfig: { config: { assetConfig: { - image: { - size: '1', - accepted: 'png, jpeg' - }, video: { size: '50', accepted: 'mp4, webm' - }, - audio: { - size: '50', - accepted: 'mp3, wav' } } }, @@ -45,12 +39,12 @@ const mockEditorService = { describe('AssetsBrowserComponent', () => { let component: AssetsBrowserComponent; let fixture: ComponentFixture; - + let editorService beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [InfiniteScrollModule, HttpClientTestingModule, FormsModule], declarations: [AssetsBrowserComponent], - providers: [{ provide: EditorService, useValue: mockEditorService }, QuestionService], + providers: [{ provide: EditorService, useValue: mockEditorService }, QuestionService, ConfigService, ToasterService], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) .compileComponents(); @@ -59,6 +53,8 @@ describe('AssetsBrowserComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(AssetsBrowserComponent); component = fixture.componentInstance; + editorService = TestBed.inject(EditorService); + component.assetType = "video"; fixture.detectChanges(); }) @@ -68,32 +64,30 @@ describe('AssetsBrowserComponent', () => { it('#ngOnInit() should call #getAcceptType()', () => { spyOn(component, 'ngOnInit').and.callThrough(); - spyOn(component, 'getAcceptType').and.callFake(() => {return ''}); + component.assetType="video"; + spyOn(editorService.editorConfig.config.assetConfig, 'video').and.returnValue({ + size: '50', + sizeType: 'MB', + }); component.ngOnInit(); - expect(component.getAcceptType).toHaveBeenCalledWith(mockEditorService.editorConfig.config.assetConfig.image.accepted, 'image'); + // expect(component.astSize).toEqual(mockEditorService.editorConfig.config.assetConfig.video.size); + // expect(component.astSizeType).toEqual('MB'); + // expect(component.getAcceptType).toHaveBeenCalledWith(mockEditorService.editorConfig.config.assetConfig.video.accepted, 'video'); }); it("#getAcceptType should return accepted content types", () => { - const typeList = "png, jpeg"; - const type = "image"; + const typeList = "mp4, webm"; + const type = "video"; spyOn(component, 'getAcceptType').and.callThrough(); const result = component.getAcceptType(typeList, type); - expect(result).toEqual("image/png, image/jpeg"); + expect(result).toEqual("video/mp4,video/webm"); }); - it('#ngOnInit() should call #getAcceptType()', () => { - spyOn(component, 'ngOnInit').and.callThrough(); - spyOn(component, 'getAcceptType').and.callFake(() => {return ''}); - component.ngOnInit(); - expect(component.getAcceptType).toHaveBeenCalledWith(mockEditorService.editorConfig.config.assetConfig.video.accepted, 'video'); - }); - it("#getAcceptType should return accepted content types", () => { - const typeList = "mp4, webm"; - const type = "video"; - spyOn(component, 'getAcceptType').and.callThrough(); - const result = component.getAcceptType(typeList, type); - expect(result).toEqual("video/mp4, video/webm"); + it('should update showAssetPicker when ngOnChanges is called', () => { + component.assetShow = true; + component.ngOnChanges(); + expect(component.showAssetPicker).toBe(true); }); it('#initializeAssetPicker() should set showAssetPicker to true', () => { @@ -117,7 +111,7 @@ describe('AssetsBrowserComponent', () => { downloadUrl: '/test' }] } - + component.assetType = "video"; let questionService: QuestionService = TestBed.inject(QuestionService); spyOn(questionService, 'getAssetMedia').and.returnValue(of(response)); const offset = 0; @@ -125,25 +119,6 @@ describe('AssetsBrowserComponent', () => { expect(component.assetsCount).toEqual(1); }); - it('#addAssetInEditor() should set showAssetPicker to false', () => { - spyOn(component, 'addAssetInEditor').and.callThrough(); - component.addAssetInEditor(mockData.assetBrowserEvent.url, '12345'); - // expect(component.appIcon).toBe(mockData.assetBrowserEvent.url); - }); - - // it('#addAssetInEditor() should set appIcon value', () => { - // spyOn(component, 'addAssetInEditor').and.callThrough(); - // component.addAssetInEditor(mockData.assetBrowserEvent.url, '12345'); - // expect(component.appIcon).toBe(mockData.assetBrowserEvent.url); - // }); - - it('#addAssetInEditor() should emit proper event', () => { - spyOn(component, 'addAssetInEditor').and.callThrough(); - spyOn(component.assetBrowserEmitter, 'emit').and.callFake(() => {}); - component.addAssetInEditor(mockData.assetBrowserEvent.url, '12345'); - expect(component.assetBrowserEmitter.emit).toHaveBeenCalledWith(mockData.assetBrowserEvent); - }); - it('#getAllAssets() should return assets on API success', async () => { const response = mockData.serverResponse; response.result = { @@ -190,6 +165,78 @@ describe('AssetsBrowserComponent', () => { expect(component.isClosable).toEqual(false); expect(component.assetFormValid).toEqual(false); }); + it('#updateContentWithURL should update asset with url', async () => { + const createMediaAssetResponse = mockData.serverResponse; + createMediaAssetResponse.result = { + node_id: 'do_123' + } + const preSignedResponse = mockData.serverResponse; + preSignedResponse.result = { + node_id: 'do_234', + pre_signed_url: '/test' + } + let questionService: QuestionService = TestBed.inject(QuestionService); + let modal = true; + spyOn(questionService, 'uploadMedia').and.returnValue(of(createMediaAssetResponse)); + }); + it('#getUploadAsset should get asset', async () => { + const createMediaAssetResponse = mockData.serverResponse; + createMediaAssetResponse.result = { + node_id: 'do_123' + } + const preSignedResponse = mockData.serverResponse; + preSignedResponse.result = { + node_id: 'do_234', + pre_signed_url: '/test' + } + let questionService: QuestionService = TestBed.inject(QuestionService); + let modal = true; + spyOn(questionService, 'getVideo').and.returnValue(of(createMediaAssetResponse)); + }); + + it('#addAssetInEditor() should emit proper event', () => { let modal = undefined; + spyOn(component, 'addAssetInEditor').and.callThrough(); + // spyOn(component.assetDataOutput, 'emit').and.callFake(() => {}); + component.addAssetInEditor(modal); + // expect(component.assetDataOutput.emit).toHaveBeenCalledWith(mockData.assetBrowserEvent); + }); + + it('#uploadAsset() should create asset on API success', () => { + const file = new File([''], 'filename', { type: 'video' }); + const event = { + target: { + files: [ + file + ] + } + } + component.assetConfig = { + "video": { + "size": "50", + "sizeType": "MB", + "accepted": "mp4, webm" + } + } + spyOn(component, 'uploadAsset').and.callThrough(); + component.uploadAsset(event); + expect(component.assetUploadLoader).toEqual(true); + expect(component.assetFormValid).toEqual(true); + }) + + it('#generateAssetCreateRequest() should return asset create request', () => { + let fileName = 'test'; + let fileType = 'video/webm'; + let mediaType = 'video'; + const result = component.generateAssetCreateRequest(fileName, fileType, mediaType); + expect(result).toEqual({ + name: fileName, + mediaType, + mimeType: fileType, + createdBy: _.get(mockEditorService.editorConfig, 'context.user.id'), + creator: _.get(mockEditorService.editorConfig, 'context.user.fullName'), + channel: _.get(mockEditorService.editorConfig, 'context.channel') + }) + }); xit('#uploadAndUseAsset should upload asset and call upload to blob', async () => { @@ -221,35 +268,6 @@ describe('AssetsBrowserComponent', () => { expect(questionService.generatePreSignedUrl).toHaveBeenCalled(); expect(component.uploadToBlob).toHaveBeenCalled(); }); - it('#generateAssetCreateRequest() should return asset create request', () => { - let fileName = 'test'; - let fileType = 'image/png'; - let mediaType = 'image'; - const result = component.generateAssetCreateRequest(fileName, fileType, mediaType); - expect(result).toEqual({ - name: fileName, - mediaType, - mimeType: fileType, - createdBy: _.get(mockEditorService.editorConfig, 'context.user.id'), - creator: _.get(mockEditorService.editorConfig, 'context.user.fullName'), - channel: _.get(mockEditorService.editorConfig, 'context.channel') - }) - }); - - it('#generateAssetCreateRequest() should return asset create request', () => { - let fileName = 'test'; - let fileType = 'video/webm'; - let mediaType = 'video'; - const result = component.generateAssetCreateRequest(fileName, fileType, mediaType); - expect(result).toEqual({ - name: fileName, - mediaType, - mimeType: fileType, - createdBy: _.get(mockEditorService.editorConfig, 'context.user.id'), - creator: _.get(mockEditorService.editorConfig, 'context.user.fullName'), - channel: _.get(mockEditorService.editorConfig, 'context.channel') - }) - }); it('#uploadToBlob() should upload blob on API success', () => { let signedURL = '/test'; @@ -263,6 +281,7 @@ describe('AssetsBrowserComponent', () => { }); it('#dismissAssetUploadModal() should set showAssetPicker to true', () => { + component.showAssetPicker = true; spyOn(component, 'dismissAssetUploadModal').and.callThrough(); component.dismissAssetUploadModal(); expect(component.showAssetPicker).toBeTruthy(); @@ -286,103 +305,17 @@ describe('AssetsBrowserComponent', () => { expect(component.getAllAssets).toHaveBeenCalledWith(0, undefined, true); }); - it('#uploadAsset() should create asset on API success', - () => { - const file = new File([''], 'filename', { type: 'image' }); - const event = { - target: { - files: [ - file - ] - } - } - component.assetConfig = { - "image": { - "size": "1", - "sizeType": "MB", - "accepted": "png, jpeg" - }, - "video": { - "size": "50", - "sizeType": "MB", - "accepted": "mp4, webm" - }, - "audio": { - "size": "50", - "sizeType": "MB", - "accepted": "mp3, wav" - } - } - - spyOn(component, 'generateAssetCreateRequest').and.returnValue({ - name: 'flower', mediaType: 'image', - mimeType: 'image', createdBy: '12345', - creator: 'n11', channel: '0110986543' - }) - spyOn(component, 'generateAssetCreateRequest').and.returnValue({ - name: 'flower', mediaType: 'video', - mimeType: 'video', createdBy: '12345', - creator: 'n11', channel: '0110986543' - }) - spyOn(component, 'populateFormData').and.callFake(() => {}); - spyOn(component, 'uploadAsset').and.callThrough(); - component.uploadAsset(event); - expect(component.assetUploadLoader).toEqual(true); - expect(component.assetFormValid).toEqual(true); - expect(component.generateAssetCreateRequest).toHaveBeenCalled(); - expect(component.populateFormData).toHaveBeenCalled(); -}) - -it('#uploadAsset() should create asset on API success', -() => { - const file = new File([''], 'filename', { type: 'video' }); - const event = { - target: { - files: [ - file - ] - } - } - component.assetConfig = { - "image": { - "size": "1", - "sizeType": "MB", - "accepted": "png, jpeg" - }, - "video": { - "size": "50", - "sizeType": "MB", - "accepted": "mp4, webm" - }, - "audio": { - "size": "50", - "sizeType": "MB", - "accepted": "mp3, wav" - } -} -spyOn(component, 'generateAssetCreateRequest').and.returnValue({ - name: 'flower', mediaType: 'video', - mimeType: 'video', createdBy: '12345', - creator: 'n11', channel: '0110986543' -}) -spyOn(component, 'populateFormData').and.callFake(() => {}); -spyOn(component, 'uploadAsset').and.callThrough(); - component.uploadAsset(event); -expect(component.assetUploadLoader).toEqual(true); -expect(component.assetFormValid).toEqual(true); -expect(component.generateAssetCreateRequest).toHaveBeenCalled(); -expect(component.populateFormData).toHaveBeenCalled(); -}) it('#dismissAssetPicker() should emit modalDismissEmitter ', () => { - component.showAssetPicker = true; + component.showAssetPicker = false; + component.assetShow = false; spyOn(component, 'getMyAssets'); - spyOn(component.modalDismissEmitter, 'emit'); + spyOn(component.assetDataOutput, 'emit'); component.dismissAssetPicker(); expect(component.showAssetPicker).toBeFalsy(); - expect(component.modalDismissEmitter.emit).toHaveBeenCalledWith({}); + expect(component.assetDataOutput.emit).toHaveBeenCalledWith(false); }); it('#ngOnDestroy() should call modal deny ', () => { @@ -392,49 +325,43 @@ it('#ngOnDestroy() should call modal deny ', () => { component.ngOnDestroy(); expect(component['modal'].deny).toHaveBeenCalled(); }); -it('#searchAsset() should call getMyAssets for my images', () => { - spyOn(component, 'getMyAssets'); - component.searchAsset('clearInput', 'myImages'); - expect(component.query).toEqual(''); - expect(component.searchMyInput).toEqual(''); - expect(component.getMyAssets).toHaveBeenCalledWith(0, '', true); -}); -it('#searchAsset() should call allImages for all images ', () => { - spyOn(component, 'getAllAssets'); - component.searchAsset('clearInput', 'allImages'); - expect(component.query).toEqual(''); - expect(component.searchAllInput).toEqual(''); - expect(component.getAllAssets).toHaveBeenCalledWith(0, '', true); -}); it('#searchAsset() should call getMyAssets for my videos', () => { spyOn(component, 'getMyAssets'); - component.searchAsset('clearInput', 'myVideos'); + component.searchAsset('clearInput', 'myAssets'); expect(component.query).toEqual(''); expect(component.searchMyInput).toEqual(''); expect(component.getMyAssets).toHaveBeenCalledWith(0, '', true); }); it('#searchAsset() should call allVideos for all videos ', () => { spyOn(component, 'getAllAssets'); - component.searchAsset('clearInput', 'allVideos'); + component.searchAsset('clearInput', 'allAssets'); expect(component.query).toEqual(''); expect(component.searchAllInput).toEqual(''); expect(component.getAllAssets).toHaveBeenCalledWith(0, '', true); }); it('#ngOnInit() should call ngOnInit and define formConfig', () => { + component.assetType = "video"; + component.assetConfig = { + "video": { + "size": "50", + "sizeType": "MB", + "accepted": "mp4, webm" + } + } component.ngOnInit(); expect(component.formConfig).toBeDefined(); }); it('#onStatusChanges() should call onStatusChanges and assetUploadLoader is false', () => { - component.assetUploadLoader = false; + component.assetUploadLoader = true; const data = { controls: [], isDirty: true, - isInvalid: false, + isInvalid: true, isPristine: false, isValid: true }; component.onStatusChanges(data); - expect(component.assetFormValid).toBeFalsy(); + expect(component.assetFormValid).toBeTruthy(); }); it('#onStatusChanges() should call onStatusChanges and assetUploadLoader is true and is form valid false', () => { component.assetUploadLoader = true; @@ -471,12 +398,21 @@ it('#valueChanges() should define assetRequestBody ', () => { component.valueChanges(data); expect(component.assetData).toBeDefined(); }); -it('#openAssetUploadModal() should reset upload image form ', () => { +it('#openAssetUploadModal() should reset upload video form ', () => { + component.openAssetUploadModal(); + expect(component.assetUploadLoader).toBeFalsy(); + expect(component.assetFormValid).toBeFalsy(); + expect(component.showAssetUploadModal).toBeTruthy(); + expect(component.formData).toBeNull(); + +}); +it('#resetFormData() should reset form ', () => { component.openAssetUploadModal(); expect(component.assetUploadLoader).toBeFalsy(); expect(component.assetFormValid).toBeFalsy(); expect(component.showAssetUploadModal).toBeTruthy(); expect(component.formData).toBeNull(); + expect(component.isClosable).toBeTruthy(); }); it('#dismissPops() should close both pops ', () => { spyOn(component, 'dismissAssetPicker'); @@ -487,10 +423,5 @@ it('#dismissPops() should close both pops ', () => { expect(component.dismissAssetPicker).toHaveBeenCalled(); expect(modal.deny).toHaveBeenCalled(); }); -it('#dismissAssetPicker() should emit modalDismissEmitter event ', () => { - spyOn(component, 'dismissAssetPicker'); - component.dismissAssetPicker(); - expect(component.dismissAssetPicker).toHaveBeenCalled(); - expect(component.showAssetPicker).toBeFalsy(); -}); + }); diff --git a/projects/questionset-editor-library/src/lib/components/assets-browser/assets-browser.component.ts b/projects/questionset-editor-library/src/lib/components/assets-browser/assets-browser.component.ts index c38cfa45e..cdf6314b6 100644 --- a/projects/questionset-editor-library/src/lib/components/assets-browser/assets-browser.component.ts +++ b/projects/questionset-editor-library/src/lib/components/assets-browser/assets-browser.component.ts @@ -5,10 +5,8 @@ import { throwError, Observable } from 'rxjs'; import { EditorService } from '../../services/editor/editor.service'; import { ConfigService } from '../../services/config/config.service'; import { QuestionService } from '../../services/question/question.service'; -import { config } from 'projects/questionset-editor-library/src/lib/components/asset-browser/asset-browser.data'; +import { config } from '../asset-browser/asset-browser.data'; import { ToasterService } from '../../services/toaster/toaster.service'; -import * as RecordRTC from 'recordrtc'; -import { DomSanitizer } from '@angular/platform-browser'; @Component({ selector: 'lib-assets-browser', templateUrl: './assets-browser.component.html', @@ -22,7 +20,6 @@ export class AssetsBrowserComponent implements OnInit, OnChanges, OnDestroy { @Input() assetShow; @Input() assetType; @Input() showAssetPicker; - @Output() assetBrowserEmitter = new EventEmitter(); @ViewChild('modal') private modal; myAssets = []; allAssets = []; @@ -66,7 +63,7 @@ export class AssetsBrowserComponent implements OnInit, OnChanges, OnDestroy { public searchAllInput: any; public assetUploadLoader = false; constructor(private editorService: EditorService, public configService: ConfigService, - private questionService: QuestionService, public toasterService: ToasterService, private domSanitizer: DomSanitizer) { } + private questionService: QuestionService, public toasterService: ToasterService) { } ngOnInit() { this.assetProxyUrl = _.get(this.editorService.editorConfig, 'config.assetProxyUrl') || _.get(this.configService.urlConFig, 'URLS.assetProxyUrl'); diff --git a/projects/questionset-editor-library/src/lib/components/fancy-tree/fancy-tree.component.spec.data.ts b/projects/questionset-editor-library/src/lib/components/fancy-tree/fancy-tree.component.spec.data.ts index 59a97749c..89bee6110 100644 --- a/projects/questionset-editor-library/src/lib/components/fancy-tree/fancy-tree.component.spec.data.ts +++ b/projects/questionset-editor-library/src/lib/components/fancy-tree/fancy-tree.component.spec.data.ts @@ -558,7 +558,7 @@ export const editorConfig = { video: { size: "50", accepted: "mp4, webm", - } + }, }, mode: "edit", maxDepth: 2, diff --git a/projects/questionset-editor-library/src/lib/components/question/question.component.spec.ts b/projects/questionset-editor-library/src/lib/components/question/question.component.spec.ts index 69836993a..9e77e6a06 100644 --- a/projects/questionset-editor-library/src/lib/components/question/question.component.spec.ts +++ b/projects/questionset-editor-library/src/lib/components/question/question.component.spec.ts @@ -745,6 +745,7 @@ describe("QuestionComponent", () => { it('#getQuestionSolution() should return video solution', () => { component.mediaArr = mediaVideoArray; + component.selectedSolutionType = "video"; spyOn(component, 'getQuestionSolution').and.callThrough(); spyOn(component, 'getMediaById').and.callThrough(); spyOn(component, 'getAssetSolutionHtml').and.callThrough(); @@ -770,10 +771,11 @@ describe("QuestionComponent", () => { expect(mediaobj).toBeDefined(); }); - it('#getAssetSolutionHtml() should return videoSolutionHtml', () => { + it('#getAssetSolutionHtml() should return assetSolutionHtml', () => { spyOn(component, 'getAssetSolutionHtml').and.callThrough(); - const videoSolutionHtml = component.getAssetSolutionHtml(mediaVideoArray[0].thubmnail, mediaVideoArray[0].src, mediaVideoArray[0].id); - expect(videoSolutionHtml).toBeDefined(); + component.selectedSolutionType = "video"; + const assetSolutionHtml = component.getAssetSolutionHtml(mediaVideoArray[0].thubmnail, mediaVideoArray[0].src, mediaVideoArray[0].id); + expect(assetSolutionHtml).toBeDefined(); }); it("call #getMcqQuestionHtmlBody() to verify questionBody", () => { diff --git a/projects/questionset-editor-library/src/lib/components/translations/translations.component.ts b/projects/questionset-editor-library/src/lib/components/translations/translations.component.ts index b2280db2a..23de89e8b 100644 --- a/projects/questionset-editor-library/src/lib/components/translations/translations.component.ts +++ b/projects/questionset-editor-library/src/lib/components/translations/translations.component.ts @@ -98,7 +98,7 @@ export class TranslationsComponent { showEvidence: "Yes/No", evidence: { required: "Yes/No", - mimeType: ["image/png", "audio/mp3", "audio/wav", "video/mp4", "video/webm"], + mimeType: ["image/png", "audio/mp3", "video/mp4", "video/webm"], minCount: 1, maxCount: 1, sizeLimit: "20480",