/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package org.apache.shindig.gadgets.rewrite; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import org.apache.shindig.common.uri.Uri; import org.apache.shindig.gadgets.Gadget; import org.apache.shindig.gadgets.rewrite.DomWalker.Visitor.VisitStatus; import org.apache.shindig.gadgets.uri.ProxyUriManager; import org.easymock.Capture; import org.junit.Test; import org.w3c.dom.Element; import org.w3c.dom.Node; import java.util.ArrayList; import java.util.List; import java.util.Map; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; /** * Test of proxying rewriter */ public class ProxyingVisitorTest extends DomWalkerTestBase { private static final String URL_STRING = "http://www.foo.com/"; private static final Map<String, String> ALL_RESOURCES = ProxyingVisitor.Tags .ALL_RESOURCES.getResourceTags(); @Test public void imgVisitReserved() throws Exception { checkVisitReserved("img", true); } @Test public void inputVisitReserved() throws Exception { checkVisitReserved("input", true); } @Test public void bodyVisitReserved() throws Exception { checkVisitReserved("body", true); } @Test public void embedVisitReserved() throws Exception { checkVisitReserved("embed", false); } @Test public void csslinkVisitReserved() throws Exception { checkVisitReserved("link", true, "rel", "stylesheet", "type", "text/css"); } @Test public void linkWithNoRelVisitReserved() throws Exception { checkVisitReserved("link", false, "type", "text/css"); } @Test public void linkWithNoTypeVisitReserved() throws Exception { checkVisitReserved("link", false, "rel", "stylesheet"); } @Test public void altlinkVisitReserved() throws Exception { checkVisitReserved("link", false, "rel", "alternate", "hreflang", "el"); } @Test public void scriptVisitReserved() throws Exception { checkVisitReserved("script", true); } @Test public void objectVisitReserved() throws Exception { checkVisitReserved("object", false); } @Test public void otherVisitNotReserved() throws Exception { checkVisitReserved("other", false); } @Test public void imgWithEmptySrc() throws Exception { Node node = elem("img", "src", ""); ContentRewriterFeature.Config config = createMock(ContentRewriterFeature.Config.class); expect(config.shouldRewriteURL("")).andReturn(true).anyTimes(); expect(config.shouldRewriteTag("img")).andReturn(true).anyTimes(); replay(config); ProxyingVisitor rewriter = new ProxyingVisitor(config, null, ProxyingVisitor.Tags.SCRIPT, ProxyingVisitor.Tags.STYLESHEET, ProxyingVisitor.Tags.EMBEDDED_IMAGES); VisitStatus status = rewriter.visit(null, node); verify(config); assertEquals("Empty attribute should not be rewritten", VisitStatus.BYPASS, status); } private void checkVisitReserved(String tag, boolean result, String ... attrs) throws Exception { tag = tag.toLowerCase(); assertEquals(result, getVisitReserved(tag, true, true, attrs)); assertEquals(result, getVisitReserved(tag.toUpperCase(), true, true, attrs)); assertFalse(getVisitReserved(tag, false, true, attrs)); assertFalse(getVisitReserved(tag, true, false, attrs)); assertFalse(getVisitReserved(tag, false, false, attrs)); } private boolean getVisitReserved(String tag, boolean resUrl, boolean resTag, String ... attrs) throws Exception { // Reserved when lower-case and both URL and Tag reserved. String attrName = ALL_RESOURCES.get(tag.toLowerCase()); attrName = attrName != null ? attrName : "src"; ArrayList <String> attrsList = Lists.newArrayList(attrs); attrsList.add(0, attrName); attrsList.add(1, URL_STRING); attrs = attrsList.toArray(attrs); Node node = elem(tag, attrs); ContentRewriterFeature.Config config = createMock(ContentRewriterFeature.Config.class); expect(config.shouldRewriteURL(URL_STRING)).andReturn(resUrl).anyTimes(); expect(config.shouldRewriteTag(tag.toLowerCase())).andReturn(resTag).anyTimes(); replay(config); ProxyingVisitor rewriter = new ProxyingVisitor(config, null, ProxyingVisitor.Tags.SCRIPT, ProxyingVisitor.Tags.STYLESHEET, ProxyingVisitor.Tags.EMBEDDED_IMAGES); VisitStatus status = rewriter.visit(null, node); verify(config); return status != VisitStatus.BYPASS; } @Test public void revisitModifyValidSkipInvalid() throws Exception { // Batch test: ensures in-order modification. // Includes one mod and one skip. // No need to test invalid nodes since visit() and DomWalker tests preclude this. String scriptSrc = "http://script.com/foo.js"; String imgSrc = "http://script.com/foo.jpg"; Element e1 = elem("script", "src", scriptSrc); Element e2 = elem("script", "src", "^!,,|BLARGH"); Element e3 = elem("IMG", "src", imgSrc); Element e4 = elem("script", "src", " " + scriptSrc + " "); List<Node> nodes = ImmutableList.<Node>of(e1, e2, e3, e4); ProxyUriManager uriManager = createMock(ProxyUriManager.class); Uri rewrittenUri = Uri.parse("http://bar.com/"); List<Uri> returned = Lists.newArrayList(rewrittenUri, rewrittenUri, rewrittenUri); ContentRewriterFeature.Config config = createMock(ContentRewriterFeature.Config.class); Integer expires = 3; expect(config.getExpires()).andReturn(expires).once(); expect(config); Capture<List<ProxyUriManager.ProxyUri>> cap = new Capture<List<ProxyUriManager.ProxyUri>>(); Capture<Integer> intCap = new Capture<Integer>(); expect(uriManager.make(capture(cap), capture(intCap))).andReturn(returned).once(); replay(config, uriManager); Gadget gadget = gadget(); ProxyingVisitor rewriter = new ProxyingVisitor(config, uriManager, ProxyingVisitor.Tags.SCRIPT, ProxyingVisitor.Tags.STYLESHEET, ProxyingVisitor.Tags.EMBEDDED_IMAGES); assertTrue(rewriter.revisit(gadget, nodes)); verify(config, uriManager); assertEquals(3, cap.getValue().size()); assertEquals(Uri.parse(scriptSrc), cap.getValue().get(0).getResource()); assertEquals(Uri.parse(imgSrc), cap.getValue().get(1).getResource()); assertEquals(Uri.parse(scriptSrc), cap.getValue().get(2).getResource()); assertSame(expires, intCap.getValue()); assertEquals(rewrittenUri.toString(), e1.getAttribute("src")); assertEquals("^!,,|BLARGH", e2.getAttribute("src")); assertEquals(rewrittenUri.toString(), e3.getAttribute("src")); assertEquals(rewrittenUri.toString(), e4.getAttribute("src")); // Test that the html tag context has been correctly filled. assertEquals("script", cap.getValue().get(0).getHtmlTagContext()); assertEquals("img", cap.getValue().get(1).getHtmlTagContext()); assertEquals("script", cap.getValue().get(2).getHtmlTagContext()); } }