1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wifi.hotspot2.anqp; 18 19import static org.junit.Assert.assertEquals; 20 21import android.support.test.filters.SmallTest; 22 23import org.junit.Test; 24 25import java.io.ByteArrayOutputStream; 26import java.io.IOException; 27import java.net.ProtocolException; 28import java.nio.BufferUnderflowException; 29import java.nio.ByteBuffer; 30import java.nio.charset.StandardCharsets; 31import java.util.Locale; 32 33/** 34 * Unit tests for {@link com.android.server.wifi.hotspot2.anqp.I18Name}. 35 */ 36@SmallTest 37public class I18NameTest { 38 private static final String TEST_LANGUAGE = "en"; 39 private static final Locale TEST_LOCALE = Locale.forLanguageTag(TEST_LANGUAGE); 40 private static final String TEST_TEXT = "Hello World"; 41 42 /** 43 * Helper function for returning byte array containing test data. 44 * 45 * @param language The language code string 46 * @param text The text string 47 * @return byte[] 48 * @throws IOException 49 */ 50 private byte[] getTestData(String language, String text) throws IOException { 51 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 52 stream.write(language.getBytes(StandardCharsets.US_ASCII)); 53 stream.write(new byte[]{(byte) 0x0}); // Padding for language code. 54 stream.write(text.getBytes(StandardCharsets.UTF_8)); 55 return stream.toByteArray(); 56 } 57 58 /** 59 * Helper function for generating default test data. The test data include the language code 60 * and text field. 61 * 62 * @return byte[] of data 63 * @throws IOException 64 */ 65 private byte[] getDefaultTestData() throws IOException { 66 return getTestData(TEST_LANGUAGE, TEST_TEXT); 67 } 68 69 /** 70 * Helper function for returning a buffer containing a I18Name test data. 71 * 72 * @Param data The byte array of I18Name data 73 * @param length The length value to set in the I18Name header 74 * @return {@link ByteBuffer} 75 * @throws IOException 76 */ 77 private ByteBuffer getTestBuffer(byte[] data, int length) throws IOException { 78 // Allocate extra byte for storing the length field. 79 ByteBuffer buffer = ByteBuffer.allocate(data.length + 1); 80 buffer.put((byte) length); 81 buffer.put(data); 82 buffer.position(0); 83 return buffer; 84 } 85 86 /** 87 * Verify that BufferUnderflowException will be thrown when parsing from an empty buffer. 88 * 89 * @throws Exception 90 */ 91 @Test(expected = BufferUnderflowException.class) 92 public void parseEmptyBuffer() throws Exception { 93 I18Name.parse(ByteBuffer.allocate(0)); 94 } 95 96 /** 97 * Verify that BufferUnderflowException will be thrown when the length field is set to more 98 * than the actual buffer size. 99 * 100 * @throws Exception 101 */ 102 @Test(expected = BufferUnderflowException.class) 103 public void parseTruncatedBuffer() throws Exception { 104 byte[] data = getDefaultTestData(); 105 ByteBuffer buffer = getTestBuffer(data, data.length); 106 buffer.limit(buffer.remaining() - 1); 107 I18Name.parse(buffer); 108 } 109 110 /** 111 * Verify that ProtocolException will be thrown when the length field is set to less than 112 * the minimum. 113 * 114 * @throws Exception 115 */ 116 @Test(expected = ProtocolException.class) 117 public void parseBufferWithLengthLessThanMinimum() throws Exception { 118 byte[] data = getDefaultTestData(); 119 I18Name.parse(getTestBuffer(data, I18Name.MINIMUM_LENGTH - 1)); 120 } 121 122 /** 123 * Verify that the expected I18Name will be returned when parsing a buffer contained the 124 * predefined test data. 125 * 126 * @throws Exception 127 */ 128 @Test 129 public void parseBufferWithDefaultTestData() throws Exception { 130 byte[] data = getDefaultTestData(); 131 I18Name actualName = I18Name.parse(getTestBuffer(data, data.length)); 132 I18Name expectedName = new I18Name(TEST_LANGUAGE, TEST_LOCALE, TEST_TEXT); 133 assertEquals(expectedName, actualName); 134 } 135 136 /** 137 * Verify that the expected I18Name will be returned when parsing a buffer contained 138 * a non-English (French) language. 139 * 140 * @throws Exception 141 */ 142 @Test 143 public void parseBufferWithFrenchData() throws Exception { 144 // Test data for French. 145 String language = "fr"; 146 String text = "Hello World"; 147 byte[] data = getTestData(language, text); 148 I18Name actualName = I18Name.parse(getTestBuffer(data, data.length)); 149 I18Name expectedName = new I18Name(language, Locale.forLanguageTag(language), text); 150 assertEquals(expectedName, actualName); 151 } 152 153 /** 154 * Verify that an I18Name with an empty text will be returned when parsing a buffer contained 155 * an empty text field. 156 * 157 * @throws Exception 158 */ 159 @Test 160 public void parseBufferWithEmptyText() throws Exception { 161 byte[] data = getTestData(TEST_LANGUAGE, ""); 162 I18Name actualName = I18Name.parse(getTestBuffer(data, data.length)); 163 I18Name expectedName = new I18Name(TEST_LANGUAGE, TEST_LOCALE, ""); 164 assertEquals(expectedName, actualName); 165 } 166} 167