QrCodeControllerTest.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. namespace Tests\Api\v1\Controllers;
  3. use App\Api\v1\Controllers\QrCodeController;
  4. use App\Models\TwoFAccount;
  5. use App\Models\User;
  6. use PHPUnit\Framework\Attributes\CoversClass;
  7. use PHPUnit\Framework\Attributes\Test;
  8. use Tests\Classes\LocalFile;
  9. use Tests\FeatureTestCase;
  10. /**
  11. * QrCodeController test class
  12. */
  13. #[CoversClass(QrCodeController::class)]
  14. class QrCodeControllerTest extends FeatureTestCase
  15. {
  16. /**
  17. * @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
  18. */
  19. protected $user;
  20. protected $anotherUser;
  21. /**
  22. * @var App\Models\TwoFAccount
  23. */
  24. protected $twofaccount;
  25. protected function setUp() : void
  26. {
  27. parent::setUp();
  28. $this->user = User::factory()->create();
  29. $this->anotherUser = User::factory()->create();
  30. $this->twofaccount = TwoFAccount::factory()->for($this->user)->create([
  31. 'otp_type' => 'totp',
  32. 'account' => 'account',
  33. 'service' => 'service',
  34. 'secret' => 'A4GRFHZVRBGY7UIW',
  35. 'algorithm' => 'sha1',
  36. 'digits' => 6,
  37. 'period' => 30,
  38. 'legacy_uri' => 'otpauth://hotp/service:account?secret=A4GRFHZVRBGY7UIW&issuer=service',
  39. ]);
  40. }
  41. #[Test]
  42. public function test_show_qrcode_returns_base64_image()
  43. {
  44. $response = $this->actingAs($this->user, 'api-guard')
  45. ->json('GET', '/api/v1/twofaccounts/' . $this->twofaccount->id . '/qrcode')
  46. ->assertJsonStructure([
  47. 'qrcode',
  48. ])
  49. ->assertOk();
  50. $this->assertStringStartsWith('data:image/svg+xml;base64', $response->getData()->qrcode);
  51. }
  52. #[Test]
  53. public function test_show_missing_qrcode_returns_not_found()
  54. {
  55. $response = $this->actingAs($this->user, 'api-guard')
  56. ->json('GET', '/api/v1/twofaccounts/1000/qrcode')
  57. ->assertNotFound()
  58. ->assertJsonStructure([
  59. 'message',
  60. ]);
  61. }
  62. #[Test]
  63. public function test_show_qrcode_of_another_user_is_forbidden()
  64. {
  65. $response = $this->actingAs($this->anotherUser, 'api-guard')
  66. ->json('GET', '/api/v1/twofaccounts/' . $this->twofaccount->id . '/qrcode')
  67. ->assertForbidden()
  68. ->assertJsonStructure([
  69. 'message',
  70. ]);
  71. }
  72. #[Test]
  73. public function test_decode_qrcode_return_success()
  74. {
  75. $file = LocalFile::fake()->validQrcode();
  76. $response = $this->withHeaders(['Content-Type' => 'multipart/form-data'])
  77. ->actingAs($this->user, 'api-guard')
  78. ->json('POST', '/api/v1/qrcode/decode', [
  79. 'qrcode' => $file,
  80. 'inputFormat' => 'fileUpload',
  81. ])
  82. ->assertOk()
  83. ->assertExactJson([
  84. 'data' => 'otpauth://totp/test@test.com?secret=A4GRFHVIRBGY7UIW',
  85. ]);
  86. }
  87. #[Test]
  88. public function test_decode_missing_qrcode_return_validation_error()
  89. {
  90. $response = $this->actingAs($this->user, 'api-guard')
  91. ->json('POST', '/api/v1/qrcode/decode', [
  92. 'qrcode' => '',
  93. ])
  94. ->assertStatus(422);
  95. }
  96. #[Test]
  97. public function test_decode_invalid_qrcode_return_bad_request()
  98. {
  99. $file = LocalFile::fake()->invalidQrcode();
  100. $response = $this->withHeaders(['Content-Type' => 'multipart/form-data'])
  101. ->actingAs($this->user, 'api-guard')
  102. ->json('POST', '/api/v1/qrcode/decode', [
  103. 'qrcode' => $file,
  104. 'inputFormat' => 'fileUpload',
  105. ])
  106. ->assertStatus(400)
  107. ->assertJsonStructure([
  108. 'message',
  109. ]);
  110. }
  111. }