Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issue when accept:*/* and operation is a subscription. #7732

Merged
merged 2 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ protected virtual void OnWriteResponseHeaders(
return _multiPartFormat;
}

if (mediaType.Kind is EventStream)
if (mediaType.Kind is EventStream or All)
{
return _eventStreamFormat;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ protected virtual TestServer CreateStarWarsServer(
.AddStarWarsTypes()
.AddTypeExtension<QueryExtension>()
.AddTypeExtension<SubscriptionsExtensions>()
.AddType<Foo>()
.AddStarWarsRepositories()
.AddInMemorySubscriptions()
.UseInstrumentation()
Expand Down Expand Up @@ -165,4 +166,10 @@ protected virtual TestServer CreateServer(
.UseRouting()
.UseEndpoints(endpoints => configureConventions?.Invoke(endpoints)));
}

[DirectiveType(DirectiveLocation.Subscription)]
public class Foo
{
public required int Bar { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,102 @@ public async Task EventStream_Sends_KeepAlive()
Snapshot
.Create()
.Add(response)
.MatchInline("""
.MatchInline(
"""
Headers:
Cache-Control: no-cache
Content-Type: text/event-stream; charset=utf-8
-------------------------->
Status Code: OK
-------------------------->
event: next
data: {"data":{"delay":"next"}}

:

event: next
data: {"data":{"delay":"next"}}

:

event: complete


""");
}

[Fact]
public async Task EventStream_When_Accept_Is_All()
{
// arrange
var server = CreateStarWarsServer();
var client = server.CreateClient();
client.Timeout = TimeSpan.FromSeconds(30);

// act
using var request = new HttpRequestMessage(HttpMethod.Post, _url);
request.Content = JsonContent.Create(
new ClientQueryRequest
{
Query = "subscription {delay(count: 2, delay:15000)}",
});
request.Headers.Add("Accept", "*/*");

using var response = await client.SendAsync(request, ResponseHeadersRead);

// assert
Snapshot
.Create()
.Add(response)
.MatchInline(
"""
Headers:
Cache-Control: no-cache
Content-Type: text/event-stream; charset=utf-8
-------------------------->
Status Code: OK
-------------------------->
event: next
data: {"data":{"delay":"next"}}

:

event: next
data: {"data":{"delay":"next"}}

:

event: complete


""");
}

[Fact]
public async Task EventStream_When_Accept_Is_All_And_Subscription_Directive()
{
// arrange
var server = CreateStarWarsServer();
var client = server.CreateClient();
client.Timeout = TimeSpan.FromSeconds(30);

// act
using var request = new HttpRequestMessage(HttpMethod.Post, _url);
request.Content = JsonContent.Create(
new ClientQueryRequest
{
Query = "subscription foo @foo(bar: 1) {delay(count: 2, delay:15000)}",
});
request.Headers.Add("Accept", "*/*");

using var response = await client.SendAsync(request, ResponseHeadersRead);

// assert
Snapshot
.Create()
.Add(response)
.MatchInline(
"""
Headers:
Cache-Control: no-cache
Content-Type: text/event-stream; charset=utf-8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#pragma warning disable CS0618 // Type or member is obsolete
#nullable enable

using System.Runtime.CompilerServices;
using CookieCrumble;
using HotChocolate.Execution;
using HotChocolate.Subscriptions;
Expand Down Expand Up @@ -647,6 +648,44 @@ public async Task Arguments_Can_Be_Declared_On_The_Stream()
""");
}

[Fact]
public async Task Subscription_Directives_Are_Allowed()
{
// arrange
// act
var executor = await new ServiceCollection()
.AddGraphQLServer()
.AddDocumentFromString(
"""
type Subscription {
bookAdded: String!
}

directive @bug(test: Int!) on SUBSCRIPTION
""")
.BindRuntimeType<SubscriptionWithDirective>("Subscription")
.ModifyOptions(o => o.StrictValidation = false)
.BuildRequestExecutorAsync();

var result = await executor.ExecuteAsync(
"""
subscription test @bug(test: 123) {
bookAdded
}
""");

// assert
result.MatchInlineSnapshot(
"""
{
"data": {
"bookAdded": "foo"
}
}

""");
}

public class TestObservable : IObservable<string>, IDisposable
{
public bool DisposeRaised { get; private set; }
Expand Down Expand Up @@ -1047,4 +1086,18 @@ public string OnExplicit(
[EventMessage] string message) =>
message;
}


public class SubscriptionWithDirective
{
[Subscribe(With = nameof(GetStream))]
public string BookAdded([EventMessage] string foo) => foo;

private async IAsyncEnumerable<string> GetStream(
[EnumeratorCancellation] CancellationToken ct = default)
{
await Task.Delay(200, ct);
yield return "foo";
}
}
}
Loading