265 lines
8.1 KiB
Go
265 lines
8.1 KiB
Go
package internal
|
|
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
const sampleXML = `<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
<?xml-stylesheet type="text/xsl" href="sms.xsl"?>
|
|
<smses count="2">
|
|
<sms protocol="0" address="332" date="1285799668193" type="2" subject="null" body="Sample Message Sent from the phone" toa="null" sc_toa="null" service_center="null" read="1" status="-1" locked="0" readable_date="Sep 30, 2010 8:34:28 AM" contact_name="(Unknown)" />
|
|
<sms protocol="0" address="4433221123" date="1289643415810" type="1" subject="null" body="Sample Message received by the phone" toa="null" sc_toa="null" service_center="null" read="0" status="-1" locked="0" readable_date="Nov 13, 2010 9:16:55 PM" contact_name="(Unknown)" />
|
|
</smses>`
|
|
|
|
func TestSampleXMLParsing(t *testing.T) {
|
|
// Parse the XML
|
|
reader := strings.NewReader(sampleXML)
|
|
result, err := ParseSMSBackup(reader)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse XML: %v", err)
|
|
}
|
|
|
|
// Verify we got 2 messages
|
|
if len(result.Messages) != 2 {
|
|
t.Errorf("Expected 2 messages, got %d", len(result.Messages))
|
|
}
|
|
|
|
// Verify first message (sent)
|
|
msg1 := result.Messages[0]
|
|
if msg1.Address != "332" {
|
|
t.Errorf("Expected address '332', got '%s'", msg1.Address)
|
|
}
|
|
if msg1.Type != 2 {
|
|
t.Errorf("Expected type 2 (sent), got %d", msg1.Type)
|
|
}
|
|
if msg1.Body != "Sample Message Sent from the phone" {
|
|
t.Errorf("Expected body 'Sample Message Sent from the phone', got '%s'", msg1.Body)
|
|
}
|
|
if msg1.Protocol != 0 {
|
|
t.Errorf("Expected protocol 0, got %d", msg1.Protocol)
|
|
}
|
|
if !msg1.Read {
|
|
t.Errorf("Expected message to be read (read=1)")
|
|
}
|
|
if msg1.Status != -1 {
|
|
t.Errorf("Expected status -1, got %d", msg1.Status)
|
|
}
|
|
// Check date: 1285799668193 milliseconds = Sep 30, 2010 8:34:28 AM
|
|
expectedDate1 := time.Unix(1285799668, 0)
|
|
if !msg1.Date.Equal(expectedDate1) {
|
|
t.Errorf("Expected date %v, got %v", expectedDate1, msg1.Date)
|
|
}
|
|
|
|
// Verify second message (received)
|
|
msg2 := result.Messages[1]
|
|
// Phone number normalization adds +1 to 10-digit US numbers
|
|
if msg2.Address != "+14433221123" {
|
|
t.Errorf("Expected address '+14433221123', got '%s'", msg2.Address)
|
|
}
|
|
if msg2.Type != 1 {
|
|
t.Errorf("Expected type 1 (received), got %d", msg2.Type)
|
|
}
|
|
if msg2.Body != "Sample Message received by the phone" {
|
|
t.Errorf("Expected body 'Sample Message received by the phone', got '%s'", msg2.Body)
|
|
}
|
|
if msg2.Read {
|
|
t.Errorf("Expected message to be unread (read=0)")
|
|
}
|
|
// Check date: 1289643415810 milliseconds = Nov 13, 2010 9:16:55 PM
|
|
expectedDate2 := time.Unix(1289643415, 0)
|
|
if !msg2.Date.Equal(expectedDate2) {
|
|
t.Errorf("Expected date %v, got %v", expectedDate2, msg2.Date)
|
|
}
|
|
|
|
// Verify no call logs in this sample
|
|
if len(result.Calls) != 0 {
|
|
t.Errorf("Expected 0 call logs, got %d", len(result.Calls))
|
|
}
|
|
}
|
|
|
|
func TestSampleXMLDatabaseIngestion(t *testing.T) {
|
|
// Create a temporary database file
|
|
tmpDB := "test_messages.db"
|
|
defer os.Remove(tmpDB) // Clean up after test
|
|
|
|
// Initialize database
|
|
err := InitDB(tmpDB)
|
|
if err != nil {
|
|
t.Fatalf("Failed to initialize database: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// Parse the XML
|
|
reader := strings.NewReader(sampleXML)
|
|
result, err := ParseSMSBackup(reader)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse XML: %v", err)
|
|
}
|
|
|
|
// Insert messages into database
|
|
messageCount := 0
|
|
for i := range result.Messages {
|
|
err := InsertMessage(db, &result.Messages[i])
|
|
if err != nil {
|
|
t.Errorf("Failed to insert message %d: %v", i, err)
|
|
continue
|
|
}
|
|
messageCount++
|
|
|
|
// Verify the ID was set
|
|
if result.Messages[i].ID == 0 {
|
|
t.Errorf("Message %d: ID was not set after insert", i)
|
|
}
|
|
}
|
|
|
|
// Verify we inserted 2 messages
|
|
if messageCount != 2 {
|
|
t.Errorf("Expected to insert 2 messages, inserted %d", messageCount)
|
|
}
|
|
|
|
// Retrieve messages from database and verify
|
|
messages, err := GetMessages(db, "332", nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed to retrieve messages for address '332': %v", err)
|
|
}
|
|
if len(messages) != 1 {
|
|
t.Errorf("Expected 1 message for address '332', got %d", len(messages))
|
|
} else {
|
|
msg := messages[0]
|
|
if msg.Body != "Sample Message Sent from the phone" {
|
|
t.Errorf("Retrieved message has wrong body: '%s'", msg.Body)
|
|
}
|
|
if msg.Type != 2 {
|
|
t.Errorf("Retrieved message has wrong type: %d", msg.Type)
|
|
}
|
|
if msg.Protocol != 0 {
|
|
t.Errorf("Retrieved message has wrong protocol: %d", msg.Protocol)
|
|
}
|
|
if msg.Status != -1 {
|
|
t.Errorf("Retrieved message has wrong status: %d", msg.Status)
|
|
}
|
|
if !msg.Read {
|
|
t.Errorf("Retrieved message should be marked as read")
|
|
}
|
|
}
|
|
|
|
// Retrieve second message
|
|
messages2, err := GetMessages(db, "+14433221123", nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed to retrieve messages for address '+14433221123': %v", err)
|
|
}
|
|
if len(messages2) != 1 {
|
|
t.Errorf("Expected 1 message for address '+14433221123', got %d", len(messages2))
|
|
} else {
|
|
msg := messages2[0]
|
|
if msg.Body != "Sample Message received by the phone" {
|
|
t.Errorf("Retrieved message has wrong body: '%s'", msg.Body)
|
|
}
|
|
if msg.Type != 1 {
|
|
t.Errorf("Retrieved message has wrong type: %d", msg.Type)
|
|
}
|
|
if msg.Read {
|
|
t.Errorf("Retrieved message should be marked as unread")
|
|
}
|
|
}
|
|
|
|
// Test GetConversations
|
|
conversations, err := GetConversations(db, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get conversations: %v", err)
|
|
}
|
|
if len(conversations) != 2 {
|
|
t.Errorf("Expected 2 conversations, got %d", len(conversations))
|
|
}
|
|
|
|
// Verify conversations are sorted by date (most recent first)
|
|
// Second message (1289643415) should be first as it's more recent
|
|
if len(conversations) == 2 {
|
|
if conversations[0].Address != "+14433221123" {
|
|
t.Errorf("Expected first conversation to be '+14433221123', got '%s'", conversations[0].Address)
|
|
}
|
|
if conversations[1].Address != "332" {
|
|
t.Errorf("Expected second conversation to be '332', got '%s'", conversations[1].Address)
|
|
}
|
|
if conversations[0].MessageCount != 1 {
|
|
t.Errorf("Expected first conversation to have 1 message, got %d", conversations[0].MessageCount)
|
|
}
|
|
if conversations[0].Type != "conversation" {
|
|
t.Errorf("Expected conversation type to be 'conversation', got '%s'", conversations[0].Type)
|
|
}
|
|
}
|
|
|
|
// Test date range functionality
|
|
startDate := time.Unix(1289000000, 0) // After first message, before second
|
|
messages3, err := GetMessages(db, "332", &startDate, nil)
|
|
if err != nil {
|
|
t.Fatalf("Failed to retrieve messages with date filter: %v", err)
|
|
}
|
|
if len(messages3) != 0 {
|
|
t.Errorf("Expected 0 messages after start date, got %d", len(messages3))
|
|
}
|
|
|
|
// Get date range
|
|
minDate, maxDate, err := GetDateRange(db)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get date range: %v", err)
|
|
}
|
|
expectedMin := time.Unix(1285799668, 0)
|
|
expectedMax := time.Unix(1289643415, 0)
|
|
if !minDate.Equal(expectedMin) {
|
|
t.Errorf("Expected min date %v, got %v", expectedMin, minDate)
|
|
}
|
|
if !maxDate.Equal(expectedMax) {
|
|
t.Errorf("Expected max date %v, got %v", expectedMax, maxDate)
|
|
}
|
|
}
|
|
|
|
func TestEmptyXML(t *testing.T) {
|
|
emptyXML := `<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
<smses count="0">
|
|
</smses>`
|
|
|
|
reader := strings.NewReader(emptyXML)
|
|
result, err := ParseSMSBackup(reader)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse empty XML: %v", err)
|
|
}
|
|
|
|
if len(result.Messages) != 0 {
|
|
t.Errorf("Expected 0 messages, got %d", len(result.Messages))
|
|
}
|
|
if len(result.Calls) != 0 {
|
|
t.Errorf("Expected 0 calls, got %d", len(result.Calls))
|
|
}
|
|
}
|
|
|
|
func TestInvalidXML(t *testing.T) {
|
|
invalidXML := `<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
|
<smses count="1">
|
|
<sms protocol="invalid" address="123" date="notanumber" type="2" body="Test" />
|
|
</smses>`
|
|
|
|
reader := strings.NewReader(invalidXML)
|
|
result, err := ParseSMSBackup(reader)
|
|
|
|
// Should parse but skip invalid entries or use defaults
|
|
if err != nil {
|
|
t.Fatalf("Parser should handle invalid data gracefully: %v", err)
|
|
}
|
|
|
|
// The message might be parsed with default values for invalid fields
|
|
if len(result.Messages) > 0 {
|
|
msg := result.Messages[0]
|
|
// Protocol "invalid" should parse as 0
|
|
if msg.Protocol != 0 {
|
|
t.Logf("Invalid protocol parsed as: %d", msg.Protocol)
|
|
}
|
|
// Date "notanumber" should result in Unix epoch
|
|
t.Logf("Invalid date parsed as: %v", msg.Date)
|
|
}
|
|
}
|