package main

import (
	"testing"
)

func TestReadCommonHeader(t *testing.T) {
	SetupConfig()
	var msg = `<xml><ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
<FromUserName><![CDATA[oUN420bxqFqlx0ZQHciUOesZO3PE]]></FromUserName>
<CreateTime>1492972518</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[CLICK]]></Event>
<EventKey><![CDATA[V1001_TODAY_MUSIC]]></EventKey>
</xml>`

	h := ReadCommonHeader(msg)
	AssertEqual(t, h.ToUserName, "gh_f09231355c68", "ToUserName failed")
	AssertEqual(t, h.FromUserName, "oUN420bxqFqlx0ZQHciUOesZO3PE", "FromUserName failed")
	AssertEqual(t, h.CreateTime, int64(1492972518), "CreateTime Failed")
	AssertEqual(t, h.MsgType, "event", "MsgType failed")

}

func TestTxtMsg(t *testing.T) {
	msg := `<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[this is a test]]></Content>
 <MsgId>1234567890123456</MsgId>
 </xml>`
	h := ReadCommonHeader(msg)
	AssertEqual(t, h.MsgType, "text", "Expect text type")

	m := ReadTextMsg(msg)
	AssertEqual(t, m.Content, "this is a test", "Content failed")
	AssertEqual(t, m.MsgId, int64(1234567890123456), "MsgId not match")
}

func TestPicMsg(t *testing.T) {
	msg := `<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[image]]></MsgType>
 <PicUrl><![CDATA[this is a url]]></PicUrl>
 <MediaId><![CDATA[media_id]]></MediaId>
 <MsgId>1234567890123456</MsgId>
 </xml>`
	h := ReadCommonHeader(msg)
	AssertEqual(t, h.MsgType, "image", "")

	m := ReadPicMsg(msg)
	AssertEqual(t, m.MediaId, "media_id", "Media id failed")
	AssertEqual(t, m.PicUrl, "this is a url", "PicUrl failed")
	AssertEqual(t, m.MsgId, int64(1234567890123456), "MsgId not match")

}

func TestVoiceMsg(t *testing.T) {
	msg := `<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<Format><![CDATA[Format]]></Format>
<Recognition><![CDATA[some result]]></Recognition>
<MsgId>1234567890123456</MsgId>
</xml>`

	h := ReadCommonHeader(msg)
	AssertEqual(t, h.MsgType, "voice", "Message type should be voice")

	m := ReadVoiceMsg(msg)
	AssertEqual(t, m.MediaId, "media_id", "Media id failed")
	AssertEqual(t, m.Format, "Format", "Format failed")
	AssertEqual(t, m.Recognition, "some result", "Recognition failed")
	AssertEqual(t, m.MsgId, int64(1234567890123456), "MsgId not match")

}

func TestVideoMsg(t *testing.T) {
	msg := `<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
<MsgId>1234567890123456</MsgId>
</xml>`

	h := ReadCommonHeader(msg)
	AssertEqual(t, h.MsgType, "video", "Message type should be video")

	m := ReadVideoMsg(msg)
	AssertEqual(t, m.MediaId, "media_id", "Media id failed")
	AssertEqual(t, m.ThumbMediaId, "thumb_media_id", "Format failed")
	AssertEqual(t, m.MsgId, int64(1234567890123456), "MsgId not match")

}

func TestShortVideoMsg(t *testing.T) {
	msg := `<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[shortvideo]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
<MsgId>1234567890123456</MsgId>
</xml>`
	h := ReadCommonHeader(msg)
	AssertEqual(t, h.MsgType, "shortvideo", "Message type should be video")

	m := ReadShortVideoMsg(msg)
	AssertEqual(t, m.MediaId, "media_id", "Media id failed")
	AssertEqual(t, m.ThumbMediaId, "thumb_media_id", "thumb_media_id failed")
	AssertEqual(t, m.MsgId, int64(1234567890123456), "MsgId not match")
}

func TestLocationMsg(t *testing.T) {
	msg := `<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[location]]></MsgType>
<Location_X>23.134521</Location_X>
<Location_Y>113.358803</Location_Y>
<Scale>20</Scale>
<Label><![CDATA[Location description]]></Label>
<MsgId>1234567890123456</MsgId>
</xml>`

	h := ReadCommonHeader(msg)
	AssertEqual(t, h.MsgType, "location", "Message type should be video")

	m := ReadLocationMsg(msg)
	AssertEqual(t, m.Location_X, (float64(23.134521)), "Location_X failed")
	AssertEqual(t, m.Location_Y, (float64(113.358803)), "Location_Y failed")
	AssertEqual(t, m.Scale, int(20), "Scale failed")
	AssertEqual(t, m.Label, "Location description", "Label failed")
	AssertEqual(t, m.MsgId, int64(1234567890123456), "MsgId not match")
}

func TestLinkMsg(t *testing.T) {
	msg := `<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[link]]></MsgType>
<Title><![CDATA[somelinktitle]]></Title>
<Description><![CDATA[somelinktitleDescription]]></Description>
<Url><![CDATA[url]]></Url>
<MsgId>1234567890123456</MsgId>
</xml>`
	h := ReadCommonHeader(msg)
	AssertEqual(t, h.MsgType, "link", "Message type should be link")

	m := ReadLinkMsg(msg)
	AssertEqual(t, m.Title, "somelinktitle", "Title failed")
	AssertEqual(t, m.Description, "somelinktitleDescription", "Description failed")
	AssertEqual(t, m.Url, "url", "Url failed")
	AssertEqual(t, m.MsgId, int64(1234567890123456), "MsgId not match")
}

func TestReadEncryptMsg(t *testing.T) {
	msg := `<xml>
    <ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
    <Encrypt><![CDATA[Dv3epMMhmmGU1o6lg71IfbpRrOYX1S8oZX3nwW0uBAHHMKx62T4KniS4efuf8fNHWf6gsF/YGaDraF6HhGOdKp8vbzluiIEsCnIveKN1pO+IUDOBBxzPAzQSFSYJ3OwVXWmBdBcC1S5guQrOxLysH+6UIWSor9cEef+94UAKTNw/MLB0zPfqK5TVoN1A0yobmP9OU8wtFJP0L1aKySPFGGbqBMfJkStRTrYLjIQfZ7pAIisB/g3c87w26r7LUz9hVh4ey3/T6cjQ8vKvgNKL3j8y4IwUdmnmTPrrdOsyA1pz69977xKHFtIptZYHKGD9dTW6PyPcKKTP6iOod6Agb8TI+is80auqHkjvUyvT/xPG8fxak/wI9BKzKndAnwxlcDG/8WElkHVl0TwxpsCb48ZxLEf4GFKaYaliC9xBVweKLNnqdbBmzwfe7GBNWC61h7KQYqwtZqMkZs3BBsStcQ==]]></Encrypt>
</xml>`
	m := ReadEncryptedMsg(msg)
	AssertEqual(t, m.ToUserName, "gh_f09231355c68", "ToUserName failed")
	AssertEqual(t, m.Encrypt, "Dv3epMMhmmGU1o6lg71IfbpRrOYX1S8oZX3nwW0uBAHHMKx62T4KniS4efuf8fNHWf6gsF/YGaDraF6HhGOdKp8vbzluiIEsCnIveKN1pO+IUDOBBxzPAzQSFSYJ3OwVXWmBdBcC1S5guQrOxLysH+6UIWSor9cEef+94UAKTNw/MLB0zPfqK5TVoN1A0yobmP9OU8wtFJP0L1aKySPFGGbqBMfJkStRTrYLjIQfZ7pAIisB/g3c87w26r7LUz9hVh4ey3/T6cjQ8vKvgNKL3j8y4IwUdmnmTPrrdOsyA1pz69977xKHFtIptZYHKGD9dTW6PyPcKKTP6iOod6Agb8TI+is80auqHkjvUyvT/xPG8fxak/wI9BKzKndAnwxlcDG/8WElkHVl0TwxpsCb48ZxLEf4GFKaYaliC9xBVweKLNnqdbBmzwfe7GBNWC61h7KQYqwtZqMkZs3BBsStcQ==", "ToUserName failed")
}

func TestReadEventClick(t *testing.T) {
	msg := `<xml><ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
<FromUserName><![CDATA[oUN420bxqFqlx0ZQHciUOesZO3PE]]></FromUserName>
<CreateTime>1493903506</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[CLICK]]></Event>
<EventKey><![CDATA[MEMBER_SEARCH]]></EventKey>
</xml>`
	m := ReadEventMsg(msg)
	AssertEqual(t, m.Event, "CLICK", "Expect Click event")
	AssertEqual(t, m.EventKey, "MEMBER_SEARCH", "Expect MEMBER_SEARCH")
	AssertEqual(t, m.Ticket, "", "Expect Empty Ticket")
	AssertEqual(t, m.Latitude, 0.0, "Expect 0")
	AssertEqual(t, m.Longitude, 0.0, "Expect 0")
	AssertEqual(t, m.Precision, 0.0, "Expect 0")
}

func TestAcceptLocationInfo(t *testing.T) {

	// POST /api?signature=1a9991fc0d1916495e26e07dca7d2c305c529b0d&timestamp=1493303819&nonce=1367712073&openid=oUN420bxqFqlx0ZQHciUOesZO3PE&encrypt_type=aes&msg_signature=46331890d4c95a017a014a009ccc7f37228665db HTTP/1.1
	// Host: wechat.hitxy.org.au
	// Accept: */*
	// Cache-Control: no-cache
	// Connection: Keep-Alive
	// Content-Length: 618
	// Content-Type: text/xml
	// Pragma: no-cache
	// User-Agent: Mozilla/4.0
	// X-Forwarded-For: 103.7.30.105
	// X-Forwarded-Host: wechat.hitxy.org.au
	// X-Forwarded-Server: wechat.hitxy.org.au

	// <xml>
	//     <ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
	//     <Encrypt><![CDATA[OyVaYtbrg9fVyLiNJlL18YFP7C36y9kGL3SZDz5ZpWcelnIfUQwUhXXfl2yvbRlaCRW9q9hqPZ0W9ha2p4KzmWikw/vcorrTagz5vGpr980dEqDb0whsybk5R7jZ7hj7+QfZCEyDxYy/O/QsYFYesq6SsDjUQ7JWoxmOZz6g2Sv2WEJ6cXo2iL1fGswc0jYlSynsp3lnVFeVcT4M0a2IEXAxEEuQ7vB9EMAkRQtl5spMDrrH/xXya6O0N9ux3jw+CTl7Oy4TCnJNRxOCq+6SJR4P3PWgWMKcvvgWcTeVGCvduPHDpYbJ+dpfqlxa3WNASrXpSYgQu8edpuIBIXx0b51jBQF1tcekA+z5nCUS53/9CHVo1a1YXLco5bzdMMh7QnafQOtxBbhz1YASj3XpJpyW+qfXc/QoEsZAhVdZVKBNVRz7yJKarkcQopJhevMzFGP0agjkYA/wQ8MAXD7JJ3r8ecOEhebOhfpt+fQ21yYS7YyFyQeUxEhhsSG8O9Ve]]></Encrypt>
	// </xml>

	// Decript as:
	msg := `
	<xml><ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
	<FromUserName><![CDATA[oUN420bxqFqlx0ZQHciUOesZO3PE]]></FromUserName>
	<CreateTime>1493304047</CreateTime>
	<MsgType><![CDATA[event]]></MsgType>
	<Event><![CDATA[LOCATION]]></Event>
	<Latitude>-33.764935</Latitude>
	<Longitude>150.960327</Longitude>
	<Precision>110.000000</Precision>
	</xml>`
	m := ReadEventMsg(msg)
	AssertEqual(t, m.Event, "LOCATION", "Expect LOCATION event")
	AssertEqual(t, m.Longitude, 150.960327, "Expect 150.960327")
	AssertEqual(t, m.Latitude, -33.764935, "Expect -33.764935")
	AssertEqual(t, m.Precision, 110.000000, "Expect 110.000000")
	AssertEqual(t, m.EventKey, "", "Expect Empty EventKey")
	AssertEqual(t, m.Ticket, "", "Expect Empty Ticket")

}

func TestReadEventFollow(t *testing.T) {
	msg := `<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
</xml>`
	m := ReadEventMsg(msg)
	AssertEqual(t, m.Event, "subscribe", "Expect subscribe")
	AssertEqual(t, m.EventKey, "", "Expect Empty EventKey")
	AssertEqual(t, m.Ticket, "", "Expect Empty Ticket")
	AssertEqual(t, m.Latitude, 0.0, "Expect 0")
	AssertEqual(t, m.Longitude, 0.0, "Expect 0")
	AssertEqual(t, m.Precision, 0.0, "Expect 0")

}

func TestReadEventScanNoFollow(t *testing.T) {
	msg := `<xml><ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[qrscene_123123]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>`
	m := ReadEventMsg(msg)
	AssertEqual(t, m.Event, "subscribe", "Expect subscribe")
	AssertEqual(t, m.EventKey, "qrscene_123123", "Expect qrscene_123123")
	AssertEqual(t, m.Ticket, "TICKET", "Expect TICKET")
	AssertEqual(t, m.Latitude, 0.0, "Expect 0")
	AssertEqual(t, m.Longitude, 0.0, "Expect 0")
	AssertEqual(t, m.Precision, 0.0, "Expect 0")

}

func TestReadEventScanWithFollow(t *testing.T) {
	msg := `<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[SCAN]]></Event>
<EventKey><![CDATA[SCENE_VALUE]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>`
	m := ReadEventMsg(msg)
	AssertEqual(t, m.Event, "SCAN", "Expect SCAN")
	AssertEqual(t, m.EventKey, "SCENE_VALUE", "Expect SCENE_VALUE")
	AssertEqual(t, m.Ticket, "TICKET", "Expect TICKET")
	AssertEqual(t, m.Latitude, 0.0, "Expect 0")
	AssertEqual(t, m.Longitude, 0.0, "Expect 0")
	AssertEqual(t, m.Precision, 0.0, "Expect 0")

}

func TestReadEventView(t *testing.T) {
	msg := `<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[VIEW]]></Event>
<EventKey><![CDATA[www.qq.com]]></EventKey>
</xml>`
	m := ReadEventMsg(msg)
	AssertEqual(t, m.Event, "VIEW", "Expect VIEW")
	AssertEqual(t, m.EventKey, "www.qq.com", "Expectwww.qq.com")
	AssertEqual(t, m.Ticket, "", "Expect Empty Ticket")
	AssertEqual(t, m.Latitude, 0.0, "Expect 0")
	AssertEqual(t, m.Longitude, 0.0, "Expect 0")
	AssertEqual(t, m.Precision, 0.0, "Expect 0")

}
