From 89910031cd143192b99a16a1f9b9f022b68e8ca7 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Jul 2018 18:31:02 +0200 Subject: [PATCH] Test the attachment controller. --- .../V1/Controllers/AttachmentController.php | 10 +- database/factories/ModelFactory.php | 26 +- .../V1/Controllers/AccountControllerTest.php | 2 +- .../Controllers/AttachmentControllerTest.php | 295 ++++++++++++++++++ 4 files changed, 323 insertions(+), 10 deletions(-) create mode 100644 tests/Api/V1/Controllers/AttachmentControllerTest.php diff --git a/app/Api/V1/Controllers/AttachmentController.php b/app/Api/V1/Controllers/AttachmentController.php index cdc5a8cd75..8dae717b38 100644 --- a/app/Api/V1/Controllers/AttachmentController.php +++ b/app/Api/V1/Controllers/AttachmentController.php @@ -172,9 +172,9 @@ class AttachmentController extends Controller /** * Store a newly created resource in storage. * - * @param \Illuminate\Http\Request $request + * @param AttachmentRequest $request * - * @return \Illuminate\Http\Response + * @return JsonResponse * @throws FireflyException */ public function store(AttachmentRequest $request): JsonResponse @@ -214,16 +214,16 @@ class AttachmentController extends Controller * @param Request $request * @param Attachment $attachment * - * @return LaravelResponse + * @return JsonResponse */ - public function upload(Request $request, Attachment $attachment): LaravelResponse + public function upload(Request $request, Attachment $attachment): JsonResponse { /** @var AttachmentHelperInterface $helper */ $helper = app(AttachmentHelperInterface::class); $body = $request->getContent(); $helper->saveAttachmentFromApi($attachment, $body); - return response('', 200); + return response()->json([], 204); } } \ No newline at end of file diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index 668e584a90..9a702f7221 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -46,6 +46,24 @@ $factory->define( } ); + +$factory->define( + FireflyIII\Models\Attachment::class, + function (Faker\Generator $faker) { + return [ + 'user_id' => 1, + 'attachable_id' => 1, + 'attachable_type' => \FireflyIII\Models\TransactionJournal::class, + 'md5' => md5($faker->words(6, true)), + 'mime' => 'text/plain', + 'size' => 1, + 'filename' => 'ok', + 'uploaded' => true, + + ]; + } +); + $factory->define( FireflyIII\Models\CurrencyExchangeRate::class, function (Faker\Generator $faker) { @@ -245,13 +263,13 @@ $factory->define( 'transaction_amount' => (string)$faker->randomFloat(2, -100, 100), 'destination_amount' => (string)$faker->randomFloat(2, -100, 100), 'opposing_account_id' => $faker->numberBetween(1, 10), - 'source_id' => $faker->numberBetween(1, 10), + 'source_id' => $faker->numberBetween(1, 10), 'opposing_account_name' => $faker->words(3, true), 'description' => $faker->words(3, true), - 'source_name' => $faker->words(3, true), - 'destination_id' => $faker->numberBetween(1, 10), + 'source_name' => $faker->words(3, true), + 'destination_id' => $faker->numberBetween(1, 10), 'date' => new Carbon, - 'destination_name' => $faker->words(3, true), + 'destination_name' => $faker->words(3, true), 'amount' => (string)$faker->randomFloat(2, -100, 100), 'budget_id' => 0, 'category' => $faker->words(3, true), diff --git a/tests/Api/V1/Controllers/AccountControllerTest.php b/tests/Api/V1/Controllers/AccountControllerTest.php index e1c235d769..a35fbd0def 100644 --- a/tests/Api/V1/Controllers/AccountControllerTest.php +++ b/tests/Api/V1/Controllers/AccountControllerTest.php @@ -40,7 +40,7 @@ class AccountControllerTest extends TestCase /** * */ - public function setUp() + public function setUp(): void { parent::setUp(); Passport::actingAs($this->user()); diff --git a/tests/Api/V1/Controllers/AttachmentControllerTest.php b/tests/Api/V1/Controllers/AttachmentControllerTest.php new file mode 100644 index 0000000000..77398f7c6d --- /dev/null +++ b/tests/Api/V1/Controllers/AttachmentControllerTest.php @@ -0,0 +1,295 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Api\V1\Controllers; + +use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; +use FireflyIII\Models\Attachment; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use Laravel\Passport\Passport; +use Log; +use Tests\TestCase; + +/** + * + * Class AttachmentControllerTest + */ +class AttachmentControllerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Passport::actingAs($this->user()); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * Destroy account over API. + * + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + */ + public function testDelete(): void + { + // mock stuff: + $repository = $this->mock(AttachmentRepositoryInterface::class); + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('destroy')->once()->andReturn(true); + + // get attachment: + $attachment = $this->user()->attachments()->first(); + + // call API + $response = $this->delete('/api/v1/attachments/' . $attachment->id); + $response->assertStatus(204); + } + + /** + * Download attachment + * + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + */ + public function testDownload(): void + { + // mock stuff: + $repository = $this->mock(AttachmentRepositoryInterface::class); + $content = 'Attachment content ' . random_int(100, 1000); + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('exists')->andReturn(true)->once(); + $repository->shouldReceive('getContent')->andReturn($content)->once(); + + // get attachment: + $attachment = $this->user()->attachments()->first(); + + // call API + $response = $this->get('/api/v1/attachments/' . $attachment->id . '/download'); + + $response->assertStatus(200); + $response->assertSee($content); + + } + + /** + * Download attachment but file doesn't exist. + * + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + * @expectedExceptionMessage Some error message + */ + public function testDownloadNotExisting(): void + { + // mock stuff: + $repository = $this->mock(AttachmentRepositoryInterface::class); + $content = 'Attachment content ' . random_int(100, 1000); + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('exists')->andReturn(false)->once(); + + // get attachment: + $attachment = $this->user()->attachments()->first(); + + // call API + $response = $this->get('/api/v1/attachments/' . $attachment->id . '/download'); + + $response->assertStatus(500); + $response->assertSee('Could not find the indicated attachment. The file is no longer there.'); + } + + /** + * Download attachment + * + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + */ + public function testDownloadNotUploaded(): void + { + // mock stuff: + $repository = $this->mock(AttachmentRepositoryInterface::class); + // mock calls: + $repository->shouldReceive('setUser')->once(); + + // create attachment + $attachment = Attachment::create( + [ + 'user_id' => $this->user()->id, + 'attachable_id' => 1, + 'attachable_type' => TransactionJournal::class, + 'md5' => md5('Hello' . random_int(1, 1000)), + 'filename' => 'some name', + 'mime' => 'text/plain', + 'size' => 5, + 'uploaded' => false, + + ] + ); + + // call API + $response = $this->get('/api/v1/attachments/' . $attachment->id . '/download'); + + $response->assertStatus(500); + $response->assertSee('No file has been uploaded for this attachment (yet).'); + } + + /** + * List all attachments. + * + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + */ + public function testIndex(): void + { + // create stuff + $attachments = factory(Attachment::class, 10)->create(); + + // mock stuff: + $repository = $this->mock(AttachmentRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('get')->once()->andReturn($attachments); + + // test API + $response = $this->get('/api/v1/attachments'); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => 10, 'count' => 10, 'per_page' => true, 'current_page' => 1, 'total_pages' => 1]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * List one attachment. + * + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + */ + public function testShow(): void + { + /** @var Attachment $attachment */ + $attachment = $this->user()->attachments()->first(); + + // mock stuff: + $repository = $this->mock(AttachmentRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + + // test API + $response = $this->get('/api/v1/attachments/' . $attachment->id); + $response->assertStatus(200); + $response->assertStatus(200); + $response->assertJson(['data' => ['type' => 'attachments', 'links' => true],]); + $response->assertSee($attachment->filename); // attachment file name + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + + /** + * Store a new attachment. + * + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + */ + public function testStore(): void + { + /** @var Attachment $attachment */ + $attachment = $this->user()->attachments()->first(); + + // mock stuff: + $repository = $this->mock(AttachmentRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('store')->once()->andReturn($attachment); + + $journalRepos->shouldReceive('setUser')->once(); + $journalRepos->shouldReceive('findNull')->once()->andReturn($this->user()->transactionJournals()->find(1)); + + // data to submit + $data = [ + 'filename' => 'Some new att', + 'description' => sprintf('Attempt #%d', random_int(1, 1000)), + 'model' => TransactionJournal::class, + 'model_id' => 1, + ]; + + + // test API + $response = $this->post('/api/v1/attachments', $data); + $response->assertStatus(200); + $response->assertJson(['data' => ['type' => 'attachments', 'links' => true],]); + $response->assertSee($attachment->filename); // the file name. + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * Update an attachment. + * + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + * @covers \FireflyIII\Api\V1\Requests\AttachmentRequest + */ + public function testUpdate(): void + { + // mock repositories + $repository = $this->mock(AttachmentRepositoryInterface::class); + + /** @var Attachment $attachment */ + $attachment = $this->user()->attachments()->first(); + + // mock calls: + $repository->shouldReceive('setUser'); + $repository->shouldReceive('update')->once()->andReturn($attachment); + + // data to submit + $data = [ + 'filename' => $attachment->filename, + 'description' => sprintf('Attempt #%d', random_int(1, 1000)), + 'model' => TransactionJournal::class, + 'model_id' => 1, + ]; + + // test API + $response = $this->put('/api/v1/attachments/' . $attachment->id, $data, ['Accept' => 'application/json']); + $response->assertStatus(200); + $response->assertJson(['data' => ['type' => 'attachments', 'links' => true],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + $response->assertSee($attachment->description); + + } + + public function testUpload(): void + { + /** @var Attachment $attachment */ + $attachment = $this->user()->attachments()->first(); + $content = 'Hello there'; + // mock helper: + $helper = $this->mock(AttachmentHelperInterface::class); + $helper->shouldReceive('saveAttachmentFromApi')->once(); + + $response = $this->call('POST', '/api/v1/attachments/' . $attachment->id . '/upload',[],[],[],[], $content); + //$response = $this->post('/api/v1/attachments/' . $attachment->id . '/upload',$content, ['Accept' => 'application/json']); + $response->assertStatus(204); + } +} \ No newline at end of file