Merge branch 'Dev' of https://github.com/dotnet/eShopOnContainers
This commit is contained in:
commit
99b26d5387
23
add-firewall-docker.ps1
Normal file
23
add-firewall-docker.ps1
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
param([switch]$Elevated)
|
||||||
|
function Check-Admin {
|
||||||
|
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
|
||||||
|
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
|
||||||
|
}
|
||||||
|
if ((Check-Admin) -eq $false) {
|
||||||
|
if ($elevated)
|
||||||
|
{
|
||||||
|
# could not elevate, quit
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
|
||||||
|
}
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
$reglas = Get-NetFirewallRule -DisplayName 'EshopDocker'
|
||||||
|
if ($reglas.Length -gt 0)
|
||||||
|
{
|
||||||
|
New-NetFirewallRule -DisplayName EshopDocker -Confirm -Description "Eshop on Containers" -LocalAddress Any -LocalPort Any -Protocol tcp -RemoteAddress Any -RemotePort 5100-5105 -Direction Inbound
|
||||||
|
New-NetFirewallRule -DisplayName EshopDocker -Confirm -Description "Eshop on Containers" -LocalAddress Any -LocalPort Any -Protocol tcp -RemoteAddress Any -RemotePort 5100-5105 -Direction Outbound
|
||||||
|
}
|
@ -14,8 +14,8 @@ services:
|
|||||||
- CatalogUrl=http://catalog.api
|
- CatalogUrl=http://catalog.api
|
||||||
- OrderingUrl=http://ordering.api:5102
|
- OrderingUrl=http://ordering.api:5102
|
||||||
#- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
#- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
||||||
#- IdentityUrl=http://10.0.75.1:5105 #Local: You need to open windows firewall at range 5100-5105.
|
- IdentityUrl=http://10.0.75.1:5105 #Local: You need to open windows firewall at range 5100-5105.
|
||||||
- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
#- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||||
- BasketUrl=http://basket.api:5103
|
- BasketUrl=http://basket.api:5103
|
||||||
ports:
|
ports:
|
||||||
- "5100:5100"
|
- "5100:5100"
|
||||||
@ -25,7 +25,8 @@ services:
|
|||||||
- CatalogUrl=http://catalog.api
|
- CatalogUrl=http://catalog.api
|
||||||
- OrderingUrl=http://ordering.api
|
- OrderingUrl=http://ordering.api
|
||||||
#- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
#- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
||||||
- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
#- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||||
|
- IdentityUrl=http://10.0.75.1:5105 #Local: You need to open windows firewall at range 5100-5105.
|
||||||
- BasketUrl=http://basket.api:5103
|
- BasketUrl=http://basket.api:5103
|
||||||
ports:
|
ports:
|
||||||
- "5104:80"
|
- "5104:80"
|
||||||
@ -34,7 +35,8 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ConnectionString=basket.data
|
- ConnectionString=basket.data
|
||||||
#- identityUrl=http://13.88.8.119:5105 #Remote
|
#- identityUrl=http://13.88.8.119:5105 #Remote
|
||||||
- identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
#- identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||||
|
- identityUrl=http://10.0.75.1:5105 #Local: You need to open windows firewall at range 5100-5105.
|
||||||
ports:
|
ports:
|
||||||
- "5103:5103"
|
- "5103:5103"
|
||||||
|
|
||||||
@ -47,8 +49,9 @@ services:
|
|||||||
ordering.api:
|
ordering.api:
|
||||||
environment:
|
environment:
|
||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||||
- identityUrl=http://identity.service:5105 #local
|
#- identityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
|
||||||
#- identityUrl=http://13.88.8.119:5105 #remote
|
#- identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||||
|
- identityUrl=http://10.0.75.1:5105 #Local: You need to open windows firewall at range 5100-5105.
|
||||||
ports:
|
ports:
|
||||||
- "5102:5102"
|
- "5102:5102"
|
||||||
|
|
||||||
@ -57,8 +60,8 @@ services:
|
|||||||
- SpaClient=http://localhost:5104
|
- SpaClient=http://localhost:5104
|
||||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
||||||
#- MvcClient=http://13.88.8.119:5100 #Remote: VM Needs to have public access at 5105.
|
#- MvcClient=http://13.88.8.119:5100 #Remote: VM Needs to have public access at 5105.
|
||||||
- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
|
#- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
|
||||||
#10.0.75.1:5105 CCE/TODO: try to avoid host entry.
|
- MvcClient=http://10.0.75.1:5100 #Local: You need to open windows firewall at range 5100-5105.
|
||||||
ports:
|
ports:
|
||||||
- "5105:5105"
|
- "5105:5105"
|
||||||
|
|
||||||
|
@ -47,3 +47,5 @@ services:
|
|||||||
|
|
||||||
basket.data:
|
basket.data:
|
||||||
image: redis
|
image: redis
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
@ -73,7 +73,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.UITests",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{67F9D3A8-F71E-4428-913F-C37AE82CDB24}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{67F9D3A8-F71E-4428-913F-C37AE82CDB24}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.Application", "src\Services\Ordering\Ordering.Application\Ordering.Application.xproj", "{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "UnitTest", "test\Services\UnitTest\UnitTest.xproj", "{7796F5D8-31FC-45A4-B673-19DE5BA194CF}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -908,54 +908,54 @@ Global
|
|||||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x64.Build.0 = Release|Any CPU
|
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.ActiveCfg = Release|Any CPU
|
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.Build.0 = Release|Any CPU
|
{67F9D3A8-F71E-4428-913F-C37AE82CDB24}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|ARM.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x64.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x86.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|ARM.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhone.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x64.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x86.Build.0 = Debug|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|ARM.ActiveCfg = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|ARM.Build.0 = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhone.ActiveCfg = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhone.Build.0 = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhone.Build.0 = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x64.ActiveCfg = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x64.Build.0 = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x86.ActiveCfg = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x86.Build.0 = Release|Any CPU
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -990,6 +990,6 @@ Global
|
|||||||
{621E7211-58D0-45FD-9600-1CB490BD930E} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
|
{621E7211-58D0-45FD-9600-1CB490BD930E} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
|
||||||
{E3B18084-842C-4B80-8E4A-A7E588EC3137} = {B7B1D395-4E06-4036-BE86-C216756B9367}
|
{E3B18084-842C-4B80-8E4A-A7E588EC3137} = {B7B1D395-4E06-4036-BE86-C216756B9367}
|
||||||
{67F9D3A8-F71E-4428-913F-C37AE82CDB24} = {778289CA-31F7-4464-8C2A-612EE846F8A7}
|
{67F9D3A8-F71E-4428-913F-C37AE82CDB24} = {778289CA-31F7-4464-8C2A-612EE846F8A7}
|
||||||
{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B}
|
{7796F5D8-31FC-45A4-B673-19DE5BA194CF} = {EF0337F2-ED00-4643-89FD-EE10863F1870}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
(function ($, swaggerUi) {
|
||||||
|
$(function () {
|
||||||
|
var settings = {
|
||||||
|
authority: 'https://localhost:5105',
|
||||||
|
client_id: 'js',
|
||||||
|
popup_redirect_uri: window.location.protocol
|
||||||
|
+ '//'
|
||||||
|
+ window.location.host
|
||||||
|
+ '/tokenclient/popup.html',
|
||||||
|
|
||||||
|
response_type: 'id_token token',
|
||||||
|
scope: 'openid profile basket',
|
||||||
|
|
||||||
|
filter_protocol_claims: true
|
||||||
|
},
|
||||||
|
manager = new OidcTokenManager(settings),
|
||||||
|
$inputApiKey = $('#input_apiKey');
|
||||||
|
|
||||||
|
$inputApiKey.on('dblclick', function () {
|
||||||
|
manager.openPopupForTokenAsync()
|
||||||
|
.then(function () {
|
||||||
|
$inputApiKey.val(manager.access_token).change();
|
||||||
|
}, function (error) {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(jQuery, window.swaggerUi);
|
8896
src/Services/Basket/Basket.API/Auth/Client/oidc-token-manager.js
Normal file
8896
src/Services/Basket/Basket.API/Auth/Client/oidc-token-manager.js
Normal file
File diff suppressed because one or more lines are too long
13
src/Services/Basket/Basket.API/Auth/Client/popup.html
Normal file
13
src/Services/Basket/Basket.API/Auth/Client/popup.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" src="oidc-token-manager.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
new OidcTokenManager().processTokenPopup();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,35 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||||
|
using Swashbuckle.Swagger.Model;
|
||||||
|
using Swashbuckle.SwaggerGen.Generator;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Basket.API.Auth.Server
|
||||||
|
{
|
||||||
|
public class AuthorizationHeaderParameterOperationFilter : IOperationFilter
|
||||||
|
{
|
||||||
|
public void Apply(Operation operation, OperationFilterContext context)
|
||||||
|
{
|
||||||
|
var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
|
||||||
|
var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
|
||||||
|
var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);
|
||||||
|
|
||||||
|
if (isAuthorized && !allowAnonymous)
|
||||||
|
{
|
||||||
|
if (operation.Parameters == null)
|
||||||
|
operation.Parameters = new List<IParameter>();
|
||||||
|
|
||||||
|
operation.Parameters.Add(new NonBodyParameter
|
||||||
|
{
|
||||||
|
Name = "Authorization",
|
||||||
|
In = "header",
|
||||||
|
Description = "access token",
|
||||||
|
Required = true,
|
||||||
|
Type = "string"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
using Swashbuckle.Swagger.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Basket.API.Auth.Server
|
||||||
|
{
|
||||||
|
public class IdentitySecurityScheme:SecurityScheme
|
||||||
|
{
|
||||||
|
public IdentitySecurityScheme()
|
||||||
|
{
|
||||||
|
Type = "IdentitySecurityScheme";
|
||||||
|
Description = "Security definition that provides to the user of Swagger a mechanism to obtain a token from the identity service that secures the api";
|
||||||
|
Extensions.Add("authorizationUrl", "http://localhost:5103/Auth/Client/popup.html");
|
||||||
|
Extensions.Add("flow", "implicit");
|
||||||
|
Extensions.Add("scopes", new List<string>
|
||||||
|
{
|
||||||
|
"basket"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,8 @@ using Microsoft.eShopOnContainers.Services.Basket.API.Model;
|
|||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using Swashbuckle.Swagger.Model;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Basket.API.Auth.Server;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Basket.API
|
namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||||
{
|
{
|
||||||
@ -48,8 +50,11 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
|||||||
});
|
});
|
||||||
|
|
||||||
services.AddSwaggerGen();
|
services.AddSwaggerGen();
|
||||||
|
//var sch = new IdentitySecurityScheme();
|
||||||
services.ConfigureSwaggerGen(options =>
|
services.ConfigureSwaggerGen(options =>
|
||||||
{
|
{
|
||||||
|
//options.AddSecurityDefinition("IdentityServer", sch);
|
||||||
|
options.OperationFilter<AuthorizationHeaderParameterOperationFilter>();
|
||||||
options.DescribeAllEnumsAsStrings();
|
options.DescribeAllEnumsAsStrings();
|
||||||
options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info()
|
options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info()
|
||||||
{
|
{
|
||||||
@ -79,6 +84,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
|||||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||||
loggerFactory.AddDebug();
|
loggerFactory.AddDebug();
|
||||||
|
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
// Use frameworks
|
// Use frameworks
|
||||||
app.UseCors("CorsPolicy");
|
app.UseCors("CorsPolicy");
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||||
|
using Model;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -41,8 +41,8 @@ namespace eShopOnContainers.Identity.Configuration
|
|||||||
ClientName = "eShop SPA OpenId Client",
|
ClientName = "eShop SPA OpenId Client",
|
||||||
AllowedGrantTypes = GrantTypes.Implicit,
|
AllowedGrantTypes = GrantTypes.Implicit,
|
||||||
AllowAccessTokensViaBrowser = true,
|
AllowAccessTokensViaBrowser = true,
|
||||||
RedirectUris = { $"{clientsUrl["Spa"]}/callback.html" },
|
RedirectUris = { $"{clientsUrl["Spa"]}/" },
|
||||||
PostLogoutRedirectUris = { $"{clientsUrl["Spa"]}/index.html" },
|
PostLogoutRedirectUris = { $"{clientsUrl["Spa"]}/" },
|
||||||
AllowedCorsOrigins = { $"{clientsUrl["Spa"]}" },
|
AllowedCorsOrigins = { $"{clientsUrl["Spa"]}" },
|
||||||
AllowedScopes =
|
AllowedScopes =
|
||||||
{
|
{
|
||||||
@ -82,7 +82,9 @@ namespace eShopOnContainers.Identity.Configuration
|
|||||||
RedirectUris = new List<string>
|
RedirectUris = new List<string>
|
||||||
{
|
{
|
||||||
$"{clientsUrl["Mvc"]}/signin-oidc",
|
$"{clientsUrl["Mvc"]}/signin-oidc",
|
||||||
"http://104.40.62.65:5100/signin-oidc"
|
"http://104.40.62.65:5100/signin-oidc",
|
||||||
|
"http://localhost:5100/signin-oidc",
|
||||||
|
"http://13.88.8.119:5100/signin-oidc"
|
||||||
},
|
},
|
||||||
PostLogoutRedirectUris = new List<string>
|
PostLogoutRedirectUris = new List<string>
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using Api.Application.Commands;
|
using Api.Application.Commands;
|
||||||
using Api.Application.Queries;
|
using Api.Application.Queries;
|
||||||
using AspNetCore.Authorization;
|
using AspNetCore.Authorization;
|
||||||
|
using Infrastructure.Services;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Models;
|
using Models;
|
||||||
@ -11,13 +12,14 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
[Route("api/v1/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
//[Authorize]
|
[Authorize]
|
||||||
public class OrdersController : Controller
|
public class OrdersController : Controller
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
private readonly IOrderQueries _orderQueries;
|
private readonly IOrderQueries _orderQueries;
|
||||||
|
private readonly IIdentityService _identityService;
|
||||||
|
|
||||||
public OrdersController(IMediator mediator, IOrderQueries orderQueries)
|
public OrdersController(IMediator mediator, IOrderQueries orderQueries, IIdentityService identityService)
|
||||||
{
|
{
|
||||||
if (mediator == null)
|
if (mediator == null)
|
||||||
{
|
{
|
||||||
@ -29,21 +31,24 @@
|
|||||||
throw new ArgumentNullException(nameof(orderQueries));
|
throw new ArgumentNullException(nameof(orderQueries));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (identityService == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(nameof(identityService));
|
||||||
|
}
|
||||||
|
|
||||||
_mediator = mediator;
|
_mediator = mediator;
|
||||||
_orderQueries = orderQueries;
|
_orderQueries = orderQueries;
|
||||||
|
_identityService = identityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("new")]
|
[Route("new")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> AddOrder([FromBody]NewOrderRequest order)
|
public async Task<IActionResult> AddOrder([FromBody]NewOrderRequest order)
|
||||||
{
|
{
|
||||||
if (order.CardExpiration == DateTime.MinValue)
|
|
||||||
order.CardExpiration = DateTime.Now.AddYears(5);
|
|
||||||
|
|
||||||
if (order.CardTypeId == 0)
|
if (order.CardTypeId == 0)
|
||||||
order.CardTypeId = 1;
|
order.CardTypeId = 1;
|
||||||
|
|
||||||
order.Buyer = GetUserName();
|
order.Buyer = _identityService.GetUserIdentity();
|
||||||
|
|
||||||
var added = await _mediator.SendAsync(order);
|
var added = await _mediator.SendAsync(order);
|
||||||
if (added)
|
if (added)
|
||||||
@ -86,17 +91,7 @@
|
|||||||
|
|
||||||
return Ok(cardTypes);
|
return Ok(cardTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the GUID corresponding to the Id of the authenticated user.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>GUID (string)</returns>
|
|
||||||
string GetUserName()
|
|
||||||
{
|
|
||||||
return HttpContext.User.FindFirst("sub").Value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services
|
||||||
|
{
|
||||||
|
public interface IIdentityService
|
||||||
|
{
|
||||||
|
string GetUserIdentity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services
|
||||||
|
{
|
||||||
|
public class IdentityService : IIdentityService
|
||||||
|
{
|
||||||
|
private IHttpContextAccessor _context;
|
||||||
|
|
||||||
|
public IdentityService(IHttpContextAccessor context)
|
||||||
|
{
|
||||||
|
if (context == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetUserIdentity()
|
||||||
|
{
|
||||||
|
return _context.HttpContext.User.FindFirst("sub").Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API
|
||||||
{
|
{
|
||||||
|
using AspNetCore.Http;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Autofac.Extensions.DependencyInjection;
|
using Autofac.Extensions.DependencyInjection;
|
||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
using Infrastructure.AutofacModules;
|
using Infrastructure.AutofacModules;
|
||||||
using Infrastructure.Filters;
|
using Infrastructure.Filters;
|
||||||
using MediatR;
|
using Infrastructure.Services;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -15,8 +16,6 @@
|
|||||||
using Ordering.Infrastructure;
|
using Ordering.Infrastructure;
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
@ -77,7 +76,10 @@
|
|||||||
.AllowCredentials());
|
.AllowCredentials());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add application services.
|
||||||
|
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||||
services.AddSingleton<IConfiguration>(this.Configuration);
|
services.AddSingleton<IConfiguration>(this.Configuration);
|
||||||
|
services.AddTransient<IIdentityService,IdentityService>();
|
||||||
|
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
public class OrderQueries
|
public class OrderQueries
|
||||||
: IOrderQueries
|
: IOrderQueries
|
||||||
@ -97,5 +98,31 @@
|
|||||||
|
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO/CCE: try to use this method instead actual.
|
||||||
|
//private object MapOrderItems(dynamic result)
|
||||||
|
//{
|
||||||
|
// IEnumerable<dynamic> items = (result as System.Collections.IEnumerable).Cast<dynamic>();
|
||||||
|
// var order = new
|
||||||
|
// {
|
||||||
|
// ordernumber = result[0].ordernumbe,
|
||||||
|
// date = result[0].date,
|
||||||
|
// status = result[0].status,
|
||||||
|
// street = result[0].street,
|
||||||
|
// city = result[0].city,
|
||||||
|
// zipcode = result[0].zipcode,
|
||||||
|
// country = result[0].country,
|
||||||
|
// total = items.Select(r => (int)r.units * (int)r.unitprice).Sum(),
|
||||||
|
// orderItems = items.Select(r => new
|
||||||
|
// {
|
||||||
|
// productname = r.productname,
|
||||||
|
// units = r.units,
|
||||||
|
// unitprice = r.unitprice,
|
||||||
|
// pictureurl = r.pictureurl
|
||||||
|
// })
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return order;
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,6 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
// builder.AddUserSecrets();
|
// builder.AddUserSecrets();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//builder.AddJsonFile("appsettings.override.json");
|
|
||||||
//builder.AddEnvironmentVariables();
|
|
||||||
|
|
||||||
Configuration = builder.Build();
|
Configuration = builder.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +48,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||||
|
|
||||||
services.AddTransient<ICatalogService, CatalogService>();
|
services.AddTransient<ICatalogService, CatalogService>();
|
||||||
services.AddSingleton<IOrderingService, OrderingService>(); //CCE: Once services are integrated, a singleton is not needed we can left transient.
|
services.AddTransient<IOrderingService, OrderingService>();
|
||||||
services.AddTransient<IBasketService, BasketService>();
|
services.AddTransient<IBasketService, BasketService>();
|
||||||
services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>();
|
services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>();
|
||||||
}
|
}
|
||||||
@ -86,9 +83,6 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
var callBackUrl = Configuration.GetValue<string>("CallBackUrl");
|
var callBackUrl = Configuration.GetValue<string>("CallBackUrl");
|
||||||
var log = loggerFactory.CreateLogger("identity");
|
var log = loggerFactory.CreateLogger("identity");
|
||||||
|
|
||||||
log.LogDebug(identityUrl.ToString());
|
|
||||||
log.LogDebug(callBackUrl.ToString());
|
|
||||||
|
|
||||||
var oidcOptions = new OpenIdConnectOptions
|
var oidcOptions = new OpenIdConnectOptions
|
||||||
{
|
{
|
||||||
AuthenticationScheme = "oidc",
|
AuthenticationScheme = "oidc",
|
||||||
|
2
src/Web/WebMVC/wwwroot/css/site.min.css
vendored
2
src/Web/WebMVC/wwwroot/css/site.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1,3 +1,4 @@
|
|||||||
|
<div class="app">
|
||||||
<header class="navbar navbar-light navbar-static-top">
|
<header class="navbar navbar-light navbar-static-top">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -7,7 +8,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<esh-basket-status></esh-basket-status>
|
<esh-basket-status *ngIf="Authenticated"></esh-basket-status>
|
||||||
|
<esh-identity *ngIf="!Authenticated"></esh-identity>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -37,5 +39,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,23 +3,18 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: Montserrat;
|
font-family: Montserrat;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: url("../fonts/Montserrat-Regular.eot?") format("eot"),url("../fonts/Montserrat-Regular.woff") format("woff"),url("../fonts/Montserrat-Regular.ttf") format("truetype"),url("../fonts/Montserrat-Regular.svg#Montserrat") format("svg")
|
src: url("../dist/fonts/Montserrat-Regular.eot?") format("eot"),url("../dist/fonts/Montserrat-Regular.woff") format("woff"),url("../dist/fonts/Montserrat-Regular.ttf") format("truetype"),url("../dist/fonts/Montserrat-Regular.svg#Montserrat") format("svg")
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: Montserrat;
|
font-family: Montserrat;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
src: url("../fonts/Montserrat-Bold.eot?") format("eot"),url("../fonts/Montserrat-Bold.woff") format("woff"),url("../fonts/Montserrat-Bold.ttf") format("truetype"),url("../fonts/Montserrat-Bold.svg#Montserrat") format("svg")
|
src: url("../dist/fonts/Montserrat-Bold.eot?") format("eot"),url("../dist/fonts/Montserrat-Bold.woff") format("woff"),url("../dist/fonts/Montserrat-Bold.ttf") format("truetype"),url("../dist/fonts/Montserrat-Bold.svg#Montserrat") format("svg")
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
padding-top: 80px;
|
|
||||||
/*padding-bottom: 20px;*/
|
|
||||||
font-family: Montserrat,sans-serif;
|
|
||||||
min-width:480px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app {
|
.app {
|
||||||
|
font-family: Montserrat,sans-serif;
|
||||||
|
|
||||||
&-footer {
|
&-footer {
|
||||||
padding-top: 40px;
|
padding-top: 40px;
|
||||||
padding-bottom: 40px;
|
padding-bottom: 40px;
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
|
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
import { DataService } from './shared/services/data.service';
|
import { DataService } from './shared/services/data.service';
|
||||||
|
import { SecurityService } from './shared/services/security.service';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* App Component
|
* App Component
|
||||||
@ -15,14 +17,16 @@ import { DataService } from './shared/services/data.service';
|
|||||||
templateUrl: './app.component.html'
|
templateUrl: './app.component.html'
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
|
private Authenticated: boolean = false;
|
||||||
|
subscription: Subscription;
|
||||||
|
|
||||||
|
constructor(private titleService: Title, private securityService: SecurityService) {
|
||||||
constructor(private titleService: Title) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
console.log('app on init');
|
||||||
|
this.subscription = this.securityService.authenticationChallenge$.subscribe(res => this.Authenticated = res);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setTitle(newTitle: string) {
|
public setTitle(newTitle: string) {
|
||||||
|
@ -9,6 +9,7 @@ import { AppService } from './app.service';
|
|||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { SharedModule } from './shared/shared.module';
|
import { SharedModule } from './shared/shared.module';
|
||||||
import { CatalogModule } from './catalog/catalog.module';
|
import { CatalogModule } from './catalog/catalog.module';
|
||||||
|
import { OrdersModule } from './orders/orders.module';
|
||||||
import { BasketModule } from './basket/basket.module';
|
import { BasketModule } from './basket/basket.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -20,6 +21,7 @@ import { BasketModule } from './basket/basket.module';
|
|||||||
// Only module that app module loads
|
// Only module that app module loads
|
||||||
SharedModule.forRoot(),
|
SharedModule.forRoot(),
|
||||||
CatalogModule,
|
CatalogModule,
|
||||||
|
OrdersModule,
|
||||||
BasketModule
|
BasketModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -2,11 +2,13 @@ import { Routes, RouterModule } from '@angular/router';
|
|||||||
|
|
||||||
import { BasketComponent } from './basket/basket.component';
|
import { BasketComponent } from './basket/basket.component';
|
||||||
import { CatalogComponent } from './catalog/catalog.component';
|
import { CatalogComponent } from './catalog/catalog.component';
|
||||||
|
import { OrdersComponent } from './orders/orders.component';
|
||||||
|
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{ path: '', redirectTo: 'catalog', pathMatch: 'full' },
|
{ path: '', redirectTo: 'catalog', pathMatch: 'full' },
|
||||||
{ path: 'basket', component: BasketComponent },
|
{ path: 'basket', component: BasketComponent },
|
||||||
{ path: 'catalog', component: CatalogComponent }
|
{ path: 'catalog', component: CatalogComponent },
|
||||||
|
{ path: 'orders', component: OrdersComponent }
|
||||||
//Lazy async modules (angular-loader-router) and enable a router in each module.
|
//Lazy async modules (angular-loader-router) and enable a router in each module.
|
||||||
//{
|
//{
|
||||||
// path: 'basket', loadChildren: '/basket/basket.module' });
|
// path: 'basket', loadChildren: '/basket/basket.module' });
|
||||||
|
@ -19,10 +19,15 @@ export class BasketStatusComponent implements OnInit {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.subscription = this.basketEvents.addItemToBasket$.subscribe(
|
this.subscription = this.basketEvents.addItemToBasket$.subscribe(
|
||||||
item => {
|
item => {
|
||||||
|
console.log('element received in basket');
|
||||||
console.log(item);
|
console.log(item);
|
||||||
this.service.setBasket(item);
|
this.service.setBasket(item).subscribe(res => {
|
||||||
|
console.log(res);
|
||||||
this.service.getBasket().subscribe(basket => {
|
this.service.getBasket().subscribe(basket => {
|
||||||
this.badge = basket.items.length;
|
this.badge = basket.items.length;
|
||||||
|
console.log('response from basket api');
|
||||||
|
console.log(basket.items.length);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { IBasket } from '../shared/models/basket.model';
|
|||||||
import { IBasketItem } from '../shared/models/basketItem.model';
|
import { IBasketItem } from '../shared/models/basketItem.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'esh-basket',
|
selector: 'esh-basket .esh-basket',
|
||||||
styleUrls: ['./basket.component.scss'],
|
styleUrls: ['./basket.component.scss'],
|
||||||
templateUrl: './basket.component.html'
|
templateUrl: './basket.component.html'
|
||||||
})
|
})
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
//import { Routes, RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
//import { BasketComponent } from './basket.component';
|
|
||||||
|
|
||||||
//const routes: Routes = [
|
|
||||||
// { path: '', component: BasketComponent }
|
|
||||||
//];
|
|
||||||
|
|
||||||
//export const routing = RouterModule.forChild(routes);
|
|
@ -1,7 +1,8 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Response } from '@angular/http';
|
import { Response, Headers } from '@angular/http';
|
||||||
|
|
||||||
import { DataService } from '../shared/services/data.service';
|
import { DataService } from '../shared/services/data.service';
|
||||||
|
import { SecurityService } from '../shared/services/security.service';
|
||||||
import { IBasket } from '../shared/models/basket.model';
|
import { IBasket } from '../shared/models/basket.model';
|
||||||
import { IBasketItem } from '../shared/models/basketItem.model';
|
import { IBasketItem } from '../shared/models/basketItem.model';
|
||||||
|
|
||||||
@ -19,13 +20,16 @@ export class BasketService {
|
|||||||
items: []
|
items: []
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(private service: DataService) {
|
constructor(private service: DataService, private authService: SecurityService) {
|
||||||
this.basket.items = [];
|
this.basket.items = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
setBasket(item) {
|
setBasket(item): Observable<boolean> {
|
||||||
|
console.log('set basket');
|
||||||
this.basket.items.push(item);
|
this.basket.items.push(item);
|
||||||
this.service.post(this.basket.buyerId, this.basket.items);
|
return this.service.post(this.basketUrl + '/', this.basket).map((response: Response) => {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getBasket(): Observable<IBasket> {
|
getBasket(): Observable<IBasket> {
|
||||||
|
@ -8,7 +8,7 @@ import { IPager } from '../shared/models/pager.model';
|
|||||||
import { BasketWrapperService} from '../shared/services/basket.wrapper.service';
|
import { BasketWrapperService} from '../shared/services/basket.wrapper.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'esh-catalog',
|
selector: 'esh-catalog .catalog',
|
||||||
styleUrls: ['./catalog.component.scss'],
|
styleUrls: ['./catalog.component.scss'],
|
||||||
templateUrl: './catalog.component.html'
|
templateUrl: './catalog.component.html'
|
||||||
})
|
})
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
//import { Routes, RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
//import { CatalogComponent } from './catalog.component';
|
|
||||||
|
|
||||||
//const routes: Routes = [
|
|
||||||
// { path: '', component: CatalogComponent }
|
|
||||||
//];
|
|
||||||
|
|
||||||
//export const routing = RouterModule.forChild(routes);
|
|
@ -0,0 +1,43 @@
|
|||||||
|
<div class="esh-orders-header">
|
||||||
|
<ul class="container">
|
||||||
|
<li class="esh-orders-header-back" routerLink="/catalog">Back to list</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="container esh-orders-container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<section>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="esh-orders-order-column">
|
||||||
|
ORDER NUMBER
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
DATE
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
TOTAL
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
STATUS
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr *ngFor="let order of orders">
|
||||||
|
<td class="esh-orders-order-column">{{order.ordernumber}}</td>
|
||||||
|
<td class="esh-orders-order-column">{{order.date | date:'short'}}</td>
|
||||||
|
<td class="esh-orders-order-column">$ {{order.total}}</td>
|
||||||
|
<td class="esh-orders-order-column">{{order.status}}</td>
|
||||||
|
<td class="esh-orders-order-column">
|
||||||
|
<a class="esh-orders-order-link" href="#">Detail</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,85 @@
|
|||||||
|
@import '../_variables.scss';
|
||||||
|
|
||||||
|
.esh-orders {
|
||||||
|
min-height: 80vh;
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
background-color: #00A69C;
|
||||||
|
height: 63px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
display: inline;
|
||||||
|
opacity: 0.5;
|
||||||
|
margin-top: 25px;
|
||||||
|
margin-left: 10px;
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
li a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-back {
|
||||||
|
float: left !important;
|
||||||
|
margin-top: 20px !important;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
li a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
min-height: 70vh;
|
||||||
|
padding-top: 40px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
min-width: 992px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-order-column {
|
||||||
|
max-width: 120px;
|
||||||
|
vertical-align: middle !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-order-link {
|
||||||
|
color: #83d01b;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-order-image {
|
||||||
|
max-width: 210px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-total-value {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #00a69c;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-total-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #404040;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-totals {
|
||||||
|
border-bottom:none!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td {
|
||||||
|
border-top: solid 1px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table thead th {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { OrdersService } from './orders.service';
|
||||||
|
import { IOrder } from '../shared/models/order.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'esh-orders .orders',
|
||||||
|
styleUrls: ['./orders.component.scss'],
|
||||||
|
templateUrl: './orders.component.html'
|
||||||
|
})
|
||||||
|
export class OrdersComponent implements OnInit {
|
||||||
|
orders: IOrder[];
|
||||||
|
|
||||||
|
constructor(private service: OrdersService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.getOrders();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getOrders() {
|
||||||
|
this.service.getOrders().subscribe(orders => {
|
||||||
|
this.orders = orders;
|
||||||
|
console.log('orders items retrieved: ' + orders.length);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
import { SharedModule } from '../shared/shared.module';
|
||||||
|
import { OrdersComponent } from './orders.component';
|
||||||
|
import { OrdersService } from './orders.service';
|
||||||
|
import { Pager } from '../shared/components/pager/pager';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [BrowserModule, SharedModule],
|
||||||
|
declarations: [OrdersComponent],
|
||||||
|
providers: [OrdersService]
|
||||||
|
})
|
||||||
|
export class OrdersModule { }
|
@ -0,0 +1,27 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Response } from '@angular/http';
|
||||||
|
|
||||||
|
import { DataService } from '../shared/services/data.service';
|
||||||
|
import { IOrder } from '../shared/models/order.model';
|
||||||
|
|
||||||
|
import 'rxjs/Rx';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import 'rxjs/add/observable/throw';
|
||||||
|
import { Observer } from 'rxjs/Observer';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class OrdersService {
|
||||||
|
private ordersUrl: string = 'http://eshopcontainers:5102/api/v1/orders';
|
||||||
|
|
||||||
|
constructor(private service: DataService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
getOrders(): Observable<any> {
|
||||||
|
var url = this.ordersUrl;
|
||||||
|
|
||||||
|
return this.service.get(url).map((response: Response) => {
|
||||||
|
return response.json();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
<button *ngIf="!authenticated" (click)="login()">Login</button>
|
||||||
|
<div *ngIf="authenticated">userName: {{userName}}</div>
|
@ -0,0 +1,3 @@
|
|||||||
|
.identity {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
import { Component, OnInit, OnChanges, Output, Input, EventEmitter } from '@angular/core';
|
||||||
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
|
import { IIdentity } from '../../models/identity.model';
|
||||||
|
import { SecurityService } from '../../services/security.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'esh-identity',
|
||||||
|
templateUrl: './identity.html',
|
||||||
|
styleUrls: ['./identity.scss']
|
||||||
|
})
|
||||||
|
export class Identity implements OnInit {
|
||||||
|
private authenticated: boolean = false;
|
||||||
|
private subscription: Subscription;
|
||||||
|
private userName: string = "";
|
||||||
|
|
||||||
|
constructor(private service: SecurityService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.subscription = this.service.authenticationChallenge$.subscribe(res =>
|
||||||
|
{
|
||||||
|
//console.log(res);
|
||||||
|
//console.log(this.service.UserData);
|
||||||
|
//console.log(this.service);
|
||||||
|
this.authenticated = res;
|
||||||
|
this.userName = this.service.UserData.email;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.location.hash) {
|
||||||
|
this.service.AuthorizedCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
login() {
|
||||||
|
this.service.Authorize();
|
||||||
|
}
|
||||||
|
|
||||||
|
logout() {
|
||||||
|
this.service.Logoff();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export interface IIdentity {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
export interface IOrder {
|
||||||
|
ordernumber: number,
|
||||||
|
date: Date,
|
||||||
|
status: string,
|
||||||
|
total: number
|
||||||
|
}
|
@ -8,15 +8,19 @@ import { Observer } from 'rxjs/Observer';
|
|||||||
import 'rxjs/add/operator/map';
|
import 'rxjs/add/operator/map';
|
||||||
import 'rxjs/add/operator/catch';
|
import 'rxjs/add/operator/catch';
|
||||||
|
|
||||||
|
import { SecurityService } from './security.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DataService {
|
export class DataService {
|
||||||
|
constructor(private http: Http, private securityService: SecurityService) { }
|
||||||
constructor(private http: Http) { }
|
|
||||||
|
|
||||||
get(url: string, params?: any): Observable<Response> {
|
get(url: string, params?: any): Observable<Response> {
|
||||||
let options: RequestOptionsArgs = {};
|
let options: RequestOptionsArgs = {};
|
||||||
|
|
||||||
|
if (this.securityService) {
|
||||||
options.headers = new Headers();
|
options.headers = new Headers();
|
||||||
this.addCors(options);
|
options.headers.append("Authorization", "Bearer " + this.securityService.GetToken());
|
||||||
|
}
|
||||||
|
|
||||||
return this.http.get(url, options).map(
|
return this.http.get(url, options).map(
|
||||||
(res: Response) => {
|
(res: Response) => {
|
||||||
@ -24,13 +28,18 @@ export class DataService {
|
|||||||
}).catch(this.handleError);
|
}).catch(this.handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
post(url: string, data: any, params?: any) {
|
post(url: string, data: any, params?: any): Observable<Response> {
|
||||||
return this.http.post(url, data, params);
|
let options: RequestOptionsArgs = {};
|
||||||
|
|
||||||
|
if (this.securityService) {
|
||||||
|
options.headers = new Headers();
|
||||||
|
options.headers.append("Authorization", "Bearer " + this.securityService.GetToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
private addCors(options: RequestOptionsArgs): RequestOptionsArgs {
|
return this.http.post(url, data, options).map(
|
||||||
options.headers.append('Access-Control-Allow-Origin', '*');
|
(res: Response) => {
|
||||||
return options;
|
return res;
|
||||||
|
}).catch(this.handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleError(error: any) {
|
private handleError(error: any) {
|
||||||
|
@ -0,0 +1,237 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Http, Response, Headers } from '@angular/http';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
//import { Configuration } from '../app.constants';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SecurityService {
|
||||||
|
|
||||||
|
private actionUrl: string;
|
||||||
|
private headers: Headers;
|
||||||
|
private storage: any;
|
||||||
|
private authenticationSource = new Subject<boolean>();
|
||||||
|
authenticationChallenge$ = this.authenticationSource.asObservable();
|
||||||
|
|
||||||
|
constructor(private _http: Http, private _router: Router) {
|
||||||
|
this.headers = new Headers();
|
||||||
|
this.headers.append('Content-Type', 'application/json');
|
||||||
|
this.headers.append('Accept', 'application/json');
|
||||||
|
this.storage = sessionStorage; //localStorage;
|
||||||
|
|
||||||
|
if (this.retrieve("IsAuthorized") !== "") {
|
||||||
|
this.IsAuthorized = this.retrieve("IsAuthorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IsAuthorized: boolean;
|
||||||
|
|
||||||
|
public GetToken(): any {
|
||||||
|
return this.retrieve("authorizationData");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResetAuthorizationData() {
|
||||||
|
this.store("authorizationData", "");
|
||||||
|
this.store("authorizationDataIdToken", "");
|
||||||
|
|
||||||
|
this.IsAuthorized = false;
|
||||||
|
this.store("IsAuthorized", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserData: any;
|
||||||
|
public SetAuthorizationData(token: any, id_token:any) {
|
||||||
|
if (this.retrieve("authorizationData") !== "") {
|
||||||
|
this.store("authorizationData", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.store("authorizationData", token);
|
||||||
|
this.store("authorizationDataIdToken", id_token);
|
||||||
|
this.IsAuthorized = true;
|
||||||
|
this.store("IsAuthorized", true);
|
||||||
|
|
||||||
|
this.getUserData()
|
||||||
|
.subscribe(data => {
|
||||||
|
this.UserData = data;
|
||||||
|
//emit observable
|
||||||
|
this.authenticationSource.next(true);
|
||||||
|
},
|
||||||
|
error => this.HandleError(error),
|
||||||
|
() => {
|
||||||
|
console.log(this.UserData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Authorize() {
|
||||||
|
this.ResetAuthorizationData();
|
||||||
|
|
||||||
|
var authorizationUrl = 'http://localhost:5105/connect/authorize';
|
||||||
|
var client_id = 'js';
|
||||||
|
var redirect_uri = 'http://localhost:5104/';
|
||||||
|
var response_type = "id_token token";
|
||||||
|
var scope = "openid profile orders basket";
|
||||||
|
var nonce = "N" + Math.random() + "" + Date.now();
|
||||||
|
var state = Date.now() + "" + Math.random();
|
||||||
|
|
||||||
|
this.store("authStateControl", state);
|
||||||
|
this.store("authNonce", nonce);
|
||||||
|
|
||||||
|
var url =
|
||||||
|
authorizationUrl + "?" +
|
||||||
|
"response_type=" + encodeURI(response_type) + "&" +
|
||||||
|
"client_id=" + encodeURI(client_id) + "&" +
|
||||||
|
"redirect_uri=" + encodeURI(redirect_uri) + "&" +
|
||||||
|
"scope=" + encodeURI(scope) + "&" +
|
||||||
|
"nonce=" + encodeURI(nonce) + "&" +
|
||||||
|
"state=" + encodeURI(state);
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthorizedCallback() {
|
||||||
|
this.ResetAuthorizationData();
|
||||||
|
|
||||||
|
var hash = window.location.hash.substr(1);
|
||||||
|
|
||||||
|
var result: any = hash.split('&').reduce(function (result : any, item: string) {
|
||||||
|
var parts = item.split('=');
|
||||||
|
result[parts[0]] = parts[1];
|
||||||
|
return result;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
|
var token = "";
|
||||||
|
var id_token = "";
|
||||||
|
var authResponseIsValid = false;
|
||||||
|
if (!result.error) {
|
||||||
|
|
||||||
|
if (result.state !== this.retrieve("authStateControl")) {
|
||||||
|
console.log("AuthorizedCallback incorrect state");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
token = result.access_token;
|
||||||
|
id_token = result.id_token
|
||||||
|
|
||||||
|
var dataIdToken: any = this.getDataFromToken(id_token);
|
||||||
|
console.log(dataIdToken);
|
||||||
|
|
||||||
|
// validate nonce
|
||||||
|
if (dataIdToken.nonce !== this.retrieve("authNonce")) {
|
||||||
|
console.log("AuthorizedCallback incorrect nonce");
|
||||||
|
} else {
|
||||||
|
this.store("authNonce", "");
|
||||||
|
this.store("authStateControl", "");
|
||||||
|
|
||||||
|
authResponseIsValid = true;
|
||||||
|
console.log("AuthorizedCallback state and nonce validated, returning access token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authResponseIsValid) {
|
||||||
|
this.SetAuthorizationData(token, id_token);
|
||||||
|
console.log(this.retrieve("authorizationData"));
|
||||||
|
|
||||||
|
// router navigate to DataEventRecordsList
|
||||||
|
this._router.navigate(['/dataeventrecords/list']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.ResetAuthorizationData();
|
||||||
|
this._router.navigate(['/Unauthorized']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Logoff() {
|
||||||
|
// /connect/endsession?id_token_hint=...&post_logout_redirect_uri=https://myapp.com
|
||||||
|
console.log("BEGIN Authorize, no auth data");
|
||||||
|
|
||||||
|
var authorizationUrl = 'http://localhost:5105/connect/endsession';
|
||||||
|
console.log(this.retrieve("authorizationDataIdToken"));
|
||||||
|
var id_token_hint = this.retrieve("authorizationDataIdToken");
|
||||||
|
var post_logout_redirect_uri = 'http://localhost:5104/';
|
||||||
|
|
||||||
|
var url =
|
||||||
|
authorizationUrl + "?" +
|
||||||
|
"id_token_hint=" + encodeURI(id_token_hint) + "&" +
|
||||||
|
"post_logout_redirect_uri=" + encodeURI(post_logout_redirect_uri);
|
||||||
|
|
||||||
|
this.ResetAuthorizationData();
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HandleError(error: any) {
|
||||||
|
console.log(error);
|
||||||
|
if (error.status == 403) {
|
||||||
|
this._router.navigate(['/Forbidden'])
|
||||||
|
}
|
||||||
|
else if (error.status == 401) {
|
||||||
|
this.ResetAuthorizationData();
|
||||||
|
this._router.navigate(['/Unauthorized'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private urlBase64Decode(str: string) {
|
||||||
|
var output = str.replace('-', '+').replace('_', '/');
|
||||||
|
switch (output.length % 4) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
output += '==';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
output += '=';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw 'Illegal base64url string!';
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.atob(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getDataFromToken(token: any) {
|
||||||
|
var data = {};
|
||||||
|
if (typeof token !== 'undefined') {
|
||||||
|
var encoded = token.split('.')[1];
|
||||||
|
data = JSON.parse(this.urlBase64Decode(encoded));
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private retrieve(key: string): any {
|
||||||
|
var item = this.storage.getItem(key);
|
||||||
|
|
||||||
|
if (item && item !== 'undefined') {
|
||||||
|
return JSON.parse(this.storage.getItem(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private store(key: string, value: any) {
|
||||||
|
this.storage.setItem(key, JSON.stringify(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private getUserData = (): Observable<string[]> => {
|
||||||
|
this.setHeaders();
|
||||||
|
return this._http.get('http://localhost:5105/connect/userinfo', {
|
||||||
|
headers: this.headers,
|
||||||
|
body: ''
|
||||||
|
}).map(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
private setHeaders() {
|
||||||
|
this.headers = new Headers();
|
||||||
|
this.headers.append('Content-Type', 'application/json');
|
||||||
|
this.headers.append('Accept', 'application/json');
|
||||||
|
|
||||||
|
var token = this.GetToken();
|
||||||
|
|
||||||
|
if (token !== "") {
|
||||||
|
this.headers.append('Authorization', 'Bearer ' + token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,9 +17,11 @@ import { DataService } from './services/data.service';
|
|||||||
import { UtilityService } from './services/utility.service';
|
import { UtilityService } from './services/utility.service';
|
||||||
import { UppercasePipe } from './pipes/uppercase.pipe';
|
import { UppercasePipe } from './pipes/uppercase.pipe';
|
||||||
import { BasketWrapperService} from './services/basket.wrapper.service';
|
import { BasketWrapperService} from './services/basket.wrapper.service';
|
||||||
|
import { SecurityService } from './services/security.service';
|
||||||
|
|
||||||
//Components:
|
//Components:
|
||||||
import {Pager } from './components/pager/pager';
|
import {Pager } from './components/pager/pager';
|
||||||
|
import {Identity } from './components/identity/identity';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -39,7 +41,8 @@ import {Pager } from './components/pager/pager';
|
|||||||
ErrorSummaryComponent,
|
ErrorSummaryComponent,
|
||||||
PageHeadingComponent,
|
PageHeadingComponent,
|
||||||
UppercasePipe,
|
UppercasePipe,
|
||||||
Pager
|
Pager,
|
||||||
|
Identity
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
// Modules
|
// Modules
|
||||||
@ -57,9 +60,9 @@ import {Pager } from './components/pager/pager';
|
|||||||
//HeaderComponent,
|
//HeaderComponent,
|
||||||
PageHeadingComponent,
|
PageHeadingComponent,
|
||||||
UppercasePipe,
|
UppercasePipe,
|
||||||
Pager
|
Pager,
|
||||||
|
Identity
|
||||||
]
|
]
|
||||||
|
|
||||||
})
|
})
|
||||||
export class SharedModule {
|
export class SharedModule {
|
||||||
static forRoot(): ModuleWithProviders {
|
static forRoot(): ModuleWithProviders {
|
||||||
@ -70,7 +73,8 @@ export class SharedModule {
|
|||||||
DataService,
|
DataService,
|
||||||
FormControlService,
|
FormControlService,
|
||||||
UtilityService,
|
UtilityService,
|
||||||
BasketWrapperService
|
BasketWrapperService,
|
||||||
|
SecurityService
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ namespace eShopConContainers.WebSPA
|
|||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseConfiguration(config)
|
.UseConfiguration(config)
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseUrls("http://localhost:5104/")
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
//.UseUrls("http://localhost:5104/")
|
|
||||||
.UseStartup<Startup>()
|
.UseStartup<Startup>()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ var extractCSS = new ExtractTextPlugin('styles.css');
|
|||||||
var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
|
var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
|
||||||
var devConfig = require('./webpack.config.dev');
|
var devConfig = require('./webpack.config.dev');
|
||||||
var prodConfig = require('./webpack.config.prod');
|
var prodConfig = require('./webpack.config.prod');
|
||||||
|
var CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
var isDevelopment = process.env.ASPNETCORE_ENVIRONMENT === 'Development';
|
var isDevelopment = process.env.ASPNETCORE_ENVIRONMENT === 'Development';
|
||||||
|
|
||||||
console.log("==========Dev Mode = " + isDevelopment + " ============" )
|
console.log("==========Dev Mode = " + isDevelopment + " ============" )
|
||||||
@ -74,6 +75,9 @@ module.exports = merge({
|
|||||||
'process.env': {
|
'process.env': {
|
||||||
'ENV': JSON.stringify(process.env.ASPNETCORE_ENVIRONMENT)
|
'ENV': JSON.stringify(process.env.ASPNETCORE_ENVIRONMENT)
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
new CopyWebpackPlugin([
|
||||||
|
{ from: 'Client/fonts', to: 'fonts' }
|
||||||
|
])
|
||||||
]
|
]
|
||||||
}, isDevelopment ? devConfig : prodConfig);
|
}, isDevelopment ? devConfig : prodConfig);
|
||||||
|
@ -71,11 +71,11 @@
|
|||||||
"@types/source-map": "0.1.28",
|
"@types/source-map": "0.1.28",
|
||||||
"@types/uglify-js": "2.6.28",
|
"@types/uglify-js": "2.6.28",
|
||||||
"@types/webpack": "1.12.35",
|
"@types/webpack": "1.12.35",
|
||||||
"angular2-template-loader": "0.6.0",
|
|
||||||
"angular2-router-loader": "0.3.4",
|
"angular2-router-loader": "0.3.4",
|
||||||
|
"angular2-template-loader": "0.6.0",
|
||||||
"awesome-typescript-loader": "2.2.4",
|
"awesome-typescript-loader": "2.2.4",
|
||||||
"codelyzer": "1.0.0-beta.3",
|
"codelyzer": "1.0.0-beta.3",
|
||||||
"copy-webpack-plugin": "^4.0.0",
|
"copy-webpack-plugin": "^4.0.1",
|
||||||
"css": "2.2.1",
|
"css": "2.2.1",
|
||||||
"css-loader": "0.25.0",
|
"css-loader": "0.25.0",
|
||||||
"es6-promise": "3.2.1",
|
"es6-promise": "3.2.1",
|
||||||
|
@ -39,8 +39,8 @@
|
|||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"Microsoft.DotNet.Watcher.Tools": {
|
"Microsoft.DotNet.Watcher.Tools": {
|
||||||
"version": "1.0.0-*",
|
"version": "1.0.0-preview2-final",
|
||||||
"imports": "portable-net451+win8"
|
"imports": "portable-net451+win8+dnxcore50"
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.Razor.Tools": {
|
"Microsoft.AspNetCore.Razor.Tools": {
|
||||||
"version": "1.0.0-preview2-final",
|
"version": "1.0.0-preview2-final",
|
||||||
|
34
test/Services/UnitTest/Catalog/CatalogControllertest.cs
Normal file
34
test/Services/UnitTest/Catalog/CatalogControllertest.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Catalog.API.Controllers;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
|
||||||
|
using Moq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace UnitTest.Catalog
|
||||||
|
{
|
||||||
|
public class CatalogControllerTest
|
||||||
|
{
|
||||||
|
private readonly Mock<CatalogContext> _mockContext;
|
||||||
|
private readonly Mock<IQueryable<CatalogItem>> _mockItems;
|
||||||
|
public CatalogControllerTest()
|
||||||
|
{
|
||||||
|
_mockContext = new Mock<CatalogContext>();
|
||||||
|
_mockItems = new Mock<IQueryable<CatalogItem>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Items_ReturnsOKObject_WhenItemsFound()
|
||||||
|
{
|
||||||
|
//CCE: TODO
|
||||||
|
Assert.True(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
using MediatR;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.Domain;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
|
||||||
|
using Moq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace UnitTest.Ordering.Application
|
||||||
|
{
|
||||||
|
public class NewOrderRequestHandlerTest
|
||||||
|
{
|
||||||
|
private readonly Mock<IBuyerRepository> _buyerRepositoryMock;
|
||||||
|
private readonly Mock<IOrderRepository> _orderRepositoryMock;
|
||||||
|
|
||||||
|
public NewOrderRequestHandlerTest()
|
||||||
|
{
|
||||||
|
//Mocks;
|
||||||
|
_buyerRepositoryMock = new Mock<IBuyerRepository>();
|
||||||
|
_orderRepositoryMock = new Mock<IOrderRepository>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Handle_ReturnsTrue_WhenOrderIsPersistedSuccesfully()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().Buyer))
|
||||||
|
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
|
||||||
|
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
|
||||||
|
.Returns(Task.FromResult(1));
|
||||||
|
|
||||||
|
_orderRepositoryMock.Setup(or => or.Add(FakeOrder())).Returns(FakeOrder());
|
||||||
|
_orderRepositoryMock.Setup(or => or.UnitOfWork.SaveChangesAsync(default(CancellationToken))).Returns(Task.FromResult(1));
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var handler = new NewOrderRequestHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object);
|
||||||
|
var result = await handler.Handle(FakeOrderRequestWithBuyer());
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Assert.True(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Handle_ReturnsFalse_WhenOrderIsNotPersisted()
|
||||||
|
{
|
||||||
|
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().Buyer))
|
||||||
|
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
|
||||||
|
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
|
||||||
|
.Returns(Task.FromResult(1));
|
||||||
|
|
||||||
|
_orderRepositoryMock.Setup(or => or.Add(FakeOrder())).Returns(FakeOrder());
|
||||||
|
_orderRepositoryMock.Setup(or => or.UnitOfWork.SaveChangesAsync(default(CancellationToken))).Returns(Task.FromResult(0));
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var handler = new NewOrderRequestHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object);
|
||||||
|
var result = await handler.Handle(FakeOrderRequestWithBuyer());
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Assert.False(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Buyer FakeBuyer()
|
||||||
|
{
|
||||||
|
return new Buyer(Guid.NewGuid().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Order FakeOrder()
|
||||||
|
{
|
||||||
|
return new Order(1, 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private NewOrderRequest FakeOrderRequestWithBuyer()
|
||||||
|
{
|
||||||
|
return new NewOrderRequest
|
||||||
|
{
|
||||||
|
Buyer = "1234",
|
||||||
|
CardNumber = "1234",
|
||||||
|
CardExpiration = DateTime.Now.AddYears(1),
|
||||||
|
CardSecurityNumber = "123",
|
||||||
|
CardHolderName = "XXX"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,152 @@
|
|||||||
|
using System;
|
||||||
|
using Xunit;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Moq;
|
||||||
|
using MediatR;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.API.Controllers;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace UnitTest.Ordering.Controllers
|
||||||
|
{
|
||||||
|
public class OrderControllerTest
|
||||||
|
{
|
||||||
|
private readonly Mock<IMediator> _mediatorMock;
|
||||||
|
private readonly Mock<IIdentityService> _identityMock;
|
||||||
|
private readonly Mock<IOrderQueries> _queriesMock;
|
||||||
|
|
||||||
|
public OrderControllerTest()
|
||||||
|
{
|
||||||
|
//Mocks;
|
||||||
|
_mediatorMock = new Mock<IMediator>();
|
||||||
|
_identityMock = new Mock<IIdentityService>();
|
||||||
|
_queriesMock = new Mock<IOrderQueries>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AddOrder_ReturnsBadRequestResult_WhenPersitenceOperationFails()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var orderRequest = new object() as IAsyncRequest<bool>;
|
||||||
|
|
||||||
|
_mediatorMock.Setup(mediator => mediator.SendAsync(OrderFakeNotExpired()))
|
||||||
|
.Returns(Task.FromResult(false));
|
||||||
|
|
||||||
|
_identityMock.Setup(identity => identity.GetUserIdentity())
|
||||||
|
.Returns(Guid.NewGuid().ToString());
|
||||||
|
|
||||||
|
var controller = new OrdersController(_mediatorMock.Object, _queriesMock.Object, _identityMock.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var badRequestResult = await controller.AddOrder(OrderFakeNotExpired());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<BadRequestResult>(badRequestResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AddOrder_ReturnsOK_WhenPersistenceOperationSucceed()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_mediatorMock.Setup(mediator => mediator.SendAsync(OrderFakeNotExpired()))
|
||||||
|
.Returns(Task.FromResult(true));
|
||||||
|
|
||||||
|
_identityMock.Setup(identity => identity.GetUserIdentity())
|
||||||
|
.Returns(Guid.NewGuid().ToString());
|
||||||
|
|
||||||
|
var controller = new OrdersController(_mediatorMock.Object, _queriesMock.Object, _identityMock.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var badRequestResult = await controller.AddOrder(OrderFakeNotExpired());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<BadRequestResult>(badRequestResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetOrder_ReturnsNotFound_WhenItemNotFound()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_queriesMock.Setup(queries => queries.GetOrder(1))
|
||||||
|
.Throws(new KeyNotFoundException());
|
||||||
|
|
||||||
|
var controller = new OrdersController(_mediatorMock.Object, _queriesMock.Object, _identityMock.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var notFoundResult = await controller.GetOrder(1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<NotFoundResult>(notFoundResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetOrder_ReturnsOkObjecResult_WheItemFound()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_queriesMock.Setup(queries => queries.GetOrder(1))
|
||||||
|
.Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
var controller = new OrdersController(_mediatorMock.Object, _queriesMock.Object, _identityMock.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var OkObjectResult = await controller.GetOrder(1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<OkObjectResult>(OkObjectResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetOrders_ReturnsOkObjectResult()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_queriesMock.Setup(queries => queries.GetOrders())
|
||||||
|
.Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
var controller = new OrdersController(_mediatorMock.Object, _queriesMock.Object, _identityMock.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var OkObjectResult = await controller.GetOrders();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<OkObjectResult>(OkObjectResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetCardTypes()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_queriesMock.Setup(queries => queries.GetCardTypes())
|
||||||
|
.Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
var controller = new OrdersController(_mediatorMock.Object, _queriesMock.Object, _identityMock.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var OkObjectResult = await controller.GetCardTypes();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<OkObjectResult>(OkObjectResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fakes
|
||||||
|
private NewOrderRequest OrderFakeNotExpired()
|
||||||
|
{
|
||||||
|
return new NewOrderRequest()
|
||||||
|
{
|
||||||
|
CardTypeId = 1,
|
||||||
|
CardExpiration = DateTime.Now.AddYears(1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private NewOrderRequest OrderFakeExpired()
|
||||||
|
{
|
||||||
|
return new NewOrderRequest()
|
||||||
|
{
|
||||||
|
CardTypeId = 1,
|
||||||
|
CardExpiration = DateTime.Now.AddYears(-1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
test/Services/UnitTest/Properties/AssemblyInfo.cs
Normal file
19
test/Services/UnitTest/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("UnitTest")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("7796f5d8-31fc-45a4-b673-19de5ba194cf")]
|
22
test/Services/UnitTest/UnitTest.xproj
Normal file
22
test/Services/UnitTest/UnitTest.xproj
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>7796f5d8-31fc-45a4-b673-19de5ba194cf</ProjectGuid>
|
||||||
|
<RootNamespace>UnitTest</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
24
test/Services/UnitTest/project.json
Normal file
24
test/Services/UnitTest/project.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"MediatR": "2.1.0",
|
||||||
|
"Moq": "4.6.38-alpha",
|
||||||
|
"Microsoft.NETCore.App": "1.1.0",
|
||||||
|
"xunit": "2.2.0-beta4-build3444",
|
||||||
|
"Ordering.API": "1.0.0-*",
|
||||||
|
"Catalog.API": "1.0.0-*",
|
||||||
|
"Microsoft.AspNetCore.TestHost": "1.1.0",
|
||||||
|
"dotnet-test-xunit": "2.2.0-preview2-build1029"
|
||||||
|
},
|
||||||
|
"testRunner": "xunit",
|
||||||
|
"runtimes": {
|
||||||
|
"win10-x64": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"netcoreapp1.0": {
|
||||||
|
"dependencies": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Xunit;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Moq;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace UnitTests
|
||||||
|
{
|
||||||
|
public class OrderControllerTest
|
||||||
|
{
|
||||||
|
private readonly Mock<IMediator> _mock;
|
||||||
|
|
||||||
|
public OrderControllerTest()
|
||||||
|
{
|
||||||
|
//config mock;
|
||||||
|
_mock = new Mock<IMediator>();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AddOrder_ReturnsBadRequestResult_WhenPersitenceOperationFails()
|
||||||
|
{
|
||||||
|
//Add order:
|
||||||
|
var orderRequest = new object() as IAsyncRequest<bool>;
|
||||||
|
_mock.Setup(mediator => mediator.SendAsync(orderRequest))
|
||||||
|
.Returns(Task.FromResult(false));
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
var controller = new OrdersController(mockRepo.Object);
|
||||||
|
controller.ModelState.AddModelError("SessionName", "Required");
|
||||||
|
var newSession = new HomeController.NewSessionModel();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await controller.Index(newSession);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var badRequestResult = Assert.IsType<BadRequestObjectResult>(result);
|
||||||
|
Assert.IsType<SerializableError>(badRequestResult.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Implement Fake method for mock.
|
||||||
|
private MediatorMockForAddOrder()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("UnitTests")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("UnitTests")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("ecbb8dc1-22ea-42d2-a45a-4ae800c73356")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
117
test/Services/UnitTests__/UnitTests/UnitTests.csproj
Normal file
117
test/Services/UnitTests__/UnitTests/UnitTests.csproj
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{ECBB8DC1-22EA-42D2-A45A-4AE800C73356}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>UnitTests</RootNamespace>
|
||||||
|
<AssemblyName>UnitTests</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||||
|
<IsCodedUITest>False</IsCodedUITest>
|
||||||
|
<TestProjectType>UnitTest</TestProjectType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="MediatR, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\MediatR.2.1.0\lib\net45\MediatR.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Moq, Version=4.6.38.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\Moq.4.6.38-alpha\lib\net45\Moq.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="xunit.assert, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\xunit.assert.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.assert.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="xunit.core, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\xunit.extensibility.core.2.2.0-beta4-build3444\lib\net45\xunit.core.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="xunit.execution.desktop, Version=2.2.0.3444, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\xunit.extensibility.execution.2.2.0-beta4-build3444\lib\net45\xunit.execution.desktop.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Choose>
|
||||||
|
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||||
|
</ItemGroup>
|
||||||
|
</When>
|
||||||
|
<Otherwise>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Otherwise>
|
||||||
|
</Choose>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Ordering\OrderControllerTest.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Catalog\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Choose>
|
||||||
|
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
</When>
|
||||||
|
</Choose>
|
||||||
|
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
12
test/Services/UnitTests__/UnitTests/packages.config
Normal file
12
test/Services/UnitTests__/UnitTests/packages.config
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Castle.Core" version="3.3.3" targetFramework="net452" />
|
||||||
|
<package id="MediatR" version="2.1.0" targetFramework="net452" />
|
||||||
|
<package id="Moq" version="4.6.38-alpha" targetFramework="net452" />
|
||||||
|
<package id="xunit" version="2.2.0-beta4-build3444" targetFramework="net452" />
|
||||||
|
<package id="xunit.abstractions" version="2.0.1" targetFramework="net452" />
|
||||||
|
<package id="xunit.assert" version="2.2.0-beta4-build3444" targetFramework="net452" />
|
||||||
|
<package id="xunit.core" version="2.2.0-beta4-build3444" targetFramework="net452" />
|
||||||
|
<package id="xunit.extensibility.core" version="2.2.0-beta4-build3444" targetFramework="net452" />
|
||||||
|
<package id="xunit.extensibility.execution" version="2.2.0-beta4-build3444" targetFramework="net452" />
|
||||||
|
</packages>
|
Loading…
x
Reference in New Issue
Block a user