diff --git a/common.props b/common.props index 48e20853bf..2c7058128c 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 0.3.4 + 0.3.5 $(NoWarn);CS1591 http://www.aspnetboilerplate.com/images/abp_nupkg.png http://abp.io diff --git a/docs/Tutorials/AspNetCore-Mvc/Part-I.md b/docs/Tutorials/AspNetCore-Mvc/Part-I.md index 290c0a558e..43fbf7b500 100644 --- a/docs/Tutorials/AspNetCore-Mvc/Part-I.md +++ b/docs/Tutorials/AspNetCore-Mvc/Part-I.md @@ -20,7 +20,7 @@ This tutorial assumes that you have created a new project, named `Acme.BookStore This is the layered solution structure created from the startup template: -![bookstore-visual-studio-solution](../../images/bookstore-visual-studio-solution.png) +![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution.png) ### Create the Book Entity @@ -95,7 +95,7 @@ public class BookStoreDbContext : AbpDbContext Startup template uses [EF Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/) to create and maintain the database schema. Open the **Package Manager Console (PMC)**, select the `Acme.BookStore.EntityFrameworkCore` as the **default project** and execute the following command: -![bookstore-pmc-add-book-migration](../../images/bookstore-pmc-add-book-migration.png) +![bookstore-pmc-add-book-migration](images/bookstore-pmc-add-book-migration.png) This will create a new migration class inside the `Migrations` folder. Then execute the `Update-Database` command to update the database schema: @@ -107,7 +107,7 @@ PM> Update-Database `Update-Database` command created the `Books` table in the database. Enter a few sample rows, so you can show them on the page: -![bookstore-books-table](../../images/bookstore-books-table.png) +![bookstore-books-table](images/bookstore-books-table.png) ### Create the Application Service @@ -247,7 +247,7 @@ ABP can automatically configures your application services as MVC API Controller The startup template is configured to run the [swagger UI](https://swagger.io/tools/swagger-ui/) using the [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) library. Run the application and enter `http://localhost:53929/swagger/` as URL on your browser: -![bookstore-swagger](../../images/bookstore-swagger.png) +![bookstore-swagger](images/bookstore-swagger.png) You will see some built-in service endpoints as well as the `Book` service and its REST-style endpoints. @@ -273,7 +273,7 @@ acme.bookStore.book.getList({}).done(function (result) { console.log(result); }) Running this code produces such an output: -![bookstore-test-js-proxy-getlist](../../images/bookstore-test-js-proxy-getlist.png) +![bookstore-test-js-proxy-getlist](images/bookstore-test-js-proxy-getlist.png) You can see the **book list** returned from the server. @@ -297,7 +297,7 @@ It's time to create something visible! Instead of classic MVC, we will use the n Create a new `Books` folder under the `Pages` folder of the `Acme.BookStore.Web` project and add a new Razor Page named `Index.html`: -![bookstore-add-index-page](../../images/bookstore-add-index-page.png) +![bookstore-add-index-page](images/bookstore-add-index-page.png) Open the `Index.cshtml` and change the content as shown below: @@ -327,7 +327,7 @@ context.Menu.AddItem( Localization texts are located under the `Localization/BookStore` folder of the `Acme.BookStore.Domain` project: -![bookstore-localization-files](../../images/bookstore-localization-files.png) +![bookstore-localization-files](images/bookstore-localization-files.png) Open the `en.json` file and add localization texts for `Menu:BookStore` and `Menu:Books` keys: @@ -347,7 +347,7 @@ Open the `en.json` file and add localization texts for `Menu:BookStore` and `Men Run the application and see the menu items are added to the top bar: -![bookstore-menu-items](../../images/bookstore-menu-items.png) +![bookstore-menu-items](images/bookstore-menu-items.png) When you click to the Books menu item, you are redirected to the new Books page. @@ -396,7 +396,7 @@ Change the `Pages/Books/Index.cshtml` as following: Create `index.js` JavaScript file under the `wwwroot/pages/books/` folder: -![bookstore-index-js-file](../../images/bookstore-index-js-file.png) +![bookstore-index-js-file](images/bookstore-index-js-file.png) `index.js` content is shown below: @@ -436,7 +436,7 @@ $(function() { The final UI is shown below: -![bookstore-book-list](../../images/bookstore-book-list.png) +![bookstore-book-list](images/bookstore-book-list.png) ### Next Part diff --git a/docs/Tutorials/AspNetCore-Mvc/Part-II.md b/docs/Tutorials/AspNetCore-Mvc/Part-II.md index 422e226d15..adcc389e7b 100644 --- a/docs/Tutorials/AspNetCore-Mvc/Part-II.md +++ b/docs/Tutorials/AspNetCore-Mvc/Part-II.md @@ -16,13 +16,13 @@ You can download the **source code** of the application [from here](https://gith In this section, you will learn how to create a new modal dialog form to create a new book. The result dialog will be like that: -![bookstore-create-dialog](../../images/bookstore-create-dialog.png) +![bookstore-create-dialog](images/bookstore-create-dialog.png) #### Create the Modal Form Create a new razor page, named `CreateModal.cshtml` under the `Pages/Books` folder of the `Acme.BookStore.Web` project: -![bookstore-add-create-dialog](../../images/bookstore-add-create-dialog.png) +![bookstore-add-create-dialog](images/bookstore-add-create-dialog.png) ##### CreateModal.cshtml.cs @@ -110,7 +110,7 @@ Open the `Pages/Books/Index.cshtml` and change the `abp-card-header` tag as show Just added a **New book** button to the **top right** of the table: -![bookstore-new-book-button](../../images/bookstore-new-book-button.png) +![bookstore-new-book-button](images/bookstore-new-book-button.png) Open the `wwwroot/pages/books/index.js` and add the following code just after the datatable configuration: @@ -135,7 +135,7 @@ Now, you can **run the application** and add new books using the new modal form. Create a new razor page, named `EditModal.cshtml` under the `Pages/Books` folder of the `Acme.BookStore.Web` project: -![bookstore-add-edit-dialog](../../images/bookstore-add-edit-dialog.png) +![bookstore-add-edit-dialog](images/bookstore-add-edit-dialog.png) #### EditModal.cshtml.cs @@ -251,7 +251,7 @@ This page is very similar to the `CreateModal.cshtml` except; We will add a dropdown button ("Actions") for each row of the table. The final UI looks like this: -![bookstore-books-table-actions](../../images/bookstore-books-table-actions.png) +![bookstore-books-table-actions](images/bookstore-books-table-actions.png) Open the `Pages/Books/Index.cshtml` page and change the table section as shown below: diff --git a/docs/Tutorials/AspNetCore-Mvc/Part-III.md b/docs/Tutorials/AspNetCore-Mvc/Part-III.md index 18e006adf4..1b03bc8059 100644 --- a/docs/Tutorials/AspNetCore-Mvc/Part-III.md +++ b/docs/Tutorials/AspNetCore-Mvc/Part-III.md @@ -12,4 +12,207 @@ This is the third part of the tutorial series. See all parts: You can download the **source code** of the application [from here](https://github.com/volosoft/abp/tree/master/samples/BookStore). -TODO... \ No newline at end of file +### Test Projects in the Solution + +There are two test projects in the solution: + +![bookstore-test-projects](images/bookstore-test-projects.png) + +* `Acme.BookStore.Application.Tests` is for unit & integration test projects. You can write tests for application services those are integrated to the framework. It uses **EF Core SQLite in-memory** database. +* `Acme.BookStore.Web.Tests` is for full stack integration tests including the web layer. So, you can write tests for UI too. + +Test projects uses the following libraries for testing: + +* [xunit](https://xunit.github.io/) as the main test framework. +* [Shoudly](http://shouldly.readthedocs.io/en/latest/) as an assertion library. +* [NSubstitute](http://nsubstitute.github.io/) as a mocking library. + +### Adding Test Data + +Startup template contains the `BookStoreTestDataBuilder` class in the `Acme.BookStore.Application.Tests` project that creates some data to run tests on. It's shown below: + +````C# +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.Threading; + +namespace Acme.BookStore +{ + public class BookStoreTestDataBuilder : ITransientDependency + { + private readonly IIdentityDataSeeder _identityDataSeeder; + + public BookStoreTestDataBuilder(IIdentityDataSeeder identityDataSeeder) + { + _identityDataSeeder = identityDataSeeder; + } + + public void Build() + { + AsyncHelper.RunSync(BuildInternalAsync); + } + + public async Task BuildInternalAsync() + { + await _identityDataSeeder.SeedAsync("1q2w3E*"); + } + } +} +```` + +* It simply uses `IIdentityDataSeeder` which is implemented by the identity module and creates an admin role and admin user. You can use them in the tests. + +Change the `BookStoreTestDataBuilder` class as show below: + +````C# +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Identity; +using Volo.Abp.Threading; + +namespace Acme.BookStore +{ + public class BookStoreTestDataBuilder : ITransientDependency + { + private readonly IIdentityDataSeeder _identityDataSeeder; + private readonly IRepository _bookRepository; + + public BookStoreTestDataBuilder( + IIdentityDataSeeder identityDataSeeder, + IRepository bookRepository) + { + _identityDataSeeder = identityDataSeeder; + _bookRepository = bookRepository; + } + + public void Build() + { + AsyncHelper.RunSync(BuildInternalAsync); + } + + public async Task BuildInternalAsync() + { + await _identityDataSeeder.SeedAsync("1q2w3E*"); + + await _bookRepository.InsertAsync( + new Book + { + Id = Guid.NewGuid(), + Name = "Test book 1", + Type = BookType.Fantastic, + PublishDate = new DateTime(2015, 05, 24), + Price = 21 + } + ); + + await _bookRepository.InsertAsync( + new Book + { + Id = Guid.NewGuid(), + Name = "Test book 2", + Type = BookType.Science, + PublishDate = new DateTime(2014, 02, 11), + Price = 15 + } + ); + } + } +} +```` + +* Injected `IRepository` and used it in the `BuildInternalAsync` to create 2 book entities. + +### Testing the BookAppService + +Create a test class named `BookAppService_Tests` in the `Acme.BookStore.Application.Tests` project: + +````C# +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Application.Dtos; +using Xunit; + +namespace Acme.BookStore +{ + public class BookAppService_Tests : BookStoreApplicationTestBase + { + private readonly IBookAppService _bookAppService; + + public BookAppService_Tests() + { + _bookAppService = GetRequiredService(); + } + + [Fact] + public async Task Should_Get_List_Of_Books() + { + //Act + var result = await _bookAppService.GetListAsync( + new PagedAndSortedResultRequestDto() + ); + + //Assert + result.TotalCount.ShouldBeGreaterThan(0); + result.Items.ShouldContain(b => b.Name == "Test book 1"); + } + } +} +```` + +* `Should_Get_List_Of_Books` test simply uses `BookAppService.GetListAsync` method to get and check the list of users. + +Add a new test that creates a valid new book: + +````C# +[Fact] +public async Task Should_Create_A_Valid_Book() +{ + //Act + var result = await _bookAppService.CreateAsync( + new CreateUpdateBookDto + { + Name = "New test book 42", + Price = 10, + PublishDate = DateTime.Now, + Type = BookType.ScienceFiction + } + ); + + //Assert + result.Id.ShouldNotBe(Guid.Empty); + result.Name.ShouldBe("New test book 42"); +} +```` + +Add a new test that tries to create an invalid book and fails: + +````C# +[Fact] +public async Task Should_Not_Create_A_Book_Without_Name() +{ + var exception = await Assert.ThrowsAsync(async () => + { + await _bookAppService.CreateAsync( + new CreateUpdateBookDto + { + Name = "", + Price = 10, + PublishDate = DateTime.Now, + Type = BookType.ScienceFiction + } + ); + }); + + exception.ValidationErrors + .ShouldContain(err => err.MemberNames.Any(mem => mem == "Name")); +} +```` + +* Since the `Name` is set as empty, ABP throws an `AbpValidationException`. + +### Testing Web Pages + +TODO \ No newline at end of file diff --git a/docs/images/bookstore-add-create-dialog.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog.png similarity index 100% rename from docs/images/bookstore-add-create-dialog.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog.png diff --git a/docs/images/bookstore-add-edit-dialog.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png similarity index 100% rename from docs/images/bookstore-add-edit-dialog.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png diff --git a/docs/images/bookstore-add-index-page.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page.png similarity index 100% rename from docs/images/bookstore-add-index-page.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page.png diff --git a/docs/images/bookstore-book-list.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-book-list.png similarity index 100% rename from docs/images/bookstore-book-list.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-book-list.png diff --git a/docs/images/bookstore-books-table-actions.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png similarity index 100% rename from docs/images/bookstore-books-table-actions.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png diff --git a/docs/images/bookstore-books-table.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png similarity index 100% rename from docs/images/bookstore-books-table.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png diff --git a/docs/images/bookstore-create-dialog.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog.png similarity index 100% rename from docs/images/bookstore-create-dialog.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog.png diff --git a/docs/images/bookstore-create-template.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-create-template.png similarity index 100% rename from docs/images/bookstore-create-template.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-create-template.png diff --git a/docs/images/bookstore-homepage.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-homepage.png similarity index 100% rename from docs/images/bookstore-homepage.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-homepage.png diff --git a/docs/images/bookstore-index-js-file.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file.png similarity index 100% rename from docs/images/bookstore-index-js-file.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file.png diff --git a/docs/images/bookstore-localization-files.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files.png similarity index 100% rename from docs/images/bookstore-localization-files.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files.png diff --git a/docs/images/bookstore-menu-items.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png similarity index 100% rename from docs/images/bookstore-menu-items.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png diff --git a/docs/images/bookstore-new-book-button.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png similarity index 100% rename from docs/images/bookstore-new-book-button.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png diff --git a/docs/images/bookstore-pmc-add-book-migration.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration.png similarity index 100% rename from docs/images/bookstore-pmc-add-book-migration.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration.png diff --git a/docs/images/bookstore-swagger.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png similarity index 100% rename from docs/images/bookstore-swagger.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png diff --git a/docs/images/bookstore-test-js-proxy-getlist.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png similarity index 100% rename from docs/images/bookstore-test-js-proxy-getlist.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png diff --git a/docs/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects.png new file mode 100644 index 0000000000..f9511d7b11 Binary files /dev/null and b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects.png differ diff --git a/docs/images/bookstore-user-management.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-user-management.png similarity index 100% rename from docs/images/bookstore-user-management.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-user-management.png diff --git a/docs/images/bookstore-visual-studio-solution.png b/docs/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution.png similarity index 100% rename from docs/images/bookstore-visual-studio-solution.png rename to docs/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution.png diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs index 7c854baef1..23453df1d0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs @@ -1,4 +1,5 @@ -using System.Text; +using System.Linq; +using System.Text; using Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @@ -8,15 +9,18 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = null; - output.PreContent.SetHtmlContent(CreatePreContent()); + output.PreContent.SetHtmlContent(CreatePreContent(output)); output.PostContent.SetHtmlContent(CreatePostContent()); } - protected virtual string CreatePreContent() + protected virtual string CreatePreContent(TagHelperOutput output) { var sb = new StringBuilder(); - sb.AppendLine("
"); + var attritubutes = output.Attributes.Select(a => " " + a.Name + "=\"" + a.Value + "\" ").ToList(); + var attritubutesAsJoin = string.Join(" ", attritubutes.ToArray()); + + sb.AppendLine("
"); sb.AppendLine("
"); sb.AppendLine("
"); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Alerts.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Alerts.cshtml index 37367dd4bc..d2356bf771 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Alerts.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Alerts.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Alerts"; } +@section styles { + + + +} +

Alerts

Based on Bootstrap Alert.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Badges.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Badges.cshtml index ee5ea9b293..d5352312a7 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Badges.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Badges.cshtml @@ -4,17 +4,23 @@ ViewData["Title"] = "Badges"; } +@section styles { + + + +} +

Badges

-

Based on Bootstrap Badge.

+

Based on Bootstrap Badge.

# Badges Examples

- I'm an abp badge! - I'm an abp pill badge! + I'm an abp badge! + I'm an abp pill badge! I'm an abp badge link! I'm an abp pill badge link! diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Blockquotes.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Blockquotes.cshtml index fb7f2b990f..4f8b1c3a5f 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Blockquotes.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Blockquotes.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Badges"; } +@section styles { + + + +} +

Blockquotes

Based on Bootstrap Blockquotes.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Borders.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Borders.cshtml index 14cedaff07..0f59a257eb 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Borders.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Borders.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Borders"; } +@section styles { + + + +} +

Borders

Based on Bootstrap Border.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Breadcrumbs.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Breadcrumbs.cshtml index 59e94a0fca..e3ab71b246 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Breadcrumbs.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Breadcrumbs.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Breadcrumbs"; } +@section styles { + + + +} +

Breadcrumbs

Based on Bootstrap Breadcrumb.

@@ -14,9 +20,9 @@
- - - + + +
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml index 11464b53cc..ce2cb2d42d 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Buttons"; } +@section styles { + + + +} +

Buttons

Based on Bootstrap button.

@@ -12,7 +18,7 @@
- Default + Primary Secondary Success @@ -25,7 +31,7 @@
-<abp-button>Default</abp-button>
+<abp-button text="Default"/>
 <abp-button button-type="Primary">Primary</abp-button>
 <abp-button button-type="Secondary">Secondary</abp-button>
 <abp-button button-type="Success">Success</abp-button>
@@ -42,9 +48,9 @@
 

# Example

-
+
Link - Button + @@ -52,10 +58,51 @@
 <a abp-button="Primary" href="#">Link</a>
-<abp-button button-type="Primary" type="submit">Button</abp-button>
+<abp-button button-type="Primary" type="submit" text="Button"/>
 <input abp-button="Primary" value="Input" />
 <input abp-button="Primary" type="submit" value="Submit" />
 <input abp-button="Primary" type="reset" value="Reset" />
+
+
+
+ +

# Example

+ +
+
+ + +
+
+
+<abp-button size="Large" text="Large"/>
+<abp-button size="Small" text="Small"/>
+
+
+
+ +

# Example

+ +
+
+ +
+
+
+<abp-button icon-type="FontAwesome" icon="info" text="With Icon"/>
+
+
+
+ +

# Example

+ +
+
+ +
+
+
+<abp-button text="Busy" busy-text="Saving..."/>
 
\ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Cards.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Cards.cshtml index 194ca96ad8..4f23e041f8 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Cards.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Cards.cshtml @@ -4,19 +4,14 @@ ViewData["Title"] = "Cards"; } -

Cards

+@section styles { + + + +} -@* -

# Example

+

Cards

-
-
-
-
-

-        
-
-*@

Based on Bootstrap card.

@@ -100,10 +95,10 @@ Active @@ -122,10 +117,10 @@ <a class="nav-link active" href="#">Active</a> </li> <li class="nav-item"> - <a class="nav-link" href="#">Link</a> + <a class="nav-link" href="#link">Link</a> </li> <li class="nav-item"> - <a class="nav-link disabled" href="#">Disabled</a> + <a class="nav-link disabled" href="#disabledlink">Disabled</a> </li> </ul> </abp-card-header> diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml index c36abe3728..2ea6fa3f60 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Carousels"; } +@section styles { + + + +} +

Carousels

Based on Bootstrap Carousel.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml index 644df447d7..adbe35a3fa 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml @@ -5,6 +5,12 @@ ViewData["Title"] = "Collapse"; } + +@section styles { + + + +}

Collapse

Based on Bootstrap Collapse.

@@ -48,13 +54,13 @@
- +

Toggle

- + 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml index eedef519ce..7604f18abc 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Dropdowns"; } +@section styles { + + + +} +

Dropdowns

Based on Bootstrap button.

@@ -14,13 +20,13 @@
- + Dropdown header Action Another disabled action Something else here - + Separated link @@ -49,13 +55,13 @@
- + Dropdown header Action Another disabled action Something else here - + Separated link @@ -84,13 +90,13 @@
- + Dropdown header Action Another disabled action Something else here - + Separated link diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml index 745bc3befa..87d4c75a84 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml @@ -6,13 +6,19 @@ ViewData["Title"] = "Forms"; } +@section styles { + + + +} +

Dynamic Forms

# Dynamic Form Example

- +
Posted Values:
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Grids.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Grids.cshtml index aa12bf5431..4957fd3636 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Grids.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Grids.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Grids"; } +@section styles { + + + +} +

Grids

Based on Bootstrap grid.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml index 693160844c..9ec4f0106e 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Images"; } +@section styles { + + + +} +

Images

Based on Bootstrap Images.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ListGroup.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ListGroup.cshtml index d0f107cf7f..90097a3c4d 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ListGroup.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ListGroup.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "List Groups"; } +@section styles { + + + +} +

List Groups

Based on Bootstrap List Group.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml index d1548826b2..0a3aa3d8b9 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml @@ -5,19 +5,26 @@ ViewData["Title"] = "Modals"; } +@section styles { + + + +} +

Modals

-

Based on Bootstrap Modal.

+

Based on Bootstrap Modal.

# Modal Example

+ Launch modal + + - - - + Body @@ -29,7 +36,7 @@
-<abp-modal>
+<abp-modal id="myModal">
    <abp-modal-header title="Header"></abp-modal-header>
    <abp-modal-body>
        Body
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml
index 1edd06dd09..d351878652 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml
@@ -4,6 +4,12 @@
     ViewData["Title"] = "Navs";
 }
 
+@section styles {
+    
+        
+    
+}
+
 

Navs

Based on Bootstrap Navs.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml index 2d40ca5416..bcf117945c 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Paginator"; } +@section styles { + + + +} +

Paginator

# Paginator Examples

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml index 954008260a..f9563a5c8b 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Badges"; } +@section styles { + + + +} +

Popovers

Based on Bootstrap Popovers.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ProgressBars.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ProgressBars.cshtml index 08c5a18fb3..563e23a9c8 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ProgressBars.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ProgressBars.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Progress Bars"; } +@section styles { + + + +} +

Progress Bars

Based on Bootstrap Progress Bars.

@@ -14,8 +20,8 @@
- - + +
@@ -30,7 +36,7 @@
- + %50 diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tables.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tables.cshtml index d083d1e40d..127cd61715 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tables.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tables.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Tables"; } +@section styles { + + + +} +

Tables

Based on Bootstrap Tables.

@@ -15,32 +21,32 @@ - - # - First - Last - Handle - + + # + First + Last + Handle + - - 1 - Mark - Otto - mdo - - - 2 - Jacob - Thornton - fat - - - 3 - Larry - the Bird - twitter - + + 1 + Mark + Otto + mdo + + + 2 + Jacob + Thornton + fat + + + 3 + Larry + the Bird + twitter + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tabs.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tabs.cshtml index f821994e3f..1baa0047e1 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tabs.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tabs.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Tabs"; } +@section styles { + + + +} +

Tabs

Based on Bootstrap tab.

@@ -15,7 +21,7 @@ Content_Home - + Content_Profile @@ -48,7 +54,7 @@ Content_Home - + Content_Profile @@ -81,7 +87,7 @@ Content_Home - + Content_Profile @@ -114,7 +120,7 @@ Content_Home - + Content_Profile diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tooltips.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tooltips.cshtml index a85d70e159..fe0aeebae4 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tooltips.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tooltips.cshtml @@ -4,6 +4,12 @@ ViewData["Title"] = "Badges"; } +@section styles { + + + +} +

Tooltips

Based on Bootstrap Tooltips.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.scss b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.scss index b37214bf94..c9c78fa28b 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.scss +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.scss @@ -1,15 +1,16 @@ .demo-with-code { - padding-bottom: 10px; margin-bottom: 10px; .demo-area { + margin-top: 20px; margin-bottom: 1em; } .code-area { border: 1px solid #ddd; padding: 10px; + margin-top: 10px; font-size: 0.9em; } } diff --git a/modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj b/modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj index ee579b03ca..042a6023e7 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj +++ b/modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj @@ -28,8 +28,11 @@ - - + + + + + diff --git a/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj b/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj index 97b44a489c..e98734642d 100644 --- a/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj +++ b/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj @@ -22,5 +22,16 @@ + + + + + + + + + + + diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Volo.Abp.TenantManagement.Web.csproj b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Volo.Abp.TenantManagement.Web.csproj index b672ed2438..94071ed59e 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Volo.Abp.TenantManagement.Web.csproj +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Volo.Abp.TenantManagement.Web.csproj @@ -1,4 +1,4 @@ - + @@ -17,6 +17,17 @@ + + + + + + + + + + + diff --git a/samples/BookStore/test/Acme.BookStore.Application.Tests/BookAppService_Tests.cs b/samples/BookStore/test/Acme.BookStore.Application.Tests/BookAppService_Tests.cs new file mode 100644 index 0000000000..78d291bb33 --- /dev/null +++ b/samples/BookStore/test/Acme.BookStore.Application.Tests/BookAppService_Tests.cs @@ -0,0 +1,70 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Validation; +using Xunit; + +namespace Acme.BookStore +{ + public class BookAppService_Tests : BookStoreApplicationTestBase + { + private readonly IBookAppService _bookAppService; + + public BookAppService_Tests() + { + _bookAppService = GetRequiredService(); + } + + [Fact] + public async Task Should_Get_List_Of_Books() + { + //Act + var result = await _bookAppService.GetListAsync(new PagedAndSortedResultRequestDto()); + + //Assert + result.TotalCount.ShouldBeGreaterThan(0); + result.Items.ShouldContain(b => b.Name == "Test book 1"); + } + + [Fact] + public async Task Should_Create_A_Valid_Book() + { + //Act + var result = await _bookAppService.CreateAsync( + new CreateUpdateBookDto + { + Name = "New test book 42", + Price = 10, + PublishDate = DateTime.Now, + Type = BookType.ScienceFiction + } + ); + + //Assert + result.Id.ShouldNotBe(Guid.Empty); + result.Name.ShouldBe("New test book 42"); + } + + [Fact] + public async Task Should_Not_Create_A_Book_Without_Name() + { + var exception = await Assert.ThrowsAsync(async () => + { + await _bookAppService.CreateAsync( + new CreateUpdateBookDto + { + Name = "", + Price = 10, + PublishDate = DateTime.Now, + Type = BookType.ScienceFiction + } + ); + }); + + exception.ValidationErrors + .ShouldContain(err => err.MemberNames.Any(mem => mem == "Name")); + } + } +} diff --git a/samples/BookStore/test/Acme.BookStore.Application.Tests/BookStoreTestDataBuilder.cs b/samples/BookStore/test/Acme.BookStore.Application.Tests/BookStoreTestDataBuilder.cs index 9881b7e7be..d29cad952f 100644 --- a/samples/BookStore/test/Acme.BookStore.Application.Tests/BookStoreTestDataBuilder.cs +++ b/samples/BookStore/test/Acme.BookStore.Application.Tests/BookStoreTestDataBuilder.cs @@ -1,5 +1,7 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; using Volo.Abp.Identity; using Volo.Abp.Threading; @@ -8,10 +10,14 @@ namespace Acme.BookStore public class BookStoreTestDataBuilder : ITransientDependency { private readonly IIdentityDataSeeder _identityDataSeeder; + private readonly IRepository _bookRepository; - public BookStoreTestDataBuilder(IIdentityDataSeeder identityDataSeeder) + public BookStoreTestDataBuilder( + IIdentityDataSeeder identityDataSeeder, + IRepository bookRepository) { _identityDataSeeder = identityDataSeeder; + _bookRepository = bookRepository; } public void Build() @@ -22,6 +28,28 @@ namespace Acme.BookStore public async Task BuildInternalAsync() { await _identityDataSeeder.SeedAsync("1q2w3E*"); + + await _bookRepository.InsertAsync( + new Book + { + Id = Guid.NewGuid(), + Name = "Test book 1", + Type = BookType.Fantastic, + PublishDate = new DateTime(2015, 05, 24), + Price = 21 + } + ); + + await _bookRepository.InsertAsync( + new Book + { + Id = Guid.NewGuid(), + Name = "Test book 2", + Type = BookType.Science, + PublishDate = new DateTime(2014, 02, 11), + Price = 15 + } + ); } } } \ No newline at end of file