public async Task PublishSubEvent_ExistingEventCollectionisAppendedTo()
        {
            var server = new TestServerBuilder()
                         .AddGraphController <InvokableController>()
                         .Build();

            var fieldContextBuilder = server.CreateFieldContextBuilder <InvokableController>(
                nameof(InvokableController.MutationRaisesSubEvent));

            var arg1Value = "random string";

            fieldContextBuilder.AddInputArgument("arg1", arg1Value);

            var resolutionContext = fieldContextBuilder.CreateResolutionContext();
            var eventCollection   = new List <SubscriptionEventProxy>();

            resolutionContext.Request.Items.TryAdd(SubscriptionConstants.RAISED_EVENTS_COLLECTION_KEY, eventCollection);

            var controller = new InvokableController();
            var result     = await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext);

            // ensure the method executed completely
            Assert.IsNotNull(result);
            Assert.IsTrue(result is ObjectReturnedGraphActionResult);

            Assert.AreEqual(1, eventCollection.Count);
        }
        public async Task MethodInvocation_EnsureInternalPropertiesAreSet()
        {
            var server = new TestServerBuilder()
                         .AddGraphController <InvokableController>()
                         .Build();

            var fieldContextBuilder = server.CreateFieldContextBuilder <InvokableController>(nameof(InvokableController.AsyncActionMethod));

            fieldContextBuilder.AddInputArgument("arg1", "random string");

            var resolutionContext = fieldContextBuilder.CreateResolutionContext();

            var controller = new InvokableController();
            var result     = await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext);

            Assert.IsNotNull(result);
            Assert.IsTrue(result is ObjectReturnedGraphActionResult);

            Assert.AreEqual(3, controller.CapturedItems.Count);

            Assert.AreEqual(server.ServiceProvider, controller.CapturedItems["RequestServices"]);
            Assert.AreEqual(resolutionContext.Request, controller.CapturedItems["Request"]);
            var modelState = controller.CapturedItems["ModelState"] as InputModelStateDictionary;

            Assert.IsTrue(modelState.IsValid);
            Assert.IsTrue(modelState.ContainsKey("arg1"));
        }
        public async Task PublishSubEvent_NoDataYieldsNoEvent()
        {
            var server = new TestServerBuilder()
                         .AddGraphController <InvokableController>()
                         .Build();

            var fieldContextBuilder = server.CreateFieldContextBuilder <InvokableController>(
                nameof(InvokableController.MutationRaisesSubEventNoData));

            var arg1Value = "random string";

            fieldContextBuilder.AddInputArgument("arg1", arg1Value);

            var resolutionContext = fieldContextBuilder.CreateResolutionContext();

            var controller = new InvokableController();
            var result     = await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext);

            // ensure the method executed completely
            Assert.IsNotNull(result);
            Assert.IsTrue(result is ObjectReturnedGraphActionResult);

            // ensure the event collection was not created
            Assert.IsFalse(resolutionContext
                           .Request
                           .Items
                           .ContainsKey(SubscriptionConstants.RAISED_EVENTS_COLLECTION_KEY));
        }
        public async Task PublishSubEvent_UnusableListForSubscriptionEvents_ThrowsException()
        {
            var server = new TestServerBuilder()
                         .AddGraphController <InvokableController>()
                         .Build();

            var fieldContextBuilder = server.CreateFieldContextBuilder <InvokableController>(
                nameof(InvokableController.MutationRaisesSubEvent));

            var arg1Value = "random string";

            fieldContextBuilder.AddInputArgument("arg1", arg1Value);

            var resolutionContext = fieldContextBuilder.CreateResolutionContext();

            // prepopulate with a collection thats not really a collection
            var eventCollection = new TwoPropertyObject();

            resolutionContext.Request.Items.TryAdd(SubscriptionConstants.RAISED_EVENTS_COLLECTION_KEY, eventCollection);

            var controller = new InvokableController();

            Assert.ThrowsAsync <GraphExecutionException>(async() =>
            {
                var result = await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext);
            });

            await Task.CompletedTask;
        }
        public void MethodInvocation_UserCodeExceptionIsAllowedToThrow()
        {
            var tester = new TestServerBuilder().Build();
            var fieldContextBuilder = tester.CreateFieldContextBuilder <InvokableController>(nameof(InvokableController.AsyncActionMethodToCauseException));

            fieldContextBuilder.AddInputArgument("arg1", "random string");

            var controller        = new InvokableController();
            var resolutionContext = fieldContextBuilder.CreateResolutionContext();

            Assert.ThrowsAsync <UserThrownException>(async() => await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext));
        }
        public async Task MethodInvocation_SyncMethodReturnsObjectNotTask()
        {
            var tester = new TestServerBuilder().Build();
            var fieldContextBuilder = tester.CreateFieldContextBuilder <InvokableController>(nameof(InvokableController.SyncronousActionMethod));

            fieldContextBuilder.AddInputArgument("arg1", "random string");

            var controller        = new InvokableController();
            var resolutionContext = fieldContextBuilder.CreateResolutionContext();
            var result            = await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext);

            Assert.IsNotNull(result);
            Assert.IsTrue(result is ObjectReturnedGraphActionResult);
        }
        public async Task NotFoundResult_ViaCustomErrorMessage()
        {
            var server = new TestServerBuilder().Build();
            var fieldContextBuilder = server.CreateFieldContextBuilder <InvokableController>(nameof(InvokableController.CreateNotFoundResult));

            var controller        = new InvokableController();
            var resolutionContext = fieldContextBuilder.CreateResolutionContext();
            var result            = await controller.InvokeActionAsync(
                fieldContextBuilder.GraphMethod.Object,
                resolutionContext) as RouteNotFoundGraphActionResult;

            Assert.IsNotNull(result);
            Assert.AreEqual("it was not found", result.Message);
        }
        public async Task MethodInvocation_MissingMethodInfo_ReturnsInternalServerError()
        {
            var tester = new TestServerBuilder().Build();
            var fieldContextBuilder = tester.CreateFieldContextBuilder <InvokableController>(nameof(InvokableController.SyncronousActionMethod));

            fieldContextBuilder.AddInputArgument("arg1", "random string");
            fieldContextBuilder.GraphMethod.Setup(x => x.Method).Returns <MethodInfo>(null);

            var controller        = new InvokableController();
            var resolutionContext = fieldContextBuilder.CreateResolutionContext();
            var result            = await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext);

            // ensure a server error reslt is generated
            Assert.IsNotNull(result);
            Assert.IsTrue(result is InternalServerErrorGraphActionResult);
        }
        public async Task ErrorResult()
        {
            var server = new TestServerBuilder().Build();
            var fieldContextBuilder = server.CreateFieldContextBuilder <InvokableController>(nameof(InvokableController.ErrorResult));

            var controller        = new InvokableController();
            var resolutionContext = fieldContextBuilder.CreateResolutionContext();
            var result            = await controller.InvokeActionAsync(
                fieldContextBuilder.GraphMethod.Object,
                resolutionContext) as GraphFieldErrorActionResult;

            Assert.IsNotNull(result);
            Assert.AreEqual("an error happened", result.Message);
            Assert.AreEqual("12345", result.Code);
            Assert.IsNotNull(result.Exception);
            Assert.AreEqual("exception text", result.Exception.Message);
        }
        public async Task PublishSubEvent_PublishesEventWithCorrectData()
        {
            var server = new TestServerBuilder()
                         .AddGraphController <InvokableController>()
                         .Build();

            var fieldContextBuilder = server.CreateFieldContextBuilder <InvokableController>(
                nameof(InvokableController.MutationRaisesSubEvent));

            var arg1Value = "random string";

            fieldContextBuilder.AddInputArgument("arg1", arg1Value);

            var resolutionContext = fieldContextBuilder.CreateResolutionContext();

            var controller = new InvokableController();
            var result     = await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext);

            // ensure the method executed completely
            Assert.IsNotNull(result);
            Assert.IsTrue(result is ObjectReturnedGraphActionResult);

            // ensure the event collection was created on the context
            Assert.IsTrue(resolutionContext.Request.Items.ContainsKey(SubscriptionConstants.RAISED_EVENTS_COLLECTION_KEY));
            var raisedEvents = resolutionContext.Request.Items[SubscriptionConstants.RAISED_EVENTS_COLLECTION_KEY]
                               as List <SubscriptionEventProxy>;

            // ensure only one event was added
            Assert.AreEqual(1, raisedEvents.Count);
            var eventData = raisedEvents[0];

            // ensure event properties
            Assert.AreEqual("event1", eventData.EventName);
            var obj = eventData.DataObject as TwoPropertyObject;

            Assert.IsNotNull(obj);
            Assert.AreEqual(arg1Value, obj.Property1);
        }
        public async Task PublishSubEvent_NoEventNameFailsTheResolver_BubblesExceptionUp()
        {
            var server = new TestServerBuilder()
                         .AddGraphController <InvokableController>()
                         .Build();

            var fieldContextBuilder = server.CreateFieldContextBuilder <InvokableController>(
                nameof(InvokableController.MutationRaiseSubEventWithNoEventName));

            var arg1Value = "random string";

            fieldContextBuilder.AddInputArgument("arg1", arg1Value);

            var resolutionContext = fieldContextBuilder.CreateResolutionContext();
            var controller        = new InvokableController();

            Assert.ThrowsAsync <ArgumentException>(async() =>
            {
                var result = await controller.InvokeActionAsync(fieldContextBuilder.GraphMethod.Object, resolutionContext);
            });

            await Task.CompletedTask;
        }