public void UpdatedFieldIsAdded_CanBeRetrieved() { var path = new GraphFieldPath(GraphCollection.Subscription, "path1/path2"); var mock = new Mock <IGraphField>(); mock.Setup(x => x.Route).Returns(path); mock.Setup(x => x.FieldSource).Returns(GraphFieldTemplateSource.Action); var o = new object(); var o1 = new object(); var collection = new DefaultFieldSourceCollection(GraphFieldTemplateSource.Action); // add then update the source collection.AddSource(mock.Object, o); collection.AddSource(mock.Object, o1); var found = collection.TryRetrieveSource(mock.Object, out var result); Assert.IsTrue(collection.ContainsKey(mock.Object)); Assert.AreEqual(1, collection.Count); Assert.IsTrue(found); Assert.IsNotNull(result); // ensure retrieved result is the second object added Assert.AreEqual(o1, result); }
/// <summary> /// Makes the unique route being used for this virtual field type safe, removing special control characters /// but retaining its uniqueness. /// </summary> /// <param name="path">The path.</param> /// <returns>System.String.</returns> private string MakeSafeTypeNameFromRoutePath(GraphFieldPath path) { var segments = new List <string>(); foreach (var pathSegmentName in path) { switch (pathSegmentName) { case Constants.Routing.QUERY_ROOT: segments.Add(Constants.ReservedNames.QUERY_TYPE_NAME); break; case Constants.Routing.MUTATION_ROOT: segments.Add(Constants.ReservedNames.MUTATION_TYPE_NAME); break; case Constants.Routing.SUBSCRIPTION_ROOT: segments.Add(Constants.ReservedNames.SUBSCRIPTION_TYPE_NAME); break; default: segments.Add(_formatter.FormatGraphTypeName(pathSegmentName)); break; } } segments.Reverse(); return(string.Join("_", segments)); }
public void Destructuring( string rawPath, string expectedPath, bool expectedValidState, GraphCollection expectedRoot, string expectedName, bool shouldHaveParent, string expectedParentPath) { var route = new GraphFieldPath(rawPath); // valid path should be untouched Assert.AreEqual(expectedValidState, route.IsValid); Assert.AreEqual(rawPath, route.Raw); Assert.AreEqual(expectedPath, route.Path); Assert.AreEqual(expectedRoot, route.RootCollection); Assert.AreEqual(expectedName, route.Name); if (!shouldHaveParent) { Assert.IsNull(route.Parent); } else { Assert.IsNotNull(route.Parent); Assert.AreEqual(expectedParentPath, route.Parent.Path); } }
public void UnFoundField_IsNotReturned() { var path = new GraphFieldPath(GraphCollection.Subscription, "path1/path2"); var mock = new Mock <IGraphField>(); mock.Setup(x => x.Route).Returns(path); mock.Setup(x => x.FieldSource).Returns(GraphFieldTemplateSource.Action); var path1 = new GraphFieldPath(GraphCollection.Subscription, "path1/path3"); var mock1 = new Mock <IGraphField>(); mock1.Setup(x => x.Route).Returns(path1); mock1.Setup(x => x.FieldSource).Returns(GraphFieldTemplateSource.Action); var o = new object(); var collection = new DefaultFieldSourceCollection(); collection.AddSource(mock.Object, o); Assert.AreEqual(1, collection.Count); // retreive for an object def. not in the collection var found = collection.TryRetrieveSource(mock1.Object, out var result); Assert.IsFalse(found); Assert.IsNull(result); }
public async Task ReceiveEvent_OnNonSubscribedEventNAme_YieldsNothing() { (var socketClient, var apolloClient) = await this.CreateConnection(); // start a real subscription so the client is tracking one var startMessage = new ApolloClientStartMessage() { Id = "abc", Payload = new GraphQueryData() { Query = "subscription { apolloSubscription { watchForPropObject { property1 } } }", }, }; await apolloClient.DispatchMessage(startMessage); // fire an event against a route not tracked, ensure the client skips it. var route = new GraphFieldPath("[subscription]/ApolloSubscription/WatchForPropObject_NotReal"); await apolloClient.ReceiveEvent(route, new TwoPropertyObject() { Property1 = "value1", Property2 = 33, }); Assert.AreEqual(0, socketClient.ResponseMessageCount); }
public async Task ReceiveEvent_OnStartedSubscription_YieldsDataMessage() { (var socketClient, var apolloClient) = await this.CreateConnection(); var startMessage = new ApolloClientStartMessage() { Id = "abc", Payload = new GraphQueryData() { Query = "subscription { apolloSubscription { watchForPropObject { property1 } } }", }, }; await apolloClient.DispatchMessage(startMessage); var route = new GraphFieldPath("[subscription]/ApolloSubscription/WatchForPropObject"); await apolloClient.ReceiveEvent(route, new TwoPropertyObject() { Property1 = "value1", Property2 = 33, }); socketClient.AssertApolloResponse( ApolloMessageType.DATA, "abc", @"{ ""data"" : { ""apolloSubscription"" : { ""watchForPropObject"" : { ""property1"" : ""value1"", } } } }"); }
public void GraphRouteArgumentPath_YieldsAlternatePathString() { var parent = new GraphFieldPath($"{Constants.Routing.TYPE_ROOT}/typeName/fieldName"); var route = new GraphArgumentFieldPath(parent, "arg1"); Assert.AreEqual($"{Constants.Routing.TYPE_ROOT}/typeName/fieldName[arg1]", route.Path); }
public void ApolloClientSubscriptionEventReceived_PropertyCheck() { var router = new Mock <ISubscriptionEventRouter>(); var server = new ApolloSubscriptionServer <GraphSchema>( new GraphSchema(), new SubscriptionServerOptions <GraphSchema>(), router.Object); var connection = new Mock <IClientConnection>(); var proxy = new ApolloClientProxy <GraphSchema>( connection.Object, new SubscriptionServerOptions <GraphSchema>(), new AspNet.Apollo.Messages.Converters.ApolloMessageConverterFactory()); var sub = new Mock <ISubscription>(); sub.Setup(x => x.Id).Returns("sub1"); var subs = new List <ISubscription>(); subs.Add(sub.Object); var fieldPath = new GraphFieldPath("[subscription]/bob1"); var entry = new ApolloClientSubscriptionEventReceived <GraphSchema>( proxy, fieldPath, subs); Assert.AreEqual(proxy.Id, entry.ClientId); Assert.AreEqual(fieldPath.ToString(), entry.SubscriptionRoute); Assert.AreEqual(1, entry.SubscriptionCount); CollectionAssert.AreEquivalent(subs.Select(x => x.Id).ToList(), entry.SubscriptionIds); Assert.AreNotEqual(entry.GetType().Name, entry.ToString()); }
public void Join_WithRoot_JoinsAsExpected(GraphCollection root, string leftSide, string rightSide, string expectedOutput) { // standard join var fragment = GraphFieldPath.Join(root, leftSide, rightSide); Assert.AreEqual(expectedOutput, fragment); }
private GraphFieldArgumentTemplate ExtractParameterTemplate(string paramName, out ParameterInfo paramInfo) { paramInfo = typeof(ParameterTestClass) .GetMethod(nameof(ParameterTestClass.TestMethod)) .GetParameters() .FirstOrDefault(x => x.Name == paramName); var mockMethod = new Mock <IGraphFieldBaseTemplate>(); mockMethod.Setup(x => x.InternalFullName) .Returns($"{nameof(ParameterTestClass)}.{nameof(ParameterTestClass.TestMethod)}"); mockMethod.Setup(x => x.ObjectType).Returns(typeof(ParameterTestClass)); var route = new GraphFieldPath(GraphFieldPath.Join( GraphCollection.Query, nameof(ParameterTestClass), nameof(ParameterTestClass.TestMethod))); mockMethod.Setup(x => x.Route).Returns(route); var argTemplate = new GraphFieldArgumentTemplate(mockMethod.Object, paramInfo); argTemplate.Parse(); argTemplate.ValidateOrThrow(); return(argTemplate); }
public void IsSameRoute(string fragment1, string fragment2, bool areTheSame) { var route1 = new GraphFieldPath(fragment1); var route2 = new GraphFieldPath(fragment2); // valid path should be untouched Assert.AreEqual(areTheSame, route1.IsSameRoute(route2)); }
public void HasChildRoute(string fragment1, string fragment2, bool frag2IsChildof1) { var route = new GraphFieldPath(fragment1); var route2 = new GraphFieldPath(fragment2); // route2 is a child of route 1, but not the other way around Assert.AreEqual(frag2IsChildof1, route.HasChildRoute(route2)); }
/// <summary> /// When overridden in a child class, this metyhod builds the route that will be assigned to this method /// using the implementation rules of the concrete type. /// </summary> /// <returns>GraphRoutePath.</returns> protected override GraphFieldPath GenerateFieldPath() { // a standard graph object cannot contain any route pathing or nesting like controllers can // before creating hte route, ensure that the declared name, by itself, is valid for graphql var graphName = GraphTypeNames.ParseName(this.ObjectType, TypeKind.INPUT_OBJECT); return(new GraphFieldPath(GraphFieldPath.Join(GraphCollection.Types, graphName))); }
/// <summary> /// When overridden in a child class, this method builds the route that will be assigned to this method /// using the implementation rules of the concrete type. /// </summary> /// <returns>GraphRoutePath.</returns> protected override GraphFieldPath GenerateFieldPath() { // A class property cannot contain any route pathing or nesting like controllers or actions. // Before creating hte route, ensure that the declared name, by itself, is valid for graphql such that resultant // global path for this property will also be correct. var graphName = this.SingleAttributeOfTypeOrDefault <GraphFieldAttribute>()?.Template?.Trim() ?? Constants.Routing.ACTION_METHOD_META_NAME; graphName = graphName.Replace(Constants.Routing.ACTION_METHOD_META_NAME, this.Property.Name).Trim(); return(new GraphFieldPath(GraphFieldPath.Join(this.Parent.Route.Path, graphName))); }
/// <summary> /// When overridden in a child class, this metyhod builds the route that will be assigned to this method /// using the implementation rules of the concrete type. /// </summary> /// <returns>GraphRoutePath.</returns> protected override GraphFieldPath GenerateFieldPath() { // an object method cannot contain any route pathing or nesting like controller methods can // before creating hte route, ensure that the declared name, by itself, is valid for graphql var graphName = this.Method.SingleAttributeOrDefault <GraphFieldAttribute>()?.Template?.Trim() ?? Constants.Routing.ACTION_METHOD_META_NAME; graphName = graphName.Replace(Constants.Routing.ACTION_METHOD_META_NAME, this.Method.Name).Trim(); GraphValidation.EnsureGraphNameOrThrow(this.InternalFullName, graphName); return(new GraphFieldPath(GraphFieldPath.Join(this.Parent.Route.Path, graphName))); }
public void GenerateParentPathSegments_TopLevelFieldReturnsEmptyList() { var fragment = "[query]/path1"; var route = new GraphFieldPath(fragment); Assert.IsTrue(route.IsTopLevelField); var parents = route.GenerateParentPathSegments(); Assert.IsNotNull(parents); Assert.AreEqual(0, parents.Count); }
/// <summary> /// Initializes a new instance of the <see cref="ApolloClientSubscriptionEventReceived{TSchema}" /> class. /// </summary> /// <param name="client">The client proxy that received the event.</param> /// <param name="fieldPath">The field path of the event recieved.</param> /// <param name="subscriptionsToReceive">The filtered set of subscriptions for this client /// that will receive the event.</param> public ApolloClientSubscriptionEventReceived( ApolloClientProxy <TSchema> client, GraphFieldPath fieldPath, IReadOnlyList <ISubscription> subscriptionsToReceive) : base(ApolloLogEventIds.ClientSubscriptionEventRecieved) { this.SchemaTypeName = typeof(TSchema).FriendlyName(true); this.SubscriptionRoute = fieldPath.Path; this.SubscriptionCount = subscriptionsToReceive.Count; this.SubscriptionIds = subscriptionsToReceive.Select(x => x.Id).ToList(); this.ClientId = client.Id; }
public void GenerateParentPathSegments_InvalidPathSegmentReturnsEmptyList() { var fragment = "pat!$#@%h1"; var route = new GraphFieldPath(fragment); Assert.IsFalse(route.IsValid); var parents = route.GenerateParentPathSegments(); Assert.IsNotNull(parents); Assert.AreEqual(0, parents.Count); }
/// <summary> /// When overridden in a child class, this method builds the route that will be assigned to this method /// using the implementation rules of the concrete type. /// </summary> /// <returns>GraphRoutePath.</returns> protected override GraphFieldPath GenerateFieldPath() { // extract the parent name from the global meta data about the type being extended var parentName = GraphTypeNames.ParseName(_typeAttrib.TypeToExtend, TypeKind.OBJECT); // an object method cannot contain any route pathing or nesting like controller methods can // before creating hte route, ensure that the declared name, by itself, is valid for graphql var graphName = _typeAttrib.Template?.Trim() ?? Constants.Routing.ACTION_METHOD_META_NAME; graphName = graphName.Replace(Constants.Routing.ACTION_METHOD_META_NAME, this.Method.Name).Trim(); return(new GraphFieldPath(GraphFieldPath.Join(GraphCollection.Types, parentName, graphName))); }
public async Task ReceiveEvent_WhenNoSubscriptions_YieldsNothing() { (var socketClient, var apolloClient) = await this.CreateConnection(); var route = new GraphFieldPath("[subscription]/ApolloSubscription/WatchForPropObject"); await apolloClient.ReceiveEvent(route, new TwoPropertyObject() { Property1 = "value1", Property2 = 33, }); Assert.AreEqual(0, socketClient.ResponseMessageCount); }
public void AddNewSub_NotReturnedOnNullRoute() { var collection = new ApolloSubscriptionCollection <GraphSchema>(); var fakeSub = new Mock <ISubscription <GraphSchema> >(); var field = new GraphFieldPath("[subscription]/field1"); fakeSub.Setup(x => x.Id).Returns("abc123"); fakeSub.Setup(x => x.Route).Returns(field); collection.Add(fakeSub.Object); Assert.AreEqual(0, collection.CountByRoute(null)); }
public void GenerateParentPathSegments_LeafPathReturnsParentList() { var fragment = "[query]/path1/path2/path3/path4"; var route = new GraphFieldPath(fragment); var parents = route.GenerateParentPathSegments(); Assert.IsNotNull(parents); Assert.AreEqual(3, parents.Count); Assert.AreEqual("[query]/path1", parents[0].Path); Assert.AreEqual("[query]/path1/path2", parents[1].Path); Assert.AreEqual("[query]/path1/path2/path3", parents[2].Path); }
public void Destructuring_Query_TwoFragmentPathHasADefinedParent() { var fragment = "[query]/path1/path2"; var route = new GraphFieldPath(fragment); // valid path should be untouched Assert.IsTrue(route.IsValid); Assert.AreEqual(fragment, route.Raw); Assert.AreEqual(fragment, route.Path); Assert.IsNotNull(route.Parent); Assert.AreEqual(GraphCollection.Query, route.RootCollection); Assert.AreEqual("path2", route.Name); Assert.AreEqual("path1", route.Parent.Name); Assert.AreEqual("[query]/path1", route.Parent.Path); }
/// <summary> /// When overridden in a child class, this metyhod builds the route that will be assigned to this method /// using the implementation rules of the concrete type. /// </summary> /// <returns>GraphRoutePath.</returns> protected override GraphFieldPath GenerateFieldPath() { // Various meta data fields about the method // ------------------------------------------- var graphMethodAttrib = this.SingleAttributeOfTypeOrDefault <GraphFieldAttribute>(); var fieldType = graphMethodAttrib?.FieldType ?? GraphCollection.Unknown; var routeFragment = graphMethodAttrib?.Template?.Trim() ?? Constants.Routing.ACTION_METHOD_META_NAME; routeFragment = routeFragment.Replace(Constants.Routing.ACTION_METHOD_META_NAME, this.Method.Name).Trim(); // remove the parent fragment this method should be nested under if this method is marked as a root entry var parentRouteFragment = (graphMethodAttrib?.IsRootFragment ?? false) ? string.Empty : this.Parent.Route.Path; return(new GraphFieldPath(GraphFieldPath.Join(fieldType, parentRouteFragment, routeFragment))); }
/// <summary> /// Retrieves the total number of subscriptions registered for the given unique route. /// </summary> /// <param name="route">The route to filter by.</param> /// <returns>System.Int32.</returns> public int CountByRoute(GraphFieldPath route) { if (route == null || !route.IsValid) { return(0); } lock (_syncLock) { if (!_subsByRoute.ContainsKey(route)) { return(0); } return(_subsByRoute[route].Count); } }
/// <summary> /// Finds the set all known subscriptions for a given route and returns them. /// </summary> /// <param name="route">The route.</param> /// <returns>IEnumerable<ISubscription<TSchema>>.</returns> public IReadOnlyList <ISubscription <TSchema> > RetreiveByRoute(GraphFieldPath route) { List <ISubscription <TSchema> > subs = new List <ISubscription <TSchema> >(); if (route != null) { lock (_syncLock) { if (_subsByRoute.ContainsKey(route)) { subs.AddRange(_subsByRoute[route]); } } } return(subs); }
public void NotADirectiveMethod_ThrowsException() { var method = typeof(TestDirectiveMethodTemplateContainer) .GetMethod(nameof(TestDirectiveMethodTemplateContainer.NotADirectiveMethod)); var mock = new Mock <IGraphTypeTemplate>(); mock.Setup(x => x.InternalFullName).Returns("Simple"); var route = new GraphFieldPath(GraphCollection.Directives, "Simple"); mock.Setup(x => x.Route).Returns(route); var template = new GraphDirectiveMethodTemplate(mock.Object, method); Assert.Throws <GraphTypeDeclarationException>(() => { template.ValidateOrThrow(); }); }
private async Task ExecuteSubscriptionEvent( ISubscriptionClientProxy client, GraphFieldPath route, object data, CancellationToken cancelToken = default) { try { // execute the request through the runtime await _eventSendSemaphore.WaitAsync().ConfigureAwait(false); await client.ReceiveEvent(route, data, cancelToken).ConfigureAwait(false); } finally { _eventSendSemaphore.Release(); } }
public void AddNewSub_OfDifferentRoute_ReflectsInCollectionCount() { var collection = new ApolloSubscriptionCollection <GraphSchema>(); var fakeSub = new Mock <ISubscription <GraphSchema> >(); var field = new GraphFieldPath("[subscription]/field1"); var field2 = new GraphFieldPath("[subscription]/field2"); var field3 = new GraphFieldPath("[subscription]/field3"); fakeSub.Setup(x => x.Id).Returns("abc123"); fakeSub.Setup(x => x.Route).Returns(field); var fakeSub2 = new Mock <ISubscription <GraphSchema> >(); fakeSub2.Setup(x => x.Id).Returns("abc1234"); fakeSub2.Setup(x => x.Route).Returns(field2); collection.Add(fakeSub.Object); collection.Add(fakeSub2.Object); Assert.AreEqual(1, collection.CountByRoute(field)); Assert.AreEqual(1, collection.CountByRoute(field2)); Assert.AreEqual(2, collection.Count); var foundSubs = collection.RetreiveByRoute(field); Assert.AreEqual(fakeSub.Object, foundSubs.Single()); foundSubs = collection.RetreiveByRoute(field2); Assert.AreEqual(fakeSub2.Object, foundSubs.Single()); foundSubs = collection.RetreiveByRoute(field3); CollectionAssert.IsEmpty(foundSubs); var counted = 0; foreach (var sub in collection) { Assert.IsTrue(sub == fakeSub.Object || sub == fakeSub2.Object); counted++; } Assert.AreEqual(2, counted); }
public void MethodWithSkipAttached_ThrowsException() { // afterfieldResolution is marked skipped var method = typeof(TestDirectiveMethodTemplateContainer) .GetMethod(nameof(TestDirectiveMethodTemplateContainer.AfterFieldResolution)); var mock = new Mock <IGraphTypeTemplate>(); mock.Setup(x => x.InternalFullName).Returns("Simple"); var route = new GraphFieldPath(GraphCollection.Directives, "Simple"); mock.Setup(x => x.Route).Returns(route); var template = new GraphDirectiveMethodTemplate(mock.Object, method); Assert.Throws <GraphTypeDeclarationException>(() => { template.ValidateOrThrow(); }); }