diff --git a/.gitignore b/.gitignore index e40411d..650294e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ /.idea /.composer /vendor - composer.lock diff --git a/config/blt.php b/config/blt.php index 4e9793b..6bbc256 100644 --- a/config/blt.php +++ b/config/blt.php @@ -11,7 +11,8 @@ "namespaces" => [ "default" => "App\\", "types" => [ - "User" => "App\Models\User", + "role" => "Spatie\Permission\Models\Role", + "user" => "App\Models\User", ], ], "helpers" => [ diff --git a/docs/customHighlight.css b/docs/customHighlight.css new file mode 100644 index 0000000..bbf3198 --- /dev/null +++ b/docs/customHighlight.css @@ -0,0 +1,66 @@ +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-section, +.hljs-doctag, +.hljs-title { + color: #c678dd; +} + +.hljs-string, +.hljs-meta .hljs-string, +.hljs-attr, +.hljs-template-tag, +.hljs-template-variable, +.hljs-addition { + color: #98c379; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion { + color: #5c6370; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-selector-id, +.hljs-selector-class { + color: #1f8ef1; +} + +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-class .hljs-title { + color: #d19a66; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-function, +.hljs-title, +.hljs-keyword, +.hljs-selector-tag, +.hljs-selector-pseudo { + color: #61dafb; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/docs/elements/application.html b/docs/elements/application.html new file mode 100644 index 0000000..7ea43d4 --- /dev/null +++ b/docs/elements/application.html @@ -0,0 +1,75 @@ +Application + + +

+ Use
+ Blumilk\BLT\Features\Application context
+ or add
+ Blumilk\BLT\Features\Traits\Application trait to test your application's + application features. +

+
+ + +

+ In the development and testing of Laravel applications, mocking services is quite important. By mocking + services, you can isolate and test specific parts of your application without relying on external dependencies. + This ensures your tests are reliable and focused. +

+

+ This chapter covers the Application trait in the BLT package, which provides methods to mock + services in your Laravel application during tests. You will learn how to mock individual services and multiple + services at once using this trait. +

+
+ +Mocking individual services + +

+ The following example demonstrates how to mock a specified service with a given mock class. This method ensures + that the specified service is replaced by the mock during the test scenario. +

+
+ + + + +

+ In this example, the NotificationService is replaced with NotificationServiceMock. + This allows the test to run with the mocked version of the service. +

+
+ +Mocking multiple services + +

+ The following example demonstrates how to mock multiple services at once using a table to specify the services + and their respective mocks. This method ensures that each specified service is replaced by the corresponding + mock during the test scenario. +

+
+ + + + +

+ In this example, both the EmailService and PaymentService are replaced with their + respective mocks, EmailServiceMock and PaymentServiceMock. This allows the test to run + with the mocked versions of these services. +

+
diff --git a/docs/elements/authentication.html b/docs/elements/authentication.html new file mode 100644 index 0000000..9bede6f --- /dev/null +++ b/docs/elements/authentication.html @@ -0,0 +1,188 @@ +Authentication + + +

+ Use
+ Blumilk\BLT\Features\Authentication context
+ or add
+ Blumilk\BLT\Features\Traits\Authentication trait to test your application's + authentication features. +

+
+ +Authentication Checks and Operations + +

+ The Authentication trait provides several methods to manage and verify authentication states for + various objects within your Laravel application. These methods ensure that your application's authentication + features are functioning as expected. +

+
+ + +

+ This snippet authenticates a user by a specified value in a given field and logs them into the session. +

+
+ + + +

+ This snippet logs out any authenticated user from the session. +

+
+ + +

+ This snippet authenticates a user with the specified attributes. +

+
+ + + +

+ This snippet logs out any authenticated user, ensuring no user is authenticated. +

+
+ + + +

+ This snippet authenticates a user with a specified email. +

+
+ + + +

+ This snippet asserts that no user is authenticated in the session. +

+
+ + + +

+ This snippet asserts that the authenticated user in the session has a specific value in a given field. +

+
+ + + +

+ This snippet asserts that the authenticated user's email matches the specified value. +

+
+ + + +

+ This snippet asserts that the authenticated user has a specific attribute with a given value. +

+
+ + + +

+ This snippet logs out the authenticated user and asserts that no user is authenticated. +

+
+ + + +

+ This snippet asserts that the authenticated user is redirected to a specified URL. +

+
+ + + +

+ This snippet asserts that a user with a specified email cannot access a given URL. +

+
+ diff --git a/docs/elements/basic-usage.html b/docs/elements/basic-usage.html new file mode 100644 index 0000000..0fe9f35 --- /dev/null +++ b/docs/elements/basic-usage.html @@ -0,0 +1,54 @@ +Basic usage + +Bootstrap BLT + +

+ To start using BLT you need to add it to your Behat context: +

+ + class FeatureContext extends Toolbox implements Context + { + public function __construct() + { + $bootstrapper = new \Blumilk\BLT\Bootstrapping\LaravelBootstrapper(); + $bootstrapper->boot(); + } + } + + + Instead using whole Toolbox you can add individual traits: + + class FeatureContext implements Context + { + use \Blumilk\BLT\Features\Traits\Http; + use \Blumilk\BLT\Features\Traits\Eloquent; + + public function __construct() + { + $bootstrapper = new \Blumilk\BLT\Bootstrapping\LaravelBootstrapper(); + $bootstrapper->boot(); + } + } + +
+ +Start writing tests + +

+ Now you can start writing tests. For most of the tests you won't need to write single line of code. +

+ + Feature: Signup test + + Scenario: User can signup with proper credentials + Given a user is requesting "/register" using POST method + Given request body contains: + | key | value | + | name | user | + | email | user@example.com | + | password | password | + When a request is sent + Then the response should have status 302 + And user is authenticated in session as user in name field + +
diff --git a/docs/elements/code-blocks.html b/docs/elements/code-blocks.html new file mode 100644 index 0000000..4c520ce --- /dev/null +++ b/docs/elements/code-blocks.html @@ -0,0 +1,49 @@ +Code Blocks + + +

+ Add
+ Blumilk\BLT\Features\Traits\CodeBlocks trait to use ready complex functions from Codeblocks. +

+
+ +Authentication Checks and Operations + +

+ The CodeBlocks trait provides several methods to manage and verify authentication states for + various objects within your Laravel application. These methods ensure that your application's authentication + features are functioning as expected. +

+
+ + +

+ This snippet authenticates a user by a specified value in a given field and logs them into the session. +

+
+ + + +

+ This snippet authenticates a user by a specified value in a given field and logs them into the session. +

+
+ diff --git a/docs/elements/configuration.html b/docs/elements/configuration.html new file mode 100644 index 0000000..4b7aa78 --- /dev/null +++ b/docs/elements/configuration.html @@ -0,0 +1,44 @@ +Cnfiguration + + +

+ The config file in the BLT package contains the configuration settings for the package. You can customize these settings to suit your application's requirements.

+

Here's default configuration file that is being stored in config/blt.php: + + <?php + + declare(strict_types=1); + use Blumilk\BLT\Helpers\ArrayHelper; + use Blumilk\BLT\Helpers\BooleanHelper; + use Blumilk\BLT\Helpers\ClassHelper; + use Blumilk\BLT\Helpers\NullableHelper; + + return [ + "namespaces" => [ + "default" => "App\\", + "types" => [ + "user" => "App\Models\User", + "role" => "Spatie\Permission\Models\Role", + //you can define additional namespaces: "model" => "My\App\Namespace\Model\\", + ], + ], + "helpers" => [ + "array" => ArrayHelper::class, + "boolean" => BooleanHelper::class, + "class" => ClassHelper::class, + "nullable" => NullableHelper::class, + ], + ]; + +

+ The configuration allows for specifying default namespaces and types for the package. You can also define custom helpers that are extending existing ones to better fit your application's needs. +

+ + "helpers" => [ + "array" => ArrayHelper::class, + "boolean" => BooleanHelper::class, + "class" => ClassHelper::class, + "nullable" => "App\My|Namespace\MyHelper" + ], + +
diff --git a/docs/elements/console.html b/docs/elements/console.html new file mode 100644 index 0000000..75200bf --- /dev/null +++ b/docs/elements/console.html @@ -0,0 +1,105 @@ +Console + + +

+ Use
+ Blumilk\BLT\Features\Console context
+ or add
+ Blumilk\BLT\Features\Traits\Console trait to test your application's + console features. +

+
+ +Console Methods + +

+ The Console trait provides several methods to handle console commands within your Laravel application. These methods help ensure that your application's command-line interface is functioning as expected and can be tested effectively. +

+
+ + +

+ This snippet runs a specified Artisan command. It allows you to test scenarios where specific console commands need to be executed. +
+ You can specify the command to run and capture its output and exit code. +

+
+ + + +

+ The runCommandWithOptionsAndArguments method runs a specified Artisan command with options and arguments provided in a table. This is useful for testing scenarios where commands require additional parameters. +

+
+ + + + +

+ The seeInConsole method verifies that the console output contains a specified string. This is useful for ensuring that the command's output includes expected messages or results. +

+
+ + + + +

+ The consoleOutputIsNotEmpty method verifies that the console output is not empty. This is useful for ensuring that the command produces output. +

+
+ + + + +

+ The consoleOutputIsEmpty method verifies that the console output is empty. This is useful for ensuring that the command produces no output. +

+
+ + + + +

+ The consoleExitCodeIs method verifies that the console exit code matches the expected code. This is useful for ensuring that the command exits with the correct status. +

+
+ + diff --git a/docs/elements/context-classes-vs-traits.html b/docs/elements/context-classes-vs-traits.html new file mode 100644 index 0000000..58461ab --- /dev/null +++ b/docs/elements/context-classes-vs-traits.html @@ -0,0 +1,50 @@ +Context Classes vs. Traits + +

+ In this package, both context classes and traits are utilized to extend the functionality and modularity of your + Behat tests. While context classes serve as the primary structure for defining test behaviors, traits allow you + to encapsulate and reuse common test logic across different contexts. +

+

+ Traits provide predefined methods that can be included in your context classes to perform specific actions. By + using traits, you can avoid code duplication and ensure consistency across your test scenarios. For example, the + HttpResponse trait includes methods for asserting the status and content of HTTP + responses, while the Translations trait provides methods for testing translation + features in your Laravel application. +

+
+ +Using Traits in Context Classes + +

+ To use a trait in your context class, simply include it using the use keyword. Here is an example of how to + include the HttpResponse trait in a context class: +

+
+ + + + + <?php + + declare(strict_types=1); + + namespace Blumilk\BLT\Features; + + use Behat\Behat\Context\Context; + use Blumilk\BLT\Features\Traits\HttpResponse; + + class HttpResponseContext implements Context + { + use HttpResponse; + } + + + + + +

+ By leveraging traits, you can streamline your test scenarios and ensure consistent behavior across different + contexts. This modular approach helps maintain cleaner and more efficient test code. +

+
diff --git a/docs/elements/cookies.html b/docs/elements/cookies.html new file mode 100644 index 0000000..7f282c0 --- /dev/null +++ b/docs/elements/cookies.html @@ -0,0 +1,106 @@ +Cookies + +

+ Use
+ Blumilk\BLT\Features\Cookies context
+ or add
+ Blumilk\BLT\Features\Traits\Cookies trait to test your application's cookie features. +

+
+ +Cookies Methods + +

+The Cookies trait provides several methods to handle cookie operations within your Laravel application. These methods help ensure that your application's cookies are correctly set up and managed for testing purposes. +

+
+ +

+ This snippet sets a cookie with a specified name and value. It allows you to simulate setting cookies in your application. +

+
+ + +

+ The assertCookieValue method verifies that a cookie with the specified name has the expected value. This is useful for ensuring that cookies are set correctly in your application. +

+
+ + +

+ The deleteCookie method removes a cookie with the specified name. This is useful for testing scenarios where you need to clear cookies. +

+
+ + +

+ The assertCookieNotExists method verifies that a cookie with the specified name does not exist. This is useful for ensuring that cookies are properly deleted or not set. +

+
+ + +

+ The assertCookiesExist method verifies that multiple cookies with specified names and values are present. This is useful for checking the state of several cookies in your application. +

+
+ \ No newline at end of file diff --git a/docs/elements/database.html b/docs/elements/database.html new file mode 100644 index 0000000..d124cc5 --- /dev/null +++ b/docs/elements/database.html @@ -0,0 +1,65 @@ +Database + + +

+ Use
+ Blumilk\BLT\Features\Database context
+ or add
+ Blumilk\BLT\Features\Traits\Database trait to test your application's + database features. +

+
+Database Methods + +

+ The Database trait provides several methods to handle database operations within your Laravel + application. These methods help ensure that your application's database state is correctly set up for testing + purposes. +

+
+ + +

+ This snippet refreshes the database. It ensures that the database schema is up-to-date and empty from all + records. +

+
+ + + +

+ The refreshDatabaseWithSeeding method refreshes and seeds the database. This is useful for + scenarios where you need both a fresh schema and initial data. +

+
+ + + + +

+ The seederWasRan method runs a specified seeder class. This is useful for adding specific data sets + to your database as needed for your test scenarios. +

+
+ + diff --git a/docs/elements/dispatcher.html b/docs/elements/dispatcher.html new file mode 100644 index 0000000..9794614 --- /dev/null +++ b/docs/elements/dispatcher.html @@ -0,0 +1,97 @@ +Dispatcher + + +

+ Use
+ Blumilk\BLT\Features\Dispatcher context
+ or add
+ Blumilk\BLT\Features\Traits\Dispatcher trait to test your application's + dispatcher features. +

+
+ +Dispatcher Methods + +

+ The Dispatcher trait provides several methods to handle the dispatching of jobs and events within + your Laravel application. These methods ensure that your application's event and job dispatching features are + functioning as expected. +

+
+ + +

+ This snippet starts the bus fake, allowing you to simulate the dispatching of jobs within your tests. +

+
+ + + +

+ The fakeEvents method starts the event fake, allowing you to simulate the dispatching of events + within your tests. +

+
+ + + + +

+ The dispatchObject method dispatches a specified number of jobs or events with optional parameters. + This is useful for testing scenarios where you need to dispatch multiple instances of a job or event. +

+
+ + + + +

+ The assertDispatched method verifies that a specified number of jobs or events have been + dispatched. This is useful for assertions in your tests to ensure that the expected jobs or events have been + dispatched. +

+
+ + diff --git a/docs/elements/eloquent.html b/docs/elements/eloquent.html new file mode 100644 index 0000000..99d39a3 --- /dev/null +++ b/docs/elements/eloquent.html @@ -0,0 +1,148 @@ +Eloquent + + +

+ Use
+ Blumilk\BLT\Features\Eloquent context
+ or add
+ Blumilk\BLT\Features\Traits\Eloquent trait to test your application's + eloquent features. +

+
+Eloquent Methods + +

+ The Eloquent trait provides several methods to handle Eloquent models and their relationships + within your Laravel application. These methods help ensure that your application's database interactions and + model relationships are functioning as expected. +

+
+ + +

+ This snippet seeds a specified model into the database with optional attributes. This is useful for scenarios + where you need to ensure that specific models exist in the database for testing. +
+ You can specify the model name and optional attributes to create the model. +

+
+ + + +

+ The assertModelExistsInTheDatabase method checks that a specified model exists in the database. + This is useful for assertions in your tests to ensure that the expected models are present. +

+
+ + + + +

+ The thereAreModelsInTheDatabase method ensures that a specified number of instances of a model + exist in the database. This is useful for setting up scenarios where multiple instances of a model are required. +

+
+ + + + +

+ The theModelHasMany method verifies that a model has a "has many" relationship with another model. + This ensures that the relationship methods are correctly defined. +

+
+ + + + +

+ The theModelBelongsTo method verifies that a model has a "belongs to" relationship with another + model. This ensures that the relationship methods are correctly defined. +

+
+ + + + +

+ The theModelHasOne method verifies that a model has a "has one" relationship with another model. + This ensures that the relationship methods are correctly defined. +

+
+ + + + +

+ The theModelBelongsToMany method verifies that a model has a "belongs to many" relationship with + another model. This ensures that the relationship methods are correctly defined. +

+
+ + + + +

+ The theModelHasExpectedNumberOfRelated method verifies that a model has a specified number of + related models. This ensures that the relationships are correctly established with the expected number of + related models. +

+
+ + diff --git a/docs/elements/environment.html b/docs/elements/environment.html new file mode 100644 index 0000000..ed6468e --- /dev/null +++ b/docs/elements/environment.html @@ -0,0 +1,92 @@ +Environment + +

+ Use
+ Blumilk\BLT\Features\Environment context
+ or add
+ Blumilk\BLT\Features\Traits\Environment trait to test your application's + environment features. +

+
+ + +

+ In the development and testing of Laravel applications, the environment + configuration plays a crucial role. The environment settings determine how + your application behaves under different conditions and scenarios. By + configuring the environment appropriately, you can simulate production, + development, and testing setups to ensure your application is robust and + reliable. +

+

+ This chapter covers various aspects of environment configuration in Laravel, + including how to change configuration values dynamically during testing with + Behat. You will learn how to set up different environments, modify + configuration settings for specific test scenarios, and leverage these + configurations to catch potential issues early in the development cycle. + Understanding and managing environment configurations effectively will help + you create more resilient and adaptable applications. +

+
+ +Changing Laravel configuration values + +

+ When working with Laravel applications, you might need to change + configuration values during your tests to simulate different environments or + settings. This is particularly useful in Behat testing to ensure your + application behaves correctly under various configurations. +

+

+ The following examples demonstrate how to modify configuration values for + your Laravel application during Behat tests. By setting different + configuration parameters, you can test specific scenarios and edge cases + more effectively. +

+
+ + + + +

+ In this example, the application is configured to run in the 'local' + environment. This setting is ideal for development and testing purposes. By + ensuring that 'app.env' is set to 'local', you can simulate the behavior of + your application as it would run on a developer's machine. +

+

+ Adjusting the environment configuration helps in identifying issues that + might not be apparent in production but could affect development or testing + environments. +

+
+ + + + +

+ Here, we enable Laravel Telescope, a debugging assistant for Laravel. + Enabling Telescope during tests can help you monitor and debug the actions + that your application performs during a Behat scenario. +

+

+ By enabling or disabling certain features like Telescope, you can ensure + that your application behaves correctly with different toolsets and + configurations, leading to more robust and reliable software. +

+
diff --git a/docs/elements/faq.html b/docs/elements/faq.html new file mode 100644 index 0000000..008749b --- /dev/null +++ b/docs/elements/faq.html @@ -0,0 +1,49 @@ +FAQ + +

Here are some of the most frequently asked questions about using the BLT and their answers.

+
+ + +

Q: What is this package?

+

A: BLT, Behat + Laravel Toolbox, is a toolkit designed to facilitate the testing of Laravel applications using Behat. It provides many features and traits that simplify the integration and testing process, making it easier to write and maintain robust tests.

+
+ + +

Q: How do I install BLT?

+

A: You can install BLT via Composer by running the command:

+

composer require blumilksoftware/blt

+
+ + +

Q: How do I configure BLT?

+

A: BLT configuration can be customized in the config/blt.php file. You can set namespaces, endpoints, and other settings as per your requirements.

+
+ + +

Q: How do I mock services in my tests?

+

A: You can use the Application trait to mock services. It allows you to replace actual services with mock implementations for isolated testing.

+
+ + +

Q: I have a question, how can I contact you?

+

A: You can contact us interns directly or write to the contact page at Blumilk.

+

Emails:

+

jakub.kermes@studenci.collegiumwitelona.pl

+

piotr.fedak@studenci.collegiumwitelona.pl

+

Website: https://www.blumilk.pl/contact

+
+ + +

Q: What does BLT stand for?

+

A: BLT is a humorous acronym referring to the classic sandwich, Bacon, Lettuce, and Tomato. However, in our context, it represents "Behat + Laravel Toolbox," a toolkit for testing Laravel applications with Behat.

+
+ + +

Q: I found a bug, can I report it?

+

A: Of course, please contact us or you can write an issue on GitHub.

+

To report a bug, you can create an issue on our GitHub repository:

+

https://github.com/blumilksoftware/blt/issues

+

Alternatively, you can also contact us via email:

+

jakub.kermes@studenci.collegiumwitelona.pl

+

piotr.fedak@studenci.collegiumwitelona.pl

+
diff --git a/docs/elements/helpers.html b/docs/elements/helpers.html new file mode 100644 index 0000000..f165c17 --- /dev/null +++ b/docs/elements/helpers.html @@ -0,0 +1,59 @@ +Helpers + + +

We have a few helpers in use that, if you want, you can replace with your own to better suit your use case.

+ +

If you want to use Your helper, just change namespaces in config file at config/blt.php.

+ + +use Blumilk\BLT\Helpers\ArrayHelper; +use Blumilk\BLT\Helpers\BooleanHelper; +use Blumilk\BLT\Helpers\ClassHelper; +use Blumilk\BLT\Helpers\NullableHelper; + + "helpers" => [ + "array" => ArrayHelper::class, + "boolean" => BooleanHelper::class, + "class" => ClassHelper::class, + "nullable" => NullableHelper::class, + "user" => "App\MyHelpers\ReplacementHelper", + ], + + +

Your replacement helpers should be inheriting after ours though, ensuring compatibility

+ + Helper functions: +

ArrayHelper.php

+ + public function toArray(string|array $input, string $separator = " "): array + + public function toString(string|array $input, string $separator = " "): string + + +

BooleanHelper.php

+ + public function toBoolean(string $value): bool + + +

NullableHelper.php

+ + public function toNullable(string $nullable): ?string + + +

ClassHelper.php

+ + public function recognizeObjectClass(string $objectName): string + + public function getObjectNamespace(string $type): string + + public function guessType(string $objectName): string + + +

UserHelper.php

+ + public function getBy(string $field, string $value): ?object + + public function getByEmail(string $value): ?object + + +
diff --git a/docs/elements/hooks.html b/docs/elements/hooks.html new file mode 100644 index 0000000..4d59d14 --- /dev/null +++ b/docs/elements/hooks.html @@ -0,0 +1,40 @@ +Hooks + + +

Hooks are special methods that run at specified points in your test suite's lifecycle. They allow you to execute + code before and after certain events, providing a powerful mechanism to manage your test environment and ensure + consistency across your tests.

+ + + Reboot after feature + +

The Blumilk\BLT\Features\Hooks\RebootAfterFeature hook is designed to ensure that the system under test is reset to a clean state after each + feature is executed.

+ + + Refresh database before scenario + +

+ The Blumilk\BLT\Features\Hooks\RefreshDatabaseBeforeScenario hook is designed to reset the database to a known state before each scenario + is executed. This ensures that each test scenario runs with a fresh and consistent database, which is crucial + for maintaining the integrity and reliability of your test results. +

+ +

To use hooks simply include them in your feature context

+ + + use Blumilk\BLT\Features\Hooks\RefreshDatabaseBeforeScenario; + + class FeatureContext extends Toolbox implements Context + { + use RefreshDatabaseBeforeScenario; + + public function __construct() + { + $bootstrapper = new LaravelBootstrapper(); + $bootstrapper->boot(); + } + } + + +
\ No newline at end of file diff --git a/docs/elements/http.html b/docs/elements/http.html new file mode 100644 index 0000000..50f3833 --- /dev/null +++ b/docs/elements/http.html @@ -0,0 +1,662 @@ +Http + + +

+ Use
+ Blumilk\BLT\Features\Http context
+ or add
+ Blumilk\BLT\Features\Traits\Http trait to test your application's + http features. +

+ If you want to use only Request or Response methods, you can use + Blumilk\BLT\Features\Traits\HttpRequest + Blumilk\BLT\Features\Traits\HttpResponse + to include only one of them. +
+ +HttpRequest +HttpRequest Methods + +

+ The HttpRequest trait provides several methods to handle HTTP requests within your Laravel + application. These methods help ensure that your application's request handling and response mechanisms are + functioning as expected. +

+
+ + +

+ This snippet creates a new HTTP request to the specified URL using the specified method. It allows you to + simulate different types of requests to test your application's endpoints. +
+ You can specify the request method (GET, POST, etc.) and the endpoint URL. +

+
+ + + +

+ The requestBodyContainsKeyValuePair method sets a key-value pair in the request body. This is + useful for testing scenarios where the request body needs specific data. +

+
+ + + + +

+ The requestBodyContains method sets multiple key-value pairs in the request body using a table. + This is useful for testing scenarios where the request body needs multiple specific data points. +

+
+ + + + +

+ The requestHeadersContainsKeyValuePair method sets a key-value pair in the request headers. This is + useful for testing scenarios where specific headers need to be included in the request. +

+
+ + + + +

+ The requestHeadersContains method sets multiple key-value pairs in the request headers using a + table. This is useful for testing scenarios where multiple specific headers need to be included in the request. +

+
+ + + + +

+ The thereAreValuesInFormParams method sets multiple key-value pairs in the form parameters of the + request using a table. This is useful for testing form submissions with specific data. +

+
+ + + + +

+ The requestQueryParamsContains method sets multiple key-value pairs in the query parameters of the + request using a table. This is useful for testing URL query parameters with specific data. +

+
+ + + + +

+ The requestCookiesContains method sets multiple key-value pairs in the cookies of the request using + a table. This is useful for testing scenarios where specific cookies need to be included in the request. +

+
+ + + + +

+ The requestServerParamsContains method sets multiple key-value pairs in the server parameters of + the request using a table. This is useful for testing scenarios where specific server parameters need to be + included in the request. +

+
+ + + + +

+ The requestHasBearerToken method sets the Authorization header to a Bearer token. This is useful + for testing scenarios where authentication via Bearer token is required. +

+
+ + + + +

+ The requestHasAcceptLanguage method sets the Accept-Language header. This is useful for testing + scenarios where the request needs to specify a preferred language. +

+
+ + + + +

+ The requestHasContentType method sets the Content-Type header. This is useful for testing scenarios + where the request needs to specify the type of content being sent. +

+
+ + + + +

+ The requestHasUserAgent method sets the User-Agent header. This is useful for testing scenarios + where the request needs to specify the client making the request. +

+
+ + + + +

+ The requestHasHost method sets the Host header. This is useful for testing scenarios where the + request needs to specify the host. +

+
+ + + +HttpResponse + + +

+ Use
+ Blumilk\BLT\Features\Traits\HttpResponse trait to manage and test HTTP responses + within your Laravel application. This trait provides methods to send requests and assert various aspects of the + HTTP responses received. +

+
+ +HttpResponse Methods + +

+ The HttpResponse trait provides several methods to handle HTTP responses within your Laravel + application. These methods help ensure that your application's response handling and status codes are + functioning as expected. +

+
+ + +

+ This snippet sends the prepared request and captures the response. It is useful for testing scenarios where you + need to verify the response from a specific request. +

+
+ + + +

+ The aResponseStatusCodeShouldBe method verifies that the response status code matches the expected + status. This is useful for ensuring that the correct status code is returned. +

+
+ + + + +

+ The aResponseHTMLShouldContainPhrase method verifies that the response HTML contains a specified + phrase. This is useful for ensuring that certain content is present in the response body. +

+
+ + + + +

+ The aResponseHTMLShouldContainCSRFToken method verifies that the response HTML contains a CSRF + token. This is useful for ensuring that CSRF protection is included in forms. +

+
+ + + + +

+ The aResponseShouldBeJson method verifies that the response content is in JSON format. This is + useful for ensuring that the response type is correct for API endpoints. +

+
+ + + + +

+ The aResponseShouldContainJson method verifies that the response JSON contains specified key-value + pairs. This is useful for ensuring that the response data includes expected values. +

+
+ + + + +

+ The aResponseShouldHaveCookie method verifies that the response contains a specified cookie. This + is useful for ensuring that cookies are set correctly in the response. +

+
+ + + + +

+ The aResponseShouldHaveHeader method verifies that the response contains a specified header. This + is useful for ensuring that specific headers are included in the response. +

+
+ + + + +

+ The aResponseShouldHaveHeaderEqualTo method verifies that a response header has a specific value. + This is useful for ensuring that headers contain the correct values. +

+
+ + + + +

+ The aResponseShouldHaveStatus method verifies that the response status is equal to desired one. This is + useful for ensuring that the request has desired code. +

+
+ + + + +

+ The aResponseStatusShouldBeOk method verifies that the response status is HTTP 200 OK. This is + useful for ensuring that the request was successful. +

+
+ + + + +

+ The aResponseStatusShouldBeCreated method verifies that the response status is HTTP 201 Created. + This is useful for ensuring that a resource was successfully created. +

+
+ + + + +

+ The aResponseStatusShouldBeNoContent method verifies that the response status is HTTP 204 No + Content. This is useful for ensuring that the request was successful but no content is returned. +

+
+ + + + +

+ The aResponseStatusShouldBeBadRequest method verifies that the response status is HTTP 400 Bad + Request. This is useful for ensuring that the request was invalid. +

+
+ + + + +

+ The aResponseStatusShouldBeUnauthorized method verifies that the response status is HTTP 401 + Unauthorized. This is useful for ensuring that the request requires authentication. +

+
+ + + + +

+ The aResponseStatusShouldBeForbidden method verifies that the response status is HTTP 403 + Forbidden. This is useful for ensuring that the request is not allowed. +

+
+ + + + +

+ The aResponse + + StatusShouldBeNotFound method verifies that the response status is HTTP 404 Not Found. This is useful for + ensuring that the requested resource does not exist. +

+
+ + + + +

+ The aResponseStatusShouldBeConflict method verifies that the response status is HTTP 409 Conflict. + This is useful for ensuring that there is a conflict with the request. +

+
+ + + + +

+ The aResponseStatusShouldBeUnprocessable method verifies that the response status is HTTP 422 + Unprocessable Entity. This is useful for ensuring that the request contains invalid data. +

+
+ + + + +

+ The aResponseStatusShouldBeTooManyRequests method verifies that the response status is HTTP 429 Too + Many Requests. This is useful for ensuring that the rate limit has been exceeded. +

+
+ + + + +

+ The aResponseStatusShouldBeGone method verifies that the response status is HTTP 410 Gone. This is + useful for ensuring that the requested resource is no longer available. +

+
+ + + + +

+ The aResponseStatusShouldBeServiceUnavailable method verifies that the response status is HTTP 503 + Service Unavailable. This is useful for ensuring that the service is temporarily unavailable. +

+
+ + + + +

+ The aResponseStatusShouldBeFound method verifies that the response status is HTTP 302 Found. This + is useful for ensuring that the resource was found and the request was redirected. +

+
+ + + + +

+ The aResponseShouldBeRedirectedTo method verifies that the response is a redirect to the specified + URL. This is useful for ensuring that the request was redirected to the correct location. +

+
+ + + + +

+ The aResponseShouldHaveHeaderContaining method verifies that a response header contains a specified + value. This is useful for ensuring that headers contain expected values. +

+
+ + + + +

+ The aResponseShouldHaveNoContent method verifies that the response content is empty. This is useful + for ensuring that no content is returned in the response. +

+
+ + diff --git a/docs/elements/installation.html b/docs/elements/installation.html new file mode 100644 index 0000000..83d0bc5 --- /dev/null +++ b/docs/elements/installation.html @@ -0,0 +1,23 @@ +Installation + +

To start using a package if you don't already have Behat initialized in your project:

+ + composer require blumilksoftware/blt --dev
+ php artisan blt:init +
+

Or if you want to do that manually:

+

Use Composer to get the package from the Packagist repository:

+ + composer require blumilksoftware/blt --dev + +

Create .env.behat file in your project root directory and set up your environment variables for Behat.

+ + cp .env.example .env.behat + +

Initialize Behat in your project:

+ + php vendor/bin/behat --init + +

To learn more about Behat visit Behat documentation.

+
diff --git a/docs/elements/middleware.html b/docs/elements/middleware.html new file mode 100644 index 0000000..24797ea --- /dev/null +++ b/docs/elements/middleware.html @@ -0,0 +1,130 @@ +Middleware + + +

+ Use
+ Blumilk\BLT\Features\Middleware context
+ or add
+ Blumilk\BLT\Features\Traits\Middleware trait to test your application's + middleware features. +

+
+ +Middleware Methods + +

+ The Middleware trait provides several methods to handle middleware within your Laravel application. + These methods help ensure that your application's middleware is functioning as expected and can be enabled or + disabled for specific test scenarios. +

+
+ + +

+ This snippet disables a specified middleware. It allows you to test scenarios where certain middleware should be + bypassed. +
+ You can specify the middleware class to disable it. +

+
+ + + +

+ The disableMiddlewares method disables multiple middlewares specified in a table. This is useful + for scenarios where you need to disable several middlewares at once. +

+
+ + + + +

+ The disableThrottling method disables the throttling middleware. This is useful for testing + scenarios where rate limiting should be bypassed. +

+
+ + + + +

+ The disableCsrfProtection method disables the CSRF protection middleware. This is useful for + testing scenarios where CSRF protection should be bypassed. +

+
+ + + + +

+ The enableMiddleware method enables a specified middleware. This is useful for scenarios where you + need to ensure that a particular middleware is active. +

+
+ + + + +

+ The requestShouldHaveUuidInField method verifies that a specified field in the request contains a + valid UUID. This is useful for ensuring that UUIDs are correctly generated and included in the request. +

+
+ + + + +

+ The middlewareShouldBeAppliedToRequest method verifies that a specified middleware has been applied + to the request. This is useful for ensuring that the middleware is correctly modifying the request as expected. +

+
+ + diff --git a/docs/elements/notification.html b/docs/elements/notification.html new file mode 100644 index 0000000..73b544f --- /dev/null +++ b/docs/elements/notification.html @@ -0,0 +1,98 @@ +Notification + + +

+ Use
+ Blumilk\BLT\Features\Notification context
+ or add
+ Blumilk\BLT\Features\Traits\Notification trait to test your application's + notification features. +

+
+ +Notification Methods + +

+ The Notification trait provides several methods to handle notifications within your Laravel application. These methods help ensure that your application's notification system is functioning as expected and can be tested effectively. +

+
+ + +

+ This snippet fakes notifications, allowing you to test scenarios where notifications are sent without actually sending them. It is useful for capturing and asserting notifications during tests. +

+
+ + + +

+ The sendNotification method sends a specified notification to an object identified by a value in a specified field. This is useful for testing scenarios where notifications need to be sent to specific users or objects. +

+
+ + + + +

+ The assertNotificationSent method verifies that a specified notification was sent a certain number of times. This is useful for ensuring that notifications are sent the expected number of times. +

+
+ + + + +

+ The assertNotificationSentToUser method verifies that a specified notification was sent to an object identified by a value in a specified field. This is useful for ensuring that notifications are sent to the correct users or objects. +

+
+ + + + +

+ The assertNotificationNotSent method verifies that a specified notification was not sent to an object identified by a value in a specified field. This is useful for ensuring that notifications are not sent when they shouldn't be. +

+
+ + + + +

+ The assertNothingWasSent method verifies that no notifications were sent. This is useful for ensuring that no notifications are sent when they shouldn't be. +

+
+ + diff --git a/docs/elements/overview.html b/docs/elements/overview.html new file mode 100644 index 0000000..c741650 --- /dev/null +++ b/docs/elements/overview.html @@ -0,0 +1,46 @@ +Overview + + +

This package is meant to streamline testing Laravel apps with Behat. It provides ready to use code snippets and + contexts for testing Laravel applications.

+
+

+ Our goal is to provide a set of tools that will help you write tests faster and more efficiently. We want to + make sure that you can focus on writing tests that matter, rather than spending time on boilerplate code. + We would love to make it so no other code is needed for testing, but we are not there yet. We are constantly + working on improving the package and adding new features. +

+ +
+ + +Available options + + + +
+ + If you have any suggestions or ideas on how to improve the package, feel free to open an issue on our GitHub repository. +
diff --git a/docs/elements/session.html b/docs/elements/session.html new file mode 100644 index 0000000..0498545 --- /dev/null +++ b/docs/elements/session.html @@ -0,0 +1,212 @@ +Session + + +

+ Use
+ Blumilk\BLT\Features\Session context
+ or add
+ Blumilk\BLT\Features\Traits\Session trait to test your application's + session features. +

+
+ +Session Methods + +

+ The Session trait provides several methods to handle session data within your Laravel application. + These methods help ensure that your application's session management is functioning as expected. +

+
+ + +

+ This snippet verifies that the session contains the specified errors. It checks if the session flash data has + the expected error messages. +

+
+ + + +

+ The aSessionFlashesNoErrors method verifies that the session does not contain any errors. This is + useful for ensuring that the session is clear of errors. +

+
+ + + + +

+ The theSessionHasTheFollowingData method sets multiple key-value pairs in the session. This is + useful for populating the session with specific data for testing scenarios. +

+
+ + + + +

+ The theSessionShouldHaveTheFollowingData method verifies that the session contains the specified + key-value pairs. This is useful for asserting that the session has the expected data. +

+
+ + + + +

+ The theSessionIsRevoked method invalidates the session. This is useful for scenarios where the + session needs to be cleared or reset. +

+
+ + + + +

+ The theSessionHasNoData method clears all data from the session. This is useful for ensuring that + the session starts with no data. +

+
+ + + + +

+ The theSessionFlashesTheFollowingData method sets multiple key-value pairs in the session as flash + data. This is useful for testing scenarios where session flash data needs to be set. +

+
+ + + + +

+ The theSessionShouldFlashTheFollowingData method verifies that the session contains the specified + flash data. This is useful for asserting that the session flash data has the expected values. +

+
+ + + + +

+ The theSessionShouldHaveKey method verifies that the session contains a specified key. This is + useful for asserting the presence of specific session keys. +

+
+ + + + +

+ The theSessionShouldNotHaveKey method verifies that the session does not contain a specified key. + This is useful for asserting the absence of specific session keys. +

+
+ + + + +

+ The theSessionShouldHaveKeyWithValue method verifies that a session key contains a specified value. + This is useful for asserting that session keys have the expected values. +

+
+ + + + +

+ The theSessionForgetsKey method removes a specified key from the session. This is useful for + scenarios where specific session keys need to be cleared. +

+
+ + diff --git a/docs/elements/spatie-permission.html b/docs/elements/spatie-permission.html new file mode 100644 index 0000000..6bc759f --- /dev/null +++ b/docs/elements/spatie-permission.html @@ -0,0 +1,149 @@ +Spatie Permission + + +

+ Use
+ Blumilk\BLT\Features\SpatiePermission context +
or add
+ Blumilk\BLT\Features\Traits\SpatiePermission trait to test your application's + roles and permissions. +

+
+ +Role and Permission Checks + +

+ The SpatiePermission trait provides several methods to check and manipulate roles and permissions + for various objects within your Laravel application. These methods ensure that your application's security + features are functioning as expected. +

+
+ + +

+ This snippet checks if a given object can have roles by verifying that the object uses the Spatie\Permission\Traits\HasRoles + trait. This is useful for ensuring that your objects are correctly configured to handle roles. +
+ You can insert any model name here instead of user. +

+
+ + + +

+ The assignRoleTo method assigns a specified role to an object identified by a value in a specified + field. This helps in setting up your test scenarios where specific roles need to be assigned to users or other + objects. +

+
+ + + + + +

+ The givePermissionTo method assigns a specified permission to an object. This is essential for + setting up scenarios where certain permissions need to be granted dynamically. +

+
+ + + + +

+ The assertHasRole method checks if an object has a specified role. This is useful for assertions in + your tests to verify that roles are correctly assigned. +

+
+ + + + +

+ The assertHasPermission method checks if an object has a specified permission. This helps ensure + that your permission settings are correctly applied and verified during testing. +

+
+ + + + +

+ The assertHas method allows for a table of key-value pairs to be checked against an object. This is + particularly useful for verifying multiple roles and permissions in a single test scenario. +

+
+ + + + +

+ The revokePermissionTo method revokes a specified permission from an object. This is useful for + testing scenarios where permissions need to be dynamically removed. +

+
+ + + + +

+ The revokeRoleTo method removes a specified role from an object. This is particularly useful for + scenarios where you need to test the behavior of your application when roles are removed. +

+
+ + diff --git a/docs/elements/testing.html b/docs/elements/testing.html new file mode 100644 index 0000000..5398bd1 --- /dev/null +++ b/docs/elements/testing.html @@ -0,0 +1,50 @@ +Testing + + +

+ Use
+ Blumilk\BLT\Features\Testing context
+ or add
+ Blumilk\BLT\Features\Traits\Testing trait to test your application's + testing features. +

+
+ +Testing Methods + +

+ The Testing trait provides a mechanism to call PHPUnit assertions dynamically within your test scenarios. This trait helps ensure that your test assertions are concise and easy to use. +

+
+ + +

+ This function demonstrates the dynamic method call for PHPUnit assertions. It allows you to call any PHPUnit assertion method using the trait. +

+
+ + <?php + + declare(strict_types=1); + + namespace Blumilk\BLT\Features\Traits; + + use PHPUnit\Framework\Assert; + + /** + * @mixin Assert + */ + trait Testing + { + public function __call(string $name, array $arguments): void + { + Assert::$name(...$arguments); + } + } + + + +

+ The __call method intercepts calls to undefined methods and dynamically calls the corresponding PHPUnit assertion method. This makes it easier to write and maintain test assertions. +

+
diff --git a/docs/elements/translations.html b/docs/elements/translations.html new file mode 100644 index 0000000..f8997a6 --- /dev/null +++ b/docs/elements/translations.html @@ -0,0 +1,102 @@ +Translations + + +

+ Use
+ Blumilk\BLT\Features\Translations context
+ or add
+ Blumilk\BLT\Features\Traits\Translations trait to test your application's + translations features. +

+
+ +Translations Methods + +

+ The Translations trait provides several methods to handle translations within your Laravel + application. These methods help ensure that your application's localization and translation features are + functioning as expected. +

+
+ + +

+ This snippet sets the application's locale to the specified language. It allows you to test scenarios where + different locales need to be set. +
+ You can specify the locale code (e.g., 'en', 'fr', 'es') to change the application's language. +

+
+ + + +

+ The askToTranslate method sets the input phrase to be translated. This is useful for scenarios + where you need to test the translation of specific phrases. +

+
+ + + + +

+ The assertTranslationMatches method verifies that the translations match the expected phrases. This + is useful for ensuring that the translations are correct for different locales. +

+
+ + + + +

+ The assertEndpointTranslationMatches method verifies that the response from an endpoint matches the + expected translations for different locales. This is useful for ensuring that API responses are correctly + translated. + You'll need to run + + before this step. +

+
+ + diff --git a/docs/elements/view.html b/docs/elements/view.html new file mode 100644 index 0000000..6d793ae --- /dev/null +++ b/docs/elements/view.html @@ -0,0 +1,76 @@ +View + + +

+ Use
+ Blumilk\BLT\Features\View context
+ or add
+ Blumilk\BLT\Features\Traits\View trait to test your application's + view features. +

+
+ +View Methods + +

+ The View trait provides several methods to handle views within your Laravel application. These methods help ensure that your application's views are rendered correctly and contain the expected data. +

+
+ + +

+ This snippet sets the view that the user is looking at, with optional parameters. It allows you to test scenarios where specific views need to be rendered with given parameters. +
+ You can specify the view name and optionally pass a table of parameters to the view. +

+
+ + + +

+ The theViewContains method verifies that the view contains the specified data. This is useful for ensuring that the view has the expected data passed to it. +

+
+ + + + +

+ The viewResponseContains method verifies that the response view contains the specified data. + This is useful for ensuring that the response includes the expected view data. +

+

Requires running

+ + Given a user is requesting :endpoint + [...] + Given a request is sent + +

before in your test scenario.

+
+ + diff --git a/docs/eloquent.md b/docs/eloquent.md deleted file mode 100644 index 22f315c..0000000 --- a/docs/eloquent.md +++ /dev/null @@ -1,11 +0,0 @@ -## Eloquent -Use `Blumilk\BLT\Features\Eloquent` context to asserts Eloquent queries results. - -```gherkin -@eloquent @users -Feature: Test if users are seeded properly - - Scenario: Users seeder is ran - Given UsersSeeder is ran - Then there should be 5 users in database -``` diff --git a/docs/environment.md b/docs/environment.md deleted file mode 100644 index 6e2e176..0000000 --- a/docs/environment.md +++ /dev/null @@ -1,23 +0,0 @@ -## Environment -Use `Blumilk\BLT\Features\Environment` context to manipulate boot configuration on the fly. For example, you can change `app` variable `env` value to simulate other environments: - -```gherkin -@telescope @views -Feature: Test if Telescope works properly - - Scenario: User is requesting telescope when environment is local - Given application is booted with config: - | config | value | - | app.env | local | - Given a user is requesting "/telescope" - When a request is sent - Then a response status code should be "200" - - Scenario: User is requesting telescope when environment is production - Given application is booted with config: - | config | value | - | app.env | production | - Given a user is requesting "/telescope" - When a request is sent - Then a response status code should be "404" -``` \ No newline at end of file diff --git a/docs/icons/check.icon.svg b/docs/icons/check.icon.svg new file mode 100644 index 0000000..1b8bfea --- /dev/null +++ b/docs/icons/check.icon.svg @@ -0,0 +1,3 @@ + diff --git a/docs/icons/close.icon.svg b/docs/icons/close.icon.svg new file mode 100644 index 0000000..4a00a62 --- /dev/null +++ b/docs/icons/close.icon.svg @@ -0,0 +1,3 @@ + diff --git a/docs/img/BLT.png b/docs/img/BLT.png new file mode 100644 index 0000000..4b3d579 Binary files /dev/null and b/docs/img/BLT.png differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..de31d81 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + + Behat + Laravel Toolbox documentation + + + + + + +
+ + + + + + diff --git a/docs/index.js b/docs/index.js new file mode 100644 index 0000000..b0ba645 --- /dev/null +++ b/docs/index.js @@ -0,0 +1,254 @@ +class SidebarHeader extends HTMLElement { + connectedCallback() { + const content = this.innerHTML; + this.innerHTML = ` +
  • + ${content} +
  • + `; + } +} + +class SidebarElement extends HTMLElement { + static get observedAttributes() { + return ["href", "target"]; + } + + connectedCallback() { + const content = this.innerHTML; + const href = this.getAttribute('href') || '#'; + const target = this.getAttribute('target') || '_self'; + if (target === '_blank') { + this.innerHTML = ` +
  • + ${content} +
  • + `; + } else { + this.innerHTML = ` +
  • + ${content} +
  • + `; + } + } +} + +class ArticleHeader extends HTMLElement { + connectedCallback() { + const content = this.innerHTML; + this.innerHTML = ` +
    +

    ${content}

    +
    + `; + } +} + +class ArticleParagraphs extends HTMLElement { + connectedCallback() { + const content = this.innerHTML; + this.innerHTML = ` +
    ${content}
    + `; + } +} + +class SectionHeader extends HTMLElement { + connectedCallback() { + const content = this.innerHTML; + this.innerHTML = ` +
    +

    ${content}

    +
    + `; + } +} + +class CodeSnippet extends HTMLElement { + connectedCallback() { + const gherkinText = this.getAttribute('gherkin'); + const phpText = this.getAttribute('php'); + + this.innerHTML = ` +
    +
    + + +
    +
    + +
    +
    +
    +
    ${gherkinText}
    +
    + +
    +
    + `; + + this.querySelectorAll('button[data-tabs-target]').forEach(button => { + button.addEventListener('click', this.highlightActive.bind(this)); + }); + + this.setDefaultActive(); + hljs.highlightAll(); + } + + setDefaultActive() { + const gherkinTab = this.querySelector('#gherkin-tab'); + const gherkinPanel = this.querySelector('#gherkin'); + + if (gherkinTab && gherkinPanel) { + gherkinTab.classList.add('border-blue-500', 'text-blue-600'); + gherkinTab.classList.remove('border-transparent'); + gherkinPanel.classList.remove('hidden'); + } else { + console.error('Default Gherkin tab or panel not found.'); + } + } + + highlightActive(event) { + const tabButtons = this.querySelectorAll('button[data-tabs-target]'); + const tabPanels = this.querySelectorAll('#default-tab-content > div'); + + tabButtons.forEach(button => { + button.classList.remove('border-blue-500', 'text-blue-600'); + button.classList.add('border-transparent'); + }); + + tabPanels.forEach(panel => { + panel.classList.add('hidden'); + }); + + const target = event.currentTarget.getAttribute('data-tabs-target'); + const targetPanel = this.querySelector(target); + + if (targetPanel) { + event.currentTarget.classList.add('border-blue-500', 'text-blue-600'); + event.currentTarget.classList.remove('border-transparent'); + targetPanel.classList.remove('hidden'); + hljs.highlightElement(targetPanel.querySelector('code')); + } else { + console.error(`Element with selector "${target}" not found.`); + } + } +} + +class CodeBlock extends HTMLElement { + connectedCallback() { + const content = this.innerHTML + this.innerHTML = ` +
    + +
    ${content}
    +
    + `; + } +} + +customElements.define('sidebar-header', SidebarHeader); +customElements.define('sidebar-element', SidebarElement); +customElements.define('article-header', ArticleHeader); +customElements.define('article-paragraphs', ArticleParagraphs); +customElements.define('section-header', SectionHeader); +customElements.define('code-snippet', CodeSnippet); +customElements.define('code-block', CodeBlock); + +function loadContent(page, element) { + fetch(page) + .then(response => response.text()) + .then(data => { + document.getElementById("content").innerHTML = ` +
    + ${data} +
    + `; + highlightActive(element); + hljs.highlightAll(); + }); +} + +function copyToClipboard(text, type = 'Text') { + navigator.clipboard.writeText(text).then(() => { + showToast(`Copied ${type} to clipboard`); + }).catch(err => { + console.error('Failed to copy text: ', err); + }); +} + +function showToast(message) { + const toast = document.getElementById('toast'); + const toastMessage = document.getElementById('toast-message'); + toastMessage.textContent = message; + toast.classList.remove('hidden'); + setTimeout(() => { + hideToast(); + }, 3000); +} + +function hideToast() { + const toast = document.getElementById('toast'); + toast.classList.add('hidden'); +} + +function highlightActive(element) { + const sidebarElements = document.querySelectorAll('sidebar-element'); + sidebarElements.forEach(el => { + const anchor = el.querySelector('a'); + anchor.classList.remove('text-sky-600', 'font-semibold'); + anchor.textContent = anchor.textContent.replace(/^# /, ''); + }); + const anchor = element.querySelector('a'); + anchor.classList.add('text-sky-600', 'font-semibold'); + anchor.textContent = `# ${anchor.textContent}`; +} + +document.addEventListener("DOMContentLoaded", function () { + const defaultElement = document.querySelector('sidebar-element[href="elements/overview.html"]'); + loadContent("elements/overview.html", defaultElement); + highlightActive(defaultElement); +}); + +document.querySelectorAll('sidebar-element').forEach(element => { + element.addEventListener('click', function () { + if (this.getAttribute('target') !== '_blank') { + loadContent(this.getAttribute('href'), this); + } + }); +}); diff --git a/src/Features/Cookies.php b/src/Features/Cookies.php new file mode 100644 index 0000000..7096cf4 --- /dev/null +++ b/src/Features/Cookies.php @@ -0,0 +1,13 @@ +login($this->getUserModel()::query()->where("email", $email)->first()); } - /** - * @Given there are users in the database: - */ - public function thereAreUsersInTheDatabase(TableNode $table): void - { - foreach ($table->getColumnsHash() as $userData) { - $this->getUserModel()::firstOrCreate($userData); - } - } - /** * @Given there is an unauthenticated user * @throws BindingResolutionException diff --git a/src/Features/Traits/Cookies.php b/src/Features/Traits/Cookies.php new file mode 100644 index 0000000..a450e1c --- /dev/null +++ b/src/Features/Traits/Cookies.php @@ -0,0 +1,70 @@ +getContainer()->make(CookieFactory::class); + $cookieFactory->queue($name, $value); + } + + /** + * @Then cookie :name should have value :value + * @Then the cookie :name should contain value :value + * @Then the cookie named :name should have the value :value + */ + public function assertCookieValue(string $name, string $value): void + { + $cookieValue = $this->request->cookies->get($name); + Assert::assertEquals($value, $cookieValue, "Cookie $name does not have the expected value $value."); + } + + /** + * @When cookie :name is deleted + * @When cookie :name is removed + * @When cookie :name is cleared + */ + public function deleteCookie(string $name): void + { + $cookieFactory = $this->getContainer()->make(CookieFactory::class); + $cookieFactory->queue($cookieFactory->forget($name)); + } + + /** + * @Then the cookie :name should be missing + * @Then the cookie named :name should not be present + */ + public function assertCookieNotExists(string $name): void + { + $cookieValue = $this->request->cookies->get($name); + Assert::assertNull($cookieValue, "Cookie $name should not exist."); + } + + /** + * @Then the following cookies should be present: + * @Then the cookies should be set to: + */ + public function assertCookiesExist(TableNode $table): void + { + foreach ($table as $row) { + $cookieValue = $this->request->cookies->get($row["name"]); + Assert::assertEquals($row["value"], $cookieValue, "Cookie {$row["name"]} does not have the expected value {$row["value"]}."); + } + } +} diff --git a/src/Features/Traits/Database.php b/src/Features/Traits/Database.php index 9763151..9a6c6be 100644 --- a/src/Features/Traits/Database.php +++ b/src/Features/Traits/Database.php @@ -33,7 +33,7 @@ public function refreshDatabaseWithSeeding(): void } /** - * @Given :class seeder has been ran + * @Given :class seeder has been run */ public function seederWasRan(string $class): void { diff --git a/src/Features/Traits/HttpRequest.php b/src/Features/Traits/HttpRequest.php index c4a0356..7f5b233 100644 --- a/src/Features/Traits/HttpRequest.php +++ b/src/Features/Traits/HttpRequest.php @@ -76,16 +76,6 @@ public function requestQueryParamsContains(TableNode $table): void } } - /** - * @Given request cookies contains: - */ - public function requestCookiesContains(TableNode $table): void - { - foreach ($table as $row) { - $this->request->cookies->set($row["key"], $row["value"]); - } - } - /** * @Given request server params contains: */ diff --git a/src/Features/Traits/HttpResponse.php b/src/Features/Traits/HttpResponse.php index 5a280db..aa0f3e1 100644 --- a/src/Features/Traits/HttpResponse.php +++ b/src/Features/Traits/HttpResponse.php @@ -79,17 +79,6 @@ public function aResponseShouldContainJsonFragment(TableNode $table): void } } - /** - * @Then the response should have cookie :name - */ - public function aResponseShouldHaveCookie(string $name): void - { - Assert::assertTrue($this->response->headers->has("Set-Cookie")); - $cookies = $this->response->headers->getCookies(); - $cookieNames = array_map(fn($cookie) => $cookie->getName(), $cookies); - Assert::assertContains($name, $cookieNames); - } - /** * @Then the response should have header :header */ diff --git a/src/Features/Traits/Optional/SpatiePermission.php b/src/Features/Traits/Optional/SpatiePermission.php new file mode 100644 index 0000000..ed4928b --- /dev/null +++ b/src/Features/Traits/Optional/SpatiePermission.php @@ -0,0 +1,105 @@ +recognizeObjectClass($objectName); + $usedTraits = class_uses_recursive($this->getContainer()->make($objectClass)); + Assert::assertTrue(in_array(SpatieLaravelPermissionTraits::HAS_ROLES, $usedTraits, strict: true)); + } + + /** + * @Given :object with :value value in :field field has :role role + */ + public function assignRoleTo(string $role, string $object, string $value, string $field): void + { + $object = $this->getObjectInstance($object, $value, $field); + $object->assignRole($role); + } + + /** + * @Given :object with :value value in :field field :permission permission has been revoked + */ + public function revokePermissionTo(string $permission, string $value, string $field, string $object): void + { + $object = $this->getObjectInstance($object, $value, $field); + $object->revokePermissionTo($permission); + } + + /** + * @Given :object with :value value in :field field :role role has been removed + */ + public function revokeRoleTo(string $role, string $object, string $value, string $field): void + { + $object = $this->getObjectInstance($object, $value, $field); + $object->removeRole($role); + } + + /** + * @Given :object with :value value in :field field has :permission permission + */ + public function givePermissionTo(string $permission, string $value, string $field, string $object): void + { + $object = $this->getObjectInstance($object, $value, $field); + $object->givePermissionTo($permission); + } + + /** + * @Then :object with :value value in :field field should have :role role + */ + public function assertHasRole(string $object, string $field, string $value, string $role): void + { + $object = $this->getObjectInstance($object, $value, $field); + Assert::assertTrue($object->hasRole($role)); + } + + /** + * @Then :object with :value value in :field field should have :permission permission + */ + public function assertHasPermission(string $object, string $field, string $value, string $permission): void + { + $object = $this->getObjectInstance($object, $value, $field); + Assert::assertTrue($object->hasPermissionTo($permission)); + } + + /** + * @Then :object with :value value in :field field should have: + */ + public function assertHas(string $object, string $field, string $value, TableNode $table): void + { + $object = $this->getObjectInstance($object, $value, $field); + + foreach ($table as $row) { + match ($row["key"]) { + "role" => Assert::assertTrue($object->hasRole($row["value"])), + "permission" => Assert::assertTrue($object->hasPermissionTo($row["value"])), + }; + } + } + + private function getObjectInstance(string $object, string $value, string $field): object + { + $objectClass = ContextHelper::getClassHelper()->recognizeObjectClass($object); + + return $objectClass::query()->where($field, $value)->first(); + } +} diff --git a/src/Helpers/ClassHelper.php b/src/Helpers/ClassHelper.php index fb11008..adc52cc 100644 --- a/src/Helpers/ClassHelper.php +++ b/src/Helpers/ClassHelper.php @@ -28,7 +28,7 @@ public function recognizeObjectClass(string $objectName): string return $typeNamespaces[$type] . $objectName; } - return self::getObjectNamespace(Str::singular($objectName), $type) . $objectName; + return self::getObjectNamespace($type) . $objectName; } public function getObjectNamespace(string $type): string diff --git a/src/SpatieLaravelPermissionTraits.php b/src/SpatieLaravelPermissionTraits.php new file mode 100644 index 0000000..37bd03e --- /dev/null +++ b/src/SpatieLaravelPermissionTraits.php @@ -0,0 +1,10 @@ +getPublicFunctions(); + + foreach ($functions as $class => $methods) { + $trait = explode("\\", $class); + $fileName = Str::kebab(end($trait)) . ".html"; + $filePath = "docs/elements/$fileName"; + + $replacements = [ + "http-request.html" => "http.html", + "http-response.html" => "http.html", + ]; + + foreach ($replacements as $search => $replacement) { + if (str_ends_with($filePath, $search)) { + $filePath = str_replace($search, $replacement, $filePath); + } + } + + if (!file_exists($filePath)) { + $this->fail("Documentation file $filePath does not exist."); + } + + $fileContent = file_get_contents($filePath); + + if ($fileContent === false) { + $this->fail("Unable to read the file $filePath."); + } + + foreach ($methods as $method) { + $containsFunction = str_contains($fileContent, $method) !== false; + $this->assertTrue($containsFunction, "Function $method is not documented in $filePath."); + } + } + } + + protected function getBltTraits(): array + { + $classes = include "vendor/composer/autoload_classmap.php"; + $bltTraits = []; + + foreach (array_keys($classes) as $class) { + if (str_starts_with($class, "Blumilk\BLT\Features\Traits")) { + $bltTraits[] = $class; + } + } + + return $bltTraits; + } + + protected function getPublicFunctions(): array + { + $traitClasses = $this->getBltTraits(); + $publicFunctions = []; + + foreach ($traitClasses as $traitClass) { + $traitReflection = new ReflectionClass($traitClass); + $publicMethods = $traitReflection->getMethods(ReflectionMethod::IS_PUBLIC); + $includedTraitNames = $traitReflection->getTraitNames(); + $includedTraitPublicMethods = []; + + foreach ($includedTraitNames as $includedTraitName) { + $includedTraitPublicMethods = array_merge( + (new ReflectionClass($includedTraitName))->getMethods(ReflectionMethod::IS_PUBLIC), + $includedTraitPublicMethods, + ); + } + + $includedTraitMethodNames = []; + + foreach ($includedTraitPublicMethods as $includedTraitMethod) { + $includedTraitMethodNames[] = $includedTraitMethod->getName(); + } + + foreach ($publicMethods as $publicMethod) { + if (!in_array($publicMethod->getName(), $includedTraitMethodNames, strict: true)) { + $publicFunctions[$traitClass][] = $publicMethod->getName(); + } + } + } + + return $publicFunctions; + } +}