Skip to content

Commit

Permalink
Merge pull request #21 from pusher/ReleaseCandidateChanges
Browse files Browse the repository at this point in the history
Release candidate changes
  • Loading branch information
ewmy committed Feb 11, 2016
2 parents 1c644af + 806ef37 commit ab0c1cf
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 41 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## 3.0.0 rc3

* [ADDED] Build support for the Pusher Travis instance
* [CHANGED] Trigger based calls that result in a bad response no longer throw TriggerResponseExceptions. The response and original content are now available as properties for interrogation
* [ADDED] The Pusher HTTP API Host & Port can now be set via PusherOptions.HostName & PusherOptions.Port properties
* [ADDED] TriggerAsync to allow asynchronous requests to be made to the HTTP API.
* [ADDED] New API abstractions onto Pusher for fetching info on single and multiple channels, and fetching users from a presence Channel. Both sync and sync calls are supported.
* [REMOVED] Event Buffer support
* [ADDED] Support for providing a different JSON serializer & deserializer

## 3.0.0 rc1/2

* [CHANGED] `Trigger` calls that result in a non 200 response from the Pusher HTTP API now result in a `TriggerResponseException` being thrown.
This is a BREAKING CHANGE as previously you could inspect the `ITriggerResult.StatusCode` to detect a failed request.
* [ADDED] When triggering events against a Pusher cluster that supports Event Buffer functionality the IDs of the triggered events
can be retrieved via `ITriggerResult.EventIds`
* [ADDED] The Pusher HTTP API Host can now be set via `PusherOptions.Host`
* [ADDED] `TriggerAsync` to allow asynchronous requests to be made to the HTTP API.

## 2.1.1

* [FIXED] Channel name and socket_id values are validated for `Pusher.Trigger`
Expand Down
49 changes: 47 additions & 2 deletions PusherServer.Tests/AcceptanceTests/ChannelState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,30 @@ public void It_should_return_the_state_asynchronously_When_given_a_channel_name_
Assert.AreEqual(1, result.Data.User_Count);
}

[Test]
public void It_should_return_the_state_asynchronously_When_given_a_channel_name_that_exists_and_no_info_object_is_provided()
{
var reset = new AutoResetEvent(false);

var channelName = "presence-state-channel-async-1";

var pusherServer = ClientServerFactory.CreateServer();
var pusherClient = ClientServerFactory.CreateClient(pusherServer, reset, channelName);

IGetResult<ChannelStateMessage> result = null;

pusherServer.FetchStateForChannelAsync<ChannelStateMessage>(channelName, getResult =>
{
result = getResult;
reset.Set();
});

reset.WaitOne(TimeSpan.FromSeconds(30));

Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
Assert.IsTrue(result.Data.Occupied);
}

[Test]
public void It_should_not_return_the_state_based_asynchronously_When_given_a_channel_name_that_exists_an_bad_attributes()
{
Expand Down Expand Up @@ -218,7 +242,6 @@ public void It_should_return_the_state_When_given_a_channel_name_that_exists()
var result = pusherServer.FetchStateForChannels<object>(info);

Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
// Really need to introduce a mechanism to use a different deserialiser!
Assert.AreEqual(1, ((((Dictionary<string, object>)result.Data)["channels"] as Dictionary<string, object>)["presence-multiple-state-channel3"] as Dictionary<string, object>)["user_count"]);
}

Expand Down Expand Up @@ -263,10 +286,32 @@ public void It_should_return_the_state_asynchronously_When_given_a_channel_name_
reset.WaitOne(TimeSpan.FromSeconds(30));

Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
// Really need to introduce a mechanism to use a different deserialiser!
Assert.AreEqual(1, ((((Dictionary<string, object>)result.Data)["channels"] as Dictionary<string, object>)["presence-multiple-state-channel-async-3"] as Dictionary<string, object>)["user_count"]);
}

[Test]
public void It_should_return_the_state_asynchronously_When_given_a_channel_name_that_exists_and_no_info_object_is_provided()
{
var reset = new AutoResetEvent(false);

var channelName = "presence-multiple-state-channel-async-3";

var pusherServer = ClientServerFactory.CreateServer();
var pusherClient = ClientServerFactory.CreateClient(pusherServer, reset, channelName);

IGetResult<object> result = null;

pusherServer.FetchStateForChannelsAsync<object>(getResult =>
{
result = getResult;
reset.Set();
});

reset.WaitOne(TimeSpan.FromSeconds(30));

Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}

[Test]
public void It_should_not_return_the_state_asynchronously_based_When_given_a_channel_name_that_exists_an_bad_attributes()
{
Expand Down
15 changes: 15 additions & 0 deletions PusherServer/IPusher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ public interface IPusher
/// <returns>The result of the Channel State query</returns>
IGetResult<T> FetchStateForChannel<T>(string channelName, object info);

/// <summary>
/// Queries the Pusher API for the state of a Channel asynchronously
/// </summary>
/// <typeparam name="T">The type of object that will be returned by the API</typeparam>
/// <param name="channelName">The name of the channel to query</param>
/// <param name="callback">The callback to receive the result of the query</param>
void FetchStateForChannelAsync<T>(string channelName, Action<IGetResult<T>> callback);

/// <summary>
/// Queries the Pusher API for the state of a Channel asynchronously
/// </summary>
Expand All @@ -207,6 +215,13 @@ public interface IPusher
/// <returns>The result of the Channels State query</returns>
IGetResult<T> FetchStateForChannels<T>(object info);

/// <summary>
/// Queries the Pusher API for the state of all channels based upon the info object
/// </summary>
/// <typeparam name="T">The type of object that will be returned by the API</typeparam>
/// <param name="callback">The callback to receive the result of the query</param>
void FetchStateForChannelsAsync<T>(Action<IGetResult<T>> callback);

/// <summary>
/// Queries the Pusher API for the state of all channels based upon the info object
/// </summary>
Expand Down
5 changes: 3 additions & 2 deletions PusherServer/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Pusher")]
[assembly: AssemblyProduct("pusher-http-dotnet")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand All @@ -32,6 +32,7 @@
// 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("2.1.1")]
[assembly: AssemblyVersion("3.0.0")]
[assembly: AssemblyInformationalVersion("3.0.0-rc3")]

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("PusherServer.Tests")]
19 changes: 10 additions & 9 deletions PusherServer/Pusher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ public void FetchUsersFromPresenceChannelAsync<T>(string channelName, Action<IGe
}

/// <inheritDoc/>
public IGetResult<T> FetchStateForChannel<T>(string channelName, object info)
public IGetResult<T> FetchStateForChannel<T>(string channelName, object info = null)
{
ThrowArgumentExceptionIfNullOrEmpty(channelName, "channelName");

Expand All @@ -341,14 +341,9 @@ public IGetResult<T> FetchStateForChannel<T>(string channelName, object info)
}

/// <inheritDoc/>
public void FetchUsersFromPrecenceChannelAsync<T>(string channelName, Action<IGetResult<T>> callback)
public void FetchStateForChannelAsync<T>(string channelName, Action<IGetResult<T>> callback)
{
var request = CreateAuthenticatedRequest(Method.GET, string.Format(ChannelUsersResource, channelName), null, null);

_options.RestClient.ExecuteAsync(request, response =>
{
callback(new GetResult<T>(response, _options.JsonDeserializer));
});
FetchStateForChannelAsync<T>(channelName, null, callback);
}

/// <inheritDoc/>
Expand All @@ -365,7 +360,7 @@ public void FetchStateForChannelAsync<T>(string channelName, object info, Action
}

/// <inheritDoc/>
public IGetResult<T> FetchStateForChannels<T>(object info)
public IGetResult<T> FetchStateForChannels<T>(object info = null)
{
var request = CreateAuthenticatedRequest(Method.GET, MultipleChannelsResource, info, null);

Expand All @@ -374,6 +369,12 @@ public IGetResult<T> FetchStateForChannels<T>(object info)
return new GetResult<T>(response, _options.JsonDeserializer);
}

/// <inheritDoc/>
public void FetchStateForChannelsAsync<T>(Action<IGetResult<T>> callback)
{
FetchStateForChannelsAsync<T>(null, callback);
}

/// <inheritDoc/>
public void FetchStateForChannelsAsync<T>(object info, Action<IGetResult<T>> callback)
{
Expand Down
55 changes: 27 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,14 @@ To trigger an event on one or more channels use the trigger function.

#### A single channel

```cs
var result = pusher.Trigger( "channel-1", "test_event", new { message = "hello world" } );
```

or asynchronously

```cs
pusher.TriggerAsync( "channel-1", "test_event", new { message = "hello world" }, (ITriggerResult result) =>
{
});
var result = pusher.Trigger( "channel-1", "test_event", new { message = "hello world" } );
```

#### Multiple channels

```cs
var result = pusher.Trigger( new string[]{ "channel-1", "channel-2" ], "test_event", new { message: "hello world" } );
```

or asynchronously

```
pusher.TriggeAsync( new string[]{ "channel-1", "channel-2" ], "test_event", new { message: "hello world" }, (ITriggerResult result) =>
{
});
var result = pusher.Trigger( new string[]{ "channel-1", "channel-2" ], "test_event", new { message: "hello world" } );
```

### Excluding event recipients
Expand Down Expand Up @@ -110,15 +94,35 @@ You can get a list of channels that are present within your application:
IGetResult<ChannelsList> result = pusher.Get<ChannelsList>("/channels");
```

or

```
IGetResult<ChannelsList> result = pusher.FetchStateForChannels<ChannelsList>();
```

You can provide additional parameters to filter the list of channels that is returned.

```
IGetResult<ChannelsList> result = pusher.Get<ChannelsList>("/channels", new { filter_by_prefix = "presence-" } );
```

or

```
IGetResult<ChannelsList> result = pusher.FetchStateForChannels<ChannelsList>(new { filter_by_prefix = "presence-" } );
```

There is also an asynchronous variation

```
pusher.FetchStateForChannelsAsync<ChannelsList>((IGetResult<ChannelsList> result) =>
{
});
```

#### Fetch channel information

Retrive information about a single channel:
Retrieve information about a single channel:

```
IGetResult<object> result = pusher.Get<object>("/channels/my_channel" );
Expand All @@ -138,7 +142,7 @@ pusher.FetchStateForChannelAsync<object>("my_channel", (ITriggerResult result) =
});
```

Retrive information about multiple channels:
Retrieve information about multiple channels:

```
IGetResult<object> result = pusher.FetchStateForChannels<object>();
Expand All @@ -155,10 +159,10 @@ pusher.FetchStateForChannelsAsync<object>((ITriggerResult result) =>
#### Fetch a list of users on a presence channel
Retrive a list of users that are on a presence channel:
Retrieve a list of users that are on a presence channel:
```
IGetResult<object> result = pusher.Get<object>("/channels/presence-channel/users" );
IGetResult<object> result = pusher.FetchUsersFromPresence<object>("/channels/presence-channel/users" );
```
or
Expand Down Expand Up @@ -221,14 +225,9 @@ else {
* Developed using Visual Studio Community 2013
* The NUnit test framework is used for testing, your copy of Visual Studio needs the "NUnit test adapter" installed from Tools -> Extensions and Updates if you wish to run the test from the IDE.
* PusherServer acceptance tests depends on [PusherClient](https://github.com/pusher/pusher-dotnet-client).
* PusherServer acceptance tests depends on [PusherClient](https://github.com/pusher-community/pusher-websocket-dotnet).
## Publish to NuGet
### Running Tests

In order to run the tests modify `PusherServer.Tests/App.config` and replace the configuration values with Pusher application credtials. Then run the tests in Visual Studio.

### Publish to NuGet
You should be familiar with [creating an publishing NuGet packages](http://docs.nuget.org/docs/creating-packages/creating-and-publishing-a-package).
Expand Down

0 comments on commit ab0c1cf

Please sign in to comment.