diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5f05b3f..5eab30e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,6 +3,9 @@ on: push: branches: - main + pull_request: + branches: + - main jobs: # Unit tests back (phpunit) @@ -23,27 +26,39 @@ jobs: env: LARAVEL: 12.* TESTBENCH: 10.* + - php: 8.5 + env: + LARAVEL: 12.* + TESTBENCH: 10.* env: ${{ matrix.env }} name: P${{ matrix.php }} - L${{ matrix.env.LARAVEL }} - TB${{ matrix.env.TESTBENCH }} steps: - uses: actions/checkout@v4 + - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} extensions: mbstring, dom, fileinfo, mysql + - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Cache composer dependencies uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- + - name: Install Composer dependencies run: | composer require "laravel/framework:${LARAVEL}" "orchestra/testbench:${TESTBENCH}" --no-interaction --no-update --prefer-dist composer update --prefer-stable --prefer-dist --no-interaction + + - name: Run Security Audit + run: composer audit + - name: Execute tests (Unit and Feature tests) via PHPUnit run: ./vendor/bin/phpunit diff --git a/composer.json b/composer.json index bbe965e..f21f910 100755 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "email": "antoine@code16.fr" }], "require": { - "php": "^8.2|^8.3|^8.4", + "php": "^8.2|^8.3|^8.4|^8.5", "laravel/framework": "^10.0|^11.0|^12.0", "nesbot/carbon": "^2.0|^3.0", "maatwebsite/excel": "^3.1", @@ -18,7 +18,7 @@ "require-dev": { "fakerphp/faker": "^1.19.0", "mockery/mockery": "^1.3.0", - "phpunit/phpunit": "^10.0|^11.0", + "phpunit/phpunit": "^10.0|^11.0|^12.0", "doctrine/dbal": "^3.0", "orchestra/testbench": "6.*|7.*|8.*|9.*|10.*", "code16/sharp": "^9.0", diff --git a/tests/Feature/FormojAnswerControllerTest.php b/tests/Feature/FormojAnswerControllerTest.php index 043aaef..aa30a66 100644 --- a/tests/Feature/FormojAnswerControllerTest.php +++ b/tests/Feature/FormojAnswerControllerTest.php @@ -6,19 +6,20 @@ use Code16\Formoj\Models\Field; use Code16\Formoj\Tests\FormojTestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class FormojAnswerControllerTest extends FormojTestCase { use RefreshDatabase; - - /** @test */ + + #[Test] function we_cant_get_a_non_existing_answer() { $this->get("/formoj/api/answer/1") ->assertStatus(404); } - /** @test */ + #[Test] function we_can_get_a_answer_with_fields() { $this->withoutExceptionHandling(); @@ -54,7 +55,7 @@ function we_can_get_a_answer_with_fields() ]); } - /** @test */ + #[Test] function we_allow_missing_fields() { $this->withoutExceptionHandling(); @@ -79,7 +80,7 @@ function we_allow_missing_fields() ->assertJsonCount(0, "data.fields"); } - /** @test */ + #[Test] function we_can_get_only_field_of_the_current_answer() { $this->withoutExceptionHandling(); diff --git a/tests/Feature/FormojFormControllerTest.php b/tests/Feature/FormojFormControllerTest.php index 0b29a97..010b82b 100644 --- a/tests/Feature/FormojFormControllerTest.php +++ b/tests/Feature/FormojFormControllerTest.php @@ -8,19 +8,20 @@ use Code16\Formoj\Tests\FormojTestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Str; +use PHPUnit\Framework\Attributes\Test; class FormojFormControllerTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_cant_get_a_non_existing_form() { $this->get("/formoj/api/form/1") ->assertStatus(404); } - /** @test */ + #[Test] function we_can_get_a_form_properly_formatted() { $field = Field::factory()->create([ @@ -64,7 +65,7 @@ function we_can_get_a_form_properly_formatted() ]); } - /** @test */ + #[Test] function we_can_get_a_form_with_a_text_field() { $field = Field::factory()->create([ @@ -96,7 +97,7 @@ function we_can_get_a_form_with_a_text_field() ]); } - /** @test */ + #[Test] function we_can_get_a_form_with_a_textarea_field() { $field = Field::factory()->create([ @@ -130,7 +131,7 @@ function we_can_get_a_form_with_a_textarea_field() ]); } - /** @test */ + #[Test] function we_can_get_a_form_with_a_single_select_field() { $field = Field::factory()->create([ @@ -169,7 +170,7 @@ function we_can_get_a_form_with_a_single_select_field() ]); } - /** @test */ + #[Test] function we_can_get_a_form_with_a_multiple_select_field() { $field = Field::factory()->create([ @@ -211,7 +212,7 @@ function we_can_get_a_form_with_a_multiple_select_field() ]); } - /** @test */ + #[Test] function we_can_get_a_form_with_an_heading_field() { $field = Field::factory()->create([ @@ -239,7 +240,7 @@ function we_can_get_a_form_with_an_heading_field() ]); } - /** @test */ + #[Test] function we_can_get_a_form_with_an_upload_field() { $field = Field::factory()->create([ @@ -273,7 +274,7 @@ function we_can_get_a_form_with_an_upload_field() ]); } - /** @test */ + #[Test] function we_can_not_get_a_not_published_already_form() { $form = Form::factory()->create([ @@ -285,7 +286,7 @@ function we_can_not_get_a_not_published_already_form() ->assertStatus(409); } - /** @test */ + #[Test] function we_can_not_get_a_to_be_published_in_the_future_form() { $form = Form::factory()->create([ @@ -297,7 +298,7 @@ function we_can_not_get_a_to_be_published_in_the_future_form() ->assertStatus(409); } - /** @test */ + #[Test] function we_can_get_a_form_with_valid_publish_dates() { $form = Form::factory()->create([ diff --git a/tests/Feature/FormojFormFillControllerTest.php b/tests/Feature/FormojFormFillControllerTest.php index 95f45ad..fe6ef02 100644 --- a/tests/Feature/FormojFormFillControllerTest.php +++ b/tests/Feature/FormojFormFillControllerTest.php @@ -15,12 +15,13 @@ use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; +use PHPUnit\Framework\Attributes\Test; class FormojFormFillControllerTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_can_fill_a_form_with_one_section() { Notification::fake(); @@ -59,7 +60,7 @@ function we_can_fill_a_form_with_one_section() ]); } - /** @test */ + #[Test] function we_cant_fill_an_outdated_form() { Notification::fake(); @@ -97,7 +98,7 @@ function we_cant_fill_an_outdated_form() ->assertStatus(403); } - /** @test */ + #[Test] function the_last_section_of_the_form_is_validated() { Notification::fake(); @@ -125,7 +126,7 @@ function the_last_section_of_the_form_is_validated() ]); } - /** @test */ + #[Test] function we_store_only_the_form_data_with_the_answer() { $this->withoutExceptionHandling(); @@ -167,7 +168,7 @@ function we_store_only_the_form_data_with_the_answer() ]); } - /** @test */ + #[Test] function we_can_update_an_existing_answer() { $this->withoutExceptionHandling(); @@ -207,7 +208,7 @@ function we_can_update_an_existing_answer() $this->assertCount(1, $field->section->form->answers); } - /** @test */ + #[Test] function we_dont_store_headings_with_the_answer() { Notification::fake(); @@ -244,7 +245,7 @@ function we_dont_store_headings_with_the_answer() ]); } - /** @test */ + #[Test] function we_store_select_values_with_the_answer() { Notification::fake(); @@ -276,7 +277,7 @@ function we_store_select_values_with_the_answer() ]); } - /** @test */ + #[Test] function we_store_multiple_select_values_with_the_answer() { Notification::fake(); @@ -309,7 +310,7 @@ function we_store_multiple_select_values_with_the_answer() ]); } - /** @test */ + #[Test] function we_move_uploads_and_store_filename_with_the_answer() { $this->withoutExceptionHandling(); @@ -356,7 +357,7 @@ function we_move_uploads_and_store_filename_with_the_answer() ->assertExists("formoj/forms/{$field->section->form_id}/answers/{$answer->id}/image.jpg"); } - /** @test */ + #[Test] function posting_a_new_answer_sends_a_notification_if_configured() { Notification::fake(); @@ -386,7 +387,7 @@ function($notification, $channels, $notifiable) { ); } - /** @test */ + #[Test] function posting_a_new_answer_does_not_sends_a_notification_if_not_configured() { Notification::fake(); @@ -410,7 +411,7 @@ function posting_a_new_answer_does_not_sends_a_notification_if_not_configured() Notification::assertNotSentTo(new AnonymousNotifiable, FormojFormWasJustAnswered::class); } - /** @test */ + #[Test] function all_sections_of_the_form_are_validated_if_validate_all_argument_is_passed() { Notification::fake(); diff --git a/tests/Feature/FormojSectionControllerTest.php b/tests/Feature/FormojSectionControllerTest.php index 3354ed3..5728493 100644 --- a/tests/Feature/FormojSectionControllerTest.php +++ b/tests/Feature/FormojSectionControllerTest.php @@ -7,12 +7,13 @@ use Code16\Formoj\Models\Section; use Code16\Formoj\Tests\FormojTestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class FormojSectionControllerTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_get_a_422_when_posting_null_for_a_required_field() { $field = Field::factory()->create([ @@ -42,7 +43,7 @@ function we_get_a_422_when_posting_null_for_a_required_field() ->assertJsonMissingValidationErrors("f" . $field2->id); } - /** @test */ + #[Test] function we_get_a_422_when_posting_a_too_long_text_with_a_max_length_property() { $field = Field::factory()->create([ @@ -67,7 +68,7 @@ function we_get_a_422_when_posting_a_too_long_text_with_a_max_length_property() ->assertJsonValidationErrors("f" . $field->id); } - /** @test */ + #[Test] function we_get_a_422_when_posting_a_non_existing_value_to_a_single_select() { $field = Field::factory()->create([ @@ -108,7 +109,7 @@ function we_get_a_422_when_posting_a_non_existing_value_to_a_single_select() ->assertStatus(200); } - /** @test */ + #[Test] function we_get_a_422_when_posting_a_non_existing_value_to_a_multiple_select() { $field = Field::factory()->create([ @@ -156,7 +157,7 @@ function we_get_a_422_when_posting_a_non_existing_value_to_a_multiple_select() ->assertStatus(200); } - /** @test */ + #[Test] function we_get_a_422_when_posting_to_much_values_to_a_multiple_select_with_max_options() { $field = Field::factory()->create([ @@ -191,7 +192,7 @@ function we_get_a_422_when_posting_to_much_values_to_a_multiple_select_with_max_ ->assertStatus(200); } - /** @test */ + #[Test] function we_cant_validate_a_section_of_an_outdated_form() { $field = Field::factory()->create([ diff --git a/tests/Feature/FormojUploadControllerTest.php b/tests/Feature/FormojUploadControllerTest.php index cfaf71b..17eb177 100644 --- a/tests/Feature/FormojUploadControllerTest.php +++ b/tests/Feature/FormojUploadControllerTest.php @@ -9,12 +9,13 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; +use PHPUnit\Framework\Attributes\Test; class FormojUploadControllerTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_can_upload_a_file() { Storage::fake('local'); @@ -45,7 +46,7 @@ function we_can_upload_a_file() Storage::disk('local')->assertExists("formoj/tmp/{$field->section->form_id}/image.jpg"); } - /** @test */ + #[Test] function we_cant_upload_an_invalid_file() { Storage::fake('local'); @@ -76,7 +77,7 @@ function we_cant_upload_an_invalid_file() ->assertStatus(422); } - /** @test */ + #[Test] function we_cant_upload_a_file_for_an_invalid_field() { Storage::fake('local'); @@ -99,7 +100,7 @@ function we_cant_upload_a_file_for_an_invalid_field() ->assertStatus(403); } - /** @test */ + #[Test] function the_uploaded_file_name_is_suffixed_if_needed() { $this->withoutExceptionHandling(); diff --git a/tests/Feature/Jobs/SendDailyNotificationsTest.php b/tests/Feature/Jobs/SendDailyNotificationsTest.php index e4ce9cb..dd157c6 100644 --- a/tests/Feature/Jobs/SendDailyNotificationsTest.php +++ b/tests/Feature/Jobs/SendDailyNotificationsTest.php @@ -11,12 +11,13 @@ use Illuminate\Notifications\AnonymousNotifiable; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Notification; +use PHPUnit\Framework\Attributes\Test; class SendDailyNotificationsTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_send_a_grouped_notification_if_configured() { Notification::fake(); diff --git a/tests/FormojTestCase.php b/tests/FormojTestCase.php index 696939e..68a8ebb 100644 --- a/tests/FormojTestCase.php +++ b/tests/FormojTestCase.php @@ -2,7 +2,6 @@ namespace Code16\Formoj\Tests; -use Illuminate\Database\Eloquent\Factory; use Orchestra\Testbench\TestCase; class FormojTestCase extends TestCase diff --git a/tests/Unit/SelectFieldCreatorTest.php b/tests/Unit/SelectFieldCreatorTest.php index 007258a..acf926b 100644 --- a/tests/Unit/SelectFieldCreatorTest.php +++ b/tests/Unit/SelectFieldCreatorTest.php @@ -7,12 +7,13 @@ use Code16\Formoj\Models\Section; use Code16\Formoj\Tests\FormojTestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class SelectFieldCreatorTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_can_create_a_new_default_select_field() { (new SelectFieldCreator(Section::factory()->create(), "test", ["a","b"])) @@ -32,7 +33,7 @@ function we_can_create_a_new_default_select_field() ]); } - /** @test */ + #[Test] function we_can_create_a_new_custom_select_field() { (new SelectFieldCreator(Section::factory()->create(), "test", ["a","b"])) @@ -55,7 +56,7 @@ function we_can_create_a_new_custom_select_field() ]); } - /** @test */ + #[Test] function we_can_create_a_new_custom_multiple_select_field() { (new SelectFieldCreator(Section::factory()->create(), "test", ["a","b"])) @@ -80,7 +81,7 @@ function we_can_create_a_new_custom_multiple_select_field() ]); } - /** @test */ + #[Test] function we_can_create_a_new_custom_radios_select_field() { (new SelectFieldCreator(Section::factory()->create(), "test", ["a","b"])) diff --git a/tests/Unit/TextFieldCreatorTest.php b/tests/Unit/TextFieldCreatorTest.php index 3dd0102..9fa84fd 100644 --- a/tests/Unit/TextFieldCreatorTest.php +++ b/tests/Unit/TextFieldCreatorTest.php @@ -7,12 +7,13 @@ use Code16\Formoj\Models\Section; use Code16\Formoj\Tests\FormojTestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class TextFieldCreatorTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_can_create_a_new_default_text_field() { (new TextFieldCreator(Section::factory()->create(), "test")) @@ -29,7 +30,7 @@ function we_can_create_a_new_default_text_field() ]); } - /** @test */ + #[Test] function we_can_create_a_new_custom_text_field() { (new TextFieldCreator(Section::factory()->create(), "test")) diff --git a/tests/Unit/TextareaFieldCreatorTest.php b/tests/Unit/TextareaFieldCreatorTest.php index 0490bc8..3fbe2cd 100644 --- a/tests/Unit/TextareaFieldCreatorTest.php +++ b/tests/Unit/TextareaFieldCreatorTest.php @@ -7,12 +7,13 @@ use Code16\Formoj\Models\Section; use Code16\Formoj\Tests\FormojTestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class TextareaFieldCreatorTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_can_create_a_new_default_textarea_field() { (new TextareaFieldCreator(Section::factory()->create(), "test")) @@ -30,7 +31,7 @@ function we_can_create_a_new_default_textarea_field() ]); } - /** @test */ + #[Test] function we_can_create_a_new_custom_textarea_field() { (new TextareaFieldCreator(Section::factory()->create(), "test")) diff --git a/tests/Unit/UploadFieldCreatorTest.php b/tests/Unit/UploadFieldCreatorTest.php index ef36064..8cdcde6 100644 --- a/tests/Unit/UploadFieldCreatorTest.php +++ b/tests/Unit/UploadFieldCreatorTest.php @@ -7,12 +7,13 @@ use Code16\Formoj\Models\Section; use Code16\Formoj\Tests\FormojTestCase; use Illuminate\Foundation\Testing\RefreshDatabase; +use PHPUnit\Framework\Attributes\Test; class UploadFieldCreatorTest extends FormojTestCase { use RefreshDatabase; - /** @test */ + #[Test] function we_can_create_a_new_default_upload_field() { (new UploadFieldCreator(Section::factory()->create(), "test")) @@ -30,7 +31,7 @@ function we_can_create_a_new_default_upload_field() ]); } - /** @test */ + #[Test] function we_can_create_a_new_custom_upload_field() { (new UploadFieldCreator(Section::factory()->create(), "test"))