public void ProcessMessage_NoOpsForUnknownMessageType()
        {
            // Arrange
            var messageData = new JObject();
            var message = new JObject
            {
                { "MessageType", "SomethingUnknown" },
                { "Data", messageData },
            };
            var called = false;
            var messageBroker = new TestPluginMessageBroker((_) => called = true);
            var assemblyLoadContext = new TestAssemblyLoadContext();
            var plugin = new RazorPlugin(messageBroker);

            // Act
            var handled = plugin.ProcessMessage(message, assemblyLoadContext);

            // Assert
            Assert.False(called);
            Assert.False(handled);
        }
        public void ProcessMessage_ResolveTagHelperDescriptors_ResolvesDesignTimeTagHelperDescriptors()
        {
            // Arrange
            var expectedSourceLocation = new SourceLocation(absoluteIndex: 1, lineIndex: 2, characterIndex: 3);
            var sourceLocationJson = JsonConvert.SerializeObject(expectedSourceLocation);
            var messageData = new JObject
            {
                { "AssemblyName", CustomTagHelperAssembly },
                { "SourceLocation", JObject.Parse(sourceLocationJson) }
            };
            var message = new JObject
            {
                { "MessageType", RazorPluginMessageTypes.ResolveTagHelperDescriptors },
                { "Data", messageData },
            };
            ResolveTagHelperDescriptorsMessage responseMessage = null;
            var messageBroker = new TestPluginMessageBroker(
                data => responseMessage = (ResolveTagHelperDescriptorsMessage)data);
            var assembly = new TestAssembly(typeof(DesignTimeTagHelper));
            var assemblyNameLookups = new Dictionary<string, Assembly>
            {
                { CustomTagHelperAssembly, assembly }
            };
            var assemblyLoadContext = new TestAssemblyLoadContext(assemblyNameLookups);
            var plugin = new RazorPlugin(messageBroker);
            var expectedDescriptor = new TagHelperDescriptor
            {
                Prefix = DefaultPrefix,
                TagName = "design-time",
                TypeName = typeof(DesignTimeTagHelper).FullName,
                AssemblyName = typeof(DesignTimeTagHelper).Assembly.GetName().Name,
                AllowedChildren = new[] { "br" },
                TagStructure = TagStructure.NormalOrSelfClosing,
                DesignTimeDescriptor = new TagHelperDesignTimeDescriptor
                {
                    OutputElementHint = "strong"
                }
            };

            // Act
            var handled = plugin.ProcessMessage(message, assemblyLoadContext);

            // Assert
            Assert.NotNull(responseMessage);
            Assert.Equal(
                RazorPluginMessageTypes.ResolveTagHelperDescriptors,
                responseMessage.MessageType,
                StringComparer.Ordinal);
            var responseData = responseMessage.Data;
            Assert.Equal(CustomTagHelperAssembly, responseData.AssemblyName, StringComparer.Ordinal);
            var actualDescriptor = Assert.Single(responseData.Descriptors);
            Assert.Equal(expectedDescriptor, actualDescriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
            Assert.Empty(responseData.Errors);
            Assert.True(handled);
        }
        public void ProcessMessage_ThrowsWhenNoData()
        {
            // Arrange
            var message = new JObject
            {
                { "MessageType", RazorPluginMessageTypes.ResolveTagHelperDescriptors }
            };
            var messageBroker = new TestPluginMessageBroker();
            var assemblyLoadContext = new TestAssemblyLoadContext();
            var plugin = new RazorPlugin(messageBroker);
            var expectedMessage = "'Data' must be provided for a '" +
                RazorPluginMessageTypes.ResolveTagHelperDescriptors + "' message.";

            // Act & Assert
            var error = Assert.Throws<InvalidOperationException>(
                () => plugin.ProcessMessage(message, assemblyLoadContext));
            Assert.Equal(expectedMessage, error.Message, StringComparer.Ordinal);
        }
        public void ProcessMessage_ThrowsWhenNoMessageType()
        {
            // Arrange
            var message = new JObject();
            var messageBroker = new TestPluginMessageBroker();
            var assemblyLoadContext = new TestAssemblyLoadContext();
            var plugin = new RazorPlugin(messageBroker);
            var expectedMessage = "'MessageType' must be provided for a 'RazorPluginRequestMessage' message.";

            // Act & Assert
            var error = Assert.Throws<InvalidOperationException>(
                () => plugin.ProcessMessage(message, assemblyLoadContext));
            Assert.Equal(expectedMessage, error.Message, StringComparer.Ordinal);
        }
        public void ProcessMessage_ResolveTagHelperDescriptors_ResolvesTagHelperDescriptors()
        {
            // Arrange
            var expectedSourceLocation = new SourceLocation(absoluteIndex: 1, lineIndex: 2, characterIndex: 3);
            var sourceLocationJson = JsonConvert.SerializeObject(expectedSourceLocation);
            var messageData = new JObject
            {
                { "AssemblyName", CustomTagHelperAssembly },
                { "SourceLocation", JObject.Parse(sourceLocationJson) }
            };
            var message = new JObject
            {
                { "MessageType", RazorPluginMessageTypes.ResolveTagHelperDescriptors },
                { "Data", messageData },
            };
            ResolveTagHelperDescriptorsMessage responseMessage = null;
            var messageBroker = new TestPluginMessageBroker(
                data => responseMessage = (ResolveTagHelperDescriptorsMessage)data);
            var assembly = new TestAssembly(typeof(CustomTagHelper));
            var assemblyNameLookups = new Dictionary<string, Assembly>
            {
                { CustomTagHelperAssembly, assembly }
            };
            var assemblyLoadContext = new TestAssemblyLoadContext(assemblyNameLookups);
            var plugin = new RazorPlugin(messageBroker);

            // Act
            var handled = plugin.ProcessMessage(message, assemblyLoadContext);

            // Assert
            Assert.NotNull(responseMessage);
            Assert.Equal(
                RazorPluginMessageTypes.ResolveTagHelperDescriptors,
                responseMessage.MessageType,
                StringComparer.Ordinal);
            var responseData = responseMessage.Data;
            Assert.Equal(CustomTagHelperAssembly, responseData.AssemblyName, StringComparer.Ordinal);
            var actualDescriptor = Assert.Single(responseData.Descriptors);
            Assert.Equal(
                CustomTagHelperDescriptor,
                actualDescriptor,
                CaseSensitiveTagHelperDescriptorComparer.Default);
            Assert.Empty(responseData.Errors);
            Assert.True(handled);
        }