001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.common.text; 017 018import static org.hamcrest.core.Is.is; 019import static org.hamcrest.core.IsNull.notNullValue; 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertThat; 022import org.junit.Before; 023import org.junit.Test; 024import org.modeshape.common.FixFor; 025 026/** 027 * @author Randall Hauch 028 */ 029public class UrlEncoderTest { 030 031 private UrlEncoder encoder = new UrlEncoder(); 032 033 @Before 034 public void beforeEach() { 035 } 036 037 protected void checkEncoding( String input, String expected ) { 038 String output = this.encoder.encode(input); 039 assertThat(output, is(notNullValue())); 040 assertEquals(expected, output); 041 assertThat(output.length(), is(expected.length())); 042 assertThat(output, is(expected)); 043 044 checkDecoding(output, input); 045 } 046 047 protected void checkForNoEncoding( String input ) { 048 String output = this.encoder.encode(input); 049 assertThat(output, is(notNullValue())); 050 assertEquals(input, output); 051 assertThat(output.length(), is(input.length())); 052 assertThat(output, is(input)); 053 054 checkDecoding(output, input); 055 } 056 057 protected void checkDecoding( String input, String output ) { 058 String decoded = this.encoder.decode(input); 059 assertEquals(output, decoded); 060 assertThat(decoded.length(), is(output.length())); 061 assertThat(decoded, is(output)); 062 } 063 064 @Test 065 public void shouldNotEncodeForwardSlashByDefault() { 066 checkEncoding("/", "%2f"); 067 this.encoder.setSlashEncoded(false); 068 checkForNoEncoding("/"); 069 } 070 071 @Test 072 public void shouldEncodePercent() { 073 checkEncoding("%", "%25"); 074 this.encoder.setSlashEncoded(false); 075 checkEncoding("%", "%25"); 076 } 077 078 @Test 079 public void shouldNotEncodeAlphabeticCharacters() { 080 checkForNoEncoding("abcdefghijklmnopqrstuvwxyz"); 081 checkForNoEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 082 this.encoder.setSlashEncoded(false); 083 checkForNoEncoding("abcdefghijklmnopqrstuvwxyz"); 084 checkForNoEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 085 } 086 087 @Test 088 public void shouldNotEncodeNumericCharacters() { 089 checkForNoEncoding("0123456789"); 090 this.encoder.setSlashEncoded(false); 091 checkForNoEncoding("0123456789"); 092 } 093 094 @Test 095 public void shouldNotEncodeReservedPunctuationCharacters() { 096 checkForNoEncoding("-_.!~*\'()"); 097 this.encoder.setSlashEncoded(false); 098 checkForNoEncoding("-_.!~*\'()"); 099 } 100 101 @Test 102 public void shouldNotDecodePercentIfNotFollowedByValidHexNumber() { 103 checkDecoding("%", "%"); 104 checkDecoding("%2", "%2"); 105 checkDecoding("%2G", "%2G"); 106 checkDecoding("%2f", "/"); 107 checkDecoding("%25", "%"); 108 } 109 110 @Test 111 public void shouldEncodeSpaceUsingHexFormat() { 112 checkEncoding(" ", "%20"); 113 } 114 115 @Test 116 public void shouldEncodePunctuationUsingHexFormat() { 117 checkEncoding("`", "%60"); 118 checkEncoding("@", "%40"); 119 checkEncoding("#", "%23"); 120 checkEncoding("$", "%24"); 121 checkEncoding("^", "%5e"); 122 checkEncoding("&", "%26"); 123 checkEncoding("{", "%7b"); 124 checkEncoding("[", "%5b"); 125 checkEncoding("}", "%7d"); 126 checkEncoding("]", "%5d"); 127 checkEncoding("|", "%7c"); 128 checkEncoding(":", "%3a"); 129 checkEncoding(";", "%3b"); 130 checkEncoding("\"", "%22"); 131 checkEncoding("<", "%3c"); 132 checkEncoding(",", "%2c"); 133 checkEncoding(">", "%3e"); 134 checkEncoding("?", "%3f"); 135 } 136 137 @Test 138 public void shouldEncodeAndDecodeUrlsCorrectly() { 139 this.encoder.setSlashEncoded(false); 140 checkEncoding("http://acme.com/this is %something?get=true;something=false", "http%3a//acme.com/this%20is%20%25something%3fget%3dtrue%3bsomething%3dfalse"); 141 } 142 143 @Test 144 @FixFor( "MODE-2258" ) 145 public void shouldEncodeNonReservedNonAsciiCharacter() { 146 this.encoder.setSlashEncoded(false); 147 checkEncoding(":Тест:的", "%3a%d0%a2%d0%b5%d1%81%d1%82%3a%e7%9a%84"); 148 } 149}