diff --git a/lib/Service/SubmissionService.php b/lib/Service/SubmissionService.php index e059add87..7c9aab902 100644 --- a/lib/Service/SubmissionService.php +++ b/lib/Service/SubmissionService.php @@ -51,6 +51,7 @@ use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Writer\Csv; use Psr\Log\LoggerInterface; @@ -348,6 +349,9 @@ private function exportData(array $header, array $data, string $fileFormat, ?Fil $exportedFile = $this->tempManager->getTemporaryFile($fileFormat); $writer = IOFactory::createWriter($spreadsheet, ucfirst($fileFormat)); + if ($writer instanceof Csv) { + $writer->setUseBOM(true); + } $writer->save($exportedFile); return file_get_contents($exportedFile); diff --git a/tests/Unit/Controller/ApiControllerTest.php b/tests/Unit/Controller/ApiControllerTest.php index 435e3401d..89b0fe0c7 100644 --- a/tests/Unit/Controller/ApiControllerTest.php +++ b/tests/Unit/Controller/ApiControllerTest.php @@ -62,6 +62,7 @@ function time($expected = null) { use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCS\OCSForbiddenException; +use OCP\AppFramework\OCS\OCSNotFoundException; use OCP\IL10N; use OCP\IRequest; use OCP\IUser; @@ -280,7 +281,7 @@ public function testExportSubmissions_invalidForm() { ->method('findByHash') ->with('hash') ->willThrowException($exception); - $this->expectException(OCSBadRequestException::class); + $this->expectException(OCSNotFoundException::class); $this->apiController->exportSubmissions('hash'); } @@ -320,13 +321,19 @@ public function testExportSubmissions() { ->with($form) ->willReturn(true); - $csv = ['data' => '__data__', 'fileName' => 'some.csv']; + $csv = 'foo,bar'; $this->submissionService->expects($this->once()) ->method('getSubmissionsData') - ->with('hash') + ->with($form, 'csv') ->willReturn($csv); - $this->assertEquals(new DataDownloadResponse($csv['data'], $csv['fileName'], 'text/csv'), $this->apiController->exportSubmissions('hash')); + $fileName = 'foo.csv'; + $this->submissionService->expects($this->once()) + ->method('getFileName') + ->with($form, 'csv') + ->willReturn($fileName); + + $this->assertEquals(new DataDownloadResponse($csv, $fileName, 'text/csv'), $this->apiController->exportSubmissions('hash')); } public function testCreateNewForm_notAllowed() { @@ -340,7 +347,7 @@ public function testCreateNewForm_notAllowed() { public function dataTestCreateNewForm() { return [ - "forms" => ['expectedForm' => [ + 'forms' => ['expectedForm' => [ 'id' => 7, 'hash' => 'formHash', 'title' => '', @@ -355,7 +362,9 @@ public function dataTestCreateNewForm() { 'submitMultiple' => false, 'showExpiration' => false, 'lastUpdated' => 123456789, - 'submissionMessage' => '', + 'submissionMessage' => null, + 'fileId' => null, + 'fileFormat' => null, ]] ]; } diff --git a/tests/Unit/FormsMigratorTest.php b/tests/Unit/FormsMigratorTest.php index 2df4991b1..d81b36ab9 100644 --- a/tests/Unit/FormsMigratorTest.php +++ b/tests/Unit/FormsMigratorTest.php @@ -114,10 +114,60 @@ public function setUp(): void { public function dataExport() { return [ 'exactlyOneOfEach' => [ - 'expectedJson' => '[{"title":"Link","description":"","created":1646251830,"access":{"permitAllUsers":false,"showToAllUsers":false},"expires":0,"isAnonymous":false,"submitMultiple":false,"showExpiration":false,"lastUpdated":123456789,"submissionMessage":"Back to website","questions":[{"id":14,"order":2,"type":"multiple","isRequired":false,"text":"checkbox","description":"huhu","extraSettings":{},"options":[{"text":"ans1"}]}],"submissions":[{"userId":"anyUser@localhost","timestamp":1651354059,"answers":[{"questionId":14,"text":"ans1"}]}]}]' + 'expectedJson' => <<<'JSON' +[ + { + "title": "Link", + "description": "", + "fileId": null, + "fileFormat": null, + "created": 1646251830, + "access": { + "permitAllUsers": false, + "showToAllUsers": false + }, + "expires": 0, + "isAnonymous": false, + "submitMultiple": false, + "showExpiration": false, + "lastUpdated": 123456789, + "submissionMessage": "Back to website", + "questions": [ + { + "id": 14, + "order": 2, + "type": "multiple", + "isRequired": false, + "text": "checkbox", + "description": "huhu", + "extraSettings": {}, + "options": [ + { + "text": "ans1" + } + ] + } + ], + "submissions": [ + { + "userId": "anyUser@localhost", + "timestamp": 1651354059, + "answers": [ + { + "questionId": 14, + "text": "ans1" + } + ] + } + ] + } +] +JSON + ] ]; } + /** * @dataProvider dataExport * @@ -213,8 +263,7 @@ public function testExport(string $expectedJson) { $exportDestination->expects($this->once()) ->method('addFileContents') ->will($this->returnCallback(function ($path, $jsonData) use ($expectedJson) { - $this->assertEquals($expectedJson, $jsonData); - return; + $this->assertJsonStringEqualsJsonString($expectedJson, $jsonData); })); $this->formsMigrator->export($user, $exportDestination, $output); } diff --git a/tests/Unit/Service/FormsServiceTest.php b/tests/Unit/Service/FormsServiceTest.php index 0430bda59..c880a7463 100644 --- a/tests/Unit/Service/FormsServiceTest.php +++ b/tests/Unit/Service/FormsServiceTest.php @@ -212,7 +212,9 @@ public function dataGetForm() { 'displayName' => 'Some User' ] ], - 'submissionMessage' => '', + 'submissionMessage' => null, + 'fileId' => null, + 'fileFormat' => null, 'permissions' => Constants::PERMISSION_ALL ]] ]; @@ -419,7 +421,9 @@ public function dataGetPublicForm() { 'permissions' => [ 'submit' ], - 'submissionMessage' => '', + 'submissionMessage' => null, + 'fileId' => null, + 'fileFormat' => null, ]] ]; } @@ -1343,7 +1347,7 @@ public function testNotifyNewSubmission($shares, $shareNotifications) { $form = Form::fromParams(['id' => 42, 'ownerId' => $owner]); $formsService->method('getShares')->willReturn($shares); - + $this->activityManager->expects($this->once()) ->method('publishNewSubmission') ->with($form, $submitter); diff --git a/tests/Unit/Service/SubmissionServiceTest.php b/tests/Unit/Service/SubmissionServiceTest.php index 1086d161b..2f02b6813 100644 --- a/tests/Unit/Service/SubmissionServiceTest.php +++ b/tests/Unit/Service/SubmissionServiceTest.php @@ -41,6 +41,7 @@ use OCP\Files\NotFoundException; use OCP\IConfig; use OCP\IL10N; +use OCP\ITempManager; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; @@ -82,6 +83,9 @@ class SubmissionServiceTest extends TestCase { /** @var IUserManager|MockObject */ private $userManager; + /** @var ITempManager|MockObject */ + private $tempManager; + public function setUp(): void { parent::setUp(); $this->formMapper = $this->createMock(FormMapper::class); @@ -109,6 +113,8 @@ public function setUp(): void { return $identity; })); + $this->tempManager = $this->createMock(ITempManager::class); + $this->submissionService = new SubmissionService( $this->formMapper, $this->questionMapper, @@ -119,7 +125,8 @@ public function setUp(): void { $this->l10n, $this->logger, $this->userManager, - $userSession + $userSession, + $this->tempManager ); } @@ -191,7 +198,7 @@ public function testGetSubmissions() { $this->assertEquals($expected, $this->submissionService->getSubmissions(5)); } - public function dataWriteCsvToCloud() { + public function dataWriteFileToCloud() { return [ 'rootFolder' => ['Some nice Form Title', '', Folder::class, '', 'Some nice Form Title (responses).csv', false], 'subFolder' => ['Some nice Form Title', '/folder path', Folder::class, '', 'Some nice Form Title (responses).csv', false], @@ -202,7 +209,7 @@ public function dataWriteCsvToCloud() { } /** - * @dataProvider dataWriteCsvToCloud + * @dataProvider dataWriteFileToCloud * * @param string $formTitle Given form title * @param string $path Selected user-path (from frontend) @@ -220,6 +227,10 @@ public function testWriteFileToCloud(string $formTitle, string $path, string $pa ->method('putContent') ->with($dataExpectation); + $fileNode->expects($this->once()) + ->method('getContent') + ->willReturn(''); + $folderNode = $this->createMock(Folder::class); if ($fileExists) { $folderNode->expects($this->once()) @@ -264,7 +275,11 @@ public function testWriteFileToCloud(string $formTitle, string $path, string $pa ->with('currentUser') ->willReturn($userFolder); - $this->assertEquals($expectedFileName, $this->submissionService->writeFileToCloud('abcdefg', $path)); + $this->tempManager->expects($this->once()) + ->method('getTemporaryFile') + ->willReturn('/tmp/abcdefg.csv'); + + $this->submissionService->writeFileToCloud('abcdefg', $path, 'csv'); } // Data for SubmissionCsv @@ -300,8 +315,8 @@ public function dataGetSubmissionsCsv() { // Expected CSV-Result ' "User ID","User display name","Timestamp","Question 1","Question 2" - "user1","User 1","1973-11-29T22:33:09+01:00","Q1A1","Q2A1" - "user2","User 2","1973-11-29T22:33:09+01:00","Q1A2","Q2A2" + "user1","User 1","1973-11-29T22:33:09+01:00","Q1A2","Q2A2" + "user2","User 2","1973-11-29T22:33:09+01:00","Q1A1","Q2A1" ' ], 'checkbox-multi-answers' => [ @@ -419,11 +434,13 @@ public function dataGetSubmissionsCsv() { */ public function testGetSubmissionsCsv(array $questions, array $submissions, string $csvText) { $dataExpectation = $this->setUpCsvTest($questions, $submissions, $csvText, 'Some nice Form Title'); + $form = $this->formMapper->findByHash('abcdefg'); + + $this->tempManager->expects($this->once()) + ->method('getTemporaryFile') + ->willReturn('/tmp/abcdefg.csv'); - $this->assertEquals([ - 'fileName' => 'Some nice Form Title (responses).csv', - 'data' => $dataExpectation, - ], $this->submissionService->getSubmissionsData('abcdefg')); + $this->assertEquals($dataExpectation, $this->submissionService->getSubmissionsData($form, 'csv')); } /**