Skip to content

Commit

Permalink
Added tests to verify response redirection handling in addition to ve…
Browse files Browse the repository at this point in the history
…rifying parse responses is handled correctly when it throws.

- Also added the wrapStart functionality to the JS test utilities

#2506
  • Loading branch information
NTaylorMullen committed Oct 24, 2013
1 parent 1aa9dcc commit 5c609df
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
<Content Include="Tests\FunctionalTests\Common\AjaxAbortFacts.js" />
<Content Include="Tests\FunctionalTests\Common\AjaxSendFacts.js" />
<Content Include="Tests\FunctionalTests\Common\KeepAliveFacts.js" />
<Content Include="Tests\FunctionalTests\Common\ResponseRedirectionFacts.js" />
<Content Include="Tests\FunctionalTests\Core\JsonFacts.js" />
<Content Include="Tests\FunctionalTests\Core\NegotiateFacts.js" />
<Content Include="Tests\FunctionalTests\Hubs\HubEventHandlerFacts.js" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ window.sessionStorage.clear();

return defaultTestTimeout;
})(),
createHubConnection: function (end, assert, testName, url) {
createHubConnection: function (end, assert, testName, url, wrapStart) {
var connection,
qs = (testName ? "test=" + window.encodeURIComponent(testName) : ""),
urlSet = !!url;
qs = (testName ? "test=" + window.encodeURIComponent(testName) : "");

wrapStart = typeof wrapStart === "undefined" ? true : false;

url = url ? url : 'signalr';
if (window.document.testUrl !== 'auto') {
Expand All @@ -80,21 +81,29 @@ window.sessionStorage.clear();

connection = $.hubConnection(url, { useDefaultPath: false, qs: qs })
connection.logging = true;
wrapConnectionStart(connection, end, assert);

if (wrapStart) {
wrapConnectionStart(connection, end, assert);
}

return connection;
},
createConnection: function (url, end, assert, testName) {
createConnection: function (url, end, assert, testName, wrapStart) {
var connection,
qs = (testName ? "test=" + window.encodeURIComponent(testName) : "");

wrapStart = typeof wrapStart === "undefined" ? true : false;

if (window.document.testUrl !== 'auto') {
url = window.document.testUrl + url;
}

connection = $.connection(url, qs);
connection.logging = true;
wrapConnectionStart(connection, end, assert);

if (wrapStart) {
wrapConnectionStart(connection, end, assert);
}

return connection;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
var buildRedirectConnection = function (redirectWhen, end, assert, testName, wrapStart) {
var connection = testUtilities.createConnection("redirectionConnection", end, assert, testName, wrapStart);

connection.qs = {
redirectWhen: redirectWhen
};

return connection;
};

QUnit.module("Response redirection facts");

testUtilities.runWithAllTransports(function (transport) {
QUnit.asyncTimeoutTest(transport + ": Negotiate fails on response redirection.", testUtilities.defaultTestTimeout, function (end, assert, testName) {
var connection = buildRedirectConnection("negotiate", end, assert, testName, false);

connection.start({ transport: transport }).done(function () {
assert.fail("Connection was started successfully.");
end();
}).fail(function () {
assert.comment("Connection start deferred failure was triggered.");
end();
});

// Cleanup
return function () {
connection.stop();
};
});

// Canont do this for long polling because it utilizes the pingServer in its connect process
if (transport !== "longPolling") {
QUnit.asyncTimeoutTest(transport + " - Ping server fails on response redirection.", testUtilities.defaultTestTimeout, function (end, assert, testName) {
var connection = buildRedirectConnection("ping", end, assert, testName),
testPingServer = function () {
$.signalR.transports._logic.pingServer(connection).done(function () {
// Successful ping
assert.fail("Successful ping with " + transport);
end();
}).fail(function (error) {
assert.comment("Failed to ping server with " + transport);
end();
});
};

// Starting/Stopping a connection to have it instantiated with all the appropriate variables
connection.start({ transport: transport }).done(function () {
assert.comment("Connected");
testPingServer();
});

// Cleanup
return function () {
connection.stop();
};
});
}
});

testUtilities.runWithTransports(["longPolling", "foreverFrame", "serverSentEvents"], function (transport) {

QUnit.asyncTimeoutTest(transport + ": Send fails on response redirection.", testUtilities.defaultTestTimeout, function (end, assert, testName) {
var connection = buildRedirectConnection("send", end, assert, testName, true);

connection.start({ transport: transport }).done(function () {
assert.comment("Connection was started successfully.");

connection.send("");

connection.error(function () {
assert.comment("Connection triggered error function on bad send response.");
end();
});
});

// Cleanup
return function () {
connection.stop();
};
});

});

QUnit.asyncTimeoutTest("LongPolling poll fails on response redirection.", testUtilities.defaultTestTimeout, function (end, assert, testName) {
var connection = buildRedirectConnection("poll", end, assert, testName);

connection.start({ transport: "longPolling" }).done(function () {
assert.comment("Connection was started successfully.");

connection.error(function () {
assert.comment("Connection triggered error function on bad poll response.");
end();
});
});

// Cleanup
return function () {
connection.stop();
};
});

Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,44 @@
};
});
});

testUtilities.runWithTransports(["longPolling", "serverSentEvents", "webSockets"], function (transport) {

QUnit.asyncTimeoutTest(transport + ": Invalid JSON payloads triggers connection error.", testUtilities.defaultTestTimeout, function (end, assert, testName) {
var connection = testUtilities.createHubConnection(end, assert, testName),
echoHub = connection.createHubProxies().echoHub;

echoHub.client.echo = function (value) {
assert.fail("Echo successfully triggered.");
end();
};

connection.start({ transport: transport }).done(function () {
assert.comment("Connected.");

connection.json = {
parse: function () {
arguments[0] += "invaaallllid";
return window.JSON.parse.apply(window, arguments);
},
stringify: function () {
return window.JSON.stringify.apply(window, arguments);
}
};

connection.error(function () {
assert.comment("Error was triggered after bad data.");
end();
});

echoHub.server.echoCallback("hello");
});

// Cleanup
return function () {
connection.stop();
};
});
});

})($, window);
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
QUnit.module("Connection Facts");
var buildRedirectConnection = function (redirectWhen, end, assert, testName, wrapStart) {
var connection = testUtilities.createConnection("redirectionConnection", end, assert, testName, wrapStart);

connection.qs = {
redirectWhen: redirectWhen
};

return connection;
};

QUnit.module("Connection Facts");

testUtilities.runWithAllTransports(function (transport) {
// Cannot run with long polling because it uses the ping server as its initial init
Expand Down Expand Up @@ -271,6 +281,7 @@ testUtilities.runWithAllTransports(function (transport) {
connection.stop();
};
});

});

QUnit.module("Connection Facts", !window.document.commandLineTest);
Expand Down Expand Up @@ -301,4 +312,3 @@ testUtilities.runWithTransports(["longPolling", "serverSentEvents", "webSockets"
});

});

Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<script src="Tests/FunctionalTests/Common/AjaxSendFacts.js"></script>
<script src="Tests/FunctionalTests/Common/KeepAliveFacts.js"></script>
<script src="Tests/FunctionalTests/Common/PingServerFacts.js"></script>
<script src="Tests/FunctionalTests/Common/ResponseRedirectionFacts.js"></script>
<script src="Tests/FunctionalTests/Core/JsonFacts.js"></script>
<script src="Tests/FunctionalTests/Core/NegotiateFacts.js"></script>
<script src="Tests/FunctionalTests/Hubs/HubEventHandlerFacts.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Routing;
using Microsoft.AspNet.SignalR.Tests.Common.Connections;
using Owin;

[assembly: PreApplicationStartMethod(typeof(Microsoft.AspNet.SignalR.FunctionalTests.Infrastructure.IIS.InitializeIISHost), "Start")]
Expand Down Expand Up @@ -58,6 +60,7 @@ public static void Start()
RouteTable.Routes.MapConnection<MyBadConnection>("errors-are-fun", "ErrorsAreFun");
RouteTable.Routes.MapConnection<MyGroupEchoConnection>("group-echo", "group-echo");
RouteTable.Routes.MapConnection<MySendingConnection>("multisend", "multisend", new ConnectionConfiguration { EnableCrossDomain = true });
RouteTable.Routes.MapConnection<RedirectionConnection>("redirectionConnection", "redirectionConnection", new ConnectionConfiguration { EnableCrossDomain = true }, ResponseRedirectionMiddleware);
RouteTable.Routes.MapConnection<MyReconnect>("my-reconnect", "my-reconnect");
RouteTable.Routes.MapConnection<ExamineHeadersConnection>("examine-request", "examine-request");
RouteTable.Routes.MapConnection<ExamineReconnectPath>("examine-reconnect", "examine-reconnect");
Expand Down Expand Up @@ -111,9 +114,43 @@ private static void Middleware(IAppBuilder app)
};
};



app.Use(middleware);
}

private static void ResponseRedirectionMiddleware(IAppBuilder app)
{
Func<AppFunc, AppFunc> middlewareRedirection = (next) =>
{
return env =>
{
string redirectWhen = "____Never____";
string queryString = ((string)env["owin.RequestQueryString"]);
if (queryString.Contains("redirectWhen="))
{
redirectWhen = queryString.Replace("?", "")
.Split('&')
.Select(val => val.Split('='))
.First(val => val[0] == "redirectWhen")[1];
}
if (env["owin.RequestPath"].ToString().Contains("/" + redirectWhen))
{
env["owin.ResponseStatusCode"] = 301;
((IDictionary<string, string[]>)env["owin.ResponseHeaders"]).Add("Location", new string[] { "http://" + ((RequestContext)env["System.Web.Routing.RequestContext"]).HttpContext.Request.Url.Authority });
return TaskAsyncHelper.Empty;
}
return next(env);
};
};

app.Use(middlewareRedirection);
}

private static void ReconnectFailedMiddleware(IAppBuilder app)
{
Func<AppFunc, AppFunc> middleware = (next) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Hosting;
using Microsoft.AspNet.SignalR.Owin;
using Microsoft.Owin;

namespace Microsoft.AspNet.SignalR.Tests.Common.Connections
{
// Awesome name, it rhymes
public class RedirectionConnection : PersistentConnection
{
protected override Task OnConnected(IRequest request, string connectionId)
{
Connection.Send(connectionId, "Hi");

return base.OnConnected(request, connectionId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
<Compile Include="App_Start\InitializeIISHost.cs" />
<Compile Include="Connections\ExamineHeadersConnection.cs" />
<Compile Include="Connections\ExamineReconnectPath.cs" />
<Compile Include="Connections\RedirectionConnection.cs" />
<Compile Include="Handlers\GCHandler.cs" />
<Compile Include="Handlers\PingHandler.cs" />
<Compile Include="Build\StartIISTask.cs" />
Expand Down

0 comments on commit 5c609df

Please sign in to comment.