Tuesday 19 April 2022

Integrate CK Editor to ASP .NET Core MVC Web Application


 If you are a newbie to ASP .NET Core and looking for a step-by-step explanation of integrating a text editing tool with your newly created ASP .NET Core MVC web application and saving the text in the database, you are going to read the right article.

In the following article, I will explain how the most popular text editing tool ‘CK Editor’ is integrated with an ASP .NET Core MVC web application. The text generated by the CK Editor will be saved in a Microsoft SQL database. Here also I will employ the Identity UI framework for user authentication in the web application.

The content is as follows:

  1. Create ASP .NET Core MVC Web Application (Code First).
  2. Create the database (Microsoft SQL).
  3. Download and extract CKEditor.
  4. Integrate CKEditor with the web app.

1. Create ASP .NET Core MVC Web Application (Code First)

Fig 01: Create ASP .NET Core MVC Web Application

Create your model classes for the ‘User’ (ApplicationUser.cs) as follows: (Remember the application user must inherit from the Identity User. Then all the attributes relevant to the Identity User also inherit to the application user.)

ApplicationUser.cs

Next, create the model class for the text document that is generated from the CK editor. I have named it ‘UserArticle.’ The fields to save the article Id, the Id of the user who wrote the article, the title of the article, the description, and the date-time the article is stored in the database are included in the model class.

UserArticle.cs

2. Create the Database

Then it is necessary to update the database context class (ApplicationDbContext.cs) to eventually create new migrations and the database. Finally, you can annotate the primary keys, foreign keys, and attributes’ parameters of the entities within the database context class.

ApplicationDbContext.cs

The ‘ASPNetUsers’ entity created by the ApplicationUser model has an ‘autogenerated string’ as the Id, and the entity ‘UserArtilcle’ created by the model ‘UserArtilcle’ has an auto-incrementing integer type Id. The date-time of the files uploaded is automatically inserted into the table.

Having modified the database context class, now you can create migrations. First, delete the available migration folder with its content and run the following command in the NuGet PackageManger console.

add-migration CKEditor-ASP.NETCore-Migrations

‘CKEditor-ASP.NETCore-Migrations’ is the name of the migration file (you can change it as your wish). The above command will create a new set of migration files. Now you can update the database. Before that, you have to take the database connection string to your Microsoft SQL database.

Then update the appsettings.json file as follows:

appsettings.json

Now run the following command in the NuGet PackageManger console to update the database and create the tables (Fig 02).

update-database
Fig 02: Users table and UserMedia tables are created by the update-database command

3. Download and extract CKEditor.

The official CKEditor website states that “CKEditor is a WYSIWYG rich text editor that enables writing content directly inside web pages or online applications.”

Go to the download page and download the required version of the CKEditor: Here, I download the ‘Full Package’ of CKEditor v4.16.0, released on 26–01–2021. You can download any package according to the requirement, and even you can customize the tools according to your preference and download the package from the final option ‘Customize’ (Fig 03).

Download URL: https://ckeditor.com/ckeditor-4/download/

Fig 03: Download ‘Full Package’ version of CKEditor 4

Then extract the content and paste the extracted ‘ckeditor’ folder under the ‘js’ folder of ‘wwwroot’ directory.

Fig 04: Extract the content and paste under the ‘js’ folder of ‘wwwroot’ directory

Next, we will integrate the CKEditor with the .cshtml view of the web application.

4. Integrate CKEditor with the web app

The final step is to modify the codebase to integrate the CKEditor into your web application.

To integrate the CKEditor with the .cshtml view, you have to import the CKEditor JavaScript library as follows:

We are using the model UserArticle to write the data into the database tables. Therefore ‘UserArticle’ model is used in the .cshtml view. Next, the CKEditor JavaScript library must be imported as follows:

<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/ckeditor/ckeditor.js"></script>

The ‘id’ attribute of the <textarea> tag should be ‘Description’ which is the property of model ‘UserArticle’ to store the article content as a markup string.

Finally, use the following jquery to load the CKEditor to the text area:

$(document).ready(function () {
CKEDITOR.replace(‘#Description’);
});

The complete .cshtml view is as follows:

WriteArticle.cshtml

Now, everything is set up correctly, and you can successfully write articles with different text formats and save the content in the database.

source: https://enlear.academy/integrate-ck-editor-to-asp-net-core-mvc-web-application-239b2cd18556



Sunday 17 April 2022

Learn how to start Testing in Laravel with Simple Examples using PHPUnit and PEST


 When talking about automated tests or unit tests in any programming language, there are two groups of people:

  • Those who don't write automated tests and think they're a waste of time
  • Those who do write tests and then can't imagine their work without them

So, with this article, I will try to convince the former camp to look at the other side and see the benefits, and see how easy it is to start with automated testing in Laravel.

First, let's talk about the "why" and then I'll show a few very basic examples of the "how".


Why You Need Automated Tests

Automated tests are not complicated: they just run parts of your code for you and report any errors. That's the most simple way to describe them. Imagine that you're launching a new feature in your app, and then a personal robot assistant would go and manually test the new functionality for you, also testing if the new code didn't break anything from the old features.

That's the main benefit: re-testing all the features automatically. And it may seem like extra work, but if you don't tell that "robot" to do it, then you should do it manually yourself, right? Or do you just launch the new features without too much testing, hoping that the users would report the bugs? I call that method sarcastically "fingers-crossed-driven development".

With every new feature of your app, automated tests pay off more and more.

  • Feature 1: saves X minutes of testing manually
  • Feature 2: saves 2X minutes - for feature 2 and feature 1 again
  • Feature 3: saves 3X minutes...
  • etc.

You get the idea. Imagine your application in a year or two, with new developers on the team who wouldn't even know how that "Feature 1" works or how to reproduce it for testing. So, your future self will thank you massively for writing the automated tests.

Of course, if you think that your project is a very short-term one and you don't care that much about its future... Nah, I believe in your good intentions, so let me show you how it's easy to start testing.


Our First Automated Tests

To run the first automated test in Laravel, you don't need to write any code. Yup, you've read that right. Everything is already configured and prepared in the default Laravel installation, including the first real basic example.

You can try to install a Laravel project and immediately run the first tests:

1laravel new project
2cd project
3php artisan test

This should be the result in your console:

1 PASS Tests\Unit\ExampleTest
2 that true is true
3 
4 PASS Tests\Feature\ExampleTest
5 the application returns a successful response
6 
7Tests: 2 passed
8Time: 0.10s

If we take a look at the default Laravel /tests folder, we have two files.

tests/Feature/ExampleTest.php:

1class ExampleTest extends TestCase
2{
3 public function test_the_application_returns_a_successful_response()
4 {
5 $response = $this->get('/');
6 
7 $response->assertStatus(200);
8 }
9}

There's no need to know any syntax, to understand what is happening here: loading the homepage and checking if the HTTP status code is "200 OK".

Also notice how the method name test_the_application_returns_a_successful_response() becomes readable text when viewing the test results, just replacing the underscore symbol with a space.

tests/Unit/ExampleTest.php:

1class ExampleTest extends TestCase
2{
3 public function test_that_true_is_true()
4 {
5 $this->assertTrue(true);
6 }
7}

This looks a bit pointless, checking that true is true? We'll talk about unit tests specifically, a bit later. For now, you need to understand what is generally happening in every test.

  • Each test file in the tests/ folder is a PHP Class extending the TestCase of PHPUnit
  • Inside of each class, you may create multiple methods, usually one method for one situation to be tested
  • Inside of each method, there are three actions: preparation of the situation, then action, and then checking (asserting) if the result is as expected

Structurally, that's all you need to know, everything else depends on the exact things you want to test.

To generate an empty test class, you just run this command:

1php artisan make:test HomepageTest

It would generate the file tests/Feature/HomepageTest.php:

1class HomepageTest extends TestCase
2{
3 // Replace this method with your own ones
4 public function test_example()
5 {
6 $response = $this->get('/');
7 
8 $response->assertStatus(200);
9 }
10}

What If Tests Fail?

Let me show you what happens if the test assertions don't return the expected result.

Let's edit the example tests to this:

1class ExampleTest extends TestCase
2{
3 public function test_the_application_returns_a_successful_response()
4 {
5 $response = $this->get('/non-existing-url');
6 
7 $response->assertStatus(200);
8 }
9}
10 
11 
12class ExampleTest extends TestCase
13{
14 public function test_that_true_is_false()
15 {
16 $this->assertTrue(false);
17 }
18}

And now, if we run php artisan test again:

1 
2 FAIL Tests\Unit\ExampleTest
3 that true is true
4 
5 FAIL Tests\Feature\ExampleTest
6 the application returns a successful response
7 
8---
9 
10 Tests\Unit\ExampleTest > that true is true
11Failed asserting that false is true.
12 
13at tests/Unit/ExampleTest.php:16
14 12▕ * @return void
15 13▕ */
16 14▕ public function test_that_true_is_true()
17 15▕ {
18 16▕ $this->assertTrue(false);
19 17▕ }
20 18▕ }
21 19▕
22 
23 Tests\Feature\ExampleTest > the application returns a successful response
24Expected response status code [200] but received 404.
25Failed asserting that 200 is identical to 404.
26 
27at tests/Feature/ExampleTest.php:19
28 15▕ public function test_the_application_returns_a_successful_response()
29 16▕ {
30 17▕ $response = $this->get('/non-existing-url');
31 18▕
32 19▕ $response->assertStatus(200);
33 20▕ }
34 21▕ }
35 22▕
36 
37 
38Tests: 2 failed
39Time: 0.11s

As you can see, there are two statements marked as FAIL, with explanations below and arrows to the exact test line that failed the assertion. So this is how the errors are shown. Convenient, isn't it?


Simple Real-Life Example: Registration Form

Let's get more practical and look at a real-life example. Imagine that you have a form, and you need to test various cases: check if it fails if filled with invalid data, check if it succeeds with the correct input, etc.

Did you know that the official Laravel Breeze starter kit comes with the feature tests inside? So, let's take a look at a few examples from there:

tests/Feature/RegistrationTest.php

1use App\Providers\RouteServiceProvider;
2use Illuminate\Foundation\Testing\RefreshDatabase;
3use Tests\TestCase;
4 
5class RegistrationTest extends TestCase
6{
7 use RefreshDatabase;
8 
9 public function test_registration_screen_can_be_rendered()
10 {
11 $response = $this->get('/register');
12 
13 $response->assertStatus(200);
14 }
15 
16 public function test_new_users_can_register()
17 {
18 $response = $this->post('/register', [
19 'name' => 'Test User',
20 'email' => 'test@example.com',
21 'password' => 'password',
22 'password_confirmation' => 'password',
23 ]);
24 
25 $this->assertAuthenticated();
26 $response->assertRedirect(RouteServiceProvider::HOME);
27 }
28}

Here we have two tests in one class, as they are both related to the registration form: one is checking if the form is loaded correctly, and another one checks if the submission works well.

Full Details