001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    
019    package org.apache.commons.codec.net;
020    
021    import static org.junit.Assert.assertEquals;
022    import static org.junit.Assert.assertFalse;
023    import static org.junit.Assert.assertNull;
024    import static org.junit.Assert.assertTrue;
025    import static org.junit.Assert.fail;
026    
027    import java.nio.charset.UnsupportedCharsetException;
028    
029    import org.apache.commons.codec.CharEncoding;
030    import org.apache.commons.codec.DecoderException;
031    import org.apache.commons.codec.EncoderException;
032    import org.junit.Test;
033    
034    /**
035     * Quoted-printable codec test cases
036     *
037     * @version $Id: QCodecTest.html 889935 2013-12-11 05:05:13Z ggregory $
038     */
039    public class QCodecTest {
040    
041        static final int SWISS_GERMAN_STUFF_UNICODE [] = {
042            0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
043        };
044    
045        static final int RUSSIAN_STUFF_UNICODE [] = {
046            0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
047            0x432, 0x435, 0x442
048        };
049    
050        private String constructString(final int [] unicodeChars) {
051            final StringBuilder buffer = new StringBuilder();
052            if (unicodeChars != null) {
053                for (final int unicodeChar : unicodeChars) {
054                    buffer.append((char)unicodeChar);
055                }
056            }
057            return buffer.toString();
058        }
059    
060        @Test
061        public void testNullInput() throws Exception {
062            final QCodec qcodec = new QCodec();
063            assertNull(qcodec.doDecoding(null));
064            assertNull(qcodec.doEncoding(null));
065        }
066    
067        @Test
068        public void testUTF8RoundTrip() throws Exception {
069    
070            final String ru_msg = constructString(RUSSIAN_STUFF_UNICODE);
071            final String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
072    
073            final QCodec qcodec = new QCodec(CharEncoding.UTF_8);
074    
075            assertEquals(
076                "=?UTF-8?Q?=D0=92=D1=81=D0=B5=D0=BC=5F=D0=BF=D1=80=D0=B8=D0=B2=D0=B5=D1=82?=",
077            qcodec.encode(ru_msg)
078            );
079            assertEquals("=?UTF-8?Q?Gr=C3=BCezi=5Fz=C3=A4m=C3=A4?=", qcodec.encode(ch_msg));
080    
081            assertEquals(ru_msg, qcodec.decode(qcodec.encode(ru_msg)));
082            assertEquals(ch_msg, qcodec.decode(qcodec.encode(ch_msg)));
083        }
084    
085    
086        @Test
087        public void testBasicEncodeDecode() throws Exception {
088            final QCodec qcodec = new QCodec();
089            final String plain = "= Hello there =\r\n";
090            final String encoded = qcodec.encode(plain);
091            assertEquals("Basic Q encoding test",
092                "=?UTF-8?Q?=3D Hello there =3D=0D=0A?=", encoded);
093            assertEquals("Basic Q decoding test",
094                plain, qcodec.decode(encoded));
095        }
096    
097        @Test
098        public void testUnsafeEncodeDecode() throws Exception {
099            final QCodec qcodec = new QCodec();
100            final String plain = "?_=\r\n";
101            final String encoded = qcodec.encode(plain);
102            assertEquals("Unsafe chars Q encoding test",
103                "=?UTF-8?Q?=3F=5F=3D=0D=0A?=", encoded);
104            assertEquals("Unsafe chars Q decoding test",
105                plain, qcodec.decode(encoded));
106        }
107    
108        @Test
109        public void testEncodeDecodeNull() throws Exception {
110            final QCodec qcodec = new QCodec();
111            assertNull("Null string Q encoding test",
112                qcodec.encode((String)null));
113            assertNull("Null string Q decoding test",
114                qcodec.decode((String)null));
115        }
116    
117        @Test
118        public void testEncodeStringWithNull() throws Exception {
119            final QCodec qcodec = new QCodec();
120            final String test = null;
121            final String result = qcodec.encode( test, "charset" );
122            assertEquals("Result should be null", null, result);
123        }
124    
125        @Test
126        public void testDecodeStringWithNull() throws Exception {
127            final QCodec qcodec = new QCodec();
128            final String test = null;
129            final String result = qcodec.decode( test );
130            assertEquals("Result should be null", null, result);
131        }
132    
133    
134        @Test
135        public void testEncodeObjects() throws Exception {
136            final QCodec qcodec = new QCodec();
137            final String plain = "1+1 = 2";
138            final String encoded = (String) qcodec.encode((Object) plain);
139            assertEquals("Basic Q encoding test",
140                "=?UTF-8?Q?1+1 =3D 2?=", encoded);
141    
142            final Object result = qcodec.encode((Object) null);
143            assertEquals( "Encoding a null Object should return null", null, result);
144    
145            try {
146                final Object dObj = new Double(3.0);
147                qcodec.encode( dObj );
148                fail( "Trying to url encode a Double object should cause an exception.");
149            } catch (final EncoderException ee) {
150                // Exception expected, test segment passes.
151            }
152        }
153    
154    
155        @Test(expected=UnsupportedCharsetException.class)
156        public void testInvalidEncoding() {
157            new QCodec("NONSENSE");
158        }
159    
160        @Test
161        public void testDecodeObjects() throws Exception {
162            final QCodec qcodec = new QCodec();
163            final String decoded = "=?UTF-8?Q?1+1 =3D 2?=";
164            final String plain = (String) qcodec.decode((Object) decoded);
165            assertEquals("Basic Q decoding test",
166                "1+1 = 2", plain);
167    
168            final Object result = qcodec.decode((Object) null);
169            assertEquals( "Decoding a null Object should return null", null, result);
170    
171            try {
172                final Object dObj = new Double(3.0);
173                qcodec.decode( dObj );
174                fail( "Trying to url encode a Double object should cause an exception.");
175            } catch (final DecoderException ee) {
176                // Exception expected, test segment passes.
177            }
178        }
179    
180    
181        @Test
182        public void testEncodeDecodeBlanks() throws Exception {
183            final String plain = "Mind those pesky blanks";
184            final String encoded1 = "=?UTF-8?Q?Mind those pesky blanks?=";
185            final String encoded2 = "=?UTF-8?Q?Mind_those_pesky_blanks?=";
186            final QCodec qcodec = new QCodec();
187            qcodec.setEncodeBlanks(false);
188            String s = qcodec.encode(plain);
189            assertEquals("Blanks encoding with the Q codec test", encoded1, s);
190            qcodec.setEncodeBlanks(true);
191            s = qcodec.encode(plain);
192            assertEquals("Blanks encoding with the Q codec test", encoded2, s);
193            s = qcodec.decode(encoded1);
194            assertEquals("Blanks decoding with the Q codec test", plain, s);
195            s = qcodec.decode(encoded2);
196            assertEquals("Blanks decoding with the Q codec test", plain, s);
197        }
198    
199    
200        @Test
201        public void testLetUsMakeCloverHappy() throws Exception {
202            final QCodec qcodec = new QCodec();
203            qcodec.setEncodeBlanks(true);
204            assertTrue(qcodec.isEncodeBlanks());
205            qcodec.setEncodeBlanks(false);
206            assertFalse(qcodec.isEncodeBlanks());
207        }
208    
209    }