package org.rakam.module.website;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.cookie.Cookie;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.rakam.collection.Event;
import org.rakam.collection.FieldDependencyBuilder;
import org.rakam.collection.SchemaField;
import org.rakam.plugin.EventMapper;
import org.rakam.util.AvroUtil;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.apache.avro.Schema.Type.NULL;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
public class TestUserAgentEventMapper {
private static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36";
@DataProvider(name = "chrome-user-agent")
public static Object[][] hashEnabledValuesProvider() throws UnknownHostException {
return new Object[][] {
{ ImmutableMap.of("_user_agent", USER_AGENT), EventMapper.RequestParams.EMPTY_PARAMS},
{ ImmutableMap.of("_user_agent", true), (EventMapper.RequestParams) () -> new DefaultHttpHeaders().set("User-Agent", USER_AGENT) },
{ ImmutableMap.of("_user_agent", USER_AGENT), (EventMapper.RequestParams) () -> new DefaultHttpHeaders().set("User-Agent", USER_AGENT) }
};
}
@Test(dataProvider = "chrome-user-agent")
public void testUserAgentMapper(Map<String, Object> props, EventMapper.RequestParams headers) throws Exception {
UserAgentEventMapper mapper = new UserAgentEventMapper(new WebsiteMapperConfig());
FieldDependencyBuilder builder = new FieldDependencyBuilder();
mapper.addFieldDependency(builder);
builder.build();
ImmutableList<Schema.Field> build = ImmutableList.<Schema.Field>builder()
.addAll(builder.build().dependentFields.get("_user_agent").stream()
.map(AvroUtil::generateAvroField).collect(Collectors.toList()))
.add(new Schema.Field("_user_agent", Schema.create(NULL), null, null))
.build();
GenericData.Record properties = new GenericData.Record(Schema.createRecord(build));
props.forEach(properties::put);
Event event = new Event("testproject", "testcollection", null, null, properties);
List<Cookie> resp = mapper.map(event, headers, InetAddress.getLocalHost(), null);
assertEquals("Chrome", event.getAttribute("_user_agent_family"));
assertEquals("Mac OS X", event.getAttribute("_os"));
assertEquals(new Long(10), event.getAttribute("_os_version"));
assertEquals("Other", event.getAttribute("_device_family"));
assertNull(resp);
GenericData.get().validate(properties.getSchema(), properties);
}
@Test()
public void testUserAgentNotExists() throws Exception {
UserAgentEventMapper mapper = new UserAgentEventMapper(new WebsiteMapperConfig());
FieldDependencyBuilder builder = new FieldDependencyBuilder();
mapper.addFieldDependency(builder);
builder.build();
List<SchemaField> fields = builder.build().dependentFields.get("_user_agent");
ImmutableList<Schema.Field> build = ImmutableList.<Schema.Field>builder()
.addAll(fields.stream()
.map(AvroUtil::generateAvroField).collect(Collectors.toList()))
.add(new Schema.Field("_user_agent", Schema.create(NULL), null, null))
.build();
GenericData.Record properties = new GenericData.Record(Schema.createRecord(build));
properties.put("_user_agent", true);
Event event = new Event("testproject", "testcollection", null, null, properties);
List<Cookie> resp = mapper.map(event, EventMapper.RequestParams.EMPTY_PARAMS, InetAddress.getLocalHost(), null);
assertNull(resp);
for (SchemaField field : fields) {
assertNull(event.getAttribute(field.getName()));
}
}
@Test()
public void testUnknownUserAgent() throws Exception {
UserAgentEventMapper mapper = new UserAgentEventMapper(new WebsiteMapperConfig());
FieldDependencyBuilder builder = new FieldDependencyBuilder();
mapper.addFieldDependency(builder);
builder.build();
List<SchemaField> fields = builder.build().dependentFields.get("_user_agent");
ImmutableList<Schema.Field> build = ImmutableList.<Schema.Field>builder()
.addAll(fields.stream()
.map(AvroUtil::generateAvroField).collect(Collectors.toList()))
.add(new Schema.Field("_user_agent", Schema.create(NULL), null, null))
.build();
GenericData.Record properties = new GenericData.Record(Schema.createRecord(build));
properties.put("_user_agent", "unknown user agent");
Event event = new Event("testproject", "testcollection", null, null, properties);
List<Cookie> resp = mapper.map(event, EventMapper.RequestParams.EMPTY_PARAMS, InetAddress.getLocalHost(), null);
assertNull(resp);
assertEquals("Other", event.getAttribute("_user_agent_family"));
assertNull(event.getAttribute("_user_agent_version"));
assertEquals("Other", event.getAttribute("_os"));
assertNull(event.getAttribute("_os_version"));
assertEquals("Other", event.getAttribute("_device_family"));
}
@Test()
public void testDisableUserAgent() throws Exception {
UserAgentEventMapper mapper = new UserAgentEventMapper(new WebsiteMapperConfig());
FieldDependencyBuilder builder = new FieldDependencyBuilder();
mapper.addFieldDependency(builder);
builder.build();
List<SchemaField> fields = builder.build().dependentFields.get("_user_agent");
ImmutableList<Schema.Field> build = ImmutableList.<Schema.Field>builder()
.addAll(fields.stream()
.map(AvroUtil::generateAvroField).collect(Collectors.toList()))
.add(new Schema.Field("_user_agent", Schema.create(NULL), null, null))
.build();
GenericData.Record properties = new GenericData.Record(Schema.createRecord(build));
properties.put("_user_agent", false);
Event event = new Event("testproject", "testcollection", null, null, properties);
List<Cookie> resp = mapper.map(event, () -> new DefaultHttpHeaders().set("User-Agent", USER_AGENT),
InetAddress.getLocalHost(), null);
assertNull(resp);
for (SchemaField field : fields) {
assertNull(event.getAttribute(field.getName()));
}
}
}