View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.codec.net;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.nio.charset.UnsupportedCharsetException;
27  
28  import org.apache.commons.codec.CharEncoding;
29  import org.apache.commons.codec.DecoderException;
30  import org.apache.commons.codec.EncoderException;
31  import org.junit.jupiter.api.Test;
32  
33  /**
34   * Quoted-printable codec test cases
35   */
36  public class QCodecTest {
37  
38      static final int SWISS_GERMAN_STUFF_UNICODE[] = { 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 };
39  
40      static final int RUSSIAN_STUFF_UNICODE[] = { 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438, 0x432, 0x435, 0x442 };
41  
42      private String constructString(final int[] unicodeChars) {
43          final StringBuilder buffer = new StringBuilder();
44          if (unicodeChars != null) {
45              for (final int unicodeChar : unicodeChars) {
46                  buffer.append((char) unicodeChar);
47              }
48          }
49          return buffer.toString();
50      }
51  
52      @Test
53      public void testBasicEncodeDecode() throws Exception {
54          final QCodec qcodec = new QCodec();
55          final String plain = "= Hello there =\r\n";
56          final String encoded = qcodec.encode(plain);
57          assertEquals("=?UTF-8?Q?=3D Hello there =3D=0D=0A?=", encoded, "Basic Q encoding test");
58          assertEquals(plain, qcodec.decode(encoded), "Basic Q decoding test");
59      }
60  
61      @Test
62      public void testDecodeObjects() throws Exception {
63          final QCodec qcodec = new QCodec();
64          final String decoded = "=?UTF-8?Q?1+1 =3D 2?=";
65          final String plain = (String) qcodec.decode((Object) decoded);
66          assertEquals("1+1 = 2", plain, "Basic Q decoding test");
67  
68          final Object result = qcodec.decode((Object) null);
69          assertNull(result, "Decoding a null Object should return null");
70          assertThrows(DecoderException.class, () -> qcodec.decode(Double.valueOf(3.0d)), "Trying to url encode a Double object should cause an exception.");
71      }
72  
73      @Test
74      public void testDecodeStringWithNull() throws Exception {
75          final QCodec qcodec = new QCodec();
76          final String test = null;
77          final String result = qcodec.decode(test);
78          assertNull(result, "Result should be null");
79      }
80  
81      @Test
82      public void testEncodeDecodeBlanks() throws Exception {
83          final String plain = "Mind those pesky blanks";
84          final String encoded1 = "=?UTF-8?Q?Mind those pesky blanks?=";
85          final String encoded2 = "=?UTF-8?Q?Mind_those_pesky_blanks?=";
86          final QCodec qcodec = new QCodec();
87          qcodec.setEncodeBlanks(false);
88          String s = qcodec.encode(plain);
89          assertEquals(encoded1, s, "Blanks encoding with the Q codec test");
90          qcodec.setEncodeBlanks(true);
91          s = qcodec.encode(plain);
92          assertEquals(encoded2, s, "Blanks encoding with the Q codec test");
93          s = qcodec.decode(encoded1);
94          assertEquals(plain, s, "Blanks decoding with the Q codec test");
95          s = qcodec.decode(encoded2);
96          assertEquals(plain, s, "Blanks decoding with the Q codec test");
97      }
98  
99      @Test
100     public void testEncodeDecodeNull() throws Exception {
101         final QCodec qcodec = new QCodec();
102         assertNull(qcodec.encode((String) null), "Null string Q encoding test");
103         assertNull(qcodec.decode((String) null), "Null string Q decoding test");
104     }
105 
106     @Test
107     public void testEncodeObjects() throws Exception {
108         final QCodec qcodec = new QCodec();
109         final String plain = "1+1 = 2";
110         final String encoded = (String) qcodec.encode((Object) plain);
111 
112         assertEquals("=?UTF-8?Q?1+1 =3D 2?=", encoded, "Basic Q encoding test");
113         final Object result = qcodec.encode((Object) null);
114         assertNull(result, "Encoding a null Object should return null");
115         assertThrows(EncoderException.class, () -> qcodec.encode(Double.valueOf(3.0d)), "Trying to url encode a Double object should cause an exception.");
116     }
117 
118     @Test
119     public void testEncodeStringWithNull() throws Exception {
120         final QCodec qcodec = new QCodec();
121         final String test = null;
122         final String result = qcodec.encode(test, "charset");
123         assertNull(result, "Result should be null");
124     }
125 
126     @Test
127     public void testInvalidEncoding() {
128         assertThrows(UnsupportedCharsetException.class, () -> new QCodec("NONSENSE"));
129     }
130 
131     @Test
132     public void testLetUsMakeCloverHappy() throws Exception {
133         final QCodec qcodec = new QCodec();
134         qcodec.setEncodeBlanks(true);
135         assertTrue(qcodec.isEncodeBlanks());
136         qcodec.setEncodeBlanks(false);
137         assertFalse(qcodec.isEncodeBlanks());
138     }
139 
140     @Test
141     public void testNullInput() throws Exception {
142         final QCodec qcodec = new QCodec();
143         assertNull(qcodec.doDecoding(null));
144         assertNull(qcodec.doEncoding(null));
145     }
146 
147     @Test
148     public void testUnsafeEncodeDecode() throws Exception {
149         final QCodec qcodec = new QCodec();
150         final String plain = "?_=\r\n";
151         final String encoded = qcodec.encode(plain);
152         assertEquals("=?UTF-8?Q?=3F=5F=3D=0D=0A?=", encoded, "Unsafe chars Q encoding test");
153         assertEquals(plain, qcodec.decode(encoded), "Unsafe chars Q decoding test");
154     }
155 
156     @Test
157     public void testUTF8RoundTrip() throws Exception {
158 
159         final String ru_msg = constructString(RUSSIAN_STUFF_UNICODE);
160         final String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
161 
162         final QCodec qcodec = new QCodec(CharEncoding.UTF_8);
163 
164         assertEquals("=?UTF-8?Q?=D0=92=D1=81=D0=B5=D0=BC=5F=D0=BF=D1=80=D0=B8=D0=B2=D0=B5=D1=82?=", qcodec.encode(ru_msg));
165         assertEquals("=?UTF-8?Q?Gr=C3=BCezi=5Fz=C3=A4m=C3=A4?=", qcodec.encode(ch_msg));
166 
167         assertEquals(ru_msg, qcodec.decode(qcodec.encode(ru_msg)));
168         assertEquals(ch_msg, qcodec.decode(qcodec.encode(ch_msg)));
169     }
170 
171 }