github.com/merlinepedra/gopphish-attack@v0.9.0/models/campaign_test.go (about)

     1  package models
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	check "gopkg.in/check.v1"
     9  )
    10  
    11  func (s *ModelsSuite) TestGenerateSendDate(c *check.C) {
    12  	campaign := s.createCampaignDependencies(c)
    13  	// Test that if no launch date is provided, the campaign's creation date
    14  	// is used.
    15  	err := PostCampaign(&campaign, campaign.UserId)
    16  	c.Assert(err, check.Equals, nil)
    17  	c.Assert(campaign.LaunchDate, check.Equals, campaign.CreatedDate)
    18  
    19  	// For comparing the dates, we need to fetch the campaign again. This is
    20  	// to solve an issue where the campaign object right now has time down to
    21  	// the microsecond, while in MySQL it's rounded down to the second.
    22  	campaign, _ = GetCampaign(campaign.Id, campaign.UserId)
    23  
    24  	ms, err := GetMailLogsByCampaign(campaign.Id)
    25  	c.Assert(err, check.Equals, nil)
    26  	for _, m := range ms {
    27  		c.Assert(m.SendDate, check.Equals, campaign.CreatedDate)
    28  	}
    29  
    30  	// Test that if no send date is provided, all the emails are sent at the
    31  	// campaign's launch date
    32  	campaign = s.createCampaignDependencies(c)
    33  	campaign.LaunchDate = time.Now().UTC()
    34  	err = PostCampaign(&campaign, campaign.UserId)
    35  	c.Assert(err, check.Equals, nil)
    36  
    37  	campaign, _ = GetCampaign(campaign.Id, campaign.UserId)
    38  
    39  	ms, err = GetMailLogsByCampaign(campaign.Id)
    40  	c.Assert(err, check.Equals, nil)
    41  	for _, m := range ms {
    42  		c.Assert(m.SendDate, check.Equals, campaign.LaunchDate)
    43  	}
    44  
    45  	// Finally, test that if a send date is provided, the emails are staggered
    46  	// correctly.
    47  	campaign = s.createCampaignDependencies(c)
    48  	campaign.LaunchDate = time.Now().UTC()
    49  	campaign.SendByDate = campaign.LaunchDate.Add(2 * time.Minute)
    50  	err = PostCampaign(&campaign, campaign.UserId)
    51  	c.Assert(err, check.Equals, nil)
    52  
    53  	campaign, _ = GetCampaign(campaign.Id, campaign.UserId)
    54  
    55  	ms, err = GetMailLogsByCampaign(campaign.Id)
    56  	c.Assert(err, check.Equals, nil)
    57  	sendingOffset := 2 / float64(len(ms))
    58  	for i, m := range ms {
    59  		expectedOffset := int(sendingOffset * float64(i))
    60  		expectedDate := campaign.LaunchDate.Add(time.Duration(expectedOffset) * time.Minute)
    61  		c.Assert(m.SendDate, check.Equals, expectedDate)
    62  	}
    63  }
    64  
    65  func (s *ModelsSuite) TestCampaignDateValidation(c *check.C) {
    66  	campaign := s.createCampaignDependencies(c)
    67  	// If both are zero, then the campaign should start immediately with no
    68  	// send by date
    69  	err := campaign.Validate()
    70  	c.Assert(err, check.Equals, nil)
    71  
    72  	// If the launch date is specified, then the send date is optional
    73  	campaign = s.createCampaignDependencies(c)
    74  	campaign.LaunchDate = time.Now().UTC()
    75  	err = campaign.Validate()
    76  	c.Assert(err, check.Equals, nil)
    77  
    78  	// If the send date is greater than the launch date, then there's no
    79  	//problem
    80  	campaign = s.createCampaignDependencies(c)
    81  	campaign.LaunchDate = time.Now().UTC()
    82  	campaign.SendByDate = campaign.LaunchDate.Add(1 * time.Minute)
    83  	err = campaign.Validate()
    84  	c.Assert(err, check.Equals, nil)
    85  
    86  	// If the send date is less than the launch date, then there's an issue
    87  	campaign = s.createCampaignDependencies(c)
    88  	campaign.LaunchDate = time.Now().UTC()
    89  	campaign.SendByDate = campaign.LaunchDate.Add(-1 * time.Minute)
    90  	err = campaign.Validate()
    91  	c.Assert(err, check.Equals, ErrInvalidSendByDate)
    92  }
    93  
    94  func (s *ModelsSuite) TestLaunchCampaignMaillogStatus(c *check.C) {
    95  	// For the first test, ensure that campaigns created with the zero date
    96  	// (and therefore are set to launch immediately) have maillogs that are
    97  	// locked to prevent race conditions.
    98  	campaign := s.createCampaign(c)
    99  	ms, err := GetMailLogsByCampaign(campaign.Id)
   100  	c.Assert(err, check.Equals, nil)
   101  
   102  	for _, m := range ms {
   103  		c.Assert(m.Processing, check.Equals, true)
   104  	}
   105  
   106  	// Next, verify that campaigns scheduled in the future do not lock the
   107  	// maillogs so that they can be picked up by the background worker.
   108  	campaign = s.createCampaignDependencies(c)
   109  	campaign.Name = "New Campaign"
   110  	campaign.LaunchDate = time.Now().Add(1 * time.Hour)
   111  	c.Assert(PostCampaign(&campaign, campaign.UserId), check.Equals, nil)
   112  	ms, err = GetMailLogsByCampaign(campaign.Id)
   113  	c.Assert(err, check.Equals, nil)
   114  
   115  	for _, m := range ms {
   116  		c.Assert(m.Processing, check.Equals, false)
   117  	}
   118  }
   119  
   120  func (s *ModelsSuite) TestDeleteCampaignAlsoDeletesMailLogs(c *check.C) {
   121  	campaign := s.createCampaign(c)
   122  	ms, err := GetMailLogsByCampaign(campaign.Id)
   123  	c.Assert(err, check.Equals, nil)
   124  	c.Assert(len(ms), check.Equals, len(campaign.Results))
   125  
   126  	err = DeleteCampaign(campaign.Id)
   127  	c.Assert(err, check.Equals, nil)
   128  
   129  	ms, err = GetMailLogsByCampaign(campaign.Id)
   130  	c.Assert(err, check.Equals, nil)
   131  	c.Assert(len(ms), check.Equals, 0)
   132  }
   133  
   134  func (s *ModelsSuite) TestCompleteCampaignAlsoDeletesMailLogs(c *check.C) {
   135  	campaign := s.createCampaign(c)
   136  	ms, err := GetMailLogsByCampaign(campaign.Id)
   137  	c.Assert(err, check.Equals, nil)
   138  	c.Assert(len(ms), check.Equals, len(campaign.Results))
   139  
   140  	err = CompleteCampaign(campaign.Id, campaign.UserId)
   141  	c.Assert(err, check.Equals, nil)
   142  
   143  	ms, err = GetMailLogsByCampaign(campaign.Id)
   144  	c.Assert(err, check.Equals, nil)
   145  	c.Assert(len(ms), check.Equals, 0)
   146  }
   147  
   148  func (s *ModelsSuite) TestCampaignGetResults(c *check.C) {
   149  	campaign := s.createCampaign(c)
   150  	got, err := GetCampaign(campaign.Id, campaign.UserId)
   151  	c.Assert(err, check.Equals, nil)
   152  	c.Assert(len(campaign.Results), check.Equals, len(got.Results))
   153  }
   154  
   155  func setupCampaignDependencies(b *testing.B, size int) {
   156  	group := Group{Name: "Test Group"}
   157  	// Create a large group of 5000 members
   158  	for i := 0; i < size; i++ {
   159  		group.Targets = append(group.Targets, Target{BaseRecipient: BaseRecipient{Email: fmt.Sprintf("test%d@example.com", i), FirstName: "User", LastName: fmt.Sprintf("%d", i)}})
   160  	}
   161  	group.UserId = 1
   162  	err := PostGroup(&group)
   163  	if err != nil {
   164  		b.Fatalf("error posting group: %v", err)
   165  	}
   166  
   167  	// Add a template
   168  	template := Template{Name: "Test Template"}
   169  	template.Subject = "{{.RId}} - Subject"
   170  	template.Text = "{{.RId}} - Text"
   171  	template.HTML = "{{.RId}} - HTML"
   172  	template.UserId = 1
   173  	err = PostTemplate(&template)
   174  	if err != nil {
   175  		b.Fatalf("error posting template: %v", err)
   176  	}
   177  
   178  	// Add a landing page
   179  	p := Page{Name: "Test Page"}
   180  	p.HTML = "<html>Test</html>"
   181  	p.UserId = 1
   182  	err = PostPage(&p)
   183  	if err != nil {
   184  		b.Fatalf("error posting page: %v", err)
   185  	}
   186  
   187  	// Add a sending profile
   188  	smtp := SMTP{Name: "Test Page"}
   189  	smtp.UserId = 1
   190  	smtp.Host = "example.com"
   191  	smtp.FromAddress = "test@test.com"
   192  	err = PostSMTP(&smtp)
   193  	if err != nil {
   194  		b.Fatalf("error posting smtp: %v", err)
   195  	}
   196  }
   197  
   198  func BenchmarkCampaign100(b *testing.B) {
   199  	setupBenchmark(b)
   200  	setupCampaignDependencies(b, 100)
   201  	b.ResetTimer()
   202  	for i := 0; i < b.N; i++ {
   203  		campaign := Campaign{Name: "Test campaign"}
   204  		campaign.UserId = 1
   205  		campaign.Template = Template{Name: "Test Template"}
   206  		campaign.Page = Page{Name: "Test Page"}
   207  		campaign.SMTP = SMTP{Name: "Test Page"}
   208  		campaign.Groups = []Group{Group{Name: "Test Group"}}
   209  
   210  		b.StartTimer()
   211  		err := PostCampaign(&campaign, 1)
   212  		if err != nil {
   213  			b.Fatalf("error posting campaign: %v", err)
   214  		}
   215  		b.StopTimer()
   216  		db.Delete(Result{})
   217  		db.Delete(MailLog{})
   218  		db.Delete(Campaign{})
   219  	}
   220  	tearDownBenchmark(b)
   221  }
   222  
   223  func BenchmarkCampaign1000(b *testing.B) {
   224  	setupBenchmark(b)
   225  	setupCampaignDependencies(b, 1000)
   226  	b.ResetTimer()
   227  	for i := 0; i < b.N; i++ {
   228  		campaign := Campaign{Name: "Test campaign"}
   229  		campaign.UserId = 1
   230  		campaign.Template = Template{Name: "Test Template"}
   231  		campaign.Page = Page{Name: "Test Page"}
   232  		campaign.SMTP = SMTP{Name: "Test Page"}
   233  		campaign.Groups = []Group{Group{Name: "Test Group"}}
   234  
   235  		b.StartTimer()
   236  		err := PostCampaign(&campaign, 1)
   237  		if err != nil {
   238  			b.Fatalf("error posting campaign: %v", err)
   239  		}
   240  		b.StopTimer()
   241  		db.Delete(Result{})
   242  		db.Delete(MailLog{})
   243  		db.Delete(Campaign{})
   244  	}
   245  	tearDownBenchmark(b)
   246  }
   247  
   248  func BenchmarkCampaign10000(b *testing.B) {
   249  	setupBenchmark(b)
   250  	setupCampaignDependencies(b, 10000)
   251  	b.ResetTimer()
   252  	for i := 0; i < b.N; i++ {
   253  		campaign := Campaign{Name: "Test campaign"}
   254  		campaign.UserId = 1
   255  		campaign.Template = Template{Name: "Test Template"}
   256  		campaign.Page = Page{Name: "Test Page"}
   257  		campaign.SMTP = SMTP{Name: "Test Page"}
   258  		campaign.Groups = []Group{Group{Name: "Test Group"}}
   259  
   260  		b.StartTimer()
   261  		err := PostCampaign(&campaign, 1)
   262  		if err != nil {
   263  			b.Fatalf("error posting campaign: %v", err)
   264  		}
   265  		b.StopTimer()
   266  		db.Delete(Result{})
   267  		db.Delete(MailLog{})
   268  		db.Delete(Campaign{})
   269  	}
   270  	tearDownBenchmark(b)
   271  }