Added MVCApp for netcore20 and tests.
This commit is contained in:
Родитель
417797000d
Коммит
dfb0e13e0f
|
@ -42,6 +42,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTestUtils20", "te
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MVCFramework.FunctionalTests", "test\MVCFramework.FunctionalTests\MVCFramework.FunctionalTests.csproj", "{1D5825CC-2EC9-43A1-BE32-778EFF5EAC80}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MVCFramework20.FunctionalTests", "test\MVCFramework20.FunctionalTests\MVCFramework20.FunctionalTests.csproj", "{51198C41-CD4A-4006-84D4-DE20A0A44363}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -80,6 +82,10 @@ Global
|
|||
{1D5825CC-2EC9-43A1-BE32-778EFF5EAC80}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1D5825CC-2EC9-43A1-BE32-778EFF5EAC80}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1D5825CC-2EC9-43A1-BE32-778EFF5EAC80}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{51198C41-CD4A-4006-84D4-DE20A0A44363}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{51198C41-CD4A-4006-84D4-DE20A0A44363}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{51198C41-CD4A-4006-84D4-DE20A0A44363}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{51198C41-CD4A-4006-84D4-DE20A0A44363}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -94,6 +100,7 @@ Global
|
|||
{C47AFD8A-3326-4391-8115-69349C04C3DA} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||
{937AF006-898E-43FD-80A6-B20D7E3A1944} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||
{1D5825CC-2EC9-43A1-BE32-778EFF5EAC80} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||
{51198C41-CD4A-4006-84D4-DE20A0A44363} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {047855A4-470F-43B1-8B74-69651DD6B8A6}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"directory": "wwwroot/lib"
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MVCFramework20.FunctionalTests.Models;
|
||||
using Microsoft.ApplicationInsights;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
|
||||
namespace MVCFramework20.FunctionalTests.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private TelemetryClient telemetryClient;
|
||||
|
||||
public HomeController(TelemetryClient telemetryClient)
|
||||
{
|
||||
this.telemetryClient = telemetryClient;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult About(int index)
|
||||
{
|
||||
ViewBag.Message = "Your application description page # " + index;
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Contact()
|
||||
{
|
||||
this.telemetryClient.TrackEvent("GetContact");
|
||||
this.telemetryClient.TrackMetric("ContactFile", 1);
|
||||
this.telemetryClient.TrackTrace("Fetched contact details.", SeverityLevel.Information);
|
||||
ViewData["Message"] = "Your contact page.";
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Exception()
|
||||
{
|
||||
throw new InvalidOperationException("Do not call the method called Exception");
|
||||
}
|
||||
|
||||
public IActionResult Dependency()
|
||||
{
|
||||
this.telemetryClient.TrackDependency("MyDependency", "MyCommand", DateTimeOffset.Now, TimeSpan.FromMilliseconds(1), success: true);
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
namespace MVCFramework20.FunctionalTests.FunctionalTest
|
||||
{
|
||||
using FunctionalTestUtils;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using Xunit;
|
||||
|
||||
public class CorrelationMvcTests : TelemetryTestsBase
|
||||
{
|
||||
private const string assemblyName = "MVCFramework20.FunctionalTests";
|
||||
|
||||
[Fact]
|
||||
public void CorrelationInfoIsPropagatedToDependendedService()
|
||||
{
|
||||
#if netcoreapp2_0 // Correlation works on .Net core.
|
||||
InProcessServer server;
|
||||
|
||||
using (server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
var task = httpClient.GetAsync(server.BaseHost + "/");
|
||||
task.Wait(TestTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
var telemetries = server.BackChannel.Buffer;
|
||||
|
||||
Assert.True(telemetries.Count >= 2);
|
||||
var requestTelemetry = telemetries.OfType<RequestTelemetry>().Single();
|
||||
var dependencyTelemetry = telemetries.OfType<DependencyTelemetry>().Single();
|
||||
Assert.Equal(requestTelemetry.Context.Operation.Id, dependencyTelemetry.Context.Operation.Id);
|
||||
Assert.Equal(requestTelemetry.Context.Operation.ParentId, dependencyTelemetry.Id);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
using System.Diagnostics;
|
||||
|
||||
namespace MVCFramework20.FunctionalTests.FunctionalTest
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using FunctionalTestUtils;
|
||||
using Microsoft.ApplicationInsights.Channel;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Xunit;
|
||||
using Microsoft.ApplicationInsights.Extensibility;
|
||||
using Microsoft.ApplicationInsights.DependencyCollector;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
public class DependencyTelemetryMvcTests : TelemetryTestsBase
|
||||
{
|
||||
private const string assemblyName = "MVCFramework20.FunctionalTests";
|
||||
|
||||
[Fact]
|
||||
public void CorrelationInfoIsNotAddedToRequestHeaderIfUserAddDomainToExcludedList()
|
||||
{
|
||||
#if netcoreapp2_0 // Correlation is supported on .Net core.
|
||||
InProcessServer server;
|
||||
|
||||
using (server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
var dependencyCollectorModule = server.ApplicationServices.GetServices<ITelemetryModule>().OfType<DependencyTrackingTelemetryModule>().Single();
|
||||
dependencyCollectorModule.ExcludeComponentCorrelationHttpHeadersOnDomains.Add(server.BaseHost);
|
||||
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
var task = httpClient.GetAsync(server.BaseHost + "/");
|
||||
task.Wait(TestTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
var telemetries = server.BackChannel.Buffer;
|
||||
try
|
||||
{
|
||||
Assert.True(telemetries.Count >= 2);
|
||||
var requestTelemetry = telemetries.OfType<RequestTelemetry>().Single();
|
||||
var dependencyTelemetry = telemetries.OfType<DependencyTelemetry>().Single();
|
||||
Assert.NotEqual(requestTelemetry.Context.Operation.Id, dependencyTelemetry.Context.Operation.Id);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
string data = DebugTelemetryItems(telemetries);
|
||||
throw new Exception(data, e);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OperationIdOfRequestIsPropagatedToChildDependency()
|
||||
{
|
||||
// https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/340
|
||||
// Verify operation of OperationIdTelemetryInitializer
|
||||
string path = "Home/Dependency";
|
||||
InProcessServer server;
|
||||
|
||||
using (server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
var task = httpClient.GetAsync(server.BaseHost + "/" + path);
|
||||
task.Wait(TestTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
var telemetries = server.BackChannel.Buffer;
|
||||
try
|
||||
{
|
||||
Assert.True(telemetries.Count >= 2);
|
||||
var requestTelemetry = telemetries.OfType<RequestTelemetry>().Single();
|
||||
var dependencyTelemetry = telemetries.OfType<DependencyTelemetry>().First(t => t.Name == "MyDependency");
|
||||
Assert.Equal(requestTelemetry.Context.Operation.Id, dependencyTelemetry.Context.Operation.Id);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
string data = DebugTelemetryItems(telemetries);
|
||||
throw new Exception(data, e);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParentIdOfChildDependencyIsIdOfRequest()
|
||||
{
|
||||
// https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/333
|
||||
// Verify operation of OperationCorrelationTelemetryInitializer
|
||||
string path = "Home/Dependency";
|
||||
InProcessServer server;
|
||||
using (server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
var task = httpClient.GetAsync(server.BaseHost + "/" + path);
|
||||
task.Wait(TestTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out any unexpected telemetry items.
|
||||
IEnumerable<ITelemetry> telemetries = server.BackChannel.Buffer.Where((t) => t.Context?.Operation?.Name != null && t.Context.Operation.Name.Contains(path));
|
||||
try
|
||||
{
|
||||
Assert.NotNull(telemetries);
|
||||
var requestTelemetry = telemetries.OfType<RequestTelemetry>().Single();
|
||||
var dependencyTelemetry = telemetries.First(t => t is DependencyTelemetry && (t as DependencyTelemetry).Name == "MyDependency");
|
||||
Assert.Equal(requestTelemetry.Id, dependencyTelemetry.Context.Operation.ParentId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
string data = DebugTelemetryItems(server.BackChannel.Buffer);
|
||||
throw new Exception(data, e);
|
||||
}
|
||||
}
|
||||
|
||||
private string DebugTelemetryItems(IList<ITelemetry> telemetries)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
foreach (ITelemetry telemetry in telemetries)
|
||||
{
|
||||
DependencyTelemetry dependency = telemetry as DependencyTelemetry;
|
||||
if (dependency != null) {
|
||||
builder.AppendLine($"{dependency.ToString()} - {dependency.Data} - {dependency.Duration} - {dependency.Id} - {dependency.Name} - {dependency.ResultCode} - {dependency.Sequence} - {dependency.Success} - {dependency.Target} - {dependency.Type}");
|
||||
} else {
|
||||
builder.AppendLine($"{telemetry.ToString()} - {telemetry.Context?.Operation?.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using Xunit;
|
||||
|
||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
||||
namespace MVCFramework20.FunctionalTests.FunctionalTest
|
||||
{
|
||||
using System;
|
||||
using FunctionalTestUtils;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Xunit;
|
||||
|
||||
public class ExceptionTelemetryMvcTests : TelemetryTestsBase
|
||||
{
|
||||
private const string assemblyName = "MVCFramework20.FunctionalTests";
|
||||
|
||||
[Fact]
|
||||
public void TestBasicRequestPropertiesAfterRequestingControllerThatThrows()
|
||||
{
|
||||
using (var server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
const string RequestPath = "/Home/Exception";
|
||||
|
||||
var expectedRequestTelemetry = new RequestTelemetry();
|
||||
expectedRequestTelemetry.Name = "GET Home/Exception";
|
||||
expectedRequestTelemetry.ResponseCode = "500";
|
||||
expectedRequestTelemetry.Success = false;
|
||||
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
|
||||
this.ValidateBasicRequest(server, "/Home/Exception", expectedRequestTelemetry);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestBasicExceptionPropertiesAfterRequestingControllerThatThrows()
|
||||
{
|
||||
using (var server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
var expectedExceptionTelemetry = new ExceptionTelemetry();
|
||||
expectedExceptionTelemetry.Exception = new InvalidOperationException();
|
||||
|
||||
this.ValidateBasicException(server, "/Home/Exception", expectedExceptionTelemetry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MVCFramework20.FunctionalTests.FunctionalTest
|
||||
{
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using FunctionalTestUtils;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Xunit;
|
||||
|
||||
public class RequestTelemetryMvcTests : TelemetryTestsBase
|
||||
{
|
||||
private const string assemblyName = "MVCFramework20.FunctionalTests";
|
||||
|
||||
[Fact]
|
||||
public void TestBasicRequestPropertiesAfterRequestingHomeController()
|
||||
{
|
||||
using (var server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
const string RequestPath = "/";
|
||||
|
||||
var expectedRequestTelemetry = new RequestTelemetry();
|
||||
expectedRequestTelemetry.Name = "GET Home/Index";
|
||||
expectedRequestTelemetry.ResponseCode = "200";
|
||||
expectedRequestTelemetry.Success = true;
|
||||
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
|
||||
|
||||
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestBasicRequestPropertiesAfterRequestingActionWithParameter()
|
||||
{
|
||||
using (var server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
const string RequestPath = "/Home/About/5";
|
||||
|
||||
var expectedRequestTelemetry = new RequestTelemetry();
|
||||
expectedRequestTelemetry.Name = "GET Home/About [id]";
|
||||
expectedRequestTelemetry.ResponseCode = "200";
|
||||
expectedRequestTelemetry.Success = true;
|
||||
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
|
||||
|
||||
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestBasicRequestPropertiesAfterRequestingNotExistingController()
|
||||
{
|
||||
using (var server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
const string RequestPath = "/not/existing/controller";
|
||||
|
||||
var expectedRequestTelemetry = new RequestTelemetry();
|
||||
expectedRequestTelemetry.Name = "GET /not/existing/controller";
|
||||
expectedRequestTelemetry.ResponseCode = "404";
|
||||
expectedRequestTelemetry.Success = false;
|
||||
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
|
||||
|
||||
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestMixedTelemetryItemsReceived()
|
||||
{
|
||||
InProcessServer server;
|
||||
using (server = new InProcessServer(assemblyName, InProcessServer.UseApplicationInsights))
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
var task = httpClient.GetAsync(server.BaseHost + "/Home/Contact");
|
||||
task.Wait(TestTimeoutMs);
|
||||
}
|
||||
}
|
||||
var telemetries = server.BackChannel.Buffer;
|
||||
Assert.Contains(telemetries.OfType<DependencyTelemetry>(), t => t.Name == "GET /Home/Contact");
|
||||
Assert.True(telemetries.Count >= 4);
|
||||
Assert.Contains(telemetries.OfType<RequestTelemetry>(), t => t.Name == "GET Home/Contact");
|
||||
Assert.Contains(telemetries.OfType<EventTelemetry>(), t => t.Name == "GetContact");
|
||||
Assert.Contains(telemetries.OfType<MetricTelemetry>(),
|
||||
t => t.Name == "ContactFile" && t.Value == 1);
|
||||
|
||||
Assert.Contains(telemetries.OfType<TraceTelemetry>(),
|
||||
t => t.Message == "Fetched contact details." && t.SeverityLevel == SeverityLevel.Information);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
namespace MVCFramework20.FunctionalTests.FunctionalTest
|
||||
{
|
||||
using FunctionalTestUtils;
|
||||
using Xunit;
|
||||
|
||||
public class TelemetryModuleWorkingMvcTests : TelemetryTestsBase
|
||||
{
|
||||
private const string assemblyName = "MVCFramework20.FunctionalTests";
|
||||
|
||||
// The NET451 conditional check is wrapped inside the test to make the tests visible in the test explorer. We can move them to the class level once if the issue is resolved.
|
||||
|
||||
[Fact]
|
||||
public void TestBasicDependencyPropertiesAfterRequestingBasicPage()
|
||||
{
|
||||
this.ValidateBasicDependency(assemblyName, "/Home/About/5", InProcessServer.UseApplicationInsights);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestIfPerformanceCountersAreCollected()
|
||||
{
|
||||
#if NET451 || NET461
|
||||
ValidatePerformanceCountersAreCollected(assemblyName, InProcessServer.UseApplicationInsights);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>2.0.0</VersionPrefix>
|
||||
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
|
||||
<RuntimeIdentifier Condition=" '$(TargetFramework)' == 'net461' ">win7-x86</RuntimeIdentifier>
|
||||
<DelaySign>true</DelaySign>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
<AssemblyName>MVCFramework20.FunctionalTests</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>../../keys/35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
<PackageId>MVCFramework.FunctionalTests</PackageId>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<UserSecretsId>aspnet-MVCFramework45.FunctionalTests-60cfc765-2dc9-454c-bb34-dc379ed92cd0</UserSecretsId>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">2.0.0</RuntimeFrameworkVersion>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\test\$(MSBuildProjectName)</OutputPath>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="App.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
</None>
|
||||
<None Update="appsettings.json;web.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="xunit.runner.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="wwwroot\**\*;Views\**\*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FunctionalTestUtils20\FunctionalTestUtils20.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.ApplicationInsights.AspNetCore\Microsoft.ApplicationInsights.AspNetCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.TagHelpers" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||
<PackageReference Include="xunit" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace MVCFramework20.FunctionalTests.Models
|
||||
{
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:34244/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"MVCFramework20.FunctionalTests": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:34245/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.ApplicationInsights.Channel;
|
||||
using FunctionalTestUtils;
|
||||
|
||||
namespace MVCFramework20.FunctionalTests
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<ITelemetryChannel>(new BackTelemetryChannel());
|
||||
services.AddMvc();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
//app.UseBrowserLink();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@{
|
||||
ViewData["Title"] = "About";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<p>Use this area to provide additional information.</p>
|
|
@ -0,0 +1,17 @@
|
|||
@{
|
||||
ViewData["Title"] = "Contact";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<address>
|
||||
One Microsoft Way<br />
|
||||
Redmond, WA 98052-6399<br />
|
||||
<abbr title="Phone">P:</abbr>
|
||||
425.555.0100
|
||||
</address>
|
||||
|
||||
<address>
|
||||
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br />
|
||||
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
|
||||
</address>
|
|
@ -0,0 +1,108 @@
|
|||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
|
||||
<ol class="carousel-indicators">
|
||||
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="1"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="2"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="3"></li>
|
||||
</ol>
|
||||
<div class="carousel-inner" role="listbox">
|
||||
<div class="item active">
|
||||
<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Learn how to build ASP.NET apps that can run anywhere.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner2.svg" alt="Visual Studio" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
There are powerful new features in Visual Studio for building modern web apps.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner3.svg" alt="Package Management" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
|
||||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
|
||||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<h2>Application uses</h2>
|
||||
<ul>
|
||||
<li>Sample pages using ASP.NET Core MVC</li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li>
|
||||
<li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>How to</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Overview</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Run & Deploy</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,22 @@
|
|||
@model ErrorViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
|
||||
</p>
|
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - MVCFramework20.FunctionalTests</title>
|
||||
|
||||
<environment include="Development">
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
|
||||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
|
||||
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
|
||||
</environment>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">MVCFramework20.FunctionalTests</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
|
||||
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
|
||||
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container body-content">
|
||||
@RenderBody()
|
||||
<hr />
|
||||
<footer>
|
||||
<p>© 2017 - MVCFramework20.FunctionalTests</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<environment include="Development">
|
||||
<script src="~/lib/jquery/dist/jquery.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
|
||||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
|
||||
asp-fallback-test="window.jQuery"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
|
||||
</script>
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
|
||||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
|
||||
</script>
|
||||
<script src="~/js/site.min.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
|
||||
@RenderSection("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<environment include="Development">
|
||||
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
|
||||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"
|
||||
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.validator"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-Fnqn3nxp3506LP/7Y3j/25BlWeA3PXTyT1l78LjECcPaKCV12TsZP7yyMxOe/G/k">
|
||||
</script>
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"
|
||||
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-JrXK+k53HACyavUKOsL+NkmSesD2P+73eDMrbTtTk0h4RmOF8hF8apPlkp26JlyH">
|
||||
</script>
|
||||
</environment>
|
|
@ -0,0 +1,3 @@
|
|||
@using MVCFramework20.FunctionalTests
|
||||
@using MVCFramework20.FunctionalTests.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@ -0,0 +1,3 @@
|
|||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "asp.net",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"bootstrap": "3.3.7",
|
||||
"jquery": "2.2.0",
|
||||
"jquery-validation": "1.14.0",
|
||||
"jquery-validation-unobtrusive": "3.2.6"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Configure bundling and minification for the project.
|
||||
// More info at https://go.microsoft.com/fwlink/?LinkId=808241
|
||||
[
|
||||
{
|
||||
"outputFileName": "wwwroot/css/site.min.css",
|
||||
// An array of relative input file paths. Globbing patterns supported
|
||||
"inputFiles": [
|
||||
"wwwroot/css/site.css"
|
||||
]
|
||||
},
|
||||
{
|
||||
"outputFileName": "wwwroot/js/site.min.js",
|
||||
"inputFiles": [
|
||||
"wwwroot/js/site.js"
|
||||
],
|
||||
// Optionally specify minification options
|
||||
"minify": {
|
||||
"enabled": true,
|
||||
"renameLocals": true
|
||||
},
|
||||
// Optionally generate .map file
|
||||
"sourceMap": false
|
||||
}
|
||||
]
|
|
@ -0,0 +1,35 @@
|
|||
body {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Wrapping element */
|
||||
/* Set some basic padding to keep content from hitting the edges */
|
||||
.body-content {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
/* Carousel */
|
||||
.carousel-caption p {
|
||||
font-size: 20px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* Make .svg files in the carousel display properly in older browsers */
|
||||
.carousel-inner .item img[src$=".svg"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* QR code generator */
|
||||
#qrCode {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
/* Hide/rearrange for smaller screens */
|
||||
@media screen and (max-width: 767px) {
|
||||
/* Hide captions */
|
||||
.carousel-caption {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 31 KiB |
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
После Ширина: | Высота: | Размер: 9.5 KiB |
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
После Ширина: | Высота: | Размер: 8.2 KiB |
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
После Ширина: | Высота: | Размер: 11 KiB |
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
После Ширина: | Высота: | Размер: 12 KiB |
|
@ -0,0 +1 @@
|
|||
// Write your JavaScript code.
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"shadowCopy": false
|
||||
}
|
Загрузка…
Ссылка в новой задаче