diff --git a/src/content/def/requests.ts b/src/content/def/requests.ts index 2d3808a05..9052235c6 100644 --- a/src/content/def/requests.ts +++ b/src/content/def/requests.ts @@ -91,6 +91,7 @@ export interface ContentImport { export interface ContentExportRequest { destinationFolder: string; contentIds: string[]; + saveLocally?: boolean; } export interface ContentMarkerRequest { diff --git a/src/content/handlers/export/copy-to-destination.spec.ts b/src/content/handlers/export/copy-to-destination.spec.ts new file mode 100644 index 000000000..e169746e1 --- /dev/null +++ b/src/content/handlers/export/copy-to-destination.spec.ts @@ -0,0 +1,83 @@ +import { CopyToDestination } from './copy-to-destination'; +import {FileService} from '../../../util/file/def/file-service'; +import {ContentEntry} from '../../db/schema'; +import {Response} from '../../../api' + +describe('CopyToDestination', () => { + let copyToDestination: CopyToDestination; + const mockFileService: Partial = {}; + + beforeAll(() => { + copyToDestination = new CopyToDestination(); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should be create a instance of copy asset', () => { + expect(copyToDestination).toBeTruthy(); + }); + + it('should be copied a file by invoked exicute() for error MEssage', async (done) => { + // arrange + const contentEntrySchema: ContentEntry.SchemaMap[] = [{ + identifier: 'IDENTIFIER', + server_data: 'SERVER_DATA', + local_data: '{"children": [{"DOWNLOAD": 1}, "do_234", "do_345"], "artifactUrl": "http:///do_123"}', + mime_type: 'MIME_TYPE', + manifest_version: 'MAINFEST_VERSION', + content_type: 'CONTENT_TYPE', + content_state: 2, + }]; + + const exportContext = { + destinationFolder: 'SAMPLE_DESTINATION_FOLDER', + tmpLocationPath: 'SAMPLE_TEMP_PATH', + contentModelsToExport: contentEntrySchema, + items: ['artifactUrl'], + metadata: {'SAMPLE_KEY': 'SAMPLE_META_DATA'}, + ecarFilePath: 'sampledir/samplefile' + }; + const response: Response = new Response(); + + response.body = exportContext; + // act + await copyToDestination.execute(response, 'SAMPLE_DESTINATION_FOLDER').then((result) => { + // assert + expect(result).toEqual(response); + done(); + }); + }); + + it('should be copied a file by invoked exicute() for error MEssage', async (done) => { + // arrange + const contentEntrySchema: ContentEntry.SchemaMap[] = [{ + identifier: 'IDENTIFIER', + server_data: 'SERVER_DATA', + local_data: '{"children": [{"DOWNLOAD": 1}, "do_234", "do_345"], "artifactUrl": "http:///do_123"}', + mime_type: 'MIME_TYPE', + manifest_version: 'MAINFEST_VERSION', + content_type: 'CONTENT_TYPE', + content_state: 2, + }]; + + const exportContext = { + destinationFolder: 'SAMPLE_DESTINATION_FOLDER', + tmpLocationPath: 'SAMPLE_TEMP_PATH', + contentModelsToExport: contentEntrySchema, + items: ['artifactUrl'], + metadata: {'SAMPLE_KEY': 'SAMPLE_META_DATA'}, + ecarFilePath: 'sampledir/samplefile' + }; + const response: Response = new Response(); + + response.body = exportContext; + // act + await copyToDestination.execute(response, 'SAMPLE_DESTINATION_FOLDER').catch((result) => { + // assert + done(); + }); + }); + +}); diff --git a/src/content/handlers/export/copy-to-destination.ts b/src/content/handlers/export/copy-to-destination.ts new file mode 100644 index 000000000..8a1ff0a03 --- /dev/null +++ b/src/content/handlers/export/copy-to-destination.ts @@ -0,0 +1,28 @@ +import { Response } from '../../../api'; +import {FileUtil} from '../../../util/file/util/file-util'; +import { ContentExportRequest } from '../..'; + +export class CopyToDestination { + + constructor() { + } + + public async execute(exportResponse: Response, contentExportRequest: ContentExportRequest): Promise { + return new Promise((resolve, reject) => { + let destinationFolder; + if (contentExportRequest.saveLocally) { + destinationFolder = contentExportRequest.destinationFolder; + } else { + destinationFolder = cordova.file.externalCacheDirectory; + } + buildconfigreader.copyFile(FileUtil.getDirecory(exportResponse.body.ecarFilePath), destinationFolder, + FileUtil.getFileName(exportResponse.body.ecarFilePath), + () => { + resolve(exportResponse); + }, err => { + console.error(err); + resolve(err); + }); + }); + } +} diff --git a/src/content/handlers/export/deletete-temp-dir.ts b/src/content/handlers/export/deletete-temp-dir.ts new file mode 100644 index 000000000..679501ace --- /dev/null +++ b/src/content/handlers/export/deletete-temp-dir.ts @@ -0,0 +1,22 @@ +import {Response} from '../../../api'; +import {ExportContentContext} from '../..'; + +export class DeleteTempDir { + + constructor() { + } + + public async execute(exportContext: ExportContentContext): Promise { + const response: Response = new Response(); + return new Promise((resolve, reject) => { + const tmpDirPath = exportContext.destinationFolder!.concat('tmp/'); + buildconfigreader.rm(tmpDirPath, '', () => { + response.body = exportContext; + resolve(response); + }, (e) => { + response.body = exportContext; + resolve(response); + }); + }); + } +} diff --git a/src/content/handlers/export/generate-export-share-telemetry.ts b/src/content/handlers/export/generate-export-share-telemetry.ts index 16eb9857a..28c514e08 100644 --- a/src/content/handlers/export/generate-export-share-telemetry.ts +++ b/src/content/handlers/export/generate-export-share-telemetry.ts @@ -1,4 +1,4 @@ -import {ContentExportResponse, ExportContentContext} from '../..'; +import {ContentExportResponse, ExportContentContext, ContentExportRequest} from '../..'; import {Response} from '../../../api'; import {Item, ShareDirection, ShareItemType, ShareType, TelemetryService, TelemetryShareRequest} from '../../../telemetry'; import {ContentUtil} from '../../util/content-util'; @@ -7,7 +7,7 @@ export class GenerateExportShareTelemetry { constructor(private telemetryService: TelemetryService) { } - execute(exportContentContext: ExportContentContext): Promise { + execute(exportContentContext: ExportContentContext, fileName: string, contentExportRequest: ContentExportRequest): Promise { const response: Response = new Response(); const items: Item[] = []; for (const element of exportContentContext.items!) { @@ -28,7 +28,13 @@ export class GenerateExportShareTelemetry { }; return this.telemetryService.share(req).toPromise() .then(() => { - const exportResponse: ContentExportResponse = {exportedFilePath: exportContentContext.ecarFilePath!}; + let exportedFilePath; + if (contentExportRequest.saveLocally) { + exportedFilePath = contentExportRequest.destinationFolder.concat(fileName); + } else { + exportedFilePath = cordova.file.externalCacheDirectory.concat(fileName); + } + const exportResponse: ContentExportResponse = {exportedFilePath: exportedFilePath}; response.body = exportResponse; return Promise.resolve(response); }).catch(() => { diff --git a/src/content/impl/content-service-impl.ts b/src/content/impl/content-service-impl.ts index d94a69440..9284422b2 100644 --- a/src/content/impl/content-service-impl.ts +++ b/src/content/impl/content-service-impl.ts @@ -93,6 +93,8 @@ import {SdkConfig} from '../../sdk-config'; import {DeviceInfo} from '../../util/device'; import {GetContentHeirarchyHandler} from './../handlers/get-content-heirarchy-handler'; import {catchError, map, mapTo, mergeMap, take} from 'rxjs/operators'; +import { CopyToDestination } from '../handlers/export/copy-to-destination'; +import { DeleteTempDir } from './../handlers/export/deletete-temp-dir'; @injectable() export class ContentServiceImpl implements ContentService, DownloadCompleteDelegate, SdkServiceOnInitDelegate { @@ -276,9 +278,9 @@ export class ContentServiceImpl implements ContentService, DownloadCompleteDeleg contentModelsToExport: contentsInDb, tmpLocationPath: tempLocationPath.nativeURL }; - return new CleanTempLoc(this.fileService).execute(exportContentContext); - }).then((exportResponse: Response) => { - return new CreateTempLoc(this.fileService).execute(exportResponse.body); + // return new CleanTempLoc(this.fileService).execute(exportContentContext); + // }).then((exportResponse: Response) => { + return new CreateTempLoc(this.fileService).execute(exportContentContext); }).then((exportResponse: Response) => { return new CreateContentExportManifest(this.dbService, exportHandler).execute(exportResponse.body); }).then((exportResponse: Response) => { @@ -292,9 +294,16 @@ export class ContentServiceImpl implements ContentService, DownloadCompleteDeleg }).then((exportResponse: Response) => { return new EcarBundle(this.fileService, this.zipService).execute(exportResponse.body); }).then((exportResponse: Response) => { - return new DeleteTempEcar(this.fileService).execute(exportResponse.body); + return new CopyToDestination().execute(exportResponse, contentExportRequest); + // }).then((exportResponse: Response) => { + // return new DeleteTempEcar(this.fileService).execute(exportResponse.body); + }).then((exportResponse: Response) => { + return new DeleteTempDir().execute(exportResponse.body); }).then((exportResponse: Response) => { - return new GenerateExportShareTelemetry(this.telemetryService).execute(exportResponse.body); + const fileName = ContentUtil.getExportedFileName(contentsInDb); + return new GenerateExportShareTelemetry( + this.telemetryService).execute(exportResponse.body, fileName, contentExportRequest + ); }).then((exportResponse: Response) => { return exportResponse.body; });